bionic/linker: allow resolving of symbols from library back to executable

Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/linker/linker.c b/linker/linker.c
index b260749..26cd0a8 100644
--- a/linker/linker.c
+++ b/linker/linker.c
@@ -51,6 +51,7 @@
 
 #include "ba.h"
 
+#define ALLOW_SYMBOLS_FROM_MAIN 1
 #define SO_MAX 96
 
 /* Assume average path length of 64 and max 8 paths */
@@ -86,6 +87,9 @@
 static soinfo *freelist = NULL;
 static soinfo *solist = &libdl_info;
 static soinfo *sonext = &libdl_info;
+#if ALLOW_SYMBOLS_FROM_MAIN
+static soinfo *somain; /* main process, always the one after libdl_info */
+#endif
 
 static inline int validate_soinfo(soinfo *si)
 {
@@ -459,6 +463,19 @@
         }
     }
 
+#if ALLOW_SYMBOLS_FROM_MAIN
+    /* If we are resolving relocations while dlopen()ing a library, it's OK for
+     * the library to resolve a symbol that's defined in the executable itself,
+     * although this is rare and is generally a bad idea.
+     */
+    if (somain) {
+        lsi = somain;
+        DEBUG("%5d %s: looking up %s in executable %s\n",
+              pid, si->name, name, lsi->name);
+        s = _do_lookup_in_so(lsi, name, &elf_hash);
+    }
+#endif
+
 done:
     if(s != NULL) {
         TRACE_TYPE(LOOKUP, "%5d si %s sym %s s->st_value = 0x%08x, "
@@ -1894,6 +1911,14 @@
         exit(-1);
     }
 
+#if ALLOW_SYMBOLS_FROM_MAIN
+    /* Set somain after we've loaded all the libraries in order to prevent
+     * linking of symbols back to the main image, which is not set up at that
+     * point yet.
+     */
+    somain = si;
+#endif
+
 #if TIMING
     gettimeofday(&t1,NULL);
     PRINT("LINKER TIME: %s: %d microseconds\n", argv[0], (int) (