From ad7ff82771b44ad36d2a66c2413dffaff20816e9 Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Tue, 10 Apr 2012 13:42:06 -0700 Subject: [PATCH] Revert "linker: remove STB_LOCAL hack" This reverts commit 61ff83475c6f3a3bb05a01ac89d668a331bfe9e9. This code is harmless, and only applies to the linker, so there's no harm in keeping it in the tree a little bit longer. Let's roll this back while we try to figure out the root cause of bug 6314858. Bug: 6314858 Change-Id: I9f5ed81d23a7abe273baf792aa8a0a2839ef094c --- linker/linker.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/linker/linker.c b/linker/linker.c index ac183fdaa..9805b35e3 100644 --- a/linker/linker.c +++ b/linker/linker.c @@ -408,6 +408,33 @@ static Elf32_Sym *_elf_lookup(soinfo *si, unsigned hash, const char *name) return NULL; } +/* + * Essentially the same method as _elf_lookup() above, but only + * searches for LOCAL symbols + */ +static Elf32_Sym *_elf_lookup_local(soinfo *si, unsigned hash, const char *name) +{ + Elf32_Sym *symtab = si->symtab; + const char *strtab = si->strtab; + unsigned n = hash % si->nbucket;; + + TRACE_TYPE(LOOKUP, "%5d LOCAL SEARCH %s in %s@0x%08x %08x %d\n", pid, + name, si->name, si->base, hash, hash % si->nbucket); + for(n = si->bucket[hash % si->nbucket]; n != 0; n = si->chain[n]){ + Elf32_Sym *s = symtab + n; + if (strcmp(strtab + s->st_name, name)) continue; + if (ELF32_ST_BIND(s->st_info) != STB_LOCAL) continue; + /* no section == undefined */ + if(s->st_shndx == 0) continue; + + TRACE_TYPE(LOOKUP, "%5d FOUND LOCAL %s in %s (%08x) %d\n", pid, + name, si->name, s->st_value, s->st_size); + return s; + } + + return NULL; +} + static unsigned elfhash(const char *_name) { const unsigned char *name = (const unsigned char *) _name; @@ -431,6 +458,16 @@ _do_lookup(soinfo *si, const char *name, unsigned *base) soinfo *lsi = si; int i; + /* If we are trying to find a symbol for the linker itself, look + * for LOCAL symbols first. Avoid using LOCAL symbols for other + * shared libraries until we have a better understanding of what + * might break by doing so. */ + if (si->flags & FLAG_LINKER) { + s = _elf_lookup_local(si, elf_hash, name); + if(s != NULL) + goto done; + } + /* Look for symbols in the local scope (the object who is * searching). This happens with C++ templates on i386 for some * reason.