about summary refs log tree commit diff
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
musl-88207361ea3ece1141af2adeac6069aa866e0de0.tar.xz
musl-88207361ea3ece1141af2adeac6069aa866e0de0.zip
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;
 }