svf-lib 1.0.736 → 1.0.737
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SVF-linux/Release-build/lib/libSvf.a +0 -0
- package/SVF-linux/include/Graphs/CHG.h +351 -0
- package/SVF-linux/include/Graphs/VFG.h +20 -4
- package/SVF-linux/include/Graphs/VFGNode.h +58 -5
- package/SVF-linux/include/MemoryModel/SVFIR.h +80 -79
- package/SVF-linux/include/MemoryModel/SVFStatements.h +102 -4
- package/SVF-linux/include/SVF-FE/CHGBuilder.h +69 -0
- package/SVF-linux/include/SVF-FE/DCHG.h +1 -1
- package/SVF-linux/include/SVF-FE/SVFIRBuilder.h +14 -7
- package/package.json +1 -1
|
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_ */
|
|
@@ -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->
|
|
609
|
-
sNode->setOpVer(0, edge->
|
|
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->
|
|
612
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
+
}
|
|
@@ -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
|
}
|