svf-tools 1.0.1012 → 1.0.1014

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.1012",
3
+ "version": "1.0.1014",
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": {
@@ -161,6 +161,8 @@ public:
161
161
  // │ ┌── ValVarKinds: Types of value variable nodes
162
162
  // │ │ ├── Represents a standard value variable
163
163
  ValNode,
164
+ // │ │ ├── Represents a Function value variable
165
+ FunValNode,
164
166
  // │ │ ├── Represents a GEP value variable
165
167
  GepValNode,
166
168
  // │ │ ├── Represents a return value node
@@ -174,8 +176,10 @@ public:
174
176
  ObjNode,
175
177
  // │ ├── GepObjNode: Represents a GEP object variable
176
178
  GepObjNode,
177
- // │ ├── FIObjNode: Represents a flow-insensitive object node
179
+ // │ └── FIObjNode: Represents a flow-insensitive object node
178
180
  FIObjNode,
181
+ // │ ├──FunObjNode: Types of function object
182
+ FunObjNode,
179
183
  // │ └── DummyObjNode: Dummy node for uninitialized objects
180
184
  DummyObjNode,
181
185
  // └────────
@@ -313,7 +317,7 @@ protected:
313
317
 
314
318
  static inline bool isSVFVarKind(GNodeK n)
315
319
  {
316
- static_assert(DummyObjNode - ValNode == 8,
320
+ static_assert(DummyObjNode - ValNode == 10,
317
321
  "The number of SVFVarKinds has changed, make sure the "
318
322
  "range is correct");
319
323
 
@@ -322,7 +326,7 @@ protected:
322
326
 
323
327
  static inline bool isValVarKinds(GNodeK n)
324
328
  {
325
- static_assert(DummyValNode - ValNode == 4,
329
+ static_assert(DummyValNode - ValNode == 5,
326
330
  "The number of ValVarKinds has changed, make sure the "
327
331
  "range is correct");
328
332
  return n <= DummyValNode && n >= ValNode;
@@ -330,12 +334,20 @@ protected:
330
334
 
331
335
  static inline bool isObjVarKinds(GNodeK n)
332
336
  {
333
- static_assert(DummyObjNode - ObjNode == 3,
337
+ static_assert(DummyObjNode - ObjNode == 4,
334
338
  "The number of ObjVarKinds has changed, make sure the "
335
339
  "range is correct");
336
340
  return n <= DummyObjNode && n >= ObjNode;
337
341
  }
338
342
 
343
+ static inline bool isFIObjVarKinds(GNodeK n)
344
+ {
345
+ static_assert(FunObjNode - FIObjNode == 1,
346
+ "The number of FIObjVarKinds has changed, make sure the "
347
+ "range is correct");
348
+ return n <= FunObjNode && n >= FIObjNode;
349
+ }
350
+
339
351
  static inline bool isVFGNodeKinds(GNodeK n)
340
352
  {
341
353
  static_assert(MInterPhi - Cmp == 24,
@@ -425,7 +425,7 @@ class CallICFGNode : public InterICFGNode
425
425
  friend class SVFIRReader;
426
426
 
427
427
  public:
428
- typedef std::vector<const SVFVar *> ActualParmNodeVec;
428
+ typedef std::vector<const ValVar *> ActualParmNodeVec;
429
429
 
430
430
  protected:
431
431
  const RetICFGNode* ret;
@@ -491,13 +491,13 @@ public:
491
491
  }
492
492
 
493
493
  /// Add actual parameters
494
- inline void addActualParms(const SVFVar *ap)
494
+ inline void addActualParms(const ValVar *ap)
495
495
  {
496
496
  APNodes.push_back(ap);
497
497
  }
498
498
  /// Parameter operations
499
499
  //@{
500
- inline const SVFVar* getArgument(u32_t ArgNo) const
500
+ inline const ValVar* getArgument(u32_t ArgNo) const
501
501
  {
502
502
  return getActualParms()[ArgNo];
503
503
  }
@@ -522,7 +522,7 @@ private:
522
522
  funRetMap[fun] = ret;
523
523
  }
524
524
  /// Add callsite arguments
525
- inline void addCallSiteArgs(CallICFGNode* callBlockNode,const SVFVar* arg)
525
+ inline void addCallSiteArgs(CallICFGNode* callBlockNode,const ValVar* arg)
526
526
  {
527
527
  callBlockNode->addActualParms(arg);
528
528
  callSiteArgsListMap[callBlockNode].push_back(arg);
@@ -545,11 +545,18 @@ private:
545
545
  /// add node into SVFIR
546
546
  //@{
547
547
  /// Add a value (pointer) node
548
- inline NodeID addValNode(const SVFValue* val, NodeID i, const SVFBaseNode* gNode)
548
+ inline NodeID addValNode(const SVFValue* val, NodeID i, const ICFGNode* icfgNode)
549
549
  {
550
- SVFVar *node = new ValVar(val,i, ValVar::ValNode, gNode);
550
+ SVFVar *node = new ValVar(val,i, ValVar::ValNode, icfgNode);
551
551
  return addValNode(val, node, i);
552
552
  }
553
+
554
+ NodeID addFunValNode(const CallGraphNode* callGraphNode, NodeID i, const ICFGNode* icfgNode)
555
+ {
556
+ FunValVar* node = new FunValVar(callGraphNode, i, icfgNode);
557
+ return addValNode(nullptr, node, i);
558
+ }
559
+
553
560
  /// Add a memory obj node
554
561
  inline NodeID addObjNode(const SVFValue* val, NodeID i)
555
562
  {
@@ -557,14 +564,16 @@ private:
557
564
  assert(mem->getId() == i && "not same object id?");
558
565
  return addFIObjNode(mem);
559
566
  }
567
+
568
+ NodeID addFunObjNode(const CallGraphNode* callGraphNode, NodeID id);
560
569
  /// Add a unique return node for a procedure
561
- inline NodeID addRetNode(const SVFFunction* val, NodeID i)
570
+ inline NodeID addRetNode(const CallGraphNode* callGraphNode, NodeID i)
562
571
  {
563
- SVFVar *node = new RetPN(val,i);
564
- return addRetNode(val, node, i);
572
+ SVFVar *node = new RetPN(callGraphNode,i);
573
+ return addRetNode(callGraphNode, node, i);
565
574
  }
566
575
  /// Add a unique vararg node for a procedure
567
- inline NodeID addVarargNode(const SVFFunction* val, NodeID i)
576
+ inline NodeID addVarargNode(const CallGraphNode* val, NodeID i)
568
577
  {
569
578
  SVFVar *node = new VarArgPN(val,i);
570
579
  return addNode(node,i);
@@ -576,6 +585,7 @@ private:
576
585
  NodeID addGepObjNode(const MemObj* obj, const APOffset& apOffset, const NodeID gepId);
577
586
  /// Add a field-insensitive node, this method can only invoked by getFIGepObjNode
578
587
  NodeID addFIObjNode(const MemObj* obj);
588
+
579
589
  //@}
580
590
 
581
591
  /// Add a dummy value/object node according to node ID (llvm value is null)
@@ -628,7 +638,7 @@ private:
628
638
  return addNode(node, i);
629
639
  }
630
640
  /// Add a unique return node for a procedure
631
- inline NodeID addRetNode(const SVFFunction*, SVFVar *node, NodeID i)
641
+ inline NodeID addRetNode(const CallGraphNode*, SVFVar *node, NodeID i)
632
642
  {
633
643
  return addNode(node,i);
634
644
  }
@@ -87,8 +87,7 @@ public:
87
87
  "dummy node do not have value!");
88
88
  assert(!SymbolTableInfo::isBlkObjOrConstantObj(this->getId()) &&
89
89
  "blackhole and constant obj do not have value");
90
- assert(value &&
91
- "value is null (GepObjNode whose basenode is a DummyObj?)");
90
+ assert(value && "value is null (GepObjNode whose basenode is a DummyObj?)");
92
91
  return value;
93
92
  }
94
93
 
@@ -112,7 +111,7 @@ public:
112
111
  bool isConstDataOrAggDataButNotNullPtr() const;
113
112
 
114
113
  /// Whether this is an isolated node on the SVFIR graph
115
- bool isIsolatedNode() const;
114
+ virtual bool isIsolatedNode() const;
116
115
 
117
116
  /// Get name of the LLVM value
118
117
  // TODO: (Optimization) Should it return const reference instead of value?
@@ -127,8 +126,6 @@ public:
127
126
  return inst->getParent()->getParent();
128
127
  else if (auto arg = SVFUtil::dyn_cast<SVFArgument>(value))
129
128
  return arg->getParent();
130
- else if (auto fun = SVFUtil::dyn_cast<SVFFunction>(value))
131
- return fun;
132
129
  }
133
130
  return nullptr;
134
131
  }
@@ -269,10 +266,10 @@ class ValVar: public SVFVar
269
266
  friend class SVFIRReader;
270
267
 
271
268
  private:
272
- const SVFBaseNode* gNode; // constant, gepValvar, retPN, dummy could be null
269
+ const ICFGNode* icfgNode; // icfgnode related to valvar
273
270
  protected:
274
271
  /// Constructor to create an empty ValVar (for SVFIRReader/deserialization)
275
- ValVar(NodeID i, PNODEK ty = ValNode) : SVFVar(i, ty), gNode(nullptr) {}
272
+ ValVar(NodeID i, PNODEK ty = ValNode) : SVFVar(i, ty), icfgNode(nullptr) {}
276
273
 
277
274
  public:
278
275
  /// Methods for support type inquiry through isa, cast, and dyn_cast:
@@ -296,8 +293,8 @@ public:
296
293
  //@}
297
294
 
298
295
  /// Constructor
299
- ValVar(const SVFValue* val, NodeID i, PNODEK ty = ValNode, const SVFBaseNode* node = nullptr)
300
- : SVFVar(val, i, ty), gNode(node)
296
+ ValVar(const SVFValue* val, NodeID i, PNODEK ty = ValNode, const ICFGNode* node = nullptr)
297
+ : SVFVar(val, i, ty), icfgNode(node)
301
298
  {
302
299
  }
303
300
  /// Return name of a LLVM value
@@ -308,9 +305,9 @@ public:
308
305
  return "";
309
306
  }
310
307
 
311
- const SVFBaseNode* getGNode() const
308
+ const ICFGNode* getICFGNode() const
312
309
  {
313
- return gNode;
310
+ return icfgNode;
314
311
  }
315
312
 
316
313
  virtual const std::string toString() const;
@@ -540,7 +537,7 @@ class FIObjVar: public ObjVar
540
537
  friend class SVFIRWriter;
541
538
  friend class SVFIRReader;
542
539
 
543
- private:
540
+ protected:
544
541
  /// Constructor to create empty ObjVar (for SVFIRReader/deserialization)
545
542
  FIObjVar(NodeID i, PNODEK ty = FIObjNode) : ObjVar(i, ty) {}
546
543
 
@@ -553,19 +550,19 @@ public:
553
550
  }
