/
main.cpp
100 lines (85 loc) · 3.23 KB
/
main.cpp
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
92
93
94
95
96
97
98
99
100
#include <befa.hpp>
using instr_type = ExecutableFile::inst_t::type;
using basic_block_type = ExecutableFile::bb_t::type;
using symbol_type = ExecutableFile::sym_t::type;
using section_type = ExecutableFile::sec_t::type;
int main(int argc, const char **argv) {
assert_ex(argc == 2, "missing path parameter");
// open file + check if file is valid
auto file = ExecutableFile::open(*(argv + 1));
assert_ex(file.isValid(), "file is not valid");
auto sym_table_symbols = file.generate_table();
file.disassembly()
.reduce(
// default last basic block, symbol, section
std::make_tuple((bfd_vma)-1, std::string(""), std::string("")),
[&sym_table_symbols](
std::tuple<bfd_vma, std::string, std::string> acc,
const instr_type &instruction
) {
auto bb = instruction.getParent();
auto sym = ptr_lock(bb->getParent());
auto sec = ptr_lock(sym->getParent());
auto last_sec = sec->getName();
auto last_sym = sym->getName();
auto last_bb = bb->getId();
if (std::get<2>(acc) != last_sec) {
printf("%s <0x%08lx>:\n",
sec->getName().c_str(),
sec->getAddress()
);
}
if (std::get<1>(acc) != last_sym) {
printf(" %s <0x%08lx>:\n",
sym->getName().c_str(),
sym->getAddress()
);
}
if (std::get<0>(acc) != last_bb) {
printf(" BasicBlock #%lu <0x%08lx>:\n",
bb->getId(),
instruction.getAddress()
);
}
// iterate through arguments of instruction
instruction
.getArgs(sym_table_symbols)
// convert to string
.map([](
auto arg
) {
return map_visitable<symbol_table::SymbolVisitorL>(
arg, [](const symbol_table::Symbol *ptr)
{ return ptr->getName(); });
})
// filter out empty (non-symbol stuff)
.filter([](
std::string name
) -> bool { return name != ""; })
// string join achieved by reduction
.reduce(std::string(""), [](
auto seed, auto b
) {
return seed == "" ? b : seed + ", " + b;
})
// print instruction
.subscribe([&instruction](
auto str_params
) {
printf(" <%08lx> %s %s\n",
instruction.getAddress(),
instruction.getName().c_str(),
str_params.c_str());
});
std::get<2>(acc) = last_sec;
std::get<1>(acc) = last_sym;
std::get<0>(acc) = last_bb;
return acc;
}
)
// we don't care about result of reduction
// cause all is in console
.subscribe([](const auto &) {});
file.runDisassembler();
return 0;
}