Skip to content

Commit

Permalink
Only add CFI instructions for panic=unwind build
Browse files Browse the repository at this point in the history
  • Loading branch information
nbdd0121 committed Oct 21, 2024
1 parent c5f39d6 commit 07d305b
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 45 deletions.
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

0 comments on commit 07d305b

Please sign in to comment.