554
551
  static inline bool classof(const ObjVar* node)
555
552
  {
556
- return node->getNodeKind() == SVFVar::FIObjNode;
553
+ return isFIObjVarKinds(node->getNodeKind());
557
554
  }
558
555
  static inline bool classof(const SVFVar* node)
559
556
  {
560
- return node->getNodeKind() == SVFVar::FIObjNode;
557
+ return isFIObjVarKinds(node->getNodeKind());
561
558
  }
562
559
  static inline bool classof(const GenericPAGNodeTy* node)
563
560
  {
564
- return node->getNodeKind() == SVFVar::FIObjNode;
561
+ return isFIObjVarKinds(node->getNodeKind());
565
562
  }
566
563
  static inline bool classof(const SVFBaseNode* node)
567
564
  {
568
- return node->getNodeKind() == SVFVar::FIObjNode;
565
+ return isFIObjVarKinds(node->getNodeKind());
569
566
  }
570
567
  //@}
571
568
 
@@ -587,6 +584,111 @@ public:
587
584
  virtual const std::string toString() const;
588
585
  };
589
586
 
587
+ class CallGraphNode;
588
+
589
+ class FunValVar : public ValVar
590
+ {
591
+ friend class SVFIRWriter;
592
+ friend class SVFIRReader;
593
+ private:
594
+ const CallGraphNode* callGraphNode;
595
+
596
+ public:
597
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
598
+ //@{
599
+ static inline bool classof(const FunValVar*)
600
+ {
601
+ return true;
602
+ }
603
+ static inline bool classof(const ValVar* node)
604
+ {
605
+ return node->getNodeKind() == FunValNode;
606
+ }
607
+ static inline bool classof(const SVFVar* node)
608
+ {
609
+ return node->getNodeKind() == FunValNode;
610
+ }
611
+ static inline bool classof(const GenericPAGNodeTy* node)
612
+ {
613
+ return node->getNodeKind() == FunValNode;
614
+ }
615
+ static inline bool classof(const SVFBaseNode* node)
616
+ {
617
+ return node->getNodeKind() == FunValNode;
618
+ }
619
+ //@}
620
+
621
+ inline const CallGraphNode* getCallGraphNode() const
622
+ {
623
+ return callGraphNode;
624
+ }
625
+
626
+ /// Constructor
627
+ FunValVar(const CallGraphNode* cgn, NodeID i, const ICFGNode* icn,
628
+ PNODEK ty = FunValNode)
629
+ : ValVar(nullptr, i, ty, icn), callGraphNode(cgn)
630
+ {
631
+
632
+ }
633
+
634
+ virtual const std::string toString() const;
635
+ };
636
+
637
+ class FunObjVar : public FIObjVar
638
+ {
639
+ friend class SVFIRWriter;
640
+ friend class SVFIRReader;
641
+
642
+ private:
643
+ const CallGraphNode* callGraphNode;
644
+
645
+ private:
646
+ /// Constructor to create empty ObjVar (for SVFIRReader/deserialization)
647
+ FunObjVar(NodeID i, PNODEK ty = FunObjNode) : FIObjVar(i, ty) {}
648
+
649
+ public:
650
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
651
+ //@{
652
+ static inline bool classof(const FunObjVar*)
653
+ {
654
+ return true;
655
+ }
656
+ static inline bool classof(const FIObjVar* node)
657
+ {
658
+ return node->getNodeKind() == FunObjNode;
659
+ }
660
+ static inline bool classof(const ObjVar* node)
661
+ {
662
+ return node->getNodeKind() == FunObjNode;
663
+ }
664
+ static inline bool classof(const SVFVar* node)
665
+ {
666
+ return node->getNodeKind() == FunObjNode;
667
+ }
668
+ static inline bool classof(const GenericPAGNodeTy* node)
669
+ {
670
+ return node->getNodeKind() == FunObjNode;
671
+ }
672
+ static inline bool classof(const SVFBaseNode* node)
673
+ {
674
+ return node->getNodeKind() == FunObjNode;
675
+ }
676
+ //@}
677
+
678
+ /// Constructor
679
+ FunObjVar(const CallGraphNode* cgNode, NodeID i, const MemObj* mem,
680
+ PNODEK ty = FunObjNode);
681
+
682
+ inline const CallGraphNode* getCallGraphNode() const
683
+ {
684
+ return callGraphNode;
685
+ }
686
+
687
+ virtual bool isIsolatedNode() const;
688
+
689
+ virtual const std::string toString() const;
690
+ };
691
+
590
692
  /*
591
693
  * Unique Return node of a procedure
592
694
  */
