aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2017-06-14 10:47:25 +0930
committerAlan Modra <amodra@gmail.com>2017-06-14 10:47:25 +0930
commit0572433b5beb636de1a49ec6b4fdab830c38cdc5 (patch)
tree718b3b7cd3011961b409a8233dfac4f2b0c6c487
parentd5b411854f0a3135c931921dfa8a33af395acfd3 (diff)
downloadglibc-0572433b5beb636de1a49ec6b4fdab830c38cdc5.zip
glibc-0572433b5beb636de1a49ec6b4fdab830c38cdc5.tar.gz
glibc-0572433b5beb636de1a49ec6b4fdab830c38cdc5.tar.bz2
PowerPC64 ELFv2 PPC64_OPT_LOCALENTRY
ELFv2 functions with localentry:0 are those with a single entry point, ie. global entry == local entry, that have no requirement on r2 or r12 and guarantee r2 is unchanged on return. Such an external function can be called via the PLT without saving r2 or restoring it on return, avoiding a common load-hit-store for small functions. This patch implements the ld.so changes necessary for this optimization. ld.so needs to check that an optimized plt call sequence is in fact calling a function implemented with localentry:0, end emit a fatal error otherwise. The elf/testobj6.c change is to stop "error while loading shared libraries: expected localentry:0 `preload'" when running elf/preloadtest, which we'd get otherwise. * 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.
-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 af57561..a06a70c 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 7d1d240..51d3819 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 fff893d..3900b4c 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 fcba016..84da4c9 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 15d79a6..02fab04 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 7580cd2..7077796 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 2c72972..7053ead 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 59749bd..4153760 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 787b95f..b7bdf87 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 57d4a0b..9ee9d02 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 9c08161..8d0d3c9 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 8f457ce..fd8fb00 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 cc80b30..9481ff1 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 ed47513..74ead7f 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 8d2b18d..b5fdd9b 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 28eb50f..1f8437e 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 0eccc66..2cfd43b 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 6391b3a..aeb91b8 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 2e3c77c..c302c9d 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 f2aeb1e..7513520 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 2b468af..7106afb 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 95f6732..436e4e6 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 1b59d78..c2871dc 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 c1d7845..ae92673 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 0015db4..6a04cbc 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)
{