Control: reassign 1151166 golang-golang-x-sys 0.49.0+dfsg-1
Control: retitle 1151166 golang-golang-x-sys: ppc64x syscall trampolines omit 
the ELFv2 R12 setup, so PIE binaries die at startup
Control: tags 1151166 + patch

Reassigning. This is not golang-1.27.

I filed it against golang-1.27 because siso built on ppc64el under 1.26 and
failed under 1.27. Two things had changed at once. Holding the toolchain fixed
and varying only x/sys, three runs each:

    go1.27.2 + x/sys 0.48.0, -buildmode=pie, ppc64le   ok     3/3
    go1.27.2 + x/sys 0.49.0, -buildmode=pie, ppc64le   crash  3/3
    go1.26.9 + x/sys 0.49.0, -buildmode=pie, ppc64le   crash  3/3

Both toolchains fail with 0.49.0, so only the x/sys version matters.

The cause is in unix/asm_linux_ppc64x.s. The Syscall, Syscall6, RawSyscall and
RawSyscall6 trampolines branch to the global entry point of the generated
syscall ABI0 wrapper without setting R12:

    TEXT ·Syscall(SB),NOSPLIT,$0-56
            MOVD    $syscall·Syscall(SB), R31
            MOVD    R31, CTR
            JMP     (CTR)

In a PIE binary that wrapper derives its TOC from R12, as ELFv2 requires of a
caller that enters through the global entry point. R12 is stale, so the TOC is
displaced and every global access afterwards is wrong. Non-PIE wrappers have no
such prologue, which is why only PIE fails.

One instruction per trampoline fixes it, MOVD R31, R12 after the address load.
The trampolines came back in upstream b6b8557 (2026-10-05), which reverts
7155702 (2018, Fixes golang/go#16662). That commit had removed them on purpose,
because the ppc64x external linker cannot always handle the direct branch when
the offset is too far. Not forwarded upstream yet.

The patch and the measurements are in this merge request:
https://salsa.debian.org/go-team/packages/golang-golang-x-sys/-/merge_requests/6

ppc64 big-endian is not tested. The file serves both and I only ran ppc64le.

Reply via email to