summaryrefslogtreecommitdiffstats
path: root/libc-top-half/musl/src/ldso
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libc-top-half/musl/src/ldso/__dlsym.c14
-rw-r--r--libc-top-half/musl/src/ldso/aarch64/dlsym.s6
-rw-r--r--libc-top-half/musl/src/ldso/aarch64/tlsdesc.s31
-rw-r--r--libc-top-half/musl/src/ldso/arm/dlsym.s8
-rw-r--r--libc-top-half/musl/src/ldso/arm/dlsym_time64.S3
-rw-r--r--libc-top-half/musl/src/ldso/arm/find_exidx.c42
-rw-r--r--libc-top-half/musl/src/ldso/arm/tlsdesc.S55
-rw-r--r--libc-top-half/musl/src/ldso/dl_iterate_phdr.c47
-rw-r--r--libc-top-half/musl/src/ldso/dladdr.c9
-rw-r--r--libc-top-half/musl/src/ldso/dlclose.c7
-rw-r--r--libc-top-half/musl/src/ldso/dlerror.c87
-rw-r--r--libc-top-half/musl/src/ldso/dlinfo.c14
-rw-r--r--libc-top-half/musl/src/ldso/dlopen.c10
-rw-r--r--libc-top-half/musl/src/ldso/dlsym.c7
-rw-r--r--libc-top-half/musl/src/ldso/i386/dlsym.s11
-rw-r--r--libc-top-half/musl/src/ldso/i386/dlsym_time64.S3
-rw-r--r--libc-top-half/musl/src/ldso/i386/tlsdesc.s23
-rw-r--r--libc-top-half/musl/src/ldso/m68k/dlsym.s12
-rw-r--r--libc-top-half/musl/src/ldso/m68k/dlsym_time64.S3
-rw-r--r--libc-top-half/musl/src/ldso/microblaze/dlsym.s6
-rw-r--r--libc-top-half/musl/src/ldso/microblaze/dlsym_time64.S3
-rw-r--r--libc-top-half/musl/src/ldso/mips/dlsym.s17
-rw-r--r--libc-top-half/musl/src/ldso/mips/dlsym_time64.S3
-rw-r--r--libc-top-half/musl/src/ldso/mips64/dlsym.s17
-rw-r--r--libc-top-half/musl/src/ldso/mipsn32/dlsym.s17
-rw-r--r--libc-top-half/musl/src/ldso/mipsn32/dlsym_time64.S3
-rw-r--r--libc-top-half/musl/src/ldso/or1k/dlsym.s6
-rw-r--r--libc-top-half/musl/src/ldso/or1k/dlsym_time64.S3
-rw-r--r--libc-top-half/musl/src/ldso/powerpc/dlsym.s8
-rw-r--r--libc-top-half/musl/src/ldso/powerpc/dlsym_time64.S3
-rw-r--r--libc-top-half/musl/src/ldso/powerpc64/dlsym.s11
-rw-r--r--libc-top-half/musl/src/ldso/riscv64/dlsym.s6
-rw-r--r--libc-top-half/musl/src/ldso/s390x/dlsym.s6
-rw-r--r--libc-top-half/musl/src/ldso/sh/dlsym.s11
-rw-r--r--libc-top-half/musl/src/ldso/sh/dlsym_time64.S3
-rw-r--r--libc-top-half/musl/src/ldso/tlsdesc.c9
-rw-r--r--libc-top-half/musl/src/ldso/x32/dlsym.s7
-rw-r--r--libc-top-half/musl/src/ldso/x86_64/dlsym.s7
-rw-r--r--libc-top-half/musl/src/ldso/x86_64/tlsdesc.s23
39 files changed, 561 insertions, 0 deletions
diff --git a/libc-top-half/musl/src/ldso/__dlsym.c b/libc-top-half/musl/src/ldso/__dlsym.c
new file mode 100644
index 0000000..0384f97
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/__dlsym.c
@@ -0,0 +1,14 @@
+#include <dlfcn.h>
+#include "dynlink.h"
+
+static void *stub_dlsym(void *restrict p, const char *restrict s, void *restrict ra)
+{
+ __dl_seterr("Symbol not found: %s", s);
+ return 0;
+}
+
+weak_alias(stub_dlsym, __dlsym);
+
+#if _REDIR_TIME64
+weak_alias(stub_dlsym, __dlsym_redir_time64);
+#endif
diff --git a/libc-top-half/musl/src/ldso/aarch64/dlsym.s b/libc-top-half/musl/src/ldso/aarch64/dlsym.s
new file mode 100644
index 0000000..abaae4d
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/aarch64/dlsym.s
@@ -0,0 +1,6 @@
+.global dlsym
+.hidden __dlsym
+.type dlsym,%function
+dlsym:
+ mov x2,x30
+ b __dlsym
diff --git a/libc-top-half/musl/src/ldso/aarch64/tlsdesc.s b/libc-top-half/musl/src/ldso/aarch64/tlsdesc.s
new file mode 100644
index 0000000..c6c685b
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/aarch64/tlsdesc.s
@@ -0,0 +1,31 @@
+// size_t __tlsdesc_static(size_t *a)
+// {
+// return a[1];
+// }
+.global __tlsdesc_static
+.hidden __tlsdesc_static
+.type __tlsdesc_static,@function
+__tlsdesc_static:
+ ldr x0,[x0,#8]
+ ret
+
+// size_t __tlsdesc_dynamic(size_t *a)
+// {
+// struct {size_t modidx,off;} *p = (void*)a[1];
+// size_t *dtv = *(size_t**)(tp - 8);
+// return dtv[p->modidx] + p->off - tp;
+// }
+.global __tlsdesc_dynamic
+.hidden __tlsdesc_dynamic
+.type __tlsdesc_dynamic,@function
+__tlsdesc_dynamic:
+ stp x1,x2,[sp,#-16]!
+ mrs x1,tpidr_el0 // tp
+ ldr x0,[x0,#8] // p
+ ldp x0,x2,[x0] // p->modidx, p->off
+ sub x2,x2,x1 // p->off - tp
+ ldr x1,[x1,#-8] // dtv
+ ldr x1,[x1,x0,lsl #3] // dtv[p->modidx]
+ add x0,x1,x2 // dtv[p->modidx] + p->off - tp
+ ldp x1,x2,[sp],#16
+ ret
diff --git a/libc-top-half/musl/src/ldso/arm/dlsym.s b/libc-top-half/musl/src/ldso/arm/dlsym.s
new file mode 100644
index 0000000..2652c34
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/arm/dlsym.s
@@ -0,0 +1,8 @@
+.syntax unified
+.text
+.global dlsym
+.hidden __dlsym
+.type dlsym,%function
+dlsym:
+ mov r2,lr
+ b __dlsym
diff --git a/libc-top-half/musl/src/ldso/arm/dlsym_time64.S b/libc-top-half/musl/src/ldso/arm/dlsym_time64.S
new file mode 100644
index 0000000..bb2e704
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/arm/dlsym_time64.S
@@ -0,0 +1,3 @@
+#define __dlsym __dlsym_redir_time64
+#define dlsym __dlsym_time64
+#include "dlsym.s"
diff --git a/libc-top-half/musl/src/ldso/arm/find_exidx.c b/libc-top-half/musl/src/ldso/arm/find_exidx.c
new file mode 100644
index 0000000..77c4472
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/arm/find_exidx.c
@@ -0,0 +1,42 @@
+#define _GNU_SOURCE
+#include <link.h>
+#include <stdint.h>
+
+struct find_exidx_data {
+ uintptr_t pc, exidx_start;
+ int exidx_len;
+};
+
+static int find_exidx(struct dl_phdr_info *info, size_t size, void *ptr)
+{
+ struct find_exidx_data *data = ptr;
+ const ElfW(Phdr) *phdr = info->dlpi_phdr;
+ uintptr_t addr, exidx_start = 0;
+ int i, match = 0, exidx_len = 0;
+
+ for (i = info->dlpi_phnum; i > 0; i--, phdr++) {
+ addr = info->dlpi_addr + phdr->p_vaddr;
+ switch (phdr->p_type) {
+ case PT_LOAD:
+ match |= data->pc >= addr && data->pc < addr + phdr->p_memsz;
+ break;
+ case PT_ARM_EXIDX:
+ exidx_start = addr;
+ exidx_len = phdr->p_memsz;
+ break;
+ }
+ }
+ data->exidx_start = exidx_start;
+ data->exidx_len = exidx_len;
+ return match;
+}
+
+uintptr_t __gnu_Unwind_Find_exidx(uintptr_t pc, int *pcount)
+{
+ struct find_exidx_data data;
+ data.pc = pc;
+ if (dl_iterate_phdr(find_exidx, &data) <= 0)
+ return 0;
+ *pcount = data.exidx_len / 8;
+ return data.exidx_start;
+}
diff --git a/libc-top-half/musl/src/ldso/arm/tlsdesc.S b/libc-top-half/musl/src/ldso/arm/tlsdesc.S
new file mode 100644
index 0000000..3ae133c
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/arm/tlsdesc.S
@@ -0,0 +1,55 @@
+.syntax unified
+
+.text
+.global __tlsdesc_static
+.hidden __tlsdesc_static
+.type __tlsdesc_static,%function
+__tlsdesc_static:
+ ldr r0,[r0]
+ bx lr
+
+.global __tlsdesc_dynamic
+.hidden __tlsdesc_dynamic
+.type __tlsdesc_dynamic,%function
+__tlsdesc_dynamic:
+ push {r2,r3,ip,lr}
+ ldr r1,[r0]
+ ldr r2,[r1,#4] // r2 = offset
+ ldr r1,[r1] // r1 = modid
+
+#if ((__ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \
+ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
+ mrc p15,0,r0,c13,c0,3
+#else
+ ldr r0,1f
+ add r0,r0,pc
+ ldr r0,[r0]
+2:
+#if __ARM_ARCH >= 5
+ blx r0 // r0 = tp
+#else
+#if __thumb__
+ add lr,pc,#1
+#else
+ mov lr,pc
+#endif
+ bx r0
+#endif
+#endif
+ ldr r3,[r0,#-4] // r3 = dtv
+ ldr ip,[r3,r1,LSL #2]
+ sub r0,ip,r0
+ add r0,r0,r2 // r0 = r3[r1]-r0+r2
+#if __ARM_ARCH >= 5
+ pop {r2,r3,ip,pc}
+#else
+ pop {r2,r3,ip,lr}
+ bx lr
+#endif
+
+#if ((__ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \
+ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
+#else
+ .align 2
+1: .word __a_gettp_ptr - 2b
+#endif
diff --git a/libc-top-half/musl/src/ldso/dl_iterate_phdr.c b/libc-top-half/musl/src/ldso/dl_iterate_phdr.c
new file mode 100644
index 0000000..9546dd3
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/dl_iterate_phdr.c
@@ -0,0 +1,47 @@
+#include <elf.h>
+#include <link.h>
+#include "pthread_impl.h"
+#include "libc.h"
+
+#define AUX_CNT 38
+
+extern weak hidden const size_t _DYNAMIC[];
+
+static int static_dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
+{
+ unsigned char *p;
+ ElfW(Phdr) *phdr, *tls_phdr=0;
+ size_t base = 0;
+ size_t n;
+ struct dl_phdr_info info;
+ size_t i, aux[AUX_CNT] = {0};
+
+ for (i=0; libc.auxv[i]; i+=2)
+ if (libc.auxv[i]<AUX_CNT) aux[libc.auxv[i]] = libc.auxv[i+1];
+
+ for (p=(void *)aux[AT_PHDR],n=aux[AT_PHNUM]; n; n--,p+=aux[AT_PHENT]) {
+ phdr = (void *)p;
+ if (phdr->p_type == PT_PHDR)
+ base = aux[AT_PHDR] - phdr->p_vaddr;
+ if (phdr->p_type == PT_DYNAMIC && _DYNAMIC)
+ base = (size_t)_DYNAMIC - phdr->p_vaddr;
+ if (phdr->p_type == PT_TLS)
+ tls_phdr = phdr;
+ }
+ info.dlpi_addr = base;
+ info.dlpi_name = "/proc/self/exe";
+ info.dlpi_phdr = (void *)aux[AT_PHDR];
+ info.dlpi_phnum = aux[AT_PHNUM];
+ info.dlpi_adds = 0;
+ info.dlpi_subs = 0;
+ if (tls_phdr) {
+ info.dlpi_tls_modid = 1;
+ info.dlpi_tls_data = __tls_get_addr((tls_mod_off_t[]){1,0});
+ } else {
+ info.dlpi_tls_modid = 0;
+ info.dlpi_tls_data = 0;
+ }
+ return (callback)(&info, sizeof (info), data);
+}
+
+weak_alias(static_dl_iterate_phdr, dl_iterate_phdr);
diff --git a/libc-top-half/musl/src/ldso/dladdr.c b/libc-top-half/musl/src/ldso/dladdr.c
new file mode 100644
index 0000000..e5c8020
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/dladdr.c
@@ -0,0 +1,9 @@
+#define _GNU_SOURCE
+#include <dlfcn.h>
+
+static int stub_dladdr(const void *addr, Dl_info *info)
+{
+ return 0;
+}
+
+weak_alias(stub_dladdr, dladdr);
diff --git a/libc-top-half/musl/src/ldso/dlclose.c b/libc-top-half/musl/src/ldso/dlclose.c
new file mode 100644
index 0000000..e437422
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/dlclose.c
@@ -0,0 +1,7 @@
+#include <dlfcn.h>
+#include "dynlink.h"
+
+int dlclose(void *p)
+{
+ return __dl_invalid_handle(p);
+}
diff --git a/libc-top-half/musl/src/ldso/dlerror.c b/libc-top-half/musl/src/ldso/dlerror.c
new file mode 100644
index 0000000..afe5925
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/dlerror.c
@@ -0,0 +1,87 @@
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "pthread_impl.h"
+#include "dynlink.h"
+#include "lock.h"
+#include "fork_impl.h"
+
+#define malloc __libc_malloc
+#define calloc __libc_calloc
+#define realloc __libc_realloc
+#define free __libc_free
+
+char *dlerror()
+{
+ pthread_t self = __pthread_self();
+ if (!self->dlerror_flag) return 0;
+ self->dlerror_flag = 0;
+ char *s = self->dlerror_buf;
+ if (s == (void *)-1)
+ return "Dynamic linker failed to allocate memory for error message";
+ else
+ return s;
+}
+
+static volatile int freebuf_queue_lock[1];
+static void **freebuf_queue;
+volatile int *const __dlerror_lockptr = freebuf_queue_lock;
+
+void __dl_thread_cleanup(void)
+{
+ pthread_t self = __pthread_self();
+ if (self->dlerror_buf && self->dlerror_buf != (void *)-1) {
+ LOCK(freebuf_queue_lock);
+ void **p = (void **)self->dlerror_buf;
+ *p = freebuf_queue;
+ freebuf_queue = p;
+ UNLOCK(freebuf_queue_lock);
+ }
+}
+
+hidden void __dl_vseterr(const char *fmt, va_list ap)
+{
+ LOCK(freebuf_queue_lock);
+ void **q = freebuf_queue;
+ freebuf_queue = 0;
+ UNLOCK(freebuf_queue_lock);
+
+ while (q) {
+ void **p = *q;
+ free(q);
+ q = p;
+ }
+
+ va_list ap2;
+ va_copy(ap2, ap);
+ pthread_t self = __pthread_self();
+ if (self->dlerror_buf != (void *)-1)
+ free(self->dlerror_buf);
+ size_t len = vsnprintf(0, 0, fmt, ap2);
+ if (len < sizeof(void *)) len = sizeof(void *);
+ va_end(ap2);
+ char *buf = malloc(len+1);
+ if (buf) {
+ vsnprintf(buf, len+1, fmt, ap);
+ } else {
+ buf = (void *)-1;
+ }
+ self->dlerror_buf = buf;
+ self->dlerror_flag = 1;
+}
+
+hidden void __dl_seterr(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ __dl_vseterr(fmt, ap);
+ va_end(ap);
+}
+
+static int stub_invalid_handle(void *h)
+{
+ __dl_seterr("Invalid library handle %p", (void *)h);
+ return 1;
+}
+
+weak_alias(stub_invalid_handle, __dl_invalid_handle);
diff --git a/libc-top-half/musl/src/ldso/dlinfo.c b/libc-top-half/musl/src/ldso/dlinfo.c
new file mode 100644
index 0000000..b55f5fe
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/dlinfo.c
@@ -0,0 +1,14 @@
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include "dynlink.h"
+
+int dlinfo(void *dso, int req, void *res)
+{
+ if (__dl_invalid_handle(dso)) return -1;
+ if (req != RTLD_DI_LINKMAP) {
+ __dl_seterr("Unsupported request %d", req);
+ return -1;
+ }
+ *(struct link_map **)res = dso;
+ return 0;
+}
diff --git a/libc-top-half/musl/src/ldso/dlopen.c b/libc-top-half/musl/src/ldso/dlopen.c
new file mode 100644
index 0000000..69372a2
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/dlopen.c
@@ -0,0 +1,10 @@
+#include <dlfcn.h>
+#include "dynlink.h"
+
+static void *stub_dlopen(const char *file, int mode)
+{
+ __dl_seterr("Dynamic loading not supported");
+ return 0;
+}
+
+weak_alias(stub_dlopen, dlopen);
diff --git a/libc-top-half/musl/src/ldso/dlsym.c b/libc-top-half/musl/src/ldso/dlsym.c
new file mode 100644
index 0000000..65eb276
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/dlsym.c
@@ -0,0 +1,7 @@
+#include <dlfcn.h>
+#include "dynlink.h"
+
+void *dlsym(void *restrict p, const char *restrict s)
+{
+ return __dlsym(p, s, 0);
+}
diff --git a/libc-top-half/musl/src/ldso/i386/dlsym.s b/libc-top-half/musl/src/ldso/i386/dlsym.s
new file mode 100644
index 0000000..097e30c
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/i386/dlsym.s
@@ -0,0 +1,11 @@
+.text
+.global dlsym
+.hidden __dlsym
+.type dlsym,@function
+dlsym:
+ push (%esp)
+ push 12(%esp)
+ push 12(%esp)
+ call __dlsym
+ add $12,%esp
+ ret
diff --git a/libc-top-half/musl/src/ldso/i386/dlsym_time64.S b/libc-top-half/musl/src/ldso/i386/dlsym_time64.S
new file mode 100644
index 0000000..bb2e704
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/i386/dlsym_time64.S
@@ -0,0 +1,3 @@
+#define __dlsym __dlsym_redir_time64
+#define dlsym __dlsym_time64
+#include "dlsym.s"
diff --git a/libc-top-half/musl/src/ldso/i386/tlsdesc.s b/libc-top-half/musl/src/ldso/i386/tlsdesc.s
new file mode 100644
index 0000000..32c8176
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/i386/tlsdesc.s
@@ -0,0 +1,23 @@
+.text
+.global __tlsdesc_static
+.hidden __tlsdesc_static
+.type __tlsdesc_static,@function
+__tlsdesc_static:
+ mov 4(%eax),%eax
+ ret
+
+.global __tlsdesc_dynamic
+.hidden __tlsdesc_dynamic
+.type __tlsdesc_dynamic,@function
+__tlsdesc_dynamic:
+ mov 4(%eax),%eax
+ push %edx
+ mov %gs:4,%edx
+ push %ecx
+ mov (%eax),%ecx
+ mov 4(%eax),%eax
+ add (%edx,%ecx,4),%eax
+ pop %ecx
+ sub %gs:0,%eax
+ pop %edx
+ ret
diff --git a/libc-top-half/musl/src/ldso/m68k/dlsym.s b/libc-top-half/musl/src/ldso/m68k/dlsym.s
new file mode 100644
index 0000000..5209ae1
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/m68k/dlsym.s
@@ -0,0 +1,12 @@
+.text
+.global dlsym
+.hidden __dlsym
+.type dlsym,@function
+dlsym:
+ move.l (%sp),-(%sp)
+ move.l 12(%sp),-(%sp)
+ move.l 12(%sp),-(%sp)
+ lea __dlsym-.-8,%a1
+ jsr (%pc,%a1)
+ add.l #12,%sp
+ rts
diff --git a/libc-top-half/musl/src/ldso/m68k/dlsym_time64.S b/libc-top-half/musl/src/ldso/m68k/dlsym_time64.S
new file mode 100644
index 0000000..bb2e704
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/m68k/dlsym_time64.S
@@ -0,0 +1,3 @@
+#define __dlsym __dlsym_redir_time64
+#define dlsym __dlsym_time64
+#include "dlsym.s"
diff --git a/libc-top-half/musl/src/ldso/microblaze/dlsym.s b/libc-top-half/musl/src/ldso/microblaze/dlsym.s
new file mode 100644
index 0000000..ea9d8be
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/microblaze/dlsym.s
@@ -0,0 +1,6 @@
+.global dlsym
+.hidden __dlsym
+.type dlsym,@function
+dlsym:
+ brid __dlsym
+ add r7, r15, r0
diff --git a/libc-top-half/musl/src/ldso/microblaze/dlsym_time64.S b/libc-top-half/musl/src/ldso/microblaze/dlsym_time64.S
new file mode 100644
index 0000000..bb2e704
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/microblaze/dlsym_time64.S
@@ -0,0 +1,3 @@
+#define __dlsym __dlsym_redir_time64
+#define dlsym __dlsym_time64
+#include "dlsym.s"
diff --git a/libc-top-half/musl/src/ldso/mips/dlsym.s b/libc-top-half/musl/src/ldso/mips/dlsym.s
new file mode 100644
index 0000000..1573e51
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/mips/dlsym.s
@@ -0,0 +1,17 @@
+.set noreorder
+.global dlsym
+.hidden __dlsym
+.type dlsym,@function
+dlsym:
+ lui $gp, %hi(_gp_disp)
+ addiu $gp, %lo(_gp_disp)
+ addu $gp, $gp, $25
+ move $6, $ra
+ lw $25, %call16(__dlsym)($gp)
+ addiu $sp, $sp, -16
+ sw $ra, 12($sp)
+ jalr $25
+ nop
+ lw $ra, 12($sp)
+ jr $ra
+ addiu $sp, $sp, 16
diff --git a/libc-top-half/musl/src/ldso/mips/dlsym_time64.S b/libc-top-half/musl/src/ldso/mips/dlsym_time64.S
new file mode 100644
index 0000000..bb2e704
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/mips/dlsym_time64.S
@@ -0,0 +1,3 @@
+#define __dlsym __dlsym_redir_time64
+#define dlsym __dlsym_time64
+#include "dlsym.s"
diff --git a/libc-top-half/musl/src/ldso/mips64/dlsym.s b/libc-top-half/musl/src/ldso/mips64/dlsym.s
new file mode 100644
index 0000000..32e0ddd
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/mips64/dlsym.s
@@ -0,0 +1,17 @@
+.set noreorder
+.global dlsym
+.hidden __dlsym
+.type dlsym,@function
+dlsym:
+ lui $3, %hi(%neg(%gp_rel(dlsym)))
+ daddiu $3, $3, %lo(%neg(%gp_rel(dlsym)))
+ daddu $3, $3, $25
+ move $6, $ra
+ ld $25, %got_disp(__dlsym)($3)
+ daddiu $sp, $sp, -32
+ sd $ra, 24($sp)
+ jalr $25
+ nop
+ ld $ra, 24($sp)
+ jr $ra
+ daddiu $sp, $sp, 32
diff --git a/libc-top-half/musl/src/ldso/mipsn32/dlsym.s b/libc-top-half/musl/src/ldso/mipsn32/dlsym.s
new file mode 100644
index 0000000..1c82da3
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/mipsn32/dlsym.s
@@ -0,0 +1,17 @@
+.set noreorder
+.global dlsym
+.hidden __dlsym
+.type dlsym,@function
+dlsym:
+ lui $3, %hi(%neg(%gp_rel(dlsym)))
+ addiu $3, $3, %lo(%neg(%gp_rel(dlsym)))
+ addu $3, $3, $25
+ move $6, $ra
+ lw $25, %got_disp(__dlsym)($3)
+ addiu $sp, $sp, -32
+ sd $ra, 16($sp)
+ jalr $25
+ nop
+ ld $ra, 16($sp)
+ jr $ra
+ addiu $sp, $sp, 32
diff --git a/libc-top-half/musl/src/ldso/mipsn32/dlsym_time64.S b/libc-top-half/musl/src/ldso/mipsn32/dlsym_time64.S
new file mode 100644
index 0000000..bb2e704
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/mipsn32/dlsym_time64.S
@@ -0,0 +1,3 @@
+#define __dlsym __dlsym_redir_time64
+#define dlsym __dlsym_time64
+#include "dlsym.s"
diff --git a/libc-top-half/musl/src/ldso/or1k/dlsym.s b/libc-top-half/musl/src/ldso/or1k/dlsym.s
new file mode 100644
index 0000000..122475c
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/or1k/dlsym.s
@@ -0,0 +1,6 @@
+.global dlsym
+.hidden __dlsym
+.type dlsym,@function
+dlsym:
+ l.j __dlsym
+ l.ori r5, r9, 0
diff --git a/libc-top-half/musl/src/ldso/or1k/dlsym_time64.S b/libc-top-half/musl/src/ldso/or1k/dlsym_time64.S
new file mode 100644
index 0000000..bb2e704
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/or1k/dlsym_time64.S
@@ -0,0 +1,3 @@
+#define __dlsym __dlsym_redir_time64
+#define dlsym __dlsym_time64
+#include "dlsym.s"
diff --git a/libc-top-half/musl/src/ldso/powerpc/dlsym.s b/libc-top-half/musl/src/ldso/powerpc/dlsym.s
new file mode 100644
index 0000000..cfe308e
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/powerpc/dlsym.s
@@ -0,0 +1,8 @@
+ .text
+ .global dlsym
+ .hidden __dlsym
+ .type dlsym,@function
+dlsym:
+ mflr 5 # The return address is arg3.
+ b __dlsym
+ .size dlsym, .-dlsym
diff --git a/libc-top-half/musl/src/ldso/powerpc/dlsym_time64.S b/libc-top-half/musl/src/ldso/powerpc/dlsym_time64.S
new file mode 100644
index 0000000..bb2e704
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/powerpc/dlsym_time64.S
@@ -0,0 +1,3 @@
+#define __dlsym __dlsym_redir_time64
+#define dlsym __dlsym_time64
+#include "dlsym.s"
diff --git a/libc-top-half/musl/src/ldso/powerpc64/dlsym.s b/libc-top-half/musl/src/ldso/powerpc64/dlsym.s
new file mode 100644
index 0000000..a14715f
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/powerpc64/dlsym.s
@@ -0,0 +1,11 @@
+ .text
+ .global dlsym
+ .hidden __dlsym
+ .type dlsym,@function
+dlsym:
+ addis 2, 12, .TOC.-dlsym@ha
+ addi 2, 2, .TOC.-dlsym@l
+ .localentry dlsym,.-dlsym
+ mflr 5 # The return address is arg3.
+ b __dlsym
+ .size dlsym, .-dlsym
diff --git a/libc-top-half/musl/src/ldso/riscv64/dlsym.s b/libc-top-half/musl/src/ldso/riscv64/dlsym.s
new file mode 100644
index 0000000..2bafd72
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/riscv64/dlsym.s
@@ -0,0 +1,6 @@
+.global dlsym
+.hidden __dlsym
+.type dlsym, %function
+dlsym:
+ mv a2, ra
+ tail __dlsym
diff --git a/libc-top-half/musl/src/ldso/s390x/dlsym.s b/libc-top-half/musl/src/ldso/s390x/dlsym.s
new file mode 100644
index 0000000..2e9fa8f
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/s390x/dlsym.s
@@ -0,0 +1,6 @@
+ .global dlsym
+ .hidden __dlsym
+ .type dlsym,@function
+dlsym:
+ lgr %r4, %r14
+ jg __dlsym
diff --git a/libc-top-half/musl/src/ldso/sh/dlsym.s b/libc-top-half/musl/src/ldso/sh/dlsym.s
new file mode 100644
index 0000000..11a6fff
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/sh/dlsym.s
@@ -0,0 +1,11 @@
+.text
+.global dlsym
+.hidden __dlsym
+.type dlsym, @function
+dlsym:
+ mov.l L1, r0
+1: braf r0
+ mov.l @r15, r6
+
+.align 2
+L1: .long __dlsym@PLT-(1b+4-.)
diff --git a/libc-top-half/musl/src/ldso/sh/dlsym_time64.S b/libc-top-half/musl/src/ldso/sh/dlsym_time64.S
new file mode 100644
index 0000000..bb2e704
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/sh/dlsym_time64.S
@@ -0,0 +1,3 @@
+#define __dlsym __dlsym_redir_time64
+#define dlsym __dlsym_time64
+#include "dlsym.s"
diff --git a/libc-top-half/musl/src/ldso/tlsdesc.c b/libc-top-half/musl/src/ldso/tlsdesc.c
new file mode 100644
index 0000000..49a1f18
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/tlsdesc.c
@@ -0,0 +1,9 @@
+#include <stddef.h>
+#include <dynlink.h>
+
+ptrdiff_t __tlsdesc_static()
+{
+ return 0;
+}
+
+weak_alias(__tlsdesc_static, __tlsdesc_dynamic);
diff --git a/libc-top-half/musl/src/ldso/x32/dlsym.s b/libc-top-half/musl/src/ldso/x32/dlsym.s
new file mode 100644
index 0000000..d840b95
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/x32/dlsym.s
@@ -0,0 +1,7 @@
+.text
+.global dlsym
+.hidden __dlsym
+.type dlsym,@function
+dlsym:
+ mov (%rsp),%rdx
+ jmp __dlsym
diff --git a/libc-top-half/musl/src/ldso/x86_64/dlsym.s b/libc-top-half/musl/src/ldso/x86_64/dlsym.s
new file mode 100644
index 0000000..d840b95
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/x86_64/dlsym.s
@@ -0,0 +1,7 @@
+.text
+.global dlsym
+.hidden __dlsym
+.type dlsym,@function
+dlsym:
+ mov (%rsp),%rdx
+ jmp __dlsym
diff --git a/libc-top-half/musl/src/ldso/x86_64/tlsdesc.s b/libc-top-half/musl/src/ldso/x86_64/tlsdesc.s
new file mode 100644
index 0000000..e08f1d7
--- /dev/null
+++ b/libc-top-half/musl/src/ldso/x86_64/tlsdesc.s
@@ -0,0 +1,23 @@
+.text
+.global __tlsdesc_static
+.hidden __tlsdesc_static
+.type __tlsdesc_static,@function
+__tlsdesc_static:
+ mov 8(%rax),%rax
+ ret
+
+.global __tlsdesc_dynamic
+.hidden __tlsdesc_dynamic
+.type __tlsdesc_dynamic,@function
+__tlsdesc_dynamic:
+ mov 8(%rax),%rax
+ push %rdx
+ mov %fs:8,%rdx
+ push %rcx
+ mov (%rax),%rcx
+ mov 8(%rax),%rax
+ add (%rdx,%rcx,8),%rax
+ pop %rcx
+ sub %fs:0,%rax
+ pop %rdx
+ ret