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?

Reply via email to