Browse Source

RTLD_NEXT support

the asm wrapper is needed to get the return address without
compiler-specific extensions.
Rich Felker 13 years ago
parent
commit
623753ad64
4 changed files with 32 additions and 3 deletions
  1. 8 0
      src/ldso/dlsym.c
  2. 8 3
      src/ldso/dynlink.c
  3. 10 0
      src/ldso/i386/dlsym.s
  4. 6 0
      src/ldso/x86_64/dlsym.s

+ 8 - 0
src/ldso/dlsym.c

@@ -0,0 +1,8 @@
+#include <dlfcn.h>
+
+void *__dlsym(void *, const char *, void *);
+
+void *dlsym(void *p, const char *s)
+{
+	return __dlsym(p, s, 0);
+}

+ 8 - 3
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;
 }

+ 10 - 0
src/ldso/i386/dlsym.s

@@ -0,0 +1,10 @@
+.text
+.global dlsym
+.type dlsym,@function
+dlsym:
+	push (%esp)
+	push 12(%esp)
+	push 12(%esp)
+	call __dlsym
+	add $12,%esp
+	ret

+ 6 - 0
src/ldso/x86_64/dlsym.s

@@ -0,0 +1,6 @@
+.text
+.global dlsym
+.type dlsym,@function
+dlsym:
+	mov (%rsp),%edx
+	jmp __dlsym