Stream: git-wasmtime

Topic: wasmtime / issue #6567 Tail calls seem incompatible with ...


view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2023 at 21:28):

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

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2023 at 21:28):

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

view this post on Zulip Wasmtime GitHub notifications bot (Jun 12 2023 at 21:37):

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