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