1pub mod arm;
2pub mod pic17;
3pub mod pic18;
4pub 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#[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
204pub 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 for (i, name) in self.f.names.arguments.iter().enumerate() {
285 if i > 0 {
286 res.push_str(", ");
287 }
288 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
367impl <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 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
472impl Symbol {
479 fn to_function(sym: &Symbol) -> Option<Function> {
480 match sym {
481 Symbol(Library::Name(library), f) if library == "kernel32.dll" && f == "GetProcAddress" => {
482Some(
484 Function::of(
485 "GetProcAddress".to_string(),
486 vec![
487 Parameter::of("hModule").typed(
488types::TypeSpec::Top
490 ),
491 Parameter::of("lpProcName").typed(
492types::TypeSpec::Top
494 ),
495 ],
496 vec![
497 Parameter::of("proc").typed(
498types::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
537pub 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 {
549PIC18(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 {
561Device::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
706pub 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 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 {
733None
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 {
753None
755 }
756 } else {
757 None
758 }
759 }
760 }
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 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 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 None
809 }
810 } else {
811 None
812 }
813 }
814 }
819}