@@ -595,6 +697,8 @@ class RetPN: public ValVar
595
697
  friend class SVFIRWriter;
596
698
  friend class SVFIRReader;
597
699
 
700
+ private:
701
+ const CallGraphNode* callGraphNode;
598
702
  private:
599
703
  /// Constructor to create empty RetPN (for SVFIRReader/deserialization)
600
704
  RetPN(NodeID i) : ValVar(i, RetNode) {}
@@ -623,15 +727,20 @@ public:
623
727
  }
624
728
  //@}
625
729
 
730
+
626
731
  /// Constructor
627
- RetPN(const SVFFunction* val, NodeID i) : ValVar(val, i, RetNode) {}
732
+ RetPN(const CallGraphNode* node, NodeID i);
628
733
 
629
- /// Return name of a LLVM value
630
- const std::string getValueName() const
734
+ inline const CallGraphNode* getCallGraphNode() const
631
735
  {
632
- return value->getName() + "_ret";
736
+ return callGraphNode;
633
737
  }
634
738
 
739
+ virtual const SVFFunction* getFunction() const;
740
+
741
+ /// Return name of a LLVM value
742
+ const std::string getValueName() const;
743
+
635
744
  virtual const std::string toString() const;
636
745
  };
637
746
 
@@ -642,6 +751,8 @@ class VarArgPN: public ValVar
642
751
  {
643
752
  friend class SVFIRWriter;
644
753
  friend class SVFIRReader;
754
+ private:
755
+ const CallGraphNode* callGraphNode;
645
756
 
646
757
  private:
647
758
  /// Constructor to create empty VarArgPN (for SVFIRReader/deserialization)
@@ -672,13 +783,12 @@ public:
672
783
  //@}
673
784
 
674
785
  /// Constructor
675
- VarArgPN(const SVFFunction* val, NodeID i) : ValVar(val, i, VarargNode) {}
786
+ VarArgPN(const CallGraphNode* node, NodeID i) : ValVar(nullptr, i, VarargNode), callGraphNode(node) {}
787
+
788
+ virtual const SVFFunction* getFunction() const;
676
789
 
677
790
  /// Return name of a LLVM value
678
- inline const std::string getValueName() const
679
- {
680
- return value->getName() + "_vararg";
681
- }
791
+ const std::string getValueName() const;
682
792
 
683
793
  virtual const std::string toString() const;
684
794
  };
@@ -351,9 +351,11 @@ inline bool isArgOfUncalledFunction(const SVFValue* svfval)
351
351
  return false;
352
352
  }
353
353
 
354
+ const ObjVar* getObjVarOfValVar(const ValVar* valVar);
355
+
354
356
  /// Return thread fork function
355
357
  //@{
356
- inline const SVFVar* getForkedFun(const CallICFGNode *inst)
358
+ inline const ValVar* getForkedFun(const CallICFGNode *inst)
357
359
  {
358
360
  return ThreadAPI::getThreadAPI()->getForkedFun(inst);
359
361
  }
@@ -432,7 +434,7 @@ inline bool isBarrierWaitCall(const CallICFGNode* cs)
432
434
 
433
435
  /// Return sole argument of the thread routine
434
436
  //@{
435
- inline const SVFVar* getActualParmAtForkSite(const CallICFGNode* cs)
437
+ inline const ValVar* getActualParmAtForkSite(const CallICFGNode* cs)
436
438
  {
437
439
  return ThreadAPI::getThreadAPI()->getActualParmAtForkSite(cs);
438
440
  }
@@ -39,6 +39,8 @@ class SVFModule;
39
39
  class ICFGNode;
40
40
  class CallICFGNode;
41
41
  class SVFVar;
42
+ class ValVar;
43
+ class ObjVar;
42
44
 
