Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/link_elf_obj.c
Show First 20 Lines • Show All 1,160 Lines • ▼ Show 20 Lines | link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym) | ||||
} | } | ||||
return ENOENT; | return ENOENT; | ||||
} | } | ||||
static int | static int | ||||
link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, | link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, | ||||
linker_symval_t *symval) | linker_symval_t *symval) | ||||
{ | { | ||||
elf_file_t ef = (elf_file_t) lf; | elf_file_t ef; | ||||
const Elf_Sym *es = (const Elf_Sym*) sym; | const Elf_Sym *es; | ||||
caddr_t val; | |||||
ef = (elf_file_t) lf; | |||||
es = (const Elf_Sym*) sym; | |||||
val = (caddr_t)es->st_value; | |||||
if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) { | if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) { | ||||
symval->name = ef->ddbstrtab + es->st_name; | symval->name = ef->ddbstrtab + es->st_name; | ||||
symval->value = (caddr_t)es->st_value; | val = (caddr_t)es->st_value; | ||||
if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC) | |||||
val = ((caddr_t (*)(void))val)(); | |||||
symval->value = val; | |||||
symval->size = es->st_size; | symval->size = es->st_size; | ||||
return 0; | return 0; | ||||
} | } | ||||
return ENOENT; | return ENOENT; | ||||
} | } | ||||
static int | static int | ||||
link_elf_search_symbol(linker_file_t lf, caddr_t value, | link_elf_search_symbol(linker_file_t lf, caddr_t value, | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
elf_file_t ef = (elf_file_t)file; | elf_file_t ef = (elf_file_t)file; | ||||
const Elf_Sym *symp; | const Elf_Sym *symp; | ||||
int i, error; | int i, error; | ||||
/* Exhaustive search */ | /* Exhaustive search */ | ||||
for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { | for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { | ||||
if (symp->st_value != 0 && | if (symp->st_value != 0 && | ||||
ELF_ST_TYPE(symp->st_info) == STT_FUNC) { | (ELF_ST_TYPE(symp->st_info) == STT_FUNC || | ||||
ELF_ST_TYPE(symp->st_info) == STT_GNU_IFUNC)) { | |||||
error = callback(ef->ddbstrtab + symp->st_name, opaque); | error = callback(ef->ddbstrtab + symp->st_name, opaque); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
} | } | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
link_elf_each_function_nameval(linker_file_t file, | link_elf_each_function_nameval(linker_file_t file, | ||||
linker_function_nameval_callback_t callback, void *opaque) | linker_function_nameval_callback_t callback, void *opaque) | ||||
{ | { | ||||
linker_symval_t symval; | linker_symval_t symval; | ||||
elf_file_t ef = (elf_file_t)file; | elf_file_t ef = (elf_file_t)file; | ||||
const Elf_Sym* symp; | const Elf_Sym* symp; | ||||
int i, error; | int i, error; | ||||
/* Exhaustive search */ | /* Exhaustive search */ | ||||
for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { | for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { | ||||
if (symp->st_value != 0 && | if (symp->st_value != 0 && | ||||
ELF_ST_TYPE(symp->st_info) == STT_FUNC) { | (ELF_ST_TYPE(symp->st_info) == STT_FUNC || | ||||
error = link_elf_symbol_values(file, (c_linker_sym_t) symp, &symval); | ELF_ST_TYPE(symp->st_info) == STT_GNU_IFUNC)) { | ||||
error = link_elf_symbol_values(file, | |||||
(c_linker_sym_t)symp, &symval); | |||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
error = callback(file, i, &symval, opaque); | error = callback(file, i, &symval, opaque); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
} | } | ||||
} | } | ||||
return (0); | return (0); | ||||
▲ Show 20 Lines • Show All 231 Lines • Show Last 20 Lines |