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]);
}
}
}