svf-lib 1.0.737 → 1.0.741

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.
@@ -1,8 +1,8 @@
1
- //===----- CHG.h -- Base class of pointer analyses ---------------------------//
1
+ //===----- CHG.h -- Class hirachary graph ---------------------------//
2
2
  //
3
3
  // SVF: Static Value-Flow Analysis
4
4
  //
5
- // Copyright (C) <2013-2017> <Yulei Sui>
5
+ // Copyright (C) <2013-> <Yulei Sui>
6
6
  //
7
7
 
8
8
  // This program is free software: you can redistribute it and/or modify
@@ -103,8 +103,9 @@ protected:
103
103
  NodeID phiId = getDef(cs_ret);
104
104
  NodeID retdef = getDef(fun_ret);
105
105
  /// If a function does not have any return instruction. The def of a FormalRetVFGNode is itself (see VFG.h: addFormalRetVFGNode).
106
- /// Therefore, we do not connect return edge from a function without any return instruction.
107
- if (retdef == getFormalRetVFGNode(fun_ret)->getId())
106
+ /// Therefore, we do not connect return edge from a function without any return instruction (i.e., pag->isPhiNode(fun_ret)==false)
107
+ /// because unique fun_ret PAGNode was not collected as a PhiNode in SVFIRBuilder::visitReturnInst
108
+ if (pag->isPhiNode(fun_ret)==false)
108
109
  return;
109
110
 
110
111
  SVFGEdge* edge = addRetEdge(retdef, phiId, csId);
