summaryrefslogtreecommitdiff
path: root/ldso
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2019-03-01 15:09:16 -0500
committerRich Felker <dalias@aerifal.cx>2019-03-02 17:29:29 -0500
commit88207361ea3ece1141af2adeac6069aa866e0de0 (patch)
tree23668c3ce9edf635de6589624b03af6165607c1f /ldso
parent0c5c8f5da6e36fe4ab704bee0cd981837859e23f (diff)
downloadmusl-88207361ea3ece1141af2adeac6069aa866e0de0.tar.gz
record preloaded libraries as direct pseudo-dependencies of main app
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.
Diffstat (limited to 'ldso')
-rw-r--r--ldso/dynlink.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index c230b833..2617d553 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -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;
}