Commit 6c14011
[ppc64le] Add ELFv2 global entry prologue to coroutine_transfer
The hand-written `coroutine_transfer` in `coroutine/ppc64le/Context.S`
lacks the ELFv2 ABI global entry prologue. When the function is reached
via the PLT (lazy resolution path), r2 (TOC pointer) is left pointing
at whatever the resolver had loaded — typically the dynamic linker's
own TOC — instead of libruby's TOC.
The wrong r2 propagates through the fiber switch into `fiber_entry`,
which jumps into `fiber_restore_thread` → `rb_current_ec_set`. The
first PLT thunk inside the new fiber (`__plt___tls_get_addr` for the
`ruby_current_ec` thread-local) computes its GOT entry as
`r2 + offset` and segfaults dereferencing the bogus address.
This manifests as a SIGSEGV on any code path that uses fibers —
including `Enumerator#next`, so even a one-liner crashes:
ruby -e 'a=[1,2,3]; e=a.to_enum; loop { p e.next }'
# [BUG] Segmentation fault at 0x000000081009ac38
Reproduced on FreeBSD 16-CURRENT/powerpc64le with Ruby 4.0.4. The same
asm exists unchanged in 3.3 and 3.4, so they are likely affected as
well. Linux ppc64le may not hit this if its rtld preserves the caller's
r2 across PLT resolution, but per the ELFv2 ABI spec §2.3.1.2 a global
function entered via the PLT is responsible for setting up its own r2
from r12 — relying on the resolver is non-conformant.
The fix adds the standard two-instruction global entry prologue plus a
`.localentry` directive of 8, matching what the compiler emits for
ordinary C functions (e.g. `rb_current_ec_set` carries `<other: 0x60>`,
i.e. STO_PPC64_LOCAL=3). The local entry point now lands at the
original first instruction (`addi 1,1,-160`), so `coroutine_initialize`
in `Context.h` continues to work unchanged — `start + 8` (which skips
fiber_entry's global prologue to reach its local entry) is still
correct because the offset between global and local entry is identical
across all functions in this module.
References:
- Power Architecture 64-Bit ELF V2 ABI Specification, §2.3.1.2
"Function Calling Sequence"
- STO_PPC64_LOCAL encoding: §3.3 "Symbol Values"1 parent efd35db commit 6c14011
1 file changed
Lines changed: 7 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
9 | 16 | | |
10 | 17 | | |
11 | 18 | | |
| |||
0 commit comments