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.
Files changed (47) hide show
  1. package/SVF-osx/Release-build/lib/CUDD/libCudd.a +0 -0
  2. package/SVF-osx/Release-build/lib/libSvf.a +0 -0
  3. package/SVF-osx/include/DDA/ContextDDA.h +1 -1
  4. package/SVF-osx/include/DDA/DDAClient.h +8 -8
  5. package/SVF-osx/include/DDA/DDAVFSolver.h +5 -5
  6. package/SVF-osx/include/DDA/FlowDDA.h +1 -1
  7. package/SVF-osx/include/Graphs/ConsG.h +6 -6
  8. package/SVF-osx/include/Graphs/ConsGEdge.h +2 -2
  9. package/SVF-osx/include/Graphs/ConsGNode.h +1 -1
  10. package/SVF-osx/include/Graphs/ExternalPAG.h +14 -14
  11. package/SVF-osx/include/Graphs/ICFGNode.h +14 -14
  12. package/SVF-osx/include/Graphs/IRGraph.h +245 -0
  13. package/SVF-osx/include/Graphs/OfflineConsG.h +1 -1
  14. package/SVF-osx/include/Graphs/SVFG.h +1 -1
  15. package/SVF-osx/include/Graphs/SVFGOPT.h +3 -3
  16. package/SVF-osx/include/Graphs/VFG.h +19 -19
  17. package/SVF-osx/include/Graphs/VFGNode.h +2 -3
  18. package/SVF-osx/include/MSSA/MemRegion.h +11 -11
  19. package/SVF-osx/include/MSSA/MemSSA.h +4 -4
  20. package/SVF-osx/include/MTA/FSMPTA.h +1 -1
  21. package/SVF-osx/include/MemoryModel/PAGBuilderFromFile.h +8 -8
  22. package/SVF-osx/include/MemoryModel/PTAStat.h +31 -31
  23. package/SVF-osx/include/MemoryModel/PointerAnalysis.h +9 -9
  24. package/SVF-osx/include/MemoryModel/PointerAnalysisImpl.h +3 -3
  25. package/SVF-osx/include/MemoryModel/SVFIR.h +591 -233
  26. package/SVF-osx/include/MemoryModel/SVFStatements.h +738 -0
  27. package/SVF-osx/include/MemoryModel/SVFVariables.h +842 -0
  28. package/SVF-osx/include/MemoryModel/SymbolTableInfo.h +346 -55
  29. package/SVF-osx/include/SABER/SaberSVFGBuilder.h +0 -2
  30. package/SVF-osx/include/SABER/SrcSnkDDA.h +3 -3
  31. package/SVF-osx/include/SVF-FE/Graph2Json.h +1 -3
  32. package/SVF-osx/include/SVF-FE/SVFIRBuilder.h +392 -0
  33. package/SVF-osx/include/SVF-FE/SymbolTableBuilder.h +0 -1
  34. package/SVF-osx/include/Util/CFLSolver.h +1 -1
  35. package/SVF-osx/include/Util/ExtAPI.h +1 -1
  36. package/SVF-osx/include/Util/IRAnnotator.h +6 -6
  37. package/SVF-osx/include/Util/Options.h +1 -1
  38. package/SVF-osx/include/Util/TypeBasedHeapCloning.h +11 -11
  39. package/SVF-osx/include/WPA/Andersen.h +11 -11
  40. package/SVF-osx/include/WPA/AndersenSFR.h +4 -4
  41. package/SVF-osx/include/WPA/FlowSensitive.h +2 -2
  42. package/SVF-osx/include/WPA/FlowSensitiveTBHC.h +1 -1
  43. package/SVF-osx/include/WPA/Steensgaard.h +2 -2
  44. package/SVF-osx/include/WPA/TypeAnalysis.h +1 -1
  45. package/SVF-osx/include/WPA/VersionedFlowSensitive.h +2 -2
  46. package/SVF-osx/include/WPA/WPAStat.h +1 -2
  47. package/package.json +1 -1
@@ -30,351 +30,709 @@
30
30
  #ifndef SVFIR_H_
31
31
  #define SVFIR_H_
32
32
 
33
- #include <set>
34
- #include <map>
35
- #include "Util/BasicTypes.h"
33
+ #include "Graphs/IRGraph.h"
36
34
 
37
35
  namespace SVF
