Changeset View
Changeset View
Standalone View
Standalone View
head/libexec/rtld-elf/map_object.c
Show First 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | map_object(int fd, const char *path, const struct stat *sb) | ||||
caddr_t bss_addr; | caddr_t bss_addr; | ||||
Elf_Word stack_flags; | Elf_Word stack_flags; | ||||
Elf_Addr relro_page; | Elf_Addr relro_page; | ||||
size_t relro_size; | size_t relro_size; | ||||
Elf_Addr note_start; | Elf_Addr note_start; | ||||
Elf_Addr note_end; | Elf_Addr note_end; | ||||
char *note_map; | char *note_map; | ||||
size_t note_map_len; | size_t note_map_len; | ||||
Elf_Addr text_end; | |||||
hdr = get_elf_header(fd, path, sb); | hdr = get_elf_header(fd, path, sb); | ||||
if (hdr == NULL) | if (hdr == NULL) | ||||
return (NULL); | return (NULL); | ||||
/* | /* | ||||
* Scan the program header entries, and save key information. | * Scan the program header entries, and save key information. | ||||
* | * | ||||
* We expect that the loadable segments are ordered by load address. | * We expect that the loadable segments are ordered by load address. | ||||
*/ | */ | ||||
phdr = (Elf_Phdr *) ((char *)hdr + hdr->e_phoff); | phdr = (Elf_Phdr *) ((char *)hdr + hdr->e_phoff); | ||||
phsize = hdr->e_phnum * sizeof (phdr[0]); | phsize = hdr->e_phnum * sizeof (phdr[0]); | ||||
phlimit = phdr + hdr->e_phnum; | phlimit = phdr + hdr->e_phnum; | ||||
nsegs = -1; | nsegs = -1; | ||||
phdyn = phinterp = phtls = NULL; | phdyn = phinterp = phtls = NULL; | ||||
phdr_vaddr = 0; | phdr_vaddr = 0; | ||||
relro_page = 0; | relro_page = 0; | ||||
relro_size = 0; | relro_size = 0; | ||||
note_start = 0; | note_start = 0; | ||||
note_end = 0; | note_end = 0; | ||||
note_map = NULL; | note_map = NULL; | ||||
segs = alloca(sizeof(segs[0]) * hdr->e_phnum); | segs = alloca(sizeof(segs[0]) * hdr->e_phnum); | ||||
stack_flags = RTLD_DEFAULT_STACK_PF_EXEC | PF_R | PF_W; | stack_flags = RTLD_DEFAULT_STACK_PF_EXEC | PF_R | PF_W; | ||||
text_end = 0; | |||||
while (phdr < phlimit) { | while (phdr < phlimit) { | ||||
switch (phdr->p_type) { | switch (phdr->p_type) { | ||||
case PT_INTERP: | case PT_INTERP: | ||||
phinterp = phdr; | phinterp = phdr; | ||||
break; | break; | ||||
case PT_LOAD: | case PT_LOAD: | ||||
segs[++nsegs] = phdr; | segs[++nsegs] = phdr; | ||||
if ((segs[nsegs]->p_align & (PAGE_SIZE - 1)) != 0) { | if ((segs[nsegs]->p_align & (PAGE_SIZE - 1)) != 0) { | ||||
_rtld_error("%s: PT_LOAD segment %d not page-aligned", | _rtld_error("%s: PT_LOAD segment %d not page-aligned", | ||||
path, nsegs); | path, nsegs); | ||||
goto error; | goto error; | ||||
} | } | ||||
if ((segs[nsegs]->p_flags & PF_X) == PF_X) { | |||||
text_end = MAX(text_end, | |||||
round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz)); | |||||
} | |||||
break; | break; | ||||
case PT_PHDR: | case PT_PHDR: | ||||
phdr_vaddr = phdr->p_vaddr; | phdr_vaddr = phdr->p_vaddr; | ||||
phsize = phdr->p_memsz; | phsize = phdr->p_memsz; | ||||
break; | break; | ||||
case PT_DYNAMIC: | case PT_DYNAMIC: | ||||
▲ Show 20 Lines • Show All 134 Lines • ▼ Show 20 Lines | if (phdr_vaddr == 0 && data_offset <= hdr->e_phoff && | ||||
obj = obj_new(); | obj = obj_new(); | ||||
if (sb != NULL) { | if (sb != NULL) { | ||||
obj->dev = sb->st_dev; | obj->dev = sb->st_dev; | ||||
obj->ino = sb->st_ino; | obj->ino = sb->st_ino; | ||||
} | } | ||||
obj->mapbase = mapbase; | obj->mapbase = mapbase; | ||||
obj->mapsize = mapsize; | obj->mapsize = mapsize; | ||||
obj->textsize = round_page(segs[0]->p_vaddr + segs[0]->p_memsz) - | obj->textsize = text_end - base_vaddr; | ||||
base_vaddr; | |||||
obj->vaddrbase = base_vaddr; | obj->vaddrbase = base_vaddr; | ||||
obj->relocbase = mapbase - base_vaddr; | obj->relocbase = mapbase - base_vaddr; | ||||
obj->dynamic = (const Elf_Dyn *) (obj->relocbase + phdyn->p_vaddr); | obj->dynamic = (const Elf_Dyn *) (obj->relocbase + phdyn->p_vaddr); | ||||
if (hdr->e_entry != 0) | if (hdr->e_entry != 0) | ||||
obj->entry = (caddr_t) (obj->relocbase + hdr->e_entry); | obj->entry = (caddr_t) (obj->relocbase + hdr->e_entry); | ||||
if (phdr_vaddr != 0) { | if (phdr_vaddr != 0) { | ||||
obj->phdr = (const Elf_Phdr *) (obj->relocbase + phdr_vaddr); | obj->phdr = (const Elf_Phdr *) (obj->relocbase + phdr_vaddr); | ||||
} else { | } else { | ||||
▲ Show 20 Lines • Show All 187 Lines • Show Last 20 Lines |