summaryrefslogtreecommitdiff
path: root/ldso
diff options
context:
space:
mode:
authorJoakim Tjernlund <joakim.tjernlund@transmode.se>2004-08-19 08:53:29 +0000
committerJoakim Tjernlund <joakim.tjernlund@transmode.se>2004-08-19 08:53:29 +0000
commit0a98c1b6b0a98fc7010e69f48a4cc13fa31d6f81 (patch)
treef5c976b804f0b025687eaffb089b1028c2dd2964 /ldso
parent4135087a92ec76555f2c8d242cd526afc8384cdd (diff)
Move the app specific stuff from dl-startup.c to ldso.c.
Diffstat (limited to 'ldso')
-rw-r--r--ldso/include/ldso.h3
-rw-r--r--ldso/ldso/dl-startup.c99
-rw-r--r--ldso/ldso/ldso.c92
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)