Binary file
@@ -0,0 +1,351 @@
1
+ //===----- CHG.h -- Base class of pointer analyses ---------------------------//
2
+ //
3
+ // SVF: Static Value-Flow Analysis
4
+ //
5
+ // Copyright (C) <2013-2017> <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
+ * CHG.h (previously CHA.h)
25
+ *
26
+ * Created on: Apr 13, 2016
27
+ * Author: Xiaokang Fan
28
+ *
29
+ * Created on: Aug 24, 2019
30
+ * Author: Mohamad Barbar
31
+ */
32
+
33
+ #ifndef CHA_H_
34
+ #define CHA_H_
35
+
36
+ #include "Util/SVFModule.h"
37
+ #include "Graphs/GenericGraph.h"
38
+ #include "Util/WorkList.h"
39
+
40
+ namespace SVF
41
+ {
42
+
43
+ class SVFModule;
44
+ class CHNode;
45
+
46
+ typedef Set<const GlobalValue*> VTableSet;
47
+ typedef Set<const SVFFunction*> VFunSet;
48
+
49
+ /// Common base for class hierarchy graph. Only implements what PointerAnalysis needs.
50
+ class CommonCHGraph
51
+ {
52
+ public:
53
+ virtual ~CommonCHGraph() { };
54
+ enum CHGKind
55
+ {
56
+ Standard,
57
+ DI
58
+ };
59
+
60
+ virtual bool csHasVFnsBasedonCHA(CallSite cs) = 0;
61
+ virtual const VFunSet &getCSVFsBasedonCHA(CallSite cs) = 0;
62
+ virtual bool csHasVtblsBasedonCHA(CallSite cs) = 0;
63
+ virtual const VTableSet &getCSVtblsBasedonCHA(CallSite cs) = 0;
64
+ virtual void getVFnsFromVtbls(CallSite cs, const VTableSet &vtbls, VFunSet &virtualFunctions) = 0;
65
+
66
+ CHGKind getKind(void) const
67
+ {
68
+ return kind;
69
+ }
70
+
71
+ protected:
72
+ CHGKind kind;
73
+ };
74
+
75
+
76
+ typedef GenericEdge<CHNode> GenericCHEdgeTy;
77
+ class CHEdge: public GenericCHEdgeTy
78
+ {
79
+ public:
80
+ typedef enum
81
+ {
82
+ INHERITANCE = 0x1, // inheritance relation
83
+ INSTANTCE = 0x2 // template-instance relation
84
+ } CHEDGETYPE;
85
+
86
+ typedef GenericNode<CHNode,CHEdge>::GEdgeSetTy CHEdgeSetTy;
87
+
88
+ CHEdge(CHNode *s, CHNode *d, CHEDGETYPE et, GEdgeFlag k = 0):
89
+ GenericCHEdgeTy(s,d,k)
90
+ {
91
+ edgeType = et;
92
+ }
93
+
94
+ CHEDGETYPE getEdgeType() const
95
+ {
96
+ return edgeType;
97
+ }
98
+
99
+ private:
100
+ CHEDGETYPE edgeType;
101
+ };
102
+
103
+ typedef GenericNode<CHNode,CHEdge> GenericCHNodeTy;
104
+ class CHNode: public GenericCHNodeTy
105
+ {
106
+ public:
107
+ typedef enum
108
+ {
109
+ PURE_ABSTRACT = 0x1, // pure virtual abstract class
110
+ MULTI_INHERITANCE = 0x2, // multi inheritance class
111
+ TEMPLATE = 0x04 // template class
112
+ } CLASSATTR;
113
+
114
+ typedef std::vector<const SVFFunction*> FuncVector;
115
+
116
+ CHNode (const std::string name, NodeID i = 0, GNodeK k = 0):
117
+ GenericCHNodeTy(i, k), vtable(nullptr), className(name), flags(0)
118
+ {
119
+ }
120
+ ~CHNode()
121
+ {
122
+ }
123
+ std::string getName() const
124
+ {
125
+ return className;
126
+ }
127
+ /// Flags
128
+ //@{
129
+ inline void setFlag(CLASSATTR mask)
130
+ {
131
+ flags |= mask;
132
+ }
133
+ inline bool hasFlag(CLASSATTR mask) const
134
+ {
135
+ return (flags & mask) == mask;
136
+ }
137
+ //@}
138
+
139
+ /// Attribute
140
+ //@{
141
+ inline void setPureAbstract()
142
+ {
143
+ setFlag(PURE_ABSTRACT);
144
+ }
145
+ inline void setMultiInheritance()
146
+ {
147
+ setFlag(MULTI_INHERITANCE);
148
+ }
149
+ inline void setTemplate()
150
+ {
151
+ setFlag(TEMPLATE);
152
+ }
153
+ inline bool isPureAbstract() const
154
+ {
155
+ return hasFlag(PURE_ABSTRACT);
156
+ }
157
+ inline bool isMultiInheritance() const
158
+ {
159
+ return hasFlag(MULTI_INHERITANCE);
160
+ }
161
+ inline bool isTemplate() const
162
+ {
163
+ return hasFlag(TEMPLATE);
164
+ }
165
+ //@}
166
+
167
+ void addVirtualFunctionVector(FuncVector vfuncvec)
168
+ {
169
+ virtualFunctionVectors.push_back(vfuncvec);
170
+ }
171
+ const std::vector<FuncVector> &getVirtualFunctionVectors() const
172
+ {
173
+ return virtualFunctionVectors;
174
+ }
175
+ void getVirtualFunctions(u32_t idx, FuncVector &virtualFunctions) const;
176
+
177
+ const GlobalValue *getVTable() const
178
+ {
179
+ return vtable;
180
+ }
181
+
182
+ void setVTable(const GlobalValue *vtbl)
183
+ {
184
+ vtable = vtbl;
185
+ }
186
+
187
+ private:
188
+ const GlobalValue* vtable;
189
+ std::string className;
190
+ size_t flags;
191
+ /*
192
+ * virtual functions inherited from different classes are separately stored
193
+ * to model different vtables inherited from different fathers.
194
+ *
195
+ * Example:
196
+ * class C: public A, public B
197
+ * vtableC = {Af1, Af2, ..., inttoptr, Bg1, Bg2, ...} ("inttoptr"
198
+ * instruction works as the delimiter for separating virtual functions
199
+ * inherited from different classes)
200
+ *
201
+ * virtualFunctionVectors = {{Af1, Af2, ...}, {Bg1, Bg2, ...}}
202
+ */
203
+ std::vector<FuncVector> virtualFunctionVectors;
204
+ };
205
+
206
+ /// class hierarchy graph
207
+ typedef GenericGraph<CHNode,CHEdge> GenericCHGraphTy;
208
+ class CHGraph: public CommonCHGraph, public GenericCHGraphTy
209
+ {
210
+ friend class CHGBuilder;
211
+
212
+ public:
213
+ typedef Set<const CHNode*> CHNodeSetTy;
214
+ typedef FIFOWorkList<const CHNode*> WorkList;
215
+ typedef Map<std::string, CHNodeSetTy> NameToCHNodesMap;
216
+ typedef Map<CallSite, CHNodeSetTy> CallSiteToCHNodesMap;
217
+ typedef Map<CallSite, VTableSet> CallSiteToVTableSetMap;
218
+ typedef Map<CallSite, VFunSet> CallSiteToVFunSetMap;
219
+
220
+ typedef enum
221
+ {
222
+ CONSTRUCTOR = 0x1, // connect node based on constructor
223
+ DESTRUCTOR = 0x2 // connect node based on destructor
224
+ } RELATIONTYPE;
225
+
226
+ CHGraph(SVFModule* svfModule): svfMod(svfModule), classNum(0), vfID(0), buildingCHGTime(0)
227
+ {
228
+ this->kind = Standard;
229
+ }
230
+ ~CHGraph() override = default;
231
+
232
+ void addEdge(const std::string className,
233
+ const std::string baseClassName,
234
+ CHEdge::CHEDGETYPE edgeType);
235
+ CHNode *getNode(const std::string name) const;
236
+ void getVFnsFromVtbls(CallSite cs, const VTableSet &vtbls, VFunSet &virtualFunctions) override;
237
+ void dump(const std::string& filename);
238
+ void view();
239
+ void printCH();
240
+
241
+ inline s32_t getVirtualFunctionID(const SVFFunction* vfn) const
242
+ {
243
+ Map<const SVFFunction*, s32_t>::const_iterator it =
244
+ virtualFunctionToIDMap.find(vfn);
245
+ if (it != virtualFunctionToIDMap.end())
246
+ return it->second;
247
+ else
248
+ return -1;
249
+ }
250
+ inline const SVFFunction* getVirtualFunctionBasedonID(s32_t id) const
251
+ {
252
+ Map<const SVFFunction*, s32_t>::const_iterator it, eit;
253
+ for (it = virtualFunctionToIDMap.begin(), eit =
254
+ virtualFunctionToIDMap.end(); it != eit; ++it)
255
+ {
256
+ if (it->second == id)
257
+ return it->first;
258
+ }
259
+ return nullptr;
260
+ }
261
+
262
+ inline void addInstances(const std::string templateName, CHNode* node)
263
+ {
264
+ NameToCHNodesMap::iterator it = templateNameToInstancesMap.find(
265
+ templateName);
266
+ if (it != templateNameToInstancesMap.end())
267
+ it->second.insert(node);
268
+ else
269
+ templateNameToInstancesMap[templateName].insert(node);
270
+ }
271
+ inline const CHNodeSetTy &getDescendants(const std::string className)
272
+ {
273
+ return classNameToDescendantsMap[className];
274
+ }
275
+ inline const CHNodeSetTy &getInstances(const std::string className)
276
+ {
277
+ return templateNameToInstancesMap[className];
278
+ }
279
+
280
+ inline bool csHasVtblsBasedonCHA(CallSite cs) override
281
+ {
282
+ CallSiteToVTableSetMap::const_iterator it = csToCHAVtblsMap.find(cs);
283
+ return it != csToCHAVtblsMap.end();
284
+ }
285
+ inline bool csHasVFnsBasedonCHA(CallSite cs) override
286
+ {
287
+ CallSiteToVFunSetMap::const_iterator it = csToCHAVFnsMap.find(cs);
288
+ return it != csToCHAVFnsMap.end();
289
+ }
290
+ inline const VTableSet &getCSVtblsBasedonCHA(CallSite cs) override
291
+ {
292
+ CallSiteToVTableSetMap::const_iterator it = csToCHAVtblsMap.find(cs);
293
+ assert(it != csToCHAVtblsMap.end() && "cs does not have vtabls based on CHA.");
294
+ return it->second;
295
+ }
296
+ inline const VFunSet &getCSVFsBasedonCHA(CallSite cs) override
297
+ {
298
+ CallSiteToVFunSetMap::const_iterator it = csToCHAVFnsMap.find(cs);
299
+ assert(it != csToCHAVFnsMap.end() && "cs does not have vfns based on CHA.");
300
+ return it->second;
301
+ }
302
+
303
+ static inline bool classof(const CommonCHGraph *chg)
304
+ {
305
+ return chg->getKind() == Standard;
306
+ }
307
+
308
+
309
+ private:
310
+ SVFModule* svfMod;
311
+ u32_t classNum;
312
+ s32_t vfID;
313
+ double buildingCHGTime;
314
+ Map<std::string, CHNode *> classNameToNodeMap;
315
+ NameToCHNodesMap classNameToDescendantsMap;
316
+ NameToCHNodesMap classNameToAncestorsMap;
317
+ NameToCHNodesMap classNameToInstAndDescsMap;
318
+ NameToCHNodesMap templateNameToInstancesMap;
319
+ CallSiteToCHNodesMap csToClassesMap;
320
+
321
+ Map<const SVFFunction*, s32_t> virtualFunctionToIDMap;
322
+ CallSiteToVTableSetMap csToCHAVtblsMap;
323
+ CallSiteToVFunSetMap csToCHAVFnsMap;
324
+ };
325
+
326
+ } // End namespace SVF
327
+
328
+ namespace llvm
329
+ {
330
+ /* !
331
+ * GraphTraits specializations for generic graph algorithms.
332
+ * Provide graph traits for traversing from a constraint node using standard graph traversals.
333
+ */
334
+ template<> struct GraphTraits<SVF::CHNode*> : public GraphTraits<SVF::GenericNode<SVF::CHNode,SVF::CHEdge>* >
335
+ {
336
+ };
337
+
338
+ /// Inverse GraphTraits specializations for call graph node, it is used for inverse traversal.
339
+ template<>
340
+ struct GraphTraits<Inverse<SVF::CHNode*> > : public GraphTraits<Inverse<SVF::GenericNode<SVF::CHNode,SVF::CHEdge>* > >
341
+ {
342
+ };
343
+
344
+ template<> struct GraphTraits<SVF::CHGraph*> : public GraphTraits<SVF::GenericGraph<SVF::CHNode,SVF::CHEdge>* >
345
+ {
346
+ typedef SVF::CHNode *NodeRef;
347
+ };
348
+
349
+ } // End namespace llvm
350
+
351
+ #endif /* CHA_H_ */
@@ -103,8 +103,9 @@ protected:
103
103
  NodeID phiId = getDef(cs_ret);
