svf-lib 1.0.1660 → 1.0.1661

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.
@@ -0,0 +1,466 @@
1
+ //===- CDG.h -- Control Dependence Graph --------------------------------//
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 Affero 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 Affero General Public License for more details.
17
+
18
+ // You should have received a copy of the GNU Affero General Public License
19
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ //
21
+ //===----------------------------------------------------------------------===//
22
+
23
+ /*
24
+ * CDG.h
25
+ *
26
+ * Created on: Sep 27, 2023
27
+ * Author: Xiao Cheng
28
+ */
29
+
30
+ #ifndef SVF_CONTROLDG_H
31
+ #define SVF_CONTROLDG_H
32
+
33
+ #include "SVFIR/SVFIR.h"
34
+
35
+ namespace SVF
36
+ {
37
+
38
+ class CDGNode;
39
+
40
+ typedef GenericEdge<CDGNode> GenericCDGEdgeTy;
41
+
42
+ class CDGEdge : public GenericCDGEdgeTy
43
+ {
44
+ public:
45
+ typedef std::pair<const SVFValue *, s32_t> BranchCondition;
46
+
47
+ /// Constructor
48
+ CDGEdge(CDGNode *s, CDGNode *d) : GenericCDGEdgeTy(s, d, 0)
49
+ {
50
+ }
51
+
52
+ /// Destructor
53
+ ~CDGEdge()
54
+ {
55
+ }
56
+
57
+ typedef GenericNode<CDGNode, CDGEdge>::GEdgeSetTy CDGEdgeSetTy;
58
+ typedef CDGEdgeSetTy SVFGEdgeSetTy;
59
+
60
+ virtual const std::string toString() const
61
+ {
62
+ std::string str;
63
+ std::stringstream rawstr(str);
64
+ rawstr << "CDGEdge " << " [";
65
+ rawstr << getDstID() << "<--" << getSrcID() << "\t";
66
+ return rawstr.str();
67
+ }
68
+
69
+ /// get/set branch condition
70
+ //{@
71
+ const Set<BranchCondition> &getBranchConditions() const
72
+ {
73
+ return brConditions;
74
+ }
75
+
76
+ void insertBranchCondition(const SVFValue *pNode, s32_t branchID)
77
+ {
78
+ brConditions.insert(std::make_pair(pNode, branchID));
79
+ }
80
+ //@}
81
+
82
+
83
+ private:
84
+ Set<BranchCondition> brConditions;
85
+ };
86
+
87
+ typedef GenericNode<CDGNode, CDGEdge> GenericCDGNodeTy;
88
+
89
+ class CDGNode : public GenericCDGNodeTy
90
+ {
91
+
92
+ public:
93
+
94
+ typedef CDGEdge::CDGEdgeSetTy::iterator iterator;
95
+ typedef CDGEdge::CDGEdgeSetTy::const_iterator const_iterator;
96
+
97
+ public:
98
+ /// Constructor
99
+ CDGNode(const ICFGNode *icfgNode) : GenericCDGNodeTy(icfgNode->getId(), 0), _icfgNode(icfgNode)
100
+ {
101
+
102
+ }
103
+
104
+ virtual const std::string toString() const
105
+ {
106
+ std::string str;
107
+ std::stringstream rawstr(str);
108
+ rawstr << getId();
109
+ return rawstr.str();
110
+ }
111
+
112
+ const ICFGNode *getICFGNode() const
113
+ {
114
+ return _icfgNode;
115
+ }
116
+
117
+
118
+ private:
119
+ const ICFGNode *_icfgNode;
120
+ };
121
+
122
+ typedef std::vector<std::pair<NodeID, NodeID>> NodePairVector;
123
+ typedef GenericGraph<CDGNode, CDGEdge> GenericCDGTy;
124
+
125
+ class CDG : public GenericCDGTy
126
+ {
127
+
128
+ public:
129
+
130
+ typedef Map<NodeID, CDGNode *> CDGNodeIDToNodeMapTy;
131
+ typedef CDGEdge::CDGEdgeSetTy CDGEdgeSetTy;
132
+ typedef CDGNodeIDToNodeMapTy::iterator iterator;
133
+ typedef CDGNodeIDToNodeMapTy::const_iterator const_iterator;
134
+ typedef std::vector<const ICFGNode *> ICFGNodeVector;
135
+ typedef std::vector<std::pair<const ICFGNode *, const ICFGNode *>> ICFGNodePairVector;
136
+
137
+ private:
138
+ static CDG *controlDg; ///< Singleton pattern here
139
+ /// Constructor
140
+ CDG()
141
+ {
142
+
143
+ }
144
+
145
+
146
+ public:
147
+ /// Singleton design here to make sure we only have one instance during any analysis
148
+ //@{
149
+ static inline CDG * getCDG()
150
+ {
151
+ if (controlDg == nullptr)
152
+ {
153
+ controlDg = new CDG();
154
+ }
155
+ return controlDg;
156
+ }
157
+
158
+ static void releaseCDG()
159
+ {
160
+ if (controlDg)
161
+ delete controlDg;
162
+ controlDg = nullptr;
163
+ }
164
+ //@}
165
+
166
+ /// Destructor
167
+ virtual ~CDG() {}
168
+
169
+ /// Get a CDG node
170
+ inline CDGNode *getCDGNode(NodeID id) const
171
+ {
172
+ if (!hasCDGNode(id))
173
+ return nullptr;
174
+ return getGNode(id);
175
+ }
176
+
177
+ /// Whether has the CDGNode
178
+ inline bool hasCDGNode(NodeID id) const
179
+ {
180
+ return hasGNode(id);
181
+ }
182
+
183
+ /// Whether we has a CDG edge
184
+ bool hasCDGEdge(CDGNode *src, CDGNode *dst)
185
+ {
186
+ CDGEdge edge(src, dst);
187
+ CDGEdge *outEdge = src->hasOutgoingEdge(&edge);
188
+ CDGEdge *inEdge = dst->hasIncomingEdge(&edge);
189
+ if (outEdge && inEdge)
190
+ {
191
+ assert(outEdge == inEdge && "edges not match");
192
+ return true;
193
+ }
194
+ else
195
+ return false;
196
+ }
197
+
198
+ /// Get a control dependence edge according to src and dst
199
+ CDGEdge *getCDGEdge(const CDGNode *src, const CDGNode *dst)
200
+ {
201
+ CDGEdge *edge = nullptr;
202
+ size_t counter = 0;
203
+ for (CDGEdge::CDGEdgeSetTy::iterator iter = src->OutEdgeBegin();
204
+ iter != src->OutEdgeEnd(); ++iter)
205
+ {
206
+ if ((*iter)->getDstID() == dst->getId())
207
+ {
208
+ counter++;
209
+ edge = (*iter);
210
+ }
211
+ }
212
+ assert(counter <= 1 && "there's more than one edge between two CDG nodes");
213
+ return edge;
214
+ }
215
+
216
+ /// View graph from the debugger
217
+ void view()
218
+ {
219
+ SVF::ViewGraph(this, "Control Dependence Graph");
220
+ }
221
+
222
+ /// Dump graph into dot file
223
+ void dump(const std::string &filename)
224
+ {
225
+ GraphPrinter::WriteGraphToFile(SVFUtil::outs(), filename, this);
226
+ }
227
+
228
+ public:
229
+ /// Remove a control dependence edge
230
+ inline void removeCDGEdge(CDGEdge *edge)
231
+ {
232
+ edge->getDstNode()->removeIncomingEdge(edge);
233
+ edge->getSrcNode()->removeOutgoingEdge(edge);
234
+ delete edge;
235
+ }
236
+
237
+ /// Remove a CDGNode
238
+ inline void removeCDGNode(CDGNode *node)
239
+ {
240
+ std::set<CDGEdge *> temp;
241
+ for (CDGEdge *e: node->getInEdges())
242
+ temp.insert(e);
243
+ for (CDGEdge *e: node->getOutEdges())
244
+ temp.insert(e);
245
+ for (CDGEdge *e: temp)
246
+ {
247
+ removeCDGEdge(e);
248
+ }
249
+ removeGNode(node);
250
+ }
251
+
252
+ /// Remove node from nodeID
253
+ inline bool removeCDGNode(NodeID id)
254
+ {
255
+ if (hasCDGNode(id))
256
+ {
257
+ removeCDGNode(getCDGNode(id));
258
+ return true;
259
+ }
260
+ return false;
261
+ }
262
+
263
+ /// Add CDG edge
264
+ inline bool addCDGEdge(CDGEdge *edge)
265
+ {
266
+ bool added1 = edge->getDstNode()->addIncomingEdge(edge);
267
+ bool added2 = edge->getSrcNode()->addOutgoingEdge(edge);
268
+ assert(added1 && added2 && "edge not added??");
269
+ return true;
270
+ }
271
+
272
+ /// Add a CDG node
273
+ virtual inline void addCDGNode(CDGNode *node)
274
+ {
275
+ addGNode(node->getId(), node);
276
+ }
277
+
278
+ /// Add CDG nodes from nodeid vector
279
+ inline void addCDGNodesFromVector(ICFGNodeVector nodes)
280
+ {
281
+ for (const ICFGNode *icfgNode: nodes)
282
+ {
283
+ if (!IDToNodeMap.count(icfgNode->getId()))
284
+ {
285
+ addGNode(icfgNode->getId(), new CDGNode(icfgNode));
286
+ }
287
+ }
288
+ }
289
+
290
+ /// Add CDG edges from nodeid pair
291
+ void addCDGEdgeFromSrcDst(const ICFGNode *src, const ICFGNode *dst, const SVFValue *pNode, s32_t branchID);
292
+
293
+ };
294
+ } // end namespace SVF
295
+
296
+ namespace SVF
297
+ {
298
+ /* !
299
+ * GenericGraphTraits specializations for generic graph algorithms.
300
+ * Provide graph traits for traversing from a constraint node using standard graph ICFGTraversals.
301
+ */
302
+ template<>
303
+ struct GenericGraphTraits<SVF::CDGNode *>
304
+ : public GenericGraphTraits<SVF::GenericNode<SVF::CDGNode, SVF::CDGEdge> *>
305
+ {
306
+ };
307
+
308
+ /// Inverse GenericGraphTraits specializations for call graph node, it is used for inverse ICFGTraversal.
309
+ template<>
310
+ struct GenericGraphTraits<Inverse<SVF::CDGNode *> > : public GenericGraphTraits<
311
+ Inverse<SVF::GenericNode<SVF::CDGNode, SVF::CDGEdge> *> >
312
+ {
313
+ };
314
+
315
+ template<>
316
+ struct GenericGraphTraits<SVF::CDG *>
317
+ : public GenericGraphTraits<SVF::GenericGraph<SVF::CDGNode, SVF::CDGEdge> *>
318
+ {
319
+ typedef SVF::CDGNode *NodeRef;
320
+ };
321
+
322
+ template<>
323
+ struct DOTGraphTraits<SVF::CDG *> : public DOTGraphTraits<SVF::PAG *>
324
+ {
325
+
326
+ typedef SVF::CDGNode NodeType;
327
+
328
+ DOTGraphTraits(bool isSimple = false) :
329
+ DOTGraphTraits<SVF::PAG *>(isSimple)
330
+ {
331
+ }
332
+
333
+ /// Return name of the graph
334
+ static std::string getGraphName(SVF::CDG *)
335
+ {
336
+ return "Control Dependence Graph";
337
+ }
338
+
339
+ std::string getNodeLabel(NodeType *node, SVF::CDG *graph)
340
+ {
341
+ return getSimpleNodeLabel(node, graph);
342
+ }
343
+
344
+ /// Return the label of an ICFG node
345
+ static std::string getSimpleNodeLabel(NodeType *node, SVF::CDG *)
346
+ {
347
+ std::string str;
348
+ std::stringstream rawstr(str);
349
+ rawstr << "NodeID: " << node->getId() << "\n";
350
+ const SVF::ICFGNode *icfgNode = node->getICFGNode();
351
+ if (const SVF::IntraICFGNode *bNode = SVF::SVFUtil::dyn_cast<SVF::IntraICFGNode>(icfgNode))
352
+ {
353
+ rawstr << "IntraBlockNode ID: " << bNode->getId() << " \t";
354
+ SVF::PAG::SVFStmtList &edges = SVF::PAG::getPAG()->getPTASVFStmtList(bNode);
355
+ if (edges.empty())
356
+ {
357
+ rawstr << bNode->getInst()->toString() << " \t";
358
+ }
359
+ else
360
+ {
361
+ for (SVF::PAG::SVFStmtList::iterator it = edges.begin(), eit = edges.end(); it != eit; ++it)
362
+ {
363
+ const SVF::PAGEdge *edge = *it;
364
+ rawstr << edge->toString();
365
+ }
366
+ }
367
+ rawstr << " {fun: " << bNode->getFun()->getName() << "}";
368
+ }
369
+ else if (const SVF::FunEntryICFGNode *entry = SVF::SVFUtil::dyn_cast<SVF::FunEntryICFGNode>(icfgNode))
370
+ {
371
+ rawstr << entry->toString();
372
+ }
373
+ else if (const SVF::FunExitICFGNode *exit = SVF::SVFUtil::dyn_cast<SVF::FunExitICFGNode>(icfgNode))
374
+ {
375
+ rawstr << exit->toString();
376
+ }
377
+ else if (const SVF::CallICFGNode *call = SVF::SVFUtil::dyn_cast<SVF::CallICFGNode>(icfgNode))
378
+ {
379
+ rawstr << call->toString();
380
+ }
381
+ else if (const SVF::RetICFGNode *ret = SVF::SVFUtil::dyn_cast<SVF::RetICFGNode>(icfgNode))
382
+ {
383
+ rawstr << ret->toString();
384
+ }
385
+ else if (const SVF::GlobalICFGNode *glob = SVF::SVFUtil::dyn_cast<SVF::GlobalICFGNode>(icfgNode))
386
+ {
387
+ SVF::PAG::SVFStmtList &edges = SVF::PAG::getPAG()->getPTASVFStmtList(glob);
388
+ for (SVF::PAG::SVFStmtList::iterator it = edges.begin(), eit = edges.end(); it != eit; ++it)
389
+ {
390
+ const SVF::PAGEdge *edge = *it;
391
+ rawstr << edge->toString();
392
+ }
393
+ }
394
+ else
395
+ assert(false && "what else kinds of nodes do we have??");
396
+
397
+ return rawstr.str();
398
+ }
399
+
400
+ static std::string getNodeAttributes(NodeType *node, SVF::CDG *)
401
+ {
402
+ std::string str;
403
+ std::stringstream rawstr(str);
404
+ const SVF::ICFGNode *icfgNode = node->getICFGNode();
405
+
406
+ if (SVF::SVFUtil::isa<SVF::IntraICFGNode>(icfgNode))
407
+ {
408
+ rawstr << "color=black";
409
+ }
410
+ else if (SVF::SVFUtil::isa<SVF::FunEntryICFGNode>(icfgNode))
411
+ {
412
+ rawstr << "color=yellow";
413
+ }
414
+ else if (SVF::SVFUtil::isa<SVF::FunExitICFGNode>(icfgNode))
415
+ {
416
+ rawstr << "color=green";
417
+ }
418
+ else if (SVF::SVFUtil::isa<SVF::CallICFGNode>(icfgNode))
419
+ {
420
+ rawstr << "color=red";
421
+ }
422
+ else if (SVF::SVFUtil::isa<SVF::RetICFGNode>(icfgNode))
423
+ {
424
+ rawstr << "color=blue";
425
+ }
426
+ else if (SVF::SVFUtil::isa<SVF::GlobalICFGNode>(icfgNode))
427
+ {
428
+ rawstr << "color=purple";
429
+ }
430
+ else
431
+ assert(false && "no such kind of node!!");
432
+
433
+ rawstr << "";
434
+
435
+ return rawstr.str();
436
+ }
437
+
438
+ template<class EdgeIter>
439
+ static std::string getEdgeAttributes(NodeType *, EdgeIter EI, SVF::CDG *)
440
+ {
441
+ SVF::CDGEdge *edge = *(EI.getCurrent());
442
+ assert(edge && "No edge found!!");
443
+ return "style=solid";
444
+ }
445
+
446
+ template<class EdgeIter>
447
+ static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
448
+ {
449
+ SVF::CDGEdge *edge = *(EI.getCurrent());
450
+ assert(edge && "No edge found!!");
451
+
452
+ std::string str;
453
+ std::stringstream rawstr(str);
454
+ for (const auto &cond: edge->getBranchConditions())
455
+ {
456
+ rawstr << std::to_string(cond.second) << "|";
457
+ }
458
+ std::string lb = rawstr.str();
459
+ lb.pop_back();
460
+
461
+ return lb;
462
+ }
463
+ };
464
+
465
+ } // End namespace SVF
466
+ #endif //SVF_CONTROLDG_H
@@ -0,0 +1,727 @@
1
+ //===- ICFGWrapper.h -- ICFG Wrapper-----------------------------------------//
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 Affero 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 Affero General Public License for more details.
17
+
18
+ // You should have received a copy of the GNU Affero General Public License
19
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ //
21
+ //===----------------------------------------------------------------------===//
22
+
23
+ /*
24
+ * ICFGWrapper.h
25
+ *
26
+ * Created on: Sep 26, 2023
27
+ * Author: Xiao Cheng
28
+ */
29
+
30
+ #ifndef SVF_ICFGWRAPPER_H
31
+ #define SVF_ICFGWRAPPER_H
32
+
33
+ #include "Graphs/ICFG.h"
34
+ #include "SVFIR/SVFIR.h"
35
+
36
+ namespace SVF
37
+ {
38
+ class ICFGNodeWrapper;
39
+
40
+ typedef GenericEdge<ICFGNodeWrapper> GenericICFGWrapperEdgeTy;
41
+
42
+
43
+ class ICFGEdgeWrapper : public GenericICFGWrapperEdgeTy
44
+ {
45
+ public:
46
+ typedef struct equalICFGEdgeWrapper
47
+ {
48
+ bool
49
+ operator()(const ICFGEdgeWrapper *lhs, const ICFGEdgeWrapper *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<ICFGEdgeWrapper *, equalICFGEdgeWrapper> ICFGEdgeWrapperSetTy;
61
+ typedef ICFGEdgeWrapperSetTy::iterator iterator;
62
+ typedef ICFGEdgeWrapperSetTy::const_iterator const_iterator;
63
+
64
+ private:
65
+ ICFGEdge *_icfgEdge;
66
+
67
+ public:
68
+ ICFGEdgeWrapper(ICFGNodeWrapper *src, ICFGNodeWrapper *dst, ICFGEdge *edge) :
69
+ GenericICFGWrapperEdgeTy(src, dst, 0), _icfgEdge(edge)
70
+ {
71
+
72
+ }
73
+
74
+ ~ICFGEdgeWrapper() {}
75
+
76
+ virtual const std::string toString() const
77
+ {
78
+ return _icfgEdge->toString();
79
+ }
80
+
81
+ inline ICFGEdge *getICFGEdge() const
82
+ {
83
+ return _icfgEdge;
84
+ }
85
+
86
+ inline void setICFGEdge(ICFGEdge *edge)
87
+ {
88
+ _icfgEdge = edge;
89
+ }
90
+
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 ICFGEdgeWrapper *rhs) const
96
+ {
97
+ return (rhs->getSrcID() == this->getSrcID() && rhs->getDstID() == this->getDstID() &&
98
+ rhs->getICFGEdge() == this->getICFGEdge());
99
+ }
100
+ //@}
101
+
102
+ };
103
+
104
+ typedef GenericNode<ICFGNodeWrapper, ICFGEdgeWrapper> GenericICFGNodeWrapperTy;
105
+
106
+ class ICFGNodeWrapper : public GenericICFGNodeWrapperTy
107
+ {
108
+ public:
109
+ typedef ICFGEdgeWrapper::ICFGEdgeWrapperSetTy ICFGEdgeWrapperSetTy;
110
+ typedef ICFGEdgeWrapper::ICFGEdgeWrapperSetTy::iterator iterator;
111
+ typedef ICFGEdgeWrapper::ICFGEdgeWrapperSetTy::const_iterator const_iterator;
112
+ private:
113
+ const ICFGNode *_icfgNode;
114
+ ICFGNodeWrapper *_callICFGNodeWrapper{nullptr};
115
+ ICFGNodeWrapper *_retICFGNodeWrapper{nullptr};
116
+ ICFGEdgeWrapperSetTy InEdges; ///< all incoming edge of this node
117
+ ICFGEdgeWrapperSetTy OutEdges; ///< all outgoing edge of this node
118
+ public:
119
+ ICFGNodeWrapper(const ICFGNode *node) : GenericICFGNodeWrapperTy(node->getId(), 0), _icfgNode(node) {}
120
+
121
+ virtual ~ICFGNodeWrapper()
122
+ {
123
+ for (auto *edge: OutEdges)
124
+ delete edge;
125
+ }
126
+
127
+ virtual const std::string toString() const
128
+ {
129
+ return _icfgNode->toString();
130
+ }
131
+
132
+ const ICFGNode *getICFGNode() const
133
+ {
134
+ return _icfgNode;
135
+ }
136
+
137
+ ICFGNodeWrapper *getCallICFGNodeWrapper() const
138
+ {
139
+ return _callICFGNodeWrapper;
140
+ }
141
+
142
+ void setCallICFGNodeWrapper(ICFGNodeWrapper *node)
143
+ {
144
+ _callICFGNodeWrapper = node;
145
+ }
146
+
147
+ ICFGNodeWrapper *getRetICFGNodeWrapper() const
148
+ {
149
+ return _retICFGNodeWrapper;
150
+ }
151
+
152
+ void setRetICFGNodeWrapper(ICFGNodeWrapper *node)
153
+ {
154
+ _retICFGNodeWrapper = node;
155
+ }
156
+
157
+
158
+ /// Get incoming/outgoing edge set
159
+ ///@{
160
+ inline const ICFGEdgeWrapperSetTy &getOutEdges() const
161
+ {
162
+ return OutEdges;
163
+ }
164
+
165
+ inline const ICFGEdgeWrapperSetTy &getInEdges() const
166
+ {
167
+ return InEdges;
168
+ }
169
+ ///@}
170
+
171
+ /// Has incoming/outgoing edge set
172
+ //@{
173
+ inline bool hasIncomingEdge() const
174
+ {
175
+ return (InEdges.empty() == false);
176
+ }
177
+
178
+ inline bool hasOutgoingEdge() const
179
+ {
180
+ return (OutEdges.empty() == false);
181
+ }
182
+ //@}
183
+
184
+ /// iterators
185
+ //@{
186
+ inline iterator OutEdgeBegin()
187
+ {
188
+ return OutEdges.begin();
189
+ }
190
+
191
+ inline iterator OutEdgeEnd()
192
+ {
193
+ return OutEdges.end();
194
+ }
195
+
196
+ inline iterator InEdgeBegin()
197
+ {
198
+ return InEdges.begin();
199
+ }
200
+
201
+ inline iterator InEdgeEnd()
202
+ {
203
+ return InEdges.end();
204
+ }
205
+
206
+ inline const_iterator OutEdgeBegin() const
207
+ {
208
+ return OutEdges.begin();
209
+ }
210
+
211
+ inline const_iterator OutEdgeEnd() const
212
+ {
213
+ return OutEdges.end();
214
+ }
215
+
216
+ inline const_iterator InEdgeBegin() const
217
+ {
218
+ return InEdges.begin();
219
+ }
220
+
221
+ inline const_iterator InEdgeEnd() const
222
+ {
223
+ return InEdges.end();
224
+ }
225
+ //@}
226
+
227
+ /// Iterators used for SCC detection, overwrite it in child class if necessory
228
+ //@{
229
+ virtual inline iterator directOutEdgeBegin()
230
+ {
231
+ return OutEdges.begin();
232
+ }
233
+
234
+ virtual inline iterator directOutEdgeEnd()
235
+ {
236
+ return OutEdges.end();
237
+ }
238
+
239
+ virtual inline iterator directInEdgeBegin()
240
+ {
241
+ return InEdges.begin();
242
+ }
243
+
244
+ virtual inline iterator directInEdgeEnd()
245
+ {
246
+ return InEdges.end();
247
+ }
248
+
249
+ virtual inline const_iterator directOutEdgeBegin() const
250
+ {
251
+ return OutEdges.begin();
252
+ }
253
+
254
+ virtual inline const_iterator directOutEdgeEnd() const
255
+ {
256
+ return OutEdges.end();
257
+ }
258
+
259
+ virtual inline const_iterator directInEdgeBegin() const
260
+ {
261
+ return InEdges.begin();
262
+ }
263
+
264
+ virtual inline const_iterator directInEdgeEnd() const
265
+ {
266
+ return InEdges.end();
267
+ }
268
+ //@}
269
+
270
+ /// Add incoming and outgoing edges
271
+ //@{
272
+ inline bool addIncomingEdge(ICFGEdgeWrapper *inEdge)
273
+ {
274
+ return InEdges.insert(inEdge).second;
275
+ }
276
+
277
+ inline bool addOutgoingEdge(ICFGEdgeWrapper *outEdge)
278
+ {
279
+ return OutEdges.insert(outEdge).second;
280
+ }
281
+ //@}
282
+
283
+ /// Remove incoming and outgoing edges
284
+ ///@{
285
+ inline u32_t removeIncomingEdge(ICFGEdgeWrapper *edge)
286
+ {
287
+ iterator it = InEdges.find(edge);
288
+ assert(it != InEdges.end() && "can not find in edge in SVFG node");
289
+ return InEdges.erase(edge);
290
+ }
291
+
292
+ inline u32_t removeOutgoingEdge(ICFGEdgeWrapper *edge)
293
+ {
294
+ iterator it = OutEdges.find(edge);
295
+ assert(it != OutEdges.end() && "can not find out edge in SVFG node");
296
+ return OutEdges.erase(edge);
297
+ }
298
+ ///@}
299
+
300
+ /// Find incoming and outgoing edges
301
+ //@{
302
+ inline ICFGEdgeWrapper *hasIncomingEdge(ICFGEdgeWrapper *edge) const
303
+ {
304
+ const_iterator it = InEdges.find(edge);
305
+ if (it != InEdges.end())
306
+ return *it;
307
+ else
308
+ return nullptr;
309
+ }
310
+
311
+ inline ICFGEdgeWrapper *hasOutgoingEdge(ICFGEdgeWrapper *edge) const
312
+ {
313
+ const_iterator it = OutEdges.find(edge);
314
+ if (it != OutEdges.end())
315
+ return *it;
316
+ else
317
+ return nullptr;
318
+ }
319
+ //@}
320
+ };
321
+
322
+ typedef std::vector<std::pair<NodeID, NodeID>> NodePairVector;
323
+ typedef GenericGraph<ICFGNodeWrapper, ICFGEdgeWrapper> GenericICFGWrapperTy;
324
+
325
+ class ICFGWrapper : public GenericICFGWrapperTy
326
+ {
327
+ public:
328
+
329
+ typedef Map<NodeID, ICFGNodeWrapper *> ICFGWrapperNodeIDToNodeMapTy;
330
+ typedef ICFGEdgeWrapper::ICFGEdgeWrapperSetTy ICFGEdgeWrapperSetTy;
331
+ typedef ICFGWrapperNodeIDToNodeMapTy::iterator iterator;
332
+ typedef ICFGWrapperNodeIDToNodeMapTy::const_iterator const_iterator;
333
+ typedef std::vector<const ICFGNodeWrapper *> ICFGNodeWrapperVector;
334
+ typedef std::vector<std::pair<const ICFGNodeWrapper *, const ICFGNodeWrapper *>> ICFGNodeWrapperPairVector;
335
+ typedef Map<const SVFFunction *, const ICFGNodeWrapper *> SVFFuncToICFGNodeWrapperMap;
336
+ private:
337
+ static std::unique_ptr<ICFGWrapper> _icfgWrapper; ///< Singleton pattern here
338
+ SVFFuncToICFGNodeWrapperMap _funcToFunEntry;
339
+ SVFFuncToICFGNodeWrapperMap _funcToFunExit;
340
+ u32_t _edgeWrapperNum; ///< total num of node
341
+ u32_t _nodeWrapperNum; ///< total num of edge
342
+ ICFG *_icfg;
343
+
344
+ /// Constructor
345
+ ICFGWrapper(ICFG *icfg) : _edgeWrapperNum(0), _nodeWrapperNum(0), _icfg(icfg)
346
+ {
347
+ assert(_icfg && "ICFGWrapper constructor cannot accept nullptr of icfg");
348
+ }
349
+
350
+ public:
351
+ /// Singleton design here to make sure we only have one instance during any analysis
352
+ //@{
353
+ static inline const std::unique_ptr<ICFGWrapper> &getICFGWrapper(ICFG *_icfg)
354
+ {
355
+ if (_icfgWrapper == nullptr)
356
+ {
357
+ _icfgWrapper = std::make_unique<ICFGWrapper>(ICFGWrapper(_icfg));
358
+ }
359
+ return _icfgWrapper;
360
+ }
361
+
362
+ static inline const std::unique_ptr<ICFGWrapper> &getICFGWrapper()
363
+ {
364
+ assert(_icfgWrapper && "icfg wrapper not init?");
365
+ return _icfgWrapper;
366
+ }
367
+
368
+ static void releaseICFGWrapper()
369
+ {
370
+ ICFGWrapper *w = _icfgWrapper.release();
371
+ delete w;
372
+ _icfgWrapper = nullptr;
373
+ }
374
+ //@}
375
+
376
+ /// Destructor
377
+ virtual ~ICFGWrapper() = default;
378
+
379
+ /// Get a ICFG node wrapper
380
+ inline ICFGNodeWrapper *getICFGNodeWrapper(NodeID id) const
381
+ {
382
+ if (!hasICFGNodeWrapper(id))
383
+ return nullptr;
384
+ return getGNode(id);
385
+ }
386
+
387
+ /// Whether has the ICFGNodeWrapper
388
+ inline bool hasICFGNodeWrapper(NodeID id) const
389
+ {
390
+ return hasGNode(id);
391
+ }
392
+
393
+ /// Whether we has a ICFG Edge Wrapper
394
+ bool hasICFGEdgeWrapper(ICFGNodeWrapper *src, ICFGNodeWrapper *dst, ICFGEdge *icfgEdge)
395
+ {
396
+ ICFGEdgeWrapper edge(src, dst, icfgEdge);
397
+ ICFGEdgeWrapper *outEdge = src->hasOutgoingEdge(&edge);
398
+ ICFGEdgeWrapper *inEdge = dst->hasIncomingEdge(&edge);
399
+ if (outEdge && inEdge)
400
+ {
401
+ assert(outEdge == inEdge && "edges not match");
402
+ return true;
403
+ }
404
+ else
405
+ return false;
406
+ }
407
+
408
+ ICFGEdgeWrapper *hasICFGEdgeWrapper(ICFGNodeWrapper *src, ICFGNodeWrapper *dst)
409
+ {
410
+ for (const auto &e: src->getOutEdges())
411
+ {
412
+ if (e->getDstNode() == dst)
413
+ return e;
414
+ }
415
+ return nullptr;
416
+ }
417
+
418
+ /// Get a ICFG edge wrapper according to src, dst and icfgEdge
419
+ ICFGEdgeWrapper *
420
+ getICFGEdgeWrapper(const ICFGNodeWrapper *src, const ICFGNodeWrapper *dst, ICFGEdge *icfgEdge)
421
+ {
422
+ ICFGEdgeWrapper *edge = nullptr;
423
+ size_t counter = 0;
424
+ for (ICFGEdgeWrapper::ICFGEdgeWrapperSetTy::iterator iter = src->OutEdgeBegin();
425
+ iter != src->OutEdgeEnd(); ++iter)
426
+ {
427
+ if ((*iter)->getDstID() == dst->getId())
428
+ {
429
+ counter++;
430
+ edge = (*iter);
431
+ }
432
+ }
433
+ assert(counter <= 1 && "there's more than one edge between two ICFGNodeWrappers");
434
+ return edge;
435
+ }
436
+
437
+ /// View graph from the debugger
438
+ void view();
439
+
440
+ /// Dump graph into dot file
441
+ void dump(const std::string &filename);
442
+
443
+ /// Remove a ICFGEdgeWrapper
444
+ inline void removeICFGEdgeWrapper(ICFGEdgeWrapper *edge)
445
+ {
446
+ if (edge->getDstNode()->hasIncomingEdge(edge))
447
+ {
448
+ edge->getDstNode()->removeIncomingEdge(edge);
449
+ }
450
+ if (edge->getSrcNode()->hasOutgoingEdge(edge))
451
+ {
452
+ edge->getSrcNode()->removeOutgoingEdge(edge);
453
+ }
454
+ delete edge;
455
+ _edgeWrapperNum--;
456
+ }
457
+
458
+ /// Remove a ICFGNodeWrapper
459
+ inline void removeICFGNodeWrapper(ICFGNodeWrapper *node)
460
+ {
461
+ std::set<ICFGEdgeWrapper *> temp;
462
+ for (ICFGEdgeWrapper *e: node->getInEdges())
463
+ temp.insert(e);
464
+ for (ICFGEdgeWrapper *e: node->getOutEdges())
465
+ temp.insert(e);
466
+ for (ICFGEdgeWrapper *e: temp)
467
+ {
468
+ removeICFGEdgeWrapper(e);
469
+ }
470
+ removeGNode(node);
471
+ _nodeWrapperNum--;
472
+ }
473
+
474
+ /// Remove node from nodeID
475
+ inline bool removeICFGNodeWrapper(NodeID id)
476
+ {
477
+ if (hasICFGNodeWrapper(id))
478
+ {
479
+ removeICFGNodeWrapper(getICFGNodeWrapper(id));
480
+ return true;
481
+ }
482
+ return false;
483
+ }
484
+
485
+ /// Add ICFGEdgeWrapper
486
+ inline bool addICFGEdgeWrapper(ICFGEdgeWrapper *edge)
487
+ {
488
+ bool added1 = edge->getDstNode()->addIncomingEdge(edge);
489
+ bool added2 = edge->getSrcNode()->addOutgoingEdge(edge);
490
+ assert(added1 && added2 && "edge not added??");
491
+ _edgeWrapperNum++;
492
+ return true;
493
+ }
494
+
495
+ /// Add a ICFGNodeWrapper
496
+ virtual inline void addICFGNodeWrapper(ICFGNodeWrapper *node)
497
+ {
498
+ addGNode(node->getId(), node);
499
+ _nodeWrapperNum++;
500
+ }
501
+
502
+ const ICFGNodeWrapper *getFunEntry(const SVFFunction *func) const
503
+ {
504
+ auto it = _funcToFunEntry.find(func);
505
+ assert(it != _funcToFunEntry.end() && "no entry?");
506
+ return it->second;
507
+ }
508
+
509
+ const ICFGNodeWrapper *getFunExit(const SVFFunction *func) const
510
+ {
511
+ auto it = _funcToFunExit.find(func);
512
+ assert(it != _funcToFunExit.end() && "no exit?");
513
+ return it->second;
514
+ }
515
+
516
+ /// Add ICFGEdgeWrappers from nodeid pair
517
+ void addICFGNodeWrapperFromICFGNode(const ICFGNode *src);
518
+
519
+ inline u32_t getNodeWrapperNum() const
520
+ {
521
+ return _nodeWrapperNum;
522
+ }
523
+
524
+ inline u32_t getEdgeWrapperNum() const
525
+ {
526
+ return _edgeWrapperNum;
527
+ }
528
+
529
+ };
530
+
531
+ class ICFGWrapperBuilder
532
+ {
533
+ public:
534
+ ICFGWrapperBuilder() {}
535
+
536
+ ~ICFGWrapperBuilder() {}
537
+
538
+ void build(ICFG *icfg);
539
+ };
540
+ }
541
+
542
+ namespace SVF
543
+ {
544
+ /* !
545
+ * GenericGraphTraits specializations for generic graph algorithms.
546
+ * Provide graph traits for traversing from a constraint node using standard graph ICFGTraversals.
547
+ */
548
+ template<>
549
+ struct GenericGraphTraits<SVF::ICFGNodeWrapper *>
550
+ : public GenericGraphTraits<SVF::GenericNode<SVF::ICFGNodeWrapper, SVF::ICFGEdgeWrapper> *>
551
+ {
552
+ };
553
+
554
+ /// Inverse GenericGraphTraits specializations for call graph node, it is used for inverse ICFGTraversal.
555
+ template<>
556
+ struct GenericGraphTraits<Inverse<SVF::ICFGNodeWrapper *> > : public GenericGraphTraits<
557
+ Inverse<SVF::GenericNode<SVF::ICFGNodeWrapper, SVF::ICFGEdgeWrapper> *> >
558
+ {
559
+ };
560
+
561
+ template<>
562
+ struct GenericGraphTraits<SVF::ICFGWrapper *>
563
+ : public GenericGraphTraits<SVF::GenericGraph<SVF::ICFGNodeWrapper, SVF::ICFGEdgeWrapper> *>
564
+ {
565
+ typedef SVF::ICFGNodeWrapper *NodeRef;
566
+ };
567
+
568
+ template<>
569
+ struct DOTGraphTraits<SVF::ICFGWrapper *> : public DOTGraphTraits<SVF::SVFIR *>
570
+ {
571
+
572
+ typedef SVF::ICFGNodeWrapper NodeType;
573
+
574
+ DOTGraphTraits(bool isSimple = false) :
575
+ DOTGraphTraits<SVF::SVFIR *>(isSimple)
576
+ {
577
+ }
578
+
579
+ /// Return name of the graph
580
+ static std::string getGraphName(SVF::ICFGWrapper *)
581
+ {
582
+ return "ICFGWrapper";
583
+ }
584
+
585
+ static bool isNodeHidden(NodeType *node, SVF::ICFGWrapper *graph)
586
+ {
587
+ return false;
588
+ }
589
+
590
+ std::string getNodeLabel(NodeType *node, SVF::ICFGWrapper *graph)
591
+ {
592
+ return getSimpleNodeLabel(node, graph);
593
+ }
594
+
595
+ /// Return the label of an ICFG node
596
+ static std::string getSimpleNodeLabel(NodeType *node, SVF::ICFGWrapper *)
597
+ {
598
+ std::string str;
599
+ std::stringstream rawstr(str);
600
+ rawstr << "NodeID: " << node->getId() << "\n";
601
+ if (const SVF::IntraICFGNode *bNode = SVF::SVFUtil::dyn_cast<SVF::IntraICFGNode>(node->getICFGNode()))
602
+ {
603
+ rawstr << "IntraICFGNode ID: " << bNode->getId() << " \t";
604
+ SVF::SVFIR::SVFStmtList &edges = SVF::SVFIR::getPAG()->getSVFStmtList(bNode);
605
+ if (edges.empty())
606
+ {
607
+ rawstr << bNode->getInst()->toString() << " \t";
608
+ }
609
+ else
610
+ {
611
+ for (SVF::SVFIR::SVFStmtList::iterator it = edges.begin(), eit = edges.end(); it != eit; ++it)
612
+ {
613
+ const SVF::PAGEdge *edge = *it;
614
+ rawstr << edge->toString();
615
+ }
616
+ }
617
+ rawstr << " {fun: " << bNode->getFun()->getName() << "}";
618
+ }
619
+ else if (const SVF::FunEntryICFGNode *entry = SVF::SVFUtil::dyn_cast<SVF::FunEntryICFGNode>(
620
+ node->getICFGNode()))
621
+ {
622
+ rawstr << entry->toString();
623
+ }
624
+ else if (const SVF::FunExitICFGNode *exit = SVF::SVFUtil::dyn_cast<SVF::FunExitICFGNode>(
625
+ node->getICFGNode()))
626
+ {
627
+ rawstr << exit->toString();
628
+ }
629
+ else if (const SVF::CallICFGNode *call = SVF::SVFUtil::dyn_cast<SVF::CallICFGNode>(node->getICFGNode()))
630
+ {
631
+ rawstr << call->toString();
632
+ }
633
+ else if (const SVF::RetICFGNode *ret = SVF::SVFUtil::dyn_cast<SVF::RetICFGNode>(node->getICFGNode()))
634
+ {
635
+ rawstr << ret->toString();
636
+ }
637
+ else if (const SVF::GlobalICFGNode *glob = SVF::SVFUtil::dyn_cast<SVF::GlobalICFGNode>(
638
+ node->getICFGNode()))
639
+ {
640
+ SVF::SVFIR::SVFStmtList &edges = SVF::SVFIR::getPAG()->getSVFStmtList(glob);
641
+ for (SVF::SVFIR::SVFStmtList::iterator it = edges.begin(), eit = edges.end(); it != eit; ++it)
642
+ {
643
+ const SVF::PAGEdge *edge = *it;
644
+ rawstr << edge->toString();
645
+ }
646
+ }
647
+ else
648
+ assert(false && "what else kinds of nodes do we have??");
649
+
650
+ return rawstr.str();
651
+ }
652
+
653
+ static std::string getNodeAttributes(NodeType *node, SVF::ICFGWrapper *)
654
+ {
655
+ std::string str;
656
+ std::stringstream rawstr(str);
657
+
658
+ if (SVF::SVFUtil::isa<SVF::IntraICFGNode>(node->getICFGNode()))
659
+ {
660
+ rawstr << "color=black";
661
+ }
662
+ else if (SVF::SVFUtil::isa<SVF::FunEntryICFGNode>(node->getICFGNode()))
663
+ {
664
+ rawstr << "color=yellow";
665
+ }
666
+ else if (SVF::SVFUtil::isa<SVF::FunExitICFGNode>(node->getICFGNode()))
667
+ {
668
+ rawstr << "color=green";
669
+ }
670
+ else if (SVF::SVFUtil::isa<SVF::CallICFGNode>(node->getICFGNode()))
671
+ {
672
+ rawstr << "color=red";
673
+ }
674
+ else if (SVF::SVFUtil::isa<SVF::RetICFGNode>(node->getICFGNode()))
675
+ {
676
+ rawstr << "color=blue";
677
+ }
678
+ else if (SVF::SVFUtil::isa<SVF::GlobalICFGNode>(node->getICFGNode()))
679
+ {
680
+ rawstr << "color=purple";
681
+ }
682
+ else
683
+ assert(false && "no such kind of node!!");
684
+
685
+ rawstr << "";
686
+
687
+ return rawstr.str();
688
+ }
689
+
690
+ template<class EdgeIter>
691
+ static std::string getEdgeAttributes(NodeType *, EdgeIter EI, SVF::ICFGWrapper *)
692
+ {
693
+ SVF::ICFGEdgeWrapper *edge = *(EI.getCurrent());
694
+ assert(edge && "No edge found!!");
695
+ if (!edge->getICFGEdge())
696
+ return "style=solid";
697
+ if (SVF::SVFUtil::isa<SVF::CallCFGEdge>(edge->getICFGEdge()))
698
+ return "style=solid,color=red";
699
+ else if (SVF::SVFUtil::isa<SVF::RetCFGEdge>(edge->getICFGEdge()))
700
+ return "style=solid,color=blue";
701
+ else
702
+ return "style=solid";
703
+ return "";
704
+ }
705
+
706
+ template<class EdgeIter>
707
+ static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
708
+ {
709
+ SVF::ICFGEdgeWrapper *edge = *(EI.getCurrent());
710
+ assert(edge && "No edge found!!");
711
+
712
+ std::string str;
713
+ std::stringstream rawstr(str);
714
+ if (!edge->getICFGEdge())
715
+ return rawstr.str();
716
+ if (SVF::CallCFGEdge *dirCall = SVF::SVFUtil::dyn_cast<SVF::CallCFGEdge>(edge->getICFGEdge()))
717
+ rawstr << dirCall->getCallSite();
718
+ else if (SVF::RetCFGEdge *dirRet = SVF::SVFUtil::dyn_cast<SVF::RetCFGEdge>(edge->getICFGEdge()))
719
+ rawstr << dirRet->getCallSite();
720
+
721
+ return rawstr.str();
722
+ }
723
+ };
724
+
725
+ } // End namespace SVF
726
+
727
+ #endif //SVF_ICFGWRAPPER_H
@@ -62,6 +62,9 @@ private:
62
62
  Map<const SVFBasicBlock*,BBSet> pdtBBsMap; ///< map a BasicBlock to BasicBlocks it PostDominates
63
63
  Map<const SVFBasicBlock*,BBSet> dfBBsMap; ///< map a BasicBlock to its Dominate Frontier BasicBlocks
64
64
  Map<const SVFBasicBlock*, LoopBBs> bb2LoopMap; ///< map a BasicBlock (if it is in a loop) to all the BasicBlocks in this loop
65
+ Map<const SVFBasicBlock*, u32_t> bb2PdomLevel; ///< map a BasicBlock to its level in pdom tree, used in findNearestCommonPDominator
66
+ Map<const SVFBasicBlock*, const SVFBasicBlock*> bb2PIdom; ///< map a BasicBlock to its immediate dominator in pdom tree, used in findNearestCommonPDominator
67
+
65
68
  public:
66
69
  SVFLoopAndDomInfo()
67
70
  {
@@ -112,6 +115,27 @@ public:
112
115
  return pdtBBsMap;
113
116
  }
114
117
 
118
+ inline const Map<const SVFBasicBlock*,u32_t>& getBBPDomLevel() const
119
+ {
120
+ return bb2PdomLevel;
121
+ }
122
+
123
+ inline Map<const SVFBasicBlock*,u32_t>& getBBPDomLevel()
124
+ {
125
+ return bb2PdomLevel;
126
+ }
127
+
128
+ inline const Map<const SVFBasicBlock*,const SVFBasicBlock*>& getBB2PIdom() const
129
+ {
130
+ return bb2PIdom;
131
+ }
132
+
133
+ inline Map<const SVFBasicBlock*,const SVFBasicBlock*>& getBB2PIdom()
134
+ {
135
+ return bb2PIdom;
136
+ }
137
+
138
+
115
139
  inline Map<const SVFBasicBlock*,BBSet>& getDomTreeMap()
116
140
  {
117
141
  return dtBBsMap;
@@ -145,6 +169,9 @@ public:
145
169
  bool dominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const;
146
170
 
147
171
  bool postDominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const;
172
+
173
+ /// find nearest common post dominator of two basic blocks
174
+ const SVFBasicBlock *findNearestCommonPDominator(const SVFBasicBlock *A, const SVFBasicBlock *B) const;
148
175
  };
149
176
 
150
177
  class SVFValue
@@ -0,0 +1,107 @@
1
+ //===----- CDGBuilder.h -- Control Dependence 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 Affero 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 Affero General Public License for more details.
17
+
18
+ // You should have received a copy of the GNU Affero General Public License
19
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ //
21
+ //===----------------------------------------------------------------------===//
22
+
23
+ /*
24
+ * CDGBuilder.h
25
+ *
26
+ * Created on: Sep 27, 2023
27
+ * Author: Xiao Cheng
28
+ */
29
+ #ifndef SVF_CDGBUILDER_H
30
+ #define SVF_CDGBUILDER_H
31
+
32
+ #include "Graphs/CDG.h"
33
+ #include "SVFIR/SVFValue.h"
34
+
35
+ // control dependence builder
36
+ namespace SVF
37
+ {
38
+ class CDGBuilder
39
+ {
40
+ public:
41
+
42
+ /// constructor
43
+ CDGBuilder() : _controlDG(CDG::getCDG())
44
+ {
45
+
46
+ }
47
+
48
+ /// destructor
49
+ ~CDGBuilder()
50
+ {
51
+
52
+ }
53
+
54
+ /// start here
55
+ void build();
56
+
57
+ /// build control dependence for each function
58
+ void buildControlDependence(const SVFModule *svfgModule);
59
+
60
+ /// build map at icfg node level
61
+ void buildICFGNodeControlMap();
62
+
63
+
64
+
65
+ private:
66
+
67
+
68
+ /// extract basic block edges to be processed
69
+ static void
70
+ extractBBS(const SVFFunction *func,
71
+ Map<const SVFBasicBlock *, std::vector<const SVFBasicBlock *>> &res);
72
+
73
+ /// extract nodes between two nodes in pdom tree
74
+ void
75
+ extractNodesBetweenPdomNodes(const SVFBasicBlock *succ, const SVFBasicBlock *LCA,
76
+ std::vector<const SVFBasicBlock *> &tgtNodes);
77
+
78
+
79
+ void dfsNodesBetweenPdomNodes(const SVFBasicBlock *cur,
80
+ const SVFBasicBlock *tgt,
81
+ std::vector<const SVFBasicBlock *> &path,
82
+ std::vector<const SVFBasicBlock *> &tgtNodes,
83
+ SVFLoopAndDomInfo *ld);
84
+
85
+
86
+ s64_t getBBSuccessorBranchID(const SVFBasicBlock *BB, const SVFBasicBlock *Succ);
87
+
88
+
89
+ /// update map
90
+ inline void updateMap(const SVFBasicBlock *pred, const SVFBasicBlock *bb, s32_t pos)
91
+ {
92
+ _svfcontrolMap[pred][bb].insert(pos);
93
+ _svfdependentOnMap[bb][pred].insert(pos);
94
+ }
95
+
96
+
97
+ private:
98
+ CDG *_controlDG;
99
+ Map<const SVFBasicBlock *, Map<const SVFBasicBlock *, Set<s32_t>>> _svfcontrolMap; ///< map a basicblock to its controlling BBs (position, set of BBs)
100
+ Map<const SVFBasicBlock *, Map<const SVFBasicBlock *, Set<s32_t>>> _svfdependentOnMap; ///< map a basicblock to its dependent on BBs (position, set of BBs)
101
+ Map<const ICFGNode *, Map<const ICFGNode *, Set<s32_t>>> _nodeControlMap; ///< map an ICFG node to its controlling ICFG nodes (position, set of Nodes)
102
+ Map<const ICFGNode *, Map<const ICFGNode *, Set<s32_t>>> _nodeDependentOnMap; ///< map an ICFG node to its dependent on ICFG nodes (position, set of Nodes)
103
+ };
104
+ }
105
+
106
+
107
+ #endif //SVF_CDGBUILDER_H
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-lib",
3
- "version": "1.0.1660",
3
+ "version": "1.0.1661",
4
4
  "description": "SVF's npm support",
5
5
  "main": "index.js",
6
6
  "scripts": {