ROSE 0.11.145.147
virtualBinCFG.C
1#include <featureTests.h>
2#ifdef ROSE_ENABLE_BINARY_ANALYSIS
3#include <sage3basic.h>
4
5#include <Rose/BinaryAnalysis/Architecture/Base.h>
6
7#include "virtualBinCFG.h"
8
9using namespace std;
10
11namespace VirtualBinCFG {
12
13 string CFGNode::toString() const {
14 if (isSgAsmFunction(node)) {
15 return "BinaryFunctionDefinition";
16 }
17 return "";
18 }
19
20 string CFGNode::toStringForDebugging() const {
21 ostringstream s;
22 if (node == NULL) {
23 s << "End of procedure";
24 } else {
25 string nodeText;
26 }
27 return s.str();
28 }
29
30 string CFGNode::id() const {
31 ostringstream s;
32 s << "n_" << hex << uintptr_t(node) << "_" << dec ;
33 return s.str();
34 }
35
36 string CFGEdge::toString() const {
37 return toStringForDebugging();
38 }
39
40 string CFGEdge::toStringForDebugging() const {
41 ostringstream s;
42 // s << src.id() << " -> " << tgt.id();
43 bool anyNonEmpty = false;
44 EdgeConditionKind cond = condition();
45 if (cond != eckUnconditional) {
46 if (anyNonEmpty) s << " "; // For consistency
47 s << "key(";
48 switch (cond) {
49 case eckTrue:
50 s << "true";
51 break;
52 case eckFalse:
53 s << "false";
54 break;
55 case eckCaseLabel:
56 // s << caseLabel()->unparseToString();
57 break;
58 case eckDefault:
59 s << "default";
60 break;
61 default:
62 s << "unknown";
63 break;
64 }
65 s << ")";
66 anyNonEmpty = true;
67 }
68 return s.str();
69 }
70
71 string CFGEdge::id() const {
72 ostringstream s;
73 s << src.id() << "__" << tgt.id();
74 return s.str();
75 }
76
77
78 EdgeConditionKind CFGEdge::condition() const {
79#if 0
80 SgAsmNode* srcNode = src.getNode();
81 unsigned int srcIndex = src.getIndex();
82 SgAsmNode* tgtNode = tgt.getNode();
83 unsigned int tgtIndex = tgt.getIndex();
84 if (isSgAsmMov(srcNode) ) {
85 SgAsmMov* ifs = isSgAsmMov(srcNode);
86#if 0
87 if (ifs->get_true_body() == tgtNode) {
88 return eckTrue;
89 } else if (ifs->get_false_body() == tgtNode) {
90 return eckFalse;
91 } else ROSE_ASSERT (!"Bad successor in if statement");
92#endif
93 }
94#if 0
95 else if (isSgWhileStmt(srcNode) && srcIndex == 1) {
96 if (srcNode == tgtNode) {
97 // False case for while test
98 return eckFalse;
99 } else {
100 return eckTrue;
101 }
102 } else if (isSgDoWhileStmt(srcNode) && srcIndex == 2) {
103 // tgtIndex values are 0 for true branch and 3 for false branch
104 if (tgtIndex == 0) {
105 return eckTrue;
106 } else {
107 return eckFalse;
108 }
109 } else if (isSgForStatement(srcNode) && srcIndex == 2) {
110 if (srcNode == tgtNode) {
111 // False case for test
112 return eckFalse;
113 } else {
114 return eckTrue;
115 }
116 } else if (isSgSwitchStatement(srcNode) && isSgCaseOptionStmt(tgtNode)) {
117 return eckCaseLabel;
118 } else if (isSgSwitchStatement(srcNode) && isSgDefaultOptionStmt(tgtNode)){
119 return eckDefault;
120 } else if (isSgConditionalExp(srcNode) && srcIndex == 1) {
121 SgConditionalExp* ce = isSgConditionalExp(srcNode);
122 if (ce->get_true_exp() == tgtNode) {
123 return eckTrue;
124 } else if (ce->get_false_exp() == tgtNode) {
125 return eckFalse;
126 } else ROSE_ASSERT (!"Bad successor in conditional expression");
127 } else if (isSgAndOp(srcNode) && srcIndex == 1) {
128 if (srcNode == tgtNode) {
129 // Short-circuited false case
130 return eckFalse;
131 } else {
132 return eckTrue;
133 }
134 } else if (isSgOrOp(srcNode) && srcIndex == 1) {
135 if (srcNode == tgtNode) {
136 // Short-circuited true case
137 return eckTrue;
138 } else {
139 return eckFalse;
140 }
141 }
142#endif
143 else {
144 // No key
145 return eckUnconditional;
146 }
147#else
148 // DQ (11/28/2009): This function was already commented out, but must return a value for use in MSVC.
149 return eckFalse;
150#endif
151 }
152
154 void makeEdge(SgAsmInstruction* from, SgAsmInstruction* to, const AuxiliaryInformation* info, vector<CFGEdge>& result) {
155#if 0
156 SgAsmNode* fromNode = from.getNode();
157 unsigned int fromIndex = from.getIndex();
158 SgAsmNode* toNode = to.getNode();
159 unsigned int toIndex = to.getIndex();
160#if 0
161 // Exit early if the edge should not exist because of a control flow discontinuity
162 if (fromIndex == 1 && (isSgGotoStatement(fromNode) || isSgBreakStmt(fromNode) || isSgContinueStmt(fromNode))) {
163 return;
164 }
165 if (isSgReturnStmt(fromNode) && toNode == fromNode->get_parent()) {
166 SgReturnStmt* rs = isSgReturnStmt(fromNode);
167 if (fromIndex == 1 || fromIndex == 0 && !rs->get_expression()) return;
168 }
169 if (fromIndex == 1 && isSgSwitchStatement(fromNode) &&
170 isSgSwitchStatement(fromNode)->get_body() == toNode) return;
171#endif
172#endif
173 // Create the edge
174 result.push_back(CFGEdge(CFGNode(from, info), CFGNode(to, info), info));
175 }
176
177#ifndef ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT
178 vector<CFGEdge> CFGNode::outEdges() const {
179 ASSERT_not_reachable("no longer supported");
180 }
181
182 vector<CFGEdge> CFGNode::inEdges() const {
183 ASSERT_not_reachable("no longer supported");
184 }
185#endif
186
187 const std::set<uint64_t>& AuxiliaryInformation::getPossibleSuccessors(SgAsmInstruction* insn) const {
188 static const std::set<uint64_t> emptySet;
189 std::map<SgAsmInstruction*, std::set<uint64_t> >::const_iterator succsIter = indirectJumpTargets.find(insn);
190 if (isSgAsmX86Instruction(insn) && isSgAsmX86Instruction(insn)->get_kind() == Rose::BinaryAnalysis::x86_ret) {
191 SgNode* f = insn;
192 while (f && !isSgAsmBlock(f) && !isSgAsmFunction(f)) f = f->get_parent();
193 std::map<SgAsmStatement*, std::set<uint64_t> >::const_iterator retIter = returnTargets.find(isSgAsmStatement(f));
194 if (retIter == returnTargets.end()) {
195 return emptySet;
196 } else {
197 return retIter->second;
198 }
199 } else if (succsIter == indirectJumpTargets.end()) {
200 return emptySet;
201 } else {
202 // rose translator has trouble in unparsing it correctly.
203 return succsIter->second;
204 }
205 }
206
207 AuxiliaryInformation::AuxiliaryInformation(SgNode* top)
208 : addressToInstructionMap(), indirectJumpTargets(), returnTargets(), incomingEdges()
209 {
210
211 struct AuxInfoTraversal: public AstSimpleProcessing {
212 AuxiliaryInformation* info;
213 AuxInfoTraversal(AuxiliaryInformation* info): info(info) {}
214 virtual void visit(SgNode* n) {
215 SgAsmInstruction* insn = isSgAsmInstruction(n);
216 if (!insn) return;
217 info->addressToInstructionMap[insn->get_address()] = insn;
218 }
219 };
220
221 struct AuxInfoTraversal2: public AstSimpleProcessing {
222 AuxiliaryInformation* info;
223 AuxInfoTraversal2(AuxiliaryInformation* info): info(info) {}
224 virtual void visit(SgNode* n) {
225 SgAsmX86Instruction* insn = isSgAsmX86Instruction(n);
226 if (!insn) return;
227 if (insn->get_kind() != Rose::BinaryAnalysis::x86_call) return;
228 //cerr << "Found call xxx at " << hex << insn->get_address() << endl;
229 uint64_t tgtAddr = 0;
230 if (!insn->architecture()->branchTarget(insn).assignTo(tgtAddr))
231 return;
232 //cerr << "Found call at " << hex << insn->get_address() << " with known target " << hex << tgtAddr << endl;
233 SgAsmInstruction* tgt = info->getInstructionAtAddress(tgtAddr);
234 if (!tgt) return;
235 //cerr << "Found target insn" << endl;
236 SgNode* f = tgt;
237 while (f && !isSgAsmBlock(f) && !isSgAsmFunction(f)) f = f->get_parent();
238 if (!f) return;
239 //cerr << "Found function of target" << endl;
240 uint64_t next = insn->get_address() + insn->get_rawBytes().size();
241 info->returnTargets[isSgAsmStatement(f)].insert(next);
242 }
243 };
244
245 struct AuxInfoTraversal3: public AstSimpleProcessing {
246 AuxiliaryInformation* info;
247 AuxInfoTraversal3(AuxiliaryInformation* info): info(info) {}
248
249 virtual void visit(SgNode* n) {
250 SgAsmInstruction* insn = isSgAsmInstruction(n);
251 if (!insn) return;
252#ifndef ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT
253 ASSERT_not_reachable("no longer supported");
254#else
255 printf ("This function is not supported in the ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT mode.\n");
256 ROSE_ABORT();
257#endif
258 }
259 };
260
261 AuxInfoTraversal trav(this);
262 trav.traverse(top, preorder);
263 AuxInfoTraversal2 trav2(this);
264 trav2.traverse(top, preorder);
265 AuxInfoTraversal3 trav3(this);
266 trav3.traverse(top, preorder);
267 }
268}
269
270#endif
Class for traversing the AST.
virtual void visit(SgNode *astNode)=0
this method is called at every traversed node.
Base class for machine instructions.
Rose::BinaryAnalysis::Architecture::BaseConstPtr architecture() const
Architecture for instruction.
SgUnsignedCharList const & get_rawBytes() const
Property: Raw bytes of an instruction.
Base class for all binary analysis IR nodes.
rose_addr_t const & get_address() const
Property: Starting virtual address.
Represents one Intel x86 machine instruction.
Rose::BinaryAnalysis::X86InstructionKind const & get_kind() const
Property: Instruction kind.
This class represents the concept of a C trinary conditional expression (e.g. "test ?...
SgExpression * get_true_exp() const
Access function for p_true_exp.
SgExpression * get_false_exp() const
Access function for p_false_exp.
This class represents the base class for all IR nodes within Sage III.
SgNode * get_parent() const
Access function for parent node.
This class represents the concept of a C Assembler statement (untested).