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.
Files changed (59) hide show
  1. package/SVF-linux/Release-build/lib/libSvf.a +0 -0
  2. package/SVF-linux/include/DDA/ContextDDA.h +1 -1
  3. package/SVF-linux/include/DDA/DDAClient.h +8 -8
  4. package/SVF-linux/include/DDA/DDAVFSolver.h +5 -5
  5. package/SVF-linux/include/DDA/FlowDDA.h +1 -1
  6. package/SVF-linux/include/Graphs/CHG.h +351 -0
  7. package/SVF-linux/include/Graphs/ConsG.h +6 -6
  8. package/SVF-linux/include/Graphs/ConsGEdge.h +2 -2
  9. package/SVF-linux/include/Graphs/ConsGNode.h +1 -1
  10. package/SVF-linux/include/Graphs/ExternalPAG.h +14 -14
  11. package/SVF-linux/include/Graphs/GenericGraph.h +1 -1
  12. package/SVF-linux/include/Graphs/ICFGNode.h +14 -14
  13. package/SVF-linux/include/Graphs/IRGraph.h +236 -0
  14. package/SVF-linux/include/Graphs/OfflineConsG.h +1 -1
  15. package/SVF-linux/include/Graphs/SVFG.h +1 -1
  16. package/SVF-linux/include/Graphs/SVFGOPT.h +3 -3
  17. package/SVF-linux/include/Graphs/VFG.h +53 -52
  18. package/SVF-linux/include/Graphs/VFGNode.h +60 -8
  19. package/SVF-linux/include/MSSA/MemRegion.h +11 -11
  20. package/SVF-linux/include/MSSA/MemSSA.h +4 -4
  21. package/SVF-linux/include/MTA/FSMPTA.h +1 -1
  22. package/SVF-linux/include/MemoryModel/PAGBuilderFromFile.h +8 -8
  23. package/SVF-linux/include/MemoryModel/PTAStat.h +31 -31
  24. package/SVF-linux/include/MemoryModel/PointerAnalysis.h +9 -9
  25. package/SVF-linux/include/MemoryModel/PointerAnalysisImpl.h +3 -3
  26. package/SVF-linux/include/MemoryModel/SVFIR.h +525 -233
  27. package/SVF-linux/include/MemoryModel/SVFStatements.h +970 -0
  28. package/SVF-linux/include/MemoryModel/SVFVariables.h +842 -0
  29. package/SVF-linux/include/MemoryModel/SymbolTableInfo.h +346 -55
  30. package/SVF-linux/include/SABER/SaberSVFGBuilder.h +0 -2
  31. package/SVF-linux/include/SABER/SrcSnkDDA.h +3 -3
  32. package/SVF-linux/include/SVF-FE/CHGBuilder.h +69 -0
  33. package/SVF-linux/include/SVF-FE/DCHG.h +1 -1
  34. package/SVF-linux/include/SVF-FE/Graph2Json.h +1 -3
  35. package/SVF-linux/include/SVF-FE/SVFIRBuilder.h +405 -0
  36. package/SVF-linux/include/SVF-FE/SymbolTableBuilder.h +0 -1
  37. package/SVF-linux/include/Util/CFLSolver.h +1 -1
  38. package/SVF-linux/include/Util/ExtAPI.h +1 -1
  39. package/SVF-linux/include/Util/IRAnnotator.h +6 -6
  40. package/SVF-linux/include/Util/Options.h +1 -1
  41. package/SVF-linux/include/Util/TypeBasedHeapCloning.h +11 -11
  42. package/SVF-linux/include/WPA/Andersen.h +11 -11
  43. package/SVF-linux/include/WPA/AndersenSFR.h +4 -4
  44. package/SVF-linux/include/WPA/FlowSensitive.h +2 -2
  45. package/SVF-linux/include/WPA/FlowSensitiveTBHC.h +1 -1
  46. package/SVF-linux/include/WPA/Steensgaard.h +2 -2
  47. package/SVF-linux/include/WPA/TypeAnalysis.h +1 -1
  48. package/SVF-linux/include/WPA/VersionedFlowSensitive.h +2 -2
  49. package/SVF-linux/include/WPA/WPAStat.h +1 -2
  50. package/SVF-osx/Release-build/lib/CUDD/libCudd.a +0 -0
  51. package/SVF-osx/Release-build/lib/libSvf.a +0 -0
  52. package/SVF-osx/include/Graphs/GenericGraph.h +1 -1
  53. package/SVF-osx/include/Graphs/IRGraph.h +6 -15
  54. package/SVF-osx/include/Graphs/VFG.h +26 -41
  55. package/SVF-osx/include/Graphs/VFGNode.h +2 -2
  56. package/SVF-osx/include/MemoryModel/SVFIR.h +29 -96
  57. package/SVF-osx/include/MemoryModel/SVFStatements.h +156 -22
  58. package/SVF-osx/include/SVF-FE/SVFIRBuilder.h +12 -6
  59. package/package.json +1 -1
