From 65da9563c76080002eb5018b4666220e15c9d70d Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 12 Sep 2002 10:12:33 +0000 Subject: * elf/rtld.c (_dl_start_final): Move _begin, _end decls outside the fn. (_dl_start) [DONT_USE_BOOTSTRAP_MAP]: Use &_begin instead of l_addr to find the ELF header. --- ChangeLog | 4 ++++ elf/rtld.c | 19 +++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7489eaf59d..f0eba51b32 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2002-09-12 Roland McGrath + * elf/rtld.c (_dl_start_final): Move _begin, _end decls outside the fn. + (_dl_start) [DONT_USE_BOOTSTRAP_MAP]: Use &_begin instead of l_addr to + find the ELF header. + * elf/rtld.c (dl_main) [USE_TLS]: Adjust l_tls_initimage of main executable if needed, in case it's actually a shared object. diff --git a/elf/rtld.c b/elf/rtld.c index 22aa48543a..ea9cee1d7e 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -150,6 +150,11 @@ static ElfW(Addr) _dl_start_final (void *arg, struct link_map *bootstrap_map_p); #endif +/* These defined magically in the linker script. */ +extern char _begin[] attribute_hidden; +extern char _end[] attribute_hidden; + + #ifdef RTLD_START RTLD_START #else @@ -180,8 +185,6 @@ _dl_start_final (void *arg, struct link_map *bootstrap_map_p) #endif { ElfW(Addr) start_addr; - extern char _begin[] attribute_hidden; - extern char _end[] attribute_hidden; if (HP_TIMING_AVAIL) { @@ -313,9 +316,17 @@ _dl_start (void *arg) bootstrap_map.l_tls_modid = 0; # endif - /* Get the dynamic linkers program header. */ + /* Get the dynamic linker's own program header. First we need the ELF + file header. The `_begin' symbol created by the linker script points + to it. When we have something like GOTOFF relocs, we can use a plain + reference to find the runtime address. Without that, we have to rely + on the `l_addr' value, which is not the value we want when prelinked. */ +#ifdef DONT_USE_BOOTSTRAP_MAP + ehdr = (ElfW(Ehdr) *) &_begin; +#else ehdr = (ElfW(Ehdr) *) bootstrap_map.l_addr; - phdr = (ElfW(Phdr) *) (bootstrap_map.l_addr + ehdr->e_phoff); +#endif + phdr = (ElfW(Phdr) *) ((ElfW(Addr)) ehdr + ehdr->e_phoff); for (cnt = 0; cnt < ehdr->e_phnum; ++cnt) if (phdr[cnt].p_type == PT_TLS) { -- cgit v1.2.3