ROSE  0.11.2.0
virtualBinCFG.C
1 #include <rosePublicConfig.h>
2 #ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT
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;
227  if (!insn->getBranchTarget(&tgtAddr)) return;
228  //cerr << "Found call at " << hex << insn->get_address() << " with known target " << hex << tgtAddr << endl;
229  SgAsmInstruction* tgt = info->getInstructionAtAddress(tgtAddr);
230  if (!tgt) return;
231  //cerr << "Found target insn" << endl;
232  SgNode* f = tgt;
233  while (f && !isSgAsmBlock(f) && !isSgAsmFunction(f)) f = f->get_parent();
234  if (!f) return;
235  //cerr << "Found function of target" << endl;
236  uint64_t next = insn->get_address() + insn->get_raw_bytes().size();
237  info->returnTargets[isSgAsmStatement(f)].insert(next);
238  }
239  };
240 
241  struct AuxInfoTraversal3: public AstSimpleProcessing {
242  AuxiliaryInformation* info;
243  AuxInfoTraversal3(AuxiliaryInformation* info): info(info) {}
244 
245  virtual void visit(SgNode* n) {
246  SgAsmInstruction* insn = isSgAsmInstruction(n);
247  if (!insn) return;
248 #ifndef ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT
249  ASSERT_not_reachable("no longer supported");
250 #else
251  printf ("This function is not supported in the ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT mode.\n");
252  ROSE_ASSERT(false);
253 #endif
254  }
255  };
256 
257  AuxInfoTraversal trav(this);
258  trav.traverse(top, preorder);
259  AuxInfoTraversal2 trav2(this);
260  trav2.traverse(top, preorder);
261  AuxInfoTraversal3 trav3(this);
262  trav3.traverse(top, preorder);
263  }
264 }
265 
266 #endif
Base class for all binary analysis IR nodes.
Class for traversing the AST.
Base class for machine instructions.
STL namespace.
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.
Definition: Cxx_Grammar.h:9311
const SgUnsignedList & get_raw_bytes() const
Property: Raw bytes of an instruction.
Represents one Intel x86 machine instruction.
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 bool getBranchTarget(rose_addr_t *target)
Obtains the virtual address for a branching instruction.