Static Value-Flow Analysis
Loading...
Searching...
No Matches
CDG.h
Go to the documentation of this file.
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 "Graphs/GenericGraph.h"
34#include "Graphs/GraphPrinter.h"
35#include "Graphs/ICFGNode.h"
36#include "SVFIR/SVFIR.h"
37#include "Util/GeneralType.h"
38#include "Util/SVFUtil.h"
39
40namespace SVF
41{
42
43class CDGNode;
44class SVFVar;
45
47
49{
50public:
51 typedef std::pair<const SVFVar *, s32_t> BranchCondition;
52
55 {
56 }
57
60 {
61 }
62
65
66 virtual const std::string toString() const
67 {
68 std::string str;
69 std::stringstream rawstr(str);
70 rawstr << "CDGEdge " << " [";
71 rawstr << getDstID() << "<--" << getSrcID() << "\t";
72 return rawstr.str();
73 }
74
76 //{@
78 {
79 return brConditions;
80 }
81
83 {
84 brConditions.insert(std::make_pair(pNode, branchID));
85 }
87
88
89private:
91};
92
94
96{
97
98public:
99
100 typedef CDGEdge::CDGEdgeSetTy::iterator iterator;
101 typedef CDGEdge::CDGEdgeSetTy::const_iterator const_iterator;
102
103public:
105 CDGNode(const ICFGNode *icfgNode) : GenericCDGNodeTy(icfgNode->getId(), CDNodeKd), _icfgNode(icfgNode)
106 {
107
108 }
109
110 virtual const std::string toString() const
111 {
112 std::string str;
113 std::stringstream rawstr(str);
114 rawstr << getId();
115 return rawstr.str();
116 }
117
118 const ICFGNode *getICFGNode() const
119 {
120 return _icfgNode;
121 }
122
124
125 static inline bool classof(const CDGNode *)
126 {
127 return true;
128 }
129
130 static inline bool classof(const GenericICFGNodeTy* node)
131 {
132 return node->getNodeKind() == CDNodeKd;
133 }
134
135 static inline bool classof(const SVFValue* node)
136 {
137 return node->getNodeKind() == CDNodeKd;
138 }
140
141private:
143};
144
145typedef std::vector<std::pair<NodeID, NodeID>> NodePairVector;
147
148class CDG : public GenericCDGTy
149{
150
151public:
152
155 typedef CDGNodeIDToNodeMapTy::iterator iterator;
156 typedef CDGNodeIDToNodeMapTy::const_iterator const_iterator;
157 typedef std::vector<const ICFGNode *> ICFGNodeVector;
158 typedef std::vector<std::pair<const ICFGNode *, const ICFGNode *>> ICFGNodePairVector;
159
160private:
161 static CDG *controlDg;
164 {
165
166 }
167
168
169public:
171
172 static inline CDG * getCDG()
173 {
174 if (controlDg == nullptr)
175 {
176 controlDg = new CDG();
177 }
178 return controlDg;
179 }
180
181 static void releaseCDG()
182 {
183 if (controlDg)
184 delete controlDg;
185 controlDg = nullptr;
186 }
188
190 virtual ~CDG() {}
191
193 inline CDGNode *getCDGNode(NodeID id) const
194 {
195 if (!hasCDGNode(id))
196 return nullptr;
197 return getGNode(id);
198 }
199
201 inline bool hasCDGNode(NodeID id) const
202 {
203 return hasGNode(id);
204 }
205
207 bool hasCDGEdge(CDGNode *src, CDGNode *dst)
208 {
209 CDGEdge edge(src, dst);
212 if (outEdge && inEdge)
213 {
214 assert(outEdge == inEdge && "edges not match");
215 return true;
216 }
217 else
218 return false;
219 }
220
222 CDGEdge *getCDGEdge(const CDGNode *src, const CDGNode *dst)
223 {
224 CDGEdge *edge = nullptr;
225 size_t counter = 0;
226 for (CDGEdge::CDGEdgeSetTy::iterator iter = src->OutEdgeBegin();
227 iter != src->OutEdgeEnd(); ++iter)
228 {
229 if ((*iter)->getDstID() == dst->getId())
230 {
231 counter++;
232 edge = (*iter);
233 }
234 }
235 assert(counter <= 1 && "there's more than one edge between two CDG nodes");
236 return edge;
237 }
238
240 void view()
241 {
242 SVF::ViewGraph(this, "Control Dependence Graph");
243 }
244
246 void dump(const std::string &filename)
247 {
249 }
250
251public:
254 {
255 edge->getDstNode()->removeIncomingEdge(edge);
256 edge->getSrcNode()->removeOutgoingEdge(edge);
257 delete edge;
258 }
259
261 inline void removeCDGNode(CDGNode *node)
262 {
263 std::set<CDGEdge *> temp;
264 for (CDGEdge *e: node->getInEdges())
265 temp.insert(e);
266 for (CDGEdge *e: node->getOutEdges())
267 temp.insert(e);
268 for (CDGEdge *e: temp)
269 {
270 removeCDGEdge(e);
271 }
272 removeGNode(node);
273 }
274
276 inline bool removeCDGNode(NodeID id)
277 {
278 if (hasCDGNode(id))
279 {
281 return true;
282 }
283 return false;
284 }
285
287 inline bool addCDGEdge(CDGEdge *edge)
288 {
289 bool added1 = edge->getDstNode()->addIncomingEdge(edge);
290 bool added2 = edge->getSrcNode()->addOutgoingEdge(edge);
291 assert(added1 && added2 && "edge not added??");
292 return added1 && added2;
293 }
294
296 virtual inline void addCDGNode(CDGNode *node)
297 {
298 addGNode(node->getId(), node);
299 }
300
303 {
304 for (const ICFGNode *icfgNode: nodes)
305 {
306 if (!IDToNodeMap.count(icfgNode->getId()))
307 {
308 addGNode(icfgNode->getId(), new CDGNode(icfgNode));
309 }
310 }
311 }
312
314 void addCDGEdgeFromSrcDst(const ICFGNode *src, const ICFGNode *dst, const SVFVar *pNode, s32_t branchID);
315
316};
317} // end namespace SVF
318
319namespace SVF
320{
321/* !
322 * GenericGraphTraits specializations for generic graph algorithms.
323 * Provide graph traits for traversing from a constraint node using standard graph ICFGTraversals.
324 */
325template<>
327 : public GenericGraphTraits<SVF::GenericNode<SVF::CDGNode, SVF::CDGEdge> *>
328{
329};
330
332template<>
334 Inverse<SVF::GenericNode<SVF::CDGNode, SVF::CDGEdge> *> >
335{
336};
337
338template<>
340 : public GenericGraphTraits<SVF::GenericGraph<SVF::CDGNode, SVF::CDGEdge> *>
341{
343};
344
345template<>
346struct DOTGraphTraits<SVF::CDG *> : public DOTGraphTraits<SVF::PAG *>
347{
348
350
351 DOTGraphTraits(bool isSimple = false) :
353 {
354 }
355
357 static std::string getGraphName(SVF::CDG *)
358 {
359 return "Control Dependence Graph";
360 }
361
362 std::string getNodeLabel(NodeType *node, SVF::CDG *graph)
363 {
364 return getSimpleNodeLabel(node, graph);
365 }
366
368 static std::string getSimpleNodeLabel(NodeType *node, SVF::CDG *)
369 {
370 std::string str;
371 std::stringstream rawstr(str);
372 rawstr << "NodeID: " << node->getId() << "\n";
373 const SVF::ICFGNode *icfgNode = node->getICFGNode();
374 if (const SVF::IntraICFGNode *bNode = SVF::SVFUtil::dyn_cast<SVF::IntraICFGNode>(icfgNode))
375 {
376 rawstr << "IntraBlockNode ID: " << bNode->getId() << " \t";
378 if (edges.empty())
379 {
380 rawstr << (bNode)->toString() << " \t";
381 }
382 else
383 {
384 for (SVF::PAG::SVFStmtList::iterator it = edges.begin(), eit = edges.end(); it != eit; ++it)
385 {
386 const SVF::PAGEdge *edge = *it;
387 rawstr << edge->toString();
388 }
389 }
390 rawstr << " {fun: " << bNode->getFun()->getName() << "}";
391 }
392 else if (const SVF::FunEntryICFGNode *entry = SVF::SVFUtil::dyn_cast<SVF::FunEntryICFGNode>(icfgNode))
393 {
394 rawstr << entry->toString();
395 }
396 else if (const SVF::FunExitICFGNode *exit = SVF::SVFUtil::dyn_cast<SVF::FunExitICFGNode>(icfgNode))
397 {
398 rawstr << exit->toString();
399 }
400 else if (const SVF::CallICFGNode *call = SVF::SVFUtil::dyn_cast<SVF::CallICFGNode>(icfgNode))
401 {
402 rawstr << call->toString();
403 }
404 else if (const SVF::RetICFGNode *ret = SVF::SVFUtil::dyn_cast<SVF::RetICFGNode>(icfgNode))
405 {
406 rawstr << ret->toString();
407 }
408 else if (const SVF::GlobalICFGNode *glob = SVF::SVFUtil::dyn_cast<SVF::GlobalICFGNode>(icfgNode))
409 {
411 for (SVF::PAG::SVFStmtList::iterator it = edges.begin(), eit = edges.end(); it != eit; ++it)
412 {
413 const SVF::PAGEdge *edge = *it;
414 rawstr << edge->toString();
415 }
416 }
417 else
418 assert(false && "what else kinds of nodes do we have??");
419
420 return rawstr.str();
421 }
422
423 static std::string getNodeAttributes(NodeType *node, SVF::CDG *)
424 {
425 std::string str;
426 std::stringstream rawstr(str);
427 const SVF::ICFGNode *icfgNode = node->getICFGNode();
428
429 rawstr << "shape=record";
430
431 if (SVF::SVFUtil::isa<SVF::IntraICFGNode>(icfgNode))
432 {
433 rawstr << ",color=black";
434 }
435 else if (SVF::SVFUtil::isa<SVF::FunEntryICFGNode>(icfgNode))
436 {
437 rawstr << ",color=yellow";
438 }
439 else if (SVF::SVFUtil::isa<SVF::FunExitICFGNode>(icfgNode))
440 {
441 rawstr << ",color=green";
442 }
443 else if (SVF::SVFUtil::isa<SVF::CallICFGNode>(icfgNode))
444 {
445 rawstr << ",color=red";
446 }
447 else if (SVF::SVFUtil::isa<SVF::RetICFGNode>(icfgNode))
448 {
449 rawstr << ",color=blue";
450 }
451 else if (SVF::SVFUtil::isa<SVF::GlobalICFGNode>(icfgNode))
452 {
453 rawstr << ",color=purple";
454 }
455 else
456 assert(false && "no such kind of node!!");
457
458 return rawstr.str();
459 }
460
461 template<class EdgeIter>
463 {
464 assert(*(EI.getCurrent()) && "No edge found!!");
465 return "style=solid";
466 }
467
468 template<class EdgeIter>
469 static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
470 {
471 SVF::CDGEdge *edge = *(EI.getCurrent());
472 assert(edge && "No edge found!!");
473
474 std::string str;
475 std::stringstream rawstr(str);
476 for (const auto &cond: edge->getBranchConditions())
477 {
478 rawstr << std::to_string(cond.second) << "|";
479 }
480 std::string lb = rawstr.str();
481 lb.pop_back();
482
483 return lb;
484 }
485};
486
487} // End namespace SVF
488#endif //SVF_CONTROLDG_H
Set< BranchCondition > brConditions
Definition CDG.h:90
virtual const std::string toString() const
Definition CDG.h:66
CDGEdge(CDGNode *s, CDGNode *d)
Constructor.
Definition CDG.h:54
GenericNode< CDGNode, CDGEdge >::GEdgeSetTy CDGEdgeSetTy
Definition CDG.h:63
std::pair< const SVFVar *, s32_t > BranchCondition
Definition CDG.h:51
~CDGEdge()
Destructor.
Definition CDG.h:59
const Set< BranchCondition > & getBranchConditions() const
get/set branch condition
Definition CDG.h:77
CDGEdgeSetTy SVFGEdgeSetTy
Definition CDG.h:64
void insertBranchCondition(const SVFVar *pNode, s32_t branchID)
Definition CDG.h:82
const ICFGNode * getICFGNode() const
Definition CDG.h:118
CDGNode(const ICFGNode *icfgNode)
Constructor.
Definition CDG.h:105
static bool classof(const SVFValue *node)
Definition CDG.h:135
CDGEdge::CDGEdgeSetTy::iterator iterator
Definition CDG.h:100
static bool classof(const CDGNode *)
Methods for support type inquiry through isa, cast, and dyn_cast:
Definition CDG.h:125
const ICFGNode * _icfgNode
Definition CDG.h:142
virtual const std::string toString() const
Definition CDG.h:110
CDGEdge::CDGEdgeSetTy::const_iterator const_iterator
Definition CDG.h:101
static bool classof(const GenericICFGNodeTy *node)
Definition CDG.h:130
Map< NodeID, CDGNode * > CDGNodeIDToNodeMapTy
Definition CDG.h:153
std::vector< std::pair< const ICFGNode *, const ICFGNode * > > ICFGNodePairVector
Definition CDG.h:158
void removeCDGNode(CDGNode *node)
Remove a CDGNode.
Definition CDG.h:261
CDGNodeIDToNodeMapTy::iterator iterator
Definition CDG.h:155
void addCDGNodesFromVector(ICFGNodeVector nodes)
Add CDG nodes from nodeid vector.
Definition CDG.h:302
CDGNodeIDToNodeMapTy::const_iterator const_iterator
Definition CDG.h:156
void view()
View graph from the debugger.
Definition CDG.h:240
bool hasCDGEdge(CDGNode *src, CDGNode *dst)
Whether we has a CDG edge.
Definition CDG.h:207
bool removeCDGNode(NodeID id)
Remove node from nodeID.
Definition CDG.h:276
CDGEdge * getCDGEdge(const CDGNode *src, const CDGNode *dst)
Get a control dependence edge according to src and dst.
Definition CDG.h:222
CDG()
Constructor.
Definition CDG.h:163
static CDG * controlDg
Definition CDG.h:161
virtual ~CDG()
Destructor.
Definition CDG.h:190
static CDG * getCDG()
Singleton design here to make sure we only have one instance during any analysis.
Definition CDG.h:172
void addCDGEdgeFromSrcDst(const ICFGNode *src, const ICFGNode *dst, const SVFVar *pNode, s32_t branchID)
Add CDG edges from nodeid pair.
Definition CDG.cpp:35
void dump(const std::string &filename)
Dump graph into dot file.
Definition CDG.h:246
bool hasCDGNode(NodeID id) const
Whether has the CDGNode.
Definition CDG.h:201
virtual void addCDGNode(CDGNode *node)
Add a CDG node.
Definition CDG.h:296
static void releaseCDG()
Definition CDG.h:181
bool addCDGEdge(CDGEdge *edge)
Add CDG edge.
Definition CDG.h:287
CDGEdge::CDGEdgeSetTy CDGEdgeSetTy
Definition CDG.h:154
CDGNode * getCDGNode(NodeID id) const
Get a CDG node.
Definition CDG.h:193
std::vector< const ICFGNode * > ICFGNodeVector
Definition CDG.h:157
void removeCDGEdge(CDGEdge *edge)
Remove a control dependence edge.
Definition CDG.h:253
NodeID getDstID() const
NodeID getSrcID() const
get methods of the components
void addGNode(NodeID id, NodeType *node)
Add a Node.
void removeGNode(NodeType *node)
Delete a node.
IDToNodeMapTy IDToNodeMap
node map
bool hasGNode(NodeID id) const
Has a node.
IDToNodeMapTy::iterator iterator
Node Iterators.
NodeType * getGNode(NodeID id) const
Get a node.
OrderedSet< EdgeType *, typename EdgeType::equalGEdge > GEdgeSetTy
Edge kind.
bool hasIncomingEdge() const
Has incoming/outgoing edge set.
bool hasOutgoingEdge() const
iterator OutEdgeEnd()
const GEdgeSetTy & getOutEdges() const
const GEdgeSetTy & getInEdges() const
iterator OutEdgeBegin()
iterators
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType &GT, bool simple=false)
std::vector< const SVFStmt * > SVFStmtList
Definition SVFIR.h:59
SVFStmtList & getPTASVFStmtList(const ICFGNode *inst)
Given an instruction, get all its PTA PAGEdges.
Definition SVFIR.h:323
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:120
virtual const std::string toString() const
NodeID getId() const
Get ID.
Definition SVFValue.h:158
GNodeK getNodeKind() const
Get node kind.
Definition SVFValue.h:164
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
for isBitcode
Definition BasicTypes.h:70
std::vector< std::pair< NodeID, NodeID > > NodePairVector
Definition CDG.h:145
GenericGraph< CDGNode, CDGEdge > GenericCDGTy
Definition CDG.h:146
u32_t NodeID
Definition GeneralType.h:76
void ViewGraph(const GraphType &G, const std::string &name, bool ShortNames=false, GraphProgram::Name Program=GraphProgram::DOT)
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
signed s32_t
Definition GeneralType.h:68
iter_range< typename GenericGraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)
GenericEdge< CDGNode > GenericCDGEdgeTy
Definition CDG.h:46
GenericNode< CDGNode, CDGEdge > GenericCDGNodeTy
Definition CDG.h:93
std::string getNodeLabel(NodeType *node, SVF::CDG *graph)
Definition CDG.h:362
static std::string getGraphName(SVF::CDG *)
Return name of the graph.
Definition CDG.h:357
static std::string getSimpleNodeLabel(NodeType *node, SVF::CDG *)
Return the label of an ICFG node.
Definition CDG.h:368
DOTGraphTraits(bool isSimple=false)
Definition CDG.h:351
static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
Definition CDG.h:469
static std::string getNodeAttributes(NodeType *node, SVF::CDG *)
Definition CDG.h:423
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, SVF::CDG *)
Definition CDG.h:462