Repository navigation
aarch64: Wrong unwind info and panics on Windows #14939
Copy link
Copy link
Open
Labels
bugIncorrect behavior in the current implementation that needs fixingIncorrect behavior in the current implementation that needs fixingcraneliftIssues related to the Cranelift code generatorIssues related to the Cranelift code generatorcranelift:area:aarch64Issues related to AArch64 backend.Issues related to AArch64 backend.
Description
This test:
test unwind
set unwind_info
target aarch64-pc-windows-msvc
function %f() preserve_all {
fn0 = %g()
block0:
call fn0()
return
}
fails with:
$ cargo run -p cranelift-tools -- test preserve-all.clif
thread 'worker #N' panicked at cranelift/codegen/src/isa/unwind/winarm64.rs:263:33:
Can't save registers before X19
FAIL preserve-all.clif: panicked in worker #N: Can't save registers before X19
1 tests
Error: 1 failure
This module:
(module
(type $t (func (param i32) (result i32)))
(table funcref (elem $g))
(func $g (type $t) local.get 0 i32.const 1 i32.add)
(func (export "f") (param i32) (result i32)
local.get 0
i32.const 0
return_call_indirect (type $t)))fails with guest debugging enabled:
$ cargo run --features all-arch -- compile --target aarch64-pc-windows-msvc -D guest-debug=y retcall_ind.wat
thread '<unnamed>' panicked at cranelift/codegen/src/isa/unwind/winarm64.rs:263:33:
Can't save registers before X19
Without guest debugging it compiles, but its unwind info is wrong:
$ cargo run --features all-arch -- compile --target aarch64-pc-windows-msvc retcall_ind.wat
$ aarch64-linux-gnu-objdump -d retcall_ind.cwasm
0000000000000020 <wasm[0]::function[1]>:
20: a9bf7bfd stp x29, x30, [sp, #-16]!
24: 910003fd mov x29, sp
28: f8408050 ldur x16, [x2, #8]
2c: f8418210 ldur x16, [x16, #24]
30: 91008210 add x16, x16, #0x20
34: eb3063ff cmp sp, x16
38: 54000363 b.cc a4 <wasm[0]::function[1]+0x84>
3c: a9bf6bf3 stp x19, x26, [sp, #-16]!
...
$ aarch64-linux-gnu-objcopy -O binary --only-section=.xdata retcall_ind.cwasm retcall_ind.xdata
$ xxd -g1 retcall_ind.xdata | head -2
00000000: 05 00 00 08 e1 81 00 00 23 00 00 08 cc 01 e1 81 ........#.......
00000010: 3a 00 00 30 01 da 01 da 81 db 01 db 81 cc 01 cc :..0............
The .xdata entry for function[1] is at offset 0x8, and its unwind codes
are cc 01 e1 81:
cc 01issave_regp_x x19, x20, [sp, #-16]!, but the prologue savesx19, x26.- There's no
end(e4) code. The next function's header (3a 00 00 30) follows immediately. - The stack-limit check at 0x28-0x38 has no codes, so the codes don't map one-to-one to prologue instructions.
LLM summary, if helpful
All three are in cranelift/codegen/src/isa/unwind/winarm64.rs:
preserve_allpanic: Windows arm64 unwind codes can only describe
saves of x19-x28 and d8-d15 (short ofsave_any_xreg), and
create_unwind_infopanics on anything else.preserve_allsaves
x0-x17 too, and Wasmtime uses it for the guest-debug breakpoint
trampoline.- Non-consecutive pair: the prologue saves callee-saved registers two
at a time in sorted order, and regalloc2 doesn't hand them out
consecutively, sostp x19, x26happens. The twoSaveRegrecords are
merged into onesave_regp_x, which can only express x(N), x(N+1), and
the second register is dropped. An SEH unwinder would restore x20 from
x26's slot and leave x26 alone. - No
endcode / not one-to-one:emitwrites only the prologue
codes, neverend, and nonopcodes for prologue instructions that
don't change unwind state (bti c, the stack-limit check, the tail-call
frame move, multi-instruction SP adjustments). The format requires both
for unwinding from inside a prologue. Wasmtime's own unwinding uses
frame pointers, so this affects only SEH-based tools (debuggers, ETW,
RtlVirtualUnwind). None of this was tested on Windows.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugIncorrect behavior in the current implementation that needs fixingIncorrect behavior in the current implementation that needs fixingcraneliftIssues related to the Cranelift code generatorIssues related to the Cranelift code generatorcranelift:area:aarch64Issues related to AArch64 backend.Issues related to AArch64 backend.
Activity