svf-tools 1.0.656 → 1.0.658

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-tools",
3
- "version": "1.0.656",
3
+ "version": "1.0.658",
4
4
  "description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -51,6 +51,10 @@ public:
51
51
  /// Initialize the grammar, graph, solver
52
52
  virtual void initialize();
53
53
 
54
+ /// Initialize Solver
55
+ virtual void initializeSolver();
56
+
57
+
54
58
  /// Print grammar and graph
55
59
  virtual void finalize();
56
60
 
@@ -143,9 +147,19 @@ public:
143
147
  POCRAlias(SVFIR* ir) : CFLAlias(ir)
144
148
  {
145
149
  }
150
+ /// Initialize POCR Solver
151
+ virtual void initializeSolver();
152
+ };
146
153
 
147
- /// Initialize the grammar, graph, CFLData, solver
148
- virtual void initialize();
154
+ class POCRHybrid : public CFLAlias
155
+ {
156
+ public:
157
+ POCRHybrid(SVFIR* ir) : CFLAlias(ir)
158
+ {
159
+ }
160
+
161
+ /// Initialize POCRHybrid Solver
162
+ virtual void initializeSolver();
149
163
  };
150
164
  } // End namespace SVF
151
165
 
@@ -3,7 +3,7 @@ Start:
3
3
  Terminal:
4
4
  addr copy store load gep vgep
5
5
  Productions:
6
- F -> epsilon | F copy | addr Memflow | F store V load | store Memflow load;
6
+ F -> epsilon | F copy | addr Memflow | F store V load | store Memflow load | F F;
7
7
  Fbar -> epsilon | copybar Fbar | Memflowbar addrbar | loadbar V storebar Fbar | loadbar Memflowbar storebar;
8
8
  V -> Fbar V F | addrbar addr | gepbar_i V gep_i | gepbarpath V gep_0 | gepbar_i F gep_i | gepbar_i Fbar gep_i;
9
9
  copy -> vgep;
