svf-lib 1.0.1659 → 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