diff -Nurp -x sysdeps -x internals -x '*.a' -x '*swp' -x '*.so*' -x '*.o' -x '*progname*' -x include -x '*config*' uClibc-0.9.23/ldso/ldso/ldso.c uClibc-0.9.23-pax/ldso/ldso/ldso.c --- uClibc-0.9.23/ldso/ldso/ldso.c 2003-10-04 19:31:22.000000000 +0200 +++ uClibc-0.9.23-pax/ldso/ldso/ldso.c 2003-11-14 17:32:00.000000000 +0100 @@ -371,6 +371,26 @@ LD_BOOT(unsigned long args) app_tpnt = LD_MALLOC(sizeof(struct elf_resolve)); _dl_memset(app_tpnt, 0, sizeof(struct elf_resolve)); + /* Find the runtime load address of the main executable, this may be + * different from what the ELF header says for ET_DYN/PIE executables. + */ + { + ElfW(Phdr) *ppnt; + int i; + + ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr; + for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) + if (ppnt->p_type == PT_PHDR) { + app_tpnt->loadaddr = (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - ppnt->p_vaddr); + break; + } + } + +#ifdef __SUPPORT_LD_DEBUG_EARLY__ + SEND_STDERR("app_tpnt->loadaddr="); + SEND_ADDRESS_STDERR(app_tpnt->loadaddr, 1); +#endif + /* * This is used by gdb to locate the chain of shared libraries that are currently loaded. */ @@ -407,7 +427,7 @@ LD_BOOT(unsigned long args) ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr; for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) if (ppnt->p_type == PT_DYNAMIC) { - dpnt = (Elf32_Dyn *) ppnt->p_vaddr; + dpnt = (Elf32_Dyn *) (ppnt->p_vaddr + app_tpnt->loadaddr); while (dpnt->d_tag) { #if defined(__mips__) if (dpnt->d_tag == DT_MIPS_GOTSYM) @@ -501,8 +521,8 @@ LD_BOOT(unsigned long args) ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr; for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) { if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W)) - _dl_mprotect((void *) (ppnt->p_vaddr & PAGE_ALIGN), - (ppnt->p_vaddr & ADDR_ALIGN) + + _dl_mprotect((void *) ((ppnt->p_vaddr + app_tpnt->loadaddr) & PAGE_ALIGN), + ((ppnt->p_vaddr + app_tpnt->loadaddr) & ADDR_ALIGN) + (unsigned long) ppnt->p_filesz, PROT_READ | PROT_WRITE | PROT_EXEC); } @@ -715,8 +735,8 @@ static void _dl_get_ready_to_run(struct ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr; for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) { if (ppnt->p_type == PT_LOAD) { - if (ppnt->p_vaddr + ppnt->p_memsz > brk_addr) - brk_addr = ppnt->p_vaddr + ppnt->p_memsz; + if (ppnt->p_vaddr + app_tpnt->loadaddr + ppnt->p_memsz > brk_addr) + brk_addr = ppnt->p_vaddr + app_tpnt->loadaddr + ppnt->p_memsz; } if (ppnt->p_type == PT_DYNAMIC) { #ifndef ALLOW_ZERO_PLTGOT @@ -725,8 +745,8 @@ static void _dl_get_ready_to_run(struct continue; #endif /* OK, we have what we need - slip this one into the list. */ - app_tpnt = _dl_add_elf_hash_table("", 0, - app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz); + app_tpnt = _dl_add_elf_hash_table("", (char *)app_tpnt->loadaddr, + app_tpnt->dynamic_info, ppnt->p_vaddr + app_tpnt->loadaddr, ppnt->p_filesz); _dl_loaded_modules->libtype = elf_executable; _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr; _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val; @@ -735,7 +755,7 @@ static void _dl_get_ready_to_run(struct rpnt->dyn = _dl_loaded_modules; app_tpnt->usage_count++; app_tpnt->symbol_scope = _dl_symbol_tables; - lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]); + lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT] + app_tpnt->loadaddr); #ifdef ALLOW_ZERO_PLTGOT if (lpnt) #endif