diff --git a/elf.h b/elf.h index 82fd7ed..fe694de 100644 --- a/elf.h +++ b/elf.h @@ -431,6 +431,7 @@ typedef struct #define STT_SECTION 3 /* Symbol associated with a section */ #define STT_FILE 4 /* Symbol's name is file name */ #define STT_NUM 5 /* Number of defined types. */ +#define STT_GNU_IFUNC 10 /* Symbol is a indirect code object */ #define STT_LOOS 11 /* Start of OS-specific */ #define STT_HIOS 12 /* End of OS-specific */ #define STT_LOPROC 13 /* Start of processor-specific */ diff --git a/libtcc.c b/libtcc.c index ade77c0..c9d37b8 100644 --- a/libtcc.c +++ b/libtcc.c @@ -1431,7 +1431,11 @@ static void rt_printline(unsigned long wanted_pc) sym < sym_end; sym++) { type = ELFW(ST_TYPE)(sym->st_info); +#ifdef STT_IFUNC + if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) { +#else if (type == STT_FUNC) { +#endif if (wanted_pc >= sym->st_value && wanted_pc < sym->st_value + sym->st_size) { pstrcpy(last_func_name, sizeof(last_func_name), diff --git a/tccelf.c b/tccelf.c index 4020e24..6156cc2 100644 --- a/tccelf.c +++ b/tccelf.c @@ -1378,9 +1378,10 @@ int elf_output_file(TCCState *s1, const char *filename) build_got(s1); /* scan for undefined symbols and see if they are in the - dynamic symbols. If a symbol STT_FUNC is found, then we - add it in the PLT. If a symbol STT_OBJECT is found, we - add it in the .bss section with a suitable relocation */ + dynamic symbols. If a symbol STT_FUNC or STT_GNU_IFUNC + is found, then we add it in the PLT. If a symbol + STT_OBJECT is found, we add it in the .bss section with + a suitable relocation */ sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset); if (file_type == TCC_OUTPUT_EXE) { @@ -1393,7 +1394,7 @@ int elf_output_file(TCCState *s1, const char *filename) if (sym_index) { esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index]; type = ELFW(ST_TYPE)(esym->st_info); - if (type == STT_FUNC) { + if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) { put_got_entry(s1, R_JMP_SLOT, esym->st_size, esym->st_info, sym - (ElfW(Sym) *)symtab_section->data); @@ -1470,7 +1471,8 @@ int elf_output_file(TCCState *s1, const char *filename) sym++) { if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { #if defined(TCC_OUTPUT_DLL_WITH_PLT) - if (ELFW(ST_TYPE)(sym->st_info) == STT_FUNC && + if ((ELFW(ST_TYPE)(sym->st_info) == STT_FUNC || + ELFW(ST_TYPE)(sym->st_info) == STT_GNU_IFUNC) && sym->st_shndx == SHN_UNDEF) { put_got_entry(s1, R_JMP_SLOT, sym->st_size, sym->st_info,