metaemu_state/
register.rs

1use std::marker::PhantomData;
2use std::ops::{Deref, DerefMut};
3use std::sync::Arc;
4
5use fugue::bytes::Order;
6use fugue::ir::convention::{Convention, ReturnAddress};
7use fugue::ir::il::pcode::{Operand, Register};
8use fugue::ir::register::RegisterNames;
9use fugue::ir::{Address, Translator};
10
11use crate::{FromStateValues, IntoStateValues, State, StateOps, StateValue};
12use crate::flat::FlatState;
13use serde::{Serialize, Deserialize};
14
15pub use crate::flat::Error;
16
17#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
18pub enum ReturnLocation {
19    Register(Operand),
20    Relative(Operand, u64),
21}
22
23impl ReturnLocation {
24    pub fn from_convention(translator: &Translator, convention: &Convention) -> Self {
25        match convention.return_address() {
26            ReturnAddress::Register { varnode, .. } => {
27                Self::Register(Operand::from_varnode(translator, *varnode))
28            },
29            ReturnAddress::StackRelative { offset, .. } => {
30                Self::Relative(
31                    Operand::from_varnode(translator, *convention.stack_pointer().varnode()),
32                    *offset,
33                )
34            }
35        }
36    }
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
40// #[cfg_attr(feature = "serde_derive", derive(serde::Deserialize, serde::Serialize))]
41pub struct RegisterState<T: StateValue, O: Order> {
42    program_counter: Arc<Operand>,
43    stack_pointer: Arc<Operand>,
44    register_names: Arc<RegisterNames>,
45    return_location: Arc<ReturnLocation>,
46    inner: FlatState<T>,
47    marker: PhantomData<O>,
48}
49
50impl<T: StateValue, O: Order> AsRef<Self> for RegisterState<T, O> {
51    #[inline(always)]
52    fn as_ref(&self) -> &Self {
53        self
54    }
55}
56
57impl<T: StateValue, O: Order> AsMut<Self> for RegisterState<T, O> {
58    #[inline(always)]
59    fn as_mut(&mut self) -> &mut Self {
60        self
61    }
62}
63
64impl<T: StateValue, O: Order> AsRef<FlatState<T>> for RegisterState<T, O> {
65    #[inline(always)]
66    fn as_ref(&self) -> &FlatState<T> {
67        &self.inner
68    }
69}
70
71impl<T: StateValue, O: Order> AsMut<FlatState<T>> for RegisterState<T, O> {
72    #[inline(always)]
73    fn as_mut(&mut self) -> &mut FlatState<T> {
74        &mut self.inner
75    }
76}
77
78impl<T: StateValue, O: Order> Deref for RegisterState<T, O> {
79    type Target = FlatState<T>;
80
81    fn deref(&self) -> &Self::Target {
82        &self.inner
83    }
84}
85
86impl<T: StateValue, O: Order> DerefMut for RegisterState<T, O> {
87    fn deref_mut(&mut self) -> &mut Self::Target {
88        &mut self.inner
89    }
90}
91
92impl<T: StateValue, O: Order> From<RegisterState<T, O>> for FlatState<T> {
93    fn from(t: RegisterState<T, O>) -> Self {
94        t.inner
95    }
96}
97
98impl<V: StateValue, O: Order> State for RegisterState<V, O> {
99    type Error = Error;
100
101    #[inline(always)]
102    fn fork(&self) -> Self {
103        Self {
104            inner: self.inner.fork(),
105            stack_pointer: self.stack_pointer.clone(),
106            program_counter: self.program_counter.clone(),
107            return_location: self.return_location.clone(),
108            register_names: self.register_names.clone(),
109            marker: PhantomData,
110        }
111    }
112
113    #[inline(always)]
114    fn restore(&mut self, other: &Self) {
115        self.inner.restore(&other.inner)
116    }
117}
118
119impl<V: StateValue, O: Order> StateOps for RegisterState<V, O> {
120    type Value = V;
121
122    #[inline(always)]
123    fn len(&self) -> usize {
124        self.inner.len()
125    }
126
127    #[inline(always)]
128    fn copy_values<F, T>(&mut self, from: F, to: T, size: usize) -> Result<(), Self::Error>
129    where F: Into<Address>,
130          T: Into<Address> {
131        self.inner.copy_values(from, to, size)
132    }
133
134    #[inline(always)]
135    fn get_values<A>(&self, address: A, bytes: &mut [Self::Value]) -> Result<(), Self::Error>
136    where A: Into<Address> {
137        self.inner.get_values(address, bytes)
138    }
139
140    #[inline(always)]
141    fn view_values<A>(&self, address: A, size: usize) -> Result<&[Self::Value], Self::Error>
142    where A: Into<Address> {
143        self.inner.view_values(address, size)
144    }
145
146    #[inline(always)]
147    fn view_values_mut<A>(&mut self, address: A, size: usize) -> Result<&mut [Self::Value], Self::Error>
148    where A: Into<Address> {
149        self.inner.view_values_mut(address, size)
150    }
151
152    #[inline(always)]
153    fn set_values<A>(&mut self, address: A, bytes: &[Self::Value]) -> Result<(), Self::Error>
154    where A: Into<Address> {
155        self.inner.set_values(address, bytes)
156    }
157}
158
159impl<T: StateValue, O: Order> RegisterState<T, O> {
160    pub fn new(translator: &Translator, convention: &Convention) -> Self {
161        let program_counter = Arc::new(Operand::from_varnode(translator, *translator.program_counter()));
162        let stack_pointer = Arc::new(Operand::from_varnode(translator, *convention.stack_pointer().varnode()));
163        let return_location = Arc::new(ReturnLocation::from_convention(translator, convention));
164
165        let space = translator.manager().register_space();
166        let register_names = translator.registers().clone();
167        let size = translator.register_space_size();
168
169        log::debug!("register space size: {} bytes", size);
170
171        Self {
172            inner: FlatState::new(space, size),
173            program_counter,
174            stack_pointer,
175            return_location,
176            register_names,
177            marker: PhantomData,
178        }
179    }
180
181    pub fn program_counter(&self) -> Arc<Operand> {
182        self.program_counter.clone()
183    }
184
185    pub fn stack_pointer(&self) -> Arc<Operand> {
186        self.stack_pointer.clone()
187    }
188
189    pub fn return_location(&self) -> Arc<ReturnLocation> {
190        self.return_location.clone()
191    }
192
193    pub fn get_register_values(&self, register: &Register, values: &mut [T]) -> Result<(), Error> {
194        let view = self.view_values(register.offset(), register.size())?;
195        values.clone_from_slice(view);
196        Ok(())
197    }
198
199    pub fn register_names(&self) -> &Arc<RegisterNames> {
200        &self.register_names
201    }
202
203    pub fn register_by_name<N>(&self, name: N) -> Option<Register>
204    where N: AsRef<str> {
205        self.register_names
206            .get_by_name(name)
207            .map(|(name, offset, size)| Register::new(name.clone(), offset, size))
208    }
209
210    pub fn get_register<V: FromStateValues<T>>(&self, register: &Register) -> Result<V, Error> {
211        Ok(V::from_values::<O>(self.view_values(register.offset(), register.size())?))
212    }
213
214    pub fn set_register_values(&mut self, register: &Register, values: &[T]) -> Result<(), Error> {
215        let view = self.view_values_mut(register.offset(), register.size())?;
216        view.clone_from_slice(values);
217        Ok(())
218    }
219
220    pub fn set_register<V: IntoStateValues<T>>(&mut self, register: &Register, value: V) -> Result<(), Error> {
221        value.into_values::<O>(self.view_values_mut(register.offset(), register.size())?);
222        Ok(())
223    }
224
225    pub fn set_register_by_name<N, V: IntoStateValues<T>>(&mut self, name: N, value: V) -> Result<(), Error>
226    where N: AsRef<str> {
227        let register = self.register_by_name(&name).unwrap_or_else(|| {
228            panic!("register {} not found", name.as_ref())
229        });
230        self.set_register(&register, value)
231    }
232
233    pub fn get_register_by_name<N, V: FromStateValues<T>>(&self, name: N) -> Result<V, Error>
234    where N: AsRef<str> {
235        let register = self.register_by_name(&name).unwrap_or_else(|| {
236            panic!("register {} not found", name.as_ref())
237        });
238        self.get_register(&register)
239    }
240}