svf-lib 1.0.729 → 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 (61) hide show
  1. package/SVF-linux/Release-build/lib/libSvf.a +0 -0
  2. package/SVF-linux/include/DDA/DDAVFSolver.h +1 -1
  3. package/SVF-linux/include/Graphs/PAG.h +4 -4
  4. package/SVF-linux/include/Graphs/PAGNode.h +3 -3
  5. package/SVF-linux/include/MemoryModel/SVFIR.h +1 -1
  6. package/SVF-linux/include/MemoryModel/SVFSymbols.h +648 -0
  7. package/SVF-linux/include/MemoryModel/SymbolTableInfo.h +26 -14
  8. package/SVF-linux/include/SVF-FE/SymbolTableBuilder.h +1 -1
  9. package/SVF-osx/Release-build/lib/CUDD/libCudd.a +0 -0
  10. package/SVF-osx/Release-build/lib/libSvf.a +0 -0
  11. package/SVF-osx/include/DDA/ContextDDA.h +1 -1
  12. package/SVF-osx/include/DDA/DDAClient.h +8 -8
  13. package/SVF-osx/include/DDA/DDAVFSolver.h +6 -6
  14. package/SVF-osx/include/DDA/FlowDDA.h +1 -1
  15. package/SVF-osx/include/Graphs/ConsG.h +6 -6
  16. package/SVF-osx/include/Graphs/ConsGEdge.h +2 -2
  17. package/SVF-osx/include/Graphs/ConsGNode.h +1 -1
  18. package/SVF-osx/include/Graphs/ExternalPAG.h +14 -14
  19. package/SVF-osx/include/Graphs/ICFGNode.h +14 -14
  20. package/SVF-osx/include/Graphs/IRGraph.h +245 -0
  21. package/SVF-osx/include/Graphs/OfflineConsG.h +1 -1
  22. package/SVF-osx/include/Graphs/PAG.h +4 -4
  23. package/SVF-osx/include/Graphs/PAGNode.h +4 -4
  24. package/SVF-osx/include/Graphs/SVFG.h +1 -1
  25. package/SVF-osx/include/Graphs/SVFGOPT.h +3 -3
  26. package/SVF-osx/include/Graphs/VFG.h +19 -19
  27. package/SVF-osx/include/Graphs/VFGNode.h +2 -3
  28. package/SVF-osx/include/MSSA/MemRegion.h +11 -11
  29. package/SVF-osx/include/MSSA/MemSSA.h +4 -4
  30. package/SVF-osx/include/MTA/FSMPTA.h +1 -1
  31. package/SVF-osx/include/MemoryModel/LocationSet.h +0 -1
  32. package/SVF-osx/include/MemoryModel/PAGBuilderFromFile.h +8 -8
  33. package/SVF-osx/include/MemoryModel/PTAStat.h +31 -31
  34. package/SVF-osx/include/MemoryModel/PointerAnalysis.h +9 -9
  35. package/SVF-osx/include/MemoryModel/PointerAnalysisImpl.h +3 -3
  36. package/SVF-osx/include/MemoryModel/SVFIR.h +738 -0
  37. package/SVF-osx/include/MemoryModel/SVFStatements.h +738 -0
  38. package/SVF-osx/include/MemoryModel/SVFSymbols.h +648 -0
  39. package/SVF-osx/include/MemoryModel/SVFVariables.h +842 -0
  40. package/SVF-osx/include/MemoryModel/SymbolTableInfo.h +731 -0
  41. package/SVF-osx/include/SABER/SaberSVFGBuilder.h +0 -2
  42. package/SVF-osx/include/SABER/SrcSnkDDA.h +3 -3
  43. package/SVF-osx/include/SVF-FE/Graph2Json.h +1 -3
  44. package/SVF-osx/include/SVF-FE/SVFIRBuilder.h +392 -0
  45. package/SVF-osx/include/SVF-FE/SymbolTableBuilder.h +89 -0
  46. package/SVF-osx/include/Util/BasicTypes.h +0 -10
  47. package/SVF-osx/include/Util/CFLSolver.h +1 -1
  48. package/SVF-osx/include/Util/ExtAPI.h +1 -1
  49. package/SVF-osx/include/Util/IRAnnotator.h +6 -6
  50. package/SVF-osx/include/Util/Options.h +1 -1
  51. package/SVF-osx/include/Util/SVFUtil.h +11 -0
  52. package/SVF-osx/include/Util/TypeBasedHeapCloning.h +11 -11
  53. package/SVF-osx/include/WPA/Andersen.h +11 -100
  54. package/SVF-osx/include/WPA/AndersenSFR.h +4 -4
  55. package/SVF-osx/include/WPA/FlowSensitive.h +2 -2
  56. package/SVF-osx/include/WPA/FlowSensitiveTBHC.h +1 -1
  57. package/SVF-osx/include/WPA/Steensgaard.h +2 -2
  58. package/SVF-osx/include/WPA/TypeAnalysis.h +1 -1
  59. package/SVF-osx/include/WPA/VersionedFlowSensitive.h +2 -2
  60. package/SVF-osx/include/WPA/WPAStat.h +1 -2
  61. package/package.json +1 -1
