- /* Relocate ldso's DYNAMIC pointer and load vector */
- decode_vec((void *)(got[0] += aux[AT_BASE]), lib_dyn, DYN_CNT);
-
- /* Find the program image's DYNAMIC section and decode it */
- phdr = (void *)aux[AT_PHDR];
- for (i=aux[AT_PHNUM]; i--; phdr=(void *)((char *)phdr + aux[AT_PHENT])) {
- if (phdr->p_type == PT_DYNAMIC) {
- decode_vec((void *)phdr->p_vaddr, app_dyn, DYN_CNT);
- break;
- }
- }
-
- *app = (struct dso){
- .base = 0,
- .strings = (void *)(app_dyn[DT_STRTAB]),
- .hashtab = (void *)(app_dyn[DT_HASH]),
- .syms = (void *)(app_dyn[DT_SYMTAB]),
- .dynv = (void *)(phdr->p_vaddr),
- .name = argv[0],
- .global = 1,
- .next = lib
- };
-
- *lib = (struct dso){
- .base = (void *)aux[AT_BASE],
- .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]),
- .name = "libc.so",
- .global = 1,
- .relocated = 1
- };
-
- if (vdso_base) {
+ /* The dynamic linker load address is passed by the kernel
+ * in the AUX vector, so this is easy. */
+ lib->base = (void *)aux[AT_BASE];
+ lib->name = "libc.so";
+ lib->global = 1;
+ ehdr = (void *)lib->base;
+ lib->dynv = (void *)(lib->base + find_dyn(
+ (void *)(aux[AT_BASE]+ehdr->e_phoff),
+ ehdr->e_phnum, ehdr->e_phentsize));
+ decode_dyn(lib);
+
+ /* Assume base address of 0 for the main program. This is not
+ * valid for PIE code; we will have to search the PHDR to get
+ * the correct load address in the PIE case (not yet supported). */
+ app->base = 0;
+ app->name = argv[0];
+ app->global = 1;
+ app->dynv = (void *)(app->base + find_dyn(
+ (void *)aux[AT_PHDR], aux[AT_PHNUM], aux[AT_PHENT]));
+ decode_dyn(app);
+
+ /* Attach to vdso, if provided by the kernel */
+ for (i=0; auxv[i]; i+=2) {
+ size_t vdso_base = auxv[i+1];
+ if (auxv[i] != AT_SYSINFO_EHDR) continue;