Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only add CFI instructions for panic=unwind build #40

Merged
merged 2 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ members = [
"test_crates/throw_and_catch",
"test_crates/catch_std_exception",
"test_crates/std_catch_exception",
"test_crates/panic_abort_no_debuginfo",
]

[dependencies]
Expand Down
22 changes: 14 additions & 8 deletions src/unwinder/arch/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use core::fmt;
use core::ops;
use gimli::{AArch64, Register};

use super::maybe_cfi;

// Match DWARF_FRAME_REGISTERS in libgcc
pub const MAX_REG_RULES: usize = 97;

Expand Down Expand Up @@ -61,13 +63,15 @@ macro_rules! save {
(gp$(, $fp:ident)?) => {
// No need to save caller-saved registers here.
core::arch::naked_asm!(
"
stp x29, x30, [sp, -16]!
"stp x29, x30, [sp, -16]!",
maybe_cfi!("
.cfi_def_cfa_offset 16
.cfi_offset x29, -16
.cfi_offset x30, -8
sub sp, sp, 512
.cfi_def_cfa_offset 528
"),
"sub sp, sp, 512",
maybe_cfi!(".cfi_def_cfa_offset 528"),
"
mov x8, x0
mov x0, sp
",
Expand All @@ -85,13 +89,15 @@ macro_rules! save {
blr x8

add sp, sp, 512
.cfi_def_cfa_offset 16
ldp x29, x30, [sp], 16
",
maybe_cfi!(".cfi_def_cfa_offset 16"),
"ldp x29, x30, [sp], 16",
maybe_cfi!("
.cfi_def_cfa_offset 0
.cfi_restore x29
.cfi_restore x30
ret
",
"),
"ret",
);
};
(maybesavefp(fp)) => {
Expand Down
18 changes: 18 additions & 0 deletions src/unwinder/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,21 @@ pub use aarch64::*;
target_arch = "aarch64"
)))]
compile_error!("Current architecture is not supported");

// CFI directives cannot be used if neither debuginfo nor panic=unwind is enabled.
// We don't have an easy way to check the former, so just check based on panic strategy.
#[cfg(panic = "abort")]
macro_rules! maybe_cfi {
($x: literal) => {
""
};
}

#[cfg(panic = "unwind")]
macro_rules! maybe_cfi {
($x: literal) => {
$x
};
}

pub(crate) use maybe_cfi;
26 changes: 14 additions & 12 deletions src/unwinder/arch/riscv32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use core::fmt;
use core::ops;
use gimli::{Register, RiscV};

use super::maybe_cfi;

// Match DWARF_FRAME_REGISTERS in libgcc
pub const MAX_REG_RULES: usize = 65;

Expand Down Expand Up @@ -176,10 +178,10 @@ pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Context, *mut ()), p
"
mv t0, sp
add sp, sp, -0x190
.cfi_def_cfa_offset 0x190
sw ra, 0x180(sp)
.cfi_offset ra, -16
",
maybe_cfi!(".cfi_def_cfa_offset 0x190"),
"sw ra, 0x180(sp)",
maybe_cfi!(".cfi_offset ra, -16"),
code!(save_gp),
code!(save_fp),
"
Expand All @@ -188,10 +190,10 @@ pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Context, *mut ()), p
jalr t0
lw ra, 0x180(sp)
add sp, sp, 0x190
.cfi_def_cfa_offset 0
.cfi_restore ra
ret
",
maybe_cfi!(".cfi_def_cfa_offset 0"),
maybe_cfi!(".cfi_restore ra"),
"ret",
);
}
#[cfg(not(target_feature = "d"))]
Expand All @@ -200,21 +202,21 @@ pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Context, *mut ()), p
"
mv t0, sp
add sp, sp, -0x90
.cfi_def_cfa_offset 0x90
sw ra, 0x80(sp)
.cfi_offset ra, -16
",
maybe_cfi!(".cfi_def_cfa_offset 0x90"),
"sw ra, 0x80(sp)",
maybe_cfi!(".cfi_offset ra, -16"),
code!(save_gp),
"
mv t0, a0
mv a0, sp
jalr t0
lw ra, 0x80(sp)
add sp, sp, 0x90
.cfi_def_cfa_offset 0
.cfi_restore ra
ret
",
maybe_cfi!(".cfi_def_cfa_offset 0"),
maybe_cfi!(".cfi_restore ra"),
"ret",
);
}
}
Expand Down
26 changes: 14 additions & 12 deletions src/unwinder/arch/riscv64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use core::fmt;
use core::ops;
use gimli::{Register, RiscV};

use super::maybe_cfi;

// Match DWARF_FRAME_REGISTERS in libgcc
pub const MAX_REG_RULES: usize = 65;

