aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/uclibc
diff options
context:
space:
mode:
authorKhem Raj <raj.khem@gmail.com>2011-01-15 15:36:07 -0800
committerKhem Raj <raj.khem@gmail.com>2011-01-15 15:36:07 -0800
commit3de42fccb9d8baa70e37dbdbf8bedf5ecafb9a4d (patch)
treeaad4455eee0f3d8e21097839f4467af86629f93e /recipes/uclibc
parent700b75e7661062aa93cf81205b78c8bf7609922d (diff)
downloadopenembedded-3de42fccb9d8baa70e37dbdbf8bedf5ecafb9a4d.tar.gz
uclibc-git: Get latest patches for protected symbols
Signed-off-by: Khem Raj <raj.khem@gmail.com>
Diffstat (limited to 'recipes/uclibc')
-rw-r--r--recipes/uclibc/uclibc-git/0001-Revert-ldso-i386-support-protected-symbols.patch45
-rw-r--r--recipes/uclibc/uclibc-git/0002-Revert-ldso_sh-add-support-for-protected-symbols-to-.patch72
-rw-r--r--recipes/uclibc/uclibc-git/0003-Revert-ldso-arm-Correct-protected-symbol-resolution.patch46
-rw-r--r--recipes/uclibc/uclibc-git/0004-Add-protected-symbols-support-for-all-architectures.patch792
-rw-r--r--recipes/uclibc/uclibc-git/0005-ldso-get-rid-of-_dl_lookup_hash.patch78
-rw-r--r--recipes/uclibc/uclibc-git/pro-sym-mips-fix.patch13
-rw-r--r--recipes/uclibc/uclibc_git.bb8
7 files changed, 1053 insertions, 1 deletions
diff --git a/recipes/uclibc/uclibc-git/0001-Revert-ldso-i386-support-protected-symbols.patch b/recipes/uclibc/uclibc-git/0001-Revert-ldso-i386-support-protected-symbols.patch
new file mode 100644
index 0000000000..f14872e7bf
--- /dev/null
+++ b/recipes/uclibc/uclibc-git/0001-Revert-ldso-i386-support-protected-symbols.patch
@@ -0,0 +1,45 @@
+From 54cf252ad690363bfe7edec0cbdaf1654f58639e Mon Sep 17 00:00:00 2001
+From: Carmelo Amoroso <carmelo.amoroso@st.com>
+Date: Wed, 12 Jan 2011 08:16:26 +0100
+Subject: [PATCH 1/5] Revert "ldso/i386: support protected symbols"
+
+This reverts commit ba38f0cec27b91cc7c605417ad047c4dc77d732f.
+The generic implementation will cover all the architectures handling
+the protected symbols in _dl_lookup_hash [ldso/ldso/dl-hash.c]
+
+Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
+---
+ ldso/ldso/i386/elfinterp.c | 10 ++--------
+ 1 files changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/ldso/ldso/i386/elfinterp.c b/ldso/ldso/i386/elfinterp.c
+index 1e3a2b2..a01c1d0 100644
+--- a/ldso/ldso/i386/elfinterp.c
++++ b/ldso/ldso/i386/elfinterp.c
+@@ -175,9 +175,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
+ symbol_addr = 0;
+ symname = strtab + symtab[symtab_index].st_name;
+
+- if (symtab_index &&
+- (ELF32_ST_VISIBILITY(symtab[symtab_index].st_other)
+- != STV_PROTECTED)) {
++ if (symtab_index) {
+ symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt,
+ elf_machine_type_class(reloc_type), &tls_tpnt);
+
+@@ -190,11 +188,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
+ && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK))
+ return 1;
+ } else {
+- if (symtab_index)
+- symbol_addr = DL_FIND_HASH_VALUE(tpnt, elf_machine_type_class(reloc_type),
+- &symtab[symtab_index]);
+- else
+- symbol_addr = symtab[symtab_index].st_value;
++ symbol_addr = symtab[symtab_index].st_value;
+ tls_tpnt = tpnt;
+ }
+
+--
+1.7.3.4
+
diff --git a/recipes/uclibc/uclibc-git/0002-Revert-ldso_sh-add-support-for-protected-symbols-to-.patch b/recipes/uclibc/uclibc-git/0002-Revert-ldso_sh-add-support-for-protected-symbols-to-.patch
new file mode 100644
index 0000000000..79935049c1
--- /dev/null
+++ b/recipes/uclibc/uclibc-git/0002-Revert-ldso_sh-add-support-for-protected-symbols-to-.patch
@@ -0,0 +1,72 @@
+From 8f5cb1d94001169a6600b19078372ba824f42c6d Mon Sep 17 00:00:00 2001
+From: Carmelo Amoroso <carmelo.amoroso@st.com>
+Date: Wed, 12 Jan 2011 08:19:17 +0100
+Subject: [PATCH 2/5] Revert "ldso_sh: add support for protected symbols to SH"
+
+This reverts commit 74407db52d3953c7f3c6b8a53661cfc96cb07e22.
+The generic implementation will cover all the architectures handling
+the protected symbols in _dl_lookup_hash [ldso/ldso/dl-hash.c]
+
+Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
+---
+ ldso/ldso/sh/elfinterp.c | 42 ++++++++++++++++++------------------------
+ 1 files changed, 18 insertions(+), 24 deletions(-)
+
+diff --git a/ldso/ldso/sh/elfinterp.c b/ldso/ldso/sh/elfinterp.c
+index 756f6c4..715eadc 100644
+--- a/ldso/ldso/sh/elfinterp.c
++++ b/ldso/ldso/sh/elfinterp.c
+@@ -166,32 +166,26 @@ _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;
++ symname = strtab + symtab[symtab_index].st_name;
+
+ if (symtab_index) {
+- symname = strtab + symtab[symtab_index].st_name;
+- if (ELF32_ST_VISIBILITY(symtab[symtab_index].st_other)
+- != STV_PROTECTED) {
+- symbol_addr = (unsigned long) _dl_find_hash(symname, scope, tpnt,
+- elf_machine_type_class(reloc_type), &tls_tpnt);
+- /*
+- * 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 (!symbol_addr
+- && (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);
+-
+- /* Let the caller to handle the error: it may be non fatal if called from dlopen */
+- return 1;
+- }
+- } else
+- /* Resolve protected symbols locally */
+- symbol_addr = DL_FIND_HASH_VALUE(tpnt, elf_machine_type_class(reloc_type),
+- &symtab[symtab_index]);
++ symbol_addr = (unsigned long) _dl_find_hash(symname, scope, tpnt,
++ elf_machine_type_class(reloc_type), &tls_tpnt);
++ /*
++ * 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 (!symbol_addr
++ && (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);
++
++ /* Let the caller to handle the error: it may be non fatal if called from dlopen */
++ return 1;
++ }
+ }
+
+ #if defined (__SUPPORT_LD_DEBUG__)
+--
+1.7.3.4
+
diff --git a/recipes/uclibc/uclibc-git/0003-Revert-ldso-arm-Correct-protected-symbol-resolution.patch b/recipes/uclibc/uclibc-git/0003-Revert-ldso-arm-Correct-protected-symbol-resolution.patch
new file mode 100644
index 0000000000..3d650debd1
--- /dev/null
+++ b/recipes/uclibc/uclibc-git/0003-Revert-ldso-arm-Correct-protected-symbol-resolution.patch
@@ -0,0 +1,46 @@
+From 6f516330f556c6929a54ca8899f9c3cdf175ef13 Mon Sep 17 00:00:00 2001
+From: Carmelo Amoroso <carmelo.amoroso@st.com>
+Date: Wed, 12 Jan 2011 08:19:56 +0100
+Subject: [PATCH 3/5] Revert "ldso/arm: Correct protected symbol resolution"
+
+This reverts commit 48fb264beaac8114e5ac3e80e70dda473fbce96d.
+The generic implementation will cover all the architectures handling
+the protected symbols in _dl_lookup_hash [ldso/ldso/dl-hash.c]
+
+Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
+---
+ ldso/ldso/arm/elfinterp.c | 11 ++---------
+ 1 files changed, 2 insertions(+), 9 deletions(-)
+
+diff --git a/ldso/ldso/arm/elfinterp.c b/ldso/ldso/arm/elfinterp.c
+index adc282a..9bbf92c 100644
+--- a/ldso/ldso/arm/elfinterp.c
++++ b/ldso/ldso/arm/elfinterp.c
+@@ -198,9 +198,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
+ symtab_index = ELF32_R_SYM(rpnt->r_info);
+ symbol_addr = 0;
+
+- if (symtab_index &&
+- (ELF32_ST_VISIBILITY(symtab[symtab_index].st_other)
+- != STV_PROTECTED)) {
++ if (symtab_index) {
+ symbol_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name,
+ scope, tpnt, elf_machine_type_class(reloc_type), &def_mod);
+
+@@ -221,12 +219,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
+ * symbol value of zero, and using the module containing the
+ * reloc itself.
+ */
+- if (symtab_index)
+- symbol_addr = DL_FIND_HASH_VALUE(tpnt, elf_machine_type_class(reloc_type),
+- &symtab[symtab_index]);
+- else
+- symbol_addr = symtab[symtab_index].st_value;
+-
++ symbol_addr = symtab[symtab_index].st_value;
+ def_mod = tpnt;
+ }
+
+--
+1.7.3.4
+
diff --git a/recipes/uclibc/uclibc-git/0004-Add-protected-symbols-support-for-all-architectures.patch b/recipes/uclibc/uclibc-git/0004-Add-protected-symbols-support-for-all-architectures.patch
new file mode 100644
index 0000000000..eda7a48b69
--- /dev/null
+++ b/recipes/uclibc/uclibc-git/0004-Add-protected-symbols-support-for-all-architectures.patch
@@ -0,0 +1,792 @@
+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
+
diff --git a/recipes/uclibc/uclibc-git/0005-ldso-get-rid-of-_dl_lookup_hash.patch b/recipes/uclibc/uclibc-git/0005-ldso-get-rid-of-_dl_lookup_hash.patch
new file mode 100644
index 0000000000..cb33b7ab71
--- /dev/null
+++ b/recipes/uclibc/uclibc-git/0005-ldso-get-rid-of-_dl_lookup_hash.patch
@@ -0,0 +1,78 @@
+From 05914869dec21b2af8e317d4addd18dd8cc8600f Mon Sep 17 00:00:00 2001
+From: Carmelo Amoroso <carmelo.amoroso@st.com>
+Date: Wed, 12 Jan 2011 12:07:39 +0100
+Subject: [PATCH 5/5] ldso: get rid of _dl_lookup_hash
+
+Now _dl_find_hash and _dl_lookup_hash are exactly the same, we can get rid
+of the _dl_lookup_hash, reverting the _dl_find_hash from a wrapper of
+_dl_lookup_hash to its original role.
+
+Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
+---
+ ldso/include/dl-hash.h | 8 +-------
+ ldso/ldso/bfin/elfinterp.c | 6 +++---
+ ldso/ldso/dl-hash.c | 2 +-
+ 3 files changed, 5 insertions(+), 11 deletions(-)
+
+diff --git a/ldso/include/dl-hash.h b/ldso/include/dl-hash.h
+index d1f9acc..d8b3e3e 100644
+--- a/ldso/include/dl-hash.h
++++ b/ldso/include/dl-hash.h
+@@ -142,15 +142,9 @@ 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);
+
+-extern char *_dl_lookup_hash(const char *name, struct dyn_elf *rpnt,
++extern char *_dl_find_hash(const char *name, struct dyn_elf *rpnt,
+ struct elf_resolve *mytpnt, int type_class,
+ 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 symbol_ref *symbol)
+-{
+- return _dl_lookup_hash(name, rpnt, mytpnt, type_class, symbol);
+-}
+
+ extern int _dl_linux_dynamic_link(void);
+
+diff --git a/ldso/ldso/bfin/elfinterp.c b/ldso/ldso/bfin/elfinterp.c
+index 5accbfc..48470d5 100644
+--- a/ldso/ldso/bfin/elfinterp.c
++++ b/ldso/ldso/bfin/elfinterp.c
+@@ -67,9 +67,9 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
+ 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, &sym_ref);
++ new_addr = _dl_find_hash(symname, tpnt->symbol_scope, NULL, 0, &sym_ref);
+ if (!new_addr) {
+- new_addr = _dl_lookup_hash(symname, NULL, NULL, 0, &sym_ref);
++ new_addr = _dl_find_hash(symname, NULL, NULL, 0, &sym_ref);
+ if (!new_addr) {
+ _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
+ _dl_progname, symname);
+@@ -184,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, &sym_ref);
++ _dl_find_hash(symname, scope, NULL, 0, &sym_ref);
+
+ /*
+ * We want to allow undefined references to weak symbols - this might
+diff --git a/ldso/ldso/dl-hash.c b/ldso/ldso/dl-hash.c
+index 6db81a9..0454d61 100644
+--- a/ldso/ldso/dl-hash.c
++++ b/ldso/ldso/dl-hash.c
+@@ -268,7 +268,7 @@ _dl_lookup_sysv_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long
+ * This function resolves externals, and this is either called when we process
+ * 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,
++char *_dl_find_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve *mytpnt,
+ int type_class, struct symbol_ref *sym_ref)
+ {
+ struct elf_resolve *tpnt = NULL;
+--
+1.7.3.4
+
diff --git a/recipes/uclibc/uclibc-git/pro-sym-mips-fix.patch b/recipes/uclibc/uclibc-git/pro-sym-mips-fix.patch
new file mode 100644
index 0000000000..00725583d2
--- /dev/null
+++ b/recipes/uclibc/uclibc-git/pro-sym-mips-fix.patch
@@ -0,0 +1,13 @@
+Index: git/ldso/ldso/mips/elfinterp.c
+===================================================================
+--- git.orig/ldso/ldso/mips/elfinterp.c 2011-01-13 17:20:41.708656002 -0800
++++ git/ldso/ldso/mips/elfinterp.c 2011-01-13 17:21:59.338656002 -0800
+@@ -220,7 +220,7 @@
+ 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), &sym_ref);
+- tls_tpnt = sym_ref.tpnt;
++ tpnt_tls = 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/recipes/uclibc/uclibc_git.bb b/recipes/uclibc/uclibc_git.bb
index 0e44c4fee8..c091abb25c 100644
--- a/recipes/uclibc/uclibc_git.bb
+++ b/recipes/uclibc/uclibc_git.bb
@@ -7,7 +7,7 @@
# on whether the base patches apply to the selected (SRCDATE) svn release.
#
UCLIBC_BASE ?= "0.9.32"
-SRCREV="8764f2e75c875757529aa81e5cd96e17e6f6e5e4"
+SRCREV="8fdc17c2ba1322712604d88dca48157068e6aadb"
PR_append = "+gitr${SRCPV}"
DEFAULT_PREFERENCE = "-1"
#DEFAULT_PREFERENCE is 0 (empty), releases have a preference of 1 so take
@@ -38,5 +38,11 @@ SRC_URI = "git://uclibc.org/uClibc.git;branch=master;protocol=git \
file://include-arm-asm.h.patch \
file://detect-bx-availibility.patch \
file://remove-eabi-oabi-selection.patch \
+ file://0001-Revert-ldso-i386-support-protected-symbols.patch \
+ file://0002-Revert-ldso_sh-add-support-for-protected-symbols-to-.patch \
+ file://0003-Revert-ldso-arm-Correct-protected-symbol-resolution.patch \
+ file://0004-Add-protected-symbols-support-for-all-architectures.patch \
+ file://0005-ldso-get-rid-of-_dl_lookup_hash.patch \
+ file://pro-sym-mips-fix.patch \
"
S = "${WORKDIR}/git"