ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
virtualBinCFG.C
Go to the documentation of this file.
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  ROSE_ASSERT (node);
176  return node->cfgBinOutEdges(info);
177  }
178 
179  vector<CFGEdge> CFGNode::inEdges() const {
180  ROSE_ASSERT (node);
181  return node->cfgBinInEdges(info);
182  }
183 #endif
184 
185  const std::set<uint64_t>& AuxiliaryInformation::getPossibleSuccessors(SgAsmInstruction* insn) const {
186  static const std::set<uint64_t> emptySet;
187  std::map<SgAsmInstruction*, std::set<uint64_t> >::const_iterator succsIter = indirectJumpTargets.find(insn);
188  if (isSgAsmx86Instruction(insn) && isSgAsmx86Instruction(insn)->get_kind() == x86_ret) {
189  SgNode* f = insn;
190  while (f && !isSgAsmBlock(f) && !isSgAsmFunction(f)) f = f->get_parent();
191  std::map<SgAsmStatement*, std::set<uint64_t> >::const_iterator retIter = returnTargets.find(isSgAsmStatement(f));
192  if (retIter == returnTargets.end()) {
193  return emptySet;
194  } else {
195  return retIter->second;
196  }
197  } else if (succsIter == indirectJumpTargets.end()) {
198  return emptySet;
199  } else {
200  // rose translator has trouble in unparsing it correctly.
201  return succsIter->second;
202  }
203  }
204 
205  AuxiliaryInformation::AuxiliaryInformation(SgNode* top)
206  : addressToInstructionMap(), indirectJumpTargets(), returnTargets(), incomingEdges()
207  {
208 
209  struct AuxInfoTraversal: public AstSimpleProcessing {
210  AuxiliaryInformation* info;
211  AuxInfoTraversal(AuxiliaryInformation* info): info(info) {}
212  virtual void visit(SgNode* n) {
214  if (!insn) return;
215  info->addressToInstructionMap[insn->get_address()] = insn;
216  }
217  };
218 
219  struct AuxInfoTraversal2: public AstSimpleProcessing {
220  AuxiliaryInformation* info;
221  AuxInfoTraversal2(AuxiliaryInformation* info): info(info) {}
222  virtual void visit(SgNode* n) {
224  if (!insn) return;
225  if (insn->get_kind() != x86_call) return;
226  //cerr << "Found call xxx at " << hex << insn->get_address() << endl;
227  uint64_t tgtAddr;
228  if (!insn->get_branch_target(&tgtAddr)) 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) {
248  if (!insn) return;
249 #ifndef ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT
250  vector<CFGEdge> outEdgesSoFar = insn->cfgBinOutEdges(info);
251  for (size_t i = 0; i < outEdgesSoFar.size(); ++i) {
252  info->incomingEdges[outEdgesSoFar[i].target().getNode()].insert(insn->get_address());
253  }
254 #else
255  printf ("This function is not supported in the ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT mode.\n");
256  ROSE_ASSERT(false);
257 #endif
258  }
259  };
260 
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);
267  }
268 }