@@ -0,0 +1,738 @@
1
+ //===- SVFIR.h -- IR of SVF ---------------------------------------------//
2
+ //
3
+ // SVF: Static Value-Flow Analysis
4
+ //
5
+ // Copyright (C) <2013-> <Yulei Sui>
6
+ //
7
+
8
+ // This program is free software: you can redistribute it and/or modify
9
+ // it under the terms of the GNU General Public License as published by
10
+ // the Free Software Foundation, either version 3 of the License, or
11
+ // (at your option) any later version.
12
+
13
+ // This program is distributed in the hope that it will be useful,
14
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ // GNU General Public License for more details.
17
+
18
+ // You should have received a copy of the GNU General Public License
19
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ //
21
+ //===----------------------------------------------------------------------===//
22
+
23
+ /*
24
+ * SVFIR.h
25
+ *
26
+ * Created on: 31, 12, 2021
27
+ * Author: Yulei Sui
28
+ */
29
+
30
+ #ifndef SVFIR_H_
31
+ #define SVFIR_H_
32
+
33
+ #include "Graphs/IRGraph.h"
34
+
35
+ namespace SVF
36
+ {
37
+
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;
50
+
51
+ public:
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;
79
+
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();
111
+
112
+ public:
113
+
114
+ /// Singleton design here to make sure we only have one instance during any analysis
115
+ //@{
116
+ static inline SVFIR* getPAG(bool buildFromFile = false)
117
+ {
118
+ if (pag == nullptr)
119
+ {
120
+ pag = new SVFIR(buildFromFile);
121
+ }
122
+ return pag;
123
+ }
124
+ static void releasePAG()
125
+ {
126
+ if (pag)
127
+ delete pag;
128
+ pag = nullptr;
129
+ }
130
+ //@}
131
+ /// Return memToFieldsMap
132
+ inline MemObjToFieldsMap& getMemToFieldsMap()
133
+ {
134
+ return memToFieldsMap;
135
+ }
136
+ /// Return GepObjNodeMap
137
+ inline NodeLocationSetMap& getGepObjNodeMap()
138
+ {
139
+ return GepObjNodeMap;
140
+ }
141
+ /// Return ICFG
142
+ inline ICFG* getICFG()
143
+ {
144
+ return icfg;
145
+ }
146
+ /// Return valid pointers
147
+ inline OrderedNodeSet& getAllValidPtrs()
148
+ {
149
+ return candidatePointers;
150
+ }
151
+ /// Initialize candidate pointers
152
+ void initialiseCandidatePointers();
153
+
154
+ /// Destructor
155
+ virtual ~SVFIR()
156
+ {
157
+ destroy();
158
+ }
159
+ /// SVFIR build configurations
160
+ //@{
161
+ /// Whether to handle blackhole edge
162
+ static void handleBlackHole(bool b);
163
+ //@}
164
+ /// Get LLVM Module
165
+ inline SVFModule* getModule()
166
+ {
167
+ return SymbolTableInfo::SymbolInfo()->getModule();
168
+ }
169
+ inline void addCallSite(const CallBlockNode* call)
170
+ {
171
+ callSiteSet.insert(call);
172
+ }
173
+ inline const CallSiteSet& getCallSiteSet() const
174
+ {
175
+ return callSiteSet;
176
+ }
177
+ /// Get/set methods to get control flow information of a SVFStmt
178
+ //@{
179
+ /// Whether this instruction has SVFIR Edge
180
+ inline bool hasPAGEdgeList(const ICFGNode* inst) const
181
+ {
182
+ return inst2PAGEdgesMap.find(inst)!=inst2PAGEdgesMap.end();
183
+ }
184
+ inline bool hasPTAPAGEdgeList(const ICFGNode* inst) const
185
+ {
186
+ return inst2PTAPAGEdgesMap.find(inst)!=inst2PTAPAGEdgesMap.end();
187
+ }
188
+ /// Given an instruction, get all its PAGEdges
189
+ inline PAGEdgeList& getInstPAGEdgeList(const ICFGNode* inst)
190
+ {
191
+ return inst2PAGEdgesMap[inst];
192
+ }
193
+ /// Given an instruction, get all its PTA PAGEdges
194
+ inline PAGEdgeList& getInstPTAPAGEdgeList(const ICFGNode* inst)
195
+ {
196
+ return inst2PTAPAGEdgesMap[inst];
197
+ }
198
+ /// Add a SVFStmt into instruction map
199
+ inline void addToInstPAGEdgeList(ICFGNode* inst, SVFStmt* edge)
200
+ {
201
+ edge->setICFGNode(inst);
202
+ inst2PAGEdgesMap[inst].push_back(edge);
203
+ if (edge->isPTAEdge())
204
+ inst2PTAPAGEdgesMap[inst].push_back(edge);
205
+ }
206
+ /// Get global PAGEdges (not in a procedure)
207
+ inline void addGlobalPAGEdge(const SVFStmt* edge)
208
+ {
209
+ globPAGEdgesSet.insert(edge);
210
+ }
211
+ /// Get global PAGEdges (not in a procedure)
212
+ inline PAGEdgeSet& getGlobalPAGEdgeSet()
213
+ {
214
+ return globPAGEdgesSet;
215
+ }
216
+ /// Add phi node information
217
+ inline void addPhiNode(const SVFVar* res, const CopyPE* edge)
218
+ {
219
+ phiNodeMap[res].push_back(edge);
220
+ }
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();
225
+ }
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
265
+ {
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;
278
+ }
279
+ /// Add phi node information
280
+ inline void addCmpNode(const SVFVar* res, const CmpPE* edge)
281
+ {
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;
299
+ }
300
+ //@}
301
+
302
+ private:
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
+ }
338
+
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());
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
+ //@}
407
+
408
+ /// Node and edge statistics
409
+ //@{
410
+ inline Size_t getFieldValNodeNum() const
411
+ {
412
+ return GepValNodeMap.size();
413
+ }
414
+ inline Size_t getFieldObjNodeNum() const
415
+ {
416
+ return GepObjNodeMap.size();
417
+ }
418
+ //@}
419
+
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;
441
+ }
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
464
+ //@{
465
+ inline SVFStmt* getIntraPAGEdge(NodeID src, NodeID dst, SVFStmt::PEDGEK kind)
466
+ {
467
+ return getIntraPAGEdge(getGNode(src), getGNode(dst), kind);
468
+ }
469
+ inline SVFStmt* getIntraPAGEdge(SVFVar* src, SVFVar* dst, SVFStmt::PEDGEK kind)
470
+ {
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);
476
+ }
477
+ //@}
478
+
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;
490
+ }
491
+ inline const MemObj*getObject(const ObjPN* node) const
492
+ {
493
+ return node->getMemObj();
494
+ }
495
+ //@}
496
+
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
502
+ //@{
503
+ inline NodeID getFIObjNode(const MemObj* obj) const
504
+ {
505
+ return obj->getId();
506
+ }
507
+ inline NodeID getFIObjNode(NodeID id) const
508
+ {
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());
513
+ }
514
+ //@}
515
+
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
+ }
560
+ }
561
+ //@}
562
+
563
+ /// Base and Offset methods for Value and Object node
564
+ //@{
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
569
+ {
570
+ return getBaseObj(id)->getId();
571
+ }
572
+ inline const MemObj* getBaseObj(NodeID id) const
573
+ {
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();
578
+ }
579
+ //@}
580
+
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
+ //@}
587
+
588
+ private:
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);
615
+ }
616
+
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)
626
+ //@{
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)
632
+ {
633
+ const MemObj* mem = addDummyMemObj(i, type);
634
+ return addObjNode(nullptr, new DummyObjPN(i,mem), i);
635
+ }
636
+ inline const MemObj* addDummyMemObj(NodeID i, const Type* type)
637
+ {
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());
651
+ }
652
+ //@}
653
+
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);
675
+ }
676
+
677
+ /// Add an edge into SVFIR
678
+ //@{
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()
714
+ {
715
+ return addDummyValNode(NodeIDAllocator::get()->allocateValueId());
716
+ }
717
+ inline NodeID addDummyObjNode(const Type* type = nullptr)
718
+ {
719
+ return addDummyObjNode(NodeIDAllocator::get()->allocateObjectId(), type);
720
+ }
721
+ /// Whether a node is a valid pointer
722
+ //@{
723
+ bool isValidPointer(NodeID nodeId) const;
724
+
725
+ bool isValidTopLevelPtr(const SVFVar* node);
726
+ //@}
727
+
728
+ /// Print SVFIR
729
+ void print();
730
+ };
731
+
732
+ typedef SVFIR PAG;
733
+
734
+ } // End namespace SVF
735
+
736
+
737
+
738
+ #endif /* SVFIR_H_ */