ClearBlue
SymbolicExprGraphSolver.h
1 /*
2  * Developed by Qingkai Shi
3  * Copy Right by Prism Research Group, HKUST and State Key Lab for Novel
4  * Software Tech., Nanjing University.
5  */
6 
7 #ifndef IR_SEG_SYMBOLICEXPRGRAPHSOLVER_H
8 #define IR_SEG_SYMBOLICEXPRGRAPHSOLVER_H
9 
10 #include <llvm/IR/BasicBlock.h>
11 #include <llvm/IR/Dominators.h>
12 
13 #include <string>
14 #include <unordered_map>
15 
16 #include "Analysis/Bitcode/TSDataLayout.h"
17 #include "Analysis/Graph/DomTreePass.h"
18 
19 #include "IR/SEG/SEGArgumentNode.h"
20 #include "IR/SEG/SEGLoadMemNode.h"
21 #include "IR/SEG/SEGPhiNode.h"
22 #include "IR/SEG/SEGRegionNode.h"
23 #include "IR/SEG/SEGReturnNode.h"
24 #include "IR/SEG/SEGStoreMemNode.h"
25 
26 #include "IR/SEG/SEGBinaryWithIntConstNode.h"
27 #include "IR/SEG/SEGCastNode.h"
28 
29 #include "SMT/SMTFactory.h"
30 
31 #include "Utils/ADT/PushPopCache.h"
32 
33 using namespace llvm;
34 
35 class MessageQueue;
36 class ExternalMemorySpec;
37 class ExternalIOSpec;
38 
48 class SymbolicExprGraphSolver : public SMTSolver {
49 protected:
51  std::unordered_map<const SEGNodeBase *, SMTExpr> NodeExprMap;
52 
54  std::unordered_map<std::string, const SEGNodeBase *> NodeSymbolNameMap;
55 
56  TSDataLayout &DL;
57 
58  ExternalMemorySpec *MemSpec = nullptr;
59  ExternalIOSpec *IOSpec = nullptr;
60 
61 public:
62  SymbolicExprGraphSolver(SMTFactory &Fcty, TSDataLayout &D,
63  ExternalMemorySpec *MemSepc, ExternalIOSpec *IOSpec);
64  virtual ~SymbolicExprGraphSolver();
65 
67  SMTExprVec getCtrlDeps(const SEGNodeBase *N, void *Args = nullptr);
68 
70  virtual SMTExprVec getCtrlDeps(WrappedBasicBlock *B,
71  const SymbolicExprGraph *G,
72  void *Args = nullptr);
73 
79  virtual std::pair<SMTExprVec, SMTExprVec>
80  getCtrlDepsPair(WrappedBasicBlock *B, const SymbolicExprGraph *G,
81  void *Args = nullptr) {
82  return __getCtrlDeps(B, G);
83  }
84 
86  virtual SMTExprVec getDataDeps(const SEGNodeBase *N, void *Args = nullptr);
87 
88  // Return gated function for a child of a phiNode
89  // This is the most accurate for a phi incoming node, since it is identified
90  // with incoming BB and the value.
91  virtual SMTExprVec getPhiGated(const SEGPhiNode *PhiNode,
92  const SEGPhiNode::IncomeNode InNode,
93  void *Args = nullptr);
94 
95  // This function first try to find the inNode then call the inNode version.
96  SMTExprVec getPhiGated(const SEGPhiNode *PhiNode, const SEGNodeBase *Value,
97  WrappedBasicBlock *BB, void *Args = nullptr);
98 
99  // This is a less accurate version since one value could come from several
100  // different BBs. We collect their ctrl dep + immediate cond and then OR all
101  // of them.
102  SMTExprVec getPhiGated(const SEGPhiNode *PhiNode, const SEGNodeBase *Value,
103  void *Args = nullptr);
104 
110  virtual SMTExprVec getDeps(const SEGNodeBase *N, const SEGNodeBase *M);
111 
114  virtual std::pair<SMTExprVec, SMTExprVec> getDepsPair(const SEGNodeBase *N,
115  const SEGNodeBase *M);
116 
117 private:
120  std::pair<SMTExprVec, SMTExprVec> __getCtrlDeps(WrappedBasicBlock *B,
121  const SymbolicExprGraph *G,
122  size_t Depth = 0);
123 
124  std::pair<SMTExprVec, SMTExprVec>
125  __getPhiGated(const SEGPhiNode *PhiNd, const SEGPhiNode::IncomeNode In);
126 
128  SMTExprVec __getDataDeps(const SEGNodeBase *N, size_t Depth = 0);
129 
130 public:
131  virtual void push();
132 
133  virtual void pop(unsigned N = 1);
134 
135  virtual void reset();
136 
137  virtual SMTResultType check();
138 
139 protected:
140  PushPopCache<const SEGNodeBase *> ConstraintCache;
141  PushPopCache<WrappedBasicBlock *> BBCache;
142 
143 private:
144  PushPopCache<const SEGArgumentNode *> FunctionArgumentCache;
145  PushPopCache<const SEGCallSiteOutputNode *> CallSiteOutputCache;
146 
147  std::unordered_map<WrappedBasicBlock *, SMTExprVec> CtrlCacheMap;
148  std::unordered_map<const SEGOpcodeNode *, SMTExpr> OpcodeConstraintsCacheMap;
149 
150 public:
151  const std::unordered_set<const SEGArgumentNode *> &
152  getUsedFunctionArguments() {
153  return FunctionArgumentCache.getCacheSet();
154  }
155 
156  // see PushPopVector::getCacheVector(bool)
157  std::pair<std::vector<const SEGCallSiteOutputNode *>::iterator,
158  std::vector<const SEGCallSiteOutputNode *>::iterator>
159  getUsedCallSiteOutputs(bool Restart = false) {
160  return CallSiteOutputCache.getCacheVector(Restart);
161  }
162 
163 public:
165  const SEGNodeBase *getNodeFromSymbol(std::string Symbol) {
166  auto It = NodeSymbolNameMap.find(Symbol);
167  if (It == NodeSymbolNameMap.end()) {
168  return nullptr;
169  }
170  return It->second;
171  }
172 
173  SMTExpr getOrInsertExpr(const SEGNodeBase *N);
174 
188  SMTExpr encodeOpcodeNode(const SEGOpcodeNode *N);
189 
190  virtual SMTExpr encodeBinaryOpcodeNode(const SEGOpcodeNode *N);
191  virtual SMTExpr encodeCompareOpcodeNode(const SEGOpcodeNode *N);
192  virtual SMTExpr encodeCastOpcodeNode(const SEGOpcodeNode *N);
193  virtual SMTExpr encodeGEPOpcodeNode(const SEGOpcodeNode *N);
194  virtual SMTExpr encodeExtractElementOpcodeNode(const SEGOpcodeNode *N);
195  virtual SMTExpr encodeInsertElementOpcodeNode(const SEGOpcodeNode *N);
196  virtual SMTExpr encodeSelectOpcodeNode(const SEGOpcodeNode *N);
197  virtual SMTExpr encodeConcatOpcodeNode(const SEGOpcodeNode *N);
198 };
199 
200 // Using the domination relationship between basic blocks
201 // to refine the constraints.
203 private:
204  const DomTree *DT;
205 
206  std::unordered_map<WrappedBasicBlock *,
207  std::pair<SMTExprVec, WrappedBasicBlock *>>
208  CtrlCacheMap;
209 
210 public:
211  DTSymbolicExprGraphSolver(SMTFactory &Fcty, TSDataLayout &D,
212  ExternalMemorySpec *MemSpec, ExternalIOSpec *IOSpec,
213  const DomTree *T)
214  : SymbolicExprGraphSolver(Fcty, D, MemSpec, IOSpec), DT(T) {}
215 
216 public:
219  virtual SMTExprVec getCtrlDeps(WrappedBasicBlock *B,
220  const SymbolicExprGraph *G,
221  void *Args = nullptr);
222 
223  virtual std::pair<SMTExprVec, SMTExprVec>
224  getCtrlDepsPair(WrappedBasicBlock *B, const SymbolicExprGraph *G,
225  void *Args = nullptr) {
226  WrappedBasicBlock *PrevB = (WrappedBasicBlock *)Args;
227  return __getCtrlDepsWrapper(B, G, PrevB);
228  }
229 
232  virtual SMTExprVec getDataDeps(const SEGNodeBase *N, void *Args = nullptr);
233 
238  virtual SMTExprVec getPhiGated(const SEGPhiNode *PhiNode,
239  const SEGPhiNode::IncomeNode InNode,
240  void *Args = nullptr);
241 
242  virtual void reset();
243 
248  virtual SMTExprVec getDeps(const SEGNodeBase *N, const SEGNodeBase *M);
249 
250 private:
252  std::pair<SMTExprVec, SMTExprVec>
253  __getCtrlDepsWrapper(WrappedBasicBlock *B, const SymbolicExprGraph *G,
254  WrappedBasicBlock *PrevB);
255 
259  std::pair<SMTExprVec, SMTExprVec> __getCtrlDeps(WrappedBasicBlock *B,
260  const SymbolicExprGraph *G,
261  WrappedBasicBlock *PrevB);
262 
263  std::pair<SMTExprVec, SMTExprVec>
264  __getPhiGated(const SEGPhiNode *PhiNd, const SEGPhiNode::IncomeNode In,
265  WrappedBasicBlock *PrevB);
266 
270  SMTExprVec __getDataDeps(const SEGNodeBase *N, WrappedBasicBlock *PrevB);
271 };
272 
273 #endif
DTSymbolicExprGraphSolver::getCtrlDepsPair
virtual std::pair< SMTExprVec, SMTExprVec > getCtrlDepsPair(WrappedBasicBlock *B, const SymbolicExprGraph *G, void *Args=nullptr)
Definition: SymbolicExprGraphSolver.h:224
SEGPhiNode::IncomeNode
Definition: SEGPhiNode.h:40
SymbolicExprGraphSolver::NodeSymbolNameMap
std::unordered_map< std::string, const SEGNodeBase * > NodeSymbolNameMap
map the symbol name used by Z3 in context ctx to the SEG node
Definition: SymbolicExprGraphSolver.h:54
SymbolicExprGraph
Definition: SymbolicExprGraph.h:855
SymbolicExprGraphSolver
Definition: SymbolicExprGraphSolver.h:48
SymbolicExprGraphSolver::NodeExprMap
std::unordered_map< const SEGNodeBase *, SMTExpr > NodeExprMap
each node in seg is a z3 variable
Definition: SymbolicExprGraphSolver.h:51
SymbolicExprGraphSolver::getNodeFromSymbol
const SEGNodeBase * getNodeFromSymbol(std::string Symbol)
return the SEG node for the given symbol
Definition: SymbolicExprGraphSolver.h:165
DTSymbolicExprGraphSolver
Definition: SymbolicExprGraphSolver.h:202
SymbolicExprGraphSolver::getCtrlDepsPair
virtual std::pair< SMTExprVec, SMTExprVec > getCtrlDepsPair(WrappedBasicBlock *B, const SymbolicExprGraph *G, void *Args=nullptr)
Definition: SymbolicExprGraphSolver.h:80
SEGPhiNode
Definition: SEGPhiNode.h:31
SEGOpcodeNode
Definition: SymbolicExprGraph.h:624
SEGNodeBase
The node base of symbolic expression graph.
Definition: SymbolicExprGraph.h:288