diff options
author | Rich Felker <dalias@aerifal.cx> | 2011-06-26 21:21:04 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2011-06-26 21:21:04 -0400 |
commit | 92ab5d8d156545ab0daff6062d7a519861684fb6 (patch) | |
tree | 0e9815a77c5f6ba283ae72704eaea339e82fa8db | |
parent | 59ab43f5f8dbd1baf98d3c483c723d155b6f95c8 (diff) | |
download | musl-92ab5d8d156545ab0daff6062d7a519861684fb6.zip musl-92ab5d8d156545ab0daff6062d7a519861684fb6.tar.gz musl-92ab5d8d156545ab0daff6062d7a519861684fb6.tar.bz2 |
fix resolving symbols in objects loaded in RTLD_LOCAL mode
basically we temporarily make the library and all its dependencies
part of the global namespace but only for the duration of performing
relocations, then return them to their former state.
-rw-r--r-- | src/ldso/dynlink.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index 35ff962..305d70e 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -493,6 +493,9 @@ void *dlopen(const char *file, int mode) if (setjmp(rtld_fail)) { /* Clean up anything new that was (partially) loaded */ + if (p->deps) for (i=0; p->deps[i]; i++) + if (p->deps[i]->global < 0) + p->deps[i]->global = 0; for (p=orig_tail->next; p; p=next) { next = p->next; munmap(p->map, p->map_len); @@ -511,7 +514,15 @@ void *dlopen(const char *file, int mode) /* First load handling */ if (!p->deps) { load_deps(p); + for (i=0; p->deps[i]; i++) + if (!p->deps[i]->global) + p->deps[i]->global = -1; + if (!p->global) p->global = -1; reloc_all(p); + for (i=0; p->deps[i]; i++) + if (p->deps[i]->global < 0) + p->deps[i]->global = 0; + if (p->global < 0) p->global = 0; } if (mode & RTLD_GLOBAL) { |