svf-lib 1.0.1671 → 1.0.1672
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.
|
Binary file
|
|
Binary file
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
#ifndef SVF_CFBASICBLOCKG_H
|
|
31
31
|
#define SVF_CFBASICBLOCKG_H
|
|
32
32
|
#include "Util/SVFUtil.h"
|
|
33
|
-
#include "Graphs/
|
|
33
|
+
#include "Graphs/ICFG.h"
|
|
34
34
|
#include "Graphs/GenericGraph.h"
|
|
35
35
|
|
|
36
36
|
namespace SVF
|
|
@@ -43,7 +43,33 @@ typedef GenericEdge<CFBasicBlockNode> GenericCFBasicBlockEdgeTy;
|
|
|
43
43
|
class CFBasicBlockEdge : public GenericCFBasicBlockEdgeTy
|
|
44
44
|
{
|
|
45
45
|
public:
|
|
46
|
-
|
|
46
|
+
typedef struct equalCFBBEdge
|
|
47
|
+
{
|
|
48
|
+
bool
|
|
49
|
+
operator()(const CFBasicBlockEdge *lhs, const CFBasicBlockEdge *rhs) const
|
|
50
|
+
{
|
|
51
|
+
if (lhs->getSrcID() != rhs->getSrcID())
|
|
52
|
+
return lhs->getSrcID() < rhs->getSrcID();
|
|
53
|
+
else if (lhs->getDstID() != rhs->getDstID())
|
|
54
|
+
return lhs->getDstID() < rhs->getDstID();
|
|
55
|
+
else
|
|
56
|
+
return lhs->getICFGEdge() < rhs->getICFGEdge();
|
|
57
|
+
}
|
|
58
|
+
} equalICFGEdgeWrapper;
|
|
59
|
+
|
|
60
|
+
typedef OrderedSet<CFBasicBlockEdge *, equalICFGEdgeWrapper> CFBBEdgeSetTy;
|
|
61
|
+
typedef CFBBEdgeSetTy::iterator iterator;
|
|
62
|
+
typedef CFBBEdgeSetTy::const_iterator const_iterator;
|
|
63
|
+
|
|
64
|
+
private:
|
|
65
|
+
const ICFGEdge *_icfgEdge;
|
|
66
|
+
|
|
67
|
+
public:
|
|
68
|
+
CFBasicBlockEdge(CFBasicBlockNode* src, CFBasicBlockNode* dst,
|
|
69
|
+
const ICFGEdge* edge)
|
|
70
|
+
: GenericCFBasicBlockEdgeTy(src, dst, 0), _icfgEdge(edge)
|
|
71
|
+
{
|
|
72
|
+
}
|
|
47
73
|
|
|
48
74
|
friend std::ostream &operator<<(std::ostream &o, const CFBasicBlockEdge &edge)
|
|
49
75
|
{
|
|
@@ -53,20 +79,50 @@ public:
|
|
|
53
79
|
|
|
54
80
|
virtual const std::string toString() const
|
|
55
81
|
{
|
|
56
|
-
return
|
|
82
|
+
return _icfgEdge->toString();
|
|
57
83
|
}
|
|
84
|
+
|
|
85
|
+
inline const ICFGEdge *getICFGEdge() const
|
|
86
|
+
{
|
|
87
|
+
return _icfgEdge;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
using SVF::GenericEdge<NodeType>::operator==;
|
|
91
|
+
/// Add the hash function for std::set (we also can overload operator< to implement this)
|
|
92
|
+
// and duplicated elements in the set are not inserted (binary tree comparison)
|
|
93
|
+
//@{
|
|
94
|
+
|
|
95
|
+
virtual inline bool operator==(const CFBasicBlockEdge *rhs) const
|
|
96
|
+
{
|
|
97
|
+
return (rhs->getSrcID() == this->getSrcID() && rhs->getDstID() == this->getDstID() &&
|
|
98
|
+
rhs->getICFGEdge() == this->getICFGEdge());
|
|
99
|
+
}
|
|
100
|
+
//@}
|
|
101
|
+
|
|
58
102
|
};
|
|
59
103
|
|
|
60
104
|
typedef GenericNode<CFBasicBlockNode, CFBasicBlockEdge> GenericCFBasicBlockNodeTy;
|
|
61
105
|
|
|
62
106
|
class CFBasicBlockNode : public GenericCFBasicBlockNodeTy
|
|
63
107
|
{
|
|
108
|
+
public:
|
|
109
|
+
typedef CFBasicBlockEdge::CFBBEdgeSetTy CFBBEdgeSetTy;
|
|
110
|
+
typedef CFBasicBlockEdge::CFBBEdgeSetTy ::iterator iterator;
|
|
111
|
+
typedef CFBasicBlockEdge::CFBBEdgeSetTy::const_iterator const_iterator;
|
|
112
|
+
|
|
64
113
|
private:
|
|
65
|
-
const SVFBasicBlock *_svfBasicBlock; /// Every CFBasicBlockNode holds a SVFBasicBlock
|
|
66
114
|
std::vector<const ICFGNode *> _icfgNodes; /// Every CBFGNode holds a vector of ICFGNodes
|
|
115
|
+
CFBBEdgeSetTy InEdges; ///< all incoming edge of this node
|
|
116
|
+
CFBBEdgeSetTy OutEdges; ///< all outgoing edge of this node
|
|
67
117
|
|
|
68
118
|
public:
|
|
69
|
-
CFBasicBlockNode(
|
|
119
|
+
CFBasicBlockNode(std::vector<const ICFGNode*> icfgNodes)
|
|
120
|
+
: GenericCFBasicBlockNodeTy((*icfgNodes.begin())->getId(), 0),
|
|
121
|
+
_icfgNodes(SVFUtil::move(icfgNodes))
|
|
122
|
+
{
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
CFBasicBlockNode(const SVFBasicBlock* bb);
|
|
70
126
|
|
|
71
127
|
friend std::ostream &operator<<(std::ostream &o, const CFBasicBlockNode &node)
|
|
72
128
|
{
|
|
@@ -78,17 +134,20 @@ public:
|
|
|
78
134
|
|
|
79
135
|
inline std::string getName() const
|
|
80
136
|
{
|
|
81
|
-
|
|
137
|
+
assert(!_icfgNodes.empty() && "no ICFG nodes in CFBB");
|
|
138
|
+
return (*_icfgNodes.begin())->getBB()->getName();
|
|
82
139
|
}
|
|
83
140
|
|
|
84
141
|
inline const SVFBasicBlock *getSVFBasicBlock() const
|
|
85
142
|
{
|
|
86
|
-
|
|
143
|
+
assert(!_icfgNodes.empty() && "no ICFG nodes in CFBB");
|
|
144
|
+
return (*_icfgNodes.begin())->getBB();
|
|
87
145
|
}
|
|
88
146
|
|
|
89
147
|
inline const SVFFunction *getFunction() const
|
|
90
148
|
{
|
|
91
|
-
|
|
149
|
+
assert(!_icfgNodes.empty() && "no ICFG nodes in CFBB");
|
|
150
|
+
return (*_icfgNodes.begin())->getFun();
|
|
92
151
|
}
|
|
93
152
|
|
|
94
153
|
inline std::vector<const ICFGNode *>::const_iterator begin() const
|
|
@@ -100,6 +159,187 @@ public:
|
|
|
100
159
|
{
|
|
101
160
|
return _icfgNodes.cend();
|
|
102
161
|
}
|
|
162
|
+
|
|
163
|
+
inline void removeNode(const ICFGNode* node)
|
|
164
|
+
{
|
|
165
|
+
const auto it = std::find(_icfgNodes.begin(), _icfgNodes.end(), node);
|
|
166
|
+
assert(it != _icfgNodes.end() && "icfg node not in BB?");
|
|
167
|
+
_icfgNodes.erase(it);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
inline void addNode(const ICFGNode* node)
|
|
171
|
+
{
|
|
172
|
+
_icfgNodes.push_back(node);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
inline u32_t getICFGNodeNum() const
|
|
176
|
+
{
|
|
177
|
+
return _icfgNodes.size();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
public:
|
|
181
|
+
/// Get incoming/outgoing edge set
|
|
182
|
+
///@{
|
|
183
|
+
inline const CFBBEdgeSetTy &getOutEdges() const
|
|
184
|
+
{
|
|
185
|
+
return OutEdges;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
inline const CFBBEdgeSetTy &getInEdges() const
|
|
189
|
+
{
|
|
190
|
+
return InEdges;
|
|
191
|
+
}
|
|
192
|
+
///@}
|
|
193
|
+
|
|
194
|
+
/// Has incoming/outgoing edge set
|
|
195
|
+
//@{
|
|
196
|
+
inline bool hasIncomingEdge() const
|
|
197
|
+
{
|
|
198
|
+
return (InEdges.empty() == false);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
inline bool hasOutgoingEdge() const
|
|
202
|
+
{
|
|
203
|
+
return (OutEdges.empty() == false);
|
|
204
|
+
}
|
|
205
|
+
//@}
|
|
206
|
+
|
|
207
|
+
/// iterators
|
|
208
|
+
//@{
|
|
209
|
+
inline iterator OutEdgeBegin()
|
|
210
|
+
{
|
|
211
|
+
return OutEdges.begin();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
inline iterator OutEdgeEnd()
|
|
215
|
+
{
|
|
216
|
+
return OutEdges.end();
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
inline iterator InEdgeBegin()
|
|
220
|
+
{
|
|
221
|
+
return InEdges.begin();
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
inline iterator InEdgeEnd()
|
|
225
|
+
{
|
|
226
|
+
return InEdges.end();
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
inline const_iterator OutEdgeBegin() const
|
|
230
|
+
{
|
|
231
|
+
return OutEdges.begin();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
inline const_iterator OutEdgeEnd() const
|
|
235
|
+
{
|
|
236
|
+
return OutEdges.end();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
inline const_iterator InEdgeBegin() const
|
|
240
|
+
{
|
|
241
|
+
return InEdges.begin();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
inline const_iterator InEdgeEnd() const
|
|
245
|
+
{
|
|
246
|
+
return InEdges.end();
|
|
247
|
+
}
|
|
248
|
+
//@}
|
|
249
|
+
|
|
250
|
+
/// Iterators used for SCC detection, overwrite it in child class if necessory
|
|
251
|
+
//@{
|
|
252
|
+
virtual inline iterator directOutEdgeBegin()
|
|
253
|
+
{
|
|
254
|
+
return OutEdges.begin();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
virtual inline iterator directOutEdgeEnd()
|
|
258
|
+
{
|
|
259
|
+
return OutEdges.end();
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
virtual inline iterator directInEdgeBegin()
|
|
263
|
+
{
|
|
264
|
+
return InEdges.begin();
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
virtual inline iterator directInEdgeEnd()
|
|
268
|
+
{
|
|
269
|
+
return InEdges.end();
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
virtual inline const_iterator directOutEdgeBegin() const
|
|
273
|
+
{
|
|
274
|
+
return OutEdges.begin();
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
virtual inline const_iterator directOutEdgeEnd() const
|
|
278
|
+
{
|
|
279
|
+
return OutEdges.end();
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
virtual inline const_iterator directInEdgeBegin() const
|
|
283
|
+
{
|
|
284
|
+
return InEdges.begin();
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
virtual inline const_iterator directInEdgeEnd() const
|
|
288
|
+
{
|
|
289
|
+
return InEdges.end();
|
|
290
|
+
}
|
|
291
|
+
//@}
|
|
292
|
+
|
|
293
|
+
/// Add incoming and outgoing edges
|
|
294
|
+
//@{
|
|
295
|
+
inline bool addIncomingEdge(CFBasicBlockEdge *inEdge)
|
|
296
|
+
{
|
|
297
|
+
return InEdges.insert(inEdge).second;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
inline bool addOutgoingEdge(CFBasicBlockEdge *outEdge)
|
|
301
|
+
{
|
|
302
|
+
return OutEdges.insert(outEdge).second;
|
|
303
|
+
}
|
|
304
|
+
//@}
|
|
305
|
+
|
|
306
|
+
/// Remove incoming and outgoing edges
|
|
307
|
+
///@{
|
|
308
|
+
inline u32_t removeIncomingEdge(CFBasicBlockEdge *edge)
|
|
309
|
+
{
|
|
310
|
+
iterator it = InEdges.find(edge);
|
|
311
|
+
assert(it != InEdges.end() && "can not find in edge in SVFG node");
|
|
312
|
+
return InEdges.erase(edge);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
inline u32_t removeOutgoingEdge(CFBasicBlockEdge *edge)
|
|
316
|
+
{
|
|
317
|
+
iterator it = OutEdges.find(edge);
|
|
318
|
+
assert(it != OutEdges.end() && "can not find out edge in SVFG node");
|
|
319
|
+
return OutEdges.erase(edge);
|
|
320
|
+
}
|
|
321
|
+
///@}
|
|
322
|
+
|
|
323
|
+
/// Find incoming and outgoing edges
|
|
324
|
+
//@{
|
|
325
|
+
inline CFBasicBlockEdge *hasIncomingEdge(CFBasicBlockEdge *edge) const
|
|
326
|
+
{
|
|
327
|
+
const_iterator it = InEdges.find(edge);
|
|
328
|
+
if (it != InEdges.end())
|
|
329
|
+
return *it;
|
|
330
|
+
else
|
|
331
|
+
return nullptr;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
inline CFBasicBlockEdge *hasOutgoingEdge(CFBasicBlockEdge *edge) const
|
|
335
|
+
{
|
|
336
|
+
const_iterator it = OutEdges.find(edge);
|
|
337
|
+
if (it != OutEdges.end())
|
|
338
|
+
return *it;
|
|
339
|
+
else
|
|
340
|
+
return nullptr;
|
|
341
|
+
}
|
|
342
|
+
//@}
|
|
103
343
|
};
|
|
104
344
|
|
|
105
345
|
typedef GenericGraph<CFBasicBlockNode, CFBasicBlockEdge> GenericCFBasicBlockGTy;
|
|
@@ -107,22 +347,14 @@ typedef GenericGraph<CFBasicBlockNode, CFBasicBlockEdge> GenericCFBasicBlockGTy;
|
|
|
107
347
|
class CFBasicBlockGraph : public GenericCFBasicBlockGTy
|
|
108
348
|
{
|
|
109
349
|
friend class CFBasicBlockGBuilder;
|
|
110
|
-
|
|
111
|
-
public:
|
|
112
|
-
typedef Map<const SVFBasicBlock *, CFBasicBlockNode *> SVFBasicBlockToCFBasicBlockNodeMap;
|
|
113
|
-
|
|
114
350
|
private:
|
|
115
|
-
SVFBasicBlockToCFBasicBlockNodeMap _bbToNode;
|
|
116
|
-
const SVFFunction *_svfFunction;
|
|
117
351
|
u32_t _totalCFBasicBlockNode{0};
|
|
118
352
|
u32_t _totalCFBasicBlockEdge{0};
|
|
353
|
+
Map<const SVFBasicBlock*, CFBasicBlockNode*> _bbToNode;
|
|
119
354
|
|
|
120
355
|
public:
|
|
121
356
|
|
|
122
|
-
CFBasicBlockGraph(
|
|
123
|
-
{
|
|
124
|
-
|
|
125
|
-
}
|
|
357
|
+
CFBasicBlockGraph() = default;
|
|
126
358
|
|
|
127
359
|
~CFBasicBlockGraph() override = default;
|
|
128
360
|
|
|
@@ -138,16 +370,31 @@ public:
|
|
|
138
370
|
return getGNode(id);
|
|
139
371
|
}
|
|
140
372
|
|
|
141
|
-
inline
|
|
373
|
+
inline bool hasCFBasicBlockNode(NodeID id) const
|
|
142
374
|
{
|
|
143
|
-
|
|
144
|
-
if (it == _bbToNode.end()) return nullptr;
|
|
145
|
-
return it->second;
|
|
375
|
+
return hasGNode(id);
|
|
146
376
|
}
|
|
147
377
|
|
|
148
|
-
inline
|
|
378
|
+
inline CFBasicBlockNode* getCFBasicBlockNode(const SVFBasicBlock* bb) const
|
|
149
379
|
{
|
|
150
|
-
|
|
380
|
+
if (bb && _bbToNode.find(bb) != _bbToNode.end())
|
|
381
|
+
{
|
|
382
|
+
return _bbToNode.at(bb);
|
|
383
|
+
}
|
|
384
|
+
else
|
|
385
|
+
{
|
|
386
|
+
return nullptr;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
inline bool hasCFBasicBlockNode(const SVFBasicBlock* bb) const
|
|
391
|
+
{
|
|
392
|
+
return bb && _bbToNode.find(bb) != _bbToNode.end();
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
bool hasCFBasicBlockEdge(CFBasicBlockNode *src, CFBasicBlockNode *dst, ICFGEdge *icfgEdge)
|
|
396
|
+
{
|
|
397
|
+
CFBasicBlockEdge edge(src, dst, icfgEdge);
|
|
151
398
|
CFBasicBlockEdge *outEdge = src->hasOutgoingEdge(&edge);
|
|
152
399
|
CFBasicBlockEdge *inEdge = dst->hasIncomingEdge(&edge);
|
|
153
400
|
if (outEdge && inEdge)
|
|
@@ -159,17 +406,78 @@ public:
|
|
|
159
406
|
return false;
|
|
160
407
|
}
|
|
161
408
|
|
|
162
|
-
|
|
409
|
+
inline bool hasCFBasicBlockEdge(CFBasicBlockNode *src, CFBasicBlockNode *dst) const
|
|
410
|
+
{
|
|
411
|
+
for (const auto &e: src->getOutEdges())
|
|
412
|
+
{
|
|
413
|
+
if (e->getDstNode() == dst)
|
|
414
|
+
return true;
|
|
415
|
+
}
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
163
418
|
|
|
164
|
-
CFBasicBlockEdge* getCFBasicBlockEdge(const
|
|
419
|
+
CFBasicBlockEdge* getCFBasicBlockEdge(const CFBasicBlockNode *src, const CFBasicBlockNode *dst, const ICFGEdge *icfgEdge);
|
|
165
420
|
|
|
166
|
-
|
|
421
|
+
std::vector<CFBasicBlockEdge*> getCFBasicBlockEdge(const CFBasicBlockNode *src, const CFBasicBlockNode *dst);
|
|
167
422
|
|
|
168
|
-
///
|
|
169
|
-
inline
|
|
423
|
+
/// Remove a ICFGEdgeWrapper
|
|
424
|
+
inline void removeCFBBEdge(CFBasicBlockEdge *edge)
|
|
425
|
+
{
|
|
426
|
+
if (edge->getDstNode()->hasIncomingEdge(edge))
|
|
427
|
+
{
|
|
428
|
+
edge->getDstNode()->removeIncomingEdge(edge);
|
|
429
|
+
}
|
|
430
|
+
if (edge->getSrcNode()->hasOutgoingEdge(edge))
|
|
431
|
+
{
|
|
432
|
+
edge->getSrcNode()->removeOutgoingEdge(edge);
|
|
433
|
+
}
|
|
434
|
+
delete edge;
|
|
435
|
+
_totalCFBasicBlockEdge--;
|
|
436
|
+
}
|
|
170
437
|
|
|
171
|
-
|
|
438
|
+
/// Remove a ICFGNodeWrapper
|
|
439
|
+
inline void removeCFBBNode(CFBasicBlockNode *node)
|
|
440
|
+
{
|
|
441
|
+
std::set<CFBasicBlockEdge *> temp;
|
|
442
|
+
for (CFBasicBlockEdge *e: node->getInEdges())
|
|
443
|
+
temp.insert(e);
|
|
444
|
+
for (CFBasicBlockEdge *e: node->getOutEdges())
|
|
445
|
+
temp.insert(e);
|
|
446
|
+
for (CFBasicBlockEdge *e: temp)
|
|
447
|
+
{
|
|
448
|
+
removeCFBBEdge(e);
|
|
449
|
+
}
|
|
450
|
+
removeGNode(node);
|
|
451
|
+
_totalCFBasicBlockNode--;
|
|
452
|
+
}
|
|
172
453
|
|
|
454
|
+
/// Remove node from nodeID
|
|
455
|
+
inline bool removeCFBBNode(NodeID id)
|
|
456
|
+
{
|
|
457
|
+
if (hasGNode(id))
|
|
458
|
+
{
|
|
459
|
+
removeCFBBNode(getGNode(id));
|
|
460
|
+
return true;
|
|
461
|
+
}
|
|
462
|
+
return false;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/// Add ICFGEdgeWrapper
|
|
466
|
+
inline bool addCFBBEdge(CFBasicBlockEdge *edge)
|
|
467
|
+
{
|
|
468
|
+
bool added1 = edge->getDstNode()->addIncomingEdge(edge);
|
|
469
|
+
bool added2 = edge->getSrcNode()->addOutgoingEdge(edge);
|
|
470
|
+
assert(added1 && added2 && "edge not added??");
|
|
471
|
+
_totalCFBasicBlockEdge++;
|
|
472
|
+
return true;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/// Add a ICFGNodeWrapper
|
|
476
|
+
virtual inline void addCFBBNode(CFBasicBlockNode *node)
|
|
477
|
+
{
|
|
478
|
+
addGNode(node->getId(), node);
|
|
479
|
+
_totalCFBasicBlockNode++;
|
|
480
|
+
}
|
|
173
481
|
};
|
|
174
482
|
|
|
175
483
|
class CFBasicBlockGBuilder
|
|
@@ -179,9 +487,11 @@ private:
|
|
|
179
487
|
CFBasicBlockGraph* _CFBasicBlockG;
|
|
180
488
|
|
|
181
489
|
public:
|
|
182
|
-
CFBasicBlockGBuilder(
|
|
490
|
+
CFBasicBlockGBuilder() : _CFBasicBlockG() {}
|
|
491
|
+
|
|
492
|
+
virtual void build(SVFModule* module);
|
|
183
493
|
|
|
184
|
-
void build();
|
|
494
|
+
virtual void build(ICFG* icfg);
|
|
185
495
|
|
|
186
496
|
inline CFBasicBlockGraph* getCFBasicBlockGraph()
|
|
187
497
|
{
|