fix stderr locking and ferror semantics in getopt message printing
[musl] / src / ldso / dynlink.c
index a08300d..00af886 100644 (file)
@@ -233,6 +233,10 @@ static Sym *gnu_lookup(const char *s, uint32_t h1, struct dso *dso)
 #define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)
 #define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
 
+#ifndef ARCH_SYM_REJECT_UND
+#define ARCH_SYM_REJECT_UND(s) 0
+#endif
+
 static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
 {
        uint32_t h = 0, gh = 0;
@@ -249,7 +253,8 @@ static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
                }
                if (!sym) continue;
                if (!sym->st_shndx)
-                       if (need_def || (sym->st_info&0xf) == STT_TLS)
+                       if (need_def || (sym->st_info&0xf) == STT_TLS
+                           || ARCH_SYM_REJECT_UND(sym))
                                continue;
                if (!sym->st_value)
                        if ((sym->st_info&0xf) != STT_TLS)
@@ -640,6 +645,8 @@ static void decode_dyn(struct dso *p)
                p->hashtab = (void *)(p->base + dyn[DT_HASH]);
        if (dyn[0]&(1<<DT_RPATH))
                p->rpath_orig = (void *)(p->strings + dyn[DT_RPATH]);
+       if (dyn[0]&(1<<DT_RUNPATH))
+               p->rpath_orig = (void *)(p->strings + dyn[DT_RUNPATH]);
        if (search_vec(p->dynv, dyn, DT_GNU_HASH))
                p->ghashtab = (void *)(p->base + *dyn);
        if (search_vec(p->dynv, dyn, DT_VERSYM))
@@ -658,6 +665,11 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
        int n_th = 0;
        int is_self = 0;
 
+       if (!*name) {
+               errno = EINVAL;
+               return 0;
+       }
+
        /* Catch and block attempts to reload the implementation itself */
        if (name[0]=='l' && name[1]=='i' && name[2]=='b') {
                static const char *rp, reserved[] =
@@ -857,8 +869,8 @@ static void load_preload(char *s)
        int tmp;
        char *z;
        for (z=s; *z; s=z) {
-               for (   ; *s && isspace(*s); s++);
-               for (z=s; *z && !isspace(*z); z++);
+               for (   ; *s && (isspace(*s) || *s==':'); s++);
+               for (z=s; *z && !isspace(*z) && *z!=':'; z++);
                tmp = *z;
                *z = 0;
                load_library(s, 0);
@@ -1116,6 +1128,7 @@ void *__dynlink(int argc, char **argv)
                libc.secure = 1;
        }
        libc.page_size = aux[AT_PAGESZ];
+       libc.auxv = auxv;
 
        /* If the dynamic linker was invoked as a program itself, AT_BASE
         * will not be set. In that case, we assume the base address is
@@ -1593,10 +1606,14 @@ static int invalid_dso_handle(void *h)
 }
 void *dlopen(const char *file, int mode)
 {
+       strcpy(errbuf, "Dynamic loading not supported");
+       errflag = 1;
        return 0;
 }
 void *__dlsym(void *restrict p, const char *restrict s, void *restrict ra)
 {
+       errflag = 1;
+       snprintf(errbuf, sizeof errbuf, "Symbol not found: %s", s);
        return 0;
 }
 int __dladdr (const void *addr, Dl_info *info)