Static Value-Flow Analysis
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 
35 namespace SVF
36 {
37 
38 class CDGNode;
39 
41 
42 class CDGEdge : public GenericCDGEdgeTy
43 {
44 public:
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 
76  void insertBranchCondition(const SVFVar *pNode, s32_t branchID)
77  {
78  brConditions.insert(std::make_pair(pNode, branchID));
79  }
81 
82 
83 private:
85 };
86 
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:
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 
135 private:
137 };
138 
139 typedef std::vector<std::pair<NodeID, NodeID>> NodePairVector;
141 
142 class CDG : public GenericCDGTy
143 {
144 
145 public:
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 
154 private:
155  static CDG *controlDg;
157  CDG()
158  {
159 
160  }
161 
162 
163 public:
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);
204  CDGEdge *outEdge = src->hasOutgoingEdge(&edge);
205  CDGEdge *inEdge = dst->hasIncomingEdge(&edge);
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 
245 public:
247  inline void removeCDGEdge(CDGEdge *edge)
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 
313 namespace 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  */
319 template<>
321  : public GenericGraphTraits<SVF::GenericNode<SVF::CDGNode, SVF::CDGEdge> *>
322 {
323 };
324 
326 template<>
328  Inverse<SVF::GenericNode<SVF::CDGNode, SVF::CDGEdge> *> >
329 {
330 };
331 
332 template<>
334  : public GenericGraphTraits<SVF::GenericGraph<SVF::CDGNode, SVF::CDGEdge> *>
335 {
337 };
338 
339 template<>
340 struct DOTGraphTraits<SVF::CDG *> : public DOTGraphTraits<SVF::PAG *>
341 {
342 
344 
345  DOTGraphTraits(bool isSimple = false) :
347  {
348  }
349 
352  {
353  return "Control Dependence Graph";
354  }
355 
357  {
358  return getSimpleNodeLabel(node, graph);
359  }
360 
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 
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>
456  static std::string getEdgeAttributes(NodeType *, EdgeIter EI, SVF::CDG *)
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
const char *const string
Definition: cJSON.h:172
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
std::pair< const SVFVar *, s32_t > BranchCondition
Definition: CDG.h:45
GenericNode< CDGNode, CDGEdge >::GEdgeSetTy CDGEdgeSetTy
Definition: CDG.h:57
~CDGEdge()
Destructor.
Definition: CDG.h:53
CDGEdgeSetTy SVFGEdgeSetTy
Definition: CDG.h:58
void insertBranchCondition(const SVFVar *pNode, s32_t branchID)
Definition: CDG.h:76
const Set< BranchCondition > & getBranchConditions() const
get/set branch condition
Definition: CDG.h:71
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
const ICFGNode * getICFGNode() const
Definition: CDG.h:112
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
Definition: CDG.h:143
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
CDGNode * getCDGNode(NodeID id) const
Get a CDG node.
Definition: CDG.h:187
CDG()
Constructor.
Definition: CDG.h:157
static CDG * controlDg
Definition: CDG.h:155
virtual ~CDG()
Destructor.
Definition: CDG.h:184
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 CDG * getCDG()
Singleton design here to make sure we only have one instance during any analysis.
Definition: CDG.h:166
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
std::vector< const ICFGNode * > ICFGNodeVector
Definition: CDG.h:151
CDGEdge * getCDGEdge(const CDGNode *src, const CDGNode *dst)
Get a control dependence edge according to src and dst.
Definition: CDG.h:216
void removeCDGEdge(CDGEdge *edge)
Remove a control dependence edge.
Definition: CDG.h:247
NodeType * getSrcNode() const
Definition: GenericGraph.h:97
NodeID getDstID() const
Definition: GenericGraph.h:85
NodeID getSrcID() const
get methods of the components
Definition: GenericGraph.h:81
NodeType * getDstNode() const
Definition: GenericGraph.h:101
void addGNode(NodeID id, NodeType *node)
Add a Node.
Definition: GenericGraph.h:646
void removeGNode(NodeType *node)
Delete a node.
Definition: GenericGraph.h:668
NodeType * getGNode(NodeID id) const
Get a node.
Definition: GenericGraph.h:653
IDToNodeMapTy IDToNodeMap
node map
Definition: GenericGraph.h:699
bool hasGNode(NodeID id) const
Has a node.
Definition: GenericGraph.h:661
IDToNodeMapTy::iterator iterator
Node Iterators.
Definition: GenericGraph.h:606
OrderedSet< EdgeType *, typename EdgeType::equalGEdge > GEdgeSetTy
Edge kind.
Definition: GenericGraph.h:402
bool hasIncomingEdge() const
Has incoming/outgoing edge set.
Definition: GenericGraph.h:442
bool hasOutgoingEdge() const
Definition: GenericGraph.h:446
iterator OutEdgeEnd()
Definition: GenericGraph.h:458
const GEdgeSetTy & getOutEdges() const
Definition: GenericGraph.h:430
iterator OutEdgeBegin()
iterators
Definition: GenericGraph.h:454
const GEdgeSetTy & getInEdges() const
Definition: GenericGraph.h:434
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType &GT, bool simple=false)
Definition: GraphPrinter.h:56
GNodeK getNodeKind() const
Get node kind.
Definition: GenericGraph.h:266
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115
std::vector< const SVFStmt * > SVFStmtList
Definition: SVFIR.h:58
SVFStmtList & getPTASVFStmtList(const ICFGNode *inst)
Given an instruction, get all its PTA PAGEdges.
Definition: SVFIR.h:226
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)
Definition: GraphWriter.h:371
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition: GeneralType.h:101
signed s32_t
Definition: GeneralType.h:47
GenericEdge< CDGNode > GenericCDGEdgeTy
Definition: CDG.h:38
GenericNode< CDGNode, CDGEdge > GenericCDGNodeTy
Definition: CDG.h:87
iter_range< typename GenericGraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)
Definition: GraphTraits.h:111
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96
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