Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/link_elf.c
Show First 20 Lines • Show All 759 Lines • ▼ Show 20 Lines | link_elf_load_file(linker_class_t cls, const char* filename, | ||||
Elf_Ehdr *hdr; | Elf_Ehdr *hdr; | ||||
caddr_t firstpage; | caddr_t firstpage; | ||||
int nbytes, i; | int nbytes, i; | ||||
Elf_Phdr *phdr; | Elf_Phdr *phdr; | ||||
Elf_Phdr *phlimit; | Elf_Phdr *phlimit; | ||||
Elf_Phdr *segs[MAXSEGS]; | Elf_Phdr *segs[MAXSEGS]; | ||||
int nsegs; | int nsegs; | ||||
Elf_Phdr *phdyn; | Elf_Phdr *phdyn; | ||||
Elf_Phdr *phphdr; | |||||
caddr_t mapbase; | caddr_t mapbase; | ||||
size_t mapsize; | size_t mapsize; | ||||
Elf_Off base_offset; | |||||
Elf_Addr base_vaddr; | Elf_Addr base_vaddr; | ||||
Elf_Addr base_vlimit; | Elf_Addr base_vlimit; | ||||
int error = 0; | int error = 0; | ||||
ssize_t resid; | ssize_t resid; | ||||
int flags; | int flags; | ||||
elf_file_t ef; | elf_file_t ef; | ||||
linker_file_t lf; | linker_file_t lf; | ||||
Elf_Shdr *shdr; | Elf_Shdr *shdr; | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | #endif | ||||
* | * | ||||
* We rely on there being exactly two load segments, text and data, | * We rely on there being exactly two load segments, text and data, | ||||
* in that order. | * in that order. | ||||
*/ | */ | ||||
phdr = (Elf_Phdr *) (firstpage + hdr->e_phoff); | phdr = (Elf_Phdr *) (firstpage + hdr->e_phoff); | ||||
phlimit = phdr + hdr->e_phnum; | phlimit = phdr + hdr->e_phnum; | ||||
nsegs = 0; | nsegs = 0; | ||||
phdyn = NULL; | phdyn = NULL; | ||||
phphdr = NULL; | |||||
while (phdr < phlimit) { | while (phdr < phlimit) { | ||||
switch (phdr->p_type) { | switch (phdr->p_type) { | ||||
case PT_LOAD: | case PT_LOAD: | ||||
if (nsegs == MAXSEGS) { | if (nsegs == MAXSEGS) { | ||||
link_elf_error(filename, "Too many sections"); | link_elf_error(filename, "Too many sections"); | ||||
error = ENOEXEC; | error = ENOEXEC; | ||||
goto out; | goto out; | ||||
} | } | ||||
/* | /* | ||||
* XXX: We just trust they come in right order ?? | * XXX: We just trust they come in right order ?? | ||||
*/ | */ | ||||
segs[nsegs] = phdr; | segs[nsegs] = phdr; | ||||
++nsegs; | ++nsegs; | ||||
break; | break; | ||||
case PT_PHDR: | |||||
phphdr = phdr; | |||||
break; | |||||
case PT_DYNAMIC: | case PT_DYNAMIC: | ||||
phdyn = phdr; | phdyn = phdr; | ||||
break; | break; | ||||
case PT_INTERP: | case PT_INTERP: | ||||
error = ENOSYS; | error = ENOSYS; | ||||
goto out; | goto out; | ||||
} | } | ||||
Show All 11 Lines | if (nsegs == 0) { | ||||
goto out; | goto out; | ||||
} | } | ||||
/* | /* | ||||
* Allocate the entire address space of the object, to stake | * Allocate the entire address space of the object, to stake | ||||
* out our contiguous region, and to establish the base | * out our contiguous region, and to establish the base | ||||
* address for relocation. | * address for relocation. | ||||
*/ | */ | ||||
base_offset = trunc_page(segs[0]->p_offset); | |||||
base_vaddr = trunc_page(segs[0]->p_vaddr); | base_vaddr = trunc_page(segs[0]->p_vaddr); | ||||
base_vlimit = round_page(segs[nsegs - 1]->p_vaddr + | base_vlimit = round_page(segs[nsegs - 1]->p_vaddr + | ||||
segs[nsegs - 1]->p_memsz); | segs[nsegs - 1]->p_memsz); | ||||
mapsize = base_vlimit - base_vaddr; | mapsize = base_vlimit - base_vaddr; | ||||
lf = linker_make_file(filename, &link_elf_class); | lf = linker_make_file(filename, &link_elf_class); | ||||
if (lf == NULL) { | if (lf == NULL) { | ||||
error = ENOMEM; | error = ENOMEM; | ||||
▲ Show 20 Lines • Show All 733 Lines • Show Last 20 Lines |