From 39da164e029d73fe393804ccb52e46004d7407f6 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Tue, 15 Mar 2022 10:17:28 +0100 Subject: [PATCH 1/3] Get arm compiling --- src/linux/crash_context/arm.rs | 54 +++++++------ src/linux/dumper_cpu_info/arm.rs | 49 +++++++----- src/linux/sections/exception_stream.rs | 22 +----- src/linux/thread_info/arm.rs | 20 ++--- src/minidump_cpu.rs | 5 +- src/minidump_cpu/arm.rs | 103 ------------------------- 6 files changed, 68 insertions(+), 185 deletions(-) delete mode 100644 src/minidump_cpu/arm.rs diff --git a/src/linux/crash_context/arm.rs b/src/linux/crash_context/arm.rs index 5065c557..0d69504f 100644 --- a/src/linux/crash_context/arm.rs +++ b/src/linux/crash_context/arm.rs @@ -1,41 +1,47 @@ use super::CrashContext; -use crate::minidump_cpu::imp::*; use crate::minidump_cpu::RawContextCPU; impl CrashContext { pub fn get_instruction_pointer(&self) -> usize { - self.context.uc_mcontext.arm_pc as usize + self.inner.context.uc_mcontext.arm_pc as usize } pub fn get_stack_pointer(&self) -> usize { - self.context.uc_mcontext.arm_sp as usize + self.inner.context.uc_mcontext.arm_sp as usize } pub fn fill_cpu_context(&self, out: &mut RawContextCPU) { - out.context_flags = MD_CONTEXT_ARM_FULL; - out.iregs[0] = self.context.uc_mcontext.arm_r0; - out.iregs[1] = self.context.uc_mcontext.arm_r1; - out.iregs[2] = self.context.uc_mcontext.arm_r2; - out.iregs[3] = self.context.uc_mcontext.arm_r3; - out.iregs[4] = self.context.uc_mcontext.arm_r4; - out.iregs[5] = self.context.uc_mcontext.arm_r5; - out.iregs[6] = self.context.uc_mcontext.arm_r6; - out.iregs[7] = self.context.uc_mcontext.arm_r7; - out.iregs[8] = self.context.uc_mcontext.arm_r8; - out.iregs[9] = self.context.uc_mcontext.arm_r9; - out.iregs[10] = self.context.uc_mcontext.arm_r10; + out.context_flags = + crate::minidump_format::format::ContextFlagsArm::CONTEXT_ARM_FULL.bits(); - out.iregs[11] = self.context.uc_mcontext.arm_fp; - out.iregs[12] = self.context.uc_mcontext.arm_ip; - out.iregs[13] = self.context.uc_mcontext.arm_sp; - out.iregs[14] = self.context.uc_mcontext.arm_lr; - out.iregs[15] = self.context.uc_mcontext.arm_pc; + { + let mut 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; - out.cpsr = self.context.uc_mcontext.arm_cpsr; + 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]; + //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/src/linux/dumper_cpu_info/arm.rs b/src/linux/dumper_cpu_info/arm.rs index 3f014484..886920f5 100644 --- a/src/linux/dumper_cpu_info/arm.rs +++ b/src/linux/dumper_cpu_info/arm.rs @@ -81,26 +81,35 @@ fn parse_features(val: &str) -> u32 { // The ELF hwcaps are listed in the "Features" entry as textual tags. // This table is used to rebuild them. let cpu_features_entries = [ - CpuFeaturesEntry::new("swp", MDCPUInformationARMElfHwCaps::HWCAP_SWP), - CpuFeaturesEntry::new("half", MDCPUInformationARMElfHwCaps::HWCAP_HALF), - CpuFeaturesEntry::new("thumb", MDCPUInformationARMElfHwCaps::HWCAP_THUMB), - CpuFeaturesEntry::new("bit26", MDCPUInformationARMElfHwCaps::HWCAP_26BIT), - CpuFeaturesEntry::new("fastmult", MDCPUInformationARMElfHwCaps::HWCAP_FAST_MULT), - CpuFeaturesEntry::new("fpa", MDCPUInformationARMElfHwCaps::HWCAP_FPA), - CpuFeaturesEntry::new("vfp", MDCPUInformationARMElfHwCaps::HWCAP_VFP), - CpuFeaturesEntry::new("edsp", MDCPUInformationARMElfHwCaps::HWCAP_EDSP), - CpuFeaturesEntry::new("java", MDCPUInformationARMElfHwCaps::HWCAP_JAVA), - CpuFeaturesEntry::new("iwmmxt", MDCPUInformationARMElfHwCaps::HWCAP_IWMMXT), - CpuFeaturesEntry::new("crunch", MDCPUInformationARMElfHwCaps::HWCAP_CRUNCH), - CpuFeaturesEntry::new("thumbee", MDCPUInformationARMElfHwCaps::HWCAP_THUMBEE), - CpuFeaturesEntry::new("neon", MDCPUInformationARMElfHwCaps::HWCAP_NEON), - CpuFeaturesEntry::new("vfpv3", MDCPUInformationARMElfHwCaps::HWCAP_VFPv3), - CpuFeaturesEntry::new("vfpv3d16", MDCPUInformationARMElfHwCaps::HWCAP_VFPv3D16), - CpuFeaturesEntry::new("tls", MDCPUInformationARMElfHwCaps::HWCAP_TLS), - CpuFeaturesEntry::new("vfpv4", MDCPUInformationARMElfHwCaps::HWCAP_VFPv4), - CpuFeaturesEntry::new("idiva", MDCPUInformationARMElfHwCaps::HWCAP_IDIVA), - CpuFeaturesEntry::new("idivt", MDCPUInformationARMElfHwCaps::HWCAP_IDIVT), - CpuFeaturesEntry::new("idiv", HWCAP_IDIV), + CpuFeaturesEntry::new("swp", MDCPUInformationARMElfHwCaps::HWCAP_SWP.bits()), + CpuFeaturesEntry::new("half", MDCPUInformationARMElfHwCaps::HWCAP_HALF.bits()), + CpuFeaturesEntry::new("thumb", MDCPUInformationARMElfHwCaps::HWCAP_THUMB.bits()), + CpuFeaturesEntry::new("bit26", MDCPUInformationARMElfHwCaps::HWCAP_26BIT.bits()), + CpuFeaturesEntry::new( + "fastmult", + MDCPUInformationARMElfHwCaps::HWCAP_FAST_MULT.bits(), + ), + CpuFeaturesEntry::new("fpa", MDCPUInformationARMElfHwCaps::HWCAP_FPA.bits()), + CpuFeaturesEntry::new("vfp", MDCPUInformationARMElfHwCaps::HWCAP_VFP.bits()), + CpuFeaturesEntry::new("edsp", MDCPUInformationARMElfHwCaps::HWCAP_EDSP.bits()), + CpuFeaturesEntry::new("java", MDCPUInformationARMElfHwCaps::HWCAP_JAVA.bits()), + CpuFeaturesEntry::new("iwmmxt", MDCPUInformationARMElfHwCaps::HWCAP_IWMMXT.bits()), + CpuFeaturesEntry::new("crunch", MDCPUInformationARMElfHwCaps::HWCAP_CRUNCH.bits()), + CpuFeaturesEntry::new( + "thumbee", + MDCPUInformationARMElfHwCaps::HWCAP_THUMBEE.bits(), + ), + CpuFeaturesEntry::new("neon", MDCPUInformationARMElfHwCaps::HWCAP_NEON.bits()), + CpuFeaturesEntry::new("vfpv3", MDCPUInformationARMElfHwCaps::HWCAP_VFPv3.bits()), + CpuFeaturesEntry::new( + "vfpv3d16", + MDCPUInformationARMElfHwCaps::HWCAP_VFPv3D16.bits(), + ), + CpuFeaturesEntry::new("tls", MDCPUInformationARMElfHwCaps::HWCAP_TLS.bits()), + CpuFeaturesEntry::new("vfpv4", MDCPUInformationARMElfHwCaps::HWCAP_VFPv4.bits()), + CpuFeaturesEntry::new("idiva", MDCPUInformationARMElfHwCaps::HWCAP_IDIVA.bits()), + CpuFeaturesEntry::new("idivt", MDCPUInformationARMElfHwCaps::HWCAP_IDIVT.bits()), + CpuFeaturesEntry::new("idiv", MDCPUInformationARMElfHwCaps::HWCAP_IDIV.bits()), ]; let mut ehwc = 0; diff --git a/src/linux/sections/exception_stream.rs b/src/linux/sections/exception_stream.rs index 45da0284..665b2b47 100644 --- a/src/linux/sections/exception_stream.rs +++ b/src/linux/sections/exception_stream.rs @@ -46,28 +46,8 @@ pub fn write( buffer: &mut DumpBuf, ) -> Result { let exception = if let Some(context) = &config.crash_context { - let sig_addr; - #[cfg(target_arch = "arm")] - { - // Not part of libc-crate, but thats how the Linux-variant does it - // and according to the systemheaders, android as well. - #[allow(non_camel_case_types)] - #[repr(C)] - struct siginfo_sigfault { - _si_signo: libc::c_int, - _si_errno: libc::c_int, - _si_code: libc::c_int, - si_addr: *mut libc::c_void, - } + let sig_addr = context.inner.siginfo.ssi_addr as u64; - sig_addr = unsafe { - (*(&context.siginfo as *const libc::siginfo_t as *const siginfo_sigfault)).si_addr - } as u64; - } - #[cfg(not(target_arch = "arm"))] - { - sig_addr = context.inner.siginfo.ssi_addr as u64; - } MDException { exception_code: context.inner.siginfo.ssi_signo as u32, exception_flags: context.inner.siginfo.ssi_code as u32, diff --git a/src/linux/thread_info/arm.rs b/src/linux/thread_info/arm.rs index a66670ce..6359f9b8 100644 --- a/src/linux/thread_info/arm.rs +++ b/src/linux/thread_info/arm.rs @@ -1,11 +1,5 @@ use super::{CommonThreadInfo, Pid}; -use crate::errors::ThreadInfoError; -use crate::minidump_cpu::imp::{ - MD_CONTEXT_ARM_FULL, MD_CONTEXT_ARM_GPR_COUNT, MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT, - MD_FLOATINGSAVEAREA_ARM_FPR_COUNT, -}; -use crate::minidump_cpu::RawContextCPU; -use libc; +use crate::{errors::ThreadInfoError, minidump_cpu::RawContextCPU}; use nix::sys::ptrace; type Result = std::result::Result; @@ -44,7 +38,7 @@ pub struct user_fpregs { #[repr(C)] #[derive(Debug, Eq, Hash, PartialEq, Copy, Clone, Default)] pub struct user_regs { - uregs: [libc::c_long; 18], + uregs: [u32; 18], } #[derive(Debug)] @@ -82,18 +76,16 @@ impl ThreadInfoArm { } pub fn fill_cpu_context(&self, out: &mut RawContextCPU) { - out.context_flags = MD_CONTEXT_ARM_FULL; - for idx in 0..MD_CONTEXT_ARM_GPR_COUNT { - out.iregs[idx] = self.regs.uregs[idx] as u32; - } + out.context_flags = + crate::minidump_format::format::ContextFlagsArm::CONTEXT_ARM_FULL.bits(); + + out.iregs.copy_from_slice(&self.regs.uregs[..16]); // No CPSR register in ThreadInfo(it's not accessible via ptrace) out.cpsr = 0; #[cfg(not(target_os = "android"))] { out.float_save.fpscr = self.fpregs.fpsr as u64 | ((self.fpregs.fpcr as u64) << 32); - out.float_save.regs = [0; MD_FLOATINGSAVEAREA_ARM_FPR_COUNT]; - out.float_save.extra = [0; MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT]; } } diff --git a/src/minidump_cpu.rs b/src/minidump_cpu.rs index 8ddf29c3..4130939e 100644 --- a/src/minidump_cpu.rs +++ b/src/minidump_cpu.rs @@ -6,9 +6,8 @@ cfg_if::cfg_if! { pub type RawContextCPU = minidump_common::format::CONTEXT_X86; pub type FloatStateCPU = minidump_common::format::FLOATING_SAVE_AREA_X86; } else if #[cfg(target_arch = "arm")] { - pub mod arm; - pub use arm as imp; - pub type RawContextCPU = arm::MDRawContextARM; + pub type RawContextCPU = minidump_common::format::CONTEXT_ARM; + pub type FloatStateCPU = minidump_common::format::FLOATING_SAVE_AREA_ARM; } else if #[cfg(target_arch = "aarch64")] { /// This is the number of general purpose registers _not_ counting /// the stack pointer diff --git a/src/minidump_cpu/arm.rs b/src/minidump_cpu/arm.rs deleted file mode 100644 index f2b4c54e..00000000 --- a/src/minidump_cpu/arm.rs +++ /dev/null @@ -1,103 +0,0 @@ -pub const MD_CONTEXT_ARM_GPR_COUNT: usize = 16; - -pub const MD_FLOATINGSAVEAREA_ARM_FPR_COUNT: usize = 32; -pub const MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT: usize = 8; -/* - * Note that these structures *do not* map directly to the CONTEXT - * structure defined in WinNT.h in the Windows Mobile SDK. That structure - * does not accomodate VFPv3, and I'm unsure if it was ever used in the - * wild anyway, as Windows CE only seems to produce "cedumps" which - * are not exactly minidumps. - */ -#[repr(C)] -pub struct MDFloatingSaveAreaARM { - pub fpscr: u64, /* FPU status register */ - - /* 32 64-bit floating point registers, d0 .. d31. */ - pub regs: [u64; MD_FLOATINGSAVEAREA_ARM_FPR_COUNT], - - /* Miscellaneous control words */ - pub extra: [u32; MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT], -} - -// The std library doesn't provide "Default" for all -// array-lengths. Only up to 32. So we have to implement -// our own default, because of `reserved4: [u8; 96]` -impl Default for MDFloatingSaveAreaARM { - #[inline] - fn default() -> Self { - MDFloatingSaveAreaARM { - fpscr: 0, - regs: [0; MD_FLOATINGSAVEAREA_ARM_FPR_COUNT], - extra: [0; MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT], - } - } -} - -#[repr(C)] -pub struct MDRawContextARM { - /* The next field determines the layout of the structure, and which parts - * of it are populated - */ - pub context_flags: u32, - - /* 16 32-bit integer registers, r0 .. r15 - * Note the following fixed uses: - * r13 is the stack pointer - * r14 is the link register - * r15 is the program counter - */ - pub iregs: [u32; MD_CONTEXT_ARM_GPR_COUNT], - - /* CPSR (flags, basically): 32 bits: - bit 31 - N (negative) - bit 30 - Z (zero) - bit 29 - C (carry) - bit 28 - V (overflow) - bit 27 - Q (saturation flag, sticky) - All other fields -- ignore */ - pub cpsr: u32, - - /* The next field is included with MD_CONTEXT_ARM_FLOATING_POINT */ - pub float_save: MDFloatingSaveAreaARM, -} - -impl Default for MDRawContextARM { - #[inline] - fn default() -> Self { - MDRawContextARM { - context_flags: 0, - iregs: [0; MD_CONTEXT_ARM_GPR_COUNT], - cpsr: 0, - float_save: Default::default(), - } - } -} - -/* Indices into iregs for registers with a dedicated or conventional - * purpose. - */ -// enum MDARMRegisterNumbers { -// MD_CONTEXT_ARM_REG_IOS_FP = 7, -// MD_CONTEXT_ARM_REG_FP = 11, -// MD_CONTEXT_ARM_REG_SP = 13, -// MD_CONTEXT_ARM_REG_LR = 14, -// MD_CONTEXT_ARM_REG_PC = 15 -// } - -/* For (MDRawContextARM).context_flags. These values indicate the type of - * context stored in the structure. */ -/* CONTEXT_ARM from the Windows CE 5.0 SDK. This value isn't correct - * because this bit can be used for flags. Presumably this value was - * never actually used in minidumps, but only in "CEDumps" which - * are a whole parallel minidump file format for Windows CE. - * Therefore, Breakpad defines its own value for ARM CPUs. - */ -pub const MD_CONTEXT_ARM_OLD: u32 = 0x00000040; -/* This value was chosen to avoid likely conflicts with MD_CONTEXT_* - * for other CPUs. */ -pub const MD_CONTEXT_ARM: u32 = 0x40000000; -pub const MD_CONTEXT_ARM_INTEGER: u32 = MD_CONTEXT_ARM | 0x00000002; -pub const MD_CONTEXT_ARM_FLOATING_POINT: u32 = MD_CONTEXT_ARM | 0x00000004; -pub const MD_CONTEXT_ARM_FULL: u32 = MD_CONTEXT_ARM_INTEGER | MD_CONTEXT_ARM_FLOATING_POINT; -pub const MD_CONTEXT_ARM_ALL: u32 = MD_CONTEXT_ARM_INTEGER | MD_CONTEXT_ARM_FLOATING_POINT; From c6f8e0ea08ff063dbb3d0ac4838cf4873c927c82 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Tue, 15 Mar 2022 11:21:44 +0100 Subject: [PATCH 2/3] Remove arm restriction on set_crash_context --- src/linux/minidump_writer.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/linux/minidump_writer.rs b/src/linux/minidump_writer.rs index b67792ea..069308a5 100644 --- a/src/linux/minidump_writer.rs +++ b/src/linux/minidump_writer.rs @@ -133,7 +133,7 @@ type Result = std::result::Result; impl MinidumpWriter { pub fn new(process: Pid, blamed_thread: Pid) -> Self { - MinidumpWriter { + Self { process_id: process, blamed_thread, minidump_size_limit: None, @@ -169,8 +169,6 @@ impl MinidumpWriter { self } - // Has to be deactivated for ARM for now, as libc doesn't include ucontext_t for ARM yet - #[cfg(not(target_arch = "arm"))] pub fn set_crash_context(&mut self, crash_context: CrashContext) -> &mut Self { self.crash_context = Some(crash_context); self From 5b2de1e5006d034bff5b3ac44cb83fc1ad97d509 Mon Sep 17 00:00:00 2001 From: Jake Shadle Date: Wed, 16 Mar 2022 09:29:03 +0100 Subject: [PATCH 3/3] Fixup rebase --- src/linux/crash_context/aarch64.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/linux/crash_context/aarch64.rs b/src/linux/crash_context/aarch64.rs index 37c5eff7..c53c3772 100644 --- a/src/linux/crash_context/aarch64.rs +++ b/src/linux/crash_context/aarch64.rs @@ -26,9 +26,9 @@ impl CrashContext { { let fs = &self.inner.float_state; - out.float_save.fpsr = fs.fpsr; - out.float_save.fpcr = fs.fpcr; - out.float_save.regs[..FP_REG_COUNT].copy_from_slice(&fs.vregs[..FP_REG_COUNT]); + out.fpsr = fs.fpsr; + out.fpcr = fs.fpcr; + out.float_regs[..FP_REG_COUNT].copy_from_slice(&fs.vregs[..FP_REG_COUNT]); } } }