about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog37
-rw-r--r--elf/dl-runtime.c3
-rw-r--r--elf/elf.h3
-rw-r--r--elf/testobj6.c3
-rw-r--r--sysdeps/aarch64/dl-machine.h1
-rw-r--r--sysdeps/alpha/dl-machine.h5
-rw-r--r--sysdeps/arm/dl-machine.h1
-rw-r--r--sysdeps/generic/dl-machine.h7
-rw-r--r--sysdeps/hppa/dl-machine.h5
-rw-r--r--sysdeps/i386/dl-machine.h1
-rw-r--r--sysdeps/ia64/dl-machine.h3
-rw-r--r--sysdeps/m68k/dl-machine.h1
-rw-r--r--sysdeps/microblaze/dl-machine.h1
-rw-r--r--sysdeps/mips/dl-machine.h1
-rw-r--r--sysdeps/nios2/dl-machine.h1
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.h1
-rw-r--r--sysdeps/powerpc/powerpc64/dl-machine.c24
-rw-r--r--sysdeps/powerpc/powerpc64/dl-machine.h54
-rw-r--r--sysdeps/s390/s390-32/dl-machine.h1
-rw-r--r--sysdeps/s390/s390-64/dl-machine.h1
-rw-r--r--sysdeps/sh/dl-machine.h1
-rw-r--r--sysdeps/sparc/sparc32/dl-machine.h1
-rw-r--r--sysdeps/sparc/sparc64/dl-machine.h1
-rw-r--r--sysdeps/tile/dl-machine.h3
-rw-r--r--sysdeps/x86_64/dl-machine.h1
25 files changed, 124 insertions, 37 deletions
diff --git a/ChangeLog b/ChangeLog
index af5756112d..a06a70c939 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,42 @@
 2017-06-14  Alan Modra  <amodra@gmail.com>
 