43
45
  /*
44
46
  * ThreadAPI class contains interfaces for pthread programs
@@ -124,14 +126,14 @@ public:
124
126
  //@{
125
127
  /// Return the first argument of the call,
126
128
  /// Note that, it is the pthread_t pointer
127
- const SVFVar* getForkedThread(const CallICFGNode *inst) const;
129
+ const ValVar* getForkedThread(const CallICFGNode *inst) const;
128
130
  /// Return the third argument of the call,
129
131
  /// Note that, it could be function type or a void* pointer
130
- const SVFVar* getForkedFun(const CallICFGNode *inst) const;
132
+ const ValVar* getForkedFun(const CallICFGNode *inst) const;
131
133
 
132
134
  /// Return the forth argument of the call,
133
135
  /// Note that, it is the sole argument of start routine ( a void* pointer )
134
- const SVFVar* getActualParmAtForkSite(const CallICFGNode *inst) const;
136
+ const ValVar* getActualParmAtForkSite(const CallICFGNode *inst) const;
135
137
 
136
138
  /// Return the formal parm of forked function (the first arg in pthread)
137
139
  const SVFVar* getFormalParmOfForkedFun(const SVFFunction* F) const;
@@ -130,8 +130,7 @@ void AbsExtAPI::initExtFunMap()
130
130
  assert(lb.getInterval().is_numeral() && ub.getInterval().is_numeral());
131
131
  num.getInterval().set_to_top();
132
132
  num.getInterval().meet_with(IntervalValue(lb.getInterval().lb(), ub.getInterval().ub()));
133
- const ICFGNode* node = SVFUtil::cast<ICFGNode>(
134
- SVFUtil::cast<ValVar>(callNode->getArgument(0))->getGNode());
133
+ const ICFGNode* node = SVFUtil::cast<ValVar>(callNode->getArgument(0))->getICFGNode();
135
134
  for (const SVFStmt* stmt: node->getSVFStmts())
136
135
  {
137
136
  if (SVFUtil::isa<LoadStmt>(stmt))
@@ -30,6 +30,7 @@
30
30
  #include "SVFIR/SVFIR.h"
31
31
  #include "Util/Options.h"
32
32
  #include "Util/WorkList.h"
33
+ #include "Graphs/CallGraph.h"
33
34
  #include <cmath>
34
35
 
35
36
  using namespace SVF;
@@ -646,9 +647,9 @@ void AbstractInterpretation::indirectCallFunPass(const SVF::CallICFGNode *callNo
646
647
  AbstractValue Addrs = as[call_id];
647
648
  NodeID addr = *Addrs.getAddrs().begin();
648
649
  SVFVar *func_var = svfir->getGNode(AbstractState::getInternalID(addr));
649
- const SVFFunction *callfun = SVFUtil::dyn_cast<SVFFunction>(func_var->getValue());
650
- if (callfun)
650
+ if(const FunObjVar*funObjVar = SVFUtil::dyn_cast<FunObjVar>(func_var))
651
651
  {
652
+ const SVFFunction* callfun = funObjVar->getCallGraphNode()->getFunction();
652
653
  callSiteStack.push_back(callNode);
653
654
  abstractTrace[callNode] = as;
654
655
 
@@ -656,7 +657,7 @@ void AbstractInterpretation::indirectCallFunPass(const SVF::CallICFGNode *callNo
656
657
  handleWTOComponents(wto->getWTOComponents());
657
658
  callSiteStack.pop_back();
658
659
  // handle Ret node
659
- const RetICFGNode *retNode = callNode->getRetICFGNode();
660
+ const RetICFGNode* retNode = callNode->getRetICFGNode();
660
661
  abstractTrace[retNode] = abstractTrace[callNode];
661
662
  }
662
663
  }
@@ -786,7 +786,7 @@ struct DOTGraphTraits<ConstraintGraph*> : public DOTGraphTraits<SVFIR*>
786
786
  {
787
787
  // print the whole value
788
788
  if (!SVFUtil::isa<DummyValVar>(node) && !SVFUtil::isa<DummyObjVar>(node))
789
- rawstr << node->getId() << ":" << node->getValue()->toString();
789
+ rawstr << node->toString();
790
790
  else
791
791
  rawstr << node->getId() << ":";
792
792
 
@@ -52,7 +52,8 @@ void PTACallGraphEdge::addDirectCallSite(const CallICFGNode* call)
52
52
 
53
53
  void PTACallGraphEdge::addInDirectCallSite(const CallICFGNode* call)
54
54
  {
55
- assert((nullptr == call->getCalledFunction() || nullptr == SVFUtil::dyn_cast<SVFFunction> (SVFUtil::getForkedFun(call)->getValue())) && "not an indirect callsite??");
55
+ assert((nullptr == call->getCalledFunction() || !SVFUtil::isa<FunValVar>(SVFUtil::getForkedFun(call))) &&
56
+ "not an indirect callsite??");
56
57
  indirectCalls.insert(call);
57
58
  }
58
59
  //@}
@@ -32,6 +32,7 @@
32
32
  #include "Util/ThreadAPI.h"
33
33
  #include "SVFIR/SVFIR.h"
34
34
  #include "MemoryModel/PointerAnalysisImpl.h"
35
+ #include "Graphs/CallGraph.h"
35
36
 
36
37
  using namespace SVF;
37
38
  using namespace SVFUtil;
@@ -73,8 +74,8 @@ void ThreadCallGraph::updateCallGraph(PointerAnalysis* pta)
73
74
  // Fork sites
74
75
  for (CallSiteSet::const_iterator it = forksitesBegin(), eit = forksitesEnd(); it != eit; ++it)
75
76
  {
76
- const SVFVar* forkedval = tdAPI->getForkedFun(*it);
77
- if(SVFUtil::dyn_cast<SVFFunction>(forkedval->getValue())==nullptr)
77
+ const ValVar* forkedval = tdAPI->getForkedFun(*it);
78
+ if(SVFUtil::dyn_cast<FunValVar>(forkedval)==nullptr)
78
79
  {
79
80
  SVFIR* pag = pta->getPAG();
80
81
  const NodeBS targets = pta->getPts(forkedval->getId()).toNodeBS();
@@ -85,7 +86,7 @@ void ThreadCallGraph::updateCallGraph(PointerAnalysis* pta)
85
86
  const MemObj* obj = pag->getObject(objPN);
86
87
  if(obj->isFunction())
87
88
  {
88
- const SVFFunction* svfCallee = SVFUtil::cast<SVFFunction>(obj->getValue());
89
+ const SVFFunction* svfCallee = SVFUtil::cast<CallGraphNode>(obj->getGNode())->getFunction();
89
90
  this->addIndirectForkEdge(*it, svfCallee);
90
91
  }
91
92
  }
@@ -126,7 +127,8 @@ bool ThreadCallGraph::addDirectForkEdge(const CallICFGNode* cs)
126
127
  {
127
128
 
128
129
  PTACallGraphNode* caller = getCallGraphNode(cs->getCaller());
129
- const SVFFunction* forkee = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getForkedFun(cs)->getValue());
130
+ const SVFFunction* forkee = SVFUtil::dyn_cast<FunValVar>(tdAPI->getForkedFun(cs))
131
+ ->getCallGraphNode()->getFunction();
130
132
  assert(forkee && "callee does not exist");
131
133
  PTACallGraphNode* callee = getCallGraphNode(forkee->getDefFunForMultipleModule());
132
134
  CallSiteID csId = addCallSite(cs, callee->getFunction());
@@ -185,7 +187,10 @@ void ThreadCallGraph::addDirectJoinEdge(const CallICFGNode* cs,const CallSiteSet
185
187
  for (CallSiteSet::const_iterator it = forkset.begin(), eit = forkset.end(); it != eit; ++it)
186
188
  {
187
189
 
188
- const SVFFunction* threadRoutineFun = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getForkedFun(*it)->getValue());
190
+ const SVFFunction* threadRoutineFun =
191
+ SVFUtil::dyn_cast<FunValVar>(tdAPI->getForkedFun(*it))
192
+ ->getCallGraphNode()
193
+ ->getFunction();
189
194
  assert(threadRoutineFun && "thread routine function does not exist");
190
195
  PTACallGraphNode* threadRoutineFunNode = getCallGraphNode(threadRoutineFun);
191
196
  CallSiteID csId = addCallSite(cs, threadRoutineFun);
@@ -1090,7 +1090,7 @@ const SVFValue* BinaryOPVFGNode::getValue() const
1090
1090
 
1091
1091
  const SVFValue* PHIVFGNode::getValue() const
1092
1092
  {
1093
- return getRes()->getValue();
1093
+ return getRes()->hasValue() ? getRes()->getValue(): nullptr;
1094
1094
  }
1095
1095
 
1096
1096
  const SVFValue* ArgumentVFGNode::getValue() const
@@ -33,6 +33,7 @@
33
33
  #include "MTA/MHP.h"
34
34
  #include "MTA/LockAnalysis.h"
35
35
  #include "Graphs/ThreadCallGraph.h"
36
+ #include "Graphs/CallGraph.h"
36
37
 
37
38
  using namespace SVF;
38
39
 
@@ -49,8 +50,8 @@ void MTAStat::performThreadCallGraphStat(ThreadCallGraph* tcg)
49
50
  for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->forksitesBegin(), eit = tcg->forksitesEnd(); it != eit; ++it)
50
51
  {
51
52
  bool indirectfork = false;
52
- const SVFFunction* spawnee = SVFUtil::dyn_cast<SVFFunction>(tcg->getThreadAPI()->getForkedFun(*it)->getValue());
53
- if(spawnee==nullptr)
53
+ const ValVar* pValVar = tcg->getThreadAPI()->getForkedFun(*it);
54
+ if(!SVFUtil::isa<FunValVar>(pValVar))
54
55
  {
55
56
  numOfIndForksite++;
56
57
  indirectfork = true;
@@ -36,6 +36,7 @@
36
36
  #include "Util/PTAStat.h"
37
37
  #include "Graphs/ThreadCallGraph.h"
38
38
  #include "Graphs/ICFG.h"
39
+ #include "Graphs/CallGraph.h"
39
40
  #include "Util/CallGraphBuilder.h"
40
41
 
41
42
  #include <iomanip>
@@ -399,7 +400,7 @@ void PointerAnalysis::resolveIndCalls(const CallICFGNode* cs, const PointsTo& ta
399
400
 
400
401
  if(obj->isFunction())
401
402
  {
402
- const SVFFunction* calleefun = SVFUtil::cast<SVFFunction>(obj->getValue());
403
+ const SVFFunction* calleefun = SVFUtil::cast<CallGraphNode>(obj->getGNode())->getFunction();
403
404
  const SVFFunction* callee = calleefun->getDefFunForMultipleModule();
404
405
 
405
406
  if(SVFUtil::matchArgs(cs, callee) == false)
@@ -34,6 +34,8 @@
34
34
  #include <fstream>
35
35
  #include <sstream>
36
36
 
37
+ #include "Graphs/CallGraph.h"
38
+
37
39
  using namespace SVF;
38
40
  using namespace SVFUtil;
39
41
  using namespace std;
@@ -521,11 +523,11 @@ void BVDataPTAImpl::onTheFlyThreadCallGraphSolve(const CallSiteToFunPtrMap& call
521
523
  for(CallSiteSet::const_iterator it = tdCallGraph->forksitesBegin(),
522
524
  eit = tdCallGraph->forksitesEnd(); it != eit; ++it)
523
525
  {
524
- const SVFValue* forkedVal =tdCallGraph->getThreadAPI()->getForkedFun(*it)->getValue();
525
- if(SVFUtil::dyn_cast<SVFFunction>(forkedVal) == nullptr)
526
+ const ValVar* pVar = tdCallGraph->getThreadAPI()->getForkedFun(*it);
527
+ if(SVFUtil::dyn_cast<FunValVar>(pVar) == nullptr)
526
528
  {
527
529
  SVFIR *pag = this->getPAG();
528
- const NodeBS targets = this->getPts(pag->getValueNode(forkedVal)).toNodeBS();
530
+ const NodeBS targets = this->getPts(pVar->getId()).toNodeBS();
529
531
  for(NodeBS::iterator ii = targets.begin(), ie = targets.end(); ii != ie; ++ii)
530
532
  {
531
533
  if(ObjVar *objPN = SVFUtil::dyn_cast<ObjVar>(pag->getGNode(*ii)))
@@ -533,7 +535,7 @@ void BVDataPTAImpl::onTheFlyThreadCallGraphSolve(const CallSiteToFunPtrMap& call
533
535
  const MemObj *obj = pag->getObject(objPN);
534
536
  if(obj->isFunction())
535
537
  {
536
- const SVFFunction *svfForkedFun = SVFUtil::cast<SVFFunction>(obj->getValue());
538
+ const SVFFunction *svfForkedFun = SVFUtil::cast<CallGraphNode>(obj->getGNode())->getFunction();
537
539
  if(tdCallGraph->addIndirectForkEdge(*it, svfForkedFun))
538
540
  newForkEdges[*it].insert(svfForkedFun);
539
541
  }
@@ -195,7 +195,7 @@ SaberCondAllocator::evaluateTestNullLikeExpr(const BranchStmt *branchStmt, const
195
195
  // br i1 false, label %44, label %75, !dbg !7669 { "ln": 2033, "cl": 7, "fl": "re_lexer.c" }
196
196
  return Condition::nullExpr();
197
197
  }
198
- if (isTestNullExpr(SVFUtil::cast<ICFGNode>(condVar->getGNode())))
198
+ if (isTestNullExpr(SVFUtil::cast<ICFGNode>(condVar->getICFGNode())))
199
199
  {
200
200
  // succ is then branch
201
201
  if (succ1 == succ)
@@ -204,7 +204,7 @@ SaberCondAllocator::evaluateTestNullLikeExpr(const BranchStmt *branchStmt, const
204
204
  else
205
205
  return getTrueCond();
206
206
  }
207
- if (isTestNotNullExpr(SVFUtil::cast<ICFGNode>(condVar->getGNode())))
207
+ if (isTestNotNullExpr(condVar->getICFGNode()))
208
208
  {
209
209
  // succ is then branch
210
210
  if (succ1 == succ)
@@ -82,11 +82,8 @@ void SaberSVFGBuilder::collectGlobals(BVDataPTAImpl* pta)
82
82
  if(SVFUtil::isa<DummyObjVar>(pag->getGNode(gepobj->getBaseNode())))
83
83
  continue;
84
84
  }
85
- if(const SVFValue* val = pagNode->getValue())
86
- {
87
- if(SVFUtil::isa<SVFGlobalValue>(val))
88
- worklist.push_back(it->first);
89
- }
85
+ if(pagNode->hasValue() && SVFUtil::isa<SVFGlobalValue>(pagNode->getValue()))
86
+ worklist.push_back(it->first);
90
87
  }
91
88
 
92
89
  NodeToPTSSMap cachedPtsMap;
@@ -138,7 +135,7 @@ PointsTo& SaberSVFGBuilder::CollectPtsChain(BVDataPTAImpl* pta, NodeID id, NodeT
138
135
  if(pta->isFIObjNode(baseId) && pag->getGNode(baseId)->hasValue())
139
136
  {
140
137
  ValVar* valVar = SVFUtil::dyn_cast<ValVar>(pag->getGNode(baseId));
141
- if(valVar && valVar->getGNode() && SVFUtil::isExtCall(SVFUtil::cast<ICFGNode>(valVar->getGNode())))
138
+ if(valVar && valVar->getICFGNode() && SVFUtil::isExtCall(valVar->getICFGNode()))
142
139
  {
143
140
  return pts;
144
141
  }
@@ -224,6 +224,8 @@ cJSON* SVFIRWriter::virtToJson(const SVFVar* var)
224
224
  CASE(FIObjNode, FIObjVar);
225
225
  CASE(DummyValNode, DummyValVar);
226
226
  CASE(DummyObjNode, DummyObjVar);
227
+ CASE(FunObjNode, FunObjVar);
228
+ CASE(FunValNode, FunValVar);
227
229
  #undef CASE
228
230
  }
229
231
  }
@@ -472,6 +472,17 @@ NodeID SVFIR::addFIObjNode(const MemObj* obj)
472
472
  return addObjNode(obj->getValue(), node, obj->getId());
473
473
  }
474
474
 
475
+ NodeID SVFIR::addFunObjNode(const CallGraphNode* callGraphNode, NodeID id)
476
+ {
477
+ const MemObj* mem = getMemObj(callGraphNode->getFunction());
478
+ assert(mem->getId() == id && "not same object id?");
479
+ //assert(findPAGNode(i) == false && "this node should not be created before");
480
+ NodeID base = mem->getId();
481
+ memToFieldsMap[base].set(mem->getId());
482
+ FunObjVar*node = new FunObjVar(callGraphNode, mem->getId(), mem);
483
+ return addObjNode(mem->getValue(), node, mem->getId());
484
+ }
485
+
475
486
  /*!
476
487
  * Get all fields object nodes of an object
477
488
  */
