Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/link_elf_obj.c
Show First 20 Lines • Show All 538 Lines • ▼ Show 20 Lines | #endif | ||||
if (lf->ctors_addr != 0) { | if (lf->ctors_addr != 0) { | ||||
printf( | printf( | ||||
"%s: multiple ctor sections in %s\n", | "%s: multiple ctor sections in %s\n", | ||||
__func__, filename); | __func__, filename); | ||||
} else { | } else { | ||||
lf->ctors_addr = ef->progtab[pb].addr; | lf->ctors_addr = ef->progtab[pb].addr; | ||||
lf->ctors_size = shdr[i].sh_size; | lf->ctors_size = shdr[i].sh_size; | ||||
} | } | ||||
} else if ((ef->progtab[pb].name != NULL && | |||||
strcmp(ef->progtab[pb].name, ".dtors") == 0) || | |||||
shdr[i].sh_type == SHT_FINI_ARRAY) { | |||||
if (lf->dtors_addr != 0) { | |||||
printf( | |||||
"%s: multiple dtor sections in %s\n", | |||||
__func__, filename); | |||||
} else { | |||||
lf->dtors_addr = ef->progtab[pb].addr; | |||||
lf->dtors_size = shdr[i].sh_size; | |||||
} | } | ||||
} | |||||
/* Update all symbol values with the offset. */ | /* Update all symbol values with the offset. */ | ||||
for (j = 0; j < ef->ddbsymcnt; j++) { | for (j = 0; j < ef->ddbsymcnt; j++) { | ||||
es = &ef->ddbsymtab[j]; | es = &ef->ddbsymtab[j]; | ||||
if (es->st_shndx != i) | if (es->st_shndx != i) | ||||
continue; | continue; | ||||
es->st_value += (Elf_Addr)ef->progtab[pb].addr; | es->st_value += (Elf_Addr)ef->progtab[pb].addr; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | |||||
out: | out: | ||||
/* preload not done this way */ | /* preload not done this way */ | ||||
linker_file_unload(lf, LINKER_UNLOAD_FORCE); | linker_file_unload(lf, LINKER_UNLOAD_FORCE); | ||||
return (error); | return (error); | ||||
} | } | ||||
static void | static void | ||||
link_elf_invoke_ctors(caddr_t addr, size_t size) | link_elf_invoke_cbs(caddr_t addr, size_t size) | ||||
{ | { | ||||
void (**ctor)(void); | void (**ctor)(void); | ||||
size_t i, cnt; | size_t i, cnt; | ||||
if (addr == NULL || size == 0) | if (addr == NULL || size == 0) | ||||
return; | return; | ||||
cnt = size / sizeof(*ctor); | cnt = size / sizeof(*ctor); | ||||
ctor = (void *)addr; | ctor = (void *)addr; | ||||
Show All 24 Lines | #if defined(__i386__) || defined(__amd64__) | ||||
error = link_elf_reloc_local(lf, true); | error = link_elf_reloc_local(lf, true); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
#endif | #endif | ||||
/* Apply protections now that relocation processing is complete. */ | /* Apply protections now that relocation processing is complete. */ | ||||
link_elf_protect(ef); | link_elf_protect(ef); | ||||
link_elf_invoke_ctors(lf->ctors_addr, lf->ctors_size); | link_elf_invoke_cbs(lf->ctors_addr, lf->ctors_size); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
link_elf_load_file(linker_class_t cls, const char *filename, | link_elf_load_file(linker_class_t cls, const char *filename, | ||||
linker_file_t *result) | linker_file_t *result) | ||||
{ | { | ||||
struct nameidata *nd; | struct nameidata *nd; | ||||
▲ Show 20 Lines • Show All 342 Lines • ▼ Show 20 Lines | case SHT_FINI_ARRAY: | ||||
"%s: multiple ctor sections in %s\n", | "%s: multiple ctor sections in %s\n", | ||||
__func__, filename); | __func__, filename); | ||||
} else { | } else { | ||||
lf->ctors_addr = | lf->ctors_addr = | ||||
(caddr_t)mapbase; | (caddr_t)mapbase; | ||||
lf->ctors_size = | lf->ctors_size = | ||||
shdr[i].sh_size; | shdr[i].sh_size; | ||||
} | } | ||||
} else if (!strcmp(ef->progtab[pb].name, | |||||
".dtors") || | |||||
shdr[i].sh_type == SHT_FINI_ARRAY) { | |||||
if (lf->dtors_addr != 0) { | |||||
printf( | |||||
"%s: multiple dtor sections in %s\n", | |||||
__func__, filename); | |||||
} else { | |||||
lf->dtors_addr = | |||||
(caddr_t)mapbase; | |||||
lf->dtors_size = | |||||
shdr[i].sh_size; | |||||
} | } | ||||
} | |||||
} else if (shdr[i].sh_type == SHT_PROGBITS) | } else if (shdr[i].sh_type == SHT_PROGBITS) | ||||
ef->progtab[pb].name = "<<PROGBITS>>"; | ef->progtab[pb].name = "<<PROGBITS>>"; | ||||
#ifdef __amd64__ | #ifdef __amd64__ | ||||
else if (shdr[i].sh_type == SHT_X86_64_UNWIND) | else if (shdr[i].sh_type == SHT_X86_64_UNWIND) | ||||
ef->progtab[pb].name = "<<UNWIND>>"; | ef->progtab[pb].name = "<<UNWIND>>"; | ||||
#endif | #endif | ||||
else | else | ||||
ef->progtab[pb].name = "<<NOBITS>>"; | ef->progtab[pb].name = "<<NOBITS>>"; | ||||
▲ Show 20 Lines • Show All 167 Lines • ▼ Show 20 Lines | |||||
#if defined(__i386__) || defined(__amd64__) | #if defined(__i386__) || defined(__amd64__) | ||||
/* Now ifuncs. */ | /* Now ifuncs. */ | ||||
error = link_elf_reloc_local(lf, true); | error = link_elf_reloc_local(lf, true); | ||||
if (error != 0) | if (error != 0) | ||||
goto out; | goto out; | ||||
#endif | #endif | ||||
link_elf_protect(ef); | link_elf_protect(ef); | ||||
link_elf_invoke_ctors(lf->ctors_addr, lf->ctors_size); | link_elf_invoke_cbs(lf->ctors_addr, lf->ctors_size); | ||||
*result = lf; | *result = lf; | ||||
out: | out: | ||||
VOP_UNLOCK(nd->ni_vp); | VOP_UNLOCK(nd->ni_vp); | ||||
vn_close(nd->ni_vp, FREAD, td->td_ucred, td); | vn_close(nd->ni_vp, FREAD, td->td_ucred, td); | ||||
free(nd, M_TEMP); | free(nd, M_TEMP); | ||||
if (error && lf) | if (error && lf) | ||||
linker_file_unload(lf, LINKER_UNLOAD_FORCE); | linker_file_unload(lf, LINKER_UNLOAD_FORCE); | ||||
free(hdr, M_LINKER); | free(hdr, M_LINKER); | ||||
return error; | return error; | ||||
} | } | ||||
static void | static void | ||||
link_elf_unload_file(linker_file_t file) | link_elf_unload_file(linker_file_t file) | ||||
{ | { | ||||
elf_file_t ef = (elf_file_t) file; | elf_file_t ef = (elf_file_t) file; | ||||
u_int i; | u_int i; | ||||
link_elf_invoke_cbs(file->dtors_addr, file->dtors_size); | |||||
/* Notify MD code that a module is being unloaded. */ | /* Notify MD code that a module is being unloaded. */ | ||||
elf_cpu_unload_file(file); | elf_cpu_unload_file(file); | ||||
if (ef->progtab) { | if (ef->progtab) { | ||||
for (i = 0; i < ef->nprogtab; i++) { | for (i = 0; i < ef->nprogtab; i++) { | ||||
if (ef->progtab[i].size == 0) | if (ef->progtab[i].size == 0) | ||||
continue; | continue; | ||||
▲ Show 20 Lines • Show All 552 Lines • Show Last 20 Lines |