Expand Down Expand Up @@ -176,10 +178,10 @@ pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Context, *mut ()), p
"
mv t0, sp
add sp, sp, -0x210
.cfi_def_cfa_offset 0x210
sd ra, 0x200(sp)
.cfi_offset ra, -16
",
maybe_cfi!(".cfi_def_cfa_offset 0x210"),
"sd ra, 0x200(sp)",
maybe_cfi!(".cfi_offset ra, -16"),
code!(save_gp),
code!(save_fp),
"
Expand All @@ -188,10 +190,10 @@ pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Context, *mut ()), p
jalr t0
ld ra, 0x200(sp)
add sp, sp, 0x210
.cfi_def_cfa_offset 0
.cfi_restore ra
ret
",
maybe_cfi!(".cfi_def_cfa_offset 0"),
maybe_cfi!(".cfi_restore ra"),
"ret",
);
}
#[cfg(not(target_feature = "d"))]
Expand All @@ -200,21 +202,21 @@ pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Context, *mut ()), p
"
mv t0, sp
add sp, sp, -0x110
.cfi_def_cfa_offset 0x110
sd ra, 0x100(sp)
.cfi_offset ra, -16
",
maybe_cfi!(".cfi_def_cfa_offset 0x110"),
"sd ra, 0x100(sp)",
maybe_cfi!(".cfi_offset ra, -16"),
code!(save_gp),
"
mv t0, a0
mv a0, sp
jalr t0
ld ra, 0x100(sp)
add sp, sp, 0x110
.cfi_def_cfa_offset 0
.cfi_restore ra
ret
",
maybe_cfi!(".cfi_def_cfa_offset 0"),
maybe_cfi!(".cfi_restore ra"),
"ret",
);
}
}
Expand Down
19 changes: 11 additions & 8 deletions src/unwinder/arch/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use core::fmt;
use core::ops;
use gimli::{Register, X86};

use super::maybe_cfi;

// Match DWARF_FRAME_REGISTERS in libgcc
pub const MAX_REG_RULES: usize = 17;

Expand Down Expand Up @@ -59,10 +61,9 @@ pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Context, *mut ()), p
// No need to save caller-saved registers here.
unsafe {
core::arch::naked_asm!(
"sub esp, 52",
maybe_cfi!(".cfi_def_cfa_offset 56"),
"
sub esp, 52
.cfi_def_cfa_offset 56

mov [esp + 4], ecx
mov [esp + 8], edx
mov [esp + 12], ebx
Expand All @@ -85,15 +86,17 @@ pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Context, *mut ()), p
mov eax, [esp + 60]
mov ecx, esp
push eax
.cfi_adjust_cfa_offset 4
push ecx
.cfi_adjust_cfa_offset 4
",
maybe_cfi!(".cfi_adjust_cfa_offset 4"),
"push ecx",
maybe_cfi!(".cfi_adjust_cfa_offset 4"),
"
call [esp + 64]

add esp, 60
.cfi_def_cfa_offset 4
ret
",
maybe_cfi!(".cfi_def_cfa_offset 4"),
"ret",
);
}
}
Expand Down
12 changes: 7 additions & 5 deletions src/unwinder/arch/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use core::fmt;
use core::ops;
use gimli::{Register, X86_64};

use super::maybe_cfi;

// Match DWARF_FRAME_REGISTERS in libgcc
pub const MAX_REG_RULES: usize = 17;

Expand Down Expand Up @@ -61,9 +63,9 @@ pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Context, *mut ()), p
// No need to save caller-saved registers here.
unsafe {
core::arch::naked_asm!(
"sub rsp, 0x98",
maybe_cfi!(".cfi_def_cfa_offset 0xA0"),
"
sub rsp, 0x98
.cfi_def_cfa_offset 0xA0
mov [rsp + 0x18], rbx
mov [rsp + 0x30], rbp

Expand All @@ -87,9 +89,9 @@ pub extern "C-unwind" fn save_context(f: extern "C" fn(&mut Context, *mut ()), p
mov rdi, rsp
call rax
add rsp, 0x98
.cfi_def_cfa_offset 8
ret
"
",
maybe_cfi!(".cfi_def_cfa_offset 8"),
"ret"
);
}
}
Expand Down
7 changes: 7 additions & 0 deletions test_crates/panic_abort_no_debuginfo/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "panic_abort_no_debuginfo"
version = "0.1.0"
edition = "2021"

[dependencies]
unwinding = { path = "../../", features = ["panic"] }
11 changes: 11 additions & 0 deletions test_crates/panic_abort_no_debuginfo/check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -o pipefail

# Skip the test if need -Zbuild-std, it somehow doesn't work.
if [ -n "$BUILD_STD" ]; then
exit 0
fi

export CARGO_TARGET_DIR=$(mktemp -d)
trap "rm -rf $CARGO_TARGET_DIR" EXIT
RUSTFLAGS="-Cpanic=abort -Cdebuginfo=0" ${CARGO:-cargo} build --release $BUILD_STD 2>&1
3 changes: 3 additions & 0 deletions test_crates/panic_abort_no_debuginfo/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
extern crate unwinding;

fn main() {}
1 change: 1 addition & 0 deletions tests/compile_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ fn main() {
"throw_and_catch",
"catch_std_exception",
"std_catch_exception",
"panic_abort_no_debuginfo",
];

for test in tests {
Expand Down