@@ -675,9 +686,15 @@ bool SVFIR::isValidTopLevelPtr(const SVFVar* node)
675
686
  {
676
687
  if (SVFUtil::isa<ValVar>(node))
677
688
  {
678
- if (isValidPointer(node->getId()) && node->hasValue())
689
+ if (isValidPointer(node->getId()))
679
690
  {
680
- return !SVFUtil::isArgOfUncalledFunction(node->getValue());
691
+ // TODO: after svf value is removed, we use type to determine top level ptr
692
+ if (SVFUtil::isa<RetPN>(node) || SVFUtil::isa<VarArgPN>(node) || SVFUtil::isa<FunValVar>(node))
693
+ {
694
+ return true;
695
+ }
696
+ else if(node->hasValue())
697
+ return !SVFUtil::isArgOfUncalledFunction(node->getValue());
681
698
  }
682
699
  }
683
700
  return false;
@@ -30,6 +30,7 @@
30
30
  #include "SVFIR/SVFVariables.h"
31
31
  #include "Util/Options.h"
32
32
  #include "Util/SVFUtil.h"
33
+ #include "Graphs/CallGraph.h"
33
34
 
34
35
  using namespace SVF;
35
36
  using namespace SVFUtil;
@@ -52,11 +53,12 @@ SVFVar::SVFVar(const SVFValue* val, NodeID i, PNODEK k) :
52
53
  break;
53
54
  }
