summaryrefslogtreecommitdiffstats
path: root/linker
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2009-09-27 22:04:15 -0700
committerMathias Agopian <mathias@google.com>2009-09-27 22:04:15 -0700
commit33acbf0719c4f3db059bc9e1f52cf554a5d0295f (patch)
tree914ca013c2b4979b97c639c301a70c41a4785a4a /linker
parent4e5a965d6a4c4a0c7977cc9b90755027130c1e46 (diff)
downloadbionic-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.c100
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++;
}
}