svf-lib 1.0.732 → 1.0.736

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