]> granicus.if.org Git - musl/commitdiff
record preloaded libraries as direct pseudo-dependencies of main app
authorRich Felker <dalias@aerifal.cx>
Fri, 1 Mar 2019 20:09:16 +0000 (15:09 -0500)
committerRich Felker <dalias@aerifal.cx>
Sat, 2 Mar 2019 22:29:29 +0000 (17:29 -0500)
this makes calling dlsym on the main app more consistent with the
global symbol table (load order), and is a prerequisite for
dependency-order ctor execution to work correctly with LD_PRELOAD.

ldso/dynlink.c

index c230b833256b6692bf6fae6ab157897b7a6a7c54..2617d553eebd992a6b8974bde92999a0b989ab5e 100644 (file)
@@ -1146,16 +1146,23 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
 
 static void load_direct_deps(struct dso *p)
 {
-       size_t i, cnt;
+       size_t i, cnt=0;
        if (p->deps) return;
-       for (i=cnt=0; p->dynv[i]; i+=2)
+       /* For head, all preloads are direct pseudo-dependencies.
+        * Count and include them now to avoid realloc later. */
+       if (p==head) for (struct dso *q=p->next; q; q=q->next)
+               cnt++;
+       for (i=0; p->dynv[i]; i+=2)
                if (p->dynv[i] == DT_NEEDED) cnt++;
        p->deps = calloc(cnt+1, sizeof *p->deps);
        if (!p->deps) {
                error("Error loading dependencies for %s", p->name);
                if (runtime) longjmp(*rtld_fail, 1);
        }
-       for (i=cnt=0; p->dynv[i]; i+=2) {
+       cnt=0;
+       if (p==head) for (struct dso *q=p->next; q; q=q->next)
+               p->deps[cnt++] = q;
+       for (i=0; p->dynv[i]; i+=2) {
                if (p->dynv[i] != DT_NEEDED) continue;
                struct dso *dep = load_library(p->strings + p->dynv[i+1], p);
                if (!dep) {
@@ -1165,8 +1172,8 @@ static void load_direct_deps(struct dso *p)
                        continue;
                }
                p->deps[cnt++] = dep;
-               p->deps[cnt] = 0;
        }
+       p->deps[cnt] = 0;
        p->ndeps_direct = cnt;
 }