Skip to content

Commit 3fa26f6

Browse files
authored
Manually register-allocate in inline asm (#11595)
This commit fixes a mistake with our inline assembly for resumption of an exception on various platforms. This was detected during the development of #11592 for riscv64 but I believe this affects other platforms too. The basic issue is that our inline assembly blocks are all clobbering the frame pointer because that's what wasm uses but we have no constraint against preventing any input to these inline assembly blocks from being allocated into the frame pointer. This means that if the destination to jump to is allocated to the frame pointer register then we'll jump to wasm's old frame pointer, no the actual destination, because the frame pointer register is clobbered before jumping. An example of this for riscv64 is on [godbolt] where the `s0` register, the frame pointer on riscv64, is clobbered and then jumped to. The fix in this PR is to manually allocate all registers. All input operands are allocated to explicit registers rather than letting the compiler pick which register they're in. This ensures no overlap with the frame pointer and fixes the test in question. Note that s390x isn't updated here as it doesn't have a frame pointer. [godbolt]: https://godbolt.org/z/E9vWb9coq
1 parent b196aef commit 3fa26f6

File tree

3 files changed

+18
-18
lines changed

3 files changed

+18
-18
lines changed

crates/unwinder/src/arch/aarch64.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ pub unsafe fn resume_to_exception_handler(
5757
) -> ! {
5858
unsafe {
5959
core::arch::asm!(
60-
"mov sp, {}",
61-
"mov fp, {}",
62-
"br {}",
63-
in(reg) sp,
64-
in(reg) fp,
65-
in(reg) pc,
60+
"mov sp, x2",
61+
"mov fp, x3",
62+
"br x4",
6663
in("x0") payload1,
6764
in("x1") payload2,
65+
in("x2") sp,
66+
in("x3") fp,
67+
in("x4") pc,
6868
options(nostack, nomem, noreturn),
6969
);
7070
}

crates/unwinder/src/arch/riscv64.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ pub unsafe fn resume_to_exception_handler(
2626
) -> ! {
2727
unsafe {
2828
core::arch::asm!(
29-
"mv sp, {}",
30-
"mv fp, {}",
31-
"jr {}",
32-
in(reg) sp,
33-
in(reg) fp,
34-
in(reg) pc,
29+
"mv sp, a2",
30+
"mv fp, a3",
31+
"jr a4",
3532
in("a0") payload1,
3633
in("a1") payload2,
34+
in("a2") sp,
35+
in("a3") fp,
36+
in("a4") pc,
3737
options(nostack, nomem, noreturn),
3838
);
3939
}

crates/unwinder/src/arch/x86.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ pub unsafe fn resume_to_exception_handler(
2929
) -> ! {
3030
unsafe {
3131
core::arch::asm!(
32-
"mov rsp, {}",
33-
"mov rbp, {}",
34-
"jmp {}",
35-
in(reg) sp,
36-
in(reg) fp,
37-
in(reg) pc,
32+
"mov rsp, rcx",
33+
"mov rbp, rsi",
34+
"jmp rdi",
3835
in("rax") payload1,
3936
in("rdx") payload2,
37+
in("rcx") sp,
38+
in("rsi") fp,
39+
in("rdi") pc,
4040
options(nostack, nomem, noreturn),
4141
);
4242
}

0 commit comments

Comments
 (0)