diff options
author | jdp <jdp@FreeBSD.org> | 1999-08-30 01:54:13 +0000 |
---|---|---|
committer | jdp <jdp@FreeBSD.org> | 1999-08-30 01:54:13 +0000 |
commit | 3e8e2eed47d9851854f20f21c338340dd059810d (patch) | |
tree | c08e1c0e928782fcbf639b9566d64f1e81937ee2 /libexec/rtld-elf/map_object.c | |
parent | 7a67a7ee048e83361dbd4afda5c84ff0b8646542 (diff) | |
download | FreeBSD-src-3e8e2eed47d9851854f20f21c338340dd059810d.zip FreeBSD-src-3e8e2eed47d9851854f20f21c338340dd059810d.tar.gz |
Get the actual pathname of the dynamic linker from the executable's
PT_INTERP program header entry, to ensure that gdb always finds
the right dynamic linker.
Use obj->relocbase to simplify a few calculations where appropriate.
Diffstat (limited to 'libexec/rtld-elf/map_object.c')
-rw-r--r-- | libexec/rtld-elf/map_object.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c index ca353c7..d7b6978 100644 --- a/libexec/rtld-elf/map_object.c +++ b/libexec/rtld-elf/map_object.c @@ -62,6 +62,7 @@ map_object(int fd, const char *path, const struct stat *sb) int nsegs; Elf_Phdr *phdyn; Elf_Phdr *phphdr; + Elf_Phdr *phinterp; caddr_t mapbase; size_t mapsize; Elf_Off base_offset; @@ -136,11 +137,14 @@ map_object(int fd, const char *path, const struct stat *sb) phdr = (Elf_Phdr *) (u.buf + u.hdr.e_phoff); phlimit = phdr + u.hdr.e_phnum; nsegs = 0; - phdyn = NULL; - phphdr = NULL; + phdyn = phphdr = phinterp = NULL; while (phdr < phlimit) { switch (phdr->p_type) { + case PT_INTERP: + phinterp = phdr; + break; + case PT_LOAD: if (nsegs >= 2) { _rtld_error("%s: too many PT_LOAD segments", path); @@ -239,15 +243,15 @@ map_object(int fd, const char *path, const struct stat *sb) base_vaddr; obj->vaddrbase = base_vaddr; obj->relocbase = mapbase - base_vaddr; - obj->dynamic = (const Elf_Dyn *) - (mapbase + (phdyn->p_vaddr - base_vaddr)); + obj->dynamic = (const Elf_Dyn *) (obj->relocbase + phdyn->p_vaddr); if (u.hdr.e_entry != 0) - obj->entry = (caddr_t) (mapbase + (u.hdr.e_entry - base_vaddr)); + obj->entry = (caddr_t) (obj->relocbase + u.hdr.e_entry); if (phphdr != NULL) { - obj->phdr = (const Elf_Phdr *) - (mapbase + (phphdr->p_vaddr - base_vaddr)); + obj->phdr = (const Elf_Phdr *) (obj->relocbase + phphdr->p_vaddr); obj->phsize = phphdr->p_memsz; } + if (phinterp != NULL) + obj->interp = (const char *) (obj->relocbase + phinterp->p_vaddr); return obj; } |