alexcrichton opened issue #6567:
Locally on an AArch64 macbook I get:
$ cargo run -q test filetests/filetests/runtests/tail-call-conv.clif zsh: bus error cargo run -q test filetests/filetests/runtests/tail-call-conv.clif
If I comment out the
target aarch64 has_pauth sign_return_address
directive the test passes, and the first test that fails is:test run target aarch64 has_pauth sign_return_address ;; Test the `tail` calling convention with non-tail calls and stack arguments. function %tail_callee_stack_args(i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64) -> i64 tail { block0(v0: i64, v1: i64, v2: i64, v3: i64, v4: i64, v5: i64, v6: i64, v7: i64, v8: i64, v9: i64, v10: i64, v11: i64, v12: i64, v13: i64, v14: i64): return v14 } function %tail_caller_stack_args() -> i64 { fn0 = %tail_callee_stack_args(i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64) -> i64 tail block0: v0 = iconst.i64 10 v1 = iconst.i64 15 v2 = iconst.i64 20 v3 = iconst.i64 25 v4 = iconst.i64 30 v5 = iconst.i64 35 v6 = iconst.i64 40 v7 = iconst.i64 45 v8 = iconst.i64 50 v9 = iconst.i64 55 v10 = iconst.i64 60 v11 = iconst.i64 65 v12 = iconst.i64 70 v13 = iconst.i64 75 v14 = iconst.i64 80 v15 = call fn0(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) return v15 } ; run: %tail_caller_stack_args() == 80
Running in a debugger isn't too useful because the crashing thread says it's at address
0x0000000000000037
I don't know much about pointer authentication myself, but stepping through in a debugger this is the entire function
tail_caller_stack_args
with the highlighted instruction where when at that instruction the debugger no longer produces a backtrace:0x103fa80c8: paciasp 0x103fa80cc: stp x29, x30, [sp, #-0x10]! 0x103fa80d0: mov x29, sp 0x103fa80d4: mov x0, #0xa 0x103fa80d8: mov x1, #0xf 0x103fa80dc: mov x2, #0x14 0x103fa80e0: mov x3, #0x19 0x103fa80e4: mov x4, #0x1e 0x103fa80e8: mov x5, #0x23 0x103fa80ec: mov x6, #0x28 0x103fa80f0: mov x7, #0x2d 0x103fa80f4: mov x8, #0x32 0x103fa80f8: mov x9, #0x37 0x103fa80fc: mov x10, #0x3c 0x103fa8100: mov x11, #0x41 0x103fa8104: mov x12, #0x46 0x103fa8108: mov x13, #0x4b 0x103fa810c: mov x14, #0x50 0x103fa8110: sub sp, sp, #0x40 0x103fa8114: stur x8, [sp] 0x103fa8118: stur x9, [sp, #0x8] 0x103fa811c: stur x10, [sp, #0x10] 0x103fa8120: stur x11, [sp, #0x18] 0x103fa8124: stur x12, [sp, #0x20] 0x103fa8128: stur x13, [sp, #0x28] 0x103fa812c: stur x14, [sp, #0x30] 0x103fa8130: ldr x9, #0x8 0x103fa8134: b 0x103fa8140 0x103fa8138: .long 0x03fa8000 ; unknown opcode 0x103fa813c: udf #0x1 0x103fa8140: blr x9 0x103fa8144: ldp x29, x30, [sp], #0x10 -> 0x103fa8148: retaa
The disassembly of
tail_callee_stack_args
looks like:0x103fa8000: paciasp 0x103fa8004: stp x29, x30, [sp, #-0x10]! 0x103fa8008: mov x29, sp 0x103fa800c: ldur x9, [x29, #0x10] 0x103fa8010: ldur x11, [x29, #0x18] 0x103fa8014: ldur x13, [x29, #0x20] 0x103fa8018: ldur x15, [x29, #0x28] 0x103fa801c: ldur x1, [x29, #0x30] 0x103fa8020: ldur x3, [x29, #0x38] 0x103fa8024: ldur x0, [x29, #0x40] 0x103fa8028: ldp x29, x30, [sp], #0x10 0x103fa802c: retaa
alexcrichton labeled issue #6567:
Locally on an AArch64 macbook I get:
$ cargo run -q test filetests/filetests/runtests/tail-call-conv.clif zsh: bus error cargo run -q test filetests/filetests/runtests/tail-call-conv.clif
If I comment out the
target aarch64 has_pauth sign_return_address
directive the test passes, and the first test that fails is:test run target aarch64 has_pauth sign_return_address ;; Test the `tail` calling convention with non-tail calls and stack arguments. function %tail_callee_stack_args(i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64) -> i64 tail { block0(v0: i64, v1: i64, v2: i64, v3: i64, v4: i64, v5: i64, v6: i64, v7: i64, v8: i64, v9: i64, v10: i64, v11: i64, v12: i64, v13: i64, v14: i64): return v14 } function %tail_caller_stack_args() -> i64 { fn0 = %tail_callee_stack_args(i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64) -> i64 tail block0: v0 = iconst.i64 10 v1 = iconst.i64 15 v2 = iconst.i64 20 v3 = iconst.i64 25 v4 = iconst.i64 30 v5 = iconst.i64 35 v6 = iconst.i64 40 v7 = iconst.i64 45 v8 = iconst.i64 50 v9 = iconst.i64 55 v10 = iconst.i64 60 v11 = iconst.i64 65 v12 = iconst.i64 70 v13 = iconst.i64 75 v14 = iconst.i64 80 v15 = call fn0(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) return v15 } ; run: %tail_caller_stack_args() == 80
Running in a debugger isn't too useful because the crashing thread says it's at address
0x0000000000000037
I don't know much about pointer authentication myself, but stepping through in a debugger this is the entire function
tail_caller_stack_args
with the highlighted instruction where when at that instruction the debugger no longer produces a backtrace:0x103fa80c8: paciasp 0x103fa80cc: stp x29, x30, [sp, #-0x10]! 0x103fa80d0: mov x29, sp 0x103fa80d4: mov x0, #0xa 0x103fa80d8: mov x1, #0xf 0x103fa80dc: mov x2, #0x14 0x103fa80e0: mov x3, #0x19 0x103fa80e4: mov x4, #0x1e 0x103fa80e8: mov x5, #0x23 0x103fa80ec: mov x6, #0x28 0x103fa80f0: mov x7, #0x2d 0x103fa80f4: mov x8, #0x32 0x103fa80f8: mov x9, #0x37 0x103fa80fc: mov x10, #0x3c 0x103fa8100: mov x11, #0x41 0x103fa8104: mov x12, #0x46 0x103fa8108: mov x13, #0x4b 0x103fa810c: mov x14, #0x50 0x103fa8110: sub sp, sp, #0x40 0x103fa8114: stur x8, [sp] 0x103fa8118: stur x9, [sp, #0x8] 0x103fa811c: stur x10, [sp, #0x10] 0x103fa8120: stur x11, [sp, #0x18] 0x103fa8124: stur x12, [sp, #0x20] 0x103fa8128: stur x13, [sp, #0x28] 0x103fa812c: stur x14, [sp, #0x30] 0x103fa8130: ldr x9, #0x8 0x103fa8134: b 0x103fa8140 0x103fa8138: .long 0x03fa8000 ; unknown opcode 0x103fa813c: udf #0x1 0x103fa8140: blr x9 0x103fa8144: ldp x29, x30, [sp], #0x10 -> 0x103fa8148: retaa
The disassembly of
tail_callee_stack_args
looks like:0x103fa8000: paciasp 0x103fa8004: stp x29, x30, [sp, #-0x10]! 0x103fa8008: mov x29, sp 0x103fa800c: ldur x9, [x29, #0x10] 0x103fa8010: ldur x11, [x29, #0x18] 0x103fa8014: ldur x13, [x29, #0x20] 0x103fa8018: ldur x15, [x29, #0x28] 0x103fa801c: ldur x1, [x29, #0x30] 0x103fa8020: ldur x3, [x29, #0x38] 0x103fa8024: ldur x0, [x29, #0x40] 0x103fa8028: ldp x29, x30, [sp], #0x10 0x103fa802c: retaa
alexcrichton commented on issue #6567:
With some tweaks I could reproduce this in QEMU. I downloaded and built QEMU 8.0.2 (not sure if that's required it's just the latest) and then changed this condition to always return
true
. I then ran this in one window:$ qemu-aarch64 -g 1234 -cpu max /home/acrichto/code/wasmtime/target/debug/clif-util test filetests/filetests/runtests/tail-call-conv.clif
and this in another window:
$ gdb /home/acrichto/code/wasmtime/target/debug/clif-util (gdb) target remote :1234 Remote debugging using :1234 warning: remote target does not support file transfer, attempting to access files from local filesystem. Reading symbols from /lib/ld-linux-aarch64.so.1... (No debugging symbols found in /lib/ld-linux-aarch64.so.1) 0x000000550470e140 in ?? () from /lib/ld-linux-aarch64.so.1 (gdb) c Continuing. [New Thread 1.753689] [New Thread 1.753686] Thread 2 received signal SIGSEGV, Segmentation fault. [Switching to Thread 1.753689] 0x0020000000000037 in ?? ()
which I think reproduces the issue (although I'm not 100% sure, but it's at least the same crashing address as it was natively)
Last updated: Dec 23 2024 at 12:05 UTC