@@ -40,112 +40,6 @@ namespace SVF
40
40
  {
41
41
  typedef GrammarBase::Symbol Label;
42
42
 
43
- /*!
44
- * Hybrid graph representation for transitive relations
45
- * The implementation is based on
46
- * Yuxiang Lei, Yulei Sui, Shuo Ding, and Qirun Zhang.
47
- * Taming Transitive Redundancy for Context-Free Language Reachability.
48
- * ACM SIGPLAN Conference on Object-Oriented Programming, Systems, Languages, and Applications
49
- */
50
- class HybridData
51
- {
52
- public:
53
- struct TreeNode
54
- {
55
- NodeID id;
56
- std::unordered_set<TreeNode*> children;
57
-
58
- TreeNode(NodeID nId) : id(nId)
59
- {}
60
-
61
- ~TreeNode()
62
- {
63
- }
64
-
65
- inline bool operator==(const TreeNode& rhs) const
66
- {
67
- return id == rhs.id;
68
- }
69
-
70
- inline bool operator<(const TreeNode& rhs) const
71
- {
72
- return id < rhs.id;
73
- }
74
- };
75
-
76
-
77
- public:
78
- Map<NodeID, std::unordered_map<NodeID, TreeNode*>> indMap; // indMap[v][u] points to node v in tree(u)
79
-
80
- HybridData()
81
- {}
82
-
83
- ~HybridData()
84
- {
85
- for (auto iter1: indMap)
86
- {
87
- for (auto iter2: iter1.second)
88
- {
89
- delete iter2.second;
90
- iter2.second = NULL;
91
- }
92
- }
93
- }
94
-
95
- bool hasInd(NodeID src, NodeID dst)
96
- {
97
- auto it = indMap.find(dst);
98
- if (it == indMap.end())
99
- return false;
100
- return (it->second.find(src) != it->second.end());
101
- }
102
-
103
- /// Add a node dst to tree(src)
104
- TreeNode* addInd(NodeID src, NodeID dst)
105
- {
106
- auto resIns = indMap[dst].insert(std::make_pair(src, new TreeNode(dst)));
107
- if (resIns.second)
108
- return resIns.first->second;
109
- return nullptr;
110
- }
111
-
112
- /// Get the node dst in tree(src)
113
- TreeNode* getNode(NodeID src, NodeID dst)
114
- {
115
- return indMap[dst][src];
116
- }
117
-
118
- /// add v into desc(x) as a child of u
119
- void insertEdge(TreeNode* u, TreeNode* v)
120
- {
121
- u->children.insert(v);
122
- }
123
-
124
- void addArc(NodeID src, NodeID dst)
125
- {
126
- if (!hasInd(src, dst))
127
- {
128
- for (auto iter: indMap[src])
129
- {
130
- meld(iter.first, getNode(iter.first, src), getNode(dst, dst));
131
- }
132
- }
133
- }
134
-
135
- void meld(NodeID x, TreeNode* uNode, TreeNode* vNode)
136
- {
137
- TreeNode* newVNode = addInd(x, vNode->id);
138
- if (!newVNode)
139
- return;
140
-
141
- insertEdge(uNode, newVNode);
142
- for (TreeNode* vChild: vNode->children)
143
- {
144
- meld(x, newVNode, vChild);
145
- }
146
- }
147
- };
148
-
149
43
  class CFLSolver
150
44
  {
151
45
 
@@ -389,6 +283,92 @@ public:
389
283
 
390
284
  virtual void initialize();
391
285
  };
286
+ /*!
287
+ * Hybrid graph representation for transitive relations
288
+ * The implementation is based on
289
+ * Yuxiang Lei, Yulei Sui, Shuo Ding, and Qirun Zhang.
290
+ * Taming Transitive Redundancy for Context-Free Language Reachability.
291
+ * ACM SIGPLAN Conference on Object-Oriented Programming, Systems, Languages, and Applications
292
+ */
293
+ /// Solver Utilize Hybrid Representation of Graph
294
+ class POCRHybridSolver : public POCRSolver
295
+ {
296
+ //Hybrid
297
+ //{@
298
+ public:
299
+ struct TreeNode
300
+ {
301
+ NodeID id;
302
+ std::unordered_set<TreeNode*> children;
303
+
304
+ TreeNode(NodeID nId) : id(nId)
305
+ {}
306
+
307
+ ~TreeNode()
308
+ {
309
+ }
310
+
311
+ inline bool operator==(const TreeNode& rhs) const
312
+ {
313
+ return id == rhs.id;
314
+ }
315
+
316
+ inline bool operator<(const TreeNode& rhs) const
317
+ {
318
+ return id < rhs.id;
319
+ }
320
+ };
321
+
322
+ public:
323
+ Map<NodeID, std::unordered_map<NodeID, TreeNode*>> indMap; // indMap[v][u] points to node v in tree(u)
324
+
325
+ bool hasInd_h(NodeID src, NodeID dst);
326
+
327
+ /// Add a node dst to tree(src)
328
+ TreeNode* addInd_h(NodeID src, NodeID dst);
329
+
330
+ /// Get the node dst in tree(src)
331
+ TreeNode* getNode_h(NodeID src, NodeID dst)
332
+ {
333
+ return indMap[dst][src];
334
+ }
335
+
336
+ /// add v into desc(x) as a child of u
337
+ void insertEdge_h(TreeNode* u, TreeNode* v)
338
+ {
339
+ u->children.insert(v);
340
+ }
341
+
342
+ void addArc_h(NodeID src, NodeID dst);
343
+
344
+ void meld_h(NodeID x, TreeNode* uNode, TreeNode* vNode);
345
+ //@}
346
+ public:
347
+ POCRHybridSolver(CFLGraph* _graph, CFLGrammar* _grammar) : POCRSolver(_graph, _grammar)
348
+ {
349
+ }
350
+ /// Destructor
351
+ virtual ~POCRHybridSolver()
352
+ {
353
+ for (auto iter1: indMap)
354
+ {
355
+ for (auto iter2: iter1.second)
356
+ {
357
+ delete iter2.second;
358
+ iter2.second = NULL;
359
+ }
360
+ }
361
+ }
362
+
363
+ /// Process CFLEdge
364
+ virtual void processCFLEdge(const CFLEdge* Y_edge);
365
+
366
+ virtual void initialize();
367
+
368
+ public:
369
+ void addArc(NodeID src, NodeID dst);
370
+ void meld(NodeID x, TreeNode* uNode, TreeNode* vNode);
371
+ };
392
372
  }
393
373
 
394
374
  #endif /* INCLUDE_CFL_CFLSolver_H_*/
@@ -139,13 +139,13 @@ public:
139
139
  return conditionVar;
140
140
  }
141
141
 
142
- s32_t getSuccessorCondValue() const
142
+ s64_t getSuccessorCondValue() const
143
143
  {
144
144
  assert(getCondition() && "this is not a conditional branch edge");
145
145
  return branchCondVal;
146
146
  }
147
147
 
