about summary refs log tree commit diff
path: root/src/ldso
diff options
context:
space:
mode:
Diffstat (limited to 'src/ldso')
-rw-r--r--src/ldso/dynlink.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index 86d4b803..b26992d3 100644
--- a/src/ldso/dynlink.c
+++ b/src/ldso/dynlink.c
@@ -467,6 +467,7 @@ void *__dynlink(int argc, char **argv, size_t *got)
 	size_t i;
 	Phdr *phdr;
 	Ehdr *ehdr;
+	size_t *lib_dynv;
 	static struct dso builtin_dsos[3];
 	struct dso *const app = builtin_dsos+0;
 	struct dso *const lib = builtin_dsos+1;
@@ -498,8 +499,16 @@ void *__dynlink(int argc, char **argv, size_t *got)
 		}
 	}
 
-	/* Relocate ldso's DYNAMIC pointer and load vector */
-	decode_vec((void *)(got[0] += aux[AT_BASE]), lib_dyn, DYN_CNT);
+	/* Find the dynamic linker's DYNAMIC section and decode it */
+	ehdr = (void *)aux[AT_BASE];
+	phdr = (void *)(aux[AT_BASE] + ehdr->e_phoff);
+	for (i=ehdr->e_phnum; i--; phdr=(void *)((char *)phdr + ehdr->e_phentsize)) {
+		if (phdr->p_type == PT_DYNAMIC) {
+			lib_dynv = (void *)(aux[AT_BASE] + phdr->p_vaddr);
+			decode_vec(lib_dynv, lib_dyn, DYN_CNT);
+			break;
+		}
+	}
 
 	/* Find the program image's DYNAMIC section and decode it */
 	phdr = (void *)aux[AT_PHDR];
@@ -526,7 +535,7 @@ void *__dynlink(int argc, char **argv, size_t *got)
 		.strings = (void *)(aux[AT_BASE]+lib_dyn[DT_STRTAB]),
 		.hashtab = (void *)(aux[AT_BASE]+lib_dyn[DT_HASH]),
 		.syms = (void *)(aux[AT_BASE]+lib_dyn[DT_SYMTAB]),
-		.dynv = (void *)(got[0]),
+		.dynv = lib_dynv,
 		.name = "libc.so",
 		.global = 1,
 		.relocated = 1