summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ldso/dlsym.c8
-rw-r--r--src/ldso/dynlink.c11
-rw-r--r--src/ldso/i386/dlsym.s10
-rw-r--r--src/ldso/x86_64/dlsym.s6
4 files changed, 32 insertions, 3 deletions
diff --git a/src/ldso/dlsym.c b/src/ldso/dlsym.c
new file mode 100644
index 00000000..33693143
--- /dev/null
+++ b/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);
+}
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;
}
diff --git a/src/ldso/i386/dlsym.s b/src/ldso/i386/dlsym.s
new file mode 100644
index 00000000..abd53a09
--- /dev/null
+++ b/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
diff --git a/src/ldso/x86_64/dlsym.s b/src/ldso/x86_64/dlsym.s
new file mode 100644
index 00000000..4261145c
--- /dev/null
+++ b/src/ldso/x86_64/dlsym.s
@@ -0,0 +1,6 @@
+.text
+.global dlsym
+.type dlsym,@function
+dlsym:
+ mov (%rsp),%edx
+ jmp __dlsym