adapt static dl_iterate_phdr not to depend on !defined(SHARED)
[oweals/musl.git] / src / ldso / dynlink.c
index 2d24c78d56b8efd6a5a481bef4593384fc8ef1aa..e328679b877e913710de7cd0b353296e9eb36864 100644 (file)
@@ -1,3 +1,4 @@
+#ifdef SHARED
 #define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
@@ -23,8 +24,6 @@
 
 static void error(const char *, ...);
 
-#ifdef SHARED
-
 #define MAXP2(a,b) (-(-(a)&-(b)))
 #define ALIGN(x,y) ((x)+(y)-1 & -(y))
 
@@ -134,6 +133,15 @@ static struct fdpic_dummy_loadmap app_dummy_loadmap;
 
 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++);
@@ -602,7 +610,7 @@ static void *map_library(int fd, struct dso *dso)
                                ((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);
@@ -1271,7 +1279,7 @@ void *__tls_get_new(size_t *v)
        /* 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];
@@ -1477,7 +1485,7 @@ _Noreturn void __dls3(size_t *sp)
                }
                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",
@@ -1724,7 +1732,8 @@ end:
        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;
@@ -1779,7 +1788,7 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra)
                        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);
@@ -1814,7 +1823,7 @@ failed:
        return 0;
 }
 
-int __dladdr(const void *addr, Dl_info *info)
+int dladdr(const void *addr, Dl_info *info)
 {
        struct dso *p;
        Sym *sym, *bestsym;
@@ -1903,68 +1912,14 @@ int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void
        }
        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");
@@ -1972,20 +1927,7 @@ static void error(const char *fmt, ...)
                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