v0.3: ELF symbol parsing, sym()/addr()/symbols() globals, addrstr/here prelude helpers

This commit is contained in:
claude
2026-05-27 21:13:10 +00:00
parent 19c6154831
commit d587dbcd4c
7 changed files with 304 additions and 5 deletions
+18 -5
View File
@@ -11,6 +11,8 @@ use nix::unistd::{execvp, fork, ForkResult, Pid};
use std::ffi::CString;
use std::io::IoSliceMut;
use crate::symbols::SymbolTable;
/// Why the target stopped after a step/continue, or that it has exited.
#[derive(Debug, Clone)]
pub enum StopReason {
@@ -55,6 +57,9 @@ pub struct Target {
/// Snapshot of registers from the previous stop. None until at least one
/// step/cont has happened after spawn.
prev_regs: Option<libc::user_regs_struct>,
/// ELF symbols of the main executable. None if parsing failed (e.g.
/// stripped binary, unreadable /proc) — symbol lookups become no-ops.
symbols: Option<SymbolTable>,
}
impl Target {
@@ -102,11 +107,15 @@ impl Target {
let status = waitpid(child, None)
.map_err(|e| format!("waitpid (initial) failed: {}", e))?;
match status {
WaitStatus::Stopped(_, Signal::SIGTRAP) => Ok(Target {
pid: child,
state: State::Stopped(StopReason::Step),
prev_regs: None,
}),
WaitStatus::Stopped(_, Signal::SIGTRAP) => {
let symbols = SymbolTable::from_pid(child.as_raw()).ok();
Ok(Target {
pid: child,
state: State::Stopped(StopReason::Step),
prev_regs: None,
symbols,
})
}
WaitStatus::Exited(_, code) => {
Err(format!("child exited immediately with code {} (exec failed?)", code))
}
@@ -143,6 +152,10 @@ impl Target {
self.prev_regs
}
pub fn symbols(&self) -> Option<&SymbolTable> {
self.symbols.as_ref()
}
fn wait_for_stop(&mut self) -> Result<StopReason, String> {
let status = waitpid(self.pid, None).map_err(|e| format!("waitpid: {}", e))?;
let reason = match status {