-
Notifications
You must be signed in to change notification settings - Fork 1
/
MemEval.C
172 lines (153 loc) · 5.94 KB
/
MemEval.C
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include "rose.h"
#include "DwarfLineMapper.h"
#include "Partitioner2/Engine.h"
#include "Disassembler.h"
#include <boost/units/detail/utility.hpp>
#include <iostream>
#include <string>
#include "DispatcherX86.h"
#include "MiraSemantics.h"
using namespace std;
using namespace Rose;
using namespace Rose::BinaryAnalysis::InstructionSemantics2;
typedef boost::unordered_map<int, std::vector<SgAsmInstruction*> > instrMap;
int main(int argc, char** argv)
{
/*
* commandline format
* app binary_path source_path
*/
// check command
if (argc != 3)
{
cout << "invalid command" << endl;
exit(EXIT_FAILURE);
}
// generate binary project
vector<string> binInput;
binInput.push_back(string(argv[0]));
binInput.push_back(string(argv[1]));
SgProject* binProj = new SgProject(binInput);
// generate source project
vector<string> srcInput;
srcInput.push_back(string(argv[0]));
srcInput.push_back(string(argv[2]));
SgProject* srcProj = new SgProject(srcInput);
// get DWARF mapping
BinaryAnalysis::DwarfLineMapper lineMap = BinaryAnalysis::DwarfLineMapper(binProj);
// adjust mapping distance
lineMap.fix_holes(1000);
vector<SgAsmFunction*> asmFunction = SageInterface::querySubTree<SgAsmFunction>(binProj);
if (asmFunction.empty())
{
cout << "no binary interpretations found" << endl;
exit(EXIT_FAILURE);
}
// vector of vector for storing instructions of each loop
vector< vector<SgAsmInstruction*> > loopVec;
// map to store loop info
boost::unordered_map<int, std::pair<int, int> > loopMap;
// process source code
// locate loops in source
vector<SgForStatement*> forStatVec = SageInterface::querySubTree<SgForStatement>(srcProj);
for (vector<SgForStatement*>::iterator it = forStatVec.begin(); it != forStatVec.end(); it++)
{
SgForStatement* forStat = (*it);
// get line number for the loop head
int loopHead = forStat -> get_file_info() -> get_line();
SgStatement* body = forStat -> get_loop_body();
// get line numbers for the first/last statement inside loop
SgStatement* first = SageInterface::getFirstStatement((SgScopeStatement*)body);
SgStatement* last = SageInterface::getLastStatement((SgScopeStatement*)body);
int firstLine = first -> get_file_info() -> get_line();
int lastLine = last -> get_file_info() -> get_line();
loopMap.insert(make_pair(loopHead, make_pair(firstLine, lastLine)));
}
#if 0
// test loopMap
for (boost::unordered_map<int, std::pair<int,int> >::iterator mit = loopMap.begin(); mit != loopMap.end(); mit++)
{
cout << "map head: " << mit -> first << "map first: " << (mit -> second).first << "map last: " << (mit -> second) .second << endl;
}
#endif
instrMap* im = new instrMap();
int firstLine = -1;
int lastLine = -1;
// use map to indicate whether this loop head is processed
boost::unordered_map<int, int> loopFlag;
for (vector<SgAsmFunction*>::iterator it = asmFunction.begin(); it != asmFunction.end(); it++)
{
string funcName = (*it) -> get_name();
string demangleName = boost::units::detail::demangle(funcName.c_str());
if (demangleName != "demangle :: error - unable to demangle specified symbol" || funcName == "main")
{
BinaryAnalysis::DwarfLineMapper ln = BinaryAnalysis::DwarfLineMapper(*it);
// retrieve instructions from asm statements
vector<SgAsmInstruction*> asmInstr = SageInterface::querySubTree<SgAsmInstruction>(*it);
// store instructions by line number
for (vector<SgAsmInstruction*>::iterator ins = asmInstr.begin(); ins != asmInstr.end(); ins++)
{
BinaryAnalysis::DwarfLineMapper::SrcInfo srcInfo = lineMap.addr2src((*ins) -> get_address());
int lineNum = srcInfo.line_num;
// here each instructions is mapped to corresponding line number
// currently not in use
// check if line number already exists in the map
if (im -> find(lineNum) == im -> end())
{
// line number doesn't exist
vector<SgAsmInstruction*> inV;
inV.push_back(*ins);
im -> insert(make_pair(lineNum, inV));
}else {
// line number doesn't exit
(im -> find(lineNum) -> second).push_back(*ins);
}
// currently not in use ends
#if 0
// test
cout<<"Instruction " << ((SgAsmX86Instruction*)(*ins)) -> get_kind()<< " base size "<<((SgAsmX86Instruction*)(*ins)) -> get_size() << " operand size "<<((SgAsmX86Instruction*)(*ins)) -> get_operandSize()<< " " << (*ins)->get_mnemonic()<<" line "<< lineMap.addr2src((*ins)->get_address()).line_num <<" size "<< (*ins) -> get_size()<<endl;
#endif
// go through the instructions from Binary file
// find instructions belong to loops
if(loopMap.find(lineNum) != loopMap.end())
{
// find loop head
if (loopFlag.find(lineNum) == loopFlag.end())
{
// first time to process this loop head line
// loop head initialization
firstLine = loopMap[lineNum].first;
lastLine = loopMap[lineNum].second;
vector<SgAsmInstruction*> inst;
inst.push_back(*ins);
loopVec.push_back(inst);
// update loopFlag
loopFlag.insert(make_pair(lineNum, 1));
}else{
// loop head is separated by loop body
// add the loop comparison part
loopVec.back().push_back(*ins);
}
}
if(lineNum >= firstLine && lineNum <= lastLine)
{
loopVec.back().push_back(*ins);
}
}
}
}
const RegisterDictionary* regdict = RegisterDictionary::dictionary_amd64();
BaseSemantics::RiscOperatorsPtr operators = MiraRiscOperators::instance(regdict);
BaseSemantics::DispatcherPtr dispatcher = DispatcherX86::instance(operators, 64);
for(vector< vector<SgAsmInstruction*> >::iterator it = loopVec.begin(); it != loopVec.end(); it++) {
vector<SgAsmInstruction*> instrVec = (*it);
// instructions for one loop
for (vector<SgAsmInstruction*>::iterator iit = instrVec.begin(); iit != instrVec.end(); iit++)
{
cout << "instruction: "<< (*iit) -> get_mnemonic() << endl;
dispatcher -> processInstruction(*iit);
}
cout << "---------------------------------------------------" << endl;
}
delete im;
}