summaryrefslogtreecommitdiffstats
path: root/third_party/rust/minidump-writer/src/linux/crash_context
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/minidump-writer/src/linux/crash_context')
-rw-r--r--third_party/rust/minidump-writer/src/linux/crash_context/aarch64.rs34
-rw-r--r--third_party/rust/minidump-writer/src/linux/crash_context/arm.rs47
-rw-r--r--third_party/rust/minidump-writer/src/linux/crash_context/x86.rs62
-rw-r--r--third_party/rust/minidump-writer/src/linux/crash_context/x86_64.rs78
4 files changed, 221 insertions, 0 deletions
diff --git a/third_party/rust/minidump-writer/src/linux/crash_context/aarch64.rs b/third_party/rust/minidump-writer/src/linux/crash_context/aarch64.rs
new file mode 100644
index 0000000000..c53c37720c
--- /dev/null
+++ b/third_party/rust/minidump-writer/src/linux/crash_context/aarch64.rs
@@ -0,0 +1,34 @@
+use super::CrashContext;
+use crate::{
+ minidump_cpu::{RawContextCPU, FP_REG_COUNT, GP_REG_COUNT},
+ minidump_format::format,
+};
+
+impl CrashContext {
+ pub fn get_instruction_pointer(&self) -> usize {
+ self.inner.context.uc_mcontext.pc as usize
+ }
+
+ pub fn get_stack_pointer(&self) -> usize {
+ self.inner.context.uc_mcontext.sp as usize
+ }
+
+ pub fn fill_cpu_context(&self, out: &mut RawContextCPU) {
+ out.context_flags = format::ContextFlagsArm64Old::CONTEXT_ARM64_OLD_FULL.bits() as u64;
+
+ {
+ let gregs = &self.inner.context.uc_mcontext;
+ out.cpsr = gregs.pstate as u32;
+ out.iregs[..GP_REG_COUNT].copy_from_slice(&gregs.regs[..GP_REG_COUNT]);
+ out.sp = gregs.sp;
+ out.pc = gregs.pc;
+ }
+
+ {
+ let fs = &self.inner.float_state;
+ out.fpsr = fs.fpsr;
+ out.fpcr = fs.fpcr;
+ out.float_regs[..FP_REG_COUNT].copy_from_slice(&fs.vregs[..FP_REG_COUNT]);
+ }
+ }
+}
diff --git a/third_party/rust/minidump-writer/src/linux/crash_context/arm.rs b/third_party/rust/minidump-writer/src/linux/crash_context/arm.rs
new file mode 100644
index 0000000000..e4e40216e2
--- /dev/null
+++ b/third_party/rust/minidump-writer/src/linux/crash_context/arm.rs
@@ -0,0 +1,47 @@
+use super::CrashContext;
+use crate::minidump_cpu::RawContextCPU;
+
+impl CrashContext {
+ pub fn get_instruction_pointer(&self) -> usize {
+ self.inner.context.uc_mcontext.arm_pc as usize
+ }
+
+ pub fn get_stack_pointer(&self) -> usize {
+ self.inner.context.uc_mcontext.arm_sp as usize
+ }
+
+ pub fn fill_cpu_context(&self, out: &mut RawContextCPU) {
+ out.context_flags =
+ crate::minidump_format::format::ContextFlagsArm::CONTEXT_ARM_FULL.bits();
+
+ {
+ let iregs = &mut out.iregs;
+ let gregs = &self.inner.context.uc_mcontext;
+ iregs[0] = gregs.arm_r0;
+ iregs[1] = gregs.arm_r1;
+ iregs[2] = gregs.arm_r2;
+ iregs[3] = gregs.arm_r3;
+ iregs[4] = gregs.arm_r4;
+ iregs[5] = gregs.arm_r5;
+ iregs[6] = gregs.arm_r6;
+ iregs[7] = gregs.arm_r7;
+ iregs[8] = gregs.arm_r8;
+ iregs[9] = gregs.arm_r9;
+ iregs[10] = gregs.arm_r10;
+
+ iregs[11] = gregs.arm_fp;
+ iregs[12] = gregs.arm_ip;
+ iregs[13] = gregs.arm_sp;
+ iregs[14] = gregs.arm_lr;
+ iregs[15] = gregs.arm_pc;
+
+ out.cpsr = gregs.arm_cpsr;
+ }
+
+ // TODO: this todo has been in breakpad for years....
+ // TODO: fix this after fixing ExceptionHandler
+ //out.float_save.fpscr = 0;
+ //out.float_save.regs = [0; MD_FLOATINGSAVEAREA_ARM_FPR_COUNT];
+ //out.float_save.extra = [0; MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT];
+ }
+}
diff --git a/third_party/rust/minidump-writer/src/linux/crash_context/x86.rs b/third_party/rust/minidump-writer/src/linux/crash_context/x86.rs
new file mode 100644
index 0000000000..7f092716bd
--- /dev/null
+++ b/third_party/rust/minidump-writer/src/linux/crash_context/x86.rs
@@ -0,0 +1,62 @@
+use super::CrashContext;
+use crate::{minidump_cpu::RawContextCPU, minidump_format::format::ContextFlagsX86};
+use libc::{
+ REG_CS, REG_DS, REG_EAX, REG_EBP, REG_EBX, REG_ECX, REG_EDI, REG_EDX, REG_EFL, REG_EIP, REG_ES,
+ REG_ESI, REG_ESP, REG_FS, REG_GS, REG_SS, REG_UESP,
+};
+impl CrashContext {
+ pub fn get_instruction_pointer(&self) -> usize {
+ self.inner.context.uc_mcontext.gregs[REG_EIP as usize] as usize
+ }
+
+ pub fn get_stack_pointer(&self) -> usize {
+ self.inner.context.uc_mcontext.gregs[REG_ESP as usize] as usize
+ }
+
+ pub fn fill_cpu_context(&self, out: &mut RawContextCPU) {
+ out.context_flags = ContextFlagsX86::CONTEXT_X86_FULL.bits()
+ | ContextFlagsX86::CONTEXT_X86_FLOATING_POINT.bits();
+
+ {
+ let gregs = &self.inner.context.uc_mcontext.gregs;
+ out.gs = gregs[REG_GS as usize] as u32;
+ out.fs = gregs[REG_FS as usize] as u32;
+ out.es = gregs[REG_ES as usize] as u32;
+ out.ds = gregs[REG_DS as usize] as u32;
+
+ out.edi = gregs[REG_EDI as usize] as u32;
+ out.esi = gregs[REG_ESI as usize] as u32;
+ out.ebx = gregs[REG_EBX as usize] as u32;
+ out.edx = gregs[REG_EDX as usize] as u32;
+ out.ecx = gregs[REG_ECX as usize] as u32;
+ out.eax = gregs[REG_EAX as usize] as u32;
+
+ out.ebp = gregs[REG_EBP as usize] as u32;
+ out.eip = gregs[REG_EIP as usize] as u32;
+ out.cs = gregs[REG_CS as usize] as u32;
+ out.eflags = gregs[REG_EFL as usize] as u32;
+ out.esp = gregs[REG_UESP as usize] as u32;
+ out.ss = gregs[REG_SS as usize] as u32;
+ }
+
+ {
+ let fs = &self.inner.float_state;
+ let mut out = &mut out.float_save;
+ out.control_word = fs.cw;
+ out.status_word = fs.sw;
+ out.tag_word = fs.tag;
+ out.error_offset = fs.ipoff;
+ out.error_selector = fs.cssel;
+ out.data_offset = fs.dataoff;
+ out.data_selector = fs.datasel;
+
+ debug_assert_eq!(fs._st.len() * std::mem::size_of::<libc::_libc_fpreg>(), 80);
+ out.register_area.copy_from_slice(unsafe {
+ std::slice::from_raw_parts(
+ fs._st.as_ptr().cast(),
+ fs._st.len() * std::mem::size_of::<libc::_libc_fpreg>(),
+ )
+ });
+ }
+ }
+}
diff --git a/third_party/rust/minidump-writer/src/linux/crash_context/x86_64.rs b/third_party/rust/minidump-writer/src/linux/crash_context/x86_64.rs
new file mode 100644
index 0000000000..e559692679
--- /dev/null
+++ b/third_party/rust/minidump-writer/src/linux/crash_context/x86_64.rs
@@ -0,0 +1,78 @@
+use super::CrashContext;
+use crate::{
+ minidump_cpu::RawContextCPU, minidump_format::format, thread_info::copy_u32_registers,
+};
+use libc::{
+ REG_CSGSFS, REG_EFL, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_R8, REG_R9,
+ REG_RAX, REG_RBP, REG_RBX, REG_RCX, REG_RDI, REG_RDX, REG_RIP, REG_RSI, REG_RSP,
+};
+use scroll::Pwrite;
+
+impl CrashContext {
+ pub fn get_instruction_pointer(&self) -> usize {
+ self.inner.context.uc_mcontext.gregs[REG_RIP as usize] as usize
+ }
+
+ pub fn get_stack_pointer(&self) -> usize {
+ self.inner.context.uc_mcontext.gregs[REG_RSP as usize] as usize
+ }
+
+ pub fn fill_cpu_context(&self, out: &mut RawContextCPU) {
+ out.context_flags = format::ContextFlagsAmd64::CONTEXT_AMD64_FULL.bits();
+
+ {
+ let gregs = &self.inner.context.uc_mcontext.gregs;
+ out.cs = (gregs[REG_CSGSFS as usize] & 0xffff) as u16;
+
+ out.fs = ((gregs[REG_CSGSFS as usize] >> 32) & 0xffff) as u16;
+ out.gs = ((gregs[REG_CSGSFS as usize] >> 16) & 0xffff) as u16;
+
+ out.eflags = gregs[REG_EFL as usize] as u32;
+
+ out.rax = gregs[REG_RAX as usize] as u64;
+ out.rcx = gregs[REG_RCX as usize] as u64;
+ out.rdx = gregs[REG_RDX as usize] as u64;
+ out.rbx = gregs[REG_RBX as usize] as u64;
+
+ out.rsp = gregs[REG_RSP as usize] as u64;
+ out.rbp = gregs[REG_RBP as usize] as u64;
+ out.rsi = gregs[REG_RSI as usize] as u64;
+ out.rdi = gregs[REG_RDI as usize] as u64;
+ out.r8 = gregs[REG_R8 as usize] as u64;
+ out.r9 = gregs[REG_R9 as usize] as u64;
+ out.r10 = gregs[REG_R10 as usize] as u64;
+ out.r11 = gregs[REG_R11 as usize] as u64;
+ out.r12 = gregs[REG_R12 as usize] as u64;
+ out.r13 = gregs[REG_R13 as usize] as u64;
+ out.r14 = gregs[REG_R14 as usize] as u64;
+ out.r15 = gregs[REG_R15 as usize] as u64;
+
+ out.rip = gregs[REG_RIP as usize] as u64;
+ }
+
+ {
+ let fs = &self.inner.float_state;
+
+ let mut float_save = format::XMM_SAVE_AREA32 {
+ control_word: fs.cwd,
+ status_word: fs.swd,
+ tag_word: fs.ftw as u8,
+ error_opcode: fs.fop,
+ error_offset: fs.rip as u32,
+ data_offset: fs.rdp as u32,
+ error_selector: 0, // We don't have this.
+ data_selector: 0, // We don't have this.
+ mx_csr: fs.mxcsr,
+ mx_csr_mask: fs.mxcr_mask,
+ ..Default::default()
+ };
+
+ copy_u32_registers(&mut float_save.float_registers, &fs.st_space);
+ copy_u32_registers(&mut float_save.xmm_registers, &fs.xmm_space);
+
+ out.float_save
+ .pwrite_with(float_save, 0, scroll::Endian::Little)
+ .expect("this is impossible");
+ }
+ }
+}