+#ifdef SHARED
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
static void error(const char *, ...);
-#ifdef SHARED
-
#define MAXP2(a,b) (-(-(a)&-(b)))
#define ALIGN(x,y) ((x)+(y)-1 & -(y))
struct debug *_dl_debug_addr = &debug;
+__attribute__((__visibility__("hidden")))
+void (*const __init_array_start)(void)=0, (*const __fini_array_start)(void)=0;
+
+__attribute__((__visibility__("hidden")))
+extern void (*const __init_array_end)(void), (*const __fini_array_end)(void);
+
+weak_alias(__init_array_start, __init_array_end);
+weak_alias(__fini_array_start, __fini_array_end);
+
static int dl_strcmp(const char *l, const char *r)
{
for (; *l==*r && *l; l++, r++);
((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
((ph->p_flags&PF_X) ? PROT_EXEC : 0));
map = mmap(0, ph->p_memsz + (ph->p_vaddr & PAGE_SIZE-1),
- prot, (prot&PROT_WRITE) ? MAP_PRIVATE : MAP_SHARED,
+ prot, MAP_PRIVATE,
fd, ph->p_offset & -PAGE_SIZE);
if (map == MAP_FAILED) {
unmap_library(dso);
/* Get new DTV space from new DSO if needed */
if (v[0] > (size_t)self->dtv[0]) {
void **newdtv = p->new_dtv +
- (v[0]+1)*sizeof(void *)*a_fetch_add(&p->new_dtv_idx,1);
+ (v[0]+1)*a_fetch_add(&p->new_dtv_idx,1);
memcpy(newdtv, self->dtv,
((size_t)self->dtv[0]+1) * sizeof(void *));
newdtv[0] = (void *)v[0];
}
argv[-1] = (void *)(argc - (argv-argv_orig));
if (!argv[0]) {
- dprintf(2, "musl libc\n"
+ dprintf(2, "musl libc (" LDSO_ARCH ")\n"
"Version %s\n"
"Dynamic Program Loader\n"
"Usage: %s [options] [--] pathname%s\n",
return p;
}
-static int invalid_dso_handle(void *h)
+__attribute__((__visibility__("hidden")))
+int __dl_invalid_handle(void *h)
{
struct dso *p;
for (p=head; p; p=p->next) if (h==p) return 0;
return def.dso->funcdescs + (def.sym - def.dso->syms);
return laddr(def.dso, def.sym->st_value);
}
- if (invalid_dso_handle(p))
+ if (__dl_invalid_handle(p))
return 0;
if ((ght = p->ghashtab)) {
gh = gnu_hash(s);
return 0;
}
-int __dladdr(const void *addr, Dl_info *info)
+int dladdr(const void *addr, Dl_info *info)
{
struct dso *p;
Sym *sym, *bestsym;
}
return ret;
}
-#else
-static int invalid_dso_handle(void *h)
-{
- error("Invalid library handle %p", (void *)h);
- return 1;
-}
-void *dlopen(const char *file, int mode)
-{
- error("Dynamic loading not supported");
- return 0;
-}
-void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
-{
- error("Symbol not found: %s", s);
- return 0;
-}
-int __dladdr (const void *addr, Dl_info *info)
-{
- return 0;
-}
-#endif
-
-int __dlinfo(void *dso, int req, void *res)
-{
- if (invalid_dso_handle(dso)) return -1;
- if (req != RTLD_DI_LINKMAP) {
- error("Unsupported request %d", req);
- return -1;
- }
- *(struct link_map **)res = dso;
- return 0;
-}
-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;
-}
-
-int dlclose(void *p)
-{
- return invalid_dso_handle(p);
-}
-
-void __dl_thread_cleanup(void)
-{
- pthread_t self = __pthread_self();
- if (self->dlerror_buf != (void *)-1)
- free(self->dlerror_buf);
-}
+__attribute__((__visibility__("hidden")))
+void __dl_vseterr(const char *, va_list);
static void error(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
-#ifdef SHARED
if (!runtime) {
vdprintf(2, fmt, ap);
dprintf(2, "\n");
va_end(ap);
return;
}
-#endif
- pthread_t self = __pthread_self();
- if (self->dlerror_buf != (void *)-1)
- free(self->dlerror_buf);
- size_t len = vsnprintf(0, 0, fmt, ap);
+ __dl_vseterr(fmt, ap);
va_end(ap);
- char *buf = malloc(len+1);
- if (buf) {
- va_start(ap, fmt);
- vsnprintf(buf, len+1, fmt, ap);
- va_end(ap);
- } else {
- buf = (void *)-1;
- }
- self->dlerror_buf = buf;
- self->dlerror_flag = 1;
}
+#endif