Revert "bionic/linker: fix symbol lookup during relocations"

This reverts commit 8d0c0334f1106d36f2fd5c1cf6d5dc75a4b88850.
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 *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 @@
     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 @@
         }
     }
 
-    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 @@
     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 @@
 
         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 @@
                        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++;
         }
     }