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