https://sourceware.org/bugzilla/show_bug.cgi?id=33798
Bug ID: 33798
Summary: ld ppc64 ELFv2: allow tail call `b foo` in .localentry
1 function
Product: binutils
Version: unspecified
Status: NEW
Severity: normal
Priority: P2
Component: ld
Assignee: unassigned at sourceware dot org
Reporter: i at maskray dot me
Target Milestone: ---
Consider a R_PPC64_REL24 case where `qux` calls `bar` in the same DSO, and
`bar` calls `foo` in another DSO.
If we have `.localentry bar, 1`, `foo` should allow for tail calls, since all
callers of `foo` know that the TOC pointer is clobbered (localentry 1
semantics).
This doesn't currently work because
* Linkers current reject `b foo`. bfd/elf64-ppc.c reports: call to `foo'
lacks nop, can't restore toc; (plt call stub)
* GCC and Clang don't seem to set `.localentry bar, 1` (
https://github.com/llvm/llvm-project/issues/98859 )
.abiversion 2
.text
.globl bar # -- Begin function bar
.p2align 4
.type bar,@function
.hidden bar
bar: # @bar
.Lfunc_begin0:
.localentry bar, 1
b foo
.Lfunc_end0:
.size bar, .Lfunc_end0-.Lfunc_begin0
.globl qux # -- Begin function qux
.p2align 4
.type qux,@function
qux: # @qux
.Lfunc_begin1:
.Lfunc_gep1:
addis 2, 12, .TOC.-.Lfunc_gep1@ha
addi 2, 2, .TOC.-.Lfunc_gep1@l
.Lfunc_lep1:
.localentry qux, .Lfunc_lep1-.Lfunc_gep1
bl bar
nop
bl bar
nop
.Lfunc_end1:
.size qux, .Lfunc_end1-.Lfunc_begin1
% ~/Dev/binutils-gdb/out/ppc64le/gas/as-new a.s -o a.o
% ~/Dev/binutils-gdb/out/ppc64le/ld/ld-new a.o -shared
a.o: in function `bar':
(.text+0x0): call to `foo' lacks nop, can't restore toc; (plt call stub)
/home/ray/Dev/binutils-gdb/out/ppc64le/ld/ld-new: final link failed: bad value
While this localentry=1 approach works in theory, it's difficult to associate
the `b foo` call site with the `bar` symbol.
I will summarize the discussions at
https://maskray.me/blog/2023-02-25-linker-notes-on-power-isa#tail-call
--
You are receiving this mail because:
You are on the CC list for the bug.