104
104
  NodeID retdef = getDef(fun_ret);
105
105
  /// If a function does not have any return instruction. The def of a FormalRetVFGNode is itself (see VFG.h: addFormalRetVFGNode).
106
- /// Therefore, we do not connect return edge from a function without any return instruction.
107
- if (retdef == getFormalRetVFGNode(fun_ret)->getId())
106
+ /// Therefore, we do not connect return edge from a function without any return instruction (i.e., pag->isPhiNode(fun_ret)==false)
107
+ /// because unique fun_ret PAGNode was not collected as a PhiNode in SVFIRBuilder::visitReturnInst
108
+ if (pag->isPhiNode(fun_ret)==false)
108
109
  return;
109
110
 
110
111
  SVFGEdge* edge = addRetEdge(retdef, phiId, csId);
@@ -68,6 +68,7 @@ public:
68
68
  typedef Map<const PAGNode*, IntraPHIVFGNode*> PAGNodeToPHIVFGNodeMapTy;
69
69
  typedef Map<const PAGNode*, BinaryOPVFGNode*> PAGNodeToBinaryOPVFGNodeMapTy;
70
70
  typedef Map<const PAGNode*, UnaryOPVFGNode*> PAGNodeToUnaryOPVFGNodeMapTy;
71
+ typedef Map<const PAGNode*, BranchVFGNode*> PAGNodeToBranchVFGNodeMapTy;
71
72
  typedef Map<const PAGNode*, CmpVFGNode*> PAGNodeToCmpVFGNodeMapTy;
