Skip to main content

decant_backend/
lib.rs

1//! Backend trait and mock guest model for Decant memory access.
2
3pub 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}