summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIliyan Malchev <malchev@google.com>2009-09-29 11:43:20 -0700
committerIliyan Malchev <malchev@google.com>2009-09-29 14:33:46 -0700
commit4a9afcb10151b083cd2d75253385615f459172ed (patch)
tree8879a1126fce0aa369e13b8db7b8dae0290145ae
parent9ea64da6c511e8f9f4edae4c10c20879957631ab (diff)
downloadbionic-4a9afcb10151b083cd2d75253385615f459172ed.zip
bionic-4a9afcb10151b083cd2d75253385615f459172ed.tar.gz
bionic-4a9afcb10151b083cd2d75253385615f459172ed.tar.bz2
bionic/linker: allow resolving of symbols from library back to executable
Signed-off-by: Iliyan Malchev <malchev@google.com>
-rw-r--r--linker/linker.c25
1 files changed, 25 insertions, 0 deletions
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 sopool[SO_MAX];
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 @@ _do_lookup(soinfo *si, const char *name, unsigned *base)
}
}
+#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 @@ unsigned __linker_init(unsigned **elfdata)
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) (