From dafbf62ea82d6da22a873ff5f71d5bf45aa5d0c0 Mon Sep 17 00:00:00 2001
From: Gabriele Svelto
Date: Tue, 18 Jul 2023 07:41:45 +0200
Subject: [PATCH 1/2] Add support for Android/i686
---
src/linux/auxv_reader.rs | 4 +-
src/linux/dso_debug.rs | 4 +-
src/linux/ptrace_dumper.rs | 4 +-
src/linux/thread_info/x86.rs | 105 +++++++++++++++++++++++++++++++----
4 files changed, 100 insertions(+), 17 deletions(-)
diff --git a/src/linux/auxv_reader.rs b/src/linux/auxv_reader.rs
index 3b5254f4..3ed09e5a 100644
--- a/src/linux/auxv_reader.rs
+++ b/src/linux/auxv_reader.rs
@@ -85,11 +85,11 @@ impl Iterator for ProcfsAuxvIter {
};
let at_null;
- #[cfg(target_arch = "arm")]
+ #[cfg(any(target_arch = "arm", all(target_os = "android", target_arch = "x86")))]
{
at_null = 0;
}
- #[cfg(not(target_arch = "arm"))]
+ #[cfg(not(any(target_arch = "arm", all(target_os = "android", target_arch = "x86"))))]
{
at_null = libc::AT_NULL;
}
diff --git a/src/linux/dso_debug.rs b/src/linux/dso_debug.rs
index b77f2413..b9f46626 100644
--- a/src/linux/dso_debug.rs
+++ b/src/linux/dso_debug.rs
@@ -81,12 +81,12 @@ pub fn write_dso_debug_stream(
) -> Result {
let at_phnum;
let at_phdr;
- #[cfg(target_arch = "arm")]
+ #[cfg(any(target_arch = "arm", all(target_os = "android", target_arch = "x86")))]
{
at_phdr = 3;
at_phnum = 5;
}
- #[cfg(not(target_arch = "arm"))]
+ #[cfg(not(any(target_arch = "arm", all(target_os = "android", target_arch = "x86"))))]
{
at_phdr = libc::AT_PHDR;
at_phnum = libc::AT_PHNUM;
diff --git a/src/linux/ptrace_dumper.rs b/src/linux/ptrace_dumper.rs
index 1a4f26f9..f75499bc 100644
--- a/src/linux/ptrace_dumper.rs
+++ b/src/linux/ptrace_dumper.rs
@@ -268,11 +268,11 @@ impl PtraceDumper {
// guaranteed (see http://crosbug.com/25355); therefore, try to use the
// actual entry point to find the mapping.
let at_entry;
- #[cfg(target_arch = "arm")]
+ #[cfg(any(target_arch = "arm", all(target_os = "android", target_arch = "x86")))]
{
at_entry = 9;
}
- #[cfg(not(target_arch = "arm"))]
+ #[cfg(not(any(target_arch = "arm", all(target_os = "android", target_arch = "x86"))))]
{
at_entry = libc::AT_ENTRY;
}
diff --git a/src/linux/thread_info/x86.rs b/src/linux/thread_info/x86.rs
index 0447ed09..aa1ea71b 100644
--- a/src/linux/thread_info/x86.rs
+++ b/src/linux/thread_info/x86.rs
@@ -1,33 +1,116 @@
use super::{CommonThreadInfo, NT_Elf, Pid};
use crate::{errors::ThreadInfoError, minidump_cpu::RawContextCPU, minidump_format::format};
use core::mem::size_of_val;
-use libc::user;
+#[cfg(all(not(target_os = "android"), target_arch = "x86"))]
+use libc::user_fpxregs_struct;
+#[cfg(not(all(target_os = "android", target_arch = "x86")))]
+use libc::{user, user_fpregs_struct, user_regs_struct};
use nix::sys::ptrace;
use scroll::Pwrite;
type Result = std::result::Result;
+// Not defined by libc on Android
+#[cfg(all(target_os = "android", target_arch = "x86"))]
+#[allow(non_camel_case_types)]
+#[repr(C)]
+pub struct user_regs_struct {
+ pub ebx: libc::c_long,
+ pub ecx: libc::c_long,
+ pub edx: libc::c_long,
+ pub esi: libc::c_long,
+ pub edi: libc::c_long,
+ pub ebp: libc::c_long,
+ pub eax: libc::c_long,
+ pub xds: libc::c_long,
+ pub xes: libc::c_long,
+ pub xfs: libc::c_long,
+ pub xgs: libc::c_long,
+ pub orig_eax: libc::c_long,
+ pub eip: libc::c_long,
+ pub xcs: libc::c_long,
+ pub eflags: libc::c_long,
+ pub esp: libc::c_long,
+ pub xss: libc::c_long,
+}
+
+// Not defined by libc on Android
+#[cfg(all(target_os = "android", target_arch = "x86"))]
+#[allow(non_camel_case_types)]
+#[repr(C)]
+pub struct user_fpxregs_struct {
+ pub cwd: libc::c_ushort,
+ pub swd: libc::c_ushort,
+ pub twd: libc::c_ushort,
+ pub fop: libc::c_ushort,
+ pub fip: libc::c_long,
+ pub fcs: libc::c_long,
+ pub foo: libc::c_long,
+ pub fos: libc::c_long,
+ pub mxcsr: libc::c_long,
+ __reserved: libc::c_long,
+ pub st_space: [libc::c_long; 32],
+ pub xmm_space: [libc::c_long; 32],
+ padding: [libc::c_long; 56],
+}
+
+// Not defined by libc on Android
+#[cfg(all(target_os = "android", target_arch = "x86"))]
+#[allow(non_camel_case_types)]
+#[repr(C)]
+pub struct user_fpregs_struct {
+ pub cwd: libc::c_long,
+ pub swd: libc::c_long,
+ pub twd: libc::c_long,
+ pub fip: libc::c_long,
+ pub fcs: libc::c_long,
+ pub foo: libc::c_long,
+ pub fos: libc::c_long,
+ pub st_space: [libc::c_long; 20],
+}
+
+#[cfg(all(target_os = "android", target_arch = "x86"))]
+#[allow(non_camel_case_types)]
+#[repr(C)]
+pub struct user {
+ pub regs: user_regs_struct,
+ pub u_fpvalid: libc::c_long,
+ pub i387: user_fpregs_struct,
+ pub u_tsize: libc::c_ulong,
+ pub u_dsize: libc::c_ulong,
+ pub u_ssize: libc::c_ulong,
+ pub start_code: libc::c_ulong,
+ pub start_stack: libc::c_ulong,
+ pub signal: libc::c_long,
+ __reserved: libc::c_int,
+ pub u_ar0: *mut user_regs_struct,
+ pub u_fpstate: *mut user_fpregs_struct,
+ pub magic: libc::c_ulong,
+ pub u_comm: [libc::c_char; 32],
+ pub u_debugreg: [libc::c_int; 8],
+}
+
const NUM_DEBUG_REGISTERS: usize = 8;
pub struct ThreadInfoX86 {
pub stack_pointer: usize,
pub tgid: Pid, // thread group id
pub ppid: Pid, // parent process
- pub regs: libc::user_regs_struct,
- pub fpregs: libc::user_fpregs_struct,
+ pub regs: user_regs_struct,
+ pub fpregs: user_fpregs_struct,
#[cfg(target_arch = "x86_64")]
pub dregs: [libc::c_ulonglong; NUM_DEBUG_REGISTERS],
#[cfg(target_arch = "x86")]
pub dregs: [libc::c_int; NUM_DEBUG_REGISTERS],
#[cfg(target_arch = "x86")]
- pub fpxregs: libc::user_fpxregs_struct,
+ pub fpxregs: user_fpxregs_struct,
}
impl CommonThreadInfo for ThreadInfoX86 {}
impl ThreadInfoX86 {
// nix currently doesn't support PTRACE_GETREGSET, so we have to do it ourselves
- fn getregset(pid: Pid) -> Result {
+ fn getregset(pid: Pid) -> Result {
Self::ptrace_get_data_via_io(
0x4204 as ptrace::RequestType, // PTRACE_GETREGSET
Some(NT_Elf::NT_PRSTATUS),
@@ -35,7 +118,7 @@ impl ThreadInfoX86 {
)
}
- pub fn getregs(pid: Pid) -> Result {
+ pub fn getregs(pid: Pid) -> Result {
// TODO: nix restricts PTRACE_GETREGS to arm android for some reason
Self::ptrace_get_data(
12 as ptrace::RequestType, // PTRACE_GETREGS
@@ -45,7 +128,7 @@ impl ThreadInfoX86 {
}
// nix currently doesn't support PTRACE_GETREGSET, so we have to do it ourselves
- fn getfpregset(pid: Pid) -> Result {
+ fn getfpregset(pid: Pid) -> Result {
Self::ptrace_get_data_via_io(
0x4204 as ptrace::RequestType, // PTRACE_GETREGSET
Some(NT_Elf::NT_PRFPREGSET),
@@ -54,7 +137,7 @@ impl ThreadInfoX86 {
}
// nix currently doesn't support PTRACE_GETFPREGS, so we have to do it ourselves
- fn getfpregs(pid: Pid) -> Result {
+ fn getfpregs(pid: Pid) -> Result {
Self::ptrace_get_data(
14 as ptrace::RequestType, // PTRACE_GETFPREGS
None,
@@ -64,9 +147,9 @@ impl ThreadInfoX86 {
// nix currently doesn't support PTRACE_GETFPXREGS, so we have to do it ourselves
#[cfg(target_arch = "x86")]
- fn getfpxregs(pid: Pid) -> Result {
+ fn getfpxregs(pid: Pid) -> Result {
Self::ptrace_get_data(
- ptrace::Request::PTRACE_GETFPXREGS as ptrace::RequestType,
+ 18 as ptrace::RequestType, // PTRACE_GETFPXREGS
None,
nix::unistd::Pid::from_raw(pid),
)
@@ -86,7 +169,7 @@ impl ThreadInfoX86 {
let regs = Self::getregset(tid).or_else(|_| Self::getregs(tid))?;
let fpregs = Self::getfpregset(tid).or_else(|_| Self::getfpregs(tid))?;
#[cfg(target_arch = "x86")]
- let fpxregs: libc::user_fpxregs_struct;
+ let fpxregs: user_fpxregs_struct;
#[cfg(target_arch = "x86")]
{
if cfg!(target_feature = "fxsr") {
From f4db5c96e41f42139ec8d09b87eaa15ed3dc7a0e Mon Sep 17 00:00:00 2001
From: Gabriele Svelto
Date: Tue, 18 Jul 2023 07:55:14 +0200
Subject: [PATCH 2/2] Clippy cleanups
---
src/linux/android.rs | 2 +-
src/linux/crash_context/x86.rs | 2 +-
src/linux/dumper_cpu_info/x86_mips.rs | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/linux/android.rs b/src/linux/android.rs
index 1fa28a04..05e7d4ac 100644
--- a/src/linux/android.rs
+++ b/src/linux/android.rs
@@ -116,7 +116,7 @@ fn parse_loaded_elf_program_headers(
pub fn late_process_mappings(pid: Pid, mappings: &mut [MappingInfo]) -> Result<()> {
// Only consider exec mappings that indicate a file path was mapped, and
// where the ELF header indicates a mapped shared library.
- for mut map in mappings
+ for map in mappings
.iter_mut()
.filter(|m| m.is_executable() && m.name_is_path())
{
diff --git a/src/linux/crash_context/x86.rs b/src/linux/crash_context/x86.rs
index 7f092716..5a2e43ee 100644
--- a/src/linux/crash_context/x86.rs
+++ b/src/linux/crash_context/x86.rs
@@ -41,7 +41,7 @@ impl CrashContext {
{
let fs = &self.inner.float_state;
- let mut out = &mut out.float_save;
+ let out = &mut out.float_save;
out.control_word = fs.cw;
out.status_word = fs.sw;
out.tag_word = fs.tag;
diff --git a/src/linux/dumper_cpu_info/x86_mips.rs b/src/linux/dumper_cpu_info/x86_mips.rs
index 131df34f..cefba4fd 100644
--- a/src/linux/dumper_cpu_info/x86_mips.rs
+++ b/src/linux/dumper_cpu_info/x86_mips.rs
@@ -67,7 +67,7 @@ pub fn write_cpu_information(sys_info: &mut MDRawSystemInfo) -> Result<()> {
};
let mut is_first_entry = true;
- for mut entry in cpu_info_table.iter_mut() {
+ for entry in cpu_info_table.iter_mut() {
if !is_first_entry && entry.found {
// except for the 'processor' field, ignore repeated values.
continue;