[uClibc] was initfini, crt[in].S changes and ET_DYN
pageexec at freemail.hu
pageexec at freemail.hu
Sun Nov 9 01:05:29 UTC 2003
> > the problem i found is that it assumes that the virtual addresses in
> > the ELF header of the main executable will be the runtime load
> > addresses. this is a wrong assumption, and it breaks badly for ET_DYN
> > executables since they're linked at a base of 0 but loaded elsewhere
> > (under PaX that would even be a random address). the fix is of course
> > to learn the runtime load address and make use of it instead of the
> > one in the ELF header.
ok, i ported the patch to 0.9.22 and managed to compile a working
ET_DYN executable. what i did is a very rude/quick fix for getting
it to work, there are code paths that i didn't touch (but should
be still fixed) nor is my method the best way to do it, i'll leave
doing this properly up to you now.
-------------- next part --------------
Files uClibc-0.9.22/ldso/ldso/.ldso.c.swp and uClibc-0.9.22-pax/ldso/ldso/.ldso.c.swp differ
diff -Nurp -x config -x .config uClibc-0.9.22/ldso/ldso/ldso.c uClibc-0.9.22-pax/ldso/ldso/ldso.c
--- uClibc-0.9.22/ldso/ldso/ldso.c 2003-10-04 19:31:22.000000000 +0200
+++ uClibc-0.9.22-pax/ldso/ldso/ldso.c 2003-11-09 01:52:56.000000000 +0100
@@ -403,11 +403,24 @@ LD_BOOT(unsigned long args)
{
ElfW(Phdr) *ppnt;
int i;
+ unsigned long bias = 0UL;
ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
- for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++)
+ for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
+ if (ppnt->p_type == PT_PHDR) {
+ bias = auxvt[AT_PHDR].a_un.a_ptr - ppnt->p_vaddr;
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+ SEND_STDERR("bias: ");
+ SEND_ADDRESS_STDERR(bias, 1);
+#endif
+ }
+
if (ppnt->p_type == PT_DYNAMIC) {
- dpnt = (Elf32_Dyn *) ppnt->p_vaddr;
+ dpnt = (Elf32_Dyn *) (ppnt->p_vaddr + bias);
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+ SEND_STDERR("dpnt: ");
+ SEND_ADDRESS_STDERR(dpnt, 1);
+#endif
while (dpnt->d_tag) {
#if defined(__mips__)
if (dpnt->d_tag == DT_MIPS_GOTSYM)
@@ -447,6 +460,7 @@ LD_BOOT(unsigned long args)
dpnt++;
}
}
+ }
}
#ifdef __SUPPORT_LD_DEBUG_EARLY__
@@ -658,7 +672,7 @@ static void _dl_get_ready_to_run(struct
struct dyn_elf *rpnt;
struct elf_resolve *tcurr;
struct elf_resolve *tpnt1;
- unsigned long brk_addr, *lpnt;
+ unsigned long brk_addr, *lpnt, bias = 0UL;
int (*_dl_atexit) (void *);
#if defined (__SUPPORT_LD_DEBUG__)
int (*_dl_on_exit) (void (*FUNCTION)(int STATUS, void *ARG),void*);
@@ -714,9 +728,12 @@ 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_PHDR) {
+ bias = auxvt[AT_PHDR].a_un.a_ptr - ppnt->p_vaddr;
+ }
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 + bias + ppnt->p_memsz > brk_addr)
+ brk_addr = ppnt->p_vaddr + bias + ppnt->p_memsz;
}
if (ppnt->p_type == PT_DYNAMIC) {
#ifndef ALLOW_ZERO_PLTGOT
@@ -725,8 +742,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("", bias,
+ app_tpnt->dynamic_info, ppnt->p_vaddr + bias, 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 +752,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] + bias);
#ifdef ALLOW_ZERO_PLTGOT
if (lpnt)
#endif
More information about the uClibc
mailing list