Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/link_elf.c
Show First 20 Lines • Show All 767 Lines • ▼ Show 20 Lines | if (error != 0) | ||||
break; | break; | ||||
} | } | ||||
return (error); | return (error); | ||||
#else | #else | ||||
return (0); | return (0); | ||||
#endif | #endif | ||||
} | } | ||||
#ifdef __arm__ | |||||
/* | |||||
* Locate the ARM exception/unwind table info for DDB and stack(9) use by | |||||
* searching for the section header that describes it. There may be no unwind | |||||
* info, for example in a module containing only data. | |||||
*/ | |||||
static void | |||||
link_elf_locate_exidx(linker_file_t lf, Elf_Shdr *shdr, int nhdr) | |||||
{ | |||||
int i; | |||||
for (i = 0; i < nhdr; i++) { | |||||
if (shdr[i].sh_type == SHT_ARM_EXIDX) { | |||||
lf->exidx_addr = shdr[i].sh_addr + lf->address; | |||||
lf->exidx_size = shdr[i].sh_size; | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
/* | |||||
* Locate the section headers metadata in a preloaded module, then use it to | |||||
* locate the exception/unwind table in the module. The size of the metadata | |||||
* block is stored in a uint32 word immediately before the data itself, and a | |||||
* comment in preload_search_info() says it is safe to rely on that. | |||||
*/ | |||||
static void | |||||
link_elf_locate_exidx_preload(struct linker_file *lf, caddr_t modptr) | |||||
{ | |||||
uint32_t *modinfo; | |||||
Elf_Shdr *shdr; | |||||
uint32_t nhdr; | |||||
modinfo = (uint32_t *)preload_search_info(modptr, | |||||
MODINFO_METADATA | MODINFOMD_SHDR); | |||||
if (modinfo != NULL) { | |||||
shdr = (Elf_Shdr *)modinfo; | |||||
nhdr = modinfo[-1] / sizeof(Elf_Shdr); | |||||
link_elf_locate_exidx(lf, shdr, nhdr); | |||||
} | |||||
} | |||||
#endif /* __arm__ */ | |||||
static int | static int | ||||
link_elf_link_preload(linker_class_t cls, const char *filename, | link_elf_link_preload(linker_class_t cls, const char *filename, | ||||
linker_file_t *result) | 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; | ||||
Show All 39 Lines | ctors_addrp = (Elf_Addr *)preload_search_info(modptr, | ||||
MODINFO_METADATA | MODINFOMD_CTORS_ADDR); | MODINFO_METADATA | MODINFOMD_CTORS_ADDR); | ||||
ctors_sizep = (Elf_Size *)preload_search_info(modptr, | ctors_sizep = (Elf_Size *)preload_search_info(modptr, | ||||
MODINFO_METADATA | MODINFOMD_CTORS_SIZE); | MODINFO_METADATA | MODINFOMD_CTORS_SIZE); | ||||
if (ctors_addrp != NULL && ctors_sizep != NULL) { | if (ctors_addrp != NULL && ctors_sizep != NULL) { | ||||
lf->ctors_addr = ef->address + *ctors_addrp; | lf->ctors_addr = ef->address + *ctors_addrp; | ||||
lf->ctors_size = *ctors_sizep; | lf->ctors_size = *ctors_sizep; | ||||
} | } | ||||
#ifdef __arm__ | |||||
link_elf_locate_exidx_preload(lf, modptr); | |||||
#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) | if (error == 0) | ||||
▲ Show 20 Lines • Show All 381 Lines • ▼ Show 20 Lines | if (error != 0) | ||||
goto out; | goto out; | ||||
ef->ddbsymcnt = symcnt / sizeof(Elf_Sym); | ef->ddbsymcnt = symcnt / sizeof(Elf_Sym); | ||||
ef->ddbsymtab = (const Elf_Sym *)ef->symbase; | ef->ddbsymtab = (const Elf_Sym *)ef->symbase; | ||||
ef->ddbstrcnt = strcnt; | ef->ddbstrcnt = strcnt; | ||||
ef->ddbstrtab = ef->strbase; | ef->ddbstrtab = ef->strbase; | ||||
nosyms: | nosyms: | ||||
#ifdef __arm__ | |||||
link_elf_locate_exidx(lf, shdr, hdr->e_shnum); | |||||
#endif | |||||
error = link_elf_link_common_finish(lf); | error = link_elf_link_common_finish(lf); | ||||
if (error != 0) | if (error != 0) | ||||
goto out; | goto out; | ||||
*result = lf; | *result = lf; | ||||
out: | out: | ||||
VOP_UNLOCK(nd.ni_vp, 0); | VOP_UNLOCK(nd.ni_vp, 0); | ||||
▲ Show 20 Lines • Show All 608 Lines • Show Last 20 Lines |