diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.c @@ -1643,8 +1643,17 @@ return (ENOENT); symval->name = ef->strtab + es->st_name; val = (caddr_t)ef->address + es->st_value; - if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC) + if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC) { + c_linker_sym_t sym1; + long off; + val = ((caddr_t (*)(void))val)(); + if (link_elf_search_symbol(lf, val, &sym1, &off) != 0 || + off != 0) + return (ENOENT); + es = (const Elf_Sym *)sym1; + val = (caddr_t)ef->address + es->st_value; + } symval->value = val; symval->size = es->st_size; return (0); @@ -1677,8 +1686,17 @@ if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) { symval->name = ef->ddbstrtab + es->st_name; val = (caddr_t)ef->address + es->st_value; - if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC) + if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC) { + c_linker_sym_t sym1; + long off; + val = ((caddr_t (*)(void))val)(); + if (link_elf_search_symbol(lf, val, &sym1, &off) != 0 || + off != 0) + return (ENOENT); + es = (const Elf_Sym *)sym1; + val = (caddr_t)ef->address + es->st_value; + } symval->value = val; symval->size = es->st_size; return (0); diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c --- a/sys/kern/link_elf_obj.c +++ b/sys/kern/link_elf_obj.c @@ -1526,8 +1526,17 @@ return (ENOENT); symval->name = ef->ddbstrtab + es->st_name; val = (caddr_t)es->st_value; - if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC) + if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC) { + c_linker_sym_t sym1; + long off; + val = ((caddr_t (*)(void))val)(); + if (link_elf_search_symbol(lf, val, &sym1, &off) != 0 || + off != 0) + return (ENOENT); + es = (const Elf_Sym *)sym1; + val = (caddr_t)ef->address + es->st_value; + } symval->value = val; symval->size = es->st_size; return (0);