@@ -30,351 +30,643 @@
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 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
- SVFStmt(u32_t k): kind(k){
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
- /// ClassOf
105
+ /// Singleton design here to make sure we only have one instance during any analysis
53
106
  //@{
54
- static inline bool classof(const SVFStmt*)
107
+ static inline SVFIR* getPAG(bool buildFromFile = false)
55
108
  {
56
- return true;
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
- o << stmt.toString();
67
- return o;
117
+ if (pag)
118
+ delete pag;
119
+ pag = nullptr;
68
120
  }
69
121
  //@}
70
-
71
- inline u32_t getKind() const {
72
- return kind;
122
+ /// Return memToFieldsMap
123
+ inline MemObjToFieldsMap& getMemToFieldsMap()
124
+ {
125
+ return memToFieldsMap;
73
126
  }
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){
127
+ /// Return GepObjNodeMap
128
+ inline NodeLocationSetMap& getGepObjNodeMap()
129
+ {
130
+ return GepObjNodeMap;
84
131
  }
85
-
86
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
87
- //@{
88
- static inline bool classof(const AllocStmt *)
132
+ /// Return ICFG
133
+ inline ICFG* getICFG()
89
134
  {
90
- return true;
135
+ return icfg;
91
136
  }
92
- static inline bool classof(const SVFStmt *stmt)
137
+ /// Return valid pointers
138
+ inline OrderedNodeSet& getAllValidPtrs()
93
139
  {
94
- return stmt->getKind() == SVFSTMTK::Alloc;
140
+ return candidatePointers;
95
141
  }
96
- //@}
142
+ /// Initialize candidate pointers
143
+ void initialiseCandidatePointers();
97
144
 
98
- virtual const std::string toString() const;
99
-
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){
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
- static inline bool classof(const CopyStmt *)
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 true;
158
+ return SymbolTableInfo::SymbolInfo()->getModule();
115
159
  }
116
- static inline bool classof(const SVFStmt *stmt)
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 stmt->getKind() == SVFSTMTK::Copy;
165
+ return PAGEdgeKindToSetMap[kind];
119
166
  }
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){
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
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 true;
175
+ return inst2PAGEdgesMap.find(inst)!=inst2PAGEdgesMap.end();
139
176
  }
140
- static inline bool classof(const SVFStmt *stmt)
177
+ inline bool hasPTAPAGEdgeList(const ICFGNode* inst) const
141
178
  {
142
- return stmt->getKind() == SVFSTMTK::Phi;
179
+ return inst2PTAPAGEdgesMap.find(inst)!=inst2PTAPAGEdgesMap.end();
143
180
  }
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){
181
+ /// Given an instruction, get all its PAGEdges
182
+ inline PAGEdgeList& getInstPAGEdgeList(const ICFGNode* inst)
183
+ {
184
+ return inst2PAGEdgesMap[inst];
157
185
  }
158
-
159
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
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 true;
189
+ return inst2PTAPAGEdgesMap[inst];
164
190
  }
