diff options
author | Roland McGrath <roland@hack.frob.com> | 2014-03-13 10:38:27 -0700 |
---|---|---|
committer | Roland McGrath <roland@hack.frob.com> | 2014-03-13 10:38:27 -0700 |
commit | 44c4e5d598bfcbb309f05ceb7a57ab02662e7f34 (patch) | |
tree | 93cbc5ad24779ff1ecd1f644615aa2017ed94307 /elf | |
parent | 041a92472e6db60b42cf2db229382fc3482304b9 (diff) | |
download | glibc-44c4e5d598bfcbb309f05ceb7a57ab02662e7f34.tar.gz glibc-44c4e5d598bfcbb309f05ceb7a57ab02662e7f34.tar.xz glibc-44c4e5d598bfcbb309f05ceb7a57ab02662e7f34.zip |
Use __ehdr_start, when available, for rtld to get its own headers.
Diffstat (limited to 'elf')
-rw-r--r-- | elf/rtld.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/elf/rtld.c b/elf/rtld.c index 63e92d3006..9d121dc8f5 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1371,10 +1371,25 @@ of this helper program; chances are you did not intend to run this program.\n\ GLRO(dl_use_load_bias) = main_map->l_addr == 0 ? -1 : 0; /* Set up the program header information for the dynamic linker - itself. It is needed in the dl_iterate_phdr() callbacks. */ - ElfW(Ehdr) *rtld_ehdr = (ElfW(Ehdr) *) GL(dl_rtld_map).l_map_start; - ElfW(Phdr) *rtld_phdr = (ElfW(Phdr) *) (GL(dl_rtld_map).l_map_start - + rtld_ehdr->e_phoff); + itself. It is needed in the dl_iterate_phdr callbacks. */ + const ElfW(Ehdr) *rtld_ehdr; + + /* Starting from binutils-2.23, the linker will define the magic symbol + __ehdr_start to point to our own ELF header if it is visible in a + segment that also includes the phdrs. If that's not available, we use + the old method that assumes the beginning of the file is part of the + lowest-addressed PT_LOAD segment. */ +#ifdef HAVE_EHDR_START + extern const ElfW(Ehdr) __ehdr_start __attribute__ ((visibility ("hidden"))); + rtld_ehdr = &__ehdr_start; +#else + rtld_ehdr = (void *) GL(dl_rtld_map).l_map_start; +#endif + assert (rtld_ehdr->e_ehsize == sizeof *rtld_ehdr); + assert (rtld_ehdr->e_phentsize == sizeof (ElfW(Phdr))); + + const ElfW(Phdr) *rtld_phdr = (const void *) rtld_ehdr + rtld_ehdr->e_phoff; + GL(dl_rtld_map).l_phdr = rtld_phdr; GL(dl_rtld_map).l_phnum = rtld_ehdr->e_phnum; |