svf-tools 1.0.974 → 1.0.975

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.974",
3
+ "version": "1.0.975",
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": {
@@ -143,10 +143,10 @@ protected:
143
143
  /**
144
144
  * Check if execution state exist by merging states of predecessor nodes
145
145
  *
146
- * @param curNode The ICFGNode to analyse
146
+ * @param icfgNode The icfg node to analyse
147
147
  * @return if this node has preceding execution state
148
148
  */
149
- bool mergeStatesFromPredecessors(const ICFGNode* curNode);
149
+ bool mergeStatesFromPredecessors(const ICFGNode * icfgNode);
150
150
 
151
151
  /**
152
152
  * Check if execution state exist at the branch edge
@@ -179,6 +179,8 @@ protected:
179
179
 
180
180
  void handleWTOComponents(const std::list<const ICFGWTOComp*>& wtoComps);
181
181
 
182
+ void handleWTOComponent(const ICFGWTOComp* wtoComp);
183
+
182
184
 
183
185
  /**
184
186
  * handle SVF Statement like CmpStmt, CallStmt, GepStmt, LoadStmt, StoreStmt, etc.
@@ -378,20 +380,20 @@ protected:
378
380
  AbstractState& getAbsStateFromTrace(const ICFGNode* node)
379
381
  {
380
382
  const ICFGNode* repNode = _icfg->getRepNode(node);
381
- if (_postAbsTrace.count(repNode) == 0)
383
+ if (_abstractTrace.count(repNode) == 0)
382
384
  {
383
385
  assert(0 && "No preAbsTrace for this node");
384
386
  }
385
387
  else
386
388
  {
387
- return _postAbsTrace[repNode];
389
+ return _abstractTrace[repNode];
388
390
  }
389
391
  }
390
392
 
391
393
  bool hasAbsStateFromTrace(const ICFGNode* node)
392
394
  {
393
395
  const ICFGNode* repNode = _icfg->getRepNode(node);
394
- return _postAbsTrace.count(repNode) != 0;
396
+ return _abstractTrace.count(repNode) != 0;
395
397
  }
396
398
 
397
399
  protected:
@@ -399,8 +401,7 @@ protected:
399
401
  Map<std::string, std::function<void(const CallSite &)>> _func_map;
400
402
  Set<const CallICFGNode*> _checkpoints;
401
403
  Set<std::string> _checkpoint_names;
402
- Map<const ICFGNode*, AbstractState> _preAbsTrace;
403
- Map<const ICFGNode*, AbstractState> _postAbsTrace;
404
+ Map<const ICFGNode*, AbstractState> _abstractTrace; // abstract states immediately after nodes
404
405
  std::string _moduleName;
405
406
  };
406
407
  }
@@ -178,12 +178,12 @@ private:
178
178
  virtual void handleSingletonWTO(const ICFGSingletonWTO *icfgSingletonWto) override
179
179
  {
180
180
  AbstractInterpretation::handleSingletonWTO(icfgSingletonWto);
181
- const ICFGNode* repNode = _icfg->getRepNode(icfgSingletonWto->node());
182
- if (_postAbsTrace.count(repNode) == 0)
181
+ const ICFGNode* repNode = _icfg->getRepNode(icfgSingletonWto->getICFGNode());
182
+ if (_abstractTrace.count(repNode) == 0)
183
183
  {
184
184
  return;
185
185
  }
186
- const std::vector<const ICFGNode*>& worklist_vec = _icfg->getSubNodes(icfgSingletonWto->node());
186
+ const std::vector<const ICFGNode*>& worklist_vec = _icfg->getSubNodes(icfgSingletonWto->getICFGNode());
187
187
 
188
188
  for (auto it = worklist_vec.begin(); it != worklist_vec.end(); ++it)
189
189
  {
@@ -341,7 +341,7 @@ public:
341
341
  }
342
342
 
343
343
  /// Return the graph node
344
- const NodeT* node() const
344
+ const NodeT* getICFGNode() const
345
345
  {
346
346
  return _node;
347
347
  }
@@ -457,7 +457,7 @@ public:
457
457
  std::string str;
458
458
  std::stringstream rawstr(str);
459
459
  rawstr << "(";
460
- rawstr << _head->node()->getId() << ", ";
460
+ rawstr << _head->getICFGNode()->getId() << ", ";
461
461
  for (auto it = begin(), et = end(); it != et;)
462
462
  {
463
463
  rawstr << (*it)->toString();
@@ -698,7 +698,7 @@ protected:
698
698
 
699
699
  void visit(const WTOCycleT& cycle) override
700
700
  {
701
- const NodeT* head = cycle.head()->node();
701
+ const NodeT* head = cycle.head()->getICFGNode();
702
702
  WTOCycleDepthPtr previous_cycleDepth = _wtoCycleDepth;
703
703
  _nodeToWTOCycleDepth.insert(std::make_pair(head, _wtoCycleDepth));
704
704
  _wtoCycleDepth =
@@ -714,7 +714,7 @@ protected:
714
714
  void visit(const WTONodeT& node) override
715
715
  {
716
716
  _nodeToWTOCycleDepth.insert(
717
- std::make_pair(node.node(), _wtoCycleDepth));
717
+ std::make_pair(node.getICFGNode(), _wtoCycleDepth));
718
718
  }
719
719
 
720
720
  }; // end class WTOCycleDepthBuilder
@@ -167,10 +167,9 @@ void AbstractInterpretation::analyse()
167
167
  /// handle global node
168
168
  void AbstractInterpretation::handleGlobalNode()
169
169
  {
170
- AbstractState as;
171
170
  const ICFGNode* node = _icfg->getGlobalICFGNode();
172
- _postAbsTrace[node] = _preAbsTrace[node];
173
- _postAbsTrace[node][SymbolTableInfo::NullPtr] = AddressValue();
171
+ _abstractTrace[node] = AbstractState();
172
+ _abstractTrace[node][SymbolTableInfo::NullPtr] = AddressValue();
174
173
  // Global Node, we just need to handle addr, load, store, copy and gep
175
174
  for (const SVFStmt *stmt: node->getSVFStmts())
176
175
  {
@@ -181,18 +180,18 @@ void AbstractInterpretation::handleGlobalNode()
181
180
  /// get execution state by merging states of predecessor blocks
182
181
  /// Scenario 1: preblock -----(intraEdge)----> block, join the preES of inEdges
183
182
  /// Scenario 2: preblock -----(callEdge)----> block
184
- bool AbstractInterpretation::mergeStatesFromPredecessors(const ICFGNode *block)
183
+ bool AbstractInterpretation::mergeStatesFromPredecessors(const ICFGNode * icfgNode)
185
184
  {
186
185
  std::vector<AbstractState> workList;
187
- AbstractState as;
188
- for (auto& edge: block->getInEdges())
186
+ AbstractState preAs;
187
+ for (auto& edge: icfgNode->getInEdges())
189
188
  {
190
- if (_postAbsTrace.find(edge->getSrcNode()) != _postAbsTrace.end())
189
+ if (_abstractTrace.find(edge->getSrcNode()) != _abstractTrace.end())
191
190
  {
192
191
  const IntraCFGEdge *intraCfgEdge = SVFUtil::dyn_cast<IntraCFGEdge>(edge);
193
192
  if (intraCfgEdge && intraCfgEdge->getCondition())
194
193
  {
195
- AbstractState tmpEs = _postAbsTrace[edge->getSrcNode()];
194
+ AbstractState tmpEs = _abstractTrace[edge->getSrcNode()];
196
195
  if (isBranchFeasible(intraCfgEdge, tmpEs))
197
196
  {
198
197
  workList.push_back(tmpEs);
@@ -204,7 +203,7 @@ bool AbstractInterpretation::mergeStatesFromPredecessors(const ICFGNode *block)
204
203
  }
205
204
  else
206
205
  {
207
- workList.push_back(_postAbsTrace[edge->getSrcNode()]);
206
+ workList.push_back(_abstractTrace[edge->getSrcNode()]);
208
207
  }
209
208
  }
210
209
  else
@@ -212,7 +211,6 @@ bool AbstractInterpretation::mergeStatesFromPredecessors(const ICFGNode *block)
212
211
 
213
212
  }
214
213
  }
215
- _preAbsTrace[block].clear();
216
214
  if (workList.size() == 0)
217
215
  {
218
216
  return false;
@@ -221,9 +219,12 @@ bool AbstractInterpretation::mergeStatesFromPredecessors(const ICFGNode *block)
221
219
  {
222
220
  while (!workList.empty())
223
221
  {
224
- _preAbsTrace[block].joinWith(workList.back());
222
+ preAs.joinWith(workList.back());
225
223
  workList.pop_back();
226
224
  }
225
+ // Has ES on the in edges - Feasible block
226
+ // update post as
227
+ _abstractTrace[icfgNode] = preAs;
227
228
  return true;
228
229
  }
229
230
  }
@@ -526,20 +527,8 @@ bool AbstractInterpretation::isBranchFeasible(const IntraCFGEdge* intraEdge,
526
527
  /// handle instructions in svf basic blocks
527
528
  void AbstractInterpretation::handleSingletonWTO(const ICFGSingletonWTO *icfgSingletonWto)
528
529
  {
529
- const ICFGNode* node = icfgSingletonWto->node();
530
+ const ICFGNode* node = icfgSingletonWto->getICFGNode();
530
531
  _stat->getBlockTrace()++;
531
- // Get execution states from in edges
532
- if (!mergeStatesFromPredecessors(node))
533
- {
534
- // No ES on the in edges - Infeasible block
535
- return;
536
- }
537
- else
538
- {
539
- // Has ES on the in edges - Feasible block
540
- // Get execution state from in edges
541
- _postAbsTrace[node] = _preAbsTrace[node];
542
- }
543
532
 
544
533
  std::deque<const ICFGNode*> worklist;
545
534
 
@@ -573,20 +562,27 @@ void AbstractInterpretation::handleWTOComponents(const std::list<const ICFGWTOCo
573
562
  {
574
563
  for (const ICFGWTOComp* wtoNode : wtoComps)
575
564
  {
576
- if (const ICFGSingletonWTO* node = SVFUtil::dyn_cast<ICFGSingletonWTO>(wtoNode))
577
- {
565
+ handleWTOComponent(wtoNode);
566
+ }
567
+ }
568
+
569
+ void AbstractInterpretation::handleWTOComponent(const SVF::ICFGWTOComp* wtoNode)
570
+ {
571
+ if (const ICFGSingletonWTO* node = SVFUtil::dyn_cast<ICFGSingletonWTO>(wtoNode))
572
+ {
573
+ if (mergeStatesFromPredecessors(node->getICFGNode()))
578
574
  handleSingletonWTO(node);
579
- }
580
- // Handle WTO cycles
581
- else if (const ICFGCycleWTO* cycle = SVFUtil::dyn_cast<ICFGCycleWTO>(wtoNode))
582
- {
575
+ }
576
+ // Handle WTO cycles
577
+ else if (const ICFGCycleWTO* cycle = SVFUtil::dyn_cast<ICFGCycleWTO>(wtoNode))
578
+ {
579
+ if (mergeStatesFromPredecessors(cycle->head()->getICFGNode()))
583
580
  handleCycleWTO(cycle);
584
- }
585
- // Assert false for unknown WTO types
586
- else
587
- {
588
- assert(false && "unknown WTO type!");
589
- }
581
+ }
582
+ // Assert false for unknown WTO types
583
+ else
584
+ {
585
+ assert(false && "unknown WTO type!");
590
586
  }
591
587
  }
592
588
 
@@ -656,7 +652,7 @@ void AbstractInterpretation::recursiveCallPass(const SVF::CallICFGNode *callNode
656
652
  }
657
653
  }
658
654
  }
659
- _postAbsTrace[retNode] = as;
655
+ _abstractTrace[retNode] = as;
660
656
  }
661
657
 
662
658
  bool AbstractInterpretation::isDirectCall(const SVF::CallICFGNode *callNode)
@@ -670,7 +666,7 @@ void AbstractInterpretation::directCallFunPass(const SVF::CallICFGNode *callNode
670
666
  const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite());
671
667
  _callSiteStack.push_back(callNode);
672
668
 
673
- _postAbsTrace[callNode] = as;
669
+ _abstractTrace[callNode] = as;
674
670
 
675
671
  ICFGWTO* wto = _funcToWTO[callfun];
676
672
  handleWTOComponents(wto->getWTOComponents());
@@ -679,7 +675,7 @@ void AbstractInterpretation::directCallFunPass(const SVF::CallICFGNode *callNode
679
675
  // handle Ret node
680
676
  const RetICFGNode *retNode = callNode->getRetICFGNode();
681
677
  // resume ES to callnode
682
- _postAbsTrace[retNode] = _postAbsTrace[callNode];
678
+ _abstractTrace[retNode] = _abstractTrace[callNode];
683
679
  }
684
680
 
685
681
  bool AbstractInterpretation::isIndirectCall(const SVF::CallICFGNode *callNode)
@@ -704,14 +700,14 @@ void AbstractInterpretation::indirectCallFunPass(const SVF::CallICFGNode *callNo
704
700
  if (callfun)
705
701
  {
706
702
  _callSiteStack.push_back(callNode);
707
- _postAbsTrace[callNode] = as;
703
+ _abstractTrace[callNode] = as;
708
704
 
709
705
  ICFGWTO* wto = _funcToWTO[callfun];
710
706
  handleWTOComponents(wto->getWTOComponents());
711
707
  _callSiteStack.pop_back();
712
708
  // handle Ret node
713
709
  const RetICFGNode *retNode = callNode->getRetICFGNode();
714
- _postAbsTrace[retNode] = _postAbsTrace[callNode];
710
+ _abstractTrace[retNode] = _abstractTrace[callNode];
715
711
  }
716
712
  }
717
713
 
@@ -720,54 +716,47 @@ void AbstractInterpretation::indirectCallFunPass(const SVF::CallICFGNode *callNo
720
716
  /// handle wto cycle (loop)
721
717
  void AbstractInterpretation::handleCycleWTO(const ICFGCycleWTO*cycle)
722
718
  {
723
- // Get execution states from predecessor nodes
724
- bool is_feasible = mergeStatesFromPredecessors(cycle->head()->node());
725
- if (!is_feasible)
726
- return;
727
- else
728
- {
729
- const ICFGNode* cycle_head = cycle->head()->node();
730
- // Flag to indicate if we are in the increasing phase
731
- bool increasing = true;
732
- // Infinite loop until a fixpoint is reached,
733
- for (u32_t cur_iter = 0;; cur_iter++)
734
- {
735
- // Start widening or narrowing if cur_iter >= widen threshold (widen delay)
736
- if (cur_iter >= Options::WidenDelay())
719
+ const ICFGNode* cycle_head = cycle->head()->getICFGNode();
720
+ // Flag to indicate if we are in the increasing phase
721
+ bool increasing = true;
722
+ // Infinite loop until a fixpoint is reached,
723
+ for (u32_t cur_iter = 0;; cur_iter++)
724
+ {
725
+ // Start widening or narrowing if cur_iter >= widen threshold (widen delay)
726
+ if (cur_iter >= Options::WidenDelay())
727
+ {
728
+ // Widen or narrow after processing cycle head node
729
+ AbstractState prev_head_state = _abstractTrace[cycle_head];
730
+ handleWTOComponent(cycle->head());
731
+ AbstractState cur_head_state = _abstractTrace[cycle_head];
732
+ if (increasing)
737
733
  {
738
- // Widen or narrow after processing cycle head node
739
- AbstractState prev_head_state = _postAbsTrace[cycle_head];
740
- handleSingletonWTO(cycle->head());
741
- AbstractState cur_head_state = _postAbsTrace[cycle_head];
742
- if (increasing)
743
- {
744
- // Widening phase
745
- _postAbsTrace[cycle_head] = prev_head_state.widening(cur_head_state);
746
- if (_postAbsTrace[cycle_head] == prev_head_state)
747
- {
748
- increasing = false;
749
- continue;
750
- }
751
- }
752
- else
734
+ // Widening phase
735
+ _abstractTrace[cycle_head] = prev_head_state.widening(cur_head_state);
736
+ if (_abstractTrace[cycle_head] == prev_head_state)
753
737
  {
754
- // Widening's fixpoint reached in the widening phase, switch to narrowing
755
- _postAbsTrace[cycle_head] = prev_head_state.narrowing(cur_head_state);
756
- if (_postAbsTrace[cycle_head] == prev_head_state)
757
- {
758
- // Narrowing's fixpoint reached in the narrowing phase, exit loop
759
- break;
760
- }
738
+ increasing = false;
739
+ continue;
761
740
  }
762
741
  }
763
742
  else
764
743
  {
765
- // Handle the cycle head
766
- handleSingletonWTO(cycle->head());
744
+ // Widening's fixpoint reached in the widening phase, switch to narrowing
745
+ _abstractTrace[cycle_head] = prev_head_state.narrowing(cur_head_state);
746
+ if (_abstractTrace[cycle_head] == prev_head_state)
747
+ {
748
+ // Narrowing's fixpoint reached in the narrowing phase, exit loop
749
+ break;
750
+ }
767
751
  }
768
- // Handle the cycle body
769
- handleWTOComponents(cycle->getWTOComponents());
770
752
  }
753
+ else
754
+ {
755
+ // Handle the cycle head
756
+ handleSingletonWTO(cycle->head());
757
+ }
758
+ // Handle the cycle body
759
+ handleWTOComponents(cycle->getWTOComponents());
771
760
  }
772
761
  }
773
762