ソースを参照

Move the app specific stuff from dl-startup.c to ldso.c.

Joakim Tjernlund 21 年 前
コミット
0a98c1b6b0
3 ファイル変更93 行追加101 行削除
  1. 1 2
      ldso/include/ldso.h
  2. 2 97
      ldso/ldso/dl-startup.c
  3. 90 2
      ldso/ldso/ldso.c

+ 1 - 2
ldso/include/ldso.h

@@ -67,8 +67,7 @@ extern void _dl_unsetenv(const char *symbol, char **envp);
 extern char *_dl_strdup(const char *string);
 extern char *_dl_strdup(const char *string);
 extern void _dl_dprintf(int, const char *, ...);
 extern void _dl_dprintf(int, const char *, ...);
 
 
-extern void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt,
-		unsigned long load_addr, unsigned long *hash_addr,
+extern void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
 		Elf32_auxv_t auxvt[AT_EGID + 1], char **envp, struct r_debug *debug_addr,
 		Elf32_auxv_t auxvt[AT_EGID + 1], char **envp, struct r_debug *debug_addr,
 		unsigned char *malloc_buffer, unsigned char *mmap_zero, char **argv);
 		unsigned char *malloc_buffer, unsigned char *mmap_zero, char **argv);
 
 

+ 2 - 97
ldso/ldso/dl-startup.c

@@ -127,7 +127,6 @@ DL_BOOT(unsigned long args)
 	int goof = 0;
 	int goof = 0;
 	ElfW(Ehdr) *header;
 	ElfW(Ehdr) *header;
 	struct elf_resolve *tpnt;
 	struct elf_resolve *tpnt;
-	struct elf_resolve *app_tpnt;
 	Elf32_auxv_t auxvt[AT_EGID + 1];
 	Elf32_auxv_t auxvt[AT_EGID + 1];
 	unsigned char *malloc_buffer, *mmap_zero;
 	unsigned char *malloc_buffer, *mmap_zero;
 	Elf32_Dyn *dpnt;
 	Elf32_Dyn *dpnt;
@@ -299,28 +298,6 @@ found_got:
 
 
 	tpnt = LD_MALLOC(sizeof(struct elf_resolve));
 	tpnt = LD_MALLOC(sizeof(struct elf_resolve));
 	_dl_memset(tpnt, 0, sizeof(struct elf_resolve));
 	_dl_memset(tpnt, 0, sizeof(struct elf_resolve));
-	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.
-	 */
-	{
-		int i;
-		ElfW(Phdr) *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__
-		if (app_tpnt->loadaddr) {
-			SEND_STDERR("Position Independent Executable: 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.
 	 * This is used by gdb to locate the chain of shared libraries that are currently loaded.
@@ -350,62 +327,6 @@ found_got:
 		}
 		}
 		dpnt++;
 		dpnt++;
 	}
 	}
-
-	{
-		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_DYNAMIC) {
-				dpnt = (Elf32_Dyn *) (ppnt->p_vaddr + app_tpnt->loadaddr);
-				while (dpnt->d_tag) {
-#if defined(__mips__)
-					if (dpnt->d_tag == DT_MIPS_GOTSYM)
-						app_tpnt->mips_gotsym =
-							(unsigned long) dpnt->d_un.d_val;
-					if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
-						app_tpnt->mips_local_gotno =
-							(unsigned long) dpnt->d_un.d_val;
-					if (dpnt->d_tag == DT_MIPS_SYMTABNO)
-						app_tpnt->mips_symtabno =
-							(unsigned long) dpnt->d_un.d_val;
-					if (dpnt->d_tag > DT_JMPREL) {
-						dpnt++;
-						continue;
-					}
-					app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
-
-					if (dpnt->d_tag == DT_DEBUG) {
-						/* Allow writing debug_addr into the .dynamic segment.
-						 * Even though the program header is marked RWE, the kernel gives
-						 * it to us rx.
-						 */
-						Elf32_Addr mpa = (ppnt->p_vaddr + app_tpnt->loadaddr) & ~(pagesize - 1);
-						Elf32_Word mps = ((ppnt->p_vaddr + app_tpnt->loadaddr) - mpa) + ppnt->p_memsz;
-						if(_dl_mprotect(mpa, mps, PROT_READ | PROT_WRITE | PROT_EXEC)) {
-							SEND_STDERR("Couldn't mprotect .dynamic segment to rwx.\n");
-							_dl_exit(0);
-						}
-						dpnt->d_un.d_val = (unsigned long) debug_addr;
-					}
-#else
-					if (dpnt->d_tag > DT_JMPREL) {
-						dpnt++;
-						continue;
-					}
-					app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
-					if (dpnt->d_tag == DT_DEBUG) {
-						dpnt->d_un.d_val = (unsigned long) debug_addr;
-					}
-#endif
-					if (dpnt->d_tag == DT_TEXTREL)
-						app_tpnt->dynamic_info[DT_TEXTREL] = 1;
-					dpnt++;
-				}
-			}
-	}
-
 #ifdef __SUPPORT_LD_DEBUG_EARLY__
 #ifdef __SUPPORT_LD_DEBUG_EARLY__
 	SEND_STDERR("done scanning DYNAMIC section\n");
 	SEND_STDERR("done scanning DYNAMIC section\n");
 #endif
 #endif
