This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 5/7] S/390: ifunc: Handle GOTOFF relocs on ifunc symbols.


Normally a GOTOFF reloc only uses the GOT pointer to address something
relativ to it without actually requiring a GOT or PLT slot.  Things
change if the target is an ifunc symbol though.

bfd/ChangeLog:

	* elf32-s390.c (elf_s390_check_relocs): Fallthrough to the PLT
	slot allocating code for GOTOFF relocs on ifunc symbols.
	(elf_s390_gc_sweep_hook): Decrement plt refcount for GOTOFF relocs
	on ifunc symbols.
	(elf_s390_relocate_section): Redirect a GOTOFF reloc to an iplt
	slot.
---
 bfd/elf32-s390.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c
index b1f9dbc..fcdade0 100644
--- a/bfd/elf32-s390.c
+++ b/bfd/elf32-s390.c
@@ -1112,8 +1112,6 @@ elf_s390_check_relocs (bfd *abfd,
 	}
       switch (r_type)
 	{
-	case R_390_GOTOFF16:
-	case R_390_GOTOFF32:
 	case R_390_GOTPC:
 	case R_390_GOTPCDBL:
 	  /* These relocs do not need a GOT slot.  They just load the
@@ -1121,6 +1119,10 @@ elf_s390_check_relocs (bfd *abfd,
 	     the GOT.  Since the GOT pointer has been set up above we
 	     are done.  */
 	  break;
+	case R_390_GOTOFF16:
+	case R_390_GOTOFF32:
+	  if (h == NULL || !s390_is_ifunc_symbol_p (h) || !h->def_regular)
+	    break;
 
 	case R_390_PLT12DBL:
 	case R_390_PLT16DBL:
@@ -1529,6 +1531,12 @@ elf_s390_gc_sweep_hook (bfd *abfd,
 
 	case R_390_GOTOFF16:
 	case R_390_GOTOFF32:
+	  if (s390_is_ifunc_symbol_p (h) && h->def_regular)
+	    {
+	      h->plt.refcount--;
+	      break;
+	    }
+
 	case R_390_GOTPC:
 	case R_390_GOTPCDBL:
 	  break;
@@ -2640,6 +2648,18 @@ elf_s390_relocate_section (bfd *output_bfd,
 	  /* Relocation is relative to the start of the global offset
 	     table.  */
 
+	  if (h != NULL
+	      && s390_is_ifunc_symbol_p (h)
+	      && h->def_regular
+	      && !bfd_link_executable (info))
+	    {
+	      relocation = (htab->elf.iplt->output_section->vma
+			    + htab->elf.iplt->output_offset
+			    + h->plt.offset
+			    - htab->elf.sgot->output_section->vma);
+	      goto do_relocation;
+	    }
+
 	  /* Note that sgot->output_offset is not involved in this
 	     calculation.  We always want the start of .got.  If we
 	     defined _GLOBAL_OFFSET_TABLE in a different way, as is
-- 
1.9.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]