https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83782
Alexandre Oliva <aoliva at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |aoliva at gcc dot gnu.org --- Comment #8 from Alexandre Oliva <aoliva at gcc dot gnu.org> --- I'm running into some problems that are related with this PR. First off, on i686-linux-gnu with --enable-default-pie, attr-ifunc-3.c fails to link with e.g. binutils 2.30 (the linker in Trisquel 9), from before binutils commit 4ec0995016801cc5d5cf13baf6e10163861e6852. The error was "relocation R_386_GOTOFF against STT_GNU_IFUNC symbol `foo' isn't supported". Using a binutils 2.38.50 from May 2022, it doesn't fail to link, but it fails at runtime. The @GOTOFF relocation to the IFUNC appears to be handled correctly only in PDEs. I figured @GOTOFF for IFUNCs was an unreliable feature to use on x86, and patched predicates.md:local_symbolic_operand to return !ix86_call_use_plt_p (op) instead of true for SYMBOL_REF_LOCAL_P. That got (pun not intended) attr-ifunc-3.c to pass, but regressed the testcases named after this PR. I started looking into how it was supposed to work, and how it managed to work on x86_64, and understood the reasoning of forcing into existence and using the PLT entry as the canonical address for the IFUNC. That works for hidden visibility, but I wondered, what if the symbol bound locally in a shared lib, but was still visible to the main executable, i.e., protected visibility? Alas, even on x86_64, that resolves the IFUNC to different canonical addresses. Specifically, compiling and linking pr83782-1.c s/hidden/protected/ into a shared library, and then compiling and linking the following main program with this library, the function calls succeed, but the pointer compare fails: extern void foo (void); extern void *bar(void); int main() { void (*p)(void) = bar(); p(); foo(); if (p != foo) __builtin_abort (); } ISTM the test has to be stricter than binding locally, it has to either be known to be part of the main executable (-fPIE/-fpie) or known not to be visible to other loadable modules. As for x86, I don't see that it's prudent to use @GOTOFF for IFUNC even with -fPIC: even if the PIE linker bug is fixed, regular PIC may be used in PIE, and linkers since 2018 will silently misresolve the relocation. WDYT?