1pub use decant_protocol::{MemRegion, ModuleInfo, Pid, ProcessInfo, ProtoError};
4
5mod mock;
6pub use mock::{MockBackend, MockGuest};
7
8pub mod fixtures;
9
10pub type Result<T> = std::result::Result<T, BackendError>;
11
12#[derive(Debug, thiserror::Error)]
13pub enum BackendError {
14 #[error("no such process (pid={pid:?}, name={name:?})")]
15 NoSuchProcess {
16 pid: Option<u32>,
17 name: Option<String>,
18 },
19
20 #[error("no such module {module:?} in pid {pid}")]
21 NoSuchModule { pid: u32, module: String },
22
23 #[error("read of {len} bytes at {addr:#x} failed: {reason}")]
24 ReadFailed { addr: u64, len: u64, reason: String },
25
26 #[error("write at {addr:#x} failed: {reason}")]
27 WriteFailed { addr: u64, reason: String },
28
29 #[error("unsupported operation: {op}")]
30 Unsupported { op: String },
31
32 #[error("backend error: {0}")]
33 Other(String),
34}
35
36impl From<BackendError> for ProtoError {
37 fn from(e: BackendError) -> Self {
38 match e {
39 BackendError::NoSuchProcess { pid, name } => ProtoError::NoSuchProcess { pid, name },
40 BackendError::NoSuchModule { pid, module } => ProtoError::NoSuchModule { pid, module },
41 BackendError::ReadFailed { addr, len, reason } => {
42 ProtoError::ReadFailed { addr, len, reason }
43 }
44 BackendError::WriteFailed { addr, reason } => ProtoError::WriteFailed { addr, reason },
45 BackendError::Unsupported { op } => ProtoError::Unsupported { op },
46 BackendError::Other(message) => ProtoError::Backend { message },
47 }
48 }
49}
50
51pub trait MemoryBackend: Send + Sync {
52 fn list_processes(&self) -> Result<Vec<ProcessInfo>>;
53 fn process_by_pid(&self, pid: Pid) -> Result<ProcessInfo>;
54 fn process_by_name(&self, name: &str) -> Result<ProcessInfo>;
55 fn module_list(&self, pid: Pid) -> Result<Vec<ModuleInfo>>;
56 fn module_by_name(&self, pid: Pid, name: &str) -> Result<ModuleInfo>;
57 fn module_exports(&self, pid: Pid, module: &str) -> Result<Vec<(String, u64)>>;
58 fn read(&self, pid: Pid, addr: u64, len: usize) -> Result<Vec<u8>>;
59 fn write(&self, pid: Pid, addr: u64, data: &[u8]) -> Result<usize>;
60 fn memory_map(&self, pid: Pid) -> Result<Vec<MemRegion>>;
61}