72
73
  typedef Map<const SVFFunction*, VFGNodeSet > FunToVFGNodesMapTy;
73
74
 
@@ -93,6 +94,7 @@ protected:
93
94
  PAGNodeToPHIVFGNodeMapTy PAGNodeToIntraPHIVFGNodeMap; ///< map a PAGNode to its PHIVFGNode
94
95
  PAGNodeToBinaryOPVFGNodeMapTy PAGNodeToBinaryOPVFGNodeMap; ///< map a PAGNode to its BinaryOPVFGNode
95
96
  PAGNodeToUnaryOPVFGNodeMapTy PAGNodeToUnaryOPVFGNodeMap; ///< map a PAGNode to its UnaryOPVFGNode
97
+ PAGNodeToBranchVFGNodeMapTy PAGNodeToBranchVFGNodeMap; ///< map a PAGNode to its BranchVFGNode
96
98
  PAGNodeToCmpVFGNodeMapTy PAGNodeToCmpVFGNodeMap; ///< map a PAGNode to its CmpVFGNode
97
99
  PAGEdgeToStmtVFGNodeMapTy PAGEdgeToStmtVFGNodeMap; ///< map a PAGEdge to its StmtVFGNode
98
100
  FunToVFGNodesMapTy funToVFGNodesMap; ///< map a function to its VFGNodes;
@@ -218,6 +220,12 @@ public:
218
220
  assert(it != PAGNodeToUnaryOPVFGNodeMap.end() && "UnaryOPVFGNode can not be found??");
219
221
  return it->second;
220
222
  }
223
+ inline BranchVFGNode* getBranchVFGNode(const PAGNode* pagNode) const
224
+ {
225
+ PAGNodeToBranchVFGNodeMapTy::const_iterator it = PAGNodeToBranchVFGNodeMap.find(pagNode);
226
+ assert(it != PAGNodeToBranchVFGNodeMap.end() && "BranchVFGNode can not be found??");
227
+ return it->second;
228
+ }
221
229
  inline CmpVFGNode* getCmpVFGNode(const PAGNode* pagNode) const
222
230
  {
223
231
  PAGNodeToCmpVFGNodeMapTy::const_iterator it = PAGNodeToCmpVFGNodeMap.find(pagNode);
@@ -605,11 +613,19 @@ protected:
605
613
  /// Add a UnaryOperator VFG node
606
614
  inline void addUnaryOPVFGNode(const UnaryOPPE* edge)
607
615
  {
608
- UnaryOPVFGNode* sNode = new UnaryOPVFGNode(totalVFGNode++, edge->getDstNode());
609
- sNode->setOpVer(0, edge->getSrcNode());
616
+ UnaryOPVFGNode* sNode = new UnaryOPVFGNode(totalVFGNode++, edge->getRes());
617
+ sNode->setOpVer(0, edge->getOpVar());
618
+ addVFGNode(sNode,edge->getICFGNode());
619
+ setDef(edge->getRes(),sNode);
620
+ PAGNodeToUnaryOPVFGNodeMap[edge->getRes()] = sNode;
621
+ }
622
+ /// Add a BranchVFGNode
623
+ inline void addBranchVFGNode(const BranchStmt* edge)
624
+ {
625
+ BranchVFGNode* sNode = new BranchVFGNode(totalVFGNode++, edge);
610
626
  addVFGNode(sNode,edge->getICFGNode());
611
- setDef(edge->getDstNode(),sNode);
612
- PAGNodeToUnaryOPVFGNodeMap[edge->getDstNode()] = sNode;
627
+ setDef(edge->getBranchInst(),sNode);
628
+ PAGNodeToBranchVFGNodeMap[edge->getBranchInst()] = sNode;
613
629
  }
614
630
  };
615
631
 
@@ -51,7 +51,7 @@ public:
51
51
  /// Gep represents offset edge for field sensitivity
52
52
  enum VFGNodeK
53
53
  {
54
- Addr, Copy, Gep, Store, Load, Cmp, BinaryOp, UnaryOp, TPhi, TIntraPhi, TInterPhi,
54
+ Addr, Copy, Gep, Store, Load, Cmp, BinaryOp, UnaryOp, Branch, TPhi, TIntraPhi, TInterPhi,
55
55
  MPhi, MIntraPhi, MInterPhi, FRet, ARet, AParm, FParm,
56
56
  FunRet, APIN, APOUT, FPIN, FPOUT, NPtr, DummyVProp
57
57
  };
@@ -473,10 +473,7 @@ public:
473
473
  /// Constructor
