Add AArch64 support
This commit is contained in:
parent
e39f404854
commit
789082f176
18
src/arch.rs
18
src/arch.rs
@ -33,3 +33,21 @@ mod riscv {
|
||||
}
|
||||
#[cfg(any(target_arch = "riscv64", target_arch = "riscv32"))]
|
||||
pub use riscv::*;
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
mod aarch64 {
|
||||
use gimli::{AArch64, Register};
|
||||
|
||||
pub struct Arch;
|
||||
|
||||
#[allow(unused)]
|
||||
impl Arch {
|
||||
pub const SP: Register = AArch64::SP;
|
||||
pub const RA: Register = AArch64::X30;
|
||||
|
||||
pub const UNWIND_DATA_REG: (Register, Register) = (AArch64::X0, AArch64::X1);
|
||||
pub const UNWIND_PRIVATE_DATA_SIZE: usize = 2;
|
||||
}
|
||||
}
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub use aarch64::*;
|
||||
|
129
src/unwinder/arch/aarch64.rs
Normal file
129
src/unwinder/arch/aarch64.rs
Normal file
@ -0,0 +1,129 @@
|
||||
use core::fmt;
|
||||
use core::ops;
|
||||
use gimli::{AArch64, Register};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Default)]
|
||||
pub struct Context {
|
||||
pub gp: [usize; 31],
|
||||
pub sp: usize,
|
||||
pub fp: [usize; 32],
|
||||
}
|
||||
|
||||
impl fmt::Debug for Context {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let mut fmt = fmt.debug_struct("Context");
|
||||
for i in 0..=30 {
|
||||
fmt.field(
|
||||
AArch64::register_name(Register(i as _)).unwrap(),
|
||||
&self.gp[i],
|
||||
);
|
||||
}
|
||||
fmt.field("sp", &self.sp);
|
||||
for i in 0..=31 {
|
||||
fmt.field(
|
||||
AArch64::register_name(Register((i + 64) as _)).unwrap(),
|
||||
&self.fp[i],
|
||||
);
|
||||
}
|
||||
fmt.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Index<Register> for Context {
|
||||
type Output = usize;
|
||||
|
||||
fn index(&self, reg: Register) -> &usize {
|
||||
match reg {
|
||||
Register(0..=30) => &self.gp[reg.0 as usize],
|
||||
AArch64::SP => &self.sp,
|
||||
Register(64..=95) => &self.fp[(reg.0 - 64) as usize],
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::IndexMut<gimli::Register> for Context {
|
||||
fn index_mut(&mut self, reg: Register) -> &mut usize {
|
||||
match reg {
|
||||
Register(0..=30) => &mut self.gp[reg.0 as usize],
|
||||
AArch64::SP => &mut self.sp,
|
||||
Register(64..=95) => &mut self.fp[(reg.0 - 64) as usize],
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[naked]
|
||||
pub extern "C-unwind" fn save_context() -> Context {
|
||||
// No need to save caller-saved registers here.
|
||||
unsafe {
|
||||
asm!(
|
||||
"
|
||||
stp d8, d9, [x8, 0x140]
|
||||
stp d10, d11, [x8, 0x150]
|
||||
stp d12, d13, [x8, 0x160]
|
||||
stp d14, d15, [x8, 0x170]
|
||||
|
||||
str x19, [x8, 0x98]
|
||||
stp x20, x21, [x8, 0xA0]
|
||||
stp x22, x23, [x8, 0xB0]
|
||||
stp x24, x25, [x8, 0xC0]
|
||||
stp x26, x27, [x8, 0xD0]
|
||||
stp x28, x29, [x8, 0xE0]
|
||||
mov x0, sp
|
||||
stp x30, x0, [x8, 0xF0]
|
||||
|
||||
ret
|
||||
",
|
||||
options(noreturn)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn restore_context(ctx: &Context) -> ! {
|
||||
unsafe {
|
||||
asm!(
|
||||
"
|
||||
ldp d0, d1, [x0, 0x100]
|
||||
ldp d2, d3, [x0, 0x110]
|
||||
ldp d4, d5, [x0, 0x120]
|
||||
ldp d6, d7, [x0, 0x130]
|
||||
ldp d8, d9, [x0, 0x140]
|
||||
ldp d10, d11, [x0, 0x150]
|
||||
ldp d12, d13, [x0, 0x160]
|
||||
ldp d14, d15, [x0, 0x170]
|
||||
ldp d16, d17, [x0, 0x180]
|
||||
ldp d18, d19, [x0, 0x190]
|
||||
ldp d20, d21, [x0, 0x1A0]
|
||||
ldp d22, d23, [x0, 0x1B0]
|
||||
ldp d24, d25, [x0, 0x1C0]
|
||||
ldp d26, d27, [x0, 0x1D0]
|
||||
ldp d28, d29, [x0, 0x1E0]
|
||||
ldp d30, d31, [x0, 0x1F0]
|
||||
|
||||
ldp x2, x3, [x0, 0x10]
|
||||
ldp x4, x5, [x0, 0x20]
|
||||
ldp x6, x7, [x0, 0x30]
|
||||
ldp x8, x9, [x0, 0x40]
|
||||
ldp x10, x11, [x0, 0x50]
|
||||
ldp x12, x13, [x0, 0x60]
|
||||
ldp x14, x15, [x0, 0x70]
|
||||
ldp x16, x17, [x0, 0x80]
|
||||
ldp x18, x19, [x0, 0x90]
|
||||
ldp x20, x21, [x0, 0xA0]
|
||||
ldp x22, x23, [x0, 0xB0]
|
||||
ldp x24, x25, [x0, 0xC0]
|
||||
ldp x26, x27, [x0, 0xD0]
|
||||
ldp x28, x29, [x0, 0xE0]
|
||||
ldp x30, x1, [x0, 0xF0]
|
||||
mov sp, x1
|
||||
|
||||
ldp x0, x1, [x0, 0x00]
|
||||
ret
|
||||
",
|
||||
options(noreturn)
|
||||
);
|
||||
}
|
||||
}
|
@ -7,3 +7,8 @@ pub use x86_64::*;
|
||||
mod riscv64;
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
pub use riscv64::*;
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
mod aarch64;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub use aarch64::*;
|
||||
|
Loading…
Reference in New Issue
Block a user