Static Value-Flow Analysis
VFG.cpp
Go to the documentation of this file.
1 //===- VFG.cpp -- Sparse value-flow graph-----------------------------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-2018> <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  * VFG.cpp
25  *
26  * Created on: Sep 11, 2018
27  * Author: Yulei Sui
28  */
29 
30 
31 #include <Graphs/SVFGNode.h>
32 #include "Util/Options.h"
33 #include "Graphs/VFG.h"
34 #include "SVFIR/SVFModule.h"
35 #include "Util/SVFUtil.h"
36 
37 using namespace SVF;
38 using namespace SVFUtil;
39 
41 {
42  std::string str;
43  std::stringstream rawstr(str);
44  rawstr << "VFGNode ID: " << getId() << " ";
45  return rawstr.str();
46 }
47 
49 {
50  std::string str;
51  std::stringstream rawstr(str);
52  rawstr << "StmtVFGNode ID: " << getId() << " ";
53  rawstr << getPAGEdge()->toString();
54  return rawstr.str();
55 }
56 
58 {
59  NodeBS nb;
60  nb.set(getPAGDstNodeID());
61  return nb;
62 }
63 
65 {
66  std::string str;
67  std::stringstream rawstr(str);
68  rawstr << "LoadVFGNode ID: " << getId() << " ";
69  rawstr << getPAGEdge()->toString();
70  return rawstr.str();
71 }
72 
74 {
75  NodeBS nb;
76  for (auto edge: getOutEdges())
77  {
78  if (IndirectSVFGEdge *iedge = SVFUtil::dyn_cast<IndirectSVFGEdge>(edge))
79  {
80  nb |= iedge->getPointsTo();
81  }
82  }
83  return nb;
84 }
85 
87 {
88  std::string str;
89  std::stringstream rawstr(str);
90  rawstr << "StoreVFGNode ID: " << getId() << " ";
91  rawstr << getPAGEdge()->toString();
92  return rawstr.str();
93 }
94 
96 {
97  NodeBS nb;
98  nb.set(getPAGDstNodeID());
99  return nb;
100 }
101 
103 {
104  std::string str;
105  std::stringstream rawstr(str);
106  rawstr << "CopyVFGNode ID: " << getId() << " ";
107  rawstr << getPAGEdge()->toString();
108  return rawstr.str();
109 }
110 
112 {
113  NodeBS nb;
114  nb.set(getRes()->getId());
115  return nb;
116 }
117 
119 {
120  std::string str;
121  std::stringstream rawstr(str);
122  rawstr << "CmpVFGNode ID: " << getId() << " ";
123  rawstr << "PAGEdge: [" << res->getId() << " = cmp(";
124  for(CmpVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd();
125  it != eit; it++)
126  rawstr << it->second->getId() << ", ";
127  rawstr << ")]\n";
128  if(res->hasValue())
129  {
130  rawstr << " " << res->getValue()->toString();
131  }
132  return rawstr.str();
133 }
134 
136 {
137  NodeBS nb;
138  nb.set(getRes()->getId());
139  return nb;
140 }
141 
143 {
144  std::string str;
145  std::stringstream rawstr(str);
146  rawstr << "BinaryOPVFGNode ID: " << getId() << " ";
147  rawstr << "PAGEdge: [" << res->getId() << " = Binary(";
148  for(BinaryOPVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd();
149  it != eit; it++)
150  rawstr << it->second->getId() << ", ";
151  rawstr << ")]\t";
152  if(res->hasValue())
153  {
154  rawstr << " " << res->getValue()->toString();
155  }
156  return rawstr.str();
157 }
158 
160 {
161  NodeBS nb;
162  nb.set(getRes()->getId());
163  return nb;
164 }
165 
167 {
168  std::string str;
169  std::stringstream rawstr(str);
170  rawstr << "UnaryOPVFGNode ID: " << getId() << " ";
171  rawstr << "PAGEdge: [" << res->getId() << " = Unary(";
172  for(UnaryOPVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd();
173  it != eit; it++)
174  rawstr << it->second->getId() << ", ";
175  rawstr << ")]\t";
176  if(res->hasValue())
177  {
178  rawstr << " " << res->getValue()->toString();
179  }
180  return rawstr.str();
181 }
182 
184 {
185  return NodeBS();
186 }
187 
189 {
190  std::string str;
191  std::stringstream rawstr(str);
192  rawstr << "BranchVFGNode ID: " << getId() << " ";
193  rawstr << "PAGEdge: [" << brstmt->toString() << "\t";
194  return rawstr.str();
195 }
196 
198 {
199  NodeBS nb;
200  nb.set(getPAGDstNodeID());
201  return nb;
202 }
203 
205 {
206  std::string str;
207  std::stringstream rawstr(str);
208  rawstr << "GepVFGNode ID: " << getId() << " ";
209  rawstr << getPAGEdge()->toString();
210  return rawstr.str();
211 }
212 
214 {
215  NodeBS nb;
216  nb.set(getRes()->getId());
217  return nb;
218 }
219 
221 {
222  std::string str;
223  std::stringstream rawstr(str);
224  rawstr << "PHIVFGNode ID: " << getId() << " ";
225  rawstr << "PAGNode: [" << res->getId() << " = PHI(";
226  for(PHIVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd();
227  it != eit; it++)
228  rawstr << it->second->getId() << ", ";
229  rawstr << ")]\t";
230  if(res->hasValue())
231  {
232  rawstr << " " << res->getValue()->toString();
233  }
234  return rawstr.str();
235 }
236 
237 
239 {
240  std::string str;
241  std::stringstream rawstr(str);
242  rawstr << "IntraPHIVFGNode ID: " << getId() << " ";
243  rawstr << "PAGNode: [" << res->getId() << " = PHI(";
244  for(PHIVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd();
245  it != eit; it++)
246  rawstr << it->second->getId() << ", ";
247  rawstr << ")]\t";
248  if(res->hasValue())
249  {
250  rawstr << " " << res->getValue()->toString();
251  }
252  return rawstr.str();
253 }
254 
256 {
257  NodeBS nb;
258  nb.set(getPAGDstNodeID());
259  return nb;
260 }
261 
263 {
264  std::string str;
265  std::stringstream rawstr(str);
266  rawstr << "AddrVFGNode ID: " << getId() << " ";
267  rawstr << getPAGEdge()->toString();
268  return rawstr.str();
269 }
270 
271 
273 {
274  std::string str;
275  std::stringstream rawstr(str);
276  rawstr << "ArgumentVFGNode ID: " << getId() << " ";
277  rawstr << param->toString();
278  return rawstr.str();
279 }
280 
282 {
283  NodeBS nb;
284  nb.set(getParam()->getId());
285  return nb;
286 }
287 
289 {
290  std::string str;
291  std::stringstream rawstr(str);
292  rawstr << "ActualParmVFGNode ID: " << getId() << " ";
293  rawstr << "CS[" << getCallSite()->getSourceLoc() << "]";
294  rawstr << param->toString();
295  return rawstr.str();
296 }
297 
299 {
300  NodeBS nb;
301  nb.set(getParam()->getId());
302  return nb;
303 }
304 
306 {
307  std::string str;
308  std::stringstream rawstr(str);
309  rawstr << "FormalParmVFGNode ID: " << getId() << " ";
310  rawstr << "Fun[" << getFun()->getName() << "]";
311  rawstr << param->toString();
312  return rawstr.str();
313 }
314 
316 {
317  NodeBS nb;
318  nb.set(getRev()->getId());
319  return nb;
320 }
321 
323 {
324  std::string str;
325  std::stringstream rawstr(str);
326  rawstr << "ActualRetVFGNode ID: " << getId() << " ";
327  rawstr << "CS[" << getCallSite()->getSourceLoc() << "]";
328  rawstr << param->toString();
329  return rawstr.str();
330 }
331 
332 
334 {
335  NodeBS nb;
336  nb.set(getRet()->getId());
337  return nb;
338 }
339 
341 {
342  std::string str;
343  std::stringstream rawstr(str);
344  rawstr << "FormalRetVFGNode ID: " << getId() << " ";
345  rawstr << "Fun[" << getFun()->getName() << "]";
346  rawstr << param->toString();
347  return rawstr.str();
348 }
349 
350 
352 {
353  std::string str;
354  std::stringstream rawstr(str);
355  if(isFormalParmPHI())
356  rawstr << "FormalParmPHI ID: " << getId() << " PAGNode ID: " << res->getId() << "\n" << res->getValue()->toString();
357  else
358  rawstr << "ActualRetPHI ID: " << getId() << " PAGNode ID: " << res->getId() << "\n" << res->getValue()->toString();
359  return rawstr.str();
360 }
361 
363 {
364  NodeBS nb;
365  nb.set(getPAGNode()->getId());
366  return nb;
367 }
368 
370 {
371  std::string str;
372  std::stringstream rawstr(str);
373  rawstr << "NullPtrVFGNode ID: " << getId();
374  rawstr << " PAGNode ID: " << node->getId() << "\n";
375  return rawstr.str();
376 }
377 
378 
380 {
381  std::string str;
382  std::stringstream rawstr(str);
383  rawstr << "VFGEdge: [" << getDstID() << "<--" << getSrcID() << "]\t";
384  return rawstr.str();
385 }
386 
388 {
389  std::string str;
390  std::stringstream rawstr(str);
391  rawstr << "DirectVFGEdge: [" << getDstID() << "<--" << getSrcID() << "]\t";
392  return rawstr.str();
393 }
394 
396 {
397  std::string str;
398  std::stringstream rawstr(str);
399  rawstr << "IntraDirSVFGEdge: [" << getDstID() << "<--" << getSrcID() << "]\t";
400  return rawstr.str();
401 }
402 
404 {
405  std::string str;
406  std::stringstream rawstr(str);
407  rawstr << "CallDirSVFGEdge CallSite ID: " << getCallSiteId() << " [";
408  rawstr << getDstID() << "<--" << getSrcID() << "]\t";
409  return rawstr.str();
410 }
411 
413 {
414  std::string str;
415  std::stringstream rawstr(str);
416  rawstr << "RetDirSVFGEdge CallSite ID: " << getCallSiteId() << " [";
417  rawstr << getDstID() << "<--" << getSrcID() << "]\t";
418  return rawstr.str();
419 }
420 
421 
422 
424  ArgumentVFGNode(id, n, FRet), fun(f)
425 {
426 }
427 
428 PHIVFGNode::PHIVFGNode(NodeID id, const PAGNode* r,VFGNodeK k): VFGNode(id, k), res(r)
429 {
430 
431 }
432 
441 VFG::VFG(PTACallGraph* cg, VFGK k): totalVFGNode(0), callgraph(cg), pag(SVFIR::getPAG()), kind(k)
442 {
443 
444  DBOUT(DGENERAL, outs() << pasMsg("\tCreate VFG Top Level Node\n"));
445  addVFGNodes();
446 
447  DBOUT(DGENERAL, outs() << pasMsg("\tCreate SVFG Direct Edge\n"));
449 }
450 
455 {
456  pag = nullptr;
457 }
458 
459 
464 {
465 
466  // initialize dummy definition null pointers in order to uniform the construction
467  // to be noted for black hole pointer it has already has address edge connected,
468  // and its definition will be set when processing addr SVFIR edge.
470 
471  // initialize address nodes
473  for (SVFStmt::SVFStmtSetTy::iterator iter = addrs.begin(), eiter =
474  addrs.end(); iter != eiter; ++iter)
475  {
476  addAddrVFGNode(SVFUtil::cast<AddrStmt>(*iter));
477  }
478 
479  // initialize copy nodes
481  for (SVFStmt::SVFStmtSetTy::iterator iter = copys.begin(), eiter =
482  copys.end(); iter != eiter; ++iter)
483  {
484  const CopyStmt* edge = SVFUtil::cast<CopyStmt>(*iter);
485  assert(!isPhiCopyEdge(edge) && "Copy edges can not be a PhiNode (or from PhiNode)");
486  addCopyVFGNode(edge);
487  }
488 
489  // initialize gep nodes
491  for (SVFStmt::SVFStmtSetTy::iterator iter = ngeps.begin(), eiter =
492  ngeps.end(); iter != eiter; ++iter)
493  {
494  addGepVFGNode(SVFUtil::cast<GepStmt>(*iter));
495  }
496 
497  // initialize load nodes
499  for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter =
500  loads.end(); iter != eiter; ++iter)
501  {
502  addLoadVFGNode(SVFUtil::cast<LoadStmt>(*iter));
503  }
504 
505  // initialize store nodes
507  for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter =
508  stores.end(); iter != eiter; ++iter)
509  {
510  addStoreVFGNode(SVFUtil::cast<StoreStmt>(*iter));
511  }
512 
514  for (SVFStmt::SVFStmtSetTy::iterator iter = forks.begin(), eiter =
515  forks.end(); iter != eiter; ++iter)
516  {
517  TDForkPE* forkedge = SVFUtil::cast<TDForkPE>(*iter);
518  addActualParmVFGNode(forkedge->getRHSVar(),forkedge->getCallSite());
519  }
520 
521  // initialize actual parameter nodes
522  for(SVFIR::CSToArgsListMap::iterator it = pag->getCallSiteArgsMap().begin(), eit = pag->getCallSiteArgsMap().end(); it !=eit; ++it)
523  {
524 
525  for(SVFIR::SVFVarList::iterator pit = it->second.begin(), epit = it->second.end(); pit!=epit; ++pit)
526  {
527  const PAGNode* pagNode = *pit;
528  if (isInterestedPAGNode(pagNode))
529  addActualParmVFGNode(pagNode,it->first);
530  }
531  }
532 
533  // initialize actual return nodes (callsite return)
534  for(SVFIR::CSToRetMap::iterator it = pag->getCallSiteRets().begin(), eit = pag->getCallSiteRets().end(); it !=eit; ++it)
535  {
536 
540  if(isInterestedPAGNode(it->second) == false || hasDef(it->second))
541  continue;
542 
543  addActualRetVFGNode(it->second,it->first->getCallICFGNode());
544  }
545 
546  // initialize formal parameter nodes
547  for(SVFIR::FunToArgsListMap::iterator it = pag->getFunArgsMap().begin(), eit = pag->getFunArgsMap().end(); it !=eit; ++it)
548  {
549  const SVFFunction* func = it->first;
550 
551  for(SVFIR::SVFVarList::iterator pit = it->second.begin(), epit = it->second.end(); pit!=epit; ++pit)
552  {
553  const PAGNode* param = *pit;
554  if (isInterestedPAGNode(param) == false || hasBlackHoleConstObjAddrAsDef(param))
555  continue;
556 
557  CallPESet callPEs;
558  if (param->hasIncomingEdges(SVFStmt::Call))
559  {
560  for (SVFStmt::SVFStmtSetTy::const_iterator cit = param->getIncomingEdgesBegin(SVFStmt::Call), ecit =
561  param->getIncomingEdgesEnd(SVFStmt::Call); cit != ecit; ++cit)
562  {
563  CallPE* callPE = SVFUtil::cast<CallPE>(*cit);
564  if (isInterestedPAGNode(callPE->getRHSVar()))
565  callPEs.insert(callPE);
566  }
567  }
568  addFormalParmVFGNode(param,func,callPEs);
569  }
570 
571  if (func->isVarArg())
572  {
573  const PAGNode* varParam = pag->getGNode(pag->getVarargNode(func));
574  if (isInterestedPAGNode(varParam) == false || hasBlackHoleConstObjAddrAsDef(varParam))
575  continue;
576 
577  CallPESet callPEs;
578  if (varParam->hasIncomingEdges(SVFStmt::Call))
579  {
580  for(SVFStmt::SVFStmtSetTy::const_iterator cit = varParam->getIncomingEdgesBegin(SVFStmt::Call),
581  ecit = varParam->getIncomingEdgesEnd(SVFStmt::Call); cit!=ecit; ++cit)
582  {
583  CallPE* callPE = SVFUtil::cast<CallPE>(*cit);
584  if(isInterestedPAGNode(callPE->getRHSVar()))
585  callPEs.insert(callPE);
586  }
587  }
588  addFormalParmVFGNode(varParam,func,callPEs);
589  }
590  }
591 
592  // initialize formal return nodes (callee return)
593  for (SVFIR::FunToRetMap::iterator it = pag->getFunRets().begin(), eit = pag->getFunRets().end(); it != eit; ++it)
594  {
595  const SVFFunction* func = it->first;
596 
597  const PAGNode* uniqueFunRetNode = it->second;
598 
599  RetPESet retPEs;
600  if (uniqueFunRetNode->hasOutgoingEdges(SVFStmt::Ret))
601  {
602  for (SVFStmt::SVFStmtSetTy::const_iterator cit = uniqueFunRetNode->getOutgoingEdgesBegin(SVFStmt::Ret),
603  ecit = uniqueFunRetNode->getOutgoingEdgesEnd(SVFStmt::Ret);
604  cit != ecit; ++cit)
605  {
606  const RetPE* retPE = SVFUtil::cast<RetPE>(*cit);
607  if (isInterestedPAGNode(retPE->getLHSVar()))
608  retPEs.insert(retPE);
609  }
610  }
611 
612  if(isInterestedPAGNode(uniqueFunRetNode))
613  addFormalRetVFGNode(uniqueFunRetNode, func, retPEs);
614  }
615 
616  // initialize llvm phi nodes (phi of top level pointers)
618  for (SVFStmt::SVFStmtSetTy::iterator iter = phis.begin(), eiter =
619  phis.end(); iter != eiter; ++iter)
620  {
621  const PhiStmt* edge = SVFUtil::cast<PhiStmt>(*iter);
622  if(isInterestedPAGNode(edge->getRes()))
623  addIntraPHIVFGNode(edge);
624  }
625  // initialize select statement
627  for (SVFStmt::SVFStmtSetTy::iterator iter = selects.begin(), eiter =
628  selects.end(); iter != eiter; ++iter)
629  {
630  const MultiOpndStmt* edge = SVFUtil::cast<MultiOpndStmt>(*iter);
631  if(isInterestedPAGNode(edge->getRes()))
632  addIntraPHIVFGNode(edge);
633  }
634  // initialize llvm binary nodes (binary operators)
636  for (SVFStmt::SVFStmtSetTy::iterator iter = binaryops.begin(), eiter =
637  binaryops.end(); iter != eiter; ++iter)
638  {
639  const BinaryOPStmt* edge = SVFUtil::cast<BinaryOPStmt>(*iter);
640  if(isInterestedPAGNode(edge->getRes()))
641  addBinaryOPVFGNode(edge);
642  }
643  // initialize llvm unary nodes (unary operators)
645  for (SVFStmt::SVFStmtSetTy::iterator iter = unaryops.begin(), eiter =
646  unaryops.end(); iter != eiter; ++iter)
647  {
648  const UnaryOPStmt* edge = SVFUtil::cast<UnaryOPStmt>(*iter);
649  if(isInterestedPAGNode(edge->getRes()))
650  addUnaryOPVFGNode(edge);
651  }
652  // initialize llvm unary nodes (unary operators)
654  for (SVFStmt::SVFStmtSetTy::iterator iter = brs.begin(), eiter =
655  brs.end(); iter != eiter; ++iter)
656  {
657  const BranchStmt* edge = SVFUtil::cast<BranchStmt>(*iter);
659  addBranchVFGNode(edge);
660  }
661  // initialize llvm cmp nodes (comparison)
663  for (SVFStmt::SVFStmtSetTy::iterator iter = cmps.begin(), eiter =
664  cmps.end(); iter != eiter; ++iter)
665  {
666  const CmpStmt* edge = SVFUtil::cast<CmpStmt>(*iter);
667  if(isInterestedPAGNode(edge->getRes()))
668  addCmpVFGNode(edge);
669  }
670 }
671 
676 {
677  VFGNode* srcNode = getVFGNode(srcId);
678  VFGNode* dstNode = getVFGNode(dstId);
679  checkIntraEdgeParents(srcNode, dstNode);
680  VFGEdge* edge = hasIntraVFGEdge(srcNode, dstNode, VFGEdge::IntraDirectVF);
681  if (edge != nullptr)
682  {
683  assert(edge->isDirectVFGEdge() && "this should be a direct value flow edge!");
684  return nullptr;
685  }
686  else
687  {
688  if(srcNode!=dstNode)
689  {
690  IntraDirSVFGEdge* directEdge = new IntraDirSVFGEdge(srcNode,dstNode);
691  return (addVFGEdge(directEdge) ? directEdge : nullptr);
692  }
693  else
694  return nullptr;
695  }
696 }
697 
702 {
703  VFGNode* srcNode = getVFGNode(srcId);
704  VFGNode* dstNode = getVFGNode(dstId);
705  VFGEdge* edge = hasInterVFGEdge(srcNode, dstNode, VFGEdge::CallDirVF, csId);
706  if (edge != nullptr)
707  {
708  assert(edge->isCallDirectVFGEdge() && "this should be a direct value flow edge!");
709  return nullptr;
710  }
711  else
712  {
713  CallDirSVFGEdge* callEdge = new CallDirSVFGEdge(srcNode,dstNode,csId);
714  return (addVFGEdge(callEdge) ? callEdge : nullptr);
715  }
716 }
717 
722 {
723  VFGNode* srcNode = getVFGNode(srcId);
724  VFGNode* dstNode = getVFGNode(dstId);
725  VFGEdge* edge = hasInterVFGEdge(srcNode, dstNode, VFGEdge::RetDirVF, csId);
726  if (edge != nullptr)
727  {
728  assert(edge->isRetDirectVFGEdge() && "this should be a direct value flow edge!");
729  return nullptr;
730  }
731  else
732  {
733  RetDirSVFGEdge* retEdge = new RetDirSVFGEdge(srcNode,dstNode,csId);
734  return (addVFGEdge(retEdge) ? retEdge : nullptr);
735  }
736 }
737 
738 
743 {
744 
745  for(iterator it = begin(), eit = end(); it!=eit; ++it)
746  {
747  NodeID nodeId = it->first;
748  VFGNode* node = it->second;
749 
750  if(StmtVFGNode* stmtNode = SVFUtil::dyn_cast<StmtVFGNode>(node))
751  {
753  if(SVFUtil::isa<AddrVFGNode>(stmtNode))
754  continue;
756  if (stmtNode->getPAGSrcNode()->isConstDataOrAggDataButNotNullPtr() == false)
757  // for ptr vfg, we skip src node of integer type if it is at a int2ptr copystmt
758  if(isInterestedPAGNode(stmtNode->getPAGSrcNode()))
759  addIntraDirectVFEdge(getDef(stmtNode->getPAGSrcNode()), nodeId);
760  if (const GepStmt* gepStmt = SVFUtil::dyn_cast<GepStmt>(stmtNode->getPAGEdge()))
761  {
762  for (const auto &varType: gepStmt->getOffsetVarAndGepTypePairVec())
763  {
764  if(varType.first->isConstDataOrAggDataButNotNullPtr() || isInterestedPAGNode(varType.first) == false)
765  continue;
766  addIntraDirectVFEdge(getDef(varType.first), nodeId);
767  }
768  }
770  if(SVFUtil::isa<StoreVFGNode>(stmtNode) && (stmtNode->getPAGDstNode()->isConstDataOrAggDataButNotNullPtr() == false))
771  {
772  addIntraDirectVFEdge(getDef(stmtNode->getPAGDstNode()), nodeId);
773  }
774 
775  }
776  else if(PHIVFGNode* phiNode = SVFUtil::dyn_cast<PHIVFGNode>(node))
777  {
778  for (PHIVFGNode::OPVers::const_iterator it = phiNode->opVerBegin(), eit = phiNode->opVerEnd(); it != eit; it++)
779  {
780  if (it->second->isConstDataOrAggDataButNotNullPtr() == false)
781  addIntraDirectVFEdge(getDef(it->second), nodeId);
782  }
783  }
784  else if(BinaryOPVFGNode* binaryNode = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
785  {
786  for (BinaryOPVFGNode::OPVers::const_iterator it = binaryNode->opVerBegin(), eit = binaryNode->opVerEnd(); it != eit; it++)
787  {
788  if (it->second->isConstDataOrAggDataButNotNullPtr() == false)
789  addIntraDirectVFEdge(getDef(it->second), nodeId);
790  }
791  }
792  else if(UnaryOPVFGNode* unaryNode = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
793  {
794  for (UnaryOPVFGNode::OPVers::const_iterator it = unaryNode->opVerBegin(), eit = unaryNode->opVerEnd(); it != eit; it++)
795  {
796  if (it->second->isConstDataOrAggDataButNotNullPtr() == false)
797  addIntraDirectVFEdge(getDef(it->second), nodeId);
798  }
799  }
800  else if(CmpVFGNode* cmpNode = SVFUtil::dyn_cast<CmpVFGNode>(node))
801  {
802  for (CmpVFGNode::OPVers::const_iterator it = cmpNode->opVerBegin(), eit = cmpNode->opVerEnd(); it != eit; it++)
803  {
804  if (it->second->isConstDataOrAggDataButNotNullPtr() == false)
805  addIntraDirectVFEdge(getDef(it->second), nodeId);
806  }
807  }
808  else if(BranchVFGNode* branchNode = SVFUtil::dyn_cast<BranchVFGNode>(node))
809  {
810  const SVFVar* cond = branchNode->getBranchStmt()->getCondition();
811  if (cond->isConstDataOrAggDataButNotNullPtr() == false)
812  addIntraDirectVFEdge(getDef(cond), nodeId);
813  }
814  else if(ActualParmVFGNode* actualParm = SVFUtil::dyn_cast<ActualParmVFGNode>(node))
815  {
816  if (actualParm->getParam()->isConstDataOrAggDataButNotNullPtr() == false)
817  addIntraDirectVFEdge(getDef(actualParm->getParam()), nodeId);
818  }
819  else if(FormalParmVFGNode* formalParm = SVFUtil::dyn_cast<FormalParmVFGNode>(node))
820  {
821  for(CallPESet::const_iterator it = formalParm->callPEBegin(), eit = formalParm->callPEEnd();
822  it!=eit; ++it)
823  {
824  const CallICFGNode* cs = (*it)->getCallSite();
825  ActualParmVFGNode* acutalParm = getActualParmVFGNode((*it)->getRHSVar(),cs);
826  addInterEdgeFromAPToFP(acutalParm,formalParm,getCallSiteID(cs, formalParm->getFun()));
827  }
828  }
829  else if(FormalRetVFGNode* calleeRet = SVFUtil::dyn_cast<FormalRetVFGNode>(node))
830  {
832  addIntraDirectVFEdge(getDef(calleeRet->getRet()), nodeId);
833 
835  for(RetPESet::const_iterator it = calleeRet->retPEBegin(), eit = calleeRet->retPEEnd(); it!=eit; ++it)
836  {
837  ActualRetVFGNode* callsiteRev = getActualRetVFGNode((*it)->getLHSVar());
838  const CallICFGNode* callBlockNode = (*it)->getCallSite();
839  addInterEdgeFromFRToAR(calleeRet,callsiteRev, getCallSiteID(callBlockNode, calleeRet->getFun()));
840  }
841  }
844  }
845 
848  {
851  for (SVFStmt::SVFStmtSetTy::iterator iter = forks.begin(), eiter =
852  forks.end(); iter != eiter; ++iter)
853  {
854  TDForkPE* forkedge = SVFUtil::cast<TDForkPE>(*iter);
855  ActualParmVFGNode* acutalParm = getActualParmVFGNode(forkedge->getRHSVar(),forkedge->getCallSite());
856  FormalParmVFGNode* formalParm = getFormalParmVFGNode(forkedge->getLHSVar());
857  addInterEdgeFromAPToFP(acutalParm,formalParm,getCallSiteID(forkedge->getCallSite(), formalParm->getFun()));
858  }
861  for (SVFStmt::SVFStmtSetTy::iterator iter = joins.begin(), eiter =
862  joins.end(); iter != eiter; ++iter)
863  {
864  TDJoinPE* joinedge = SVFUtil::cast<TDJoinPE>(*iter);
865  NodeID callsiteRev = getDef(joinedge->getLHSVar());
866  FormalRetVFGNode* calleeRet = getFormalRetVFGNode(joinedge->getRHSVar());
867  addRetEdge(calleeRet->getId(),callsiteRev, getCallSiteID(joinedge->getCallSite(), calleeRet->getFun()));
868  }
869  }
870 }
871 
876 {
877  VFGEdge edge(src,dst,kind);
878  VFGEdge* outEdge = src->hasOutgoingEdge(&edge);
879  VFGEdge* inEdge = dst->hasIncomingEdge(&edge);
880  if (outEdge && inEdge)
881  {
882  assert(outEdge == inEdge && "edges not match");
883  return outEdge;
884  }
885  else
886  return nullptr;
887 }
888 
889 
894 {
895  VFGEdge edge(src,dst,kind);
896  VFGEdge* outEdge = src->hasOutgoingEdge(&edge);
897  VFGEdge* inEdge = dst->hasIncomingEdge(&edge);
898  if (outEdge && inEdge)
899  {
900  assert(outEdge == inEdge && "edges not match");
901  return outEdge;
902  }
903  else
904  return nullptr;
905 }
906 
911 {
912  VFGEdge edge(src,dst,VFGEdge::makeEdgeFlagWithInvokeID(kind,csId));
913  VFGEdge* outEdge = src->hasOutgoingEdge(&edge);
914  VFGEdge* inEdge = dst->hasIncomingEdge(&edge);
915  if (outEdge && inEdge)
916  {
917  assert(outEdge == inEdge && "edges not match");
918  return outEdge;
919  }
920  else
921  return nullptr;
922 }
923 
924 
929 {
930  return hasIntraVFGEdge(const_cast<VFGNode*>(src),const_cast<VFGNode*>(dst),kind);
931 }
932 
933 
937 void VFG::dump(const std::string& file, bool simple)
938 {
939  GraphPrinter::WriteGraphToFile(outs(), file, this, simple);
940 }
941 
945 void VFG::view()
946 {
947  SVF::ViewGraph(this, "Value Flow Graph");
948 }
949 
950 
952 {
953  VFGEdgeSetTy vfEdgesAtIndCallSite;
954  PointerAnalysis::CallEdgeMap::const_iterator iter = pta->getIndCallMap().begin();
955  PointerAnalysis::CallEdgeMap::const_iterator eiter = pta->getIndCallMap().end();
956  for (; iter != eiter; iter++)
957  {
958  const CallICFGNode* newcs = iter->first;
959  assert(newcs->isIndirectCall() && "this is not an indirect call?");
960  const PointerAnalysis::FunctionSet & functions = iter->second;
961  for (PointerAnalysis::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
962  {
963  const SVFFunction* func = *func_iter;
964  connectCallerAndCallee(newcs, func, vfEdgesAtIndCallSite);
965  }
966  }
967 }
968 
973 void VFG::connectCallerAndCallee(const CallICFGNode* callBlockNode, const SVFFunction* callee, VFGEdgeSetTy& edges)
974 {
975  SVFIR * pag = SVFIR::getPAG();
976  CallSiteID csId = getCallSiteID(callBlockNode, callee);
977  const RetICFGNode* retBlockNode = callBlockNode->getRetICFGNode();
978  // connect actual and formal param
979  if (pag->hasCallSiteArgsMap(callBlockNode) && pag->hasFunArgsList(callee) &&
980  matchArgs(callBlockNode, callee))
981  {
982  const SVFIR::SVFVarList& csArgList = pag->getCallSiteArgsList(callBlockNode);
983  const SVFIR::SVFVarList& funArgList = pag->getFunArgsList(callee);
984  SVFIR::SVFVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end();
985  SVFIR::SVFVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end();
986  for (; funArgIt != funArgEit && csArgIt != csArgEit; funArgIt++, csArgIt++)
987  {
988  const PAGNode *cs_arg = *csArgIt;
989  const PAGNode *fun_arg = *funArgIt;
990  if (isInterestedPAGNode(cs_arg) && isInterestedPAGNode(fun_arg))
991  connectAParamAndFParam(cs_arg, fun_arg, callBlockNode, csId, edges);
992  }
993  assert(funArgIt == funArgEit && "function has more arguments than call site");
994 
995  if (callee->isVarArg())
996  {
997  NodeID varFunArg = pag->getVarargNode(callee);
998  const PAGNode* varFunArgNode = pag->getGNode(varFunArg);
999  if (isInterestedPAGNode(varFunArgNode))
1000  {
1001  for (; csArgIt != csArgEit; csArgIt++)
1002  {
1003  const PAGNode *cs_arg = *csArgIt;
1004  if (isInterestedPAGNode(cs_arg))
1005  connectAParamAndFParam(cs_arg, varFunArgNode, callBlockNode, csId, edges);
1006  }
1007  }
1008  }
1009  }
1010 
1011  // connect actual return and formal return
1012  if (pag->funHasRet(callee) && pag->callsiteHasRet(retBlockNode))
1013  {
1014  const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode);
1015  const PAGNode* fun_return = pag->getFunRet(callee);
1016  if (isInterestedPAGNode(cs_return) && isInterestedPAGNode(fun_return))
1017  connectFRetAndARet(fun_return, cs_return, csId, edges);
1018  }
1019 }
1020 
1024 const PAGNode* VFG::getLHSTopLevPtr(const VFGNode* node) const
1025 {
1026 
1027  if(const AddrVFGNode* addr = SVFUtil::dyn_cast<AddrVFGNode>(node))
1028  return addr->getPAGDstNode();
1029  else if(const CopyVFGNode* copy = SVFUtil::dyn_cast<CopyVFGNode>(node))
1030  return copy->getPAGDstNode();
1031  else if(const GepVFGNode* gep = SVFUtil::dyn_cast<GepVFGNode>(node))
1032  return gep->getPAGDstNode();
1033  else if(const LoadVFGNode* load = SVFUtil::dyn_cast<LoadVFGNode>(node))
1034  return load->getPAGDstNode();
1035  else if(const PHIVFGNode* phi = SVFUtil::dyn_cast<PHIVFGNode>(node))
1036  return phi->getRes();
1037  else if(const CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
1038  return cmp->getRes();
1039  else if(const BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
1040  return bop->getRes();
1041  else if(const UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
1042  return uop->getRes();
1043  else if(const ActualParmVFGNode* ap = SVFUtil::dyn_cast<ActualParmVFGNode>(node))
1044  return ap->getParam();
1045  else if(const FormalParmVFGNode*fp = SVFUtil::dyn_cast<FormalParmVFGNode>(node))
1046  return fp->getParam();
1047  else if(const ActualRetVFGNode* ar = SVFUtil::dyn_cast<ActualRetVFGNode>(node))
1048  return ar->getRev();
1049  else if(const FormalRetVFGNode* fr = SVFUtil::dyn_cast<FormalRetVFGNode>(node))
1050  return fr->getRet();
1051  else if(const NullPtrVFGNode* nullVFG = SVFUtil::dyn_cast<NullPtrVFGNode>(node))
1052  return nullVFG->getPAGNode();
1053  else
1054  assert(false && "unexpected node kind!");
1055  return nullptr;
1056 }
1057 
1061 const SVFFunction* VFG::isFunEntryVFGNode(const VFGNode* node) const
1062 {
1063  if(const FormalParmVFGNode* fp = SVFUtil::dyn_cast<FormalParmVFGNode>(node))
1064  {
1065  return fp->getFun();
1066  }
1067  else if(const InterPHIVFGNode* phi = SVFUtil::dyn_cast<InterPHIVFGNode>(node))
1068  {
1069  if(phi->isFormalParmPHI())
1070  return phi->getFun();
1071  }
1072  return nullptr;
1073 }
1074 
1075 
1077 {
1078  return getPAGEdge()->getValue();
1079 }
1080 
1082 {
1083  return getRes()->getValue();
1084 }
1085 
1087 {
1088  return getRes()->getValue();
1089 }
1090 
1092 {
1093  return getRes()->getValue();
1094 }
1095 
1097 {
1098  return param->hasValue() ? param->getValue() : nullptr;
1099 }
1100 
1104 namespace SVF
1105 {
1106 template<>
1108 {
1109 
1111  DOTGraphTraits(bool isSimple = false) :
1112  DOTGraphTraits<SVFIR*>(isSimple)
1113  {
1114  }
1115 
1118  {
1119  return "VFG";
1120  }
1121 
1123  {
1124  if (isSimple())
1125  return getSimpleNodeLabel(node, graph);
1126  else
1127  return getCompleteNodeLabel(node, graph);
1128  }
1129 
1132  {
1133  std::string str;
1134  std::stringstream rawstr(str);
1135  if(StmtVFGNode* stmtNode = SVFUtil::dyn_cast<StmtVFGNode>(node))
1136  {
1137  rawstr << stmtNode->toString();
1138  }
1139  else if(PHIVFGNode* tphi = SVFUtil::dyn_cast<PHIVFGNode>(node))
1140  {
1141  rawstr << tphi->toString();
1142  }
1143  else if(FormalParmVFGNode* fp = SVFUtil::dyn_cast<FormalParmVFGNode>(node))
1144  {
1145  rawstr << fp->toString();
1146  }
1147  else if(ActualParmVFGNode* ap = SVFUtil::dyn_cast<ActualParmVFGNode>(node))
1148  {
1149  rawstr << ap->toString();
1150  }
1151  else if (ActualRetVFGNode* ar = SVFUtil::dyn_cast<ActualRetVFGNode>(node))
1152  {
1153  rawstr << ar->toString();
1154  }
1155  else if (FormalRetVFGNode* fr = SVFUtil::dyn_cast<FormalRetVFGNode>(node))
1156  {
1157  rawstr << fr->toString();
1158  }
1159  else if(SVFUtil::isa<NullPtrVFGNode>(node))
1160  {
1161  rawstr << "NullPtr";
1162  }
1163  else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
1164  {
1165  rawstr << bop->toString();
1166  }
1167  else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
1168  {
1169  rawstr << uop->toString();
1170  }
1171  else if(CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
1172  {
1173  rawstr << cmp->toString();;
1174  }
1175  else if (BranchVFGNode* branchNode = SVFUtil::dyn_cast<BranchVFGNode>(node))
1176  {
1177  rawstr << branchNode->toString();
1178  }
1179  else
1180  assert(false && "what else kinds of nodes do we have??");
1181 
1182  return rawstr.str();
1183  }
1184 
1187  {
1188 
1189  std::string str;
1190  std::stringstream rawstr(str);
1191  if(StmtVFGNode* stmtNode = SVFUtil::dyn_cast<StmtVFGNode>(node))
1192  {
1193  rawstr << stmtNode->toString();
1194  }
1195  else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
1196  {
1197  rawstr << bop->toString();
1198  }
1199  else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
1200  {
1201  rawstr << uop->toString();
1202  }
1203  else if(CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
1204  {
1205  rawstr << cmp->toString();
1206  }
1207  else if(PHIVFGNode* phi = SVFUtil::dyn_cast<PHIVFGNode>(node))
1208  {
1209  rawstr << phi->toString();
1210  }
1211  else if(FormalParmVFGNode* fp = SVFUtil::dyn_cast<FormalParmVFGNode>(node))
1212  {
1213  rawstr << fp->toString();
1214  }
1215  else if(ActualParmVFGNode* ap = SVFUtil::dyn_cast<ActualParmVFGNode>(node))
1216  {
1217  rawstr << ap->toString();
1218  }
1219  else if(NullPtrVFGNode* nptr = SVFUtil::dyn_cast<NullPtrVFGNode>(node))
1220  {
1221  rawstr << nptr->toString();
1222  }
1223  else if (ActualRetVFGNode* ar = SVFUtil::dyn_cast<ActualRetVFGNode>(node))
1224  {
1225  rawstr << ar->toString();
1226  }
1227  else if (FormalRetVFGNode* fr = SVFUtil::dyn_cast<FormalRetVFGNode>(node))
1228  {
1229  rawstr << fr->toString();
1230  }
1231  else if (MRSVFGNode* mr = SVFUtil::dyn_cast<MRSVFGNode>(node))
1232  {
1233  rawstr << mr->toString();
1234  }
1235  else if (BranchVFGNode* branchNode = SVFUtil::dyn_cast<BranchVFGNode>(node))
1236  {
1237  rawstr << branchNode->toString();
1238  }
1239  else
1240  assert(false && "what else kinds of nodes do we have??");
1241 
1242  return rawstr.str();
1243  }
1244 
1246  {
1247  std::string str;
1248  std::stringstream rawstr(str);
1249 
1250  if(StmtVFGNode* stmtNode = SVFUtil::dyn_cast<StmtVFGNode>(node))
1251  {
1252  const PAGEdge* edge = stmtNode->getPAGEdge();
1253  if (SVFUtil::isa<AddrStmt>(edge))
1254  {
1255  rawstr << "color=green";
1256  }
1257  else if (SVFUtil::isa<CopyStmt>(edge))
1258  {
1259  rawstr << "color=black";
1260  }
1261  else if (SVFUtil::isa<RetPE>(edge))
1262  {
1263  rawstr << "color=black,style=dotted";
1264  }
1265  else if (SVFUtil::isa<GepStmt>(edge))
1266  {
1267  rawstr << "color=purple";
1268  }
1269  else if (SVFUtil::isa<StoreStmt>(edge))
1270  {
1271  rawstr << "color=blue";
1272  }
1273  else if (SVFUtil::isa<LoadStmt>(edge))
1274  {
1275  rawstr << "color=red";
1276  }
1277  else
1278  {
1279  assert(0 && "No such kind edge!!");
1280  }
1281  rawstr << "";
1282  }
1283  else if (SVFUtil::isa<CmpVFGNode>(node))
1284  {
1285  rawstr << "color=grey";
1286  }
1287  else if (SVFUtil::isa<BinaryOPVFGNode>(node))
1288  {
1289  rawstr << "color=grey";
1290  }
1291  else if (SVFUtil::isa<UnaryOPVFGNode>(node))
1292  {
1293  rawstr << "color=grey";
1294  }
1295  else if(SVFUtil::isa<PHIVFGNode>(node))
1296  {
1297  rawstr << "color=black";
1298  }
1299  else if(SVFUtil::isa<NullPtrVFGNode>(node))
1300  {
1301  rawstr << "color=grey";
1302  }
1303  else if(SVFUtil::isa<FormalParmVFGNode>(node))
1304  {
1305  rawstr << "color=yellow,penwidth=2";
1306  }
1307  else if(SVFUtil::isa<ActualParmVFGNode>(node))
1308  {
1309  rawstr << "color=yellow,penwidth=2";
1310  }
1311  else if (SVFUtil::isa<ActualRetVFGNode>(node))
1312  {
1313  rawstr << "color=yellow,penwidth=2";
1314  }
1315  else if (SVFUtil::isa<FormalRetVFGNode>(node))
1316  {
1317  rawstr << "color=yellow,penwidth=2";
1318  }
1319  else if (SVFUtil::isa<MRSVFGNode>(node))
1320  {
1321  rawstr << "color=orange,penwidth=2";
1322  }
1323  else if (SVFUtil::isa<BranchVFGNode>(node))
1324  {
1325  rawstr << "color=gold,penwidth=2";
1326  }
1327  else
1328  assert(false && "no such kind of node!!");
1329 
1330  rawstr << "";
1331 
1332  return rawstr.str();
1333  }
1334 
1335  template<class EdgeIter>
1336  static std::string getEdgeAttributes(NodeType*, EdgeIter EI, VFG*)
1337  {
1338  VFGEdge* edge = *(EI.getCurrent());
1339  assert(edge && "No edge found!!");
1340  if (SVFUtil::isa<DirectSVFGEdge>(edge))
1341  {
1342  if (SVFUtil::isa<CallDirSVFGEdge>(edge))
1343  return "style=solid,color=red";
1344  else if (SVFUtil::isa<RetDirSVFGEdge>(edge))
1345  return "style=solid,color=blue";
1346  else
1347  return "style=solid";
1348  }
1349  else if (SVFUtil::isa<IndirectSVFGEdge>(edge))
1350  {
1351  if (SVFUtil::isa<CallIndSVFGEdge>(edge))
1352  return "style=dashed,color=red";
1353  else if (SVFUtil::isa<RetIndSVFGEdge>(edge))
1354  return "style=dashed,color=blue";
1355  else
1356  return "style=dashed";
1357  }
1358  else
1359  {
1360  assert(false && "what else edge we have?");
1361  }
1362  return "";
1363  }
1364 
1365  template<class EdgeIter>
1367  {
1368  VFGEdge* edge = *(EI.getCurrent());
1369  assert(edge && "No edge found!!");
1370 
1371  std::string str;
1372  std::stringstream rawstr(str);
1373  if (CallDirSVFGEdge* dirCall = SVFUtil::dyn_cast<CallDirSVFGEdge>(edge))
1374  rawstr << dirCall->getCallSiteId();
1375  else if (RetDirSVFGEdge* dirRet = SVFUtil::dyn_cast<RetDirSVFGEdge>(edge))
1376  rawstr << dirRet->getCallSiteId();
1377 
1378  return rawstr.str();
1379  }
1380 };
1381 } // End namespace llvm
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition: SVFType.h:484
#define DGENERAL
Definition: SVFType.h:490
copy
Definition: cJSON.cpp:414
cJSON * n
Definition: cJSON.cpp:2558
const char *const string
Definition: cJSON.h:172
const std::string toString() const override
Definition: VFG.cpp:288
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: VFG.cpp:281
const std::string toString() const override
Definition: VFG.cpp:322
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: VFG.cpp:315
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: VFG.cpp:255
const std::string toString() const override
Definition: VFG.cpp:262
const std::string toString() const override
Definition: VFG.cpp:272
const SVFValue * getValue() const override
Return the corresponding LLVM value, if possible, nullptr otherwise.
Definition: VFG.cpp:1096
const PAGNode * param
Definition: VFGNode.h:848
SVFVar * getLHSVar() const
SVFVar * getRHSVar() const
const SVFValue * getValue() const override
Return the corresponding LLVM value, if possible, nullptr otherwise.
Definition: VFG.cpp:1086
const PAGNode * getRes() const
Definition: VFGNode.h:459
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: VFG.cpp:135
const std::string toString() const override
Definition: VFG.cpp:142
const SVFVar * getBranchInst() const
virtual const std::string toString() const override
Definition: VFG.cpp:188
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: VFG.cpp:183
virtual const std::string toString() const
Definition: VFG.cpp:403
bool isIndirectCall() const
Return true if this is an indirect call.
Definition: ICFGNode.h:482
const RetICFGNode * getRetICFGNode() const
Return callsite.
Definition: ICFGNode.h:457
const CallICFGNode * getCallSite() const
const SVFValue * getValue() const override
Return the corresponding LLVM value, if possible, nullptr otherwise.
Definition: VFG.cpp:1081
const std::string toString() const override
Definition: VFG.cpp:118
const PAGNode * getRes() const
Definition: VFGNode.h:384
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: VFG.cpp:111
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: VFG.cpp:95
const std::string toString() const override
Definition: VFG.cpp:102
virtual const std::string toString() const
Definition: VFG.cpp:387
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: VFG.cpp:298
const std::string toString() const override
Definition: VFG.cpp:305
const SVFFunction * getFun() const override
Return function.
Definition: VFGNode.h:965
FormalRetVFGNode()
place holder
const SVFFunction * getFun() const override
Function.
Definition: VFGNode.h:1100
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: VFG.cpp:333
const std::string toString() const override
Definition: VFG.cpp:340
iterator begin()
Iterators.
Definition: GenericGraph.h:627
NodeType * getGNode(NodeID id) const
Get a node.
Definition: GenericGraph.h:653
IDToNodeMapTy::iterator iterator
Node Iterators.
Definition: GenericGraph.h:606
bool hasIncomingEdge() const
Has incoming/outgoing edge set.
Definition: GenericGraph.h:442
bool hasOutgoingEdge() const
Definition: GenericGraph.h:446
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: VFG.cpp:197
const std::string toString() const override
Definition: VFG.cpp:204
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType &GT, bool simple=false)
Definition: GraphPrinter.h:56
virtual const SVFFunction * getFun() const
Return the function of this ICFGNode.
Definition: ICFGNode.h:76
NodeID getNullPtr() const
Definition: IRGraph.h:173
NodeID getVarargNode(const SVFFunction *func) const
getVarargNode - Return the unique node representing the variadic argument of a variadic function.
Definition: IRGraph.h:157
const std::string toString() const override
Definition: VFG.cpp:351
virtual const std::string toString() const
Definition: VFG.cpp:395
const std::string toString() const override
Definition: VFG.cpp:238
const std::string toString() const override
Definition: VFG.cpp:64
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: VFG.cpp:57
const SVFVar * getRes() const
Result SVFVar.
const std::string toString() const override
Definition: VFG.cpp:369
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: VFG.cpp:362
static const Option< bool > EnableThreadCallGraph
Definition: Options.h:132
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: VFG.cpp:213
const std::string toString() const override
Definition: VFG.cpp:220
const PAGNode * getRes() const
Definition: VFGNode.h:699
PHIVFGNode(NodeID id, const PAGNode *r, VFGNodeK k=TPhi)
Constructor.
Definition: VFG.cpp:428
const SVFValue * getValue() const override
Return the corresponding LLVM value, if possible, nullptr otherwise.
Definition: VFG.cpp:1091
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
Set< const SVFFunction * > FunctionSet
virtual const std::string toString() const
Definition: VFG.cpp:412
const CallICFGNode * getCallSite() const
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
bool isVarArg() const
Definition: SVFValue.cpp:181
const SVFVarList & getCallSiteArgsList(const CallICFGNode *cs) const
Get callsite argument list.
Definition: SVFIR.h:292
const SVFVar * getCallSiteRet(const RetICFGNode *cs) const
Get callsite return.
Definition: SVFIR.h:304
CSToArgsListMap & getCallSiteArgsMap()
Get callsite argument list.
Definition: SVFIR.h:287
const SVFVar * getFunRet(const SVFFunction *func) const
Get function return list.
Definition: SVFIR.h:320
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115
FunToArgsListMap & getFunArgsMap()
Get function arguments list.
Definition: SVFIR.h:270
std::vector< const SVFVar * > SVFVarList
Definition: SVFIR.h:59
CSToRetMap & getCallSiteRets()
Get callsite return.
Definition: SVFIR.h:299
bool hasCallSiteArgsMap(const CallICFGNode *cs) const
Callsite has argument list.
Definition: SVFIR.h:282
const SVFVarList & getFunArgsList(const SVFFunction *func) const
Get function arguments list.
Definition: SVFIR.h:275
bool callsiteHasRet(const RetICFGNode *cs) const
Definition: SVFIR.h:310
FunToRetMap & getFunRets()
Get function return list.
Definition: SVFIR.h:315
bool hasFunArgsList(const SVFFunction *func) const
Function has arguments list.
Definition: SVFIR.h:265
bool funHasRet(const SVFFunction *func) const
Definition: SVFIR.h:326
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
const SVFValue * getValue() const
bool isConstDataOrAggDataButNotNullPtr() const
bool hasValue() const
Definition: SVFVariables.h:101
bool hasIncomingEdges(SVFStmt::PEDGEK kind) const
Has incoming SVFIR statements (edges)
Definition: SVFVariables.h:147
SVFStmt::SVFStmtSetTy::iterator getIncomingEdgesBegin(SVFStmt::PEDGEK kind) const
Get incoming SVFStmt iterator.
Definition: SVFVariables.h:166
bool hasOutgoingEdges(SVFStmt::PEDGEK kind) const
Has outgoing SVFIR statements (edges)
Definition: SVFVariables.h:156
SVFStmt::SVFStmtSetTy::iterator getOutgoingEdgesBegin(SVFStmt::PEDGEK kind) const
Get outgoing SVFStmt iterator.
Definition: SVFVariables.h:182
SVFStmt::SVFStmtSetTy::iterator getOutgoingEdgesEnd(SVFStmt::PEDGEK kind) const
Get outgoing SVFStmt iterator.
Definition: SVFVariables.h:190
const SVFValue * getValue() const
Get/has methods of the components.
Definition: SVFVariables.h:83
SVFStmt::SVFStmtSetTy::iterator getIncomingEdgesEnd(SVFStmt::PEDGEK kind) const
Get incoming SVFStmt iterator.
Definition: SVFVariables.h:174
void set(unsigned Idx)
const PAGEdge * getPAGEdge() const
Definition: VFGNode.h:147
const SVFValue * getValue() const override
Return the corresponding LLVM value, if possible, nullptr otherwise.
Definition: VFG.cpp:1076
const std::string toString() const override
Definition: VFG.cpp:48
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: VFG.cpp:73
const std::string toString() const override
Definition: VFG.cpp:86
const SVFVar * getRes() const
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: VFG.cpp:159
virtual const std::string toString() const override
Definition: VFG.cpp:166
@ IntraDirectVF
Definition: VFGEdge.h:53
static GEdgeFlag makeEdgeFlagWithInvokeID(GEdgeKind k, CallSiteID cs)
Compute the unique edgeFlag value from edge kind and CallSiteID.
Definition: VFGEdge.h:120
bool isRetDirectVFGEdge() const
Definition: VFGEdge.h:96
bool isDirectVFGEdge() const
Get methods of the components.
Definition: VFGEdge.h:76
virtual const std::string toString() const
Definition: VFG.cpp:379
bool isCallDirectVFGEdge() const
Definition: VFGEdge.h:92
virtual const std::string toString() const
Definition: VFG.cpp:40
Definition: VFG.h:51
ActualRetVFGNode * getActualRetVFGNode(const PAGNode *aret) const
Definition: VFG.h:241
VFGEdge::VFGEdgeSetTy VFGEdgeSetTy
Definition: VFG.h:77
void updateCallGraph(PointerAnalysis *pta)
Update VFG based on pointer analysis results.
Definition: VFG.cpp:951
void addStoreVFGNode(const StoreStmt *store)
Definition: VFG.h:521
void addBranchVFGNode(const BranchStmt *edge)
Add a BranchVFGNode.
Definition: VFG.h:630
const PAGNode * getLHSTopLevPtr(const VFGNode *node) const
Definition: VFG.cpp:1024
SVFIR * pag
Definition: VFG.h:104
VFGEdge * addRetEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
Definition: VFG.cpp:721
virtual void connectAParamAndFParam(const PAGNode *csArg, const PAGNode *funArg, const CallICFGNode *cbn, CallSiteID csId, VFGEdgeSetTy &edges)
Connect VFG nodes between caller and callee for indirect call site.
Definition: VFG.h:386
virtual SVFStmt::SVFStmtSetTy & getPAGEdgeSet(SVFStmt::PEDGEK kind)
Get PAGEdge set.
Definition: VFG.h:436
void addVFGNodes()
Create VFG nodes.
Definition: VFG.cpp:463
void addLoadVFGNode(const LoadStmt *load)
Add a Load VFG node.
Definition: VFG.h:513
VFGK kind
Definition: VFG.h:105
VFGEdge * addIntraDirectVFEdge(NodeID srcId, NodeID dstId)
Definition: VFG.cpp:675
void checkIntraEdgeParents(const VFGNode *srcNode, const VFGNode *dstNode)
sanitize Intra edges, verify that both nodes belong to the same function.
Definition: VFG.h:351
void addCopyVFGNode(const CopyStmt *copy)
Add a Copy VFG node.
Definition: VFG.h:499
void addGepVFGNode(const GepStmt *gep)
Add a Gep VFG node.
Definition: VFG.h:506
void addNullPtrVFGNode(const PAGNode *pagNode)
Definition: VFG.h:485
CallSiteID getCallSiteID(const CallICFGNode *cs, const SVFFunction *func) const
Get callsite given a callsiteID.
Definition: VFG.h:178
void addActualRetVFGNode(const PAGNode *ret, const CallICFGNode *cs)
Add a callsite Receive VFG node.
Definition: VFG.h:571
void addUnaryOPVFGNode(const UnaryOPStmt *edge)
Add a UnaryOperator VFG node.
Definition: VFG.h:621
void addActualParmVFGNode(const PAGNode *aparm, const CallICFGNode *cs)
Definition: VFG.h:530
ActualParmVFGNode * getActualParmVFGNode(const PAGNode *aparm, const CallICFGNode *cs) const
Definition: VFG.h:235
void addCmpVFGNode(const CmpStmt *edge)
Add a Compare VFG node.
Definition: VFG.h:593
VFGEdge * addInterEdgeFromAPToFP(ActualParmVFGNode *src, FormalParmVFGNode *dst, CallSiteID csId)
Add inter VF edge from actual to formal parameters.
Definition: VFG.h:362
NodeID getDef(const PAGNode *pagNode) const
Definition: VFG.h:420
FormalParmVFGNode * getFormalParmVFGNode(const PAGNode *fparm) const
Definition: VFG.h:247
bool addVFGEdge(VFGEdge *edge)
Add VFG edge.
Definition: VFG.h:339
virtual bool isInterestedPAGNode(const SVFVar *node) const
Definition: VFG.h:444
bool hasBlackHoleConstObjAddrAsDef(const PAGNode *pagNode) const
Whether a PAGNode has a blackhole or const object as its definition.
Definition: VFG.h:265
const SVFFunction * isFunEntryVFGNode(const VFGNode *node) const
Whether a node is function entry VFGNode.
Definition: VFG.cpp:1061
VFG(PTACallGraph *callgraph, VFGK k=FULLSVFG)
Constructor.
Definition: VFG.cpp:441
bool isPhiCopyEdge(const PAGEdge *copy) const
Definition: VFG.h:458
VFGNode * getVFGNode(NodeID id) const
Get a VFG node.
Definition: VFG.h:145
VFGEdge * addCallEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
Definition: VFG.cpp:701
virtual void connectCallerAndCallee(const CallICFGNode *cs, const SVFFunction *callee, VFGEdgeSetTy &edges)
Connect VFG nodes between caller and callee for indirect call site.
Definition: VFG.cpp:973
void addFormalRetVFGNode(const PAGNode *uniqueFunRet, const SVFFunction *fun, RetPESet &retPEs)
Definition: VFG.h:552
virtual void connectFRetAndARet(const PAGNode *funReturn, const PAGNode *csReturn, CallSiteID csId, VFGEdgeSetTy &edges)
Connect formal-ret and actual ret.
Definition: VFG.h:395
bool hasDef(const PAGNode *pagNode) const
Definition: VFG.h:426
FormalRetVFGNode * getFormalRetVFGNode(const PAGNode *fret) const
Definition: VFG.h:253
VFGEdge * addInterEdgeFromFRToAR(FormalRetVFGNode *src, ActualRetVFGNode *dst, CallSiteID csId)
Add inter VF edge from callee return to callsite receive parameter.
Definition: VFG.h:367
FormalRetVFGNode::RetPESet RetPESet
Definition: VFG.h:76
VFGK
VFG kind.
Definition: VFG.h:56
VFGEdge * hasIntraVFGEdge(VFGNode *src, VFGNode *dst, VFGEdge::VFGEdgeK kind)
Whether we has a SVFG edge.
Definition: VFG.cpp:875
void addBinaryOPVFGNode(const BinaryOPStmt *edge)
Add a BinaryOperator VFG node.
Definition: VFG.h:607
void addAddrVFGNode(const AddrStmt *addr)
Add an Address VFG node.
Definition: VFG.h:492
VFGEdge * hasInterVFGEdge(VFGNode *src, VFGNode *dst, VFGEdge::VFGEdgeK kind, CallSiteID csId)
Definition: VFG.cpp:910
FormalParmVFGNode::CallPESet CallPESet
Definition: VFG.h:75
void connectDirectVFGEdges()
Create edges between VFG nodes within a function.
Definition: VFG.cpp:742
VFGEdge * getIntraVFGEdge(const VFGNode *src, const VFGNode *dst, VFGEdge::VFGEdgeK kind)
Get a SVFG edge according to src and dst.
Definition: VFG.cpp:928
void view()
Dump graph into dot file.
Definition: VFG.cpp:945
VFGEdge * hasThreadVFGEdge(VFGNode *src, VFGNode *dst, VFGEdge::VFGEdgeK kind)
Definition: VFG.cpp:893
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
Definition: VFG.cpp:937
void destroy()
Clean up memory.
Definition: VFG.cpp:454
void addIntraPHIVFGNode(const MultiOpndStmt *edge)
Add an llvm PHI VFG node.
Definition: VFG.h:579
void addFormalParmVFGNode(const PAGNode *fparm, const SVFFunction *fun, CallPESet &callPEs)
Add a formal parameter VFG node.
Definition: VFG.h:538
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition: SVFUtil.cpp:99
bool matchArgs(const CallICFGNode *cs, const SVFFunction *callee)
Definition: SVFUtil.cpp:320
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
unsigned CallSiteID
Definition: GeneralType.h:58
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
SparseBitVector NodeBS
Definition: GeneralType.h:62
static std::string getCompleteNodeLabel(NodeType *node, VFG *)
Return label of a VFG node with MemSSA information.
Definition: VFG.cpp:1186
static std::string getNodeAttributes(NodeType *node, VFG *)
Definition: VFG.cpp:1245
static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
Definition: VFG.cpp:1366
DOTGraphTraits(bool isSimple=false)
Definition: VFG.cpp:1111
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, VFG *)
Definition: VFG.cpp:1336
std::string getNodeLabel(NodeType *node, VFG *graph)
Definition: VFG.cpp:1122
static std::string getSimpleNodeLabel(NodeType *node, VFG *)
Return label of a VFG node without MemSSA information.
Definition: VFG.cpp:1131
static std::string getGraphName(VFG *)
Return name of the graph.
Definition: VFG.cpp:1117