474
474
  UnaryOPVFGNode(NodeID id, const PAGNode *r) : VFGNode(id, UnaryOp), res(r) {
475
475
  const Value *val = r->getValue();
476
- bool unop = (SVFUtil::isa<UnaryOperator>(val)
477
- || SVFUtil::isa<BranchInst>(val)
478
- || SVFUtil::isa<SwitchInst>(val));
479
- assert(unop && "not a unary operator or a BranchInst or a SwitchInst?");
476
+ assert(SVFUtil::isa<UnaryOperator>(val) && "not a unary instruction ?");
480
477
  }
481
478
  /// Methods for support type inquiry through isa, cast, and dyn_cast:
482
479
  //@{
@@ -509,6 +506,11 @@ public:
509
506
  {
510
507
  return res;
511
508
  }
509
+ inline const PAGNode* getOpVar() const
510
+ {
511
+ assert(getOpVerNum()==1 && "UnaryNode can only have one operand!");
512
+ return getOpVer(0);
513
+ }
512
514
  inline u32_t getOpVerNum() const
513
515
  {
514
516
  return opVers.size();
@@ -526,6 +528,57 @@ public:
526
528
  virtual const std::string toString() const;
527
529
  };
528
530
 
531
+ /*
532
+ * Branch VFGNode including if/else and switch statements
533
+ */
534
+ class BranchVFGNode: public VFGNode
535
+ {
536
+ private:
537
+ BranchVFGNode(); ///< place holder
538
+ BranchVFGNode(const BranchVFGNode &); ///< place holder
539
+ void operator=(const BranchVFGNode &); ///< place holder
540
+ const BranchStmt* brstmt;
541
+ public:
542
+ /// Constructor
543
+ BranchVFGNode(NodeID id, const BranchStmt* r) : VFGNode(id, Branch), brstmt(r) {
544
+ const Value *val = r->getValue();
545
+ assert((SVFUtil::isa<BranchInst>(val) || SVFUtil::isa<SwitchInst>(val)) && "not a BranchInst or a SwitchInst?");
546
+ }
547
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
548
+ //@{
549
+ static inline bool classof(const BranchVFGNode *)
550
+ {
551
+ return true;
552
+ }
553
+ static inline bool classof(const VFGNode *node)
554
+ {
555
+ return node->getNodeKind() == Branch;
556
+ }
557
+ static inline bool classof(const GenericVFGNodeTy *node)
558
+ {
559
+ return node->getNodeKind() == Branch;
560
+ }
561
+ //@}
562
+
563
+ /// Return the branch statement
564
+ const BranchStmt* getBranchStmt() const{
565
+ return brstmt;
566
+ }
567
+ /// Successors of this branch statement
568
+ ///@{
569
+ u32_t getNumSuccessors() const{
570
+ return brstmt->getNumSuccessors();
571
+ }
572
+ const std::vector<const ICFGNode*>& getSuccessors() const{
573
+ return brstmt->getSuccessors();
574
+ }
575
+ const ICFGNode* getSuccessor (u32_t i) const{
576
+ return brstmt->getSuccessor(i);
577
+ }
578
+ ///@}
579
+ virtual const std::string toString() const override;
580
+ };
581
+
529
582
  /*!
530
583
  * VFGNode for Gep
531
584
  */
@@ -197,19 +197,11 @@ public:
197
197
  inst2PTAPAGEdgesMap[inst].push_back(edge);
198
198
  }
199
199
  /// Get global PAGEdges (not in a procedure)
200
- inline void addGlobalPAGEdge(const SVFStmt* edge)
201
- {
202
- globPAGEdgesSet.insert(edge);
203
- }
204
- /// Get global PAGEdges (not in a procedure)
205
200
  inline PAGEdgeSet& getGlobalPAGEdgeSet()
206
201
  {
207
202
  return globPAGEdgesSet;
208
203
  }
209
- inline void addCallSite(const CallBlockNode* call)
210
- {
211
- callSiteSet.insert(call);
212
- }
204
+ /// Get all callsites
213
205
  inline const CallSiteSet& getCallSiteSet() const
214
206
  {
215
207
  return callSiteSet;
@@ -220,54 +212,6 @@ public:
220
212
  return phiNodeMap.find(node) != phiNodeMap.end();
221
213
  }
222
214
 
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
235
- //@{
236
- /// Add function arguments
237
- inline void addFunArgs(const SVFFunction* fun, const SVFVar* arg)
238
- {
239
- FunEntryBlockNode* funEntryBlockNode = icfg->getFunEntryBlockNode(fun);
240
- funEntryBlockNode->addFormalParms(arg);
241
- funArgsListMap[fun].push_back(arg);
242
- }
243
- /// Add function returns
244
- inline void addFunRet(const SVFFunction* fun, const SVFVar* ret)
245
- {
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?");
268
- }
269
-
270
- public:
271
215
  /// Function has arguments list
272
216
  inline bool hasFunArgsList(const SVFFunction* func) const
