Bug 26164 - powerpc64le: ld requires a nop after a branch to another compilation unit
Summary: powerpc64le: ld requires a nop after a branch to another compilation unit
Status: RESOLVED INVALID
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.35
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-06-24 13:09 UTC by Tulio Magno Quites Machado Filho
Modified: 2020-06-25 01:24 UTC (History)
3 users (show)

See Also:
Host: powerpc64le-linux-gnu
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tulio Magno Quites Machado Filho 2020-06-24 13:09:08 UTC
During the link stage for libc.so, the linker throws the following error when the code is assembled with -mpower10 or -mfuture.

sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S:163:(.text+0xfc): call to `__GI_exit' lacks nop, can't restore toc; (toc save/adjust stub)

The affected code is:

 160         li    r3,-1
 161 L(do_exit):
 162 #ifdef SHARED
 163         b     JUMPTARGET(__GI_exit);
 164 #else
 165         b     JUMPTARGET(exit);
 166         nop
 167 #endif
 168         b    L(do_exit)

The original code is available here: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S;hb=HEAD#l163
Comment 1 Alan Modra 2020-06-25 00:11:07 UTC
That would be correct linker behaviour, at least if you allow that the linker doesn't have special knowledge about __GI_exit never returning.

__makecontext is assembly declared to use and preserve r2 (localentry:8), whereas with -mcpu=power10 posix/_exit.c is compiled to a function that is declared to not use *and not preserve* r2 (localentry:1).

Faced with a call from a function that apparently needs to preserve r2 to a function that apparently does not, the linker tries to insert a stub that saves r2 with r2 being restored on return from the call.  In this case there is no nop to replace with an insn to restore r2 (and "b" rather than "bl" is used) so the linker knows r2 can't be restored.  Note that the linker decides whether the call should preserve r2 by the relocation on the call insn rather than the st_other localentry bits of __makecontext.

So it seems to me that glibc ought to be using "b __GI_exit@notoc" to call _exit from makecontext when building for power10.
Comment 2 Alan Modra 2020-06-25 01:24:14 UTC
Another thing to consider with regards to glibc assembly is that functions using plain ENTRY as opposed to ENTRY_TOCLESS may incur extra overhead when being called.  For example when linking staticly, a call from pcrel code to a function that uses r2 will never be direct to the local entry point.  Instead the call will go via a stub to the global entry point.

BTW, -Wl,-stats might be useful in tracking down these cases.