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