273
217
  {
@@ -515,8 +459,72 @@ public:
515
459
  NodeBS& getAllFieldsObjNode(NodeID id);
516
460
  NodeBS getFieldsAfterCollapse(NodeID id);
517
461
  //@}
462
+ inline NodeID addDummyValNode()
463
+ {
464
+ return addDummyValNode(NodeIDAllocator::get()->allocateValueId());
465
+ }
466
+ inline NodeID addDummyObjNode(const Type* type = nullptr)
467
+ {
468
+ return addDummyObjNode(NodeIDAllocator::get()->allocateObjectId(), type);
469
+ }
470
+ /// Whether a node is a valid pointer
471
+ //@{
472
+ bool isValidPointer(NodeID nodeId) const;
473
+
474
+ bool isValidTopLevelPtr(const SVFVar* node);
475
+ //@}
476
+
477
+ /// Print SVFIR
478
+ void print();
518
479
 
519
480
  private:
481
+
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?");
526
+ }
527
+
520
528
  /// add node into SVFIR
521
529
  //@{
522
530
  /// Add a value (pointer) node
@@ -605,6 +613,16 @@ private:
605
613
  return addNode(node,i);
606
614
  }
607
615
 
616
+ /// Add global PAGEdges (not in a procedure)
617
+ inline void addGlobalPAGEdge(const SVFStmt* edge)
618
+ {
619
+ globPAGEdgesSet.insert(edge);
620
+ }
621
+ /// Add callsites
622
+ inline void addCallSite(const CallBlockNode* call)
623
+ {
624
+ callSiteSet.insert(call);
625
+ }
608
626
  /// Add an edge into SVFIR
609
627
  //@{
610
628
  /// Add Address edge
@@ -614,11 +632,13 @@ private:
614
632
  /// Add phi node information
615
633
  PhiPE* addPhiNode(NodeID res, NodeID opnd);
616
634
  /// Add Copy edge
617
- CmpPE* addCmpPE(NodeID op1, NodeID op2, NodeID dst);
635
+ CmpPE* addCmpPE(NodeID op1, NodeID op2, NodeID dst, u32_t opcode);
618
636
  /// Add Copy edge
619
- BinaryOPPE* addBinaryOPPE(NodeID op1, NodeID op2, NodeID dst);
637
+ BinaryOPPE* addBinaryOPPE(NodeID op1, NodeID op2, NodeID dst, u32_t opcode);
620
638
  /// Add Unary edge
621
- UnaryOPPE* addUnaryOPPE(NodeID src, NodeID dst);
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);
622
642
  /// Add Load edge
623
643
  LoadPE* addLoadPE(NodeID src, NodeID dst);
624
644
  /// Add Store edge
@@ -641,25 +661,6 @@ private:
641
661
 
642
662
  /// Set a pointer points-to black hole (e.g. int2ptr)
643
663
  SVFStmt* addBlackHoleAddrPE(NodeID node);
644
-
645
- public:
646
- inline NodeID addDummyValNode()
647
- {
648
- return addDummyValNode(NodeIDAllocator::get()->allocateValueId());
649
- }
650
- inline NodeID addDummyObjNode(const Type* type = nullptr)
651
- {
652
- return addDummyObjNode(NodeIDAllocator::get()->allocateObjectId(), type);
653
- }
654
- /// Whether a node is a valid pointer
655
- //@{
656
- bool isValidPointer(NodeID nodeId) const;
657
-
658
- bool isValidTopLevelPtr(const SVFVar* node);
659
- //@}
660
-
661
- /// Print SVFIR
662
- void print();
663
664
  };
664
665
 
665
666
  typedef SVFIR PAG;
@@ -53,7 +53,7 @@ public:
53
53
  /// ThreadFork/ThreadJoin is to model parameter passings between thread spawners and spawnees.
54
54
  enum PEDGEK
55
55
  {
56
- Addr, Copy, Store, Load, Call, Ret, NormalGep, VariantGep, Phi, Cmp, BinaryOp, UnaryOp, ThreadFork, ThreadJoin
56
+ Addr, Copy, Store, Load, Call, Ret, NormalGep, VariantGep, Phi, Cmp, BinaryOp, UnaryOp, Branch, ThreadFork, ThreadJoin
57
57
  };
58
58
 
59
59
  private:
@@ -381,6 +381,8 @@ private:
381
381
  SVFVar* getDstNode(); ///< place holder, use getRes() instead
382
382
  SVFVar* getSrcID(); ///< place holder, use getOpVarID(pos) instead
383
383
  SVFVar* getDstID(); ///< place holder, use getResID() instead
384
+
385
+ u32_t opcode;
384
386
  public:
385
387
  /// Methods for support type inquiry through isa, cast, and dyn_cast:
386
388
  //@{
@@ -403,9 +405,15 @@ public:
403
405
  //@}
404
406
 
405
407
  /// constructor
406
- CmpPE(SVFVar* s, const OPVars& opnds) : MultiOpndStmt(s,opnds,SVFStmt::Cmp)
408
+ CmpPE(SVFVar* s, const OPVars& opnds, u32_t oc) : MultiOpndStmt(s,opnds,SVFStmt::Cmp), opcode(oc)
409
+ {
410
+ }
411
+
412
+ u32_t getOpcode() const
407
413
  {
414
+ return opcode;
408
415
  }
416
+
409
417
  virtual const std::string toString() const override;
410
418
  };
411
419
 
@@ -424,6 +432,8 @@ private:
424
432
  SVFVar* getSrcID(); ///< place holder, use getOpVarID(pos) instead
425
433
  SVFVar* getDstID(); ///< place holder, use getResID() instead
426
434
 
435
+ u32_t opcode;
436
+
427
437
  public:
