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