1use crate::instruction::{Instruction, decode, info};
6
7use super::Binary;
8use super::error;
9
10#[derive(Copy, Clone, Default, Debug, PartialEq)]
14pub struct Func<F: FnMut(u64) -> Result<Instruction<I>, E>, I: info::Info, E> {
15 func: F,
16 phantom: core::marker::PhantomData<(I, E)>,
17}
18
19impl<F: FnMut(u64) -> Result<Instruction<I>, E>, I: info::Info, E> Func<F, I, E> {
20 fn new(func: F) -> Self {
22 Self {
23 func,
24 phantom: Default::default(),
25 }
26 }
27}
28
29impl<F: FnMut(u64) -> Result<Instruction<I>, E>, I: info::Info, E> Binary<I> for Func<F, I, E> {
30 type Error = E;
31
32 fn get_insn(&mut self, address: u64) -> Result<Instruction<I>, Self::Error> {
33 (self.func)(address)
34 }
35}
36
37pub fn from_fn<F, I, E>(func: F) -> Func<F, I, E>
39where
40 F: FnMut(u64) -> Result<Instruction<I>, E>,
41 I: info::Info,
42{
43 Func::new(func)
44}
45
46#[derive(Copy, Clone, Debug, PartialEq)]
68pub struct Segment<T: AsRef<[u8]>, B> {
69 data: T,
70 base: B,
71}
72
73impl<T: AsRef<[u8]>, B> Segment<T, B> {
74 pub fn new(data: T, base: B) -> Self {
76 Self { data, base }
77 }
78}
79
80impl<T: AsRef<[u8]>, B: decode::Decode<I>, I: info::Info> Binary<I> for Segment<T, B> {
81 type Error = error::SegmentError;
82
83 fn get_insn(&mut self, address: u64) -> Result<Instruction<I>, Self::Error> {
84 let offset = address.try_into().map_err(Self::Error::ExceededHostUSize)?;
85 let insn_data = self
86 .data
87 .as_ref()
88 .split_at_checked(offset)
89 .map(|(_, d)| d)
90 .filter(|d| !d.is_empty())
91 .ok_or(Self::Error::AddressNotCovered)?;
92 Instruction::extract(insn_data, &self.base)
93 .map(|(i, _)| i)
94 .ok_or(Self::Error::InvalidInstruction)
95 }
96}
97
98pub fn from_segment<T: AsRef<[u8]>, B>(data: T, base: B) -> Segment<T, B> {
100 Segment::new(data, base)
101}
102
103#[derive(Copy, Clone, Default, Debug, PartialEq)]
109pub struct SimpleMap<T: AsRef<[(u64, Instruction<I>)]>, I: info::Info> {
110 inner: T,
111 phantom: core::marker::PhantomData<I>,
112}
113
114impl<T: AsRef<[(u64, Instruction<I>)]>, I: info::Info> SimpleMap<T, I> {
115 pub fn new<J>(mut inner: J) -> Self
123 where
124 T: From<J>,
125 J: AsMut<[(u64, Instruction<I>)]>,
126 {
127 inner.as_mut().sort_unstable_by_key(|(a, _)| *a);
128 Self {
129 inner: inner.into(),
130 phantom: Default::default(),
131 }
132 }
133
134 pub fn from_sorted(inner: T) -> Option<Self> {
138 inner
139 .as_ref()
140 .is_sorted_by_key(|(a, _)| *a)
141 .then_some(Self {
142 inner,
143 phantom: Default::default(),
144 })
145 }
146}
147
148impl<T, J, I> From<J> for SimpleMap<T, I>
149where
150 T: AsRef<[(u64, Instruction<I>)]> + From<J>,
151 J: AsMut<[(u64, Instruction<I>)]>,
152 I: info::Info,
153{
154 fn from(inner: J) -> Self {
155 Self::new(inner)
156 }
157}
158
159impl<T: AsRef<[(u64, Instruction<I>)]>, I: info::Info + Clone> Binary<I> for SimpleMap<T, I> {
160 type Error = error::NoInstruction;
161
162 fn get_insn(&mut self, address: u64) -> Result<Instruction<I>, Self::Error> {
163 let map = self.inner.as_ref();
164 map.binary_search_by_key(&address, |(a, _)| *a)
165 .map(|i| map[i].1.clone())
166 .map_err(|_| error::NoInstruction)
167 }
168}
169
170pub fn from_sorted_map<T, I>(inner: T) -> Option<SimpleMap<T, I>>
175where
176 T: AsRef<[(u64, Instruction<I>)]>,
177 I: info::Info,
178{
179 SimpleMap::from_sorted(inner)
180}
181
182pub fn from_map<T, J, I>(inner: J) -> SimpleMap<T, I>
184where
185 T: AsRef<[(u64, Instruction<I>)]> + From<J>,
186 J: AsMut<[(u64, Instruction<I>)]>,
187 I: info::Info,
188{
189 inner.into()
190}
191
192#[derive(Copy, Clone, Default, Debug, PartialEq)]
194pub struct Empty;
195
196impl<I: info::Info> Binary<I> for Empty {
197 type Error = error::NoInstruction;
198
199 fn get_insn(&mut self, _: u64) -> Result<Instruction<I>, Self::Error> {
200 Err(error::NoInstruction)
201 }
202}