svf-tools 1.0.1040 → 1.0.1042
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/AE/Svfexe/AbstractInterpretation.h +3 -3
- package/svf/include/DDA/DDAVFSolver.h +4 -4
- package/svf/include/Graphs/CallGraph.h +260 -24
- package/svf/include/Graphs/ICFG.h +2 -2
- package/svf/include/Graphs/ThreadCallGraph.h +24 -24
- package/svf/include/Graphs/VFG.h +4 -4
- package/svf/include/MSSA/MemRegion.h +4 -4
- package/svf/include/MTA/LockAnalysis.h +1 -1
- package/svf/include/MTA/MHP.h +2 -2
- package/svf/include/MTA/TCT.h +6 -6
- package/svf/include/MemoryModel/PointerAnalysis.h +5 -5
- package/svf/include/SABER/SaberSVFGBuilder.h +1 -1
- package/svf/include/SABER/SrcSnkDDA.h +2 -2
- package/svf/include/SVFIR/SVFIR.h +8 -9
- package/svf/include/SVFIR/SVFValue.h +0 -10
- package/svf/include/SVFIR/SVFVariables.h +13 -13
- package/svf/include/Util/CallGraphBuilder.h +1 -1
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +7 -7
- package/svf/lib/DDA/ContextDDA.cpp +1 -1
- package/svf/lib/DDA/DDAClient.cpp +2 -2
- package/svf/lib/Graphs/CallGraph.cpp +268 -28
- package/svf/lib/Graphs/ICFG.cpp +6 -6
- package/svf/lib/Graphs/SVFG.cpp +4 -4
- package/svf/lib/Graphs/SVFGReadWrite.cpp +4 -4
- package/svf/lib/Graphs/SVFGStat.cpp +1 -1
- package/svf/lib/Graphs/ThreadCallGraph.cpp +14 -16
- package/svf/lib/Graphs/VFG.cpp +1 -1
- package/svf/lib/MSSA/MemRegion.cpp +6 -6
- package/svf/lib/MTA/LockAnalysis.cpp +18 -18
- package/svf/lib/MTA/MHP.cpp +19 -19
- package/svf/lib/MTA/TCT.cpp +23 -23
- package/svf/lib/SABER/LeakChecker.cpp +4 -4
- package/svf/lib/SABER/SaberSVFGBuilder.cpp +3 -3
- package/svf/lib/SVFIR/SVFVariables.cpp +10 -10
- package/svf/lib/Util/CallGraphBuilder.cpp +2 -2
- package/svf/lib/Util/PTAStat.cpp +7 -7
- package/svf/lib/WPA/VersionedFlowSensitive.cpp +1 -1
- package/svf-llvm/include/SVF-LLVM/LLVMModule.h +0 -11
- package/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +1 -1
- package/svf-llvm/lib/LLVMModule.cpp +0 -18
- package/svf-llvm/lib/LLVMUtil.cpp +1 -1
- package/svf-llvm/lib/SVFIRBuilder.cpp +11 -11
- package/svf-llvm/lib/SVFIRExtAPI.cpp +1 -2
- package/svf-llvm/tools/AE/ae.cpp +1 -1
- package/svf-llvm/tools/Example/svf-ex.cpp +1 -1
- package/svf/include/Graphs/PTACallGraph.h +0 -494
- package/svf/lib/Graphs/PTACallGraph.cpp +0 -419
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1042",
|
|
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": {
|
|
@@ -106,7 +106,7 @@ class AbstractInterpretation
|
|
|
106
106
|
friend class BufOverflowDetector;
|
|
107
107
|
|
|
108
108
|
public:
|
|
109
|
-
typedef SCCDetection<
|
|
109
|
+
typedef SCCDetection<CallGraph*> CallGraphSCC;
|
|
110
110
|
/// Constructor
|
|
111
111
|
AbstractInterpretation();
|
|
112
112
|
|
|
@@ -251,8 +251,8 @@ private:
|
|
|
251
251
|
AEStat* stat;
|
|
252
252
|
|
|
253
253
|
std::vector<const CallICFGNode*> callSiteStack;
|
|
254
|
-
Map<const
|
|
255
|
-
Set<const
|
|
254
|
+
Map<const SVFFunction*, ICFGWTO*> funcToWTO;
|
|
255
|
+
Set<const SVFFunction*> recursiveFuns;
|
|
256
256
|
|
|
257
257
|
|
|
258
258
|
AbstractState& getAbsStateFromTrace(const ICFGNode* node)
|
|
@@ -49,8 +49,8 @@ class DDAVFSolver
|
|
|
49
49
|
friend class DDAStat;
|
|
50
50
|
public:
|
|
51
51
|
typedef SCCDetection<SVFG*> SVFGSCC;
|
|
52
|
-
typedef SCCDetection<
|
|
53
|
-
typedef
|
|
52
|
+
typedef SCCDetection<CallGraph*> CallGraphSCC;
|
|
53
|
+
typedef CallGraphEdge::CallInstSet CallInstSet;
|
|
54
54
|
typedef SVFIR::CallSiteSet CallSiteSet;
|
|
55
55
|
typedef OrderedSet<DPIm> DPTItemSet;
|
|
56
56
|
typedef OrderedMap<DPIm, CPtSet> DPImToCPtSetMap;
|
|
@@ -624,7 +624,7 @@ protected:
|
|
|
624
624
|
return (getSVFGSCCRepNode(edge->getSrcID()) == getSVFGSCCRepNode(edge->getDstID()));
|
|
625
625
|
}
|
|
626
626
|
/// Set callgraph
|
|
627
|
-
inline void setCallGraph (
|
|
627
|
+
inline void setCallGraph (CallGraph* cg)
|
|
628
628
|
{
|
|
629
629
|
_callGraph = cg;
|
|
630
630
|
}
|
|
@@ -774,7 +774,7 @@ protected:
|
|
|
774
774
|
SVFG* _svfg; ///< SVFG
|
|
775
775
|
AndersenWaveDiff* _ander; ///< Andersen's analysis
|
|
776
776
|
NodeBS candidateQueries; ///< candidate pointers;
|
|
777
|
-
|
|
777
|
+
CallGraph* _callGraph; ///< PTACallGraph
|
|
778
778
|
CallGraphSCC* _callGraphSCC; ///< SCC for PTACallGraph
|
|
779
779
|
SVFGSCC* _svfgSCC; ///< SCC for SVFG
|
|
780
780
|
DPTItemSet backwardVisited; ///< visited map during backward traversing
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//===-
|
|
1
|
+
//===- PTACallGraph.h -- Call graph representation----------------------------//
|
|
2
2
|
//
|
|
3
3
|
// SVF: Static Value-Flow Analysis
|
|
4
4
|
//
|
|
@@ -21,14 +21,14 @@
|
|
|
21
21
|
//===----------------------------------------------------------------------===//
|
|
22
22
|
|
|
23
23
|
/*
|
|
24
|
-
*
|
|
24
|
+
* PTACallGraph.h
|
|
25
25
|
*
|
|
26
26
|
* Created on: Nov 7, 2013
|
|
27
27
|
* Author: Yulei Sui
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
|
-
#ifndef
|
|
31
|
-
#define
|
|
30
|
+
#ifndef PTACALLGRAPH_H_
|
|
31
|
+
#define PTACALLGRAPH_H_
|
|
32
32
|
|
|
33
33
|
#include "Graphs/GenericGraph.h"
|
|
34
34
|
#include "SVFIR/SVFValue.h"
|
|
@@ -40,6 +40,7 @@ namespace SVF
|
|
|
40
40
|
|
|
41
41
|
class CallGraphNode;
|
|
42
42
|
class SVFModule;
|
|
43
|
+
class CallGraph;
|
|
43
44
|
|
|
44
45
|
|
|
45
46
|
/*
|
|
@@ -47,29 +48,74 @@ class SVFModule;
|
|
|
47
48
|
* Multiple calls from function A to B are merged into one call edge
|
|
48
49
|
* Each call edge has a set of direct callsites and a set of indirect callsites
|
|
49
50
|
*/
|
|
50
|
-
typedef GenericEdge<CallGraphNode>
|
|
51
|
-
class CallGraphEdge : public
|
|
51
|
+
typedef GenericEdge<CallGraphNode> GenericPTACallGraphEdgeTy;
|
|
52
|
+
class CallGraphEdge : public GenericPTACallGraphEdgeTy
|
|
52
53
|
{
|
|
53
54
|
|
|
54
55
|
public:
|
|
55
56
|
typedef Set<const CallICFGNode*> CallInstSet;
|
|
57
|
+
enum CEDGEK
|
|
58
|
+
{
|
|
59
|
+
CallRetEdge,TDForkEdge,TDJoinEdge,HareParForEdge
|
|
60
|
+
};
|
|
61
|
+
|
|
56
62
|
|
|
57
63
|
private:
|
|
58
64
|
CallInstSet directCalls;
|
|
65
|
+
CallInstSet indirectCalls;
|
|
66
|
+
CallSiteID csId;
|
|
59
67
|
public:
|
|
60
68
|
/// Constructor
|
|
61
|
-
CallGraphEdge(CallGraphNode* s, CallGraphNode* d,
|
|
62
|
-
|
|
69
|
+
CallGraphEdge(CallGraphNode* s, CallGraphNode* d, CEDGEK kind, CallSiteID cs) :
|
|
70
|
+
GenericPTACallGraphEdgeTy(s, d, makeEdgeFlagWithInvokeID(kind, cs)), csId(cs)
|
|
63
71
|
{
|
|
64
72
|
}
|
|
65
73
|
/// Destructor
|
|
66
74
|
virtual ~CallGraphEdge()
|
|
67
75
|
{
|
|
68
76
|
}
|
|
77
|
+
/// Compute the unique edgeFlag value from edge kind and CallSiteID.
|
|
78
|
+
static inline GEdgeFlag makeEdgeFlagWithInvokeID(GEdgeKind k, CallSiteID cs)
|
|
79
|
+
{
|
|
80
|
+
return (cs << EdgeKindMaskBits) | k;
|
|
81
|
+
}
|
|
82
|
+
/// Get direct and indirect calls
|
|
83
|
+
//@{
|
|
84
|
+
inline CallSiteID getCallSiteID() const
|
|
85
|
+
{
|
|
86
|
+
return csId;
|
|
87
|
+
}
|
|
88
|
+
inline bool isDirectCallEdge() const
|
|
89
|
+
{
|
|
90
|
+
return !directCalls.empty() && indirectCalls.empty();
|
|
91
|
+
}
|
|
92
|
+
inline bool isIndirectCallEdge() const
|
|
93
|
+
{
|
|
94
|
+
return directCalls.empty() && !indirectCalls.empty();
|
|
95
|
+
}
|
|
96
|
+
inline CallInstSet& getDirectCalls()
|
|
97
|
+
{
|
|
98
|
+
return directCalls;
|
|
99
|
+
}
|
|
100
|
+
inline CallInstSet& getIndirectCalls()
|
|
101
|
+
{
|
|
102
|
+
return indirectCalls;
|
|
103
|
+
}
|
|
104
|
+
inline const CallInstSet& getDirectCalls() const
|
|
105
|
+
{
|
|
106
|
+
return directCalls;
|
|
107
|
+
}
|
|
108
|
+
inline const CallInstSet& getIndirectCalls() const
|
|
109
|
+
{
|
|
110
|
+
return indirectCalls;
|
|
111
|
+
}
|
|
112
|
+
//@}
|
|
69
113
|
|
|
70
|
-
/// Add direct callsite
|
|
114
|
+
/// Add direct and indirect callsite
|
|
71
115
|
//@{
|
|
72
116
|
void addDirectCallSite(const CallICFGNode* call);
|
|
117
|
+
|
|
118
|
+
void addInDirectCallSite(const CallICFGNode* call);
|
|
73
119
|
//@}
|
|
74
120
|
|
|
75
121
|
/// Iterators for direct and indirect callsites
|
|
@@ -82,6 +128,15 @@ public:
|
|
|
82
128
|
{
|
|
83
129
|
return directCalls.end();
|
|
84
130
|
}
|
|
131
|
+
|
|
132
|
+
inline CallInstSet::const_iterator indirectCallsBegin() const
|
|
133
|
+
{
|
|
134
|
+
return indirectCalls.begin();
|
|
135
|
+
}
|
|
136
|
+
inline CallInstSet::const_iterator indirectCallsEnd() const
|
|
137
|
+
{
|
|
138
|
+
return indirectCalls.end();
|
|
139
|
+
}
|
|
85
140
|
//@}
|
|
86
141
|
|
|
87
142
|
/// ClassOf
|
|
@@ -90,6 +145,12 @@ public:
|
|
|
90
145
|
{
|
|
91
146
|
return true;
|
|
92
147
|
}
|
|
148
|
+
static inline bool classof(const GenericPTACallGraphEdgeTy *edge)
|
|
149
|
+
{
|
|
150
|
+
return edge->getEdgeKind() == CallGraphEdge::CallRetEdge ||
|
|
151
|
+
edge->getEdgeKind() == CallGraphEdge::TDForkEdge ||
|
|
152
|
+
edge->getEdgeKind() == CallGraphEdge::TDJoinEdge;
|
|
153
|
+
}
|
|
93
154
|
//@}
|
|
94
155
|
|
|
95
156
|
/// Overloading operator << for dumping ICFG node ID
|
|
@@ -110,16 +171,17 @@ public:
|
|
|
110
171
|
/*
|
|
111
172
|
* Call Graph node representing a function
|
|
112
173
|
*/
|
|
113
|
-
typedef GenericNode<CallGraphNode, CallGraphEdge>
|
|
114
|
-
class CallGraphNode : public
|
|
174
|
+
typedef GenericNode<CallGraphNode, CallGraphEdge> GenericPTACallGraphNodeTy;
|
|
175
|
+
class CallGraphNode : public GenericPTACallGraphNodeTy
|
|
115
176
|
{
|
|
116
177
|
private:
|
|
117
178
|
const SVFFunction* fun;
|
|
118
179
|
|
|
119
180
|
public:
|
|
120
181
|
/// Constructor
|
|
121
|
-
CallGraphNode(NodeID i, const SVFFunction* f) :
|
|
182
|
+
CallGraphNode(NodeID i, const SVFFunction* f) : GenericPTACallGraphNodeTy(i,CallNodeKd), fun(f)
|
|
122
183
|
{
|
|
184
|
+
|
|
123
185
|
}
|
|
124
186
|
|
|
125
187
|
inline const std::string &getName() const
|
|
@@ -133,6 +195,9 @@ public:
|
|
|
133
195
|
return fun;
|
|
134
196
|
}
|
|
135
197
|
|
|
198
|
+
/// Return TRUE if this function can be reached from main.
|
|
199
|
+
bool isReachableFromProgEntry() const;
|
|
200
|
+
|
|
136
201
|
|
|
137
202
|
/// Overloading operator << for dumping ICFG node ID
|
|
138
203
|
//@{
|
|
@@ -167,27 +232,64 @@ public:
|
|
|
167
232
|
/*!
|
|
168
233
|
* Pointer Analysis Call Graph used internally for various pointer analysis
|
|
169
234
|
*/
|
|
170
|
-
typedef GenericGraph<CallGraphNode, CallGraphEdge>
|
|
171
|
-
class CallGraph : public
|
|
235
|
+
typedef GenericGraph<CallGraphNode, CallGraphEdge> GenericPTACallGraphTy;
|
|
236
|
+
class CallGraph : public GenericPTACallGraphTy
|
|
172
237
|
{
|
|
173
|
-
friend class PTACallGraph;
|
|
174
238
|
|
|
175
239
|
public:
|
|
176
240
|
typedef CallGraphEdge::CallGraphEdgeSet CallGraphEdgeSet;
|
|
177
241
|
typedef Map<const SVFFunction*, CallGraphNode*> FunToCallGraphNodeMap;
|
|
178
242
|
typedef Map<const CallICFGNode*, CallGraphEdgeSet> CallInstToCallGraphEdgesMap;
|
|
243
|
+
typedef std::pair<const CallICFGNode*, const SVFFunction*> CallSitePair;
|
|
244
|
+
typedef Map<CallSitePair, CallSiteID> CallSiteToIdMap;
|
|
245
|
+
typedef Map<CallSiteID, CallSitePair> IdToCallSiteMap;
|
|
179
246
|
typedef Set<const SVFFunction*> FunctionSet;
|
|
180
247
|
typedef OrderedMap<const CallICFGNode*, FunctionSet> CallEdgeMap;
|
|
248
|
+
typedef CallGraphEdgeSet::iterator CallGraphEdgeIter;
|
|
249
|
+
typedef CallGraphEdgeSet::const_iterator CallGraphEdgeConstIter;
|
|
250
|
+
|
|
251
|
+
enum CGEK
|
|
252
|
+
{
|
|
253
|
+
NormCallGraph, ThdCallGraph
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
private:
|
|
257
|
+
/// Indirect call map
|
|
258
|
+
CallEdgeMap indirectCallMap;
|
|
259
|
+
|
|
260
|
+
/// Call site information
|
|
261
|
+
static CallSiteToIdMap csToIdMap; ///< Map a pair of call instruction and callee to a callsite ID
|
|
262
|
+
static IdToCallSiteMap idToCSMap; ///< Map a callsite ID to a pair of call instruction and callee
|
|
263
|
+
static CallSiteID totalCallSiteNum; ///< CallSiteIDs, start from 1;
|
|
181
264
|
|
|
182
265
|
protected:
|
|
183
266
|
FunToCallGraphNodeMap funToCallGraphNodeMap; ///< Call Graph node map
|
|
184
267
|
CallInstToCallGraphEdgesMap callinstToCallGraphEdgesMap; ///< Map a call instruction to its corresponding call edges
|
|
185
268
|
|
|
186
269
|
NodeID callGraphNodeNum;
|
|
270
|
+
u32_t numOfResolvedIndCallEdge;
|
|
271
|
+
CGEK kind;
|
|
187
272
|
|
|
188
273
|
/// Clean up memory
|
|
189
274
|
void destroy();
|
|
190
275
|
|
|
276
|
+
protected:
|
|
277
|
+
/// Add CallSiteID
|
|
278
|
+
inline CallSiteID addCallSite(const CallICFGNode* cs, const SVFFunction* callee)
|
|
279
|
+
{
|
|
280
|
+
std::pair<const CallICFGNode*, const SVFFunction*> newCS(std::make_pair(cs, callee));
|
|
281
|
+
CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS);
|
|
282
|
+
//assert(it == csToIdMap.end() && "cannot add a callsite twice");
|
|
283
|
+
if(it == csToIdMap.end())
|
|
284
|
+
{
|
|
285
|
+
CallSiteID id = totalCallSiteNum++;
|
|
286
|
+
csToIdMap.insert(std::make_pair(newCS, id));
|
|
287
|
+
idToCSMap.insert(std::make_pair(id, newCS));
|
|
288
|
+
return id;
|
|
289
|
+
}
|
|
290
|
+
return it->second;
|
|
291
|
+
}
|
|
292
|
+
|
|
191
293
|
/// Add call graph edge
|
|
192
294
|
inline void addEdge(CallGraphEdge* edge)
|
|
193
295
|
{
|
|
@@ -195,14 +297,12 @@ protected:
|
|
|
195
297
|
edge->getSrcNode()->addOutgoingEdge(edge);
|
|
196
298
|
}
|
|
197
299
|
|
|
198
|
-
|
|
199
300
|
public:
|
|
200
301
|
/// Constructor
|
|
201
|
-
CallGraph();
|
|
202
|
-
|
|
203
|
-
void addCallGraphNode(const SVFFunction* fun);
|
|
302
|
+
CallGraph(CGEK k = NormCallGraph);
|
|
204
303
|
|
|
205
|
-
|
|
304
|
+
/// Copy constructor
|
|
305
|
+
CallGraph(const CallGraph& other);
|
|
206
306
|
|
|
207
307
|
/// Destructor
|
|
208
308
|
virtual ~CallGraph()
|
|
@@ -210,8 +310,57 @@ public:
|
|
|
210
310
|
destroy();
|
|
211
311
|
}
|
|
212
312
|
|
|
313
|
+
/// Return type of this callgraph
|
|
314
|
+
inline CGEK getKind() const
|
|
315
|
+
{
|
|
316
|
+
return kind;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/// Get callees from an indirect callsite
|
|
320
|
+
//@{
|
|
321
|
+
inline CallEdgeMap& getIndCallMap()
|
|
322
|
+
{
|
|
323
|
+
return indirectCallMap;
|
|
324
|
+
}
|
|
325
|
+
inline bool hasIndCSCallees(const CallICFGNode* cs) const
|
|
326
|
+
{
|
|
327
|
+
return (indirectCallMap.find(cs) != indirectCallMap.end());
|
|
328
|
+
}
|
|
329
|
+
inline const FunctionSet& getIndCSCallees(const CallICFGNode* cs) const
|
|
330
|
+
{
|
|
331
|
+
CallEdgeMap::const_iterator it = indirectCallMap.find(cs);
|
|
332
|
+
assert(it!=indirectCallMap.end() && "not an indirect callsite!");
|
|
333
|
+
return it->second;
|
|
334
|
+
}
|
|
335
|
+
//@}
|
|
336
|
+
inline u32_t getTotalCallSiteNumber() const
|
|
337
|
+
{
|
|
338
|
+
return totalCallSiteNum;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
inline u32_t getNumOfResolvedIndCallEdge() const
|
|
342
|
+
{
|
|
343
|
+
return numOfResolvedIndCallEdge;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
inline const CallInstToCallGraphEdgesMap& getCallInstToCallGraphEdgesMap() const
|
|
347
|
+
{
|
|
348
|
+
return callinstToCallGraphEdgesMap;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/// Issue a warning if the function which has indirect call sites can not be reached from program entry.
|
|
352
|
+
void verifyCallGraph();
|
|
353
|
+
|
|
354
|
+
/// Add direct call edges
|
|
355
|
+
void addDirectCallGraphEdge(const CallICFGNode* call, const SVFFunction* callerFun, const SVFFunction* calleeFun);
|
|
356
|
+
|
|
357
|
+
void addCallGraphNode(const SVFFunction* fun);
|
|
358
|
+
|
|
213
359
|
/// Get call graph node
|
|
214
360
|
//@{
|
|
361
|
+
|
|
362
|
+
const CallGraphNode* getCallGraphNode(const std::string& name);
|
|
363
|
+
|
|
215
364
|
inline CallGraphNode* getCallGraphNode(NodeID id) const
|
|
216
365
|
{
|
|
217
366
|
return getGNode(id);
|
|
@@ -225,12 +374,99 @@ public:
|
|
|
225
374
|
|
|
226
375
|
//@}
|
|
227
376
|
|
|
377
|
+
/// Get CallSiteID
|
|
378
|
+
//@{
|
|
379
|
+
inline CallSiteID getCallSiteID(const CallICFGNode* cs, const SVFFunction* callee) const
|
|
380
|
+
{
|
|
381
|
+
CallSitePair newCS(std::make_pair(cs, callee));
|
|
382
|
+
CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS);
|
|
383
|
+
assert(it != csToIdMap.end() && "callsite id not found! This maybe a partially resolved callgraph, please check the indCallEdge limit");
|
|
384
|
+
return it->second;
|
|
385
|
+
}
|
|
386
|
+
inline bool hasCallSiteID(const CallICFGNode* cs, const SVFFunction* callee) const
|
|
387
|
+
{
|
|
388
|
+
CallSitePair newCS(std::make_pair(cs, callee));
|
|
389
|
+
CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS);
|
|
390
|
+
return it != csToIdMap.end();
|
|
391
|
+
}
|
|
392
|
+
inline const CallSitePair& getCallSitePair(CallSiteID id) const
|
|
393
|
+
{
|
|
394
|
+
IdToCallSiteMap::const_iterator it = idToCSMap.find(id);
|
|
395
|
+
assert(it != idToCSMap.end() && "cannot find call site for this CallSiteID");
|
|
396
|
+
return (it->second);
|
|
397
|
+
}
|
|
398
|
+
inline const CallICFGNode* getCallSite(CallSiteID id) const
|
|
399
|
+
{
|
|
400
|
+
return getCallSitePair(id).first;
|
|
401
|
+
}
|
|
402
|
+
inline const SVFFunction* getCallerOfCallSite(CallSiteID id) const
|
|
403
|
+
{
|
|
404
|
+
return getCallSite(id)->getCaller();
|
|
405
|
+
}
|
|
406
|
+
inline const SVFFunction* getCalleeOfCallSite(CallSiteID id) const
|
|
407
|
+
{
|
|
408
|
+
return getCallSitePair(id).second;
|
|
409
|
+
}
|
|
410
|
+
//@}
|
|
228
411
|
/// Whether we have already created this call graph edge
|
|
229
412
|
CallGraphEdge* hasGraphEdge(CallGraphNode* src, CallGraphNode* dst,
|
|
230
|
-
|
|
413
|
+
CallGraphEdge::CEDGEK kind, CallSiteID csId) const;
|
|
414
|
+
/// Get call graph edge via nodes
|
|
415
|
+
CallGraphEdge* getGraphEdge(CallGraphNode* src, CallGraphNode* dst,
|
|
416
|
+
CallGraphEdge::CEDGEK kind, CallSiteID csId);
|
|
417
|
+
|
|
418
|
+
/// Get all callees for a callsite
|
|
419
|
+
inline void getCallees(const CallICFGNode* cs, FunctionSet& callees)
|
|
420
|
+
{
|
|
421
|
+
if(hasCallGraphEdge(cs))
|
|
422
|
+
{
|
|
423
|
+
for (CallGraphEdgeSet::const_iterator it = getCallEdgeBegin(cs), eit =
|
|
424
|
+
getCallEdgeEnd(cs); it != eit; ++it)
|
|
425
|
+
{
|
|
426
|
+
callees.insert((*it)->getDstNode()->getFunction());
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/// Get call graph edge via call instruction
|
|
432
|
+
//@{
|
|
433
|
+
/// whether this call instruction has a valid call graph edge
|
|
434
|
+
inline bool hasCallGraphEdge(const CallICFGNode* inst) const
|
|
435
|
+
{
|
|
436
|
+
return callinstToCallGraphEdgesMap.find(inst)!=callinstToCallGraphEdgesMap.end();
|
|
437
|
+
}
|
|
438
|
+
inline CallGraphEdgeSet::const_iterator getCallEdgeBegin(const CallICFGNode* inst) const
|
|
439
|
+
{
|
|
440
|
+
CallInstToCallGraphEdgesMap::const_iterator it = callinstToCallGraphEdgesMap.find(inst);
|
|
441
|
+
assert(it!=callinstToCallGraphEdgesMap.end()
|
|
442
|
+
&& "call instruction does not have a valid callee");
|
|
443
|
+
return it->second.begin();
|
|
444
|
+
}
|
|
445
|
+
inline CallGraphEdgeSet::const_iterator getCallEdgeEnd(const CallICFGNode* inst) const
|
|
446
|
+
{
|
|
447
|
+
CallInstToCallGraphEdgesMap::const_iterator it = callinstToCallGraphEdgesMap.find(inst);
|
|
448
|
+
assert(it!=callinstToCallGraphEdgesMap.end()
|
|
449
|
+
&& "call instruction does not have a valid callee");
|
|
450
|
+
return it->second.end();
|
|
451
|
+
}
|
|
452
|
+
//@}
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
/// Add indirect call edges
|
|
456
|
+
//@{
|
|
457
|
+
void addIndirectCallGraphEdge(const CallICFGNode* cs,const SVFFunction* callerFun, const SVFFunction* calleeFun);
|
|
458
|
+
//@}
|
|
459
|
+
|
|
460
|
+
/// Get callsites invoking the callee
|
|
461
|
+
//@{
|
|
462
|
+
void getAllCallSitesInvokingCallee(const SVFFunction* callee, CallGraphEdge::CallInstSet& csSet);
|
|
463
|
+
void getDirCallSitesInvokingCallee(const SVFFunction* callee, CallGraphEdge::CallInstSet& csSet);
|
|
464
|
+
void getIndCallSitesInvokingCallee(const SVFFunction* callee, CallGraphEdge::CallInstSet& csSet);
|
|
465
|
+
//@}
|
|
466
|
+
|
|
467
|
+
/// Whether its reachable between two functions
|
|
468
|
+
bool isReachableBetweenFunctions(const SVFFunction* srcFn, const SVFFunction* dstFn) const;
|
|
231
469
|
|
|
232
|
-
/// Add direct call edges
|
|
233
|
-
void addDirectCallGraphEdge(const CallICFGNode* call, const SVFFunction* callerFun, const SVFFunction* calleeFun);
|
|
234
470
|
/// Dump the graph
|
|
235
471
|
void dump(const std::string& filename);
|
|
236
472
|
|
|
@@ -263,4 +499,4 @@ template<> struct GenericGraphTraits<SVF::CallGraph*> : public GenericGraphTrait
|
|
|
263
499
|
|
|
264
500
|
} // End namespace llvm
|
|
265
501
|
|
|
266
|
-
#endif /*
|
|
502
|
+
#endif /* PTACALLGRAPH_H_ */
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
namespace SVF
|
|
39
39
|
{
|
|
40
40
|
|
|
41
|
-
class
|
|
41
|
+
class CallGraph;
|
|
42
42
|
|
|
43
43
|
/*!
|
|
44
44
|
* Interprocedural Control-Flow Graph (ICFG)
|
|
@@ -111,7 +111,7 @@ public:
|
|
|
111
111
|
void view();
|
|
112
112
|
|
|
113
113
|
/// update ICFG for indirect calls
|
|
114
|
-
void updateCallGraph(
|
|
114
|
+
void updateCallGraph(CallGraph* callgraph);
|
|
115
115
|
|
|
116
116
|
/// Whether node is in a loop
|
|
117
117
|
inline bool isInLoop(const ICFGNode *node)
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
#ifndef RCG_H_
|
|
31
31
|
#define RCG_H_
|
|
32
32
|
|
|
33
|
-
#include "Graphs/
|
|
33
|
+
#include "Graphs/CallGraph.h"
|
|
34
34
|
|
|
35
35
|
namespace SVF
|
|
36
36
|
{
|
|
@@ -41,13 +41,13 @@ class PointerAnalysis;
|
|
|
41
41
|
/*!
|
|
42
42
|
* PTA thread fork edge from fork site to the entry of a start routine function
|
|
43
43
|
*/
|
|
44
|
-
class ThreadForkEdge: public
|
|
44
|
+
class ThreadForkEdge: public CallGraphEdge
|
|
45
45
|
{
|
|
46
46
|
|
|
47
47
|
public:
|
|
48
48
|
/// Constructor
|
|
49
|
-
ThreadForkEdge(
|
|
50
|
-
|
|
49
|
+
ThreadForkEdge(CallGraphNode* s, CallGraphNode* d, CallSiteID csId) :
|
|
50
|
+
CallGraphEdge(s, d, CallGraphEdge::TDForkEdge, csId)
|
|
51
51
|
{
|
|
52
52
|
}
|
|
53
53
|
/// Destructor
|
|
@@ -61,9 +61,9 @@ public:
|
|
|
61
61
|
{
|
|
62
62
|
return true;
|
|
63
63
|
}
|
|
64
|
-
static inline bool classof(const
|
|
64
|
+
static inline bool classof(const CallGraphEdge*edge)
|
|
65
65
|
{
|
|
66
|
-
return edge->getEdgeKind() ==
|
|
66
|
+
return edge->getEdgeKind() == CallGraphEdge::TDForkEdge;
|
|
67
67
|
}
|
|
68
68
|
//@}
|
|
69
69
|
|
|
@@ -78,19 +78,19 @@ public:
|
|
|
78
78
|
return rawstr.str();
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
typedef GenericNode<
|
|
81
|
+
typedef GenericNode<CallGraphNode, ThreadForkEdge>::GEdgeSetTy ForkEdgeSet;
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
/*!
|
|
85
85
|
* PTA thread join edge from the exit of a start routine function to a join point of the thread
|
|
86
86
|
*/
|
|
87
|
-
class ThreadJoinEdge: public
|
|
87
|
+
class ThreadJoinEdge: public CallGraphEdge
|
|
88
88
|
{
|
|
89
89
|
|
|
90
90
|
public:
|
|
91
91
|
/// Constructor
|
|
92
|
-
ThreadJoinEdge(
|
|
93
|
-
|
|
92
|
+
ThreadJoinEdge(CallGraphNode* s, CallGraphNode* d, CallSiteID csId) :
|
|
93
|
+
CallGraphEdge(s, d, CallGraphEdge::TDJoinEdge, csId)
|
|
94
94
|
{
|
|
95
95
|
}
|
|
96
96
|
/// Destructor
|
|
@@ -102,9 +102,9 @@ public:
|
|
|
102
102
|
{
|
|
103
103
|
return true;
|
|
104
104
|
}
|
|
105
|
-
static inline bool classof(const
|
|
105
|
+
static inline bool classof(const CallGraphEdge*edge)
|
|
106
106
|
{
|
|
107
|
-
return edge->getEdgeKind() ==
|
|
107
|
+
return edge->getEdgeKind() == CallGraphEdge::TDJoinEdge;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
virtual const std::string toString() const
|
|
@@ -118,19 +118,19 @@ public:
|
|
|
118
118
|
return rawstr.str();
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
typedef GenericNode<
|
|
121
|
+
typedef GenericNode<CallGraphNode, ThreadJoinEdge>::GEdgeSetTy JoinEdgeSet;
|
|
122
122
|
};
|
|
123
123
|
|
|
124
124
|
/*!
|
|
125
125
|
* hare_parallel_for edge from fork site to the entry of a start routine function
|
|
126
126
|
*/
|
|
127
|
-
class HareParForEdge: public
|
|
127
|
+
class HareParForEdge: public CallGraphEdge
|
|
128
128
|
{
|
|
129
129
|
|
|
130
130
|
public:
|
|
131
131
|
/// Constructor
|
|
132
|
-
HareParForEdge(
|
|
133
|
-
|
|
132
|
+
HareParForEdge(CallGraphNode* s, CallGraphNode* d, CallSiteID csId) :
|
|
133
|
+
CallGraphEdge(s, d, CallGraphEdge::HareParForEdge, csId)
|
|
134
134
|
{
|
|
135
135
|
}
|
|
136
136
|
/// Destructor
|
|
@@ -144,20 +144,20 @@ public:
|
|
|
144
144
|
{
|
|
145
145
|
return true;
|
|
146
146
|
}
|
|
147
|
-
static inline bool classof(const
|
|
147
|
+
static inline bool classof(const CallGraphEdge*edge)
|
|
148
148
|
{
|
|
149
|
-
return edge->getEdgeKind() ==
|
|
149
|
+
return edge->getEdgeKind() == CallGraphEdge::HareParForEdge;
|
|
150
150
|
}
|
|
151
151
|
//@}
|
|
152
152
|
|
|
153
|
-
typedef GenericNode<
|
|
153
|
+
typedef GenericNode<CallGraphNode, HareParForEdge>::GEdgeSetTy ParForEdgeSet;
|
|
154
154
|
};
|
|
155
155
|
|
|
156
156
|
|
|
157
157
|
/*!
|
|
158
158
|
* Thread sensitive call graph
|
|
159
159
|
*/
|
|
160
|
-
class ThreadCallGraph: public
|
|
160
|
+
class ThreadCallGraph: public CallGraph
|
|
161
161
|
{
|
|
162
162
|
|
|
163
163
|
public:
|
|
@@ -187,9 +187,9 @@ public:
|
|
|
187
187
|
{
|
|
188
188
|
return true;
|
|
189
189
|
}
|
|
190
|
-
static inline bool classof(const
|
|
190
|
+
static inline bool classof(const CallGraph*g)
|
|
191
191
|
{
|
|
192
|
-
return g->getKind() ==
|
|
192
|
+
return g->getKind() == CallGraph::ThdCallGraph;
|
|
193
193
|
}
|
|
194
194
|
//@}
|
|
195
195
|
|
|
@@ -239,7 +239,7 @@ public:
|
|
|
239
239
|
assert(it != callinstToThreadJoinEdgesMap.end() && "call instruction does not have a valid callee");
|
|
240
240
|
return it->second.end();
|
|
241
241
|
}
|
|
242
|
-
inline void getJoinSites(const
|
|
242
|
+
inline void getJoinSites(const CallGraphNode* routine, InstSet& csSet)
|
|
243
243
|
{
|
|
244
244
|
for(CallInstToJoinEdgesMap::const_iterator it = callinstToThreadJoinEdgesMap.begin(), eit = callinstToThreadJoinEdgesMap.end(); it!=eit; ++it)
|
|
245
245
|
{
|
|
@@ -390,7 +390,7 @@ public:
|
|
|
390
390
|
}
|
|
391
391
|
|
|
392
392
|
/// has thread join edge
|
|
393
|
-
inline ThreadJoinEdge* hasThreadJoinEdge(const CallICFGNode* call,
|
|
393
|
+
inline ThreadJoinEdge* hasThreadJoinEdge(const CallICFGNode* call, CallGraphNode* joinFunNode, CallGraphNode* threadRoutineFunNode, CallSiteID csId) const
|
|
394
394
|
{
|
|
395
395
|
ThreadJoinEdge joinEdge(joinFunNode,threadRoutineFunNode, csId);
|
|
396
396
|
CallInstToJoinEdgesMap::const_iterator it = callinstToThreadJoinEdgesMap.find(call);
|
package/svf/include/Graphs/VFG.h
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
#include "SVFIR/SVFIR.h"
|
|
35
|
-
#include "Graphs/
|
|
35
|
+
#include "Graphs/CallGraph.h"
|
|
36
36
|
#include "Graphs/VFGNode.h"
|
|
37
37
|
#include "Graphs/VFGEdge.h"
|
|
38
38
|
|
|
@@ -100,7 +100,7 @@ protected:
|
|
|
100
100
|
FunToVFGNodesMapTy funToVFGNodesMap; ///< map a function to its VFGNodes;
|
|
101
101
|
|
|
102
102
|
GlobalVFGNodeSet globalVFGNodes; ///< set of global store VFG nodes
|
|
103
|
-
|
|
103
|
+
CallGraph* callgraph;
|
|
104
104
|
SVFIR* pag;
|
|
105
105
|
VFGK kind;
|
|
106
106
|
|
|
@@ -109,7 +109,7 @@ protected:
|
|
|
109
109
|
|
|
110
110
|
public:
|
|
111
111
|
/// Constructor
|
|
112
|
-
VFG(
|
|
112
|
+
VFG(CallGraph* callgraph, VFGK k = FULLSVFG);
|
|
113
113
|
|
|
114
114
|
/// Destructor
|
|
115
115
|
virtual ~VFG()
|
|
@@ -136,7 +136,7 @@ public:
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
/// Return PTACallGraph
|
|
139
|
-
inline
|
|
139
|
+
inline CallGraph* getCallGraph() const
|
|
140
140
|
{
|
|
141
141
|
return callgraph;
|
|
142
142
|
}
|