uclibc-git: Get latest patches for protected symbols
authorKhem Raj <raj.khem@gmail.com>
Sat, 15 Jan 2011 23:36:07 +0000 (15:36 -0800)
committerKhem Raj <raj.khem@gmail.com>
Sat, 15 Jan 2011 23:36:07 +0000 (15:36 -0800)
Signed-off-by: Khem Raj <raj.khem@gmail.com>
recipes/uclibc/uclibc-git/0001-Revert-ldso-i386-support-protected-symbols.patch [new file with mode: 0644]
recipes/uclibc/uclibc-git/0002-Revert-ldso_sh-add-support-for-protected-symbols-to-.patch [new file with mode: 0644]
recipes/uclibc/uclibc-git/0003-Revert-ldso-arm-Correct-protected-symbol-resolution.patch [new file with mode: 0644]
recipes/uclibc/uclibc-git/0004-Add-protected-symbols-support-for-all-architectures.patch [new file with mode: 0644]
recipes/uclibc/uclibc-git/0005-ldso-get-rid-of-_dl_lookup_hash.patch [new file with mode: 0644]
recipes/uclibc/uclibc-git/pro-sym-mips-fix.patch [new file with mode: 0644]
recipes/uclibc/uclibc_git.bb

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 (file)
index 0000000..f14872e
--- /dev/null
@@ -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 (file)
index 0000000..7993504
--- /dev/null
@@ -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 (file)
index 0000000..3d650de
--- /dev/null
@@ -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 (file)
index 0000000..eda7a48
--- /dev/null
@@ -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 (file)
index 0000000..cb33b7a
--- /dev/null
@@ -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 (file)
index 0000000..0072558
--- /dev/null
@@ -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
index 0e44c4f..c091abb 100644 (file)
@@ -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"