diff options
author | Rich Felker <dalias@aerifal.cx> | 2011-08-16 00:42:13 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2011-08-16 00:42:13 -0400 |
commit | 623753ad64a3625b010c10c00c45262d2eec2495 (patch) | |
tree | 822d9f37067f4bbd51f83116696cfb835438b138 /src/ldso/dynlink.c | |
parent | 2719cc86285d85df42f13ba0ae5b07b262c39686 (diff) | |
download | musl-623753ad64a3625b010c10c00c45262d2eec2495.tar.gz musl-623753ad64a3625b010c10c00c45262d2eec2495.tar.xz musl-623753ad64a3625b010c10c00c45262d2eec2495.zip |
RTLD_NEXT support
the asm wrapper is needed to get the return address without compiler-specific extensions.
Diffstat (limited to 'src/ldso/dynlink.c')
-rw-r--r-- | src/ldso/dynlink.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index ced1637c..3fafb181 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -638,11 +638,16 @@ end: return p; } -static void *do_dlsym(struct dso *p, const char *s) +static void *do_dlsym(struct dso *p, const char *s, void *ra) { size_t i; uint32_t h; Sym *sym; + if (p == RTLD_NEXT) { + for (p=head; p && (unsigned char *)ra-p->map>p->map_len; p=p->next); + if (!p) p=head; + p=p->next; + } if (p == head || p == RTLD_DEFAULT) return find_sym(head, s, 0); h = hash(s); @@ -658,11 +663,11 @@ static void *do_dlsym(struct dso *p, const char *s) return 0; } -void *dlsym(void *p, const char *s) +void *__dlsym(void *p, const char *s, void *ra) { void *res; pthread_rwlock_rdlock(&lock); - res = do_dlsym(p, s); + res = do_dlsym(p, s, ra); pthread_rwlock_unlock(&lock); return res; } |