diff options
Diffstat (limited to 'linker/linker.c')
-rw-r--r-- | linker/linker.c | 25 |
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) ( |