generated from EmbarkStudios/opensource-template
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
RtlCaptureContext
replacement (#62)
* Cleanup implementation, add aarch64 * Fix clippy lints * Expose ffi module * Cache deny step * Fixup crash-handler with crash-context * Update crash-handler with crash-context changes * Pointless
- Loading branch information
1 parent
7cba205
commit 11fc5c9
Showing
14 changed files
with
630 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
//! Custom bindings to `CONTEXT` and some structures that relate to it, to both | ||
//! deal with bugs in bindings, as well as not be dependent particularly on | ||
//! `windows-sys` due the massive amount of version churn that crate introduces. | ||
//! | ||
//! Both [`winapi`](https://docs.rs/winapi/latest/winapi/) and | ||
//! [`windows-sys`](https://docs.rs/windows-sys/latest/windows_sys/) have | ||
//! incorrect bindings with regards to `CONTEXT` and its related structures. | ||
//! These structures **must** be aligned to 16 bytes, but [are not](https://github.com/microsoft/win32metadata/issues/1044). | ||
#![allow(non_snake_case)] | ||
|
||
extern "C" { | ||
/// Reimplementation of [`RtlCaptureContext`](https://learn.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlcapturecontext) | ||
/// | ||
/// As noted above, the structures from `winapi` and `windows-sys` have | ||
/// incorrect alignment. | ||
/// | ||
/// In addition, `RtlCaptureContext` only captures the state of the integer | ||
/// registers, while this implementation additionally captures floating point | ||
/// and vector state. | ||
/// | ||
/// The implementation is ported from Crashpad. | ||
/// | ||
/// - [x86](https://github.com/chromium/crashpad/blob/f742c1aa4aff1834dc55e97895f8cdfdfc945a21/util/misc/capture_context_win.asm) | ||
/// - [aarch64](https://github.com/chromium/crashpad/blob/f742c1aa4aff1834dc55e97895f8cdfdfc945a21/util/misc/capture_context_win_arm64.asm) | ||
pub fn capture_context(ctx: *mut CONTEXT); | ||
} | ||
|
||
pub use winapi::um::winnt::EXCEPTION_RECORD; | ||
|
||
cfg_if::cfg_if! { | ||
if #[cfg(target_arch = "x86_64")] { | ||
mod x86_64; | ||
pub use x86_64::*; | ||
} else if #[cfg(target_arch = "x86")] { | ||
compile_error!("Please file an issue if you care about this target"); | ||
//mod x86; | ||
} else if #[cfg(target_arch = "aarch64")] { | ||
mod aarch64; | ||
pub use aarch64::*; | ||
} | ||
} | ||
|
||
#[derive(Copy, Clone)] | ||
#[repr(C)] | ||
pub struct EXCEPTION_POINTERS { | ||
pub ExceptionRecord: *mut EXCEPTION_RECORD, | ||
pub ContextRecord: *mut CONTEXT, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
// Copyright 2019 The Crashpad Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#[derive(Copy, Clone)] | ||
// Note this is intentionally using natural alignment | ||
#[repr(C)] | ||
pub union ARM64_NT_NEON128 { | ||
pub Anonymous: ARM64_NT_NEON128_0, | ||
pub D: [f64; 2], | ||
pub S: [f32; 4], | ||
pub H: [u16; 8], | ||
pub B: [u8; 16], | ||
} | ||
|
||
#[derive(Copy, Clone)] | ||
// Note this is intentionally using natural alignment | ||
#[repr(C)] | ||
pub struct ARM64_NT_NEON128_0 { | ||
pub Low: u64, | ||
pub High: i64, | ||
} | ||
|
||
#[derive(Copy, Clone)] | ||
#[repr(C, align(16))] | ||
pub struct CONTEXT { | ||
pub ContextFlags: u32, | ||
pub Cpsr: u32, | ||
pub Anonymous: CONTEXT_0, | ||
pub Sp: u64, | ||
pub Pc: u64, | ||
pub V: [ARM64_NT_NEON128; 32], | ||
pub Fpcr: u32, | ||
pub Fpsr: u32, | ||
pub Bcr: [u32; 8], | ||
pub Bvr: [u64; 8], | ||
pub Wcr: [u32; 2], | ||
pub Wvr: [u64; 2], | ||
} | ||
|
||
#[derive(Copy, Clone)] | ||
#[repr(C, align(16))] | ||
pub union CONTEXT_0 { | ||
pub Anonymous: CONTEXT_0_0, | ||
pub X: [u64; 31], | ||
} | ||
|
||
#[derive(Copy, Clone)] | ||
#[repr(C, align(16))] | ||
pub struct CONTEXT_0_0 { | ||
pub X0: u64, | ||
pub X1: u64, | ||
pub X2: u64, | ||
pub X3: u64, | ||
pub X4: u64, | ||
pub X5: u64, | ||
pub X6: u64, | ||
pub X7: u64, | ||
pub X8: u64, | ||
pub X9: u64, | ||
pub X10: u64, | ||
pub X11: u64, | ||
pub X12: u64, | ||
pub X13: u64, | ||
pub X14: u64, | ||
pub X15: u64, | ||
pub X16: u64, | ||
pub X17: u64, | ||
pub X18: u64, | ||
pub X19: u64, | ||
pub X20: u64, | ||
pub X21: u64, | ||
pub X22: u64, | ||
pub X23: u64, | ||
pub X24: u64, | ||
pub X25: u64, | ||
pub X26: u64, | ||
pub X27: u64, | ||
pub X28: u64, | ||
pub Fp: u64, | ||
pub Lr: u64, | ||
} | ||
|
||
std::arch::global_asm! { | ||
".text", | ||
".global capture_context", | ||
"capture_context:", | ||
// Save general purpose registers in context.regs[i]. | ||
// The original x0 can't be recovered. | ||
"stp x0, x1, [x0, #0x008]", | ||
"stp x2, x3, [x0, #0x018]", | ||
"stp x4, x5, [x0, #0x028]", | ||
"stp x6, x7, [x0, #0x038]", | ||
"stp x8, x9, [x0, #0x048]", | ||
"stp x10, x11, [x0, #0x058]", | ||
"stp x12, x13, [x0, #0x068]", | ||
"stp x14, x15, [x0, #0x078]", | ||
"stp x16, x17, [x0, #0x088]", | ||
"stp x18, x19, [x0, #0x098]", | ||
"stp x20, x21, [x0, #0x0a8]", | ||
"stp x22, x23, [x0, #0x0b8]", | ||
"stp x24, x25, [x0, #0x0c8]", | ||
"stp x26, x27, [x0, #0x0d8]", | ||
"stp x28, x29, [x0, #0x0e8]", | ||
|
||
// The original LR can't be recovered. | ||
"str LR, [x0, #0x0f8]", | ||
|
||
// Use x1 as a scratch register. | ||
"mov x1, SP", | ||
// context.sp | ||
"str x1, [x0, #0x100]", | ||
|
||
// The link register holds the return address for this function. | ||
// context.pc | ||
"str LR, [x0, #0x108]", | ||
|
||
// pstate should hold SPSR but NZCV are the only bits we know about. | ||
"mrs x1, NZCV", | ||
|
||
// Enable Control flags, such as CONTEXT_ARM64, CONTEXT_CONTROL, | ||
// CONTEXT_INTEGER | ||
"ldr w1, =0x00400003", | ||
|
||
// Set ControlFlags /0x000/ and pstate /0x004/ at the same time. | ||
"str x1, [x0, #0x000]", | ||
|
||
// Restore x1 from the saved context. | ||
"ldr x1, [x0, #0x010]", | ||
|
||
// TODO(https://crashpad.chromium.org/bug/300): save floating-point registers | ||
"ret", | ||
} |
Oops, something went wrong.