1 #include <featureTests.h>
2 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
3 #include "sage3basic.h"
4 #include "virtualBinCFG.h"
10 string CFGNode::toString()
const {
11 if (isSgAsmFunction(node)) {
12 return "BinaryFunctionDefinition";
17 string CFGNode::toStringForDebugging()
const {
20 s <<
"End of procedure";
27 string CFGNode::id()
const {
29 s <<
"n_" << hex << uintptr_t(node) <<
"_" << dec ;
33 string CFGEdge::toString()
const {
34 return toStringForDebugging();
37 string CFGEdge::toStringForDebugging()
const {
40 bool anyNonEmpty =
false;
41 EdgeConditionKind cond = condition();
42 if (cond != eckUnconditional) {
43 if (anyNonEmpty) s <<
" ";
68 string CFGEdge::id()
const {
70 s << src.id() <<
"__" << tgt.id();
75 EdgeConditionKind CFGEdge::condition()
const {
78 unsigned int srcIndex = src.getIndex();
80 unsigned int tgtIndex = tgt.getIndex();
81 if (isSgAsmMov(srcNode) ) {
82 SgAsmMov* ifs = isSgAsmMov(srcNode);
84 if (ifs->get_true_body() == tgtNode) {
86 }
else if (ifs->get_false_body() == tgtNode) {
88 }
else ROSE_ASSERT (!
"Bad successor in if statement");
92 else if (isSgWhileStmt(srcNode) && srcIndex == 1) {
93 if (srcNode == tgtNode) {
99 }
else if (isSgDoWhileStmt(srcNode) && srcIndex == 2) {
106 }
else if (isSgForStatement(srcNode) && srcIndex == 2) {
107 if (srcNode == tgtNode) {
113 }
else if (isSgSwitchStatement(srcNode) && isSgCaseOptionStmt(tgtNode)) {
115 }
else if (isSgSwitchStatement(srcNode) && isSgDefaultOptionStmt(tgtNode)){
117 }
else if (isSgConditionalExp(srcNode) && srcIndex == 1) {
123 }
else ROSE_ASSERT (!
"Bad successor in conditional expression");
124 }
else if (isSgAndOp(srcNode) && srcIndex == 1) {
125 if (srcNode == tgtNode) {
131 }
else if (isSgOrOp(srcNode) && srcIndex == 1) {
132 if (srcNode == tgtNode) {
142 return eckUnconditional;
154 unsigned int fromIndex = from.getIndex();
156 unsigned int toIndex = to.getIndex();
159 if (fromIndex == 1 && (isSgGotoStatement(fromNode) || isSgBreakStmt(fromNode) || isSgContinueStmt(fromNode))) {
162 if (isSgReturnStmt(fromNode) && toNode == fromNode->
get_parent()) {
164 if (fromIndex == 1 || fromIndex == 0 && !rs->get_expression())
return;
166 if (fromIndex == 1 && isSgSwitchStatement(fromNode) &&
167 isSgSwitchStatement(fromNode)->
get_body() == toNode)
return;
171 result.push_back(CFGEdge(CFGNode(from, info), CFGNode(to, info), info));
174 #ifndef ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT
175 vector<CFGEdge> CFGNode::outEdges()
const {
176 ASSERT_not_reachable(
"no longer supported");
179 vector<CFGEdge> CFGNode::inEdges()
const {
180 ASSERT_not_reachable(
"no longer supported");
184 const std::set<uint64_t>& AuxiliaryInformation::getPossibleSuccessors(
SgAsmInstruction* insn)
const {
185 static const std::set<uint64_t> emptySet;
186 std::map<SgAsmInstruction*, std::set<uint64_t> >::const_iterator succsIter = indirectJumpTargets.find(insn);
187 if (isSgAsmX86Instruction(insn) && isSgAsmX86Instruction(insn)->get_kind() == Rose::BinaryAnalysis::x86_ret) {
189 while (f && !isSgAsmBlock(f) && !isSgAsmFunction(f)) f = f->
get_parent();
190 std::map<SgAsmStatement*, std::set<uint64_t> >::const_iterator retIter = returnTargets.find(isSgAsmStatement(f));
191 if (retIter == returnTargets.end()) {
194 return retIter->second;
196 }
else if (succsIter == indirectJumpTargets.end()) {
200 return succsIter->second;
204 AuxiliaryInformation::AuxiliaryInformation(
SgNode* top)
205 : addressToInstructionMap(), indirectJumpTargets(), returnTargets(), incomingEdges()
209 AuxiliaryInformation* info;
210 AuxInfoTraversal(AuxiliaryInformation* info): info(info) {}
211 virtual void visit(
SgNode* n) {
214 info->addressToInstructionMap[insn->
get_address()] = insn;
219 AuxiliaryInformation* info;
220 AuxInfoTraversal2(AuxiliaryInformation* info): info(info) {}
221 virtual void visit(
SgNode* n) {
224 if (insn->
get_kind() != Rose::BinaryAnalysis::x86_call)
return;
226 uint64_t tgtAddr = 0;
234 while (f && !isSgAsmBlock(f) && !isSgAsmFunction(f)) f = f->
get_parent();
238 info->returnTargets[isSgAsmStatement(f)].insert(next);
243 AuxiliaryInformation* info;
244 AuxInfoTraversal3(AuxiliaryInformation* info): info(info) {}
246 virtual void visit(
SgNode* n) {
249 #ifndef ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT
250 ASSERT_not_reachable(
"no longer supported");
252 printf (
"This function is not supported in the ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT mode.\n");
258 AuxInfoTraversal trav(
this);
259 trav.traverse(top, preorder);
260 AuxInfoTraversal2 trav2(
this);
261 trav2.traverse(top, preorder);
262 AuxInfoTraversal3 trav3(
this);
263 trav3.traverse(top, preorder);
Base class for all binary analysis IR nodes.
Class for traversing the AST.
Base class for machine instructions.
This class represents the concept of a C Assembler statement (untested).
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.
const SgUnsignedList & get_raw_bytes() const
Property: Raw bytes of an instruction.
Represents one Intel x86 machine instruction.
bool assignTo(U &out) const
Conditionally save a value.
SgStatement * get_body() const
Access function for p_body.
SgNode * get_parent() const
Access function for parent node.
Rose::BinaryAnalysis::X86InstructionKind get_kind() const
Property: Instruction kind.
rose_addr_t get_address() const
Property: Starting virtual address.
virtual Sawyer::Optional< rose_addr_t > branchTarget() override
Obtains the virtual address for a branching instruction.