+++ /dev/null
-From 1490e715e95d3cf6ba0321a59f6d27413ea4e131 Mon Sep 17 00:00:00 2001
-From: Salvatore Cro <salvatore.cro@st.com>
-Date: Wed, 12 Jan 2011 10:27:16 +0100
-Subject: [PATCH 4/5] Add protected symbols support for all architectures
-
-Protected symbols are global symbols for which interposition is not allowed.
-We manage them in generic _dl_lookup_hash function. To handle protected symbols
-we need to get a reference to the module that defines the symbol itself.
-So we pass a new parameter 'struct symbol_ref' to the __dl_lookup_hash
-that is defined as below:
-
-struct symbol_ref {
- const ElfW(Sym) *sym;
- struct elf_resolve *tpnt;
-};
-
-The tpnt field is used as an ouput parameter and refers to the module which defines
-the protected symbol.
-Further it can be used as output parameter for TLS relocations and FDPIC case.
-The sym field is instead used as an input parameter to detect the visibility of the
-symbol we are looking-up.
-In this way we get rid of different signatures for _dl_lookup_hash, allowing to remove
-the _dl_find_hash wrapper.
-This new structure is also suitable for prelink integration.
-
-Signed-off-by: Salvatore Cro <salvatore.cro@st.com>
-Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
----
- ldso/include/dl-hash.h | 16 ++++++++--------
- ldso/ldso/arm/elfinterp.c | 6 +++++-
- ldso/ldso/avr32/elfinterp.c | 13 +++++++------
- ldso/ldso/bfin/elfinterp.c | 18 ++++++++++++------
- ldso/ldso/cris/elfinterp.c | 5 ++++-
- ldso/ldso/dl-hash.c | 20 ++++++++++++--------
- ldso/ldso/i386/elfinterp.c | 6 +++++-
- ldso/ldso/m68k/elfinterp.c | 15 ++++++++-------
- ldso/ldso/mips/elfinterp.c | 6 +++++-
- ldso/ldso/powerpc/elfinterp.c | 20 +++++++++++---------
- ldso/ldso/sh/elfinterp.c | 10 +++++++---
- ldso/ldso/sh64/elfinterp.c | 7 +++++--
- ldso/ldso/sparc/elfinterp.c | 24 +++++++++++++-----------
- ldso/ldso/x86_64/elfinterp.c | 20 +++++++++++---------
- ldso/ldso/xtensa/elfinterp.c | 11 ++++++-----
- ldso/libdl/libdl.c | 7 ++++---
- 16 files changed, 123 insertions(+), 81 deletions(-)
-
-diff --git a/ldso/include/dl-hash.h b/ldso/include/dl-hash.h
-index 34bed1b..d1f9acc 100644
---- a/ldso/include/dl-hash.h
-+++ b/ldso/include/dl-hash.h
-@@ -25,6 +25,11 @@ struct dyn_elf {
- struct dyn_elf * prev;
- };
-
-+struct symbol_ref {
-+ const ElfW(Sym) *sym;
-+ struct elf_resolve *tpnt;
-+};
-+
- struct elf_resolve {
- /* These entries must be in this order to be compatible with the interface used
- by gdb to obtain the list of symbols. */
-@@ -137,19 +142,14 @@ extern struct elf_resolve * _dl_add_elf_hash_table(const char * libname,
- DL_LOADADDR_TYPE loadaddr, unsigned long * dynamic_info,
- unsigned long dynamic_addr, unsigned long dynamic_size);
-
--/* Only need extra arg with some configurations */
--#if !((defined(USE_TLS) && USE_TLS) || defined __FDPIC__)
--# define _dl_lookup_hash(n, r, m, c, tpntp) _dl_lookup_hash(n, r, m, c)
--# define _dl_find_hash(n, r, m, t, tpntp) _dl_find_hash(n, r, m, t)
--#endif
- extern char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt,
- struct elf_resolve *mytpnt, int type_class,
-- struct elf_resolve **tpntp);
-+ struct symbol_ref *symbol);
- static __always_inline char *_dl_find_hash(const char *name, struct dyn_elf *rpnt,
- struct elf_resolve *mytpnt, int type_class,
-- struct elf_resolve **tpntp)
-+ struct symbol_ref *symbol)
- {
-- return _dl_lookup_hash(name, rpnt, mytpnt, type_class, tpntp);
-+ return _dl_lookup_hash(name, rpnt, mytpnt, type_class, symbol);
- }
-
- extern int _dl_linux_dynamic_link(void);
-diff --git a/ldso/ldso/arm/elfinterp.c b/ldso/ldso/arm/elfinterp.c
-index 9bbf92c..707b317 100644
---- a/ldso/ldso/arm/elfinterp.c
-+++ b/ldso/ldso/arm/elfinterp.c
-@@ -189,6 +189,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
- unsigned long *reloc_addr;
- unsigned long symbol_addr;
- const Elf32_Sym *def = 0;
-+ struct symbol_ref sym_ref;
- struct elf_resolve *def_mod = 0;
- int goof = 0;
-
-@@ -197,10 +198,12 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
- reloc_type = ELF32_R_TYPE(rpnt->r_info);
- symtab_index = ELF32_R_SYM(rpnt->r_info);
- symbol_addr = 0;
-+ sym_ref.sym = &symtab[symtab_index];
-+ sym_ref.tpnt = NULL;
-
- if (symtab_index) {
- symbol_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name,
-- scope, tpnt, elf_machine_type_class(reloc_type), &def_mod);
-+ scope, tpnt, elf_machine_type_class(reloc_type), &sym_ref);
-
- /*
- * We want to allow undefined references to weak symbols - this might
-@@ -213,6 +216,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
- return 1;
-
- }
-+ def_mod = sym_ref.tpnt;
- } else {
- /*
- * Relocs against STN_UNDEF are usually treated as using a
-diff --git a/ldso/ldso/avr32/elfinterp.c b/ldso/ldso/avr32/elfinterp.c
-index 797f851..2d0dbf3 100644
---- a/ldso/ldso/avr32/elfinterp.c
-+++ b/ldso/ldso/avr32/elfinterp.c
-@@ -50,9 +50,8 @@ unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got)
- strtab = (char *)(tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
- symname = strtab + sym->st_name;
-
-- new_addr = (unsigned long) _dl_find_hash(strtab + sym->st_name,
-- tpnt->symbol_scope, tpnt,
-- resolver);
-+ new_addr = (unsigned long) _dl_find_hash(symname,
-+ tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL);
-
- entry = (unsigned long *)(got + local_gotno + sym_index - gotsym);
- *entry = new_addr;
-@@ -127,18 +126,20 @@ static int _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- #if defined(__SUPPORT_LD_DEBUG__)
- unsigned long old_val;
- #endif
-+ struct symbol_ref sym_ref;
-
- reloc_addr = (unsigned long *)(tpnt->loadaddr + rpnt->r_offset);
- reloc_type = ELF32_R_TYPE(rpnt->r_info);
- symtab_index = ELF32_R_SYM(rpnt->r_info);
- symbol_addr = 0;
-+ sym_ref.sym = &symtab[symtab_index];
-+ sym_ref.tpnt = NULL;
- symname = strtab + symtab[symtab_index].st_name;
-
- if (symtab_index) {
- symbol_addr = (unsigned long)
-- _dl_find_hash(strtab + symtab[symtab_index].st_name,
-- tpnt->symbol_scope, tpnt,
-- elf_machine_type_class(reloc_type), NULL);
-+ _dl_find_hash(symname, scope, tpnt,
-+ elf_machine_type_class(reloc_type), &sym_ref);
-
- /* Allow undefined references to weak symbols */
- if (!symbol_addr &&
-diff --git a/ldso/ldso/bfin/elfinterp.c b/ldso/ldso/bfin/elfinterp.c
-index e8d88bd..5accbfc 100644
---- a/ldso/ldso/bfin/elfinterp.c
-+++ b/ldso/ldso/bfin/elfinterp.c
-@@ -46,11 +46,11 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
- ElfW(Sym) *symtab;
- int symtab_index;
- char *rel_addr;
-- struct elf_resolve *new_tpnt;
- char *new_addr;
- struct funcdesc_value funcval;
- struct funcdesc_value volatile *got_entry;
- char *symname;
-+ struct symbol_ref sym_ref;
-
- rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL];
-
-@@ -59,15 +59,17 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
-
- symtab = (Elf32_Sym *) tpnt->dynamic_info[DT_SYMTAB];
- strtab = (char *) tpnt->dynamic_info[DT_STRTAB];
-+ sym_ref.sym = &symtab[symtab_index];
-+ sym_ref.tpnt = NULL;
- symname= strtab + symtab[symtab_index].st_name;
-
- /* Address of GOT entry fix up */
- got_entry = (struct funcdesc_value *) DL_RELOC_ADDR(tpnt->loadaddr, this_reloc->r_offset);
-
- /* Get the address to be used to fill in the GOT entry. */
-- new_addr = _dl_lookup_hash(symname, tpnt->symbol_scope, NULL, 0, &new_tpnt);
-+ new_addr = _dl_lookup_hash(symname, tpnt->symbol_scope, NULL, 0, &sym_ref);
- if (!new_addr) {
-- new_addr = _dl_lookup_hash(symname, NULL, NULL, 0, &new_tpnt);
-+ new_addr = _dl_lookup_hash(symname, NULL, NULL, 0, &sym_ref);
- if (!new_addr) {
- _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
- _dl_progname, symname);
-@@ -76,7 +78,7 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
- }
-
- funcval.entry_point = new_addr;
-- funcval.got_value = new_tpnt->loadaddr.got_value;
-+ funcval.got_value = sym_ref.tpnt->loadaddr.got_value;
-
- #if defined (__SUPPORT_LD_DEBUG__)
- if (_dl_debug_bindings) {
-@@ -165,12 +167,15 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
- #if defined (__SUPPORT_LD_DEBUG__)
- unsigned long old_val;
- #endif
-+ struct symbol_ref sym_ref;
-
- reloc_addr = (unsigned long *) DL_RELOC_ADDR(tpnt->loadaddr, rpnt->r_offset);
- __asm__ ("" : "=r" (reloc_addr_packed) : "0" (reloc_addr));
- reloc_type = ELF_R_TYPE(rpnt->r_info);
- symtab_index = ELF_R_SYM(rpnt->r_info);
- symbol_addr = 0;
-+ sym_ref.sym = &symtab[symtab_index];
-+ sym_ref.tpnt = NULL;
- symname = strtab + symtab[symtab_index].st_name;
-
- if (ELF_ST_BIND (symtab[symtab_index].st_info) == STB_LOCAL) {
-@@ -179,7 +184,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
- } else {
-
- symbol_addr = (unsigned long)
-- _dl_lookup_hash(symname, scope, NULL, 0, &symbol_tpnt);
-+ _dl_lookup_hash(symname, scope, NULL, 0, &sym_ref);
-
- /*
- * We want to allow undefined references to weak symbols - this might
-@@ -189,9 +194,10 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
-
- if (!symbol_addr && ELF_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK) {
- _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
-- _dl_progname, strtab + symtab[symtab_index].st_name);
-+ _dl_progname, symname);
- _dl_exit (1);
- }
-+ symbol_tpnt = sym_ref.tpnt;
- }
-
- #if defined (__SUPPORT_LD_DEBUG__)
-diff --git a/ldso/ldso/cris/elfinterp.c b/ldso/ldso/cris/elfinterp.c
-index 32ea2da..3cb8297 100644
---- a/ldso/ldso/cris/elfinterp.c
-+++ b/ldso/ldso/cris/elfinterp.c
-@@ -161,11 +161,14 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- #if defined (__SUPPORT_LD_DEBUG__)
- unsigned long old_val;
- #endif
-+ struct symbol_ref sym_ref;
-
- reloc_addr = (unsigned long *)(intptr_t)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
- reloc_type = ELF32_R_TYPE(rpnt->r_info);
- symtab_index = ELF32_R_SYM(rpnt->r_info);
- symbol_addr = 0;
-+ sym_ref.sym = &symtab[symtab_index];
-+ sym_ref.tpnt = NULL;
- symname = strtab + symtab[symtab_index].st_name;
-
- if (symtab_index) {
-@@ -174,7 +177,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- symbol_addr = (unsigned long)tpnt->loadaddr;
- } else {
- symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt,
-- elf_machine_type_class(reloc_type), NULL);
-+ elf_machine_type_class(reloc_type), &sym_ref);
- }
-
- if (unlikely(!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) {
-diff --git a/ldso/ldso/dl-hash.c b/ldso/ldso/dl-hash.c
-index 0048734..6db81a9 100644
---- a/ldso/ldso/dl-hash.c
-+++ b/ldso/ldso/dl-hash.c
-@@ -269,7 +269,7 @@ _dl_lookup_sysv_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long
- * relocations or when we call an entry in the PLT table for the first time.
- */
- char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve *mytpnt,
-- int type_class, struct elf_resolve **tpntp)
-+ int type_class, struct symbol_ref *sym_ref)
- {
- struct elf_resolve *tpnt = NULL;
- ElfW(Sym) *symtab;
-@@ -283,6 +283,11 @@ char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve
- unsigned long gnu_hash_number = _dl_gnu_hash((const unsigned char *)name);
- #endif
-
-+ if ((sym_ref) && (sym_ref->sym) && (ELF32_ST_VISIBILITY(sym_ref->sym->st_other) == STV_PROTECTED)) {
-+ sym = sym_ref->sym;
-+ if (mytpnt)
-+ tpnt = mytpnt;
-+ } else
- for (; rpnt; rpnt = rpnt->next) {
- tpnt = rpnt->dyn;
-
-@@ -337,9 +342,8 @@ char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve
- /* At this point we have found the requested symbol, do binding */
- #if defined(USE_TLS) && USE_TLS
- if (ELF_ST_TYPE(sym->st_info) == STT_TLS) {
-- _dl_assert(tpntp != NULL);
-- *tpntp = tpnt;
--
-+ _dl_assert(sym_ref != NULL);
-+ sym_ref->tpnt = tpnt;
- return (char *)sym->st_value;
- }
- #endif
-@@ -355,8 +359,8 @@ char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve
- #endif
- case STB_GLOBAL:
- #ifdef __FDPIC__
-- if (tpntp)
-- *tpntp = tpnt;
-+ if (sym_ref)
-+ sym_ref->tpnt = tpnt;
- #endif
- return (char *)DL_FIND_HASH_VALUE(tpnt, type_class, sym);
- default: /* Local symbols not handled here */
-@@ -364,8 +368,8 @@ char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve
- }
- }
- #ifdef __FDPIC__
-- if (tpntp)
-- *tpntp = tpnt;
-+ if (sym_ref)
-+ sym_ref->tpnt = tpnt;
- #endif
- return weak_result;
- }
-diff --git a/ldso/ldso/i386/elfinterp.c b/ldso/ldso/i386/elfinterp.c
-index a01c1d0..0017c23 100644
---- a/ldso/ldso/i386/elfinterp.c
-+++ b/ldso/ldso/i386/elfinterp.c
-@@ -168,16 +168,19 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- #if defined (__SUPPORT_LD_DEBUG__)
- unsigned long old_val;
- #endif
-+ struct symbol_ref sym_ref;
-
- reloc_addr = (unsigned long *)(intptr_t)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
- reloc_type = ELF32_R_TYPE(rpnt->r_info);
- symtab_index = ELF32_R_SYM(rpnt->r_info);
- symbol_addr = 0;
-+ sym_ref.sym = &symtab[symtab_index];
-+ sym_ref.tpnt = NULL;
- symname = strtab + symtab[symtab_index].st_name;
-
- if (symtab_index) {
- symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt,
-- elf_machine_type_class(reloc_type), &tls_tpnt);
-+ elf_machine_type_class(reloc_type), &sym_ref);
-
- /*
- * We want to allow undefined references to weak symbols - this
-@@ -187,6 +190,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- if (unlikely(!symbol_addr && (ELF_ST_TYPE(symtab[symtab_index].st_info) != STT_TLS)
- && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK))
- return 1;
-+ tls_tpnt = sym_ref.tpnt;
- } else {
- symbol_addr = symtab[symtab_index].st_value;
- tls_tpnt = tpnt;
-diff --git a/ldso/ldso/m68k/elfinterp.c b/ldso/ldso/m68k/elfinterp.c
-index 04c301e..3dfd50e 100644
---- a/ldso/ldso/m68k/elfinterp.c
-+++ b/ldso/ldso/m68k/elfinterp.c
-@@ -157,7 +157,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- int reloc_type;
- int symtab_index;
- char *symname;
-- ElfW(Sym) *sym;
-+ struct symbol_ref sym_ref;
- ElfW(Addr) *reloc_addr;
- ElfW(Addr) symbol_addr;
- #if defined (__SUPPORT_LD_DEBUG__)
-@@ -167,19 +167,20 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
- reloc_type = ELF_R_TYPE(rpnt->r_info);
- symtab_index = ELF_R_SYM(rpnt->r_info);
-- sym = &symtab[symtab_index];
-+ sym_ref.sym = &symtab[symtab_index];
-+ sym_ref.tpnt = NULL;
- symbol_addr = 0;
-- symname = strtab + sym->st_name;
-+ symname = strtab + sym_ref.sym->st_name;
-
- if (symtab_index) {
- symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt,
-- elf_machine_type_class(reloc_type), NULL);
-+ elf_machine_type_class(reloc_type), &sym_ref);
- /*
- * We want to allow undefined references to weak symbols - this
- * might have been intentional. We should not be linking local
- * symbols here, so all bases should be covered.
- */
-- if (unlikely(!symbol_addr && ELF_ST_BIND(sym->st_info) != STB_WEAK)) {
-+ if (unlikely(!symbol_addr && ELF_ST_BIND(sym_ref.sym->st_info) != STB_WEAK)) {
- _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname);
- _dl_exit(1);
- }
-@@ -230,12 +231,12 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- if (_dl_debug_move)
- _dl_dprintf(_dl_debug_file,
- "\t%s move %d bytes from %x to %x\n",
-- symname, sym->st_size,
-+ symname, sym_ref.sym->st_size,
- symbol_addr, reloc_addr);
- #endif
- _dl_memcpy ((void *) reloc_addr,
- (void *) symbol_addr,
-- sym->st_size);
-+ sym_ref.sym->st_size);
- } else
- _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n");
- break;
-diff --git a/ldso/ldso/mips/elfinterp.c b/ldso/ldso/mips/elfinterp.c
-index a56ee81..1c1489d 100644
---- a/ldso/ldso/mips/elfinterp.c
-+++ b/ldso/ldso/mips/elfinterp.c
-@@ -213,10 +213,14 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,
- # endif
- {
- struct elf_resolve *tpnt_tls = NULL;
-+ struct symbol_ref sym_ref;
-+ sym_ref.sym = &symtab[symtab_index];
-+ sym_ref.tpnt = NULL;
-
- if (ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_LOCAL) {
- symbol_addr = (unsigned long) _dl_find_hash(symname, tpnt->symbol_scope,
-- tpnt, elf_machine_type_class(reloc_type), &tpnt_tls);
-+ tpnt, elf_machine_type_class(reloc_type), &sym_ref);
-+ tls_tpnt = sym_ref.tpnt;
- }
- /* In case of a TLS reloc, tpnt_tls NULL means we have an 'anonymous'
- symbol. This is the case for a static tls variable, so the lookup
-diff --git a/ldso/ldso/powerpc/elfinterp.c b/ldso/ldso/powerpc/elfinterp.c
-index 855c040..dd35eef 100644
---- a/ldso/ldso/powerpc/elfinterp.c
-+++ b/ldso/ldso/powerpc/elfinterp.c
-@@ -187,7 +187,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
- {
- int reloc_type;
- int symtab_index;
-- ElfW(Sym) *sym;
-+ struct symbol_ref sym_ref;
- Elf32_Addr *reloc_addr;
- Elf32_Addr finaladdr;
- struct elf_resolve *tls_tpnt = NULL;
-@@ -201,21 +201,23 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
- reloc_addr = (Elf32_Addr *)(intptr_t) (symbol_addr + (unsigned long) rpnt->r_offset);
- reloc_type = ELF32_R_TYPE(rpnt->r_info);
- symtab_index = ELF32_R_SYM(rpnt->r_info);
-- sym = &symtab[symtab_index];
-- symname = strtab + sym->st_name;
-+ sym_ref.sym = &symtab[symtab_index];
-+ sym_ref.tpnt = NULL;
-+ symname = strtab + sym_ref.sym->st_name;
- if (symtab_index) {
- symbol_addr = (unsigned long) _dl_find_hash(symname, scope, tpnt,
-- elf_machine_type_class(reloc_type), &tls_tpnt);
-+ elf_machine_type_class(reloc_type), &sym_ref);
- /* We want to allow undefined references to weak symbols - this might
- * have been intentional. We should not be linking local symbols
- * here, so all bases should be covered.
- */
- if (unlikely(!symbol_addr
-- && (ELF32_ST_TYPE(sym->st_info) != STT_TLS
-- && ELF32_ST_BIND(sym->st_info) != STB_WEAK)))
-+ && (ELF32_ST_TYPE(sym_ref.sym->st_info) != STT_TLS
-+ && ELF32_ST_BIND(sym_ref.sym->st_info) != STB_WEAK)))
- return 1;
-+ tls_tpnt = sym_ref.tpnt;
- } else {
-- symbol_addr = sym->st_value;
-+ symbol_addr = sym_ref.sym->st_value;
- tls_tpnt = tpnt;
- }
- #if defined (__SUPPORT_LD_DEBUG__)
-@@ -265,10 +267,10 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
- #if defined (__SUPPORT_LD_DEBUG__)
- if (_dl_debug_move)
- _dl_dprintf(_dl_debug_file,"\n%s move %x bytes from %x to %x",
-- symname, sym->st_size,
-+ symname, sym_ref.sym->st_size,
- symbol_addr, reloc_addr);
- #endif
-- _dl_memcpy((char *) reloc_addr, (char *) finaladdr, sym->st_size);
-+ _dl_memcpy((char *) reloc_addr, (char *) finaladdr, sym_ref.sym->st_size);
- goto out_nocode; /* No code code modified */
- case R_PPC_ADDR16_HA:
- finaladdr += 0x8000; /* fall through. */
-diff --git a/ldso/ldso/sh/elfinterp.c b/ldso/ldso/sh/elfinterp.c
-index 715eadc..be3b98c 100644
---- a/ldso/ldso/sh/elfinterp.c
-+++ b/ldso/ldso/sh/elfinterp.c
-@@ -161,16 +161,19 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
- #endif
-
- struct elf_resolve *tls_tpnt = NULL;
-+ struct symbol_ref sym_ref;
-
- reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
- reloc_type = ELF32_R_TYPE(rpnt->r_info);
- symtab_index = ELF32_R_SYM(rpnt->r_info);
- symbol_addr = 0;
-- symname = strtab + symtab[symtab_index].st_name;
-+ sym_ref.sym = &symtab[symtab_index];
-+ sym_ref.tpnt = NULL;
-
- if (symtab_index) {
-+ symname = strtab + symtab[symtab_index].st_name;
- symbol_addr = (unsigned long) _dl_find_hash(symname, scope, tpnt,
-- elf_machine_type_class(reloc_type), &tls_tpnt);
-+ elf_machine_type_class(reloc_type), &sym_ref);
- /*
- * We want to allow undefined references to weak symbols - this might
- * have been intentional. We should not be linking local symbols
-@@ -181,11 +184,12 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
- && (ELF_ST_TYPE(symtab[symtab_index].st_info) != STT_TLS)
- && (ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) {
- _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
-- _dl_progname, strtab + symtab[symtab_index].st_name);
-+ _dl_progname, symname);
-
- /* Let the caller to handle the error: it may be non fatal if called from dlopen */
- return 1;
- }
-+ tls_tpnt = sym_ref.tpnt;
- }
-
- #if defined (__SUPPORT_LD_DEBUG__)
-diff --git a/ldso/ldso/sh64/elfinterp.c b/ldso/ldso/sh64/elfinterp.c
-index 74fda04..990aed1 100644
---- a/ldso/ldso/sh64/elfinterp.c
-+++ b/ldso/ldso/sh64/elfinterp.c
-@@ -173,11 +173,14 @@ static int _dl_do_reloc(struct elf_resolve *tpnt,struct dyn_elf *scope,
- #ifdef __SUPPORT_LD_DEBUG__
- unsigned long old_val;
- #endif
-+ struct symbol_ref sym_ref;
-
- reloc_type = ELF32_R_TYPE(rpnt->r_info);
- symtab_index = ELF32_R_SYM(rpnt->r_info);
- symbol_addr = 0;
- lsb = !!(symtab[symtab_index].st_other & STO_SH5_ISA32);
-+ sym_ref.sym = &symtab[symtab_index];
-+ sym_ref.tpnt = NULL;
- symname = strtab + symtab[symtab_index].st_name;
- reloc_addr = (unsigned long *)(intptr_t)
- (tpnt->loadaddr + (unsigned long)rpnt->r_offset);
-@@ -186,7 +189,7 @@ static int _dl_do_reloc(struct elf_resolve *tpnt,struct dyn_elf *scope,
- int stb;
-
- symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt,
-- elf_machine_type_class(reloc_type), NULL);
-+ elf_machine_type_class(reloc_type), &sym_ref);
-
- /*
- * We want to allow undefined references to weak symbols - this
-@@ -197,7 +200,7 @@ static int _dl_do_reloc(struct elf_resolve *tpnt,struct dyn_elf *scope,
-
- if (stb != STB_WEAK && !symbol_addr) {
- _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
-- _dl_progname, strtab + symtab[symtab_index].st_name);
-+ _dl_progname, symname);
- _dl_exit (1);
- }
- }
-diff --git a/ldso/ldso/sparc/elfinterp.c b/ldso/ldso/sparc/elfinterp.c
-index 56335cb..443f65b 100644
---- a/ldso/ldso/sparc/elfinterp.c
-+++ b/ldso/ldso/sparc/elfinterp.c
-@@ -171,7 +171,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- int symtab_index;
- char *symname;
- struct elf_resolve *tls_tpnt = 0;
-- ElfW(Sym) *sym;
-+ struct symbol_ref sym_ref;
- ElfW(Addr) *reloc_addr;
- ElfW(Addr) symbol_addr;
- #if defined (__SUPPORT_LD_DEBUG__)
-@@ -181,29 +181,31 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
- reloc_type = ELF_R_TYPE(rpnt->r_info);
- symtab_index = ELF_R_SYM(rpnt->r_info);
-- sym = &symtab[symtab_index];
-+ sym_ref.sym = &symtab[symtab_index];
-+ sym_ref.tpnt = NULL;
- symbol_addr = 0;
-- symname = strtab + sym->st_name;
-+ symname = strtab + sym_ref.sym->st_name;
-
- if (symtab_index) {
- symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt,
-- elf_machine_type_class(reloc_type), &tls_tpnt);
-+ elf_machine_type_class(reloc_type), &sym_ref);
- /*
- * We want to allow undefined references to weak symbols - this
- * might have been intentional. We should not be linking local
- * symbols here, so all bases should be covered.
- */
-- if (unlikely(!symbol_addr && (ELF_ST_TYPE(sym->st_info) != STT_TLS)
-- && (ELF_ST_BIND(sym->st_info) != STB_WEAK))) {
-+ if (unlikely(!symbol_addr && (ELF_ST_TYPE(sym_ref.sym->st_info) != STT_TLS)
-+ && (ELF_ST_BIND(sym_ref.sym->st_info) != STB_WEAK))) {
- /* This may be non-fatal if called from dlopen. */
- return 1;
-
- }
-+ tls_tpnt = sym_ref.tpnt;
- } else {
- /* Relocs against STN_UNDEF are usually treated as using a
- * symbol value of zero, and using the module containing the
- * reloc itself. */
-- symbol_addr = sym->st_value;
-+ symbol_addr = sym_ref.sym->st_value;
- tls_tpnt = tpnt;
- }
-
-@@ -262,13 +264,13 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- if (_dl_debug_move)
- _dl_dprintf(_dl_debug_file,
- "\t%s move %d bytes from %x to %x\n",
-- symname, sym->st_size,
-+ symname, sym_ref.sym->st_size,
- symbol_addr, reloc_addr);
- #endif
-
- _dl_memcpy((char *)reloc_addr,
- (char *)symbol_addr,
-- sym->st_size);
-+ sym_ref.sym->st_size);
- } else
- _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n");
- break;
-@@ -280,7 +282,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- case R_SPARC_TLS_DTPOFF32:
- /* During relocation all TLS symbols are defined and used.
- * Therefore the offset is already correct. */
-- *reloc_addr = sym->st_value + rpnt->r_addend;
-+ *reloc_addr = sym_ref.sym->st_value + rpnt->r_addend;
- break;
-
- case R_SPARC_TLS_TPOFF32:
-@@ -289,7 +291,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- * It is a negative value which will be added to the
- * thread pointer. */
- CHECK_STATIC_TLS ((struct link_map *) tls_tpnt);
-- *reloc_addr = sym->st_value - tls_tpnt->l_tls_offset + rpnt->r_addend;
-+ *reloc_addr = sym_ref.sym->st_value - tls_tpnt->l_tls_offset + rpnt->r_addend;
- break;
- #endif
- default:
-diff --git a/ldso/ldso/x86_64/elfinterp.c b/ldso/ldso/x86_64/elfinterp.c
-index fce2ec7..15d7733 100644
---- a/ldso/ldso/x86_64/elfinterp.c
-+++ b/ldso/ldso/x86_64/elfinterp.c
-@@ -158,7 +158,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- int symtab_index;
- char *symname;
- struct elf_resolve *tls_tpnt = 0;
-- ElfW(Sym) *sym;
-+ struct symbol_ref sym_ref;
- ElfW(Addr) *reloc_addr;
- ElfW(Addr) symbol_addr;
- #if defined (__SUPPORT_LD_DEBUG__)
-@@ -168,28 +168,30 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset);
- reloc_type = ELF_R_TYPE(rpnt->r_info);
- symtab_index = ELF_R_SYM(rpnt->r_info);
-- sym = &symtab[symtab_index];
-+ sym_ref.sym = &symtab[symtab_index];
-+ sym_ref.tpnt = NULL;
- symbol_addr = 0;
-- symname = strtab + sym->st_name;
-+ symname = strtab + sym_ref.sym->st_name;
-
- if (symtab_index) {
- symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt,
-- elf_machine_type_class(reloc_type), &tls_tpnt);
-+ elf_machine_type_class(reloc_type), &sym_ref);
- /*
- * We want to allow undefined references to weak symbols - this
- * might have been intentional. We should not be linking local
- * symbols here, so all bases should be covered.
- */
-- if (unlikely(!symbol_addr && (ELF_ST_TYPE(sym->st_info) != STT_TLS)
-- && (ELF_ST_BIND(sym->st_info) != STB_WEAK))) {
-+ if (unlikely(!symbol_addr && (ELF_ST_TYPE(sym_ref.sym->st_info) != STT_TLS)
-+ && (ELF_ST_BIND(sym_ref.sym->st_info) != STB_WEAK))) {
- /* This may be non-fatal if called from dlopen. */
- return 1;
- }
-+ tls_tpnt = sym_ref.tpnt;
- } else {
- /* Relocs against STN_UNDEF are usually treated as using a
- * symbol value of zero, and using the module containing the
- * reloc itself. */
-- symbol_addr = sym->st_value;
-+ symbol_addr = sym_ref.sym->st_value;
- tls_tpnt = tpnt;
- }
-
-@@ -249,13 +251,13 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
- if (_dl_debug_move)
- _dl_dprintf(_dl_debug_file,
- "\t%s move %d bytes from %x to %x\n",
-- symname, sym->st_size,
-+ symname, sym_ref.sym->st_size,
- symbol_addr, reloc_addr);
- #endif
-
- _dl_memcpy((char *)reloc_addr,
- (char *)symbol_addr,
-- sym->st_size);
-+ sym_ref.sym->st_size);
- } else
- _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n");
- break;
-diff --git a/ldso/ldso/xtensa/elfinterp.c b/ldso/ldso/xtensa/elfinterp.c
-index 4828191..8eb6009 100644
---- a/ldso/ldso/xtensa/elfinterp.c
-+++ b/ldso/ldso/xtensa/elfinterp.c
-@@ -146,7 +146,7 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
- int reloc_type;
- int symtab_index;
- char *symname;
-- Elf32_Sym *sym;
-+ struct symbol_ref sym_ref;
- Elf32_Addr *reloc_addr;
- Elf32_Addr symbol_addr;
- #if defined (__SUPPORT_LD_DEBUG__)
-@@ -156,14 +156,15 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
- reloc_addr = (Elf32_Addr *) (tpnt->loadaddr + rpnt->r_offset);
- reloc_type = ELF32_R_TYPE (rpnt->r_info);
- symtab_index = ELF32_R_SYM (rpnt->r_info);
-- sym = &symtab[symtab_index];
-+ sym_ref.sym = &symtab[symtab_index];
-+ sym_ref.tpnt = NULL;
- symbol_addr = 0;
-- symname = strtab + sym->st_name;
-+ symname = strtab + sym_ref.sym->st_name;
-
- if (symtab_index) {
- symbol_addr = (Elf32_Addr)
- _dl_find_hash (symname, scope, tpnt,
-- elf_machine_type_class (reloc_type), NULL);
-+ elf_machine_type_class (reloc_type), &sym_ref);
-
- /*
- * We want to allow undefined references to weak symbols - this might
-@@ -171,7 +172,7 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
- * here, so all bases should be covered.
- */
- if (unlikely (!symbol_addr &&
-- ELF32_ST_BIND (sym->st_info) != STB_WEAK)) {
-+ ELF32_ST_BIND (sym_ref.sym->st_info) != STB_WEAK)) {
- _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
- _dl_progname, symname);
- _dl_exit (1);
-diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
-index 3957e84..b88bc48 100644
---- a/ldso/libdl/libdl.c
-+++ b/ldso/libdl/libdl.c
-@@ -613,6 +613,7 @@ void *dlsym(void *vhandle, const char *name)
- struct dyn_elf *rpnt;
- void *ret;
- struct elf_resolve *tls_tpnt = NULL;
-+ struct symbol_ref sym_ref = { NULL, NULL };
- /* Nastiness to support underscore prefixes. */
- #ifdef __UCLIBC_UNDERSCORES__
- char tmp_buf[80];
-@@ -667,13 +668,13 @@ void *dlsym(void *vhandle, const char *name)
- tpnt = NULL;
- if (handle == _dl_symbol_tables)
- tpnt = handle->dyn; /* Only search RTLD_GLOBAL objs if global object */
-- ret = _dl_find_hash(name2, handle, NULL, 0, &tls_tpnt);
-+ ret = _dl_find_hash(name2, handle, tpnt, 0, &sym_ref);
-
- #if defined(USE_TLS) && USE_TLS && defined SHARED
-- if (tls_tpnt) {
-+ if (sym_ref.tpnt) {
- /* The found symbol is a thread-local storage variable.
- Return the address for to the current thread. */
-- ret = _dl_tls_symaddr ((struct link_map *)tls_tpnt, (Elf32_Addr)ret);
-+ ret = _dl_tls_symaddr ((struct link_map *)sym_ref.tpnt, (Elf32_Addr)ret);
- }
- #endif
-
---
-1.7.3.4
-