yaxpeax_core/arch/
mod.rs

1pub mod arm;
2pub mod pic17;
3pub mod pic18;
4// pub mod pic24;
5pub mod msp430;
6
7pub mod x86_64;
8
9pub mod display;
10pub mod interface;
11
12use std::cell::{Ref, RefCell, RefMut};
13use std::fmt::Debug;
14use std::hash::{Hash, Hasher};
15use std::rc::Rc;
16use std::fmt::{Display, Write};
17
18use crate::data::types;
19use data::ValueLocations;
20use data::Direction;
21use data::modifier::Precedence;
22
23use analyses::static_single_assignment::{NoValueDescriptions, ValueDescriptionQuery};
24
25use yaxpeax_arch::{Address, Decoder, LengthedInstruction};
26
27use memory::{MemoryRange, MemoryRepr};
28use memory::repr::cursor::ReadCursor;
29
30use serde::{Deserialize, Serialize};
31
32pub trait DecodeFrom<T: MemoryRepr<Self> + ?Sized>: yaxpeax_arch::Arch {
33    fn decode_from<'mem>(t: &ReadCursor<'mem, Self, T>) -> Result<Self::Instruction, Self::DecodeError> {
34        Self::decode_with_decoder(&Self::Decoder::default(), t)
35    }
36    fn decode_with_decoder<'mem>(decoder: &Self::Decoder, t: &ReadCursor<'mem, Self, T>) -> Result<Self::Instruction, Self::DecodeError> {
37        let mut inst = Self::Instruction::default();
38        Self::decode_with_decoder_into(decoder, t, &mut inst)?;
39        Ok(inst)
40    }
41    fn decode_with_decoder_into<'mem>(decoder: &Self::Decoder, t: &ReadCursor<'mem, Self, T>, instr: &mut Self::Instruction) -> Result<(), Self::DecodeError>;
42}
43
44pub trait FunctionQuery<A: Address> {
45    type Function;
46    fn function_at(&self, addr: A) -> Option<&Self::Function>;
47    fn all_functions(&self) -> Vec<&Self::Function>;
48}
49
50impl<Addr: Address, Loc: AbiDefaults> FunctionQuery<Addr> for std::collections::HashMap<Addr, FunctionImpl<Loc>> {
51    type Function = FunctionImpl<Loc>;
52
53    fn function_at(&self, addr: Addr) -> Option<&Self::Function> {
54        self.get(&addr)
55    }
56
57    fn all_functions(&self) -> Vec<&Self::Function> {
58        self.values().collect()
59    }
60}
61
62pub trait SymbolQuery<A: Address> {
63    fn symbol_for(&self, addr: A) -> Option<&Symbol>;
64    fn symbol_addr(&self, sym: &Symbol) -> Option<A>;
65}
66
67pub trait AddressNamer<A: Address> {
68    fn address_name(&self, addr: A) -> Option<String>;
69}
70
71impl <'a, T, A: Address, F: FunctionRepr> AddressNamer<A> for T where T: FunctionQuery<A, Function=F> + SymbolQuery<A> {
72    fn address_name(&self, addr: A) -> Option<String> {
73        self.function_at(addr).map(|func| func.name().to_owned())
74            .or_else(|| { self.symbol_for(addr).map(|sym| sym.to_string()) })
75    }
76}
77
78pub trait CommentQuery<A: Address> {
79    fn comment_for(&self, addr: A) -> Option<&str>;
80}
81
82#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
83pub struct Parameter {
84    name: Option<String>,
85    ty: Option<types::TypeSpec>
86}
87
88impl Default for Parameter {
89    fn default() -> Self {
90        Parameter {
91            name: None,
92            ty: None
93        }
94    }
95}
96
97impl Parameter {
98    pub fn of(name: &str) -> Self {
99        Parameter {
100            name: Some(name.to_owned()),
101            ty: None
102        }
103    }
104
105    pub fn typed(mut self, ty: types::TypeSpec) -> Self {
106        self.ty = Some(ty);
107        self
108    }
109}
110
111#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
112pub struct Function {
113    name: String,
114    arguments: Vec<Option<Parameter>>,
115    returns: Vec<Option<Parameter>>,
116}
117
118#[derive(Debug, Clone, Serialize, Deserialize)]
119pub struct FunctionImpl<Loc: AbiDefaults> {
120    names: Function,
121    layout: Rc<RefCell<FunctionLayout<Loc>>>,
122}
123
124pub struct FunctionImplDescription<'a, Loc: AbiDefaults, V: ValueDescriptionQuery<Loc>> {
125    f: &'a FunctionImpl<Loc>,
126    values: Option<V>
127}
128
129// PartialEq, Eq
130
131#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
132pub struct FunctionLayout<Loc: AbiDefaults> {
133    pub arguments: Vec<Option<Loc>>,
134    pub(crate) returns: Vec<Option<Loc>>,
135    pub(crate) clobbers: Vec<Option<Loc>>,
136    pub(crate) return_address: Option<Loc>,
137    defaults: Loc::AbiDefault,
138}
139
140impl <Loc: AbiDefaults> FunctionLayout<Loc> {
141    fn for_abi(default: Loc::AbiDefault) -> Self {
142        FunctionLayout {
143            arguments: Vec::new(),
144            returns: Vec::new(),
145            clobbers: Vec::new(),
146            return_address: None,
147            defaults: default
148        }
149    }
150}
151
152pub trait AbiDefaults: Clone + Debug {
153    type AbiDefault: FunctionAbiReference<Self> + Debug + Serialize + for<'de> Deserialize<'de> + Default;
154}
155
156impl <Loc: Hash + AbiDefaults> Hash for FunctionLayout<Loc> {
157    fn hash<H: Hasher>(&self, state: &mut H) {
158        self.arguments.hash(state);
159        self.returns.hash(state);
160        self.clobbers.hash(state);
161        self.return_address.hash(state);
162    }
163}
164
165fn insert_at<Loc: Clone>(vs: &mut Vec<Option<Loc>>, el: Option<Loc>, i: usize) {
166    if i >= vs.len() {
167        vs.resize(i + 1, None);
168    }
169
170    vs[i] = el;
171}
172
173impl <Loc: Clone + Debug + AbiDefaults> FunctionAbiReference<Loc> for FunctionLayout<Loc> {
174    fn argument_at(&mut self, i: usize) -> Option<Loc> {
175        if self.arguments.get(i).is_none() {
176            insert_at(&mut self.arguments, self.defaults.argument_at(i), i);
177        }
178
179        self.arguments[i].clone()
180    }
181    fn return_at(&mut self, i: usize) -> Option<Loc> {
182        if self.returns.get(i).is_none() {
183            insert_at(&mut self.returns, self.defaults.return_at(i), i);
184        }
185
186        self.returns[i].clone()
187    }
188    fn return_address(&mut self) -> Option<Loc> {
189        if self.return_address.is_none() {
190            self.return_address = self.defaults.return_address();
191        }
192
193        self.return_address.clone()
194    }
195    fn clobber_at(&mut self, i: usize) -> Option<Loc> {
196        if self.clobbers.get(i).is_none() {
197            insert_at(&mut self.clobbers, self.defaults.clobber_at(i), i);
198        }
199
200        self.clobbers[i].clone()
201    }
202}
203
204// TODO: this is an insufficient api - some calling convention/architecture combinations pick
205// locations based on the type of value at the index in question. x86_64 ABIs typically use xmm
206// registers for floating point values but 64-bit general purpose registers for arguments in the
207// same index if the value is an integer.
208pub trait FunctionAbiReference<Loc: Debug + Clone>: Debug {
209    fn argument_at(&mut self, i: usize) -> Option<Loc>;
210    fn return_at(&mut self, i: usize) -> Option<Loc>;
211    fn return_address(&mut self) -> Option<Loc>;
212    fn clobber_at(&mut self, i: usize) -> Option<Loc>;
213}
214
215#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
216struct NilAbi {}
217
218impl <Loc: Debug + Clone> FunctionAbiReference<Loc> for NilAbi {
219    fn argument_at(&mut self, _: usize) -> Option<Loc> { None }
220    fn return_at(&mut self, _: usize) -> Option<Loc> { None }
221    fn return_address(&mut self) -> Option<Loc> { None }
222    fn clobber_at(&mut self, _: usize) -> Option<Loc> { None }
223}
224
225impl <Loc: AbiDefaults + PartialEq> FunctionImpl<Loc> {
226    pub fn new(name: String) -> Self {
227        Function::of(name, vec![], vec![])
228            .unimplemented()
229    }
230
231    pub fn rename(&mut self, new_name: String) {
232        self.names.name = new_name;
233    }
234
235    pub fn append_arg(&mut self, new_arg: (Option<Loc>, Parameter)) {
236        self.names.arguments.push(Some(new_arg.1));
237        let arg_idx = self.names.arguments.len() - 1;
238        let mut layout_mut = self.layout.borrow_mut();
239        let arg = new_arg.0.or_else(|| { layout_mut.argument_at(arg_idx) });
240        while arg_idx >= layout_mut.arguments.len() {
241            layout_mut.arguments.push(None);
242        }
243        layout_mut.arguments[arg_idx] = arg;
244    }
245
246    pub fn has_arg_at(&self, loc: Loc) -> bool {
247        self.layout.borrow().arguments.contains(&Some(loc))
248    }
249
250    pub fn append_ret(&mut self, new_ret: (Option<Loc>, Parameter)) {
251        self.names.returns.push(Some(new_ret.1));
252        let ret_idx = self.names.returns.len() - 1;
253        let ret = new_ret.0.or_else(|| { self.layout.borrow_mut().return_at(ret_idx) });
254        self.layout.borrow_mut().returns[ret_idx] = ret;
255    }
256
257    pub fn layout(&self) -> Ref<FunctionLayout<Loc>> {
258        self.layout.borrow()
259    }
260
261    pub fn layout_mut(&self) -> RefMut<FunctionLayout<Loc>> {
262        self.layout.borrow_mut()
263    }
264
265    pub fn with_value_names<V: ValueDescriptionQuery<Loc>>(&self, value_descs: Option<V>) -> FunctionImplDescription<Loc, V> {
266        FunctionImplDescription {
267            f: self,
268            values: value_descs,
269        }
270    }
271}
272
273impl <T: AbiDefaults + Debug, V: ValueDescriptionQuery<T>> FunctionRepr for FunctionImplDescription<'_, T, V> {
274    fn decl_string(&self, show_locations: bool) -> String {
275        let mut res = self.f.names.name.clone();
276        res.push('(');
277        // Arguments are shown like this:
278        // <arg_name>[ -> <location>]: <value_location>[[ (= <value_description>)]]
279        //
280        // square brackets indicate text selected by `show_locations`.
281        // double square brackets are only set if a value is known for the argument.
282        //
283        // TODO: if `<arg_name>` == `<value_location>`, just fold them together.
284        for (i, name) in self.f.names.arguments.iter().enumerate() {
285            if i > 0 {
286                res.push_str(", ");
287            }
288            // TODO: figure out default naming strategy better than arg_n?
289            if let Some(name) = name.as_ref().and_then(|n| n.name.as_ref()) {
290                res.push_str(name);
291            } else {
292                res.push_str(&format!("arg_{}", i));
293            }
294            let argument = self.f.layout.borrow_mut().argument_at(i);
295            if show_locations {
296                res.push_str(" -> ");
297                write!(res, "{:?}", argument).unwrap();
298            }
299            if let (Some(argument), Some(values)) = (argument, self.values.as_ref()) {
300                if let Some(name) = values.modifier_name(argument.clone(), Direction::Read, Precedence::After) {
301                    write!(res, ": {}", name).unwrap();
302                }
303                if let Some(value) = values.modifier_value(argument.clone(), Direction::Read, Precedence::After) {
304                    write!(res, " (= {})", value).unwrap();
305                }
306            }
307        }
308        res.push(')');
309        match self.f.names.returns.len() {
310            0 => {},
311            1 => {
312                res.push_str(" -> ");
313                let ret = self.f.layout.borrow_mut().return_at(0);
314                if show_locations {
315                    write!(res, "{:?}", ret).unwrap();
316                    res.push_str(" -> ");
317                }
318                if let Some(name) = self.f.names.returns.get(0).and_then(|x| x.as_ref()).and_then(|n| n.name.as_ref()) {
319                    res.push_str(name);
320                } else {
321                    res.push_str("return_0");
322                }
323                if let (Some(ret), Some(values)) = (ret, self.values.as_ref()) {
324                    if let Some(name) = values.modifier_name(ret.clone(), Direction::Write, Precedence::After) {
325                        write!(res, ": {}", name).unwrap();
326                    }
327                    if let Some(value) = values.modifier_value(ret.clone(), Direction::Write, Precedence::After) {
328                        write!(res, " (= {})", value).unwrap();
329                    }
330                }
331            },
332            _ => {
333                res.push_str(" -> ");
334                for (i, name) in self.f.names.returns.iter().enumerate() {
335                    if i > 0 {
336                        res.push_str(", ");
337                    }
338                    let ret = self.f.layout.borrow_mut().return_at(i);
339                    if show_locations {
340                        write!(res, "{:?}", ret).unwrap();
341                        res.push_str(" -> ");
342                    }
343                    if let Some(name) = name.as_ref().and_then(|n| n.name.as_ref()) {
344                        res.push_str(name);
345                    } else {
346                        res.push_str(&format!("return_{}", i));
347                    }
348                    if let (Some(ret), Some(values)) = (ret, self.values.as_ref()) {
349                        if let Some(name) = values.modifier_name(ret.clone(), Direction::Write, Precedence::After) {
350                            write!(res, ": {}", name).unwrap();
351                        }
352                        if let Some(value) = values.modifier_value(ret.clone(), Direction::Write, Precedence::After) {
353                            write!(res, " (= {})", value).unwrap();
354                        }
355                    }
356                }
357            }
358        }
359        res
360    }
361
362    fn name(&self) -> &str {
363        &self.f.names.name
364    }
365}
366
367// TODO:
368// impl <T: Display> FunctionRepr for FunctionImpl<T> {
369impl <T: AbiDefaults + Debug + PartialEq> FunctionRepr for FunctionImpl<T> {
370    fn decl_string(&self, show_locations: bool) -> String {
371        self.with_value_names(Some(NoValueDescriptions)).decl_string(show_locations)
372    }
373    fn name(&self) -> &str {
374        &self.names.name
375    }
376}
377
378pub trait FunctionAbi<A: ValueLocations> {
379    fn argument_loc(&self, idx: usize) -> A::Location;
380    fn return_loc(&self, idx: usize) -> A::Location;
381    fn return_address(&self) -> A::Location;
382}
383
384impl Function {
385    fn implement_for<Loc: AbiDefaults>(self, layout: FunctionLayout<Loc>) -> FunctionImpl<Loc> {
386        FunctionImpl {
387            names: self,
388            layout: Rc::new(RefCell::new(layout))
389        }
390    }
391
392    fn unimplemented<Loc: AbiDefaults>(self) -> FunctionImpl<Loc> {
393        self
394            .implement_for(
395                FunctionLayout::for_abi(
396                    Loc::AbiDefault::default()
397                )
398            )
399    }
400}
401
402pub trait FunctionRepr {
403    fn decl_string(&self, show_locations: bool) -> String;
404    fn name(&self) -> &str;
405}
406
407impl Function {
408    pub fn of(name: String, args: Vec<Parameter>, rets: Vec<Parameter>) -> Function {
409        Function {
410            name: name,
411            arguments: args.into_iter().map(|x| Some(x)).collect(),
412            returns: rets.into_iter().map(|x| Some(x)).collect(),
413        }
414    }
415}
416
417impl FunctionRepr for Function {
418    // TODO: is there a way to sho locations for abstract functions? don't think so..
419    fn decl_string(&self, _show_locations: bool) -> String {
420        let mut res = self.name.clone();
421        res.push('(');
422        for (i, param) in self.arguments.iter().enumerate() {
423            if i > 0 {
424                res.push_str(", ");
425            }
426            if let Some(name) = param.as_ref().and_then(|p| p.name.as_ref()) {
427                res.push_str(name);
428            } else {
429                res.push_str(&format!("arg_{}", i));
430            }
431        }
432        res.push(')');
433        match self.returns.len() {
434            0 => {},
435            1 => {
436                if let Some(name) = self.returns[0].as_ref().and_then(|r| r.name.as_ref()) {
437                    res.push_str(name);
438                } else {
439                    res.push_str("return_0");
440                }
441            },
442            _ => {
443                for (i, ret) in self.returns.iter().enumerate() {
444                    if i > 0 {
445                        res.push_str(", ");
446                    }
447                    if let Some(name) = ret.as_ref().and_then(|r| r.name.as_ref()) {
448                        res.push_str(name);
449                    } else {
450                        res.push_str(&format!("return_{}", i));
451                    }
452                }
453            }
454        }
455        res
456    }
457    fn name(&self) -> &str {
458        &self.name
459    }
460}
461
462#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
463pub enum Library {
464    Name(String),
465    This,
466    Unknown
467}
468
469#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
470pub struct Symbol(pub Library, pub String);
471
472/*
473 * FARPROC GetProcAddress(
474 *   HMODULE hModule,
475 *   LPCSTR  lpProcName
476 * )
477 */
478impl Symbol {
479    fn to_function(sym: &Symbol) -> Option<Function> {
480        match sym {
481            Symbol(Library::Name(library), f) if library == "kernel32.dll" && f == "GetProcAddress" => {
482//                Some(Function::of("kernel32.dll!GetProcAddress", vec![Types::ptr, Types::ptr], vec![Types::ptr]))
483                Some(
484                    Function::of(
485                        "GetProcAddress".to_string(),
486                        vec![
487                            Parameter::of("hModule").typed(
488//                                Types::by_name("HMODULE")
489                                types::TypeSpec::Top
490                            ),
491                            Parameter::of("lpProcName").typed(
492//                                Types::by_name("LPCSTR")
493                                types::TypeSpec::Top
494                            ),
495                        ],
496                        vec![
497                            Parameter::of("proc").typed(
498//                                Types::by_name("FARPROC")
499                                types::TypeSpec::Top
500                            )
501                        ]
502                    )
503                )
504            }
505            _ => {
506                None
507            }
508        }
509    }
510}
511
512impl Display for Symbol {
513    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
514        match self.0 {
515            Library::Name(ref lib) => {
516                write!(f, "{}!{}", lib, self.1)
517            },
518            Library::This => {
519                write!(f, "{}", self.1)
520            },
521            Library::Unknown => {
522                write!(f, "<unknown>!{}", self.1)
523            }
524        }
525    }
526}
527
528#[derive(Debug)]
529pub enum BaseUpdate<T> {
530    AddDataComment(String),
531    AddCodeComment(String),
532    DefineSymbol(Symbol),
533    DefineFunction(Function),
534    Specialized(T)
535}
536
537// The type param is only to thread PartialInstructionContext through.. not a huge fan.
538pub trait OperandDefinitions<C> {
539    type Update;
540    type Dependence;
541
542    fn updates(&self, ctx: &C) -> Vec<Self::Update>;
543    fn dependencies(&self, ctx: &C) -> Vec<Self::Dependence>;
544}
545
546#[derive(Debug)]
547#[allow(non_camel_case_types)]
548pub enum Device {
549//    PIC24(pic24::CPU),
550    PIC18(pic18::cpu::CPU),
551    PIC17(pic17::cpu::CPU),
552    MSP430(msp430::cpu::CPU),
553    x86(x86_64::cpu::CPU),
554    x86_64(x86_64::cpu::CPU),
555    ARM
556}
557
558impl From<Device> for ISA {
559    fn from(d: Device) -> ISA {
560        match d {
561//            Device::PIC24(_) => { ISA::PIC24 }
562            Device::PIC18(_) => { ISA::PIC18 }
563            Device::PIC17(_) => { ISA::PIC17 }
564            Device::MSP430(_) => { ISA::MSP430 }
565            Device::x86(_) => { ISA::x86 }
566            Device::x86_64(_) => { ISA::x86_64 }
567            Device::ARM => { ISA::ARM }
568        }
569    }
570}
571
572#[derive(Debug, Copy, Clone, Deserialize, Serialize)]
573#[allow(non_camel_case_types)]
574pub enum ISA {
575    PIC17,
576    PIC18,
577    PIC18e,
578    PIC24,
579    MSP430,
580    Alpha,
581    AArch64,
582    ARC,
583    ARM,
584    Alpha64,
585    C6X,
586    Csky,
587    H8300,
588    Hexagon,
589    IA64,
590    M86k,
591    MIPS,
592    Microblaze,
593    NDS32,
594    NIOS2,
595    OpenRISC,
596    PARISC,
597    PowerPC,
598    RISCV,
599    S390,
600    SH3,
601    SH3DSP,
602    SH3E,
603    SH4,
604    SH5,
605    SPARC,
606    Tricore,
607    Unicore32,
608    Xtensa,
609    x86,
610    x86_64
611}
612
613impl ISA {
614    pub fn try_from_str(s: &str) -> Option<ISA> {
615        match s {
616            "pic17" => Some(ISA::PIC17),
617            "pic18" => Some(ISA::PIC18),
618            "pic18e" => Some(ISA::PIC18e),
619            "pic24" => Some(ISA::PIC24),
620            "msp430" => Some(ISA::MSP430),
621            "alpha" => Some(ISA::Alpha),
622            "aarch64" => Some(ISA::AArch64),
623            "arc" => Some(ISA::ARC),
624            "arm" => Some(ISA::ARM),
625            "alpha64" => Some(ISA::Alpha64),
626            "c6x" => Some(ISA::C6X),
627            "csky" => Some(ISA::Csky),
628            "h8300" => Some(ISA::H8300),
629            "hexagon" => Some(ISA::Hexagon),
630            "ia64" => Some(ISA::IA64),
631            "m86k" => Some(ISA::M86k),
632            "mips" => Some(ISA::MIPS),
633            "microblaze" => Some(ISA::Microblaze),
634            "nds32" => Some(ISA::NDS32),
635            "nios2" => Some(ISA::NIOS2),
636            "openrisc" => Some(ISA::OpenRISC),
637            "parisc" => Some(ISA::PARISC),
638            "powerpc" => Some(ISA::PowerPC),
639            "riscv" => Some(ISA::RISCV),
640            "s390" => Some(ISA::S390),
641            "sh3" => Some(ISA::SH3),
642            "sh3dsp" => Some(ISA::SH3DSP),
643            "sh3e" => Some(ISA::SH3E),
644            "sh4" => Some(ISA::SH4),
645            "sh5" => Some(ISA::SH5),
646            "sparc" => Some(ISA::SPARC),
647            "tricore" => Some(ISA::Tricore),
648            "unicore32" => Some(ISA::Unicore32),
649            "xtensa" => Some(ISA::Xtensa),
650            "x86" => Some(ISA::x86),
651            "x86_64" => Some(ISA::x86_64),
652            _ => None
653        }
654    }
655}
656
657pub struct InstructionIteratorSpanned<'a, A, M: MemoryRepr<A> + ?Sized> where
658    A: ?Sized + yaxpeax_arch::Arch + DecodeFrom<M>
659{
660    data: &'a M,
661    decoder: A::Decoder,
662    current: A::Address,
663    end: A::Address,
664    elem: Option<A::Instruction>
665}
666
667pub trait InstructionSpan<M: MemoryRepr<Self> + ?Sized> where
668    Self: yaxpeax_arch::Arch + DecodeFrom<M>
669{
670    fn instructions_spanning<'a>(data: &'a M, start: Self::Address, end: Self::Address) -> InstructionIteratorSpanned<'a, Self, M>;
671}
672
673impl<A, M: MemoryRepr<Self> + ?Sized> InstructionSpan<M> for A where
674    A: yaxpeax_arch::Arch + DecodeFrom<M>
675{
676    fn instructions_spanning<'a>(data: &'a M, start: Self::Address, end: Self::Address) -> InstructionIteratorSpanned<'a, Self, M> {
677        InstructionIteratorSpanned {
678            data,
679            decoder: Self::Decoder::default(),
680            current: start,
681            end: end,
682            elem: None
683        }
684    }
685}
686
687pub enum ControlFlowEffect<Addr> {
688    FollowingInstruction,
689    Relative(Addr),
690    Absolute(Addr),
691    Multiple(Vec<Addr>),
692    Indirect
693}
694
695pub trait ControlFlowDeterminant {
696    fn control_flow<T, Addr>(&self, _ctx: &T) -> ControlFlowEffect<Addr>;
697}
698
699trait MCU {
700    type Addr;
701    type Instruction: Default;
702    fn emulate(&mut self) -> Result<(), String>;
703    fn decode(&self) -> Result<Self::Instruction, String>;
704}
705
706// TODO: streaming_iterator crate
707pub trait SimpleStreamingIterator {
708    type Item;
709
710    fn next<'b>(&mut self) -> Option<&'b Self::Item>;
711}
712
713impl <'a, A, M> InstructionIteratorSpanned<'a, A, M> where
714    A: yaxpeax_arch::Arch + DecodeFrom<M>,
715    M: MemoryRepr<A> + MemoryRange<A> + ?Sized
716{
717    pub fn next<'b>(&mut self) -> Option<(A::Address, &A::Instruction)> {
718        if self.elem.is_some() {
719            let instr: &mut A::Instruction = self.elem.as_mut().unwrap();
720            //  TODO: check for wrappipng..
721            match Some(self.current + instr.len()) {
722                Some(next) => {
723                    if next <= self.end {
724                        self.current = next;
725                        if let Some(range) = self.data.range_from(self.current) {
726                            match A::decode_with_decoder_into(&self.decoder, &range, instr) {
727                                Ok(()) => {
728                                    Some((self.current, instr))
729                                },
730                                Err(_) => None
731                            }
732                        } else {
733//                            tracing::warn!("BUG: No data available for {}", self.current.show());
734                            None
735                        }
736                    } else {
737                        None
738                    }
739                },
740                None => None
741            }
742        } else {
743            if self.current <= self.end {
744                if let Some(range) = self.data.range_from(self.current) {
745                    self.elem = A::decode_with_decoder(&self.decoder, &range).ok();
746                    match self.elem {
747                        Some(ref instr) => {
748                            Some((self.current, &instr))
749                        },
750                        None => None
751                    }
752                } else {
753//                    tracing::warn!("BUG: No data available for {}", self.current.show());
754                    None
755                }
756            } else {
757                None
758            }
759        }
760        /*
761            None => {
762            }
763        }*/
764    }
765}
766
767impl <'a, A: yaxpeax_arch::Arch + DecodeFrom<M>, M: MemoryRepr<A> + MemoryRange<A>>
768    Iterator for InstructionIteratorSpanned<'a, A, M> where A::Instruction: Copy + Clone {
769    type Item = (A::Address, A::Instruction);
770
771    fn next(&mut self) -> Option<Self::Item> {
772        if self.elem.is_some() {
773            let instr: &mut A::Instruction = self.elem.as_mut().unwrap();
774            //  TODO: check for wrappipng..
775            match Some(self.current + instr.len()) {
776                Some(next) => {
777                    if next <= self.end {
778                        self.current = next;
779                        if let Some(range) = self.data.range_from(self.current) {
780                            match A::decode_with_decoder_into(&self.decoder, &range, instr) {
781                                Ok(()) => {
782                                    Some((self.current, *instr))
783                                },
784                                Err(_) => None
785                            }
786                        } else {
787                            //println!("BUG: No data available for {}", self.current.show());
788                            None
789                        }
790                    } else {
791                        None
792                    }
793                },
794                None => None
795            }
796        } else {
797            if self.current <= self.end {
798                if let Some(range) = self.data.range_from(self.current) {
799                    self.elem = A::decode_with_decoder(&self.decoder, &range).ok();
800                    match self.elem {
801                        Some(ref instr) => {
802                            Some((self.current, *instr))
803                        },
804                        None => None
805                    }
806                } else {
807                    //println!("BUG: No data available for {}", self.current.show());
808                    None
809                }
810            } else {
811                None
812            }
813        }
814        /*
815            None => {
816            }
817        }*/
818    }
819}