[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