summaryrefslogtreecommitdiff
path: root/ldso/ldso/ldso.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldso/ldso/ldso.c')
-rw-r--r--ldso/ldso/ldso.c87
1 files changed, 31 insertions, 56 deletions
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index 46b59a3b2..d231969f8 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -97,9 +97,11 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
struct elf_resolve app_tpnt_tmp;
struct elf_resolve *app_tpnt = &app_tpnt_tmp;
struct r_debug *debug_addr;
- unsigned long brk_addr, *lpnt;
+ unsigned long *lpnt;
int (*_dl_atexit) (void *);
unsigned long *_dl_envp; /* The environment address */
+ ElfW(Addr) relro_addr = 0;
+ size_t relro_size = 0;
#if defined (__SUPPORT_LD_DEBUG__)
int (*_dl_on_exit) (void (*FUNCTION)(int STATUS, void *ARG),void*);
#endif
@@ -132,23 +134,6 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
* go from there. Eventually we will run across ourself, and we
* will need to properly deal with that as well.
*/
- {
- ElfW(Ehdr) *epnt;
- ElfW(Phdr) *myppnt;
- int j;
-
- epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
- tpnt->n_phent = epnt->e_phnum;
- tpnt->ppnt = myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff);
- for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
- if (myppnt->p_type == PT_DYNAMIC) {
- tpnt->dynamic_addr = (ElfW(Dyn) *)(myppnt->p_vaddr + load_addr);
- tpnt->dynamic_size = myppnt->p_filesz;
- }
- }
- }
-
- brk_addr = 0;
rpnt = NULL;
if (_dl_getenv("LD_BIND_NOW", envp))
unlazy = RTLD_NOW;
@@ -189,46 +174,13 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
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) {
- if (ppnt->p_vaddr + app_tpnt->loadaddr + ppnt->p_memsz > brk_addr)
- brk_addr = ppnt->p_vaddr + app_tpnt->loadaddr + ppnt->p_memsz;
+ if (ppnt->p_type == PT_GNU_RELRO) {
+ relro_addr = ppnt->p_vaddr;
+ relro_size = 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;
- /* Remember... DT_MIPS_RLD_MAP > DT_JMPREL. */
- if (dpnt->d_tag == DT_MIPS_RLD_MAP) {
- *(ElfW(Addr) *)(dpnt->d_un.d_ptr) = (ElfW(Addr)) debug_addr;
- }
- if (dpnt->d_tag > DT_JMPREL) {
- dpnt++;
- continue;
- }
- app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
-#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++;
- }
+ _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr);
#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
@@ -315,6 +267,8 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
#endif
}
}
+ app_tpnt->relro_addr = relro_addr;
+ app_tpnt->relro_size = relro_size;
/* Now we need to figure out what kind of options are selected.
* Note that for SUID programs we ignore the settings in
@@ -728,10 +682,24 @@ next_lib2:
* again once all libs are loaded.
*/
if (tpnt) {
+ ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
+ ElfW(Phdr) *myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff);
+ int j;
+
tpnt = _dl_add_elf_hash_table(tpnt->libname, (char *)load_addr,
tpnt->dynamic_info,
(unsigned long)tpnt->dynamic_addr,
- tpnt->dynamic_size);
+ 0);
+
+ tpnt->n_phent = epnt->e_phnum;
+ tpnt->ppnt = myppnt;
+ for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
+ if (myppnt->p_type == PT_GNU_RELRO) {
+ tpnt->relro_addr = myppnt->p_vaddr;
+ tpnt->relro_size = myppnt->p_memsz;
+ break;
+ }
+ }
tpnt->libtype = program_interpreter;
tpnt->usage_count++;
tpnt->symbol_scope = _dl_symbol_tables;
@@ -791,6 +759,13 @@ next_lib2:
if (_dl_symbol_tables)
goof += _dl_fixup(_dl_symbol_tables, unlazy);
+ for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
+ if (tpnt->relro_size)
+ _dl_protect_relro (tpnt);
+ }
+
+
+
/* OK, at this point things are pretty much ready to run. Now we need
* to touch up a few items that are required, and then we can let the