https://sourceware.org/bugzilla/show_bug.cgi?id=29655
--- Comment #15 from Ulrich Weigand <uweigand at gcc dot gnu.org> --- Thanks for the test case! A few comments: 1. In this scenario, it is indeed not guaranteed that fn1 compares equal to fn1_public everywhere. This is because fn1 is declared hidden in libfoo.c, so all references from that file must go to the definition within the file. However, fn1_public *can* be overridden according the usual ELF rules, e.g. if the main executable (or some other library loaded earlier) had its own definition of `fn1_public`, the ELF standard requires that all references to `fn1_public` point to that definition instead of the aliased `fn1`. A decision to use a canonical PLT definition for `fn1_public` in the main executable counts as "overriding" in that sense as well. So the observed difference in behavior comes indeed down to a difference in whether canonical PLTs are used or not. 2. The difference can be observed only when compiling main with -fPIC. Without -fPIC, both x86_64 and and s390x will use canonical PLT. However, with -fPIC, only s390x uses a canonical PLT while x86_64 does not. 3. Looking at the generated assembler in the -fPIC case, the two platforms are very similar: call fn1_public@PLT movq fn1_public@GOTPCREL(%rip), %rax movq %rax, %rdi call call_callback@PLT vs. brasl %r14,fn1_public@PLT lgrl %r1,fn1_public@GOTENT lgr %r2,%r1 brasl %r14,call_callback@PLT And in fact, there *shouldn't* be any necessity for a canonical PLT on either platform - neither the call (using @PLT) nor the GOT-based function pointer would require it. So it seems to me there may indeed be a problem on s390x, but it doesn't appear to have anything to with gas - rather, the question is why the linker chooses to use a canonical PLT for fn1_public if it is only used via @PLT and @GOTENT relocations ... -- You are receiving this mail because: You are on the CC list for the bug.