1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use termion::color;
use yaxpeax_arch::Arch;
use yaxpeax_arch::ShowContextual;
use yaxpeax_arch::YaxColors;
use yaxpeax_pic17::PIC17;
use yaxpeax_pic17::{Opcode, Operand, Instruction};
use arch::pic17::MergedContextTable;
use ContextRead;
use std::fmt;
impl <T: fmt::Write, Y: YaxColors> ShowContextual<u16, MergedContextTable, T, Y> for Instruction {
fn contextualize(&self, colors: &Y, address: <PIC17 as Arch>::Address, context: Option<&MergedContextTable>, out: &mut T) -> fmt::Result {
let operand_replacements: Option<[Option<String>; 2]> = match context {
Some(context) => {
use analyses::control_flow;
use analyses::control_flow::Determinant;
let mut operand_replacements: [Option<String>; 2] = [None, None];
fn render_function(address: <PIC17 as Arch>::Address ) -> String {
format!("#{:08x}", address)
}
fn contextualize_operand(operand: &Operand, address: <PIC17 as Arch>::Address, context: Option<&MergedContextTable>) -> Option<String> {
match operand {
Operand::File(f) => {
let name = ::arch::pic17::cpu::try_debank(*f, context.map(|x| x.at(&address)).as_ref())
.map(|num| ::arch::pic17::named_file(num).to_string());
name.map(|name| {
format!("{}{}{}", color::Fg(color::Yellow), name, color::Fg(color::Reset))
})
},
_ => {
None
}
}
}
match self.opcode {
Opcode::LCALL => {
let control_flow = self.control_flow(Some(&context.at(&address)));
match control_flow.dest {
Some(control_flow::Target::Absolute(addr)) => {
operand_replacements[0] = Some(render_function(addr * 2));
}
_ => { }
}
},
Opcode::CALL |
Opcode::GOTO => {
match self.operands[0] {
Operand::ImmediateU32(i) => {
operand_replacements[0] = Some(render_function((i as u16) * 2));
},
_ => { unreachable!() }
}
},
_ => {
match &self.operands[0] {
Operand::Nothing => { },
x @ _ => { operand_replacements[0] = contextualize_operand(x, address, Some(context)) }
};
match &self.operands[0] {
Operand::Nothing => { },
x @ _ => { operand_replacements[0] = contextualize_operand(x, address, Some(context)) }
};
}
};
Some(operand_replacements)
}
None => {
None
}
};
let reffified: Option<&[Option<String>]> = operand_replacements.as_ref().map(|x| &x[..]);
self.contextualize(colors, address, reffified, out)
}
}