https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108315

Alan Modra <amodra at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |amodra at gmail dot com

--- Comment #5 from Alan Modra <amodra at gmail dot com> ---
Any caller of bar should be fine.  The localentry value of 1 means it is
advertised as having no requirement on r2 or r12 and r2 is *not* preserved.  A
call that uses R_PPC64_REL24 to bar ought to have an r2 saving stub inserted by
the linker and the nop after the call changed to restore r2.  GNU ld will do
exactly that.

0000000010000540 <00000047.long_branch.bar>:
    10000540:   18 00 41 f8     std     r2,24(r1)
    10000544:   4c 02 00 48     b       10000790 <bar>
        ...

00000000100005a0 <main>:
    100005a0:   02 10 40 3c     lis     r2,4098
    100005a4:   00 7f 42 38     addi    r2,r2,32512
    100005a8:   a6 02 08 7c     mflr    r0
    100005ac:   00 00 00 60     nop
    100005b0:   20 80 62 e8     ld      r3,-32736(r2)
    100005b4:   10 00 01 f8     std     r0,16(r1)
    100005b8:   e1 ff 21 f8     stdu    r1,-32(r1)
    100005bc:   85 ff ff 4b     bl      10000540 <00000047.long_branch.bar>
    100005c0:   18 00 41 e8     ld      r2,24(r1)

There isn't a problem if bar is passed the address of a non-pcrel function in a
shared library as it is in your example.  The call in bar will go to the global
entry point of foo, which will set up r2.  The same thing happens when linking
against foo.o, the function pointer address is that of the global entry of foo.
[amodra@gcc135 p10-interop]$ ./smain 
Hello from foo
Hello, World!

(My dynamic main won't run on gcc135 due to my build machine having a more
recent glibc, but I'm confident it would run if I fixed that.)

I don't see any problem here other than (presumably) missing linker support.

Reply via email to