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 +1 -1
- package/svf/include/Graphs/GenericGraph.h +16 -4
- package/svf/include/Graphs/ICFGNode.h +3 -3
- package/svf/include/SVFIR/SVFIR.h +18 -8
- package/svf/include/SVFIR/SVFVariables.h +135 -25
- package/svf/include/Util/SVFUtil.h +4 -2
- package/svf/include/Util/ThreadAPI.h +5 -3
- package/svf/lib/AE/Svfexe/AbsExtAPI.cpp +1 -2
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +4 -3
- package/svf/lib/Graphs/ConsG.cpp +1 -1
- package/svf/lib/Graphs/PTACallGraph.cpp +2 -1
- package/svf/lib/Graphs/ThreadCallGraph.cpp +10 -5
- package/svf/lib/Graphs/VFG.cpp +1 -1
- package/svf/lib/MTA/MTAStat.cpp +3 -2
- package/svf/lib/MemoryModel/PointerAnalysis.cpp +2 -1
- package/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +6 -4
- package/svf/lib/SABER/SaberCondAllocator.cpp +2 -2
- package/svf/lib/SABER/SaberSVFGBuilder.cpp +3 -6
- package/svf/lib/SVFIR/SVFFileSystem.cpp +2 -0
- package/svf/lib/SVFIR/SVFIR.cpp +19 -2
- package/svf/lib/SVFIR/SVFVariables.cpp +69 -6
- package/svf/lib/Util/CallGraphBuilder.cpp +3 -3
- package/svf/lib/Util/SVFUtil.cpp +7 -0
- package/svf/lib/Util/ThreadAPI.cpp +3 -3
- package/svf-llvm/include/SVF-LLVM/LLVMModule.h +11 -0
- package/svf-llvm/lib/LLVMModule.cpp +14 -1
- package/svf-llvm/lib/SVFIRBuilder.cpp +40 -8
- package/svf-llvm/lib/SVFIRExtAPI.cpp +5 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
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
|
-
// │
|
|
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 ==
|
|
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 ==
|
|
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 ==
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
548
|
+
inline NodeID addValNode(const SVFValue* val, NodeID i, const ICFGNode* icfgNode)
|
|
549
549
|
{
|
|
550
|
-
SVFVar *node = new ValVar(val,i, ValVar::ValNode,
|
|
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
|
|
570
|
+
inline NodeID addRetNode(const CallGraphNode* callGraphNode, NodeID i)
|
|
562
571
|
{
|
|
563
|
-
SVFVar *node = new RetPN(
|
|
564
|
-
return addRetNode(
|
|
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
|
|
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
|
|
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
|
|
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),
|
|
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
|
|
300
|
-
: SVFVar(val, i, ty),
|
|
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
|
|
308
|
+
const ICFGNode* getICFGNode() const
|
|
312
309
|
{
|
|
313
|
-
return
|
|
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
|
-
|
|
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()
|
|
553
|
+
return isFIObjVarKinds(node->getNodeKind());
|
|
557
554
|
}
|
|
558
555
|
static inline bool classof(const SVFVar* node)
|
|
559
556
|
{
|
|
560
|
-
return node->getNodeKind()
|
|
557
|
+
return isFIObjVarKinds(node->getNodeKind());
|
|
561
558
|
}
|
|
562
559
|
static inline bool classof(const GenericPAGNodeTy* node)
|
|
563
560
|
{
|
|
564
|
-
return node->getNodeKind()
|
|
561
|
+
return isFIObjVarKinds(node->getNodeKind());
|
|
565
562
|
}
|
|
566
563
|
static inline bool classof(const SVFBaseNode* node)
|
|
567
564
|
{
|
|
568
|
-
return node->getNodeKind()
|
|
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
|
|
732
|
+
RetPN(const CallGraphNode* node, NodeID i);
|
|
628
733
|
|
|
629
|
-
|
|
630
|
-
const std::string getValueName() const
|
|
734
|
+
inline const CallGraphNode* getCallGraphNode() const
|
|
631
735
|
{
|
|
632
|
-
return
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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<
|
|
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
|
|
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
|
|
660
|
+
const RetICFGNode* retNode = callNode->getRetICFGNode();
|
|
660
661
|
abstractTrace[retNode] = abstractTrace[callNode];
|
|
661
662
|
}
|
|
662
663
|
}
|
package/svf/lib/Graphs/ConsG.cpp
CHANGED
|
@@ -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->
|
|
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() ||
|
|
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
|
|
77
|
-
if(SVFUtil::dyn_cast<
|
|
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<
|
|
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<
|
|
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 =
|
|
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);
|
package/svf/lib/Graphs/VFG.cpp
CHANGED
|
@@ -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
|
package/svf/lib/MTA/MTAStat.cpp
CHANGED
|
@@ -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
|
|
53
|
-
if(
|
|
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<
|
|
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
|
|
525
|
-
if(SVFUtil::dyn_cast<
|
|
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(
|
|
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<
|
|
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->
|
|
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(
|
|
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(
|
|
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->
|
|
138
|
+
if(valVar && valVar->getICFGNode() && SVFUtil::isExtCall(valVar->getICFGNode()))
|
|
142
139
|
{
|
|
143
140
|
return pts;
|
|
144
141
|
}
|
package/svf/lib/SVFIR/SVFIR.cpp
CHANGED
|
@@ -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())
|
|
689
|
+
if (isValidPointer(node->getId()))
|
|
679
690
|
{
|
|
680
|
-
|
|
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
|
-
|
|
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 " <<
|
|
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 " <<
|
|
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
|
|
92
|
-
if (
|
|
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
|
}
|
package/svf/lib/Util/SVFUtil.cpp
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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/
|
|
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
|
|
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
|
-
|
|
231
|
+
icfgNode = llvmModuleSet()->getICFGNode(inst);
|
|
226
232
|
}
|
|
227
233
|
}
|
|
228
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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<
|
|
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
|
-
|
|
260
|
+
const ValVar* valVar = getForkedFun(callICFGNode);
|
|
261
|
+
if (const FunValVar* funcValVar = SVFUtil::dyn_cast<FunValVar>(valVar))
|
|
260
262
|
{
|
|
261
|
-
forkedFun =
|
|
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.
|