428
438
  /// Methods for support type inquiry through isa, cast, and dyn_cast:
429
439
  //@{
@@ -446,9 +456,15 @@ public:
446
456
  //@}
447
457
 
448
458
  /// constructor
449
- BinaryOPPE(SVFVar* s, const OPVars& opnds) : MultiOpndStmt(s,opnds,SVFStmt::BinaryOp)
459
+ BinaryOPPE(SVFVar* s, const OPVars& opnds, u32_t oc) : MultiOpndStmt(s,opnds,SVFStmt::BinaryOp), opcode(oc)
450
460
  {
451
461
  }
462
+
463
+ u32_t getOpcode() const
464
+ {
465
+ return opcode;
466
+ }
467
+
452
468
  virtual const std::string toString() const override;
453
469
  };
454
470
 
@@ -461,6 +477,12 @@ private:
461
477
  UnaryOPPE(); ///< place holder
462
478
  UnaryOPPE(const UnaryOPPE &); ///< place holder
463
479
  void operator=(const UnaryOPPE &); ///< place holder
480
+ SVFVar* getSrcNode(); ///< place holder, use getOpVar() instead
481
+ SVFVar* getDstNode(); ///< place holder, use getRes() instead
482
+ SVFVar* getSrcID(); ///< place holder, use getOpVarID() instead
483
+ SVFVar* getDstID(); ///< place holder, use getResID() instead
484
+
485
+ u32_t opcode;
464
486
  public:
465
487
  /// Methods for support type inquiry through isa, cast, and dyn_cast:
466
488
  //@{
@@ -479,14 +501,90 @@ public:
479
501
  //@}
480
502
 
481
503
  /// constructor
482
- UnaryOPPE(SVFVar* s, SVFVar* d) : SVFStmt(s,d,SVFStmt::UnaryOp)
504
+ UnaryOPPE(SVFVar* s, SVFVar* d, u32_t oc) : SVFStmt(s,d,SVFStmt::UnaryOp), opcode(oc)
483
505
  {
484
506
  }
485
507
 
508
+ u32_t getOpcode() const
509
+ {
510
+ return opcode;
511
+ }
512
+ inline const SVFVar* getOpVar() const{
513
+ return SVFStmt::getSrcNode();
514
+ }
515
+ inline const SVFVar* getRes() const{
516
+ return SVFStmt::getDstNode();
517
+ }
518
+ NodeID getOpVarID() const;
519
+ NodeID getResID() const;
520
+
486
521
  virtual const std::string toString() const override;
487
522
  };
488
523
 
489
524
 
525
+ /*!
526
+ * Branch statements including if/else and switch
527
+ */
528
+ class BranchStmt: public SVFStmt
529
+ {
530
+ private:
531
+ BranchStmt(); ///< place holder
532
+ BranchStmt(const BranchStmt &); ///< place holder
533
+ void operator=(const BranchStmt &); ///< place holder
534
+ SVFVar* getSrcNode(); ///< place holder, not allowed
535
+ SVFVar* getDstNode(); ///< place holder, not allowed
536
+ SVFVar* getSrcID(); ///< place holder, not allowed
537
+ SVFVar* getDstID(); ///< place holder, not allowed
538
+
539
+ std::vector<const ICFGNode*> successors;
540
+ const SVFVar* cond;
541
+ const SVFVar* brInst;
542
+ public:
543
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
544
+ //@{
545
+ static inline bool classof(const BranchStmt *)
546
+ {
547
+ return true;
548
+ }
549
+ static inline bool classof(const SVFStmt *edge)
550
+ {
551
+ return edge->getEdgeKind() == SVFStmt::Branch;
552
+ }
553
+ static inline bool classof(const GenericPAGEdgeTy *edge)
554
+ {
555
+ return edge->getEdgeKind() == SVFStmt::Branch;
556
+ }
557
+ //@}
558
+
559
+ /// constructor
560
+ BranchStmt(SVFVar* inst, SVFVar* c, const std::vector<const ICFGNode*>& succs) : SVFStmt(c,inst,SVFStmt::Branch), successors(succs), cond(c), brInst(inst)
561
+ {
562
+ }
563
+
564
+ /// The branch is unconditional if cond is a null value
565
+ bool isUnconditional() const;
566
+ /// The branch is conditional if cond is not a null value
567
+ bool isConditional() const;
568
+ /// Return the condition
569
+ const SVFVar* getCondition() const;
570
+ const SVFVar* getBranchInst() const{
571
+ return brInst;
572
+ }
573
+ /// Successors of this branch statement
574
+ ///@{
575
+ u32_t getNumSuccessors() const{
576
+ return successors.size();
577
+ }
578
+ const std::vector<const ICFGNode*>& getSuccessors() const{
579
+ return successors;
580
+ }
581
+ const ICFGNode* getSuccessor (u32_t i) const{
582
+ return successors.at(i);
583
+ }
584
+ ///@}
585
+ virtual const std::string toString() const override;
586
+ };
587
+
490
588
  /*!
491
589
  * Store edge
492
590
  */
