diff options
author | Renato Botelho <renato@netgate.com> | 2018-05-18 14:53:44 -0300 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2018-05-18 14:53:44 -0300 |
commit | 64f021cd075bbcb3042539dcebc63e7d335ec2c0 (patch) | |
tree | 1a64375406a7b5976f98eaf4cf19f00cf2931dd1 /sys/kern/link_elf_obj.c | |
parent | 8f29f1de284afe0ec8987780d5404a3e1a31712a (diff) | |
parent | eb64daea863b1fe3320e10c6c72cbfe7e9ce967b (diff) | |
download | FreeBSD-src-64f021cd075bbcb3042539dcebc63e7d335ec2c0.zip FreeBSD-src-64f021cd075bbcb3042539dcebc63e7d335ec2c0.tar.gz |
Merge remote-tracking branch 'origin/stable/11' into devel-11
Diffstat (limited to 'sys/kern/link_elf_obj.c')
-rw-r--r-- | sys/kern/link_elf_obj.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c index ad415ce..0953eb0 100644 --- a/sys/kern/link_elf_obj.c +++ b/sys/kern/link_elf_obj.c @@ -1194,12 +1194,19 @@ static int link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, linker_symval_t *symval) { - elf_file_t ef = (elf_file_t) lf; - const Elf_Sym *es = (const Elf_Sym*) sym; + elf_file_t ef; + 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)) { 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; return 0; } @@ -1284,7 +1291,8 @@ link_elf_each_function_name(linker_file_t file, /* Exhaustive search */ for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { 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); if (error) return (error); @@ -1305,8 +1313,10 @@ link_elf_each_function_nameval(linker_file_t file, /* Exhaustive search */ for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { if (symp->st_value != 0 && - 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_FUNC || + ELF_ST_TYPE(symp->st_info) == STT_GNU_IFUNC)) { + error = link_elf_symbol_values(file, + (c_linker_sym_t)symp, &symval); if (error) return (error); error = callback(file, i, &symval, opaque); |