1#include <featureTests.h>
2#ifdef ROSE_ENABLE_BINARY_ANALYSIS
5#include <Rose/BinaryAnalysis/Architecture/Base.h>
7#include "virtualBinCFG.h"
11namespace VirtualBinCFG {
13 string CFGNode::toString()
const {
14 if (isSgAsmFunction(node)) {
15 return "BinaryFunctionDefinition";
20 string CFGNode::toStringForDebugging()
const {
23 s <<
"End of procedure";
30 string CFGNode::id()
const {
32 s <<
"n_" << hex << uintptr_t(node) <<
"_" << dec ;
36 string CFGEdge::toString()
const {
37 return toStringForDebugging();
40 string CFGEdge::toStringForDebugging()
const {
43 bool anyNonEmpty =
false;
44 EdgeConditionKind cond = condition();
45 if (cond != eckUnconditional) {
46 if (anyNonEmpty) s <<
" ";
71 string CFGEdge::id()
const {
73 s << src.id() <<
"__" << tgt.id();
78 EdgeConditionKind CFGEdge::condition()
const {
81 unsigned int srcIndex = src.getIndex();
83 unsigned int tgtIndex = tgt.getIndex();
84 if (isSgAsmMov(srcNode) ) {
85 SgAsmMov* ifs = isSgAsmMov(srcNode);
87 if (ifs->get_true_body() == tgtNode) {
89 }
else if (ifs->get_false_body() == tgtNode) {
91 }
else ROSE_ASSERT (!
"Bad successor in if statement");
95 else if (isSgWhileStmt(srcNode) && srcIndex == 1) {
96 if (srcNode == tgtNode) {
102 }
else if (isSgDoWhileStmt(srcNode) && srcIndex == 2) {
109 }
else if (isSgForStatement(srcNode) && srcIndex == 2) {
110 if (srcNode == tgtNode) {
116 }
else if (isSgSwitchStatement(srcNode) && isSgCaseOptionStmt(tgtNode)) {
118 }
else if (isSgSwitchStatement(srcNode) && isSgDefaultOptionStmt(tgtNode)){
120 }
else if (isSgConditionalExp(srcNode) && srcIndex == 1) {
126 }
else ROSE_ASSERT (!
"Bad successor in conditional expression");
127 }
else if (isSgAndOp(srcNode) && srcIndex == 1) {
128 if (srcNode == tgtNode) {
134 }
else if (isSgOrOp(srcNode) && srcIndex == 1) {
135 if (srcNode == tgtNode) {
145 return eckUnconditional;
157 unsigned int fromIndex = from.getIndex();
159 unsigned int toIndex = to.getIndex();
162 if (fromIndex == 1 && (isSgGotoStatement(fromNode) || isSgBreakStmt(fromNode) || isSgContinueStmt(fromNode))) {
165 if (isSgReturnStmt(fromNode) && toNode == fromNode->
get_parent()) {
167 if (fromIndex == 1 || fromIndex == 0 && !rs->get_expression())
return;
169 if (fromIndex == 1 && isSgSwitchStatement(fromNode) &&
170 isSgSwitchStatement(fromNode)->get_body() == toNode)
return;
174 result.push_back(CFGEdge(CFGNode(from, info), CFGNode(to, info), info));
177#ifndef ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT
178 vector<CFGEdge> CFGNode::outEdges()
const {
179 ASSERT_not_reachable(
"no longer supported");
182 vector<CFGEdge> CFGNode::inEdges()
const {
183 ASSERT_not_reachable(
"no longer supported");
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) {
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()) {
197 return retIter->second;
199 }
else if (succsIter == indirectJumpTargets.end()) {
203 return succsIter->second;
207 AuxiliaryInformation::AuxiliaryInformation(
SgNode* top)
208 : addressToInstructionMap(), indirectJumpTargets(), returnTargets(), incomingEdges()
212 AuxiliaryInformation* info;
213 AuxInfoTraversal(AuxiliaryInformation* info): info(info) {}
217 info->addressToInstructionMap[insn->
get_address()] = insn;
222 AuxiliaryInformation* info;
223 AuxInfoTraversal2(AuxiliaryInformation* info): info(info) {}
227 if (insn->
get_kind() != Rose::BinaryAnalysis::x86_call)
return;
229 uint64_t tgtAddr = 0;
230 if (!insn->
architecture()->branchTarget(insn).assignTo(tgtAddr))
237 while (f && !isSgAsmBlock(f) && !isSgAsmFunction(f)) f = f->
get_parent();
241 info->returnTargets[isSgAsmStatement(f)].insert(next);
246 AuxiliaryInformation* info;
247 AuxInfoTraversal3(AuxiliaryInformation* info): info(info) {}
252#ifndef ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT
253 ASSERT_not_reachable(
"no longer supported");
255 printf (
"This function is not supported in the ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT mode.\n");
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);
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).