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.
This commit is contained in:
parent
7360ae0f2a
commit
a607e5d7f8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=50610
@ -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;
|
||||
}
|
||||
|
@ -61,11 +61,8 @@
|
||||
#define msg(s) (write(1, s, strlen(s)))
|
||||
#define trace() msg("trace: " __XSTRING(__LINE__) "\n");
|
||||
|
||||
#ifndef _PATH_RTLD
|
||||
#define _PATH_RTLD "/usr/libexec/ld-elf.so.1"
|
||||
#endif
|
||||
|
||||
#define END_SYM "_end"
|
||||
#define PATH_RTLD "/usr/libexec/ld-elf.so.1"
|
||||
|
||||
/* Types. */
|
||||
typedef void (*func_ptr_type)();
|
||||
@ -269,6 +266,19 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
||||
|
||||
obj_main->path = xstrdup(argv0);
|
||||
obj_main->mainprog = true;
|
||||
|
||||
/*
|
||||
* Get the actual dynamic linker pathname from the executable if
|
||||
* possible. (It should always be possible.) That ensures that
|
||||
* gdb will find the right dynamic linker even if a non-standard
|
||||
* one is being used.
|
||||
*/
|
||||
if (obj_main->interp != NULL &&
|
||||
strcmp(obj_main->interp, obj_rtld.path) != 0) {
|
||||
free(obj_rtld.path);
|
||||
obj_rtld.path = xstrdup(obj_main->interp);
|
||||
}
|
||||
|
||||
digest_dynamic(obj_main);
|
||||
|
||||
linkmap_add(obj_main);
|
||||
@ -585,6 +595,10 @@ digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path)
|
||||
obj->phsize = ph->p_memsz;
|
||||
break;
|
||||
|
||||
case PT_INTERP:
|
||||
obj->interp = (const char *) ph->p_vaddr;
|
||||
break;
|
||||
|
||||
case PT_LOAD:
|
||||
if (nsegs >= 2) {
|
||||
_rtld_error("%s: too many PT_LOAD segments", path);
|
||||
@ -867,7 +881,7 @@ init_rtld(caddr_t mapbase)
|
||||
* aren't yet initialized sufficiently to do that. Below we will
|
||||
* replace the static version with a dynamically-allocated copy.
|
||||
*/
|
||||
obj_rtld.path = _PATH_RTLD;
|
||||
obj_rtld.path = PATH_RTLD;
|
||||
obj_rtld.rtld = true;
|
||||
obj_rtld.mapbase = mapbase;
|
||||
#ifdef PIC
|
||||
|
@ -99,6 +99,7 @@ typedef struct Struct_Obj_Entry {
|
||||
caddr_t entry; /* Entry point */
|
||||
const Elf_Phdr *phdr; /* Program header if it is mapped, else NULL */
|
||||
size_t phsize; /* Size of program header in bytes */
|
||||
const char *interp; /* Pathname of the interpreter, if any */
|
||||
|
||||
/* Items from the dynamic section. */
|
||||
Elf_Addr *pltgot; /* PLT or GOT, depending on architecture */
|
||||
|
Loading…
Reference in New Issue
Block a user