summaryrefslogtreecommitdiffstats
path: root/sys/kern/link_elf_obj.c
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2018-05-18 14:53:44 -0300
committerRenato Botelho <renato@netgate.com>2018-05-18 14:53:44 -0300
commit64f021cd075bbcb3042539dcebc63e7d335ec2c0 (patch)
tree1a64375406a7b5976f98eaf4cf19f00cf2931dd1 /sys/kern/link_elf_obj.c
parent8f29f1de284afe0ec8987780d5404a3e1a31712a (diff)
parenteb64daea863b1fe3320e10c6c72cbfe7e9ce967b (diff)
downloadFreeBSD-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.c22
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);
OpenPOWER on IntegriCloud