165
- static inline bool classof(const SVFStmt *stmt)
191
+ /// Add a SVFStmt into instruction map
192
+ inline void addToInstPAGEdgeList(ICFGNode* inst, SVFStmt* edge)
166
193
  {
167
- return stmt->getKind() == SVFSTMTK::Load;
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
- 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){
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
184
- //@{
185
- static inline bool classof(const StoreStmt *)
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
- return true;
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
- static inline bool classof(const SVFStmt *stmt)
249
+ /// Get callsite return
250
+ inline CSToRetMap& getCallSiteRets()
190
251
  {
191
- return stmt->getKind() == SVFSTMTK::Store;
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
- 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){
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
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
- static inline bool classof(const GepStmt *)
313
+ inline const CallSiteToFunPtrMap& getIndirectCallsites() const
210
314
  {
211
- return true;
315
+ return indCallSiteToFunPtrMap;
212
316
  }
213
- static inline bool classof(const SVFStmt *stmt)
317
+ inline NodeID getFunPtr(const CallBlockNode* cs) const
214
318
  {
215
- return stmt->getKind() == SVFSTMTK::Gep;
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
- virtual const std::string toString() const;
220
-
221
- private:
222
- SymID resVar;
223
- SymID ptrVar;
224
- SymID offsetVar;
225
- };
226
-
227
- class CmpStmt : public SVFStmt{
228
-
229
- CmpStmt(SymID res, SymID op1, SymID op2) : SVFStmt(SVFSTMTK::Cmp), resVar(res), op1Var(op1), op2Var(op2){
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
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
- static inline bool classof(const CmpStmt *)
358
+ inline const MemObj*getObject(NodeID id) const
235
359
  {
236
- return true;
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
- static inline bool classof(const SVFStmt *stmt)
366
+ inline const MemObj*getObject(const ObjPN* node) const
239
367
  {
240
- return stmt->getKind() == SVFSTMTK::Cmp;
368
+ return node->getMemObj();
241
369
  }
242
370
  //@}
243
371
 
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){
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
391
+ /// Get black hole and constant id
258
392
  //@{
259
- static inline bool classof(const BinaryStmt *)
393
+ inline bool isBlkPtr(NodeID id) const
260
394
  {
261
- return true;
395
+ return (SymbolTableInfo::isBlkPtr(id));
262
396
  }
263
- static inline bool classof(const SVFStmt *stmt)
397
+ inline bool isNullPtr(NodeID id) const
264
398
  {
265
- return stmt->getKind() == SVFSTMTK::Binary;
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
- 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){
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
456
+ /// Get all fields of an object
283
457
  //@{
284
- static inline bool classof(const UnaryStmt *)
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 true;
464
+ return addDummyValNode(NodeIDAllocator::get()->allocateValueId());
287
465
  }
288
- static inline bool classof(const SVFStmt *stmt)
466
+ inline NodeID addDummyObjNode(const Type* type = nullptr)
289
467
  {
290
- return stmt->getKind() == SVFSTMTK::Unary;
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
- virtual const std::string toString() const;
477
+ /// Print SVFIR
478
+ void print();
295
479
 
296
480
  private:
297
- SymID resVar;
298
- SymID opVar;
299
- };
300
481
 
301
- class CallStmt : public SVFStmt{
302
-
303
- CallStmt(CallSite cs) : SVFStmt(SVFSTMTK::Call), callsite(cs){
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
528
+ /// add node into SVFIR
307
529
  //@{
308
- static inline bool classof(const CallStmt *)
530
+ /// Add a value (pointer) node
531
+ inline NodeID addValNode(const Value* val, NodeID i)
309
532
  {
310
- return true;
533
+ SVFVar *node = new ValPN(val,i);
534
+ return addValNode(val, node, i);
311
535
  }
312
- static inline bool classof(const SVFStmt *stmt)
536
+ /// Add a memory obj node
537
+ inline NodeID addObjNode(const Value* val, NodeID i)
313
538
  {
314
- return stmt->getKind() == SVFSTMTK::Call;
539
+ const MemObj* mem = getMemObj(val);
540
+ assert(((mem->getId() == i)) && "not same object id?");
541
+ return addFIObjNode(mem);
315
542
  }
316
- //@}
317
-
318
- virtual const std::string toString() const;
319
-
320
- private:
321
- CallSite callsite;
322
- };
323
-
324
- class FunRetStmt : public SVFStmt{
325
-
326
- FunRetStmt(SVFFunction* f) : SVFStmt(SVFSTMTK::FunRet), fun(f){
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
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
- static inline bool classof(const FunRetStmt *)
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 true;
577
+ return SymbolTableInfo::SymbolInfo()->createDummyObj(i,type);
334
578
  }
335
- static inline bool classof(const SVFStmt *stmt)
579
+ inline NodeID addBlackholeObjNode()
336
580
  {
337
- return stmt->getKind() == SVFSTMTK::FunRet;
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
- 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){
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
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
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
- return true;
619
+ globPAGEdgesSet.insert(edge);
357
620
  }
358
- static inline bool classof(const SVFStmt *stmt)
621
+ /// Add callsites
622
+ inline void addCallSite(const CallBlockNode* call)
359
623
  {
360
- return stmt->getKind() == SVFSTMTK::Branch;
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
- virtual const std::string toString() const;
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
- class SVFIR{
374
-
668
+ } // End namespace SVF
375
669
 
376
- };
377
670
 
378
- } // End namespace SVF
379
671
 
380
672
  #endif /* SVFIR_H_ */