diff options
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | elf/dl-load.c | 20 |
2 files changed, 18 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog index 88bc8deec8..5a7090431f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ Fri Jun 21 00:27:51 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> + * elf/dl-load.c (_dl_map_object_from_fd): Fix mapping and l_phdr + guessing to not assume p_vaddr of first load cmd is zero. + * sysdeps/sparc/elf/start.S: New file. * sysdeps/sparc/dl-machine.h: New file. diff --git a/elf/dl-load.c b/elf/dl-load.c index f655fdacef..1e0db77c55 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -278,7 +278,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname, unallocated. Then jump into the normal segment-mapping loop to handle the portion of the segment past the end of the file mapping. */ - __mprotect (mapat + c->mapend, + __mprotect ((caddr_t) (l->l_addr + c->mapend), loadcmds[nloadcmds - 1].allocend - c->mapend, 0); goto postmap; @@ -337,6 +337,20 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname, ++c; } + + if (l->l_phdr == 0) + { + /* There was no PT_PHDR specified. We need to find the phdr in the + load image ourselves. We assume it is in fact in the load image + somewhere, and that the first load command starts at the + beginning of the file and thus contains the ELF file header. */ + ElfW(Addr) bof = l->l_addr + loadcmds[0].mapstart; + assert (loadcmds[0].mapoff == 0); + l->l_phdr = (void *) (bof + ((const ElfW(Ehdr) *) bof)->e_phoff); + } + else + /* Adjust the PT_PHDR value by the runtime load address. */ + (ElfW(Addr)) l->l_phdr += l->l_addr; } /* We are done mapping in the file. We no longer need the descriptor. */ @@ -353,10 +367,6 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname, else (ElfW(Addr)) l->l_ld += l->l_addr; - if (l->l_phdr == 0) - l->l_phdr = (void *) ((const ElfW(Ehdr) *) l->l_addr)->e_phoff; - (ElfW(Addr)) l->l_phdr += l->l_addr; - l->l_entry += l->l_addr; elf_get_dynamic_info (l->l_ld, l->l_info); |