+	* elf/elf.h (PPC64_OPT_LOCALENTRY): Define.
+	* sysdeps/alpha/dl-machine.h (elf_machine_fixup_plt): Add
+	refsym and sym parameters.  Adjust callers.
+	* sysdeps/aarch64/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/arm/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/generic/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/hppa/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/i386/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/ia64/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/m68k/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/microblaze/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/mips/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/nios2/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/powerpc/powerpc32/dl-machine.h (elf_machine_fixup_plt):
+	Likewise.
+	* sysdeps/s390/s390-32/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/s390/s390-64/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/sh/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/sparc/sparc32/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/sparc/sparc64/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/tile/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/x86_64/dl-machine.h (elf_machine_fixup_plt): Likewise.
+	* sysdeps/powerpc/powerpc64/dl-machine.c (_dl_error_localentry): New.
+	(_dl_reloc_overflow): Increase buffser size.  Formatting.
+	* sysdeps/powerpc/powerpc64/dl-machine.h (ppc64_local_entry_offset):
+	Delete reloc param, add refsym and sym.  Check optimized plt
+	call stubs for localentry:0 functions.  Adjust callers.
+	(elf_machine_fixup_plt, elf_machine_plt_conflict): Add refsym
+	and sym parameters.  Adjust callers.
+	(_dl_reloc_overflow): Move attribute.
+	(_dl_error_localentry): Declare.
+	* elf/dl-runtime.c (_dl_fixup): Save original sym.  Pass
+	refsym and sym to elf_machine_fixup_plt.
+	* elf/testobj6.c (preload): Call printf.
+
+2017-06-14  Alan Modra  <amodra@gmail.com>
+
 	* sysdeps/powerpc/powerpc64/sysdep.h: Formatting.
 	(NOPS, ENTRY_3): New macros.
 	(ENTRY): Rewrite.
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index 7d1d240403..51d3819d4a 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -71,6 +71,7 @@ _dl_fixup (
   const PLTREL *const reloc
     = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
   const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
+  const ElfW(Sym) *refsym = sym;
   void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
   lookup_t result;
   DL_FIXUP_VALUE_TYPE value;
@@ -145,7 +146,7 @@ _dl_fixup (
   if (__glibc_unlikely (GLRO(dl_bind_not)))
     return value;
 
-  return elf_machine_fixup_plt (l, result, reloc, rel_addr, value);
+  return elf_machine_fixup_plt (l, result, refsym, sym, reloc, rel_addr, value);
 }
 
 #ifndef PROF
diff --git a/elf/elf.h b/elf/elf.h
index fff893d433..3900b4c9f0 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -2544,9 +2544,10 @@ enum
 #define DT_PPC64_OPT	(DT_LOPROC + 3)
 #define DT_PPC64_NUM    4
 
-/* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry.  */
+/* PowerPC64 specific bits in the DT_PPC64_OPT Dyn entry.  */
 #define PPC64_OPT_TLS		1
 #define PPC64_OPT_MULTI_TOC	2
+#define PPC64_OPT_LOCALENTRY	4
 
 /* PowerPC64 specific values for the Elf64_Sym st_other field.  */
 #define STO_PPC64_LOCAL_BIT	5
diff --git a/elf/testobj6.c b/elf/testobj6.c
index fcba01631d..84da4c9e22 100644
--- a/elf/testobj6.c
+++ b/elf/testobj6.c
@@ -1,3 +1,5 @@
+#include <stdio.h>
+
 #include "testobj.h"
 
 int
@@ -15,5 +17,6 @@ obj6func2 (int a)
 int
 preload (int a)
 {
+  printf ("testobj6 preload\n");
   return a;
 }
diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
index 15d79a6961..02fab04f40 100644
--- a/sysdeps/aarch64/dl-machine.h
+++ b/sysdeps/aarch64/dl-machine.h
@@ -245,6 +245,7 @@ dl_platform_init (void)
 
 static inline ElfW(Addr)
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const ElfW(Rela) *reloc,
 		       ElfW(Addr) *reloc_addr,
 		       ElfW(Addr) value)
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h
index 7580cd29b6..7077796d2e 100644
--- a/sysdeps/alpha/dl-machine.h
+++ b/sysdeps/alpha/dl-machine.h
@@ -260,6 +260,7 @@ dl_platform_init (void)
    rather than the dynamic linker.  */
 static inline Elf64_Addr
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf64_Rela *reloc,
 		       Elf64_Addr *got_addr, Elf64_Addr value)
 {
@@ -434,11 +435,11 @@ elf_machine_rela (struct link_map *map,
 	  RESOLVE_CONFLICT_FIND_MAP (map, reloc_addr);
 	  reloc = ((const Elf64_Rela *) D_PTR (map, l_info[DT_JMPREL]))
 		  + (r_type >> 8);
-	  elf_machine_fixup_plt (map, 0, reloc, reloc_addr, sym_value);
+	  elf_machine_fixup_plt (map, 0, 0, 0, reloc, reloc_addr, sym_value);
 	}
 #else
       else if (r_type == R_ALPHA_JMP_SLOT)
-	elf_machine_fixup_plt (map, 0, reloc, reloc_addr, sym_value);
+	elf_machine_fixup_plt (map, 0, 0, 0, reloc, reloc_addr, sym_value);
 #endif
 #ifndef RTLD_BOOTSTRAP
       else if (r_type == R_ALPHA_REFQUAD)
diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
index 2c72972bd2..7053ead16e 100644
--- a/sysdeps/arm/dl-machine.h
+++ b/sysdeps/arm/dl-machine.h
@@ -263,6 +263,7 @@ dl_platform_init (void)
 
 static inline Elf32_Addr
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rel *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
 {
diff --git a/sysdeps/generic/dl-machine.h b/sysdeps/generic/dl-machine.h
index 59749bd84f..41537601d2 100644
--- a/sysdeps/generic/dl-machine.h
+++ b/sysdeps/generic/dl-machine.h
@@ -51,10 +51,11 @@ elf_machine_load_address (void)
 
 /* Fixup a PLT entry to bounce directly to the function at VALUE.  */
 
-static inline Elf32_Addr
+static inline ElfW(Addr)
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
-		       const Elf32_Rel *reloc,
-		       Elf32_Addr *reloc_addr, Elf32_Addr value)
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
+		       const ElfW(Rel) *reloc,
+		       ElfW(Addr) *reloc_addr, ElfW(Addr) value)
 {
   return *reloc_addr = value;
 }
diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h
index 787b95f502..b7bdf871f1 100644
--- a/sysdeps/hppa/dl-machine.h
+++ b/sysdeps/hppa/dl-machine.h
@@ -112,6 +112,7 @@ elf_machine_load_address (void)
 /* Fixup a PLT entry to bounce directly to the function at VALUE. */
 static inline struct fdesc __attribute__ ((always_inline))
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, struct fdesc value)
 {
@@ -652,13 +653,13 @@ elf_machine_rela (struct link_map *map,
     case R_PARISC_IPLT:
       if (__builtin_expect (sym_map != NULL, 1))
 	{
-	  elf_machine_fixup_plt (NULL, sym_map, reloc, reloc_addr,
+	  elf_machine_fixup_plt (NULL, sym_map, NULL, NULL reloc, reloc_addr,
 				 DL_FIXUP_MAKE_VALUE(sym_map, value));
 	}
       else
 	{
 	  /* If we get here, it's a (weak) undefined sym.  */
-	  elf_machine_fixup_plt (NULL, map, reloc, reloc_addr,
+	  elf_machine_fixup_plt (NULL, map, NULL, NULL, reloc, reloc_addr,
 				 DL_FIXUP_MAKE_VALUE(map, value));
 	}
       return;
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
index 57d4a0bdbd..9ee9d02c36 100644
--- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h
@@ -246,6 +246,7 @@ dl_platform_init (void)
 
 static inline Elf32_Addr
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rel *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
 {
diff --git a/sysdeps/ia64/dl-machine.h b/sysdeps/ia64/dl-machine.h
index 9c08161d65..8d0d3c97dd 100644
--- a/sysdeps/ia64/dl-machine.h
+++ b/sysdeps/ia64/dl-machine.h
@@ -333,6 +333,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 /* Fixup a PLT entry to bounce directly to the function at VALUE.  */
 static inline struct fdesc __attribute__ ((always_inline))
 elf_machine_fixup_plt (struct link_map *l, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf64_Rela *reloc,
 		       Elf64_Addr *reloc_addr, struct fdesc value)
 {
@@ -424,7 +425,7 @@ elf_machine_rela (struct link_map *map,
 	    ;/* No adjustment.  */
 	  else if (r_type == R_IA64_IPLTLSB)
 	    {
-	      elf_machine_fixup_plt (NULL, NULL, reloc, reloc_addr,
+	      elf_machine_fixup_plt (NULL, NULL, NULL, NULL, reloc, reloc_addr,
 				     DL_FIXUP_MAKE_VALUE (sym_map, value));
 	      return;
 	    }
diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h
index 8f457cea5a..fd8fb00103 100644
--- a/sysdeps/m68k/dl-machine.h
+++ b/sysdeps/m68k/dl-machine.h
@@ -182,6 +182,7 @@ _dl_start_user:\n\
 
 static inline Elf32_Addr
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
 {
diff --git a/sysdeps/microblaze/dl-machine.h b/sysdeps/microblaze/dl-machine.h
index cc80b30868..9481ff1efa 100644
--- a/sysdeps/microblaze/dl-machine.h
+++ b/sysdeps/microblaze/dl-machine.h
@@ -174,6 +174,7 @@ _dl_start_user:\n\
 
 static inline Elf32_Addr
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
 {
diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h
index ed47513ccc..74ead7f524 100644
--- a/sysdeps/mips/dl-machine.h
+++ b/sysdeps/mips/dl-machine.h
@@ -453,6 +453,7 @@ dl_platform_init (void)
    the corresponding PLT entry instead.  */
 static inline ElfW(Addr)
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const ElfW(Rel) *reloc,
 		       ElfW(Addr) *reloc_addr, ElfW(Addr) value)
 {
diff --git a/sysdeps/nios2/dl-machine.h b/sysdeps/nios2/dl-machine.h
index 8d2b18de23..b5fdd9b2bd 100644
--- a/sysdeps/nios2/dl-machine.h
+++ b/sysdeps/nios2/dl-machine.h
@@ -207,6 +207,7 @@ _start:\n\
 
 static inline Elf32_Addr
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
 {
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
index 28eb50f92d..1f8437ed9c 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
@@ -235,6 +235,7 @@ extern Elf32_Addr __elf_machine_fixup_plt (struct link_map *map,
 
 static inline Elf32_Addr
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf64_Addr finaladdr)
 {
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.c b/sysdeps/powerpc/powerpc64/dl-machine.c
index 0eccc6621a..2cfd43b21b 100644
--- a/sysdeps/powerpc/powerpc64/dl-machine.c
+++ b/sysdeps/powerpc/powerpc64/dl-machine.c
@@ -24,11 +24,11 @@
 
 void
 _dl_reloc_overflow (struct link_map *map,
-		   const char *name,
-		   Elf64_Addr *const reloc_addr,
-		   const Elf64_Sym *refsym)
+		    const char *name,
+		    Elf64_Addr *const reloc_addr,
+		    const Elf64_Sym *refsym)
 {
-  char buffer[128];
+  char buffer[1024];
   char *t;
   t = stpcpy (buffer, name);
   t = stpcpy (t, " reloc at 0x");
@@ -45,3 +45,19 @@ _dl_reloc_overflow (struct link_map *map,
   t = stpcpy (t, " out of range");
   _dl_signal_error (0, map->l_name, NULL, buffer);
 }
+
+#if _CALL_ELF == 2
+void
+_dl_error_localentry (struct link_map *map, const Elf64_Sym *refsym)
+{
+  char buffer[1024];
+  char *t;
+  const char *strtab;
+
+  strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
+  t = stpcpy (buffer, "expected localentry:0 `");
+  t = stpcpy (t, strtab + refsym->st_name);
+  t = stpcpy (t, "'");
+  _dl_signal_error (0, map->l_name, NULL, buffer);
+}
+#endif
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
index 6391b3a558..aeb91b8f69 100644
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
@@ -440,20 +440,30 @@ elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
 }
 
 #if _CALL_ELF == 2
-/* If the PLT entry whose reloc is 'reloc' resolves to a function in
-   the same object, return the target function's local entry point
-   offset if usable.  */
+extern void attribute_hidden _dl_error_localentry (struct link_map *map,
+						   const Elf64_Sym *refsym);
+
+/* If the PLT entry resolves to a function in the same object, return
+   the target function's local entry point offset if usable.  */
 static inline Elf64_Addr __attribute__ ((always_inline))
 ppc64_local_entry_offset (struct link_map *map, lookup_t sym_map,
-			  const Elf64_Rela *reloc)
+			  const ElfW(Sym) *refsym, const ElfW(Sym) *sym)
 {
-  const Elf64_Sym *symtab;
-  const Elf64_Sym *sym;
-
   /* If the target function is in a different object, we cannot
      use the local entry point.  */
   if (sym_map != map)
-    return 0;
+    {
+      /* Check that optimized plt call stubs for localentry:0 functions
+	 are not being satisfied by a non-zero localentry symbol.  */
+      if (map->l_info[DT_PPC64(OPT)]
+	  && (map->l_info[DT_PPC64(OPT)]->d_un.d_val & PPC64_OPT_LOCALENTRY) != 0
+	  && refsym->st_info == ELFW(ST_INFO) (STB_GLOBAL, STT_FUNC)
+	  && (STO_PPC64_LOCAL_MASK & refsym->st_other) == 0
+	  && (STO_PPC64_LOCAL_MASK & sym->st_other) != 0)
+	_dl_error_localentry (map, refsym);
+
+      return 0;
+    }
 
   /* If the linker inserted multiple TOCs, we cannot use the
      local entry point.  */
@@ -461,16 +471,13 @@ ppc64_local_entry_offset (struct link_map *map, lookup_t sym_map,
       && (map->l_info[DT_PPC64(OPT)]->d_un.d_val & PPC64_OPT_MULTI_TOC))
     return 0;
 
-  /* Otherwise, we can use the local entry point.  Retrieve its offset
-     from the symbol's ELF st_other field.  */
-  symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
-  sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
-
   /* If the target function is an ifunc then the local entry offset is
      for the resolver, not the final destination.  */
   if (__builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0))
     return 0;
 
+  /* Otherwise, we can use the local entry point.  Retrieve its offset
+     from the symbol's ELF st_other field.  */
   return PPC64_LOCAL_ENTRY_OFFSET (sym->st_other);
 }
 #endif
@@ -479,6 +486,7 @@ ppc64_local_entry_offset (struct link_map *map, lookup_t sym_map,
    routine.  */
 static inline Elf64_Addr __attribute__ ((always_inline))
 elf_machine_fixup_plt (struct link_map *map, lookup_t sym_map,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf64_Rela *reloc,
 		       Elf64_Addr *reloc_addr, Elf64_Addr finaladdr)
 {
@@ -534,7 +542,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t sym_map,
   PPC_DCBST (&plt->fd_func);
   PPC_ISYNC;
 #else
-  finaladdr += ppc64_local_entry_offset (map, sym_map, reloc);
+  finaladdr += ppc64_local_entry_offset (map, sym_map, refsym, sym);
   *reloc_addr = finaladdr;
 #endif
 
@@ -543,6 +551,7 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t sym_map,
 
 static inline void __attribute__ ((always_inline))
 elf_machine_plt_conflict (struct link_map *map, lookup_t sym_map,
+			  const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 			  const Elf64_Rela *reloc,
 			  Elf64_Addr *reloc_addr, Elf64_Addr finaladdr)
 {
@@ -565,7 +574,7 @@ elf_machine_plt_conflict (struct link_map *map, lookup_t sym_map,
   PPC_DCBST (&plt->fd_toc);
   PPC_SYNC;
 #else
-  finaladdr += ppc64_local_entry_offset (map, sym_map, reloc);
+  finaladdr += ppc64_local_entry_offset (map, sym_map, refsym, sym);
   *reloc_addr = finaladdr;
 #endif
 }
@@ -604,11 +613,10 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
 
 #define dont_expect(X) __builtin_expect ((X), 0)
 
-extern void _dl_reloc_overflow (struct link_map *map,
-				const char *name,
-				Elf64_Addr *const reloc_addr,
-				const Elf64_Sym *refsym)
-				attribute_hidden;
+extern void attribute_hidden _dl_reloc_overflow (struct link_map *map,
+						 const char *name,
+						 Elf64_Addr *const reloc_addr,
+						 const Elf64_Sym *refsym);
 
 auto inline void __attribute__ ((always_inline))
 elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
@@ -728,9 +736,11 @@ elf_machine_rela (struct link_map *map,
       /* Fall thru */
     case R_PPC64_JMP_SLOT:
 #ifdef RESOLVE_CONFLICT_FIND_MAP
-      elf_machine_plt_conflict (map, sym_map, reloc, reloc_addr, value);
+      elf_machine_plt_conflict (map, sym_map, refsym, sym,
+				reloc, reloc_addr, value);
 #else
-      elf_machine_fixup_plt (map, sym_map, reloc, reloc_addr, value);
+      elf_machine_fixup_plt (map, sym_map, refsym, sym,
+			     reloc, reloc_addr, value);
 #endif
       return;
 
diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h
index 2e3c77c58e..c302c9d2ce 100644
--- a/sysdeps/s390/s390-32/dl-machine.h
+++ b/sysdeps/s390/s390-32/dl-machine.h
@@ -294,6 +294,7 @@ dl_platform_init (void)
 
 static inline Elf32_Addr
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
 {
diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h
index f2aeb1e78e..7513520417 100644
--- a/sysdeps/s390/s390-64/dl-machine.h
+++ b/sysdeps/s390/s390-64/dl-machine.h
@@ -242,6 +242,7 @@ dl_platform_init (void)
 
 static inline Elf64_Addr
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf64_Rela *reloc,
 		       Elf64_Addr *reloc_addr, Elf64_Addr value)
 {
diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h
index 2b468af6fa..7106afbdbd 100644
--- a/sysdeps/sh/dl-machine.h
+++ b/sysdeps/sh/dl-machine.h
@@ -230,6 +230,7 @@ dl_platform_init (void)
 
 static inline Elf32_Addr
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
 {
diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
index 95f673270e..436e4e6cc3 100644
--- a/sysdeps/sparc/sparc32/dl-machine.h
+++ b/sysdeps/sparc/sparc32/dl-machine.h
@@ -294,6 +294,7 @@ _dl_start_user:\n\
 
 static inline Elf32_Addr
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf32_Addr value)
 {
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
index 1b59d78a25..c2871dca3a 100644
--- a/sysdeps/sparc/sparc64/dl-machine.h
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -85,6 +85,7 @@ elf_machine_load_address (void)
 
 static inline Elf64_Addr __attribute__ ((always_inline))
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const Elf64_Rela *reloc,
 		       Elf64_Addr *reloc_addr, Elf64_Addr value)
 {
diff --git a/sysdeps/tile/dl-machine.h b/sysdeps/tile/dl-machine.h
index c1d784548c..ae92673ac8 100644
--- a/sysdeps/tile/dl-machine.h
+++ b/sysdeps/tile/dl-machine.h
@@ -239,6 +239,7 @@ dl_platform_init (void)
 
 static inline ElfW(Addr)
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const ElfW(Rela) *reloc,
 		       ElfW(Addr) *reloc_addr, ElfW(Addr) value)
 {
@@ -569,7 +570,7 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
   switch (r_type)
     {
     case R_TILE(JMP_SLOT):
-      elf_machine_fixup_plt (map, 0, reloc, reloc_addr,
+      elf_machine_fixup_plt (map, 0, 0, 0, reloc, reloc_addr,
                              value + reloc->r_addend);
       return;
 
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index 0015db4d6a..6a04cbcdc9 100644
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -253,6 +253,7 @@ dl_platform_init (void)
 
 static inline ElfW(Addr)
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
 		       const ElfW(Rela) *reloc,
 		       ElfW(Addr) *reloc_addr, ElfW(Addr) value)
 {