54
55
  case RetNode:
56
+ case FunObjNode:
55
57
  {
56
- assert(val != nullptr && "value is nullptr for RetNode");
57
- isPtr = SVFUtil::cast<SVFFunction>(val)->getReturnType()->isPointerTy();
58
+ // to be completed in derived class
58
59
  break;
59
60
  }
61
+ case FunValNode:
60
62
  case VarargNode:
61
63
  case DummyValNode:
62
64
  {
@@ -85,8 +87,6 @@ bool SVFVar::isIsolatedNode() const
85
87
  return true;
86
88
  else if (isConstDataOrAggDataButNotNullPtr())
87
89
  return true;
88
- else if (value && SVFUtil::isa<SVFFunction>(value))
89
- return SVFUtil::cast<SVFFunction>(value)->isIntrinsic();
90
90
  else
91
91
  return false;
92
92
  }
@@ -144,6 +144,21 @@ const std::string GepValVar::toString() const
144
144
  return rawstr.str();
145
145
  }
146
146
 
147
+ RetPN::RetPN(const CallGraphNode* node, NodeID i) : ValVar(i, RetNode), callGraphNode(node)
148
+ {
149
+ isPtr = node->getFunction()->getReturnType()->isPointerTy();
150
+ }
151
+
152
+ const SVFFunction* RetPN::getFunction() const
153
+ {
154
+ return callGraphNode->getFunction();
155
+ }
156
+
157
+ const std::string RetPN::getValueName() const
158
+ {
159
+ return callGraphNode->getName() + "_ret";
160
+ }
161
+
147
162
  const std::string GepObjVar::toString() const
148
163
  {
149
164
  std::string str;
@@ -170,19 +185,67 @@ const std::string FIObjVar::toString() const
170
185
  return rawstr.str();
171
186
  }
172
187
 
188
+ const std::string FunValVar::toString() const
189
+ {
190
+ std::string str;
191
+ std::stringstream rawstr(str);
192
+ rawstr << "FunValVar ID: " << getId();
193
+ if (Options::ShowSVFIRValue())
194
+ {
195
+ rawstr << "\n";
196
+ rawstr << callGraphNode->getName();
197
+ }
198
+ return rawstr.str();
199
+ }
200
+
201
+ FunObjVar::FunObjVar(const CallGraphNode* cgNode, NodeID i, const MemObj* mem,
202
+ PNODEK ty)
203
+ : FIObjVar(nullptr, i, mem, ty), callGraphNode(cgNode)
204
+ {
205
+ isPtr = callGraphNode->getFunction()->getType()->isPointerTy();
206
+ }
207
+
208
+ bool FunObjVar::isIsolatedNode() const
209
+ {
210
+ return callGraphNode->getFunction()->isIntrinsic();
211
+ }
212
+
213
+ const std::string FunObjVar::toString() const
214
+ {
215
+ std::string str;
216
+ std::stringstream rawstr(str);
217
+ rawstr << "FunObjVar ID: " << getId() << " (base object)";
218
+ if (Options::ShowSVFIRValue())
219
+ {
220
+ rawstr << "\n";
221
+ rawstr << callGraphNode->getName();
222
+ }
223
+ return rawstr.str();
224
+ }
225
+
173
226
  const std::string RetPN::toString() const
174
227
  {
175
228
  std::string str;
176
229
  std::stringstream rawstr(str);
177
- rawstr << "RetPN ID: " << getId() << " unique return node for function " << SVFUtil::cast<SVFFunction>(value)->getName();
230
+ rawstr << "RetPN ID: " << getId() << " unique return node for function " << callGraphNode->getName();
178
231
  return rawstr.str();
179
232
  }
180
233
 
234
+ const SVFFunction* VarArgPN::getFunction() const
235
+ {
236
+ return callGraphNode->getFunction();
237
+ }
238
+
239
+ const std::string VarArgPN::getValueName() const
240
+ {
241
+ return callGraphNode->getName() + "_vararg";
242
+ }
243
+
181
244
  const std::string VarArgPN::toString() const
182
245
  {
183
246
  std::string str;
184
247
  std::stringstream rawstr(str);
185
- rawstr << "VarArgPN ID: " << getId() << " Var arg node for function " << SVFUtil::cast<SVFFunction>(value)->getName();
248
+ rawstr << "VarArgPN ID: " << getId() << " Var arg node for function " << callGraphNode->getName();
186
249
  return rawstr.str();
187
250
  }
188
251
 
@@ -88,15 +88,15 @@ ThreadCallGraph* CallGraphBuilder::buildThreadCallGraph()
88
88
  {
89
89
  const CallICFGNode* cs = cast<CallICFGNode>(inst);
90
90
  cg->addForksite(cs);
91
- const SVFFunction* forkee = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getForkedFun(cs)->getValue());
92
- if (forkee)
91
+ const ValVar* svfVar = tdAPI->getForkedFun(cs);
92
+ if (SVFUtil::isa<FunValVar>(svfVar))
93
93
  {
94
94
  cg->addDirectForkEdge(cs);
95
95
  }
