about summary refs log tree commit diff
path: root/src/ldso/dynlink.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2011-08-16 00:42:13 -0400
committerRich Felker <dalias@aerifal.cx>2011-08-16 00:42:13 -0400
commit623753ad64a3625b010c10c00c45262d2eec2495 (patch)
tree822d9f37067f4bbd51f83116696cfb835438b138 /src/ldso/dynlink.c
parent2719cc86285d85df42f13ba0ae5b07b262c39686 (diff)
downloadmusl-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.c11
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;
 }