svf-lib 1.0.733 → 1.0.737
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/SVF-linux/Release-build/lib/libSvf.a +0 -0
- package/SVF-linux/include/DDA/ContextDDA.h +1 -1
- package/SVF-linux/include/DDA/DDAClient.h +8 -8
- package/SVF-linux/include/DDA/DDAVFSolver.h +5 -5
- package/SVF-linux/include/DDA/FlowDDA.h +1 -1
- package/SVF-linux/include/Graphs/CHG.h +351 -0
- package/SVF-linux/include/Graphs/ConsG.h +6 -6
- package/SVF-linux/include/Graphs/ConsGEdge.h +2 -2
- package/SVF-linux/include/Graphs/ConsGNode.h +1 -1
- package/SVF-linux/include/Graphs/ExternalPAG.h +14 -14
- package/SVF-linux/include/Graphs/GenericGraph.h +1 -1
- package/SVF-linux/include/Graphs/ICFGNode.h +14 -14
- package/SVF-linux/include/Graphs/IRGraph.h +236 -0
- package/SVF-linux/include/Graphs/OfflineConsG.h +1 -1
- package/SVF-linux/include/Graphs/SVFG.h +1 -1
- package/SVF-linux/include/Graphs/SVFGOPT.h +3 -3
- package/SVF-linux/include/Graphs/VFG.h +53 -52
- package/SVF-linux/include/Graphs/VFGNode.h +60 -8
- package/SVF-linux/include/MSSA/MemRegion.h +11 -11
- package/SVF-linux/include/MSSA/MemSSA.h +4 -4
- package/SVF-linux/include/MTA/FSMPTA.h +1 -1
- package/SVF-linux/include/MemoryModel/PAGBuilderFromFile.h +8 -8
- package/SVF-linux/include/MemoryModel/PTAStat.h +31 -31
- package/SVF-linux/include/MemoryModel/PointerAnalysis.h +9 -9
- package/SVF-linux/include/MemoryModel/PointerAnalysisImpl.h +3 -3
- package/SVF-linux/include/MemoryModel/SVFIR.h +525 -233
- package/SVF-linux/include/MemoryModel/SVFStatements.h +970 -0
- package/SVF-linux/include/MemoryModel/SVFVariables.h +842 -0
- package/SVF-linux/include/MemoryModel/SymbolTableInfo.h +346 -55
- package/SVF-linux/include/SABER/SaberSVFGBuilder.h +0 -2
- package/SVF-linux/include/SABER/SrcSnkDDA.h +3 -3
- package/SVF-linux/include/SVF-FE/CHGBuilder.h +69 -0
- package/SVF-linux/include/SVF-FE/DCHG.h +1 -1
- package/SVF-linux/include/SVF-FE/Graph2Json.h +1 -3
- package/SVF-linux/include/SVF-FE/SVFIRBuilder.h +405 -0
- package/SVF-linux/include/SVF-FE/SymbolTableBuilder.h +0 -1
- package/SVF-linux/include/Util/CFLSolver.h +1 -1
- package/SVF-linux/include/Util/ExtAPI.h +1 -1
- package/SVF-linux/include/Util/IRAnnotator.h +6 -6
- package/SVF-linux/include/Util/Options.h +1 -1
- package/SVF-linux/include/Util/TypeBasedHeapCloning.h +11 -11
- package/SVF-linux/include/WPA/Andersen.h +11 -11
- package/SVF-linux/include/WPA/AndersenSFR.h +4 -4
- package/SVF-linux/include/WPA/FlowSensitive.h +2 -2
- package/SVF-linux/include/WPA/FlowSensitiveTBHC.h +1 -1
- package/SVF-linux/include/WPA/Steensgaard.h +2 -2
- package/SVF-linux/include/WPA/TypeAnalysis.h +1 -1
- package/SVF-linux/include/WPA/VersionedFlowSensitive.h +2 -2
- package/SVF-linux/include/WPA/WPAStat.h +1 -2
- package/SVF-osx/Release-build/lib/CUDD/libCudd.a +0 -0
- package/SVF-osx/Release-build/lib/libSvf.a +0 -0
- package/SVF-osx/include/Graphs/GenericGraph.h +1 -1
- package/SVF-osx/include/Graphs/IRGraph.h +6 -15
- package/SVF-osx/include/Graphs/VFG.h +26 -41
- package/SVF-osx/include/Graphs/VFGNode.h +2 -2
- package/SVF-osx/include/MemoryModel/SVFIR.h +29 -96
- package/SVF-osx/include/MemoryModel/SVFStatements.h +156 -22
- package/SVF-osx/include/SVF-FE/SVFIRBuilder.h +12 -6
- package/package.json +1 -1
|
@@ -30,351 +30,643 @@
|
|
|
30
30
|
#ifndef SVFIR_H_
|
|
31
31
|
#define SVFIR_H_
|
|
32
32
|
|
|
33
|
-
#include
|
|
34
|
-
#include <map>
|
|
35
|
-
#include "Util/BasicTypes.h"
|
|
33
|
+
#include "Graphs/IRGraph.h"
|
|
36
34
|
|
|
37
35
|
namespace SVF
|
|
38
36
|
{
|
|
39
37
|
|
|
40
|
-
|
|
38
|
+
/*!
|
|
39
|
+
* SVF Intermediate representation, representing variables and statements as a Program Assignment Graph (PAG)
|
|
40
|
+
* Variables as nodes and statements as edges.
|
|
41
|
+
* SymID and NodeID are equal here (same numbering).
|
|
42
|
+
*/
|
|
43
|
+
class SVFIR : public IRGraph
|
|
44
|
+
{
|
|
45
|
+
|
|
46
|
+
friend class SVFIRBuilder;
|
|
47
|
+
friend class ExternalPAG;
|
|
48
|
+
friend class PAGBuilderFromFile;
|
|
49
|
+
friend class TypeBasedHeapCloning;
|
|
41
50
|
|
|
42
51
|
public:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
typedef Set<const CallBlockNode*> CallSiteSet;
|
|
53
|
+
typedef OrderedMap<const CallBlockNode*,NodeID> CallSiteToFunPtrMap;
|
|
54
|
+
typedef Map<NodeID,CallSiteSet> FunPtrToCallSitesMap;
|
|
55
|
+
typedef Map<NodeID,NodeBS> MemObjToFieldsMap;
|
|
56
|
+
typedef std::vector<const SVFStmt*> PAGEdgeList;
|
|
57
|
+
typedef std::vector<const SVFVar*> PAGNodeList;
|
|
58
|
+
typedef std::vector<const CopyPE*> CopyPEList;
|
|
59
|
+
typedef Map<const SVFVar*,PhiPE*> PHINodeMap;
|
|
60
|
+
typedef Map<const SVFFunction*,PAGNodeList> FunToArgsListMap;
|
|
61
|
+
typedef Map<const CallBlockNode*,PAGNodeList> CSToArgsListMap;
|
|
62
|
+
typedef Map<const RetBlockNode*,const SVFVar*> CSToRetMap;
|
|
63
|
+
typedef Map<const SVFFunction*,const SVFVar*> FunToRetMap;
|
|
64
|
+
typedef Map<const SVFFunction*,PAGEdgeSet> FunToPAGEdgeSetMap;
|
|
65
|
+
typedef Map<const ICFGNode*,PAGEdgeList> Inst2PAGEdgesMap;
|
|
66
|
+
typedef Map<NodeID, NodeID> NodeToNodeMap;
|
|
67
|
+
typedef std::pair<NodeID, Size_t> NodeOffset;
|
|
68
|
+
typedef std::pair<NodeID, LocationSet> NodeLocationSet;
|
|
69
|
+
typedef Map<NodeOffset,NodeID> NodeOffsetMap;
|
|
70
|
+
typedef Map<NodeLocationSet,NodeID> NodeLocationSetMap;
|
|
71
|
+
typedef Map<const Value*, NodeLocationSetMap> GepValPNMap;
|
|
72
|
+
typedef Map<NodePair,NodeID> NodePairSetMap;
|
|
47
73
|
|
|
48
|
-
|
|
74
|
+
private:
|
|
75
|
+
/// ValueNodes - This map indicates the Node that a particular Value* is
|
|
76
|
+
/// represented by. This contains entries for all pointers.
|
|
77
|
+
Inst2PAGEdgesMap inst2PAGEdgesMap; ///< Map a instruction to its PAGEdges
|
|
78
|
+
Inst2PAGEdgesMap inst2PTAPAGEdgesMap; ///< Map a instruction to its PointerAnalysis related PAGEdges
|
|
79
|
+
GepValPNMap GepValNodeMap; ///< Map a pair<base,off> to a gep value node id
|
|
80
|
+
NodeLocationSetMap GepObjNodeMap; ///< Map a pair<base,off> to a gep obj node id
|
|
81
|
+
MemObjToFieldsMap memToFieldsMap; ///< Map a mem object id to all its fields
|
|
82
|
+
PAGEdgeSet globPAGEdgesSet; ///< Global PAGEdges without control flow information
|
|
83
|
+
PHINodeMap phiNodeMap; ///< A set of phi copy edges
|
|
84
|
+
FunToArgsListMap funArgsListMap; ///< Map a function to a list of all its formal parameters
|
|
85
|
+
CSToArgsListMap callSiteArgsListMap; ///< Map a callsite to a list of all its actual parameters
|
|
86
|
+
CSToRetMap callSiteRetMap; ///< Map a callsite to its callsite returns PAGNodes
|
|
87
|
+
FunToRetMap funRetMap; ///< Map a function to its unique function return PAGNodes
|
|
88
|
+
static SVFIR* pag; ///< Singleton pattern here to enable instance of SVFIR can only be created once.
|
|
89
|
+
CallSiteToFunPtrMap indCallSiteToFunPtrMap; ///< Map an indirect callsite to its function pointer
|
|
90
|
+
FunPtrToCallSitesMap funPtrToCallSitesMap; ///< Map a function pointer to the callsites where it is used
|
|
91
|
+
/// Valid pointers for pointer analysis resolution connected by SVFIR edges (constraints)
|
|
92
|
+
/// this set of candidate pointers can change during pointer resolution (e.g. adding new object nodes)
|
|
93
|
+
OrderedNodeSet candidatePointers;
|
|
94
|
+
ICFG* icfg; // ICFG
|
|
95
|
+
CallSiteSet callSiteSet; /// all the callsites of a program
|
|
96
|
+
|
|
97
|
+
/// Constructor
|
|
98
|
+
SVFIR(bool buildFromFile);
|
|
99
|
+
|
|
100
|
+
/// Clean up memory
|
|
101
|
+
void destroy();
|
|
49
102
|
|
|
50
|
-
|
|
103
|
+
public:
|
|
51
104
|
|
|
52
|
-
///
|
|
105
|
+
/// Singleton design here to make sure we only have one instance during any analysis
|
|
53
106
|
//@{
|
|
54
|
-
static inline
|
|
107
|
+
static inline SVFIR* getPAG(bool buildFromFile = false)
|
|
55
108
|
{
|
|
56
|
-
|
|
109
|
+
if (pag == nullptr)
|
|
110
|
+
{
|
|
111
|
+
pag = new SVFIR(buildFromFile);
|
|
112
|
+
}
|
|
113
|
+
return pag;
|
|
57
114
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
virtual const std::string toString() const;
|
|
61
|
-
|
|
62
|
-
/// Overloading operator << for printing
|
|
63
|
-
//@{
|
|
64
|
-
friend raw_ostream& operator<< (raw_ostream &o, const SVFStmt &stmt)
|
|
115
|
+
static void releasePAG()
|
|
65
116
|
{
|
|
66
|
-
|
|
67
|
-
|
|
117
|
+
if (pag)
|
|
118
|
+
delete pag;
|
|
119
|
+
pag = nullptr;
|
|
68
120
|
}
|
|
69
121
|
//@}
|
|
70
|
-
|
|
71
|
-
inline
|
|
72
|
-
|
|
122
|
+
/// Return memToFieldsMap
|
|
123
|
+
inline MemObjToFieldsMap& getMemToFieldsMap()
|
|
124
|
+
{
|
|
125
|
+
return memToFieldsMap;
|
|
73
126
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
class AllocStmt : public SVFStmt{
|
|
80
|
-
|
|
81
|
-
public:
|
|
82
|
-
|
|
83
|
-
AllocStmt(SymID src, SymID dst) : SVFStmt(SVFSTMTK::Alloc), srcVar(src), dstVar(dst){
|
|
127
|
+
/// Return GepObjNodeMap
|
|
128
|
+
inline NodeLocationSetMap& getGepObjNodeMap()
|
|
129
|
+
{
|
|
130
|
+
return GepObjNodeMap;
|
|
84
131
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
//@{
|
|
88
|
-
static inline bool classof(const AllocStmt *)
|
|
132
|
+
/// Return ICFG
|
|
133
|
+
inline ICFG* getICFG()
|
|
89
134
|
{
|
|
90
|
-
return
|
|
135
|
+
return icfg;
|
|
91
136
|
}
|
|
92
|
-
|
|
137
|
+
/// Return valid pointers
|
|
138
|
+
inline OrderedNodeSet& getAllValidPtrs()
|
|
93
139
|
{
|
|
94
|
-
return
|
|
140
|
+
return candidatePointers;
|
|
95
141
|
}
|
|
96
|
-
|
|
142
|
+
/// Initialize candidate pointers
|
|
143
|
+
void initialiseCandidatePointers();
|
|
97
144
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
SymID dstVar;
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
class CopyStmt : public SVFStmt{
|
|
106
|
-
|
|
107
|
-
CopyStmt(SymID src, SymID dst) : SVFStmt(SVFSTMTK::Copy), srcVar(src), dstVar(dst){
|
|
145
|
+
/// Destructor
|
|
146
|
+
virtual ~SVFIR()
|
|
147
|
+
{
|
|
148
|
+
destroy();
|
|
108
149
|
}
|
|
109
|
-
|
|
110
|
-
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
150
|
+
/// SVFIR build configurations
|
|
111
151
|
//@{
|
|
112
|
-
|
|
152
|
+
/// Whether to handle blackhole edge
|
|
153
|
+
static void handleBlackHole(bool b);
|
|
154
|
+
//@}
|
|
155
|
+
/// Get LLVM Module
|
|
156
|
+
inline SVFModule* getModule()
|
|
113
157
|
{
|
|
114
|
-
return
|
|
158
|
+
return SymbolTableInfo::SymbolInfo()->getModule();
|
|
115
159
|
}
|
|
116
|
-
|
|
160
|
+
/// Get/set methods to get SVFStmts based on their kinds and ICFGNodes
|
|
161
|
+
//@{
|
|
162
|
+
/// Get edges set according to its kind
|
|
163
|
+
inline SVFStmt::PAGEdgeSetTy& getEdgeSet(SVFStmt::PEDGEK kind)
|
|
117
164
|
{
|
|
118
|
-
return
|
|
165
|
+
return PAGEdgeKindToSetMap[kind];
|
|
119
166
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
private:
|
|
125
|
-
SymID srcVar;
|
|
126
|
-
SymID dstVar;
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
class PhiStmt : public SVFStmt{
|
|
130
|
-
|
|
131
|
-
PhiStmt(SymID res, SymID op1, SymID op2) : SVFStmt(SVFSTMTK::Phi), resVar(res), op1Var(op1), op2Var(op2){
|
|
167
|
+
/// Get PTA edges set according to its kind
|
|
168
|
+
inline SVFStmt::PAGEdgeSetTy& getPTAEdgeSet(SVFStmt::PEDGEK kind)
|
|
169
|
+
{
|
|
170
|
+
return PTAPAGEdgeKindToSetMap[kind];
|
|
132
171
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
//@{
|
|
136
|
-
static inline bool classof(const PhiStmt *)
|
|
172
|
+
/// Whether this instruction has SVFIR Edge
|
|
173
|
+
inline bool hasPAGEdgeList(const ICFGNode* inst) const
|
|
137
174
|
{
|
|
138
|
-
return
|
|
175
|
+
return inst2PAGEdgesMap.find(inst)!=inst2PAGEdgesMap.end();
|
|
139
176
|
}
|
|
140
|
-
|
|
177
|
+
inline bool hasPTAPAGEdgeList(const ICFGNode* inst) const
|
|
141
178
|
{
|
|
142
|
-
return
|
|
179
|
+
return inst2PTAPAGEdgesMap.find(inst)!=inst2PTAPAGEdgesMap.end();
|
|
143
180
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
private:
|
|
149
|
-
SymID resVar;
|
|
150
|
-
SymID op1Var;
|
|
151
|
-
SymID op2Var;
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
class LoadStmt : public SVFStmt{
|
|
155
|
-
|
|
156
|
-
LoadStmt(SymID src, SymID dst) : SVFStmt(SVFSTMTK::Load), srcVar(src), dstVar(dst){
|
|
181
|
+
/// Given an instruction, get all its PAGEdges
|
|
182
|
+
inline PAGEdgeList& getInstPAGEdgeList(const ICFGNode* inst)
|
|
183
|
+
{
|
|
184
|
+
return inst2PAGEdgesMap[inst];
|
|
157
185
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
//@{
|
|
161
|
-
static inline bool classof(const LoadStmt *)
|
|
186
|
+
/// Given an instruction, get all its PTA PAGEdges
|
|
187
|
+
inline PAGEdgeList& getInstPTAPAGEdgeList(const ICFGNode* inst)
|
|
162
188
|
{
|
|
163
|
-
return
|
|
189
|
+
return inst2PTAPAGEdgesMap[inst];
|
|
164
190
|
}
|
|
165
|
-
|
|
191
|
+
/// Add a SVFStmt into instruction map
|
|
192
|
+
inline void addToInstPAGEdgeList(ICFGNode* inst, SVFStmt* edge)
|
|
166
193
|
{
|
|
167
|
-
|
|
194
|
+
edge->setICFGNode(inst);
|
|
195
|
+
inst2PAGEdgesMap[inst].push_back(edge);
|
|
196
|
+
if (edge->isPTAEdge())
|
|
197
|
+
inst2PTAPAGEdgesMap[inst].push_back(edge);
|
|
168
198
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
199
|
+
/// Get global PAGEdges (not in a procedure)
|
|
200
|
+
inline PAGEdgeSet& getGlobalPAGEdgeSet()
|
|
201
|
+
{
|
|
202
|
+
return globPAGEdgesSet;
|
|
203
|
+
}
|
|
204
|
+
/// Get all callsites
|
|
205
|
+
inline const CallSiteSet& getCallSiteSet() const
|
|
206
|
+
{
|
|
207
|
+
return callSiteSet;
|
|
208
|
+
}
|
|
209
|
+
/// Whether this SVFVar is a result operand a of phi node
|
|
210
|
+
inline bool isPhiNode(const SVFVar* node) const
|
|
211
|
+
{
|
|
212
|
+
return phiNodeMap.find(node) != phiNodeMap.end();
|
|
181
213
|
}
|
|
182
214
|
|
|
183
|
-
///
|
|
184
|
-
|
|
185
|
-
|
|
215
|
+
/// Function has arguments list
|
|
216
|
+
inline bool hasFunArgsList(const SVFFunction* func) const
|
|
217
|
+
{
|
|
218
|
+
return (funArgsListMap.find(func) != funArgsListMap.end());
|
|
219
|
+
}
|
|
220
|
+
/// Get function arguments list
|
|
221
|
+
inline FunToArgsListMap& getFunArgsMap()
|
|
222
|
+
{
|
|
223
|
+
return funArgsListMap;
|
|
224
|
+
}
|
|
225
|
+
/// Get function arguments list
|
|
226
|
+
inline const PAGNodeList& getFunArgsList(const SVFFunction* func) const
|
|
227
|
+
{
|
|
228
|
+
FunToArgsListMap::const_iterator it = funArgsListMap.find(func);
|
|
229
|
+
assert(it != funArgsListMap.end() && "this function doesn't have arguments");
|
|
230
|
+
return it->second;
|
|
231
|
+
}
|
|
232
|
+
/// Callsite has argument list
|
|
233
|
+
inline bool hasCallSiteArgsMap(const CallBlockNode* cs) const
|
|
234
|
+
{
|
|
235
|
+
return (callSiteArgsListMap.find(cs) != callSiteArgsListMap.end());
|
|
236
|
+
}
|
|
237
|
+
/// Get callsite argument list
|
|
238
|
+
inline CSToArgsListMap& getCallSiteArgsMap()
|
|
239
|
+
{
|
|
240
|
+
return callSiteArgsListMap;
|
|
241
|
+
}
|
|
242
|
+
/// Get callsite argument list
|
|
243
|
+
inline const PAGNodeList& getCallSiteArgsList(const CallBlockNode* cs) const
|
|
186
244
|
{
|
|
187
|
-
|
|
245
|
+
CSToArgsListMap::const_iterator it = callSiteArgsListMap.find(cs);
|
|
246
|
+
assert(it != callSiteArgsListMap.end() && "this call site doesn't have arguments");
|
|
247
|
+
return it->second;
|
|
188
248
|
}
|
|
189
|
-
|
|
249
|
+
/// Get callsite return
|
|
250
|
+
inline CSToRetMap& getCallSiteRets()
|
|
190
251
|
{
|
|
191
|
-
return
|
|
252
|
+
return callSiteRetMap;
|
|
253
|
+
}
|
|
254
|
+
/// Get callsite return
|
|
255
|
+
inline const SVFVar* getCallSiteRet(const RetBlockNode* cs) const
|
|
256
|
+
{
|
|
257
|
+
CSToRetMap::const_iterator it = callSiteRetMap.find(cs);
|
|
258
|
+
assert(it != callSiteRetMap.end() && "this call site doesn't have return");
|
|
259
|
+
return it->second;
|
|
260
|
+
}
|
|
261
|
+
inline bool callsiteHasRet(const RetBlockNode* cs) const
|
|
262
|
+
{
|
|
263
|
+
return callSiteRetMap.find(cs) != callSiteRetMap.end();
|
|
264
|
+
}
|
|
265
|
+
/// Get function return list
|
|
266
|
+
inline FunToRetMap& getFunRets()
|
|
267
|
+
{
|
|
268
|
+
return funRetMap;
|
|
269
|
+
}
|
|
270
|
+
/// Get function return list
|
|
271
|
+
inline const SVFVar* getFunRet(const SVFFunction* func) const
|
|
272
|
+
{
|
|
273
|
+
FunToRetMap::const_iterator it = funRetMap.find(func);
|
|
274
|
+
assert(it != funRetMap.end() && "this function doesn't have return");
|
|
275
|
+
return it->second;
|
|
276
|
+
}
|
|
277
|
+
inline bool funHasRet(const SVFFunction* func) const
|
|
278
|
+
{
|
|
279
|
+
return funRetMap.find(func) != funRetMap.end();
|
|
192
280
|
}
|
|
193
281
|
//@}
|
|
194
282
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
GepStmt(SymID res, SymID ptr, SymID offset) : SVFStmt(SVFSTMTK::Gep), resVar(res), ptrVar(ptr), offsetVar(offset){
|
|
283
|
+
/// Node and edge statistics
|
|
284
|
+
//@{
|
|
285
|
+
inline Size_t getFieldValNodeNum() const
|
|
286
|
+
{
|
|
287
|
+
return GepValNodeMap.size();
|
|
288
|
+
}
|
|
289
|
+
inline Size_t getFieldObjNodeNum() const
|
|
290
|
+
{
|
|
291
|
+
return GepObjNodeMap.size();
|
|
205
292
|
}
|
|
293
|
+
//@}
|
|
206
294
|
|
|
207
|
-
///
|
|
295
|
+
/// Due to constaint expression, curInst is used to distinguish different instructions (e.g., memorycpy) when creating GepValPN.
|
|
296
|
+
inline NodeID getGepValNode(const Value* curInst, NodeID base, const LocationSet& ls) const
|
|
297
|
+
{
|
|
298
|
+
GepValPNMap::const_iterator iter = GepValNodeMap.find(curInst);
|
|
299
|
+
if(iter==GepValNodeMap.end()){
|
|
300
|
+
return UINT_MAX;
|
|
301
|
+
}
|
|
302
|
+
else{
|
|
303
|
+
NodeLocationSetMap::const_iterator lit = iter->second.find(std::make_pair(base, ls));
|
|
304
|
+
if(lit==iter->second.end())
|
|
305
|
+
return UINT_MAX;
|
|
306
|
+
else
|
|
307
|
+
return lit->second;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/// Add/get indirect callsites
|
|
208
312
|
//@{
|
|
209
|
-
|
|
313
|
+
inline const CallSiteToFunPtrMap& getIndirectCallsites() const
|
|
210
314
|
{
|
|
211
|
-
return
|
|
315
|
+
return indCallSiteToFunPtrMap;
|
|
212
316
|
}
|
|
213
|
-
|
|
317
|
+
inline NodeID getFunPtr(const CallBlockNode* cs) const
|
|
214
318
|
{
|
|
215
|
-
|
|
319
|
+
CallSiteToFunPtrMap::const_iterator it = indCallSiteToFunPtrMap.find(cs);
|
|
320
|
+
assert(it!=indCallSiteToFunPtrMap.end() && "indirect callsite not have a function pointer?");
|
|
321
|
+
return it->second;
|
|
322
|
+
}
|
|
323
|
+
inline const CallSiteSet& getIndCallSites(NodeID funPtr) const
|
|
324
|
+
{
|
|
325
|
+
FunPtrToCallSitesMap::const_iterator it = funPtrToCallSitesMap.find(funPtr);
|
|
326
|
+
assert(it!=funPtrToCallSitesMap.end() && "function pointer not used at any indirect callsite?");
|
|
327
|
+
return it->second;
|
|
328
|
+
}
|
|
329
|
+
inline bool isIndirectCallSites(const CallBlockNode* cs) const
|
|
330
|
+
{
|
|
331
|
+
return (indCallSiteToFunPtrMap.find(cs) != indCallSiteToFunPtrMap.end());
|
|
332
|
+
}
|
|
333
|
+
inline bool isFunPtr(NodeID id) const
|
|
334
|
+
{
|
|
335
|
+
return (funPtrToCallSitesMap.find(id) != funPtrToCallSitesMap.end());
|
|
216
336
|
}
|
|
217
337
|
//@}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
338
|
+
/// Get an edge according to src, dst and kind
|
|
339
|
+
//@{
|
|
340
|
+
inline SVFStmt* getIntraPAGEdge(NodeID src, NodeID dst, SVFStmt::PEDGEK kind)
|
|
341
|
+
{
|
|
342
|
+
return getIntraPAGEdge(getGNode(src), getGNode(dst), kind);
|
|
343
|
+
}
|
|
344
|
+
inline SVFStmt* getIntraPAGEdge(SVFVar* src, SVFVar* dst, SVFStmt::PEDGEK kind)
|
|
345
|
+
{
|
|
346
|
+
SVFStmt edge(src,dst,kind);
|
|
347
|
+
const SVFStmt::PAGEdgeSetTy& edgeSet = getEdgeSet(kind);
|
|
348
|
+
SVFStmt::PAGEdgeSetTy::const_iterator it = edgeSet.find(&edge);
|
|
349
|
+
assert(it != edgeSet.end() && "can not find pag edge");
|
|
350
|
+
return (*it);
|
|
230
351
|
}
|
|
352
|
+
//@}
|
|
231
353
|
|
|
232
|
-
///
|
|
354
|
+
/// Get memory object - Return memory object according to pag node id
|
|
355
|
+
/// return whole allocated memory object if this node is a gep obj node
|
|
356
|
+
/// return nullptr is this node is not a ObjPN type
|
|
233
357
|
//@{
|
|
234
|
-
|
|
358
|
+
inline const MemObj*getObject(NodeID id) const
|
|
235
359
|
{
|
|
236
|
-
|
|
360
|
+
const SVFVar* node = getGNode(id);
|
|
361
|
+
if(const ObjPN* objPN = SVFUtil::dyn_cast<ObjPN>(node))
|
|
362
|
+
return getObject(objPN);
|
|
363
|
+
else
|
|
364
|
+
return nullptr;
|
|
237
365
|
}
|
|
238
|
-
|
|
366
|
+
inline const MemObj*getObject(const ObjPN* node) const
|
|
239
367
|
{
|
|
240
|
-
return
|
|
368
|
+
return node->getMemObj();
|
|
241
369
|
}
|
|
242
370
|
//@}
|
|
243
371
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
372
|
+
/// Get a field SVFIR Object node according to base mem obj and offset
|
|
373
|
+
NodeID getGepObjNode(const MemObj* obj, const LocationSet& ls);
|
|
374
|
+
/// Get a field obj SVFIR node according to a mem obj and a given offset
|
|
375
|
+
NodeID getGepObjNode(NodeID id, const LocationSet& ls) ;
|
|
376
|
+
/// Get a field-insensitive obj SVFIR node according to a mem obj
|
|
377
|
+
//@{
|
|
378
|
+
inline NodeID getFIObjNode(const MemObj* obj) const
|
|
379
|
+
{
|
|
380
|
+
return obj->getId();
|
|
381
|
+
}
|
|
382
|
+
inline NodeID getFIObjNode(NodeID id) const
|
|
383
|
+
{
|
|
384
|
+
SVFVar* node = pag->getGNode(id);
|
|
385
|
+
assert(SVFUtil::isa<ObjPN>(node) && "need an object node");
|
|
386
|
+
ObjPN* obj = SVFUtil::cast<ObjPN>(node);
|
|
387
|
+
return getFIObjNode(obj->getMemObj());
|
|
255
388
|
}
|
|
389
|
+
//@}
|
|
256
390
|
|
|
257
|
-
///
|
|
391
|
+
/// Get black hole and constant id
|
|
258
392
|
//@{
|
|
259
|
-
|
|
393
|
+
inline bool isBlkPtr(NodeID id) const
|
|
260
394
|
{
|
|
261
|
-
return
|
|
395
|
+
return (SymbolTableInfo::isBlkPtr(id));
|
|
262
396
|
}
|
|
263
|
-
|
|
397
|
+
inline bool isNullPtr(NodeID id) const
|
|
264
398
|
{
|
|
265
|
-
return
|
|
399
|
+
return (SymbolTableInfo::isNullPtr(id));
|
|
400
|
+
}
|
|
401
|
+
inline bool isBlkObjOrConstantObj(NodeID id) const
|
|
402
|
+
{
|
|
403
|
+
return (isBlkObj(id) || isConstantObj(id));
|
|
404
|
+
}
|
|
405
|
+
inline bool isBlkObj(NodeID id) const
|
|
406
|
+
{
|
|
407
|
+
return SymbolTableInfo::isBlkObj(id);
|
|
408
|
+
}
|
|
409
|
+
inline bool isConstantObj(NodeID id) const
|
|
410
|
+
{
|
|
411
|
+
const MemObj* obj = getObject(id);
|
|
412
|
+
assert(obj && "not an object node?");
|
|
413
|
+
return SymbolTableInfo::isConstantObj(id) || obj->isConstant();
|
|
414
|
+
}
|
|
415
|
+
inline bool isNonPointerObj(NodeID id) const
|
|
416
|
+
{
|
|
417
|
+
SVFVar* node = getGNode(id);
|
|
418
|
+
if (FIObjPN* fiNode = SVFUtil::dyn_cast<FIObjPN>(node))
|
|
419
|
+
{
|
|
420
|
+
return (fiNode->getMemObj()->hasPtrObj() == false);
|
|
421
|
+
}
|
|
422
|
+
else if (GepObjPN* gepNode = SVFUtil::dyn_cast<GepObjPN>(node))
|
|
423
|
+
{
|
|
424
|
+
return (gepNode->getMemObj()->isNonPtrFieldObj(gepNode->getLocationSet()));
|
|
425
|
+
}
|
|
426
|
+
else if (SVFUtil::isa<DummyObjPN>(node))
|
|
427
|
+
{
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
else
|
|
431
|
+
{
|
|
432
|
+
assert(false && "expecting a object node");
|
|
433
|
+
return false;
|
|
434
|
+
}
|
|
266
435
|
}
|
|
267
436
|
//@}
|
|
268
437
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
438
|
+
/// Base and Offset methods for Value and Object node
|
|
439
|
+
//@{
|
|
440
|
+
/// Get a base pointer node given a field pointer
|
|
441
|
+
NodeID getBaseValNode(NodeID nodeId);
|
|
442
|
+
LocationSet getLocationSetFromBaseNode(NodeID nodeId);
|
|
443
|
+
inline NodeID getBaseObjNode(NodeID id) const
|
|
444
|
+
{
|
|
445
|
+
return getBaseObj(id)->getId();
|
|
446
|
+
}
|
|
447
|
+
inline const MemObj* getBaseObj(NodeID id) const
|
|
448
|
+
{
|
|
449
|
+
const SVFVar* node = pag->getGNode(id);
|
|
450
|
+
assert(SVFUtil::isa<ObjPN>(node) && "need an object node");
|
|
451
|
+
const ObjPN* obj = SVFUtil::cast<ObjPN>(node);
|
|
452
|
+
return obj->getMemObj();
|
|
280
453
|
}
|
|
454
|
+
//@}
|
|
281
455
|
|
|
282
|
-
///
|
|
456
|
+
/// Get all fields of an object
|
|
283
457
|
//@{
|
|
284
|
-
|
|
458
|
+
NodeBS& getAllFieldsObjNode(const MemObj* obj);
|
|
459
|
+
NodeBS& getAllFieldsObjNode(NodeID id);
|
|
460
|
+
NodeBS getFieldsAfterCollapse(NodeID id);
|
|
461
|
+
//@}
|
|
462
|
+
inline NodeID addDummyValNode()
|
|
285
463
|
{
|
|
286
|
-
return
|
|
464
|
+
return addDummyValNode(NodeIDAllocator::get()->allocateValueId());
|
|
287
465
|
}
|
|
288
|
-
|
|
466
|
+
inline NodeID addDummyObjNode(const Type* type = nullptr)
|
|
289
467
|
{
|
|
290
|
-
return
|
|
468
|
+
return addDummyObjNode(NodeIDAllocator::get()->allocateObjectId(), type);
|
|
291
469
|
}
|
|
470
|
+
/// Whether a node is a valid pointer
|
|
471
|
+
//@{
|
|
472
|
+
bool isValidPointer(NodeID nodeId) const;
|
|
473
|
+
|
|
474
|
+
bool isValidTopLevelPtr(const SVFVar* node);
|
|
292
475
|
//@}
|
|
293
476
|
|
|
294
|
-
|
|
477
|
+
/// Print SVFIR
|
|
478
|
+
void print();
|
|
295
479
|
|
|
296
480
|
private:
|
|
297
|
-
SymID resVar;
|
|
298
|
-
SymID opVar;
|
|
299
|
-
};
|
|
300
481
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
482
|
+
/// Map a SVFStatement type to a set of corresponding SVF statements
|
|
483
|
+
inline void addToStmt2TypeMap(SVFStmt* edge) {
|
|
484
|
+
bool added = PAGEdgeKindToSetMap[edge->getEdgeKind()].insert(edge).second;
|
|
485
|
+
assert(added && "duplicated edge, not added!!!");
|
|
486
|
+
if (edge->isPTAEdge())
|
|
487
|
+
{
|
|
488
|
+
totalPTAPAGEdge++;
|
|
489
|
+
PTAPAGEdgeKindToSetMap[edge->getEdgeKind()].insert(edge);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
/// Get/set method for function/callsite arguments and returns
|
|
493
|
+
//@{
|
|
494
|
+
/// Add function arguments
|
|
495
|
+
inline void addFunArgs(const SVFFunction* fun, const SVFVar* arg)
|
|
496
|
+
{
|
|
497
|
+
FunEntryBlockNode* funEntryBlockNode = icfg->getFunEntryBlockNode(fun);
|
|
498
|
+
funEntryBlockNode->addFormalParms(arg);
|
|
499
|
+
funArgsListMap[fun].push_back(arg);
|
|
500
|
+
}
|
|
501
|
+
/// Add function returns
|
|
502
|
+
inline void addFunRet(const SVFFunction* fun, const SVFVar* ret)
|
|
503
|
+
{
|
|
504
|
+
FunExitBlockNode* funExitBlockNode = icfg->getFunExitBlockNode(fun);
|
|
505
|
+
funExitBlockNode->addFormalRet(ret);
|
|
506
|
+
funRetMap[fun] = ret;
|
|
507
|
+
}
|
|
508
|
+
/// Add callsite arguments
|
|
509
|
+
inline void addCallSiteArgs(CallBlockNode* callBlockNode,const SVFVar* arg)
|
|
510
|
+
{
|
|
511
|
+
callBlockNode->addActualParms(arg);
|
|
512
|
+
callSiteArgsListMap[callBlockNode].push_back(arg);
|
|
513
|
+
}
|
|
514
|
+
/// Add callsite returns
|
|
515
|
+
inline void addCallSiteRets(RetBlockNode* retBlockNode,const SVFVar* arg)
|
|
516
|
+
{
|
|
517
|
+
retBlockNode->addActualRet(arg);
|
|
518
|
+
callSiteRetMap[retBlockNode]= arg;
|
|
519
|
+
}
|
|
520
|
+
/// Add indirect callsites
|
|
521
|
+
inline void addIndirectCallsites(const CallBlockNode* cs,NodeID funPtr)
|
|
522
|
+
{
|
|
523
|
+
bool added = indCallSiteToFunPtrMap.insert(std::make_pair(cs,funPtr)).second;
|
|
524
|
+
funPtrToCallSitesMap[funPtr].insert(cs);
|
|
525
|
+
assert(added && "adding the same indirect callsite twice?");
|
|
304
526
|
}
|
|
305
527
|
|
|
306
|
-
///
|
|
528
|
+
/// add node into SVFIR
|
|
307
529
|
//@{
|
|
308
|
-
|
|
530
|
+
/// Add a value (pointer) node
|
|
531
|
+
inline NodeID addValNode(const Value* val, NodeID i)
|
|
309
532
|
{
|
|
310
|
-
|
|
533
|
+
SVFVar *node = new ValPN(val,i);
|
|
534
|
+
return addValNode(val, node, i);
|
|
311
535
|
}
|
|
312
|
-
|
|
536
|
+
/// Add a memory obj node
|
|
537
|
+
inline NodeID addObjNode(const Value* val, NodeID i)
|
|
313
538
|
{
|
|
314
|
-
|
|
539
|
+
const MemObj* mem = getMemObj(val);
|
|
540
|
+
assert(((mem->getId() == i)) && "not same object id?");
|
|
541
|
+
return addFIObjNode(mem);
|
|
315
542
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
543
|
+
/// Add a unique return node for a procedure
|
|
544
|
+
inline NodeID addRetNode(const SVFFunction* val, NodeID i)
|
|
545
|
+
{
|
|
546
|
+
SVFVar *node = new RetPN(val,i);
|
|
547
|
+
return addRetNode(val, node, i);
|
|
548
|
+
}
|
|
549
|
+
/// Add a unique vararg node for a procedure
|
|
550
|
+
inline NodeID addVarargNode(const SVFFunction* val, NodeID i)
|
|
551
|
+
{
|
|
552
|
+
SVFVar *node = new VarArgPN(val,i);
|
|
553
|
+
return addNode(node,i);
|
|
327
554
|
}
|
|
328
555
|
|
|
329
|
-
///
|
|
556
|
+
/// Add a temp field value node, this method can only invoked by getGepValNode
|
|
557
|
+
NodeID addGepValNode(const Value* curInst,const Value* val, const LocationSet& ls, NodeID i, const Type *type, u32_t fieldidx);
|
|
558
|
+
/// Add a field obj node, this method can only invoked by getGepObjNode
|
|
559
|
+
NodeID addGepObjNode(const MemObj* obj, const LocationSet& ls);
|
|
560
|
+
/// Add a field-insensitive node, this method can only invoked by getFIGepObjNode
|
|
561
|
+
NodeID addFIObjNode(const MemObj* obj);
|
|
562
|
+
//@}
|
|
563
|
+
|
|
564
|
+
/// Add a dummy value/object node according to node ID (llvm value is null)
|
|
330
565
|
//@{
|
|
331
|
-
|
|
566
|
+
inline NodeID addDummyValNode(NodeID i)
|
|
567
|
+
{
|
|
568
|
+
return addValNode(nullptr, new DummyValPN(i), i);
|
|
569
|
+
}
|
|
570
|
+
inline NodeID addDummyObjNode(NodeID i, const Type* type)
|
|
571
|
+
{
|
|
572
|
+
const MemObj* mem = addDummyMemObj(i, type);
|
|
573
|
+
return addObjNode(nullptr, new DummyObjPN(i,mem), i);
|
|
574
|
+
}
|
|
575
|
+
inline const MemObj* addDummyMemObj(NodeID i, const Type* type)
|
|
332
576
|
{
|
|
333
|
-
return
|
|
577
|
+
return SymbolTableInfo::SymbolInfo()->createDummyObj(i,type);
|
|
334
578
|
}
|
|
335
|
-
|
|
579
|
+
inline NodeID addBlackholeObjNode()
|
|
336
580
|
{
|
|
337
|
-
return
|
|
581
|
+
return addObjNode(nullptr, new DummyObjPN(getBlackHoleNode(),getBlackHoleObj()), getBlackHoleNode());
|
|
582
|
+
}
|
|
583
|
+
inline NodeID addConstantObjNode()
|
|
584
|
+
{
|
|
585
|
+
return addObjNode(nullptr, new DummyObjPN(getConstantNode(),getConstantObj()), getConstantNode());
|
|
586
|
+
}
|
|
587
|
+
inline NodeID addBlackholePtrNode()
|
|
588
|
+
{
|
|
589
|
+
return addDummyValNode(getBlkPtr());
|
|
338
590
|
}
|
|
339
591
|
//@}
|
|
340
592
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
593
|
+
/// Add a value (pointer) node
|
|
594
|
+
inline NodeID addValNode(const Value*, SVFVar *node, NodeID i)
|
|
595
|
+
{
|
|
596
|
+
assert(hasGNode(i) == false && "This NodeID clashes here. Please check NodeIDAllocator. Switch Strategy::DEBUG to SEQ or DENSE");
|
|
597
|
+
return addNode(node,i);
|
|
598
|
+
}
|
|
599
|
+
/// Add a memory obj node
|
|
600
|
+
inline NodeID addObjNode(const Value*, SVFVar *node, NodeID i)
|
|
601
|
+
{
|
|
602
|
+
assert(hasGNode(i) == false && "This NodeID clashes here. Please check NodeIDAllocator. Switch Strategy::DEBUG to SEQ or DENSE");
|
|
603
|
+
return addNode(node,i);
|
|
604
|
+
}
|
|
605
|
+
/// Add a unique return node for a procedure
|
|
606
|
+
inline NodeID addRetNode(const SVFFunction*, SVFVar *node, NodeID i)
|
|
607
|
+
{
|
|
608
|
+
return addNode(node,i);
|
|
609
|
+
}
|
|
610
|
+
/// Add a unique vararg node for a procedure
|
|
611
|
+
inline NodeID addVarargNode(const SVFFunction*, SVFVar *node, NodeID i)
|
|
612
|
+
{
|
|
613
|
+
return addNode(node,i);
|
|
350
614
|
}
|
|
351
615
|
|
|
352
|
-
///
|
|
353
|
-
|
|
354
|
-
static inline bool classof(const BranchStmt *)
|
|
616
|
+
/// Add global PAGEdges (not in a procedure)
|
|
617
|
+
inline void addGlobalPAGEdge(const SVFStmt* edge)
|
|
355
618
|
{
|
|
356
|
-
|
|
619
|
+
globPAGEdgesSet.insert(edge);
|
|
357
620
|
}
|
|
358
|
-
|
|
621
|
+
/// Add callsites
|
|
622
|
+
inline void addCallSite(const CallBlockNode* call)
|
|
359
623
|
{
|
|
360
|
-
|
|
624
|
+
callSiteSet.insert(call);
|
|
361
625
|
}
|
|
626
|
+
/// Add an edge into SVFIR
|
|
627
|
+
//@{
|
|
628
|
+
/// Add Address edge
|
|
629
|
+
AddrPE* addAddrPE(NodeID src, NodeID dst);
|
|
630
|
+
/// Add Copy edge
|
|
631
|
+
CopyPE* addCopyPE(NodeID src, NodeID dst);
|
|
632
|
+
/// Add phi node information
|
|
633
|
+
PhiPE* addPhiNode(NodeID res, NodeID opnd);
|
|
634
|
+
/// Add Copy edge
|
|
635
|
+
CmpPE* addCmpPE(NodeID op1, NodeID op2, NodeID dst, u32_t opcode);
|
|
636
|
+
/// Add Copy edge
|
|
637
|
+
BinaryOPPE* addBinaryOPPE(NodeID op1, NodeID op2, NodeID dst, u32_t opcode);
|
|
638
|
+
/// Add Unary edge
|
|
639
|
+
UnaryOPPE* addUnaryOPPE(NodeID src, NodeID dst, u32_t opcode);
|
|
640
|
+
/// Add BranchStmt
|
|
641
|
+
BranchStmt* addBranchStmt(NodeID br, NodeID cond, std::vector<const ICFGNode*> succs);
|
|
642
|
+
/// Add Load edge
|
|
643
|
+
LoadPE* addLoadPE(NodeID src, NodeID dst);
|
|
644
|
+
/// Add Store edge
|
|
645
|
+
StorePE* addStorePE(NodeID src, NodeID dst, const IntraBlockNode* val);
|
|
646
|
+
/// Add Call edge
|
|
647
|
+
CallPE* addCallPE(NodeID src, NodeID dst, const CallBlockNode* cs);
|
|
648
|
+
/// Add Return edge
|
|
649
|
+
RetPE* addRetPE(NodeID src, NodeID dst, const CallBlockNode* cs);
|
|
650
|
+
/// Add Gep edge
|
|
651
|
+
GepPE* addGepPE(NodeID src, NodeID dst, const LocationSet& ls, bool constGep);
|
|
652
|
+
/// Add Offset(Gep) edge
|
|
653
|
+
NormalGepPE* addNormalGepPE(NodeID src, NodeID dst, const LocationSet& ls);
|
|
654
|
+
/// Add Variant(Gep) edge
|
|
655
|
+
VariantGepPE* addVariantGepPE(NodeID src, NodeID dst);
|
|
656
|
+
/// Add Thread fork edge for parameter passing
|
|
657
|
+
TDForkPE* addThreadForkPE(NodeID src, NodeID dst, const CallBlockNode* cs);
|
|
658
|
+
/// Add Thread join edge for parameter passing
|
|
659
|
+
TDJoinPE* addThreadJoinPE(NodeID src, NodeID dst, const CallBlockNode* cs);
|
|
362
660
|
//@}
|
|
363
661
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
private:
|
|
367
|
-
SymID condition;
|
|
368
|
-
SVFStmt* br1;
|
|
369
|
-
SVFStmt* br2;
|
|
662
|
+
/// Set a pointer points-to black hole (e.g. int2ptr)
|
|
663
|
+
SVFStmt* addBlackHoleAddrPE(NodeID node);
|
|
370
664
|
};
|
|
371
665
|
|
|
666
|
+
typedef SVFIR PAG;
|
|
372
667
|
|
|
373
|
-
|
|
374
|
-
|
|
668
|
+
} // End namespace SVF
|
|
375
669
|
|
|
376
|
-
};
|
|
377
670
|
|
|
378
|
-
} // End namespace SVF
|
|
379
671
|
|
|
380
672
|
#endif /* SVFIR_H_ */
|