Skip to content

Commit

Permalink
Implement unwind support for ARM64 Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
dpaoliello committed Sep 19, 2024
1 parent d0cdac7 commit 43926a3
Show file tree
Hide file tree
Showing 7 changed files with 472 additions and 53 deletions.
12 changes: 12 additions & 0 deletions cranelift/codegen/src/isa/aarch64/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,13 @@ impl ABIMachineSpec for AArch64MachineDeps {
if incoming_args_diff > 0 {
// Decrement SP to account for the additional space required by a tail call.
insts.extend(Self::gen_sp_reg_adjust(-(incoming_args_diff as i32)));
if flags.unwind_info() {
insts.push(Inst::Unwind {
inst: UnwindInst::StackAlloc {
size: incoming_args_diff,
},
});
}

// Move fp and lr down.
if setup_frame {
Expand Down Expand Up @@ -921,6 +928,11 @@ impl ABIMachineSpec for AArch64MachineDeps {
let stack_size = frame_layout.fixed_frame_storage_size + frame_layout.outgoing_args_size;
if stack_size > 0 {
insts.extend(Self::gen_sp_reg_adjust(-(stack_size as i32)));
if flags.unwind_info() {
insts.push(Inst::Unwind {
inst: UnwindInst::StackAlloc { size: stack_size },
});
}
}

insts
Expand Down
9 changes: 5 additions & 4 deletions cranelift/codegen/src/isa/aarch64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,11 @@ impl TargetIsa for AArch64Backend {
)?,
))
}
UnwindInfoKind::Windows => {
// TODO: support Windows unwind info on AArch64
None
}
UnwindInfoKind::Windows => Some(UnwindInfo::WindowsArm64(
crate::isa::unwind::winarm64::create_unwind_info_from_insts(
&result.buffer.unwind_info[..],
)?,
)),
_ => None,
})
}
Expand Down
42 changes: 42 additions & 0 deletions cranelift/codegen/src/isa/unwind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ pub mod systemv;
#[cfg(feature = "unwind")]
pub mod winx64;

#[cfg(feature = "unwind")]
pub mod winarm64;

/// CFA-based unwind information used on SystemV.
pub type CfaUnwindInfo = systemv::UnwindInfo;

Expand Down Expand Up @@ -39,6 +42,9 @@ pub enum UnwindInfo {
/// System V ABI unwind information.
#[cfg(feature = "unwind")]
SystemV(CfaUnwindInfo),
/// Windows Arm64 ABI unwind information.
#[cfg(feature = "unwind")]
WindowsArm64(winarm64::UnwindInfo),
}

/// Unwind pseudoinstruction used in VCode backends: represents that
Expand Down Expand Up @@ -197,3 +203,39 @@ pub enum UnwindInst {
return_addresses: bool,
},
}

struct Writer<'a> {
buf: &'a mut [u8],
offset: usize,
}

impl<'a> Writer<'a> {
pub fn new(buf: &'a mut [u8]) -> Self {
Self { buf, offset: 0 }
}

fn write_u8(&mut self, v: u8) {
self.buf[self.offset] = v;
self.offset += 1;
}

fn write_u16_le(&mut self, v: u16) {
self.buf[self.offset..(self.offset + 2)].copy_from_slice(&v.to_le_bytes());
self.offset += 2;
}

fn write_u16_be(&mut self, v: u16) {
self.buf[self.offset..(self.offset + 2)].copy_from_slice(&v.to_be_bytes());
self.offset += 2;
}

fn write_u32_le(&mut self, v: u32) {
self.buf[self.offset..(self.offset + 4)].copy_from_slice(&v.to_le_bytes());
self.offset += 4;
}

fn write_u32_be(&mut self, v: u32) {
self.buf[self.offset..(self.offset + 4)].copy_from_slice(&v.to_be_bytes());
self.offset += 4;
}
}
Loading

0 comments on commit 43926a3

Please sign in to comment.