aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@imgtec.com>2016-05-07 02:29:54 +0100
committerMaciej W. Rozycki <macro@imgtec.com>2016-07-01 23:48:52 +0100
commitb6084a958f20b795e5e0a0644d72b6e162334cdf (patch)
tree2fd599d397fae9cfc1df09155556b568123d63bf /elf
parentSPARC: fix nearbyint on sNaN input (diff)
downloadglibc-b6084a958f20b795e5e0a0644d72b6e162334cdf.tar.gz
glibc-b6084a958f20b795e5e0a0644d72b6e162334cdf.tar.bz2
glibc-b6084a958f20b795e5e0a0644d72b6e162334cdf.zip
Treat STV_HIDDEN and STV_INTERNAL symbols as STB_LOCAL
In a reference to PR ld/19908 make ld.so respect symbol export classes aka visibility and treat STV_HIDDEN and STV_INTERNAL symbols as local, preventing such symbols from preempting exported symbols. According to the ELF gABI[1] neither STV_HIDDEN nor STV_INTERNAL symbols are supposed to be present in linked binaries: "A hidden symbol contained in a relocatable object must be either removed or converted to STB_LOCAL binding by the link-editor when the relocatable object is included in an executable file or shared object." "An internal symbol contained in a relocatable object must be either removed or converted to STB_LOCAL binding by the link-editor when the relocatable object is included in an executable file or shared object." however some GNU binutils versions produce such symbols in some cases. PR ld/19908 is one and we also have this note in scripts/abilist.awk: so clearly there is linked code out there which contains such symbols which is prone to symbol table misinterpretation, and it'll be more productive if we handle this gracefully, under the Robustness Principle: "be liberal in what you accept, and conservative in what you produce", especially as this is a simple (STV_HIDDEN|STV_INTERNAL) => STB_LOCAL mapping. References: [1] "System V Application Binary Interface - DRAFT - 24 April 2001", The Santa Cruz Operation, Inc., "Symbol Table", <http://www.sco.com/developers/gabi/2001-04-24/ch4.symtab.html> * sysdeps/generic/ldsodefs.h (dl_symbol_visibility_binds_local_p): New inline function. * elf/dl-addr.c (determine_info): Treat hidden and internal symbols as local. * elf/dl-lookup.c (do_lookup_x): Likewise. * elf/dl-reloc.c (RESOLVE_MAP): Likewise.
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-addr.c1
-rw-r--r--elf/dl-lookup.c4
-rw-r--r--elf/dl-reloc.c3
3 files changed, 7 insertions, 1 deletions
diff --git a/elf/dl-addr.c b/elf/dl-addr.c
index 291ff55816..1b16a58ced 100644
--- a/elf/dl-addr.c
+++ b/elf/dl-addr.c
@@ -88,6 +88,7 @@ determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info,
for (; (void *) symtab < (void *) symtabend; ++symtab)
if ((ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL
|| ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
+ && __glibc_likely (!dl_symbol_visibility_binds_local_p (symtab))
&& ELFW(ST_TYPE) (symtab->st_info) != STT_TLS
&& (symtab->st_shndx != SHN_UNDEF
|| symtab->st_value != 0)
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 6d299c1097..52c994e16c 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -516,6 +516,10 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
#endif
}
+ /* Hidden and internal symbols are local, ignore them. */
+ if (__glibc_unlikely (dl_symbol_visibility_binds_local_p (sym)))
+ goto skip;
+
switch (ELFW(ST_BIND) (sym->st_info))
{
case STB_WEAK:
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 14709f960d..42bddc1e2c 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -233,7 +233,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
#define RESOLVE_MAP(ref, version, r_type) \
- (ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \
+ ((ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \
+ && __glibc_likely (!dl_symbol_visibility_binds_local_p (*ref))) \
? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0) \
&& elf_machine_type_class (r_type) == l->l_lookup_cache.type_class) \
? (bump_num_cache_relocations (), \