-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #127 from marti4d/improve_auxv
Setup infrastructure to allow the auxiliary vector information to be passed from the crashed process.
- Loading branch information
Showing
10 changed files
with
217 additions
and
109 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,137 @@ | ||
pub use reader::ProcfsAuxvIter; | ||
use { | ||
crate::linux::thread_info::Pid, | ||
std::{fs::File, io::BufReader}, | ||
thiserror::Error, | ||
}; | ||
|
||
mod reader; | ||
|
||
/// The type used in auxv keys and values. | ||
#[cfg(target_pointer_width = "32")] | ||
pub type AuxvType = u32; | ||
/// The type used in auxv keys and values. | ||
#[cfg(target_pointer_width = "64")] | ||
pub type AuxvType = u64; | ||
|
||
#[cfg(target_os = "android")] | ||
mod consts { | ||
use super::AuxvType; | ||
pub const AT_PHDR: AuxvType = 3; | ||
pub const AT_PHNUM: AuxvType = 5; | ||
pub const AT_ENTRY: AuxvType = 9; | ||
pub const AT_SYSINFO_EHDR: AuxvType = 33; | ||
} | ||
#[cfg(not(target_os = "android"))] | ||
mod consts { | ||
use super::AuxvType; | ||
pub const AT_PHDR: AuxvType = libc::AT_PHDR; | ||
pub const AT_PHNUM: AuxvType = libc::AT_PHNUM; | ||
pub const AT_ENTRY: AuxvType = libc::AT_ENTRY; | ||
pub const AT_SYSINFO_EHDR: AuxvType = libc::AT_SYSINFO_EHDR; | ||
} | ||
|
||
/// An auxv key-value pair. | ||
#[derive(Debug, PartialEq, Eq)] | ||
pub struct AuxvPair { | ||
pub key: AuxvType, | ||
pub value: AuxvType, | ||
} | ||
|
||
/// Auxv info that can be passed from crashing process | ||
/// | ||
/// Since `/proc/{pid}/auxv` can sometimes be inaccessible, the calling process should prefer to transfer this | ||
/// information directly using the Linux `getauxval()` call (if possible). | ||
/// | ||
/// Any field that is set to `0` will be considered unset. In that case, minidump-writer might try other techniques | ||
/// to obtain it (like reading `/proc/{pid}/auxv`). | ||
#[repr(C)] | ||
#[derive(Clone, Debug, Default)] | ||
pub struct DirectAuxvDumpInfo { | ||
/// The value of `getauxval(AT_PHNUM)` | ||
pub program_header_count: AuxvType, | ||
/// The value of `getauxval(AT_PHDR)` | ||
pub program_header_address: AuxvType, | ||
/// The value of `getauxval(AT_SYSINFO_EHDR)` | ||
pub linux_gate_address: AuxvType, | ||
/// The value of `getauxval(AT_ENTRY)` | ||
pub entry_address: AuxvType, | ||
} | ||
|
||
impl From<DirectAuxvDumpInfo> for AuxvDumpInfo { | ||
fn from(f: DirectAuxvDumpInfo) -> AuxvDumpInfo { | ||
AuxvDumpInfo { | ||
program_header_count: (f.program_header_count > 0).then_some(f.program_header_count), | ||
program_header_address: (f.program_header_address > 0) | ||
.then_some(f.program_header_address), | ||
linux_gate_address: (f.linux_gate_address > 0).then_some(f.linux_gate_address), | ||
entry_address: (f.entry_address > 0).then_some(f.entry_address), | ||
} | ||
} | ||
} | ||
|
||
#[derive(Debug, Default)] | ||
pub struct AuxvDumpInfo { | ||
program_header_count: Option<AuxvType>, | ||
program_header_address: Option<AuxvType>, | ||
linux_gate_address: Option<AuxvType>, | ||
entry_address: Option<AuxvType>, | ||
} | ||
|
||
impl AuxvDumpInfo { | ||
pub fn try_filling_missing_info(&mut self, pid: Pid) -> Result<(), AuxvError> { | ||
if self.is_complete() { | ||
return Ok(()); | ||
} | ||
|
||
let auxv_path = format!("/proc/{pid}/auxv"); | ||
let auxv_file = File::open(&auxv_path).map_err(|e| AuxvError::OpenError(auxv_path, e))?; | ||
|
||
for AuxvPair { key, value } in | ||
ProcfsAuxvIter::new(BufReader::new(auxv_file)).filter_map(Result::ok) | ||
{ | ||
let dest_field = match key { | ||
consts::AT_PHNUM => &mut self.program_header_count, | ||
consts::AT_PHDR => &mut self.program_header_address, | ||
consts::AT_SYSINFO_EHDR => &mut self.linux_gate_address, | ||
consts::AT_ENTRY => &mut self.entry_address, | ||
_ => continue, | ||
}; | ||
if dest_field.is_none() { | ||
*dest_field = Some(value); | ||
} | ||
} | ||
|
||
Ok(()) | ||
} | ||
pub fn get_program_header_count(&self) -> Option<AuxvType> { | ||
self.program_header_count | ||
} | ||
pub fn get_program_header_address(&self) -> Option<AuxvType> { | ||
self.program_header_address | ||
} | ||
pub fn get_linux_gate_address(&self) -> Option<AuxvType> { | ||
self.linux_gate_address | ||
} | ||
pub fn get_entry_address(&self) -> Option<AuxvType> { | ||
self.entry_address | ||
} | ||
pub fn is_complete(&self) -> bool { | ||
self.program_header_count.is_some() | ||
&& self.program_header_address.is_some() | ||
&& self.linux_gate_address.is_some() | ||
&& self.entry_address.is_some() | ||
} | ||
} | ||
|
||
#[derive(Debug, Error)] | ||
pub enum AuxvError { | ||
#[error("Failed to open file {0}")] | ||
OpenError(String, #[source] std::io::Error), | ||
#[error("No auxv entry found for PID {0}")] | ||
NoAuxvEntryFound(Pid), | ||
#[error("Invalid auxv format (should not hit EOF before AT_NULL)")] | ||
InvalidFormat, | ||
#[error("IO Error")] | ||
IOError(#[from] std::io::Error), | ||
} |
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
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
Oops, something went wrong.