96
96
  // indirect call to the start routine function
97
97
  else
98
98
  {
99
- cg->addThreadForkEdgeSetMap(cs,nullptr);
99
+ cg->addThreadForkEdgeSetMap(cs, nullptr);
100
100
  }
101
101
  }
102
102
  }
@@ -423,4 +423,11 @@ const SVFFunction* SVFUtil::getProgEntryFunction()
423
423
  return (fun->getFunction());
424
424
  }
425
425
  return nullptr;
426
+ }
427
+
428
+
429
+ const ObjVar* SVFUtil::getObjVarOfValVar(const SVF::ValVar* valVar)
430
+ {
431
+ assert(valVar->getInEdges().size() == 1);
432
+ return SVFUtil::dyn_cast<ObjVar>((*valVar->getInEdges().begin())->getSrcNode());
426
433
  }
@@ -161,13 +161,13 @@ bool ThreadAPI::isTDBarWait(const CallICFGNode *inst) const
161
161
  }
162
162
 
163
163
 
164
- const SVFVar* ThreadAPI::getForkedThread(const CallICFGNode *inst) const
164
+ const ValVar* ThreadAPI::getForkedThread(const CallICFGNode *inst) const
165
165
  {
166
166
  assert(isTDFork(inst) && "not a thread fork function!");
167
167
  return inst->getArgument(0);
168
168
  }
169
169
 
170
- const SVFVar* ThreadAPI::getForkedFun(const CallICFGNode *inst) const
170
+ const ValVar* ThreadAPI::getForkedFun(const CallICFGNode *inst) const
171
171
  {
172
172
  assert(isTDFork(inst) && "not a thread fork function!");
173
173
  return inst->getArgument(2);
@@ -175,7 +175,7 @@ const SVFVar* ThreadAPI::getForkedFun(const CallICFGNode *inst) const
175
175
 
176
176
  /// Return the forth argument of the call,
177
177
  /// Note that, it is the sole argument of start routine ( a void* pointer )
178
- const SVFVar* ThreadAPI::getActualParmAtForkSite(const CallICFGNode *inst) const
178
+ const ValVar* ThreadAPI::getActualParmAtForkSite(const CallICFGNode *inst) const
179
179
  {
180
180
  assert(isTDFork(inst) && "not a thread fork function!");
181
181
  return inst->getArgument(3);
@@ -54,6 +54,7 @@ public:
54
54
  typedef Map<const GlobalVariable*, GlobalVariable*> GlobalDefToRepMapTy;
55
55
 
56
56
  typedef Map<const Function*, SVFFunction*> LLVMFun2SVFFunMap;
57
+ typedef Map<const Function*, CallGraphNode*> LLVMFun2CallGraphNodeMap;
57
58
  typedef Map<const BasicBlock*, SVFBasicBlock*> LLVMBB2SVFBBMap;
58
59
  typedef Map<const Instruction*, SVFInstruction*> LLVMInst2SVFInstMap;
59
60
  typedef Map<const Argument*, SVFArgument*> LLVMArgument2SVFArgumentMap;
@@ -89,6 +90,7 @@ private:
89
90
  GlobalDefToRepMapTy GlobalDefToRepMap;
90
91
 
91
92
  LLVMFun2SVFFunMap LLVMFunc2SVFFunc; ///< Map an LLVM Function to an SVF Function
93
+ LLVMFun2CallGraphNodeMap LLVMFunc2CallGraphNode; ///< Map an LLVM Function to an CallGraph Node
92
94
  LLVMBB2SVFBBMap LLVMBB2SVFBB;
93
95
  LLVMInst2SVFInstMap LLVMInst2SVFInst;
94
96
  LLVMArgument2SVFArgumentMap LLVMArgument2SVFArgument;
@@ -170,6 +172,8 @@ public:
170
172
  LLVMFunc2SVFFunc[func] = svfFunc;
171
173
  setValueAttr(func,svfFunc);
172
174
  }
175
+ void addFunctionMap(const Function* func, CallGraphNode* svfFunc);
176
+
173
177
  inline void addBasicBlockMap(const BasicBlock* bb, SVFBasicBlock* svfBB)
174
178
  {
175
179
  LLVMBB2SVFBB[bb] = svfBB;
@@ -234,6 +238,13 @@ public:
234
238
  return it->second;
235
239
  }
236
240
 
241
+ inline CallGraphNode* getCallGraphNode(const Function* fun) const
242
+ {
243
+ LLVMFun2CallGraphNodeMap::const_iterator it = LLVMFunc2CallGraphNode.find(fun);
244
+ assert(it!=LLVMFunc2CallGraphNode.end() && "CallGraph Node not found!");
245
+ return it->second;
246
+ }
247
+
237
248
  inline SVFBasicBlock* getSVFBasicBlock(const BasicBlock* bb) const
238
249
  {
239
250
  LLVMBB2SVFBBMap::const_iterator it = LLVMBB2SVFBB.find(bb);
@@ -41,7 +41,7 @@
41
41
  #include "SVF-LLVM/ObjTypeInference.h"
42
42
  #include "llvm/Transforms/Utils/Cloning.h"
43
43
  #include "SVF-LLVM/ICFGBuilder.h"
44
- #include "Graphs/PTACallGraph.h"
44
+ #include "Graphs/CallGraph.h"
45
45
  #include "Util/CallGraphBuilder.h"
46
46
 
47
47
  using namespace std;
@@ -174,6 +174,13 @@ void LLVMModuleSet::build()
174
174
 
175
175
  CallGraphBuilder callGraphBuilder;
176
176
  callgraph = callGraphBuilder.buildSVFIRCallGraph(svfModule);
177
+
178
+ for (const auto& it : *callgraph)
179
+ {
180
+ addFunctionMap(
181
+ SVFUtil::cast<Function>(getLLVMValue(it.second->getFunction())),
182
+ it.second);
183
+ }
177
184
  }
178
185
 
179
186
  void LLVMModuleSet::createSVFDataStructure()
@@ -1210,6 +1217,12 @@ void LLVMModuleSet::dumpModulesToFile(const std::string& suffix)
1210
1217
  }
1211
1218
  }
1212
1219
 
1220
+ void LLVMModuleSet::addFunctionMap(const SVF::Function* func, SVF::CallGraphNode* svfFunc)
1221
+ {
1222
+ LLVMFunc2CallGraphNode[func] = svfFunc;
1223
+ setValueAttr(func,svfFunc);
1224
+ }
1225
+
1213
1226
  void LLVMModuleSet::setValueAttr(const Value* val, SVFValue* svfvalue)
1214
1227
  {
1215
1228
  SVFValue2LLVMValue[svfvalue] = val;
@@ -39,6 +39,7 @@
39
39
  #include "SVFIR/SVFModule.h"
40
40
  #include "SVFIR/SVFValue.h"
41
41
  #include "Util/CallGraphBuilder.h"
42
+ #include "Graphs/CallGraph.h"
42
43
  #include "Util/Options.h"
43
44
  #include "Util/SVFUtil.h"
44
45
 
@@ -78,6 +79,11 @@ SVFIR* SVFIRBuilder::build()
78
79
  if(llvmModuleSet()->hasICFGNode(inst))
79
80
  it.second->gNode = llvmModuleSet()->getICFGNode(inst);
80
81
  }
