aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-runtime.c
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2020-05-27 12:54:21 -0700
committerVineet Gupta <vgupta@synopsys.com>2020-06-05 13:45:46 -0700
commit8dbb7a08ec52057819db4ee234f9429ab99eb4ae (patch)
tree5bf2d690342fc287e1b501de367fa1849505a52c /elf/dl-runtime.c
parenta23bd00f9d810c28d9e83ce1d7cf53968375937d (diff)
downloadglibc-8dbb7a08ec52057819db4ee234f9429ab99eb4ae.zip
glibc-8dbb7a08ec52057819db4ee234f9429ab99eb4ae.tar.gz
glibc-8dbb7a08ec52057819db4ee234f9429ab99eb4ae.tar.bz2
dl-runtime: reloc_{offset,index} now functions arch overide'able
The existing macros are fragile and expect local variables with a certain name. Fix this by defining them as functions with default implementation in a new header dl-runtime.h which arches can override if need be. This came up during ARC port review, hence the need for argument pltgot in reloc_index() which is not needed by existing ports. This patch potentially only affects hppa/x86 ports, build tested for both those configs and a few more. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Diffstat (limited to 'elf/dl-runtime.c')
-rw-r--r--elf/dl-runtime.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index cf5f1d3..85a229f 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -27,6 +27,7 @@
#include "dynamic-link.h"
#include <tls.h>
#include <dl-irel.h>
+#include <dl-runtime.h>
#if (!ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \
@@ -42,13 +43,6 @@
# define ARCH_FIXUP_ATTRIBUTE
#endif
-#ifndef reloc_offset
-# define reloc_offset reloc_arg
-# define reloc_index reloc_arg / sizeof (PLTREL)
-#endif
-
-
-
/* This function is called through a special trampoline from the PLT the
first time each PLT entry is called. We must perform the relocation
specified in the PLT of the given shared object, and return the resolved
@@ -68,8 +62,11 @@ _dl_fixup (
= (const void *) D_PTR (l, l_info[DT_SYMTAB]);
const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
+ const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
+
const PLTREL *const reloc
- = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
+ = (const void *) (D_PTR (l, l_info[DT_JMPREL])
+ + reloc_offset (pltgot, reloc_arg));
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);
@@ -180,9 +177,12 @@ _dl_profile_fixup (
l, reloc_arg);
}
+ const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
+
/* This is the address in the array where we store the result of previous
relocations. */
- struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
+ struct reloc_result *reloc_result
+ = &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
/* CONCURRENCY NOTES:
@@ -219,8 +219,11 @@ _dl_profile_fixup (
= (const void *) D_PTR (l, l_info[DT_SYMTAB]);
const char *strtab = (const char *) D_PTR (l, l_info[DT_STRTAB]);
+ const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
+
const PLTREL *const reloc
- = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
+ = (const void *) (D_PTR (l, l_info[DT_JMPREL])
+ + reloc_offset (pltgot, reloc_arg));
const ElfW(Sym) *refsym = &symtab[ELFW(R_SYM) (reloc->r_info)];
const ElfW(Sym) *defsym = refsym;
lookup_t result;
@@ -485,11 +488,14 @@ _dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
const void *inregs, void *outregs)
{
#ifdef SHARED
+ const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
+
/* This is the address in the array where we store the result of previous
relocations. */
// XXX Maybe the bound information must be stored on the stack since
// XXX with bind_not a new value could have been stored in the meantime.
- struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
+ struct reloc_result *reloc_result =
+ &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
l_info[DT_SYMTAB])
+ reloc_result->boundndx);