diff options
author | Joakim Tjernlund <joakim.tjernlund@transmode.se> | 2004-08-19 08:53:29 +0000 |
---|---|---|
committer | Joakim Tjernlund <joakim.tjernlund@transmode.se> | 2004-08-19 08:53:29 +0000 |
commit | 0a98c1b6b0a98fc7010e69f48a4cc13fa31d6f81 (patch) | |
tree | f5c976b804f0b025687eaffb089b1028c2dd2964 /ldso | |
parent | 4135087a92ec76555f2c8d242cd526afc8384cdd (diff) |
Move the app specific stuff from dl-startup.c to ldso.c.
Diffstat (limited to 'ldso')
-rw-r--r-- | ldso/include/ldso.h | 3 | ||||
-rw-r--r-- | ldso/ldso/dl-startup.c | 99 | ||||
-rw-r--r-- | ldso/ldso/ldso.c | 92 |
3 files changed, 93 insertions, 101 deletions
diff --git a/ldso/include/ldso.h b/ldso/include/ldso.h index 494b57521..6d978bf1d 100644 --- a/ldso/include/ldso.h +++ b/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 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, unsigned char *malloc_buffer, unsigned char *mmap_zero, char **argv); diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c index aaca86831..06bd146b8 100644 --- a/ldso/ldso/dl-startup.c +++ b/ldso/ldso/dl-startup.c @@ -127,7 +127,6 @@ DL_BOOT(unsigned long args) int goof = 0; ElfW(Ehdr) *header; struct elf_resolve *tpnt; - struct elf_resolve *app_tpnt; Elf32_auxv_t auxvt[AT_EGID + 1]; unsigned char *malloc_buffer, *mmap_zero; Elf32_Dyn *dpnt; @@ -299,28 +298,6 @@ found_got: tpnt = LD_MALLOC(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. @@ -350,62 +327,6 @@ found_got: } 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__ SEND_STDERR("done scanning DYNAMIC section\n"); #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 - #if defined(__mips__) #ifdef __SUPPORT_LD_DEBUG_EARLY__ 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 fixed up by now. Still no function calls outside of this library , 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. */ diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index 62b6c7437..730d40da6 100644 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -84,17 +84,19 @@ static void debug_fini (int status, void *arg) } #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, unsigned char *malloc_buffer, unsigned char *mmap_zero, char **argv) { ElfW(Phdr) *ppnt; + Elf32_Dyn *dpnt; char *lpntstr; int i, goof = 0, unlazy = 0, trace_loaded_objects = 0; struct dyn_elf *rpnt; struct elf_resolve *tcurr; struct elf_resolve *tpnt1; + struct elf_resolve app_tpnt_tmp; + struct elf_resolve *app_tpnt = &app_tpnt_tmp; unsigned long brk_addr, *lpnt; int (*_dl_atexit) (void *); #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 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; for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) { 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; } 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 /* make sure it's really there. */ if (app_tpnt->dynamic_info[DT_PLTGOT] == 0) |