@@ -436,24 +357,8 @@ found_got:
 				}
 				}
 			}
 			}
 		}
 		}
-
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
-		SEND_STDERR("calling mprotect on the application program\n");
-#endif
-		/* Now cover the application program. */
-		if (app_tpnt->dynamic_info[DT_TEXTREL]) {
-			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 + app_tpnt->loadaddr) & PAGE_ALIGN),
-						((ppnt->p_vaddr + app_tpnt->loadaddr) & ADDR_ALIGN) +
-						(unsigned long) ppnt->p_filesz,
-						PROT_READ | PROT_WRITE | PROT_EXEC);
-			}
-		}
 	}
 	}
 #endif
 #endif
-
 #if defined(__mips__)
 #if defined(__mips__)
 #ifdef __SUPPORT_LD_DEBUG_EARLY__
 #ifdef __SUPPORT_LD_DEBUG_EARLY__
 	SEND_STDERR("About to do MIPS specific GOT bootstrap\n");
 	SEND_STDERR("About to do MIPS specific GOT bootstrap\n");
@@ -527,8 +432,8 @@ found_got:
 	   free to start using global variables, since these things have all been
 	   free to start using global variables, since these things have all been
 	   fixed up by now.  Still no function calls outside of this library ,
 	   fixed up by now.  Still no function calls outside of this library ,
 	   since the dynamic resolver is not yet ready. */
 	   since the dynamic resolver is not yet ready. */
-	_dl_get_ready_to_run(tpnt, app_tpnt, load_addr, 0,
-			auxvt, envp, debug_addr, malloc_buffer, mmap_zero, argv);
+	_dl_get_ready_to_run(tpnt, load_addr, auxvt, envp,
+			     debug_addr, malloc_buffer, mmap_zero, argv);
 
 
 
 
 	/* Transfer control to the application.  */
 	/* Transfer control to the application.  */

+ 90 - 2
ldso/ldso/ldso.c

@@ -84,17 +84,19 @@ static void debug_fini (int status, void *arg)
 }
 }
 #endif
 #endif
 
 