@@ -0,0 +1,69 @@
1
+ //===----- CHGBuiler.h -- Class hierarchy graph builder ---------------------------//
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
+ * CHGBuiler.h
25
+ *
26
+ * Created on: Jun 4, 2021
27
+ * Author: Yulei Sui
28
+ */
29
+
30
+ #include "Graphs/CHG.h"
31
+
32
+ namespace SVF{
33
+
34
+ class CHGBuilder{
35
+
36
+ private:
37
+ CHGraph* chg;
38
+
39
+ public:
40
+ typedef CHGraph::CHNodeSetTy CHNodeSetTy;
41
+ typedef CHGraph::WorkList WorkList;
42
+
43
+ CHGBuilder(CHGraph* c): chg(c)
44
+ {
45
+
46
+ }
47
+ void buildCHG();
48
+ void buildCHGNodes(const GlobalValue *V);
49
+ void buildCHGNodes(const SVFFunction* F);
50
+ void buildCHGEdges(const SVFFunction* F);
51
+ void buildInternalMaps();
52
+ void readInheritanceMetadataFromModule(const Module &M);
53
+
54
+ CHNode *createNode(const std::string name);
55
+
56
+ void connectInheritEdgeViaCall(const SVFFunction* caller, CallSite cs);
57
+ void connectInheritEdgeViaStore(const SVFFunction* caller, const StoreInst* store);
58
+
59
+ void buildClassNameToAncestorsDescendantsMap();
60
+ const CHGraph::CHNodeSetTy& getInstancesAndDescendants(const std::string className);
61
+
62
+ void analyzeVTables(const Module &M);
63
+ void buildVirtualFunctionToIDMap();
64
+ void buildCSToCHAVtblsAndVfnsMap();
65
+ const CHNodeSetTy& getCSClasses(CallSite cs);
66
+ void addFuncToFuncVector(CHNode::FuncVector &v, const SVFFunction *f);
67
+ };
68
+
69
+ }
@@ -15,7 +15,7 @@
15
15
  #define DCHG_H_
16
16
 
17
17
  #include "Graphs/GenericGraph.h"
18
- #include "SVF-FE/CommonCHG.h"
18
+ #include "Graphs/CHG.h"
19
19
  #include "SVF-FE/CPPUtil.h"
20
20
  #include "Util/SVFModule.h"
21
21
  #include "Util/SVFUtil.h"
@@ -267,6 +267,8 @@ public:
267
267
  return nullPtr;
268
268
  }
269
269
 
270
+ public:
271
+
270
272
  NodeID getGepValNode(const Value* val, const LocationSet& ls, const Type *baseType, u32_t fieldidx);
271
273
 
272
274
  void setCurrentBBAndValueForPAGEdge(PAGEdge* edge);
@@ -295,29 +297,34 @@ public:
295
297
  /// Add Copy edge
296
298
  inline PhiPE* addPhiNode(NodeID res, NodeID opnd)
297
299
  {
298
- const CopyPE* copy = addCopyEdge(opnd, res);
299
300
  PhiPE *edge = pag->addPhiNode(res,opnd);
300
301
  setCurrentBBAndValueForPAGEdge(edge);
301
302
  return edge;
302
303
  }
303
304
  /// Add Copy edge
304
- inline CmpPE* addCmpEdge(NodeID op1, NodeID op2, NodeID dst)
305
+ inline CmpPE* addCmpEdge(NodeID op1, NodeID op2, NodeID dst, u32_t opcode)
305
306
  {
306
- CmpPE *edge = pag->addCmpPE(op1, op2, dst);
307
+ CmpPE *edge = pag->addCmpPE(op1, op2, dst, opcode);
307
308
  setCurrentBBAndValueForPAGEdge(edge);
308
309
  return edge;
309
310
  }
310
311
  /// Add Copy edge
311
- inline BinaryOPPE* addBinaryOPEdge(NodeID op1, NodeID op2, NodeID dst)
312
+ inline BinaryOPPE* addBinaryOPEdge(NodeID op1, NodeID op2, NodeID dst, u32_t opcode)
312
313
  {
313
- BinaryOPPE *edge = pag->addBinaryOPPE(op1, op2, dst);
314
+ BinaryOPPE *edge = pag->addBinaryOPPE(op1, op2, dst, opcode);
314
315
  setCurrentBBAndValueForPAGEdge(edge);
315
316
  return edge;
316
317
  }
317
318
  /// Add Unary edge
318
- inline UnaryOPPE* addUnaryOPEdge(NodeID src, NodeID dst)
319
+ inline UnaryOPPE* addUnaryOPEdge(NodeID src, NodeID dst, u32_t opcode)
319
320
  {
320
- UnaryOPPE *edge = pag->addUnaryOPPE(src, dst);
321
+ UnaryOPPE *edge = pag->addUnaryOPPE(src, dst, opcode);
322
+ setCurrentBBAndValueForPAGEdge(edge);
323
+ return edge;
324
+ }
325
+ /// Add Branch statement
326
+ inline BranchStmt* addBranchStmt(NodeID br, NodeID cond, const std::vector<const ICFGNode*> succs){
327
+ BranchStmt *edge = pag->addBranchStmt(br, cond, succs);
321
328
  setCurrentBBAndValueForPAGEdge(edge);
322
329
  return edge;
323
330
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-lib",
3
- "version": "1.0.737",
3
+ "version": "1.0.741",
4
4
  "description": "SVF's npm support",
5
5
  "main": "index.js",
6
6
  "scripts": {