diff options
author | Mathias Agopian <mathias@google.com> | 2009-09-27 22:04:15 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2009-09-27 22:04:15 -0700 |
commit | 33acbf0719c4f3db059bc9e1f52cf554a5d0295f (patch) | |
tree | 914ca013c2b4979b97c639c301a70c41a4785a4a /linker | |
parent | 4e5a965d6a4c4a0c7977cc9b90755027130c1e46 (diff) | |
download | bionic-33acbf0719c4f3db059bc9e1f52cf554a5d0295f.zip bionic-33acbf0719c4f3db059bc9e1f52cf554a5d0295f.tar.gz bionic-33acbf0719c4f3db059bc9e1f52cf554a5d0295f.tar.bz2 |
Revert "bionic/linker: fix symbol lookup during relocations"
This reverts commit 8d0c0334f1106d36f2fd5c1cf6d5dc75a4b88850.
Diffstat (limited to 'linker')
-rw-r--r-- | linker/linker.c | 100 |
1 files changed, 26 insertions, 74 deletions
diff --git a/linker/linker.c b/linker/linker.c index 6f09837..eed9738 100644 --- a/linker/linker.c +++ b/linker/linker.c @@ -87,12 +87,6 @@ static soinfo *freelist = NULL; static soinfo *solist = &libdl_info; static soinfo *sonext = &libdl_info; -static inline int validate_soinfo(soinfo *si) -{ - return (si >= sopool && si < sopool + SO_MAX) || - si == &libdl_info; -} - static char ldpaths_buf[LDPATH_BUFSIZE]; static const char *ldpaths[LDPATH_MAX + 1]; @@ -427,70 +421,32 @@ _do_lookup_in_so(soinfo *si, const char *name, unsigned *elf_hash) return _elf_lookup (si, *elf_hash, name); } -static Elf32_Sym * -_do_lookup(soinfo *si, const char *name, unsigned *base) -{ - unsigned elf_hash = 0; - Elf32_Sym *s; - unsigned *d; - soinfo *lsi = si; - - /* Look for symbols in the local scope first (the object who is - * searching). This happens with C++ templates on i386 for some - * reason. */ - s = _do_lookup_in_so(si, name, &elf_hash); - if(s != NULL) - goto done; - - for(d = si->dynamic; *d; d += 2) { - if(d[0] == DT_NEEDED){ - lsi = (soinfo *)d[1]; - if (!validate_soinfo(lsi)) { - DL_ERR("%5d bad DT_NEEDED pointer in %s", - pid, si->name); - return 0; - } - - DEBUG("%5d %s: looking up %s in %s\n", - pid, si->name, name, lsi->name); - s = _do_lookup_in_so(lsi, name, &elf_hash); - if(s != NULL) - goto done; - } - } - -done: - if(s != NULL) { - TRACE_TYPE(LOOKUP, "%5d si %s sym %s s->st_value = 0x%08x, " - "found in %s, base = 0x%08x\n", - pid, si->name, name, s->st_value, lsi->name, lsi->base); - *base = lsi->base; - return s; - } - - return 0; -} - -/* This is used by dl_sym(). It performs symbol lookup only within the - specified soinfo object and not in any of its dependencies. - */ +/* This is used by dl_sym() */ Elf32_Sym *lookup_in_library(soinfo *si, const char *name) { unsigned unused = 0; return _do_lookup_in_so(si, name, &unused); } -/* This is used by dl_sym(). It performs a global symbol lookup. - */ -Elf32_Sym *lookup(const char *name, unsigned *base) +static Elf32_Sym * +_do_lookup(soinfo *user_si, const char *name, unsigned *base) { unsigned elf_hash = 0; Elf32_Sym *s = NULL; soinfo *si; + /* Look for symbols in the local scope first (the object who is + * searching). This happens with C++ templates on i386 for some + * reason. */ + if (user_si) { + s = _do_lookup_in_so(user_si, name, &elf_hash); + if (s != NULL) + *base = user_si->base; + } + for(si = solist; (s == NULL) && (si != NULL); si = si->next) { - if(si->flags & FLAG_ERROR) + if((si->flags & FLAG_ERROR) || (si == user_si)) continue; s = _do_lookup_in_so(si, name, &elf_hash); if (s != NULL) { @@ -499,7 +455,7 @@ Elf32_Sym *lookup(const char *name, unsigned *base) } } - if(s != NULL) { + if (s != NULL) { TRACE_TYPE(LOOKUP, "%5d %s s->st_value = 0x%08x, " "si->base = 0x%08x\n", pid, name, s->st_value, si->base); return s; @@ -508,6 +464,12 @@ Elf32_Sym *lookup(const char *name, unsigned *base) return 0; } +/* This is used by dl_sym() */ +Elf32_Sym *lookup(const char *name, unsigned *base) +{ + return _do_lookup(NULL, name, base); +} + #if 0 static void dump(soinfo *si) { @@ -1154,16 +1116,14 @@ unsigned unload_library(soinfo *si) for(d = si->dynamic; *d; d += 2) { if(d[0] == DT_NEEDED){ - soinfo *lsi = (soinfo *)d[1]; - d[1] = 0; - if (validate_soinfo(lsi)) { - TRACE("%5d %s needs to unload %s\n", pid, - si->name, lsi->name); + TRACE("%5d %s needs to unload %s\n", pid, + si->name, si->strtab + d[1]); + soinfo *lsi = find_library(si->strtab + d[1]); + if(lsi) unload_library(lsi); - } else - DL_ERR("%5d %s: could not unload dependent library", - pid, si->name); + DL_ERR("%5d could not unload '%s'", + pid, si->strtab + d[1]); } } @@ -1681,14 +1641,6 @@ static int link_image(soinfo *si, unsigned wr_offset) pid, si->strtab + d[1], si->name, tmp_err_buf); goto fail; } - /* Save the soinfo of the loaded DT_NEEDED library in the payload - of the DT_NEEDED entry itself, so that we can retrieve the - soinfo directly later from the dynamic segment. This is a hack, - but it allows us to map from DT_NEEDED to soinfo efficiently - later on when we resolve relocations, trying to look up a symgol - with dlsym(). - */ - d[1] = (unsigned)lsi; lsi->refcount++; } } |