Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/link_elf.c
Show First 20 Lines • Show All 730 Lines • ▼ Show 20 Lines | #endif | ||||
elf_set_add(&set_vnet_list, ef->vnet_start, ef->vnet_stop, | elf_set_add(&set_vnet_list, ef->vnet_start, ef->vnet_stop, | ||||
ef->vnet_base); | ef->vnet_base); | ||||
return (0); | return (0); | ||||
} | } | ||||
#endif | #endif | ||||
#undef LS_PADDING | #undef LS_PADDING | ||||
/* | |||||
* Apply the specified protection to the loadable segments of a preloaded linker | |||||
* file. | |||||
*/ | |||||
static int | static int | ||||
link_elf_link_preload(linker_class_t cls, | preload_protect(elf_file_t ef, vm_prot_t prot) | ||||
const char* filename, linker_file_t *result) | |||||
{ | { | ||||
#ifdef __amd64__ | |||||
Elf_Ehdr *hdr; | |||||
Elf_Phdr *phdr, *phlimit; | |||||
vm_prot_t nprot; | |||||
int error; | |||||
error = 0; | |||||
hdr = (Elf_Ehdr *)ef->address; | |||||
phdr = (Elf_Phdr *)(ef->address + hdr->e_phoff); | |||||
phlimit = phdr + hdr->e_phnum; | |||||
for (; phdr < phlimit; phdr++) { | |||||
if (phdr->p_type != PT_LOAD) | |||||
continue; | |||||
nprot = prot | VM_PROT_READ; | |||||
if ((phdr->p_flags & PF_W) != 0) | |||||
nprot |= VM_PROT_WRITE; | |||||
if ((phdr->p_flags & PF_X) != 0) | |||||
nprot |= VM_PROT_EXECUTE; | |||||
error = pmap_change_prot((vm_offset_t)ef->address + | |||||
phdr->p_vaddr, round_page(phdr->p_memsz), nprot); | |||||
if (error != 0) | |||||
break; | |||||
} | |||||
return (error); | |||||
#else | |||||
return (0); | |||||
#endif | |||||
} | |||||
static int | |||||
link_elf_link_preload(linker_class_t cls, const char *filename, | |||||
linker_file_t *result) | |||||
{ | |||||
Elf_Addr *ctors_addrp; | Elf_Addr *ctors_addrp; | ||||
Elf_Size *ctors_sizep; | Elf_Size *ctors_sizep; | ||||
caddr_t modptr, baseptr, sizeptr, dynptr; | caddr_t modptr, baseptr, sizeptr, dynptr; | ||||
char *type; | char *type; | ||||
elf_file_t ef; | elf_file_t ef; | ||||
linker_file_t lf; | linker_file_t lf; | ||||
int error; | int error; | ||||
vm_offset_t dp; | vm_offset_t dp; | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | #endif | ||||
error = parse_dynamic(ef); | error = parse_dynamic(ef); | ||||
if (error == 0) | if (error == 0) | ||||
error = parse_dpcpu(ef); | error = parse_dpcpu(ef); | ||||
#ifdef VIMAGE | #ifdef VIMAGE | ||||
if (error == 0) | if (error == 0) | ||||
error = parse_vnet(ef); | error = parse_vnet(ef); | ||||
#endif | #endif | ||||
if (error == 0) | |||||
error = preload_protect(ef, VM_PROT_ALL); | |||||
if (error != 0) { | if (error != 0) { | ||||
linker_file_unload(lf, LINKER_UNLOAD_FORCE); | linker_file_unload(lf, LINKER_UNLOAD_FORCE); | ||||
return (error); | return (error); | ||||
} | } | ||||
link_elf_reloc_local(lf); | link_elf_reloc_local(lf); | ||||
*result = lf; | *result = lf; | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
link_elf_link_preload_finish(linker_file_t lf) | link_elf_link_preload_finish(linker_file_t lf) | ||||
{ | { | ||||
elf_file_t ef; | elf_file_t ef; | ||||
int error; | int error; | ||||
ef = (elf_file_t) lf; | ef = (elf_file_t) lf; | ||||
error = relocate_file(ef); | error = relocate_file(ef); | ||||
if (error == 0) | |||||
error = preload_protect(ef, VM_PROT_NONE); | |||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
(void)link_elf_preload_parse_symbols(ef); | (void)link_elf_preload_parse_symbols(ef); | ||||
return (link_elf_link_common_finish(lf)); | return (link_elf_link_common_finish(lf)); | ||||
} | } | ||||
static int | static int | ||||
▲ Show 20 Lines • Show All 443 Lines • ▼ Show 20 Lines | #endif | ||||
free(ef->ctftab, M_LINKER); | free(ef->ctftab, M_LINKER); | ||||
free(ef->ctfoff, M_LINKER); | free(ef->ctfoff, M_LINKER); | ||||
free(ef->typoff, M_LINKER); | free(ef->typoff, M_LINKER); | ||||
} | } | ||||
static void | static void | ||||
link_elf_unload_preload(linker_file_t file) | link_elf_unload_preload(linker_file_t file) | ||||
{ | { | ||||
if (file->pathname != NULL) | if (file->pathname != NULL) | ||||
preload_delete_name(file->pathname); | preload_delete_name(file->pathname); | ||||
} | } | ||||
static const char * | static const char * | ||||
symbol_name(elf_file_t ef, Elf_Size r_info) | symbol_name(elf_file_t ef, Elf_Size r_info) | ||||
{ | { | ||||
const Elf_Sym *ref; | const Elf_Sym *ref; | ||||
▲ Show 20 Lines • Show All 517 Lines • Show Last 20 Lines |