148
- void setBranchCondition(const SVFValue* c, s32_t bVal)
148
+ void setBranchCondition(const SVFValue* c, s64_t bVal)
149
149
  {
150
150
  conditionVar = c;
151
151
  branchCondVal = bVal;
@@ -159,7 +159,7 @@ private:
159
159
  /// e.g., Inst1: br %cmp label 0, label 1, Inst2 is label 0 and Inst 3 is label 1;
160
160
  /// for edge between Inst1 and Inst 2, the first element is %cmp and second element is 0
161
161
  const SVFValue* conditionVar;
162
- s32_t branchCondVal;
162
+ s64_t branchCondVal;
163
163
  };
164
164
 
165
165
  /*!
@@ -1048,7 +1048,7 @@ public:
1048
1048
  {
1049
1049
  return successors.at(i).first;
1050
1050
  }
1051
- s32_t getSuccessorCondValue (u32_t i) const
1051
+ s64_t getSuccessorCondValue (u32_t i) const
1052
1052
  {
1053
1053
  return successors.at(i).second;
1054
1054
  }
@@ -256,6 +256,7 @@ public:
256
256
  static const Option<bool> PEGTransfer;
257
257
  static const Option<bool> CFLSVFG;
258
258
  static const Option<bool> POCRAlias;
259
+ static const Option<bool> POCRHybrid;
259
260
 
260
261
  // Loop Analysis
261
262
  static const Option<bool> LoopAnalysis;
@@ -201,6 +201,11 @@ void CFLAlias::initialize()
201
201
  normalizeCFLGrammar();
202
202
 
203
203
  // Initialize sovler
204
+ initializeSolver();
205
+ }
206
+
207
+ void CFLAlias::initializeSolver()
208
+ {
204
209
  solver = new CFLSolver(graph, grammar);
205
210
  }
206
211
 
@@ -238,19 +243,12 @@ void CFLAlias::solve()
238
243
  timeOfSolving += (end - start) / TIMEINTERVAL;
239
244
  }
240
245
 
241
- void POCRAlias::initialize()
246
+ void POCRAlias::initializeSolver()
242
247
  {
243
- stat = new CFLStat(this);
244
-
245
- // Build CFL Grammar
246
- buildCFLGrammar();
247
-
248
- // Build CFL Graph
249
- buildCFLGraph();
250
-
251
- // Normalize CFL Grammar
252
- normalizeCFLGrammar();
253
-
254
- // Initialize POCRSolver
255
248
  solver = new POCRSolver(graph, grammar);
256
249
  }
250
+
251
+ void POCRHybrid::initializeSolver()
252
+ {
253
+ solver = new POCRHybridSolver(graph, grammar);
254
+ }
@@ -191,15 +191,110 @@ void POCRSolver::processCFLEdge(const CFLEdge* Y_edge)
191
191
 
192
192
  void POCRSolver::initialize()
193
193
  {
194
- for(auto it = graph->begin(); it!= graph->end(); it++)
194
+ for(auto edge : graph->getCFLEdges())
195
195
  {
196
- for(const CFLEdge* edge : (*it).second->getOutEdges())
196
+ pushIntoWorklist(edge);
197
+ }
198
+
199
+ /// Foreach production X -> epsilon
200
+ /// add X(i,i) if not exist to E and to worklist
201
+ for(const Production& prod : grammar->getEpsilonProds())
202
+ {
203
+ for(auto IDMap : getSuccMap())
197
204
  {
198
- pushIntoWorklist(edge);
205
+ Symbol X = grammar->getLHSSymbol(prod);
206
+ if (addEdge(IDMap.first, IDMap.first, X))
207
+ {
208
+ CFLNode* i = graph->getGNode(IDMap.first);
209
+ const CFLEdge* newEdge = graph->addCFLEdge(i, i, X);
210
+ pushIntoWorklist(newEdge);
211
+ }
199
212
  }
200
213
  }
214
+ }
215
+
216
+ void POCRHybridSolver::processCFLEdge(const CFLEdge* Y_edge)
217
+ {
218
+ CFLNode* i = Y_edge->getSrcNode();
219
+ CFLNode* j = Y_edge->getDstNode();
220
+
221
+ /// For each production X -> Y
222
+ /// add X(i,j) if not exist to E and to worklist
223
+ Symbol Y = Y_edge->getEdgeKind();
224
+ if (grammar->hasProdsFromSingleRHS(Y))
225
+ for(const Production& prod : grammar->getProdsFromSingleRHS(Y))
226
+ {
227
+ Symbol X = grammar->getLHSSymbol(prod);
228
+ numOfChecks++;
229
+ if (addEdge(i->getId(), j->getId(), X))
230
+ {
231
+ const CFLEdge* newEdge = graph->addCFLEdge(Y_edge->getSrcNode(), Y_edge->getDstNode(), X);
232
+ pushIntoWorklist(newEdge);
233
+ }
234
+
235
+ }
236
+
237
+ /// For each production X -> Y Z
238
+ /// Foreach outgoing edge Z(j,k) from node j do
239
+ /// add X(i,k) if not exist to E and to worklist
240
+ if (grammar->hasProdsFromFirstRHS(Y))
241
+ for(const Production& prod : grammar->getProdsFromFirstRHS(Y))
242
+ {
243
+ if ((grammar->getLHSSymbol(prod) == grammar->str2Symbol("F")) && (Y == grammar->str2Symbol("F")) && (grammar->getSecondRHSSymbol(prod) == grammar->str2Symbol("F")))
244
+ {
245
+ addArc(i->getId(), j->getId());
246
+ }
247
+ else
248
+ {
249
+ Symbol X = grammar->getLHSSymbol(prod);
250
+ NodeBS diffDsts = addEdges(i->getId(), getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)], X);
251
+ numOfChecks += getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)].count();
252
+ for (NodeID diffDst: diffDsts)
253
+ {
254
+ const CFLEdge* newEdge = graph->addCFLEdge(i, graph->getGNode(diffDst), X);
255
+ pushIntoWorklist(newEdge);
256
+ }
257
+ }
258
+ }
259
+
260
+ /// For each production X -> Z Y
261
+ /// Foreach incoming edge Z(k,i) to node i do
262
+ /// add X(k,j) if not exist to E and to worklist
263
+ if(grammar->hasProdsFromSecondRHS(Y))
264
+ for(const Production& prod : grammar->getProdsFromSecondRHS(Y))
265
+ {
266
+ if ((grammar->getLHSSymbol(prod) == grammar->str2Symbol("F")) && (Y == grammar->str2Symbol("F")) && (grammar->getFirstRHSSymbol(prod) == grammar->str2Symbol("F")))
267
+ {
268
+ addArc(i->getId(), j->getId());
269
+ }
270
+ else
271
+ {
272
+ Symbol X = grammar->getLHSSymbol(prod);
273
+ NodeBS diffSrcs = addEdges(getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)], j->getId(), X);
274
+ numOfChecks += getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)].count();
275
+ for (NodeID diffSrc: diffSrcs)
276
+ {
277
+ const CFLEdge* newEdge = graph->addCFLEdge(graph->getGNode(diffSrc), j, X);
278
+ pushIntoWorklist(newEdge);
279
+ }
280
+ }
281
+ }
282
+ }
283
+
284
+ void POCRHybridSolver::initialize()
285
+ {
286
+ for(auto edge : graph->getCFLEdges())
287
+ {
288
+ pushIntoWorklist(edge);
289
+ }
290
+
291
+ // init hybrid dataset
292
+ for (auto it = graph->begin(); it != graph->end(); ++it)
293
+ {
294
+ NodeID nId = it->first;
295
+ addInd_h(nId, nId);
296
+ }
201
297
 
202
- /// Foreach production X -> epsilon
203
298
  /// add X(i,i) if not exist to E and to worklist
204
299
  for(const Production& prod : grammar->getEpsilonProds())
205
300
  {
@@ -214,4 +309,73 @@ void POCRSolver::initialize()
214
309
  }
215
310
  }
216
311
  }
312
+ }
313
+
314
+ void POCRHybridSolver::addArc(NodeID src, NodeID dst)
315
+ {
316
+ if(hasEdge(src, dst, grammar->str2Symbol("F")))
317
+ return;
318
+
319
+ for (auto& iter: indMap[src])
320
+ {
321
+ meld(iter.first, getNode_h(iter.first, src), getNode_h(dst, dst));
322
+ }
323
+ }
324
+
325
+
326
+ void POCRHybridSolver::meld(NodeID x, TreeNode* uNode, TreeNode* vNode)
327
+ {
328
+ numOfChecks++;
329
+
330
+ TreeNode* newVNode = addInd_h(x, vNode->id);
331
+ if (!newVNode)
332
+ return;
333
+
334
+ insertEdge_h(uNode, newVNode);
335
+ for (TreeNode* vChild: vNode->children)
336
+ {
337
+ meld_h(x, newVNode, vChild);
338
+ }
339
+ }
340
+
341
+ bool POCRHybridSolver::hasInd_h(NodeID src, NodeID dst)
342
+ {
343
+ auto it = indMap.find(dst);
344
+ if (it == indMap.end())
345
+ return false;
346
+ return (it->second.find(src) != it->second.end());
347
+ }
348
+
349
+ POCRHybridSolver::TreeNode* POCRHybridSolver::addInd_h(NodeID src, NodeID dst)
350
+ {
351
+ TreeNode* newNode = new TreeNode(dst);
352
+ auto resIns = indMap[dst].insert(std::make_pair(src, newNode));
353
+ if (resIns.second)
354
+ return resIns.first->second;
355
+ delete newNode;
356
+ return nullptr;
357
+ }
358
+
359
+ void POCRHybridSolver::addArc_h(NodeID src, NodeID dst)
360
+ {
361
+ if (!hasInd_h(src, dst))
362
+ {
363
+ for (auto iter: indMap[src])
364
+ {
365
+ meld_h(iter.first, getNode_h(iter.first, src), getNode_h(dst, dst));
366
+ }
367
+ }
368
+ }
369
+
370
+ void POCRHybridSolver::meld_h(NodeID x, TreeNode* uNode, TreeNode* vNode)
371
+ {
372
+ TreeNode* newVNode = addInd_h(x, vNode->id);
373
+ if (!newVNode)
374
+ return;
375
+
376
+ insertEdge_h(uNode, newVNode);
377
+ for (TreeNode* vChild: vNode->children)
378
+ {
379
+ meld_h(x, newVNode, vChild);
380
+ }
217
381
  }
@@ -829,6 +829,12 @@ const Option<bool> Options::POCRAlias(
829
829
  false
830
830
  );
831
831
 
832
+ const Option<bool> Options::POCRHybrid(
833
+ "pocr-hybrid",
834
+ "When explicit to true, POCRHybridSolver transfer CFL graph to internal hybird graph representation.",
835
+ false
836
+ );
837
+
832
838
  const Option<bool> Options::LoopAnalysis(
833
839
  "loop-analysis",
834
840
  "Analyze every func and get loop info and loop bounds.",
@@ -841,4 +847,4 @@ const Option<u32_t> Options::LoopBound(
841
847
  1
842
848
  );
843
849
 
844
- } // namespace SVF.
850
+ } // namespace SVF.
@@ -134,7 +134,9 @@ void ICFGBuilder::processFunBody(WorkList& worklist)
134
134
  /// branch condition value
135
135
  const ConstantInt* condVal = const_cast<SwitchInst*>(si)->findCaseDest(const_cast<BasicBlock*>(succ->getParent()));
136
136
  /// default case is set to -1;
137
- s32_t val = condVal ? condVal->getSExtValue() : -1;
137
+ s64_t val = -1;
138
+ if (condVal && condVal->getBitWidth() <= 64)
139
+ val = condVal->getSExtValue();
138
140
  icfg->addConditionalIntraEdge(srcNode, dstNode, LLVMModuleSet::getLLVMModuleSet()->getSVFValue(si->getCondition()),val);
139
141
  }
140
142
  else
@@ -937,7 +937,9 @@ void SVFIRBuilder::visitSwitchInst(SwitchInst &inst)
937
937
  const Instruction* succInst = &inst.getSuccessor(i)->front();
938
938
  const ConstantInt* condVal = inst.findCaseDest(inst.getSuccessor(i));
939
939
  /// default case is set to -1;
940
- s32_t val = condVal ? condVal->getSExtValue() : -1;
940
+ s64_t val = -1;
941
+ if (condVal && condVal->getBitWidth() <= 64)
942
+ val = condVal->getSExtValue();
941
943
  const SVFInstruction* svfSuccInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(succInst);
942
944
  const ICFGNode* icfgNode = pag->getICFG()->getICFGNode(svfSuccInst);
943
945
  successors.push_back(std::make_pair(icfgNode,val));
@@ -59,6 +59,8 @@ int main(int argc, char ** argv)
59
59
  std::unique_ptr<CFLBase> cfl;
60
60
  if (Options::CFLSVFG())
61
61
  cfl = std::make_unique<CFLVF>(svfir);
62
+ else if (Options::POCRHybrid())
63
+ cfl = std::make_unique<POCRHybrid>(svfir);
62
64
  else if (Options::POCRAlias())
63
65
  cfl = std::make_unique<POCRAlias>(svfir);
64
66
  else