retour\pic/
thunk.rs

1use super::Thunkable;
2use generic_array::{ArrayLength, GenericArray};
3
4/// A closure that generates a thunk.
5pub struct FixedThunk<N: ArrayLength<u8>>(Box<dyn Fn(usize) -> GenericArray<u8, N>>);
6
7impl<N: ArrayLength<u8>> FixedThunk<N> {
8  /// Constructs a new thunk with a specific closure.
9  pub fn new<T: Fn(usize) -> GenericArray<u8, N> + 'static>(callback: T) -> Self {
10    FixedThunk(Box::new(callback))
11  }
12}
13
14/// Thunks implement the thunkable interface.
15impl<N: ArrayLength<u8>> Thunkable for FixedThunk<N> {
16  fn generate(&self, address: usize) -> Vec<u8> {
17    self.0(address).to_vec()
18  }
19
20  fn len(&self) -> usize {
21    N::to_usize()
22  }
23}
24
25/// A closure that generates an unsafe thunk.
26pub struct UnsafeThunk {
27  callback: Box<dyn Fn(usize) -> Vec<u8>>,
28  size: usize,
29}
30
31/// An unsafe thunk, because it cannot be asserted at compile time, that the
32/// generated data is the same size as `len()` (will panic otherwise when
33/// emitted).
34impl UnsafeThunk {
35  /// Constructs a new dynamic thunk with a closure.
36  pub unsafe fn new<T: Fn(usize) -> Vec<u8> + 'static>(callback: T, size: usize) -> Self {
37    UnsafeThunk {
38      callback: Box::new(callback),
39      size,
40    }
41  }
42}
43
44impl Thunkable for UnsafeThunk {
45  /// Generates a dynamic thunk, assumed to be PIC.
46  fn generate(&self, address: usize) -> Vec<u8> {
47    (self.callback)(address)
48  }
49
50  /// Returns the size of the generated thunk.
51  fn len(&self) -> usize {
52    self.size
53  }
54}