-void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt,
-		unsigned long load_addr, unsigned long *hash_addr,
+void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
 		Elf32_auxv_t auxvt[AT_EGID + 1], char **envp, struct r_debug *debug_addr,
 		Elf32_auxv_t auxvt[AT_EGID + 1], char **envp, struct r_debug *debug_addr,
 		unsigned char *malloc_buffer, unsigned char *mmap_zero, char **argv)
 		unsigned char *malloc_buffer, unsigned char *mmap_zero, char **argv)
 {
 {
 	ElfW(Phdr) *ppnt;
 	ElfW(Phdr) *ppnt;
+	Elf32_Dyn *dpnt;
 	char *lpntstr;
 	char *lpntstr;
 	int i, goof = 0, unlazy = 0, trace_loaded_objects = 0;
 	int i, goof = 0, unlazy = 0, trace_loaded_objects = 0;
 	struct dyn_elf *rpnt;
 	struct dyn_elf *rpnt;
 	struct elf_resolve *tcurr;
 	struct elf_resolve *tcurr;
 	struct elf_resolve *tpnt1;
 	struct elf_resolve *tpnt1;
+	struct elf_resolve app_tpnt_tmp;
+	struct elf_resolve *app_tpnt = &app_tpnt_tmp;
 	unsigned long brk_addr, *lpnt;
 	unsigned long brk_addr, *lpnt;
 	int (*_dl_atexit) (void *);
 	int (*_dl_atexit) (void *);
 #if defined (__SUPPORT_LD_DEBUG__)
 #if defined (__SUPPORT_LD_DEBUG__)
@@ -152,6 +154,27 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
 	   and figure out which libraries are supposed to be called.  Until
 	   and figure out which libraries are supposed to be called.  Until
 	   we have this list, we will not be completely ready for dynamic linking */
 	   we have this list, we will not be completely ready for dynamic linking */
 
 
+	/* Find the runtime load address of the main executable, this may be
+	 * different from what the ELF header says for ET_DYN/PIE executables.
+	 */
+	{
+		int i;
+		ElfW(Phdr) *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__
+		if (app_tpnt->loadaddr) {
+			SEND_STDERR("Position Independent Executable: app_tpnt->loadaddr=");
+			SEND_ADDRESS_STDERR(app_tpnt->loadaddr, 1);
+		}
+#endif
+	}
+
+
 	ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
 	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_LOAD) {
 		if (ppnt->p_type == PT_LOAD) {
@@ -159,6 +182,71 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
 				brk_addr = ppnt->p_vaddr + app_tpnt->loadaddr + ppnt->p_memsz;
 				brk_addr = ppnt->p_vaddr + app_tpnt->loadaddr + ppnt->p_memsz;
 		}
 		}
 		if (ppnt->p_type == PT_DYNAMIC) {
 		if (ppnt->p_type == PT_DYNAMIC) {
+			dpnt = (Elf32_Dyn *) (ppnt->p_vaddr + app_tpnt->loadaddr);
+			while (dpnt->d_tag) {
+#if defined(__mips__)
+				if (dpnt->d_tag == DT_MIPS_GOTSYM)
+					app_tpnt->mips_gotsym =
+						(unsigned long) dpnt->d_un.d_val;
+				if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
+					app_tpnt->mips_local_gotno =
+						(unsigned long) dpnt->d_un.d_val;
+				if (dpnt->d_tag == DT_MIPS_SYMTABNO)
+					app_tpnt->mips_symtabno =
+						(unsigned long) dpnt->d_un.d_val;
+				if (dpnt->d_tag > DT_JMPREL) {
+					dpnt++;
+					continue;
+				}
+				app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+				
+				if (dpnt->d_tag == DT_DEBUG) {
+					/* Allow writing debug_addr into the .dynamic segment.
+					 * Even though the program header is marked RWE, the kernel gives
+					 * it to us rx.
+					 */
+					Elf32_Addr mpa = (ppnt->p_vaddr + app_tpnt->loadaddr) & ~(pagesize - 1);
+					Elf32_Word mps = ((ppnt->p_vaddr + app_tpnt->loadaddr) - mpa) + ppnt->p_memsz;
+					if(_dl_mprotect(mpa, mps, PROT_READ | PROT_WRITE | PROT_EXEC)) {
+						SEND_STDERR("Couldn't mprotect .dynamic segment to rwx.\n");
+						_dl_exit(0);
+					}
+					dpnt->d_un.d_val = (unsigned long) debug_addr;
+				}
+#else
+				if (dpnt->d_tag > DT_JMPREL) {
+						dpnt++;
+						continue;
+				}
+				app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+				if (dpnt->d_tag == DT_DEBUG) {
+					dpnt->d_un.d_val = (unsigned long) debug_addr;
+				}
+#endif
+				if (dpnt->d_tag == DT_TEXTREL)
+					app_tpnt->dynamic_info[DT_TEXTREL] = 1;
+				dpnt++;
+			}
+#ifndef FORCE_SHAREABLE_TEXT_SEGMENTS
+			/* Ugly, ugly.  We need to call mprotect to change the protection of
+			   the text pages so that we can do the dynamic linking.  We can set the
+			   protection back again once we are done */
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+			SEND_STDERR("calling mprotect on the application program\n");
+#endif
+			/* Now cover the application program. */
+			if (app_tpnt->dynamic_info[DT_TEXTREL]) {
+				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 + app_tpnt->loadaddr) & PAGE_ALIGN),
+							     ((ppnt->p_vaddr + app_tpnt->loadaddr) & ADDR_ALIGN) +
+							     (unsigned long) ppnt->p_filesz,
+							     PROT_READ | PROT_WRITE | PROT_EXEC);
+				}
+			}
+#endif
+
 #ifndef ALLOW_ZERO_PLTGOT
 #ifndef ALLOW_ZERO_PLTGOT
 			/* make sure it's really there. */
 			/* make sure it's really there. */
 			if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
 			if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)