alexcrichton added the bug label to Issue #14946.
alexcrichton added the cranelift label to Issue #14946.
alexcrichton opened issue #14946:
This test:
test run target x86_64 target aarch64 ;; `%main` passes a fake vmctx where the stack limit chain resolves to 0. function %callee(i64 vmctx) -> i8 system_v { gv0 = vmctx gv1 = load.i64 notrap aligned gv0-512 gv2 = load.i64 notrap aligned gv1-520 stack_limit = gv2 ss0 = explicit_slot 64 block0(v0: i64): v1 = iconst.i8 1 return v1 } function %main() -> i8 system_v { ss0 = explicit_slot 2048 sig0 = (i64 vmctx) -> i8 system_v fn0 = %callee sig0 block0: v0 = stack_addr.i64 ss0+1024 v1 = stack_addr.i64 ss0+512 store.i64 notrap aligned v0, v1 v2 = stack_addr.i64 ss0+504 v3 = iconst.i64 0 store.i64 notrap aligned v3, v2 v4 = call fn0(v0) return v4 } ; run: %main() == 1fails with:
$ cargo run --target aarch64-unknown-linux-gnu -p cranelift-tools -- test stack-limit-chain.clif qemu: uncaught target signal 11 (Segmentation fault) - core dumpedIt passes on x86_64. The aarch64 prologue for
%calleeis:$ cargo run -p cranelift-tools -- compile --target aarch64 -D stack-limit-chain.clif Disassembly of 60 bytes <%callee>: 0: fd 7b bf a9 stp x29, x30, [sp, #-0x10]! 4: fd 03 00 91 mov x29, sp 8: f0 3f 80 92 mov x16, #-0x200 c: 10 e8 70 f8 ldr x16, [x0, x16, sxtx] 10: f0 40 80 92 mov x16, #-0x208 ; <- clobbers x16, also an address 14: 10 ea 70 f8 ldr x16, [x16, x16, sxtx] 18: 10 02 01 91 add x16, x16, #0x40 1c: ff 63 30 eb cmp sp, x16 20: c3 00 00 54 b.lo #0x38 ...<details>
<summary>LLM details, if useful</summary>
generate_gvincranelift/codegen/src/machinst/abi.rsloads every level
of astack_limitchain intoget_stacklimit_reg(), which is x16 on
aarch64, so from the second level on the load isldr x16, [x16 + off].
Whenofffits neither SImm9 nor a scaled UImm12,mem_finalize
materialises it into x16 too, overwriting the base before the load (mov x16, #-0x208above), so the load reads2*off. The result is a crash or
a garbage stack limit (a missed or spurious stack-overflow trap).Wasmtime's own chain uses small aligned offsets (
ldur x16, [x2, #8]; ldur x16, [x16, #24]), so this isn't reachable from Wasm. A possible fix is to
use x17 for the materialised offset in aarch64'sgen_load_base_offset
whenbaseis x16, likeLoadAddrdoes. riscv64 and s390x haven't been
checked for the same pattern.</details>
alexcrichton added the cranelift:area:aarch64 label to Issue #14946.
Last updated: Oct 31 2026 at 23:03 UTC