38
36
  {
39
37
 
40
- class SVFStmt{
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
- enum SVFSTMTK
44
- {
45
- Alloc, Copy, Phi, Store, Load, Call, FunRet, Gep, Cmp, Binary, Unary, Branch
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
- SVFStmt(u32_t k): kind(k){
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
- /// ClassOf
114
+ /// Singleton design here to make sure we only have one instance during any analysis
53
115
  //@{
54
- static inline bool classof(const SVFStmt*)
116
+ static inline SVFIR* getPAG(bool buildFromFile = false)
55
117
  {
56
- return true;
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
- o << stmt.toString();
67
- return o;
126
+ if (pag)
127
+ delete pag;
128
+ pag = nullptr;
68
129
  }
69
130
  //@}
70
-
71
- inline u32_t getKind() const {
72
- return kind;
131
+ /// Return memToFieldsMap
132
+ inline MemObjToFieldsMap& getMemToFieldsMap()
133
+ {
134
+ return memToFieldsMap;
73
135
  }
74
-
75
- private:
76
- u32_t kind;
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
87
- //@{
88
- static inline bool classof(const AllocStmt *)
141
+ /// Return ICFG
142
+ inline ICFG* getICFG()
89
143
  {
90
- return true;
144
+ return icfg;
91
145
  }
92
- static inline bool classof(const SVFStmt *stmt)
146
+ /// Return valid pointers
147
+ inline OrderedNodeSet& getAllValidPtrs()
93
148
  {
94
- return stmt->getKind() == SVFSTMTK::Alloc;
149
+ return candidatePointers;
95
150
  }
96
- //@}
97
-
98
- virtual const std::string toString() const;
151
+ /// Initialize candidate pointers
152
+ void initialiseCandidatePointers();
99
153
 
100
- private:
101
- SymID srcVar;
102
- SymID dstVar;
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
- static inline bool classof(const CopyStmt *)
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 true;
167
+ return SymbolTableInfo::SymbolInfo()->getModule();
115
168
  }
116
- static inline bool classof(const SVFStmt *stmt)
169
+ inline void addCallSite(const CallBlockNode* call)
117
170
  {
118
- return stmt->getKind() == SVFSTMTK::Copy;
171
+ callSiteSet.insert(call);
119
172
  }
120
- //@}
121
-
122
- virtual const std::string toString() const;
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
- static inline bool classof(const PhiStmt *)
179
+ /// Whether this instruction has SVFIR Edge
180
+ inline bool hasPAGEdgeList(const ICFGNode* inst) const
137
181
  {
138
- return true;
182
+ return inst2PAGEdgesMap.find(inst)!=inst2PAGEdgesMap.end();
139
183
  }
140
- static inline bool classof(const SVFStmt *stmt)
184
+ inline bool hasPTAPAGEdgeList(const ICFGNode* inst) const
141
185
  {
142
- return stmt->getKind() == SVFSTMTK::Phi;
186
+ return inst2PTAPAGEdgesMap.find(inst)!=inst2PTAPAGEdgesMap.end();
143
187
  }
144
- //@}
145
-
146
- virtual const std::string toString() const;
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
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 true;
196
+ return inst2PTAPAGEdgesMap[inst];
164
197
  }
165
- static inline bool classof(const SVFStmt *stmt)
198
+ /// Add a SVFStmt into instruction map
199
+ inline void addToInstPAGEdgeList(ICFGNode* inst, SVFStmt* edge)
166
200
  {
167
- return stmt->getKind() == SVFSTMTK::Load;
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
- virtual const std::string toString() const;
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
184
- //@{
185
- static inline bool classof(const StoreStmt *)
211
+ /// Get global PAGEdges (not in a procedure)
212
+ inline PAGEdgeSet& getGlobalPAGEdgeSet()
186
213
  {
187
- return true;
214
+ return globPAGEdgesSet;
188
215
  }
189
- static inline bool classof(const SVFStmt *stmt)
216
+ /// Add phi node information
217
+ inline void addPhiNode(const SVFVar* res, const CopyPE* edge)
190
218
  {
191
- return stmt->getKind() == SVFSTMTK::Store;
219
+ phiNodeMap[res].push_back(edge);
192
220
  }
193
- //@}
194
-
195
- virtual const std::string toString() const;
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
208
- //@{
209
- static inline bool classof(const GepStmt *)
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 true;
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
- static inline bool classof(const SVFStmt *stmt)
279
+ /// Add phi node information
280
+ inline void addCmpNode(const SVFVar* res, const CmpPE* edge)
214
281
  {
215
- return stmt->getKind() == SVFSTMTK::Gep;
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
- SymID resVar;
223
- SymID ptrVar;
224
- SymID offsetVar;
225
- };
226
-
227
- class CmpStmt : public SVFStmt{
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
- CmpStmt(SymID res, SymID op1, SymID op2) : SVFStmt(SVFSTMTK::Cmp), resVar(res), op1Var(op1), op2Var(op2){
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
408
+ /// Node and edge statistics
233
409
  //@{
234
- static inline bool classof(const CmpStmt *)
410
+ inline Size_t getFieldValNodeNum() const
235
411
  {
236
- return true;
412
+ return GepValNodeMap.size();
237
413
  }
238
- static inline bool classof(const SVFStmt *stmt)
414
+ inline Size_t getFieldObjNodeNum() const
239
415
  {
240
- return stmt->getKind() == SVFSTMTK::Cmp;
416
+ return GepObjNodeMap.size();
241
417
  }
242
418
  //@}
243
419
 
244
- virtual const std::string toString() const;
245
-
246
- private:
247
- SymID resVar;
248
- SymID op1Var;
249
- SymID op2Var;
250
- };
251
-
252
- class BinaryStmt : public SVFStmt{
253
-
254
- BinaryStmt(SymID res, SymID op1, SymID op2) : SVFStmt(SVFSTMTK::Binary), resVar(res), op1Var(op1), op2Var(op2){
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
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
- static inline bool classof(const BinaryStmt *)
465
+ inline SVFStmt* getIntraPAGEdge(NodeID src, NodeID dst, SVFStmt::PEDGEK kind)
260
466
  {
261
- return true;
467
+ return getIntraPAGEdge(getGNode(src), getGNode(dst), kind);
262
468
  }
263
- static inline bool classof(const SVFStmt *stmt)
469
+ inline SVFStmt* getIntraPAGEdge(SVFVar* src, SVFVar* dst, SVFStmt::PEDGEK kind)
264
470
  {
265
- return stmt->getKind() == SVFSTMTK::Binary;
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
- virtual const std::string toString() const;
270
-
271
- private:
272
- SymID resVar;
273
- SymID op1Var;
274
- SymID op2Var;
275
- };
276
-
277
- class UnaryStmt : public SVFStmt{
278
-
279
- UnaryStmt(SymID res, SymID op) : SVFStmt(SVFSTMTK::Unary), resVar(res), opVar(op){
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
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
- static inline bool classof(const UnaryStmt *)
503
+ inline NodeID getFIObjNode(const MemObj* obj) const
285
504
  {
286
- return true;
505
+ return obj->getId();
287
506
  }
288
- static inline bool classof(const SVFStmt *stmt)
507
+ inline NodeID getFIObjNode(NodeID id) const
289
508
  {
290
- return stmt->getKind() == SVFSTMTK::Unary;
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
- virtual const std::string toString() const;
295
-
296
- private:
297
- SymID resVar;
298
- SymID opVar;
299
- };
300
-
301
- class CallStmt : public SVFStmt{
302
-
303
- CallStmt(CallSite cs) : SVFStmt(SVFSTMTK::Call), callsite(cs){
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
563
+ /// Base and Offset methods for Value and Object node
307
564
  //@{
308
- static inline bool classof(const CallStmt *)
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 true;
570
+ return getBaseObj(id)->getId();
311
571
  }
312
- static inline bool classof(const SVFStmt *stmt)
572
+ inline const MemObj* getBaseObj(NodeID id) const
313
573
  {
314
- return stmt->getKind() == SVFSTMTK::Call;
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
- virtual const std::string toString() const;
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
- CallSite callsite;
322
- };
323
-
324
- class FunRetStmt : public SVFStmt{
325
-
326
- FunRetStmt(SVFFunction* f) : SVFStmt(SVFSTMTK::FunRet), fun(f){
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
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
- static inline bool classof(const FunRetStmt *)
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
- return true;
633
+ const MemObj* mem = addDummyMemObj(i, type);
634
+ return addObjNode(nullptr, new DummyObjPN(i,mem), i);
334
635
  }
335
- static inline bool classof(const SVFStmt *stmt)
636
+ inline const MemObj* addDummyMemObj(NodeID i, const Type* type)
336
637
  {
337
- return stmt->getKind() == SVFSTMTK::FunRet;
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
- virtual const std::string toString() const;
342
-
343
- private:
344
- SVFFunction* fun;
345
- };
346
-
347
- class BranchStmt : public SVFStmt{
348
-
349
- BranchStmt(SymID cond, SVFStmt* b1, SVFStmt* b2) : SVFStmt(SVFSTMTK::Branch), condition(cond),br1(b1),br2(b2){
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
677
+ /// Add an edge into SVFIR
353
678
  //@{
354
- static inline bool classof(const BranchStmt *)
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 true;
715
+ return addDummyValNode(NodeIDAllocator::get()->allocateValueId());
357
716
  }
358
- static inline bool classof(const SVFStmt *stmt)
717
+ inline NodeID addDummyObjNode(const Type* type = nullptr)
359
718
  {
360
- return stmt->getKind() == SVFSTMTK::Branch;
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
- virtual const std::string toString() const;
725
+ bool isValidTopLevelPtr(const SVFVar* node);
726
+ //@}
365
727
 
366
- private:
367
- SymID condition;
368
- SVFStmt* br1;
369
- SVFStmt* br2;
728
+ /// Print SVFIR
729
+ void print();
370
730
  };
371
731
 
732
+ typedef SVFIR PAG;
372
733
 
373
- class SVFIR{
374
-
734
+ } // End namespace SVF
375
735
 
376
- };
377
736
 
378
- } // End namespace SVF
379
737
 
380
738
  #endif /* SVFIR_H_ */