82
+ else if (const Function* func = SVFUtil::dyn_cast<Function>(llvmModuleSet()->getLLVMValue(
83
+ it.second->getValue())))
84
+ {
85
+ it.second->gNode = llvmModuleSet()->getCallGraphNode(func);
86
+ }
81
87
  }
82
88
 
83
89
  CHGraph* chg = new CHGraph(pag->getModule());
@@ -216,16 +222,26 @@ void SVFIRBuilder::initialiseNodes()
216
222
  if(iter->second == symTable->blkPtrSymID() || iter->second == symTable->nullPtrSymID())
217
223
  continue;
218
224
 
219
- const SVFBaseNode* gNode = nullptr;
225
+ const ICFGNode* icfgNode = nullptr;
220
226
  if (const Instruction* inst =
221
227
  SVFUtil::dyn_cast<Instruction>(llvmModuleSet()->getLLVMValue(iter->first)))
222
228
  {
223
229
  if (llvmModuleSet()->hasICFGNode(inst))
224
230
  {
225
- gNode = llvmModuleSet()->getICFGNode(inst);
231
+ icfgNode = llvmModuleSet()->getICFGNode(inst);
226
232
  }
227
233
  }
228
- pag->addValNode(iter->first, iter->second, gNode);
234
+
235
+ if (const Function* func =
236
+ SVFUtil::dyn_cast<Function>(llvmModuleSet()->getLLVMValue(iter->first)))
237
+ {
238
+ const CallGraphNode* cgn = llvmModuleSet()->getCallGraphNode(func);
239
+ pag->addFunValNode(cgn, iter->second, icfgNode);
240
+ }
241
+ else
242
+ {
243
+ pag->addValNode(iter->first, iter->second, icfgNode);
244
+ }
229
245
  }
230
246
 
231
247
  for (SymbolTableInfo::ValueToIDMapTy::iterator iter =
@@ -235,7 +251,15 @@ void SVFIRBuilder::initialiseNodes()
235
251
  DBOUT(DPAGBuild, outs() << "add obj node " << iter->second << "\n");
236
252
  if(iter->second == symTable->blackholeSymID() || iter->second == symTable->constantSymID())
237
253
  continue;
238
- pag->addObjNode(iter->first, iter->second);
254
+ if (const Function* func = SVFUtil::dyn_cast<Function>(
255
+ llvmModuleSet()->getLLVMValue(iter->first)))
256
+ {
257
+ pag->addFunObjNode(llvmModuleSet()->getCallGraphNode(func), iter->second);
258
+ }
259
+ else
260
+ {
261
+ pag->addObjNode(iter->first, iter->second);
262
+ }
239
263
  }
240
264
 
241
265
  for (SymbolTableInfo::FunToIDMapTy::iterator iter =
@@ -243,7 +267,10 @@ void SVFIRBuilder::initialiseNodes()
243
267
  ++iter)
244
268
  {
245
269
  DBOUT(DPAGBuild, outs() << "add ret node " << iter->second << "\n");
246
- pag->addRetNode(iter->first, iter->second);
270
+ pag->addRetNode(
271
+ llvmModuleSet()->getCallGraphNode(SVFUtil::cast<Function>(
272
+ llvmModuleSet()->getLLVMValue(iter->first))),
273
+ iter->second);
247
274
  }
248
275
 
249
276
  for (SymbolTableInfo::FunToIDMapTy::iterator iter =
@@ -251,7 +278,10 @@ void SVFIRBuilder::initialiseNodes()
251
278
  iter != symTable->varargSyms().end(); ++iter)
252
279
  {
253
280
  DBOUT(DPAGBuild, outs() << "add vararg node " << iter->second << "\n");
254
- pag->addVarargNode(iter->first, iter->second);
281
+ pag->addVarargNode(
282
+ llvmModuleSet()->getCallGraphNode(SVFUtil::cast<Function>(
283
+ llvmModuleSet()->getLLVMValue(iter->first))),
284
+ iter->second);
255
285
  }
256
286
 
257
287
  /// add address edges for constant nodes.
@@ -867,7 +897,9 @@ void SVFIRBuilder::visitCallSite(CallBase* cs)
867
897
 
868
898
  /// Collect callsite arguments and returns
869
899
  for (u32_t i = 0; i < cs->arg_size(); i++)
870
- pag->addCallSiteArgs(callBlockNode,pag->getGNode(getValueNode(cs->getArgOperand(i))));
900
+ pag->addCallSiteArgs(
901
+ callBlockNode,
902
+ SVFUtil::cast<ValVar>(pag->getGNode(getValueNode(cs->getArgOperand(i)))));
871
903
 
872
904
  if(!cs->getType()->isVoidTy())
873
905
  pag->addCallSiteRets(retBlockNode,pag->getGNode(getValueNode(cs)));
@@ -1319,7 +1351,7 @@ void SVFIRBuilder::setCurrentBBAndValueForPAGEdge(PAGEdge* edge)
1319
1351
  {
1320
1352
  assert(srcFun==curInst->getFunction() && "SrcNode of the PAGEdge not in the same function?");
1321
1353
  }
1322
- if(dstFun!=nullptr && !SVFUtil::isa<CallPE>(edge) && !SVFUtil::isa<SVFFunction>(edge->getDstNode()->getValue()))
1354
+ if(dstFun!=nullptr && !SVFUtil::isa<CallPE>(edge) && !SVFUtil::isa<RetPN>(edge->getDstNode()))
1323
1355
  {
1324
1356
  assert(dstFun==curInst->getFunction() && "DstNode of the PAGEdge not in the same function?");
1325
1357
  }
@@ -31,6 +31,7 @@
31
31
  #include "Util/SVFUtil.h"
32
32
  #include "SVF-LLVM/SymbolTableBuilder.h"
33
33
  #include "SVF-LLVM/ObjTypeInference.h"
34
+ #include "Graphs/CallGraph.h"
34
35
 
35
36
  using namespace std;
36
37
  using namespace SVF;
@@ -256,9 +257,11 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const SVFFunction* svfCalle
256
257
 
257
258
  if (isThreadForkCall(callICFGNode))
258
259
  {
259
- if (const SVFFunction* forkedFun = SVFUtil::dyn_cast<SVFFunction>(getForkedFun(callICFGNode)->getValue()))
260
+ const ValVar* valVar = getForkedFun(callICFGNode);
261
+ if (const FunValVar* funcValVar = SVFUtil::dyn_cast<FunValVar>(valVar))
260
262
  {
261
- forkedFun = forkedFun->getDefFunForMultipleModule();
263
+ const SVFFunction* forkedFun = funcValVar->getCallGraphNode()->getFunction()
264
+ ->getDefFunForMultipleModule();
262
265
  const SVFVar* actualParm = getActualParmAtForkSite(callICFGNode);
263
266
  /// pthread_create has 1 arg.
264
267
  /// apr_thread_create has 2 arg.