android13/external/rust/crates/gdbstub/examples/armv4t/gdb/extended_mode.rs

157 lines
4.9 KiB
Rust

use gdbstub::common::Pid;
use gdbstub::target;
use gdbstub::target::ext::extended_mode::{Args, AttachKind, ShouldTerminate};
use gdbstub::target::TargetResult;
use crate::emu::Emu;
/*=====================================
= Extended Mode =
=====================================*/
// This is a stub implementation of GDB's Extended Mode extensions.
//
// Truth be told, this particular emulator is _not_ very well suited to running
// in extended mode, as it doesn't technically spawn/attach to any process.
// Nonetheless, it's useful to have a stubbed implementation in-tree which can
// be used for basic usability / regression testing.
//
// If you happen to implement a "proper" extended mode gdbstub, feel free to
// file an issue / open a PR that links to your project!
impl target::ext::extended_mode::ExtendedMode for Emu {
fn kill(&mut self, pid: Option<Pid>) -> TargetResult<ShouldTerminate, Self> {
eprintln!("GDB sent a kill request for pid {:?}", pid);
Ok(ShouldTerminate::No)
}
fn restart(&mut self) -> Result<(), Self::Error> {
eprintln!("GDB sent a restart request");
Ok(())
}
fn attach(&mut self, pid: Pid) -> TargetResult<(), Self> {
eprintln!("GDB tried to attach to a process with PID {}", pid);
Err(().into()) // non-specific failure
}
fn run(&mut self, filename: Option<&[u8]>, args: Args) -> TargetResult<Pid, Self> {
// simplified example: assume UTF-8 filenames / args
//
// To be 100% pedantically correct, consider converting to an `OsStr` in the
// least lossy way possible (e.g: using the `from_bytes` extension from
// `std::os::unix::ffi::OsStrExt`).
let filename = match filename {
None => None,
Some(raw) => Some(core::str::from_utf8(raw).map_err(drop)?),
};
let args = args
.map(|raw| core::str::from_utf8(raw).map_err(drop))
.collect::<Result<Vec<_>, _>>()?;
eprintln!(
"GDB tried to run a new process with filename {:?}, and args {:?}",
filename, args
);
self.reset();
// when running in single-threaded mode, this PID can be anything
Ok(Pid::new(1337).unwrap())
}
fn query_if_attached(&mut self, pid: Pid) -> TargetResult<AttachKind, Self> {
eprintln!(
"GDB queried if it was attached to a process with PID {}",
pid
);
Ok(AttachKind::Attach)
}
#[inline(always)]
fn configure_aslr(&mut self) -> Option<target::ext::extended_mode::ConfigureAslrOps<Self>> {
Some(self)
}
#[inline(always)]
fn configure_env(&mut self) -> Option<target::ext::extended_mode::ConfigureEnvOps<Self>> {
Some(self)
}
#[inline(always)]
fn configure_startup_shell(
&mut self,
) -> Option<target::ext::extended_mode::ConfigureStartupShellOps<Self>> {
Some(self)
}
#[inline(always)]
fn configure_working_dir(
&mut self,
) -> Option<target::ext::extended_mode::ConfigureWorkingDirOps<Self>> {
Some(self)
}
}
impl target::ext::extended_mode::ConfigureAslr for Emu {
fn cfg_aslr(&mut self, enabled: bool) -> TargetResult<(), Self> {
eprintln!("GDB {} ASLR", if enabled { "enabled" } else { "disabled" });
Ok(())
}
}
impl target::ext::extended_mode::ConfigureEnv for Emu {
fn set_env(&mut self, key: &[u8], val: Option<&[u8]>) -> TargetResult<(), Self> {
// simplified example: assume UTF-8 key/val env vars
let key = core::str::from_utf8(key).map_err(drop)?;
let val = match val {
None => None,
Some(raw) => Some(core::str::from_utf8(raw).map_err(drop)?),
};
eprintln!("GDB tried to set a new env var: {:?}={:?}", key, val);
Ok(())
}
fn remove_env(&mut self, key: &[u8]) -> TargetResult<(), Self> {
let key = core::str::from_utf8(key).map_err(drop)?;
eprintln!("GDB tried to set remove a env var: {:?}", key);
Ok(())
}
fn reset_env(&mut self) -> TargetResult<(), Self> {
eprintln!("GDB tried to reset env vars");
Ok(())
}
}
impl target::ext::extended_mode::ConfigureStartupShell for Emu {
fn cfg_startup_with_shell(&mut self, enabled: bool) -> TargetResult<(), Self> {
eprintln!(
"GDB {} startup with shell",
if enabled { "enabled" } else { "disabled" }
);
Ok(())
}
}
impl target::ext::extended_mode::ConfigureWorkingDir for Emu {
fn cfg_working_dir(&mut self, dir: Option<&[u8]>) -> TargetResult<(), Self> {
let dir = match dir {
None => None,
Some(raw) => Some(core::str::from_utf8(raw).map_err(drop)?),
};
match dir {
None => eprintln!("GDB reset the working directory"),
Some(dir) => eprintln!("GDB set the working directory to {:?}", dir),
}
Ok(())
}
}