Static Value-Flow Analysis
SVFG.cpp
Go to the documentation of this file.
1 //===- SVFG.cpp -- Sparse value-flow 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  * SVFG.cpp
25  *
26  * Created on: Oct 28, 2013
27  * Author: Yulei Sui
28  */
29 
30 #include "SVFIR/SVFModule.h"
31 #include "Util/SVFUtil.h"
32 #include "Graphs/SVFG.h"
33 #include "Graphs/SVFGOPT.h"
34 #include "Graphs/SVFGStat.h"
35 #include "Graphs/ICFG.h"
36 #include "Util/Options.h"
38 #include <fstream>
39 #include "Util/Options.h"
40 
41 using namespace SVF;
42 using namespace SVFUtil;
43 
45 {
46  return getPointsTo();
47 }
48 
50 {
51  std::string str;
52  std::stringstream rawstr(str);
53  rawstr << "MRSVFGNode ID: " << getId();
54  return rawstr.str();
55 }
56 
58 {
59  std::string str;
60  std::stringstream rawstr(str);
61  rawstr << "FormalINSVFGNode ID: " << getId() << " {fun: " << getFun()->getName() << "}";
62  rawstr << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() <<
63  " = ENCHI(MR_" << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << ")\n";
64  rawstr << getMRVer()->getMR()->dumpStr() << "\n";
65  return rawstr.str();
66 }
67 
69 {
70  std::string str;
71  std::stringstream rawstr(str);
72  rawstr << "FormalOUTSVFGNode ID: " << getId() << " {fun: " << getFun()->getName() << "}";
73  rawstr << "RETMU(" << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << ")\n";
74  rawstr << getMRVer()->getMR()->dumpStr() << "\n";
75  return rawstr.str();
76 }
77 
79 {
80  std::string str;
81  std::stringstream rawstr(str);
82  rawstr << "ActualINSVFGNode ID: " << getId() << " at callsite: " << (getCallSite())->valueOnlyToString() << " {fun: " << getFun()->getName() << "}";
83  rawstr << "CSMU(" << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << ")\n";
84  rawstr << getMRVer()->getMR()->dumpStr() << "\n";
85  rawstr << "CS[" << getCallSite()->getSourceLoc() << "]";
86  return rawstr.str();
87 }
88 
90 {
91  std::string str;
92  std::stringstream rawstr(str);
93  rawstr << "ActualOUTSVFGNode ID: " << getId() << " at callsite: " << (getCallSite())->valueOnlyToString() << " {fun: " << getFun()->getName() << "}";
94  rawstr << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() <<
95  " = CSCHI(MR_" << getMRVer()->getMR()->getMRID() << "V_" << getMRVer()->getSSAVersion() << ")\n";
96  rawstr << getMRVer()->getMR()->dumpStr() << "\n";
97  rawstr << "CS[" << getCallSite()->getSourceLoc() << "]" ;
98  return rawstr.str();
99 }
100 
102 {
103  std::string str;
104  std::stringstream rawstr(str);
105  rawstr << "MSSAPHISVFGNode ID: " << getId() << " {fun: " << getFun()->getName() << "}";
106  rawstr << "MR_" << getResVer()->getMR()->getMRID()
107  << "V_" << getResVer()->getSSAVersion() << " = PHI(";
108  for (MemSSA::PHI::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd();
109  it != eit; it++)
110  rawstr << "MR_" << it->second->getMR()->getMRID() << "V_" << it->second->getSSAVersion() << ", ";
111  rawstr << ")\n";
112 
113  rawstr << getResVer()->getMR()->dumpStr();
114  if (const IntraICFGNode* intraNode =
115  dyn_cast<IntraICFGNode>(getICFGNode()->getBB()->back()))
116  {
117  rawstr << intraNode->getSourceLoc();
118  }
119  return rawstr.str();
120 }
121 
123 {
124  std::string str;
125  std::stringstream rawstr(str);
126  rawstr << "IntraMSSAPHISVFGNode ID: " << getId() << " {fun: " << getFun()->getName() << "}";
127  rawstr << MSSAPHISVFGNode::toString();
128  return rawstr.str();
129 }
130 
132 {
133  NodeBS nb;
134  nb.set(object);
135  return nb;
136 }
137 
139 {
140  std::string str;
141  std::stringstream rawstr(str);
142  if(isFormalINPHI())
143  rawstr << "FormalINPHISVFGNode ID: " << getId() << " {fun: " << getFun()->getName() << "}";
144  else
145  rawstr << "ActualOUTPHISVFGNode ID: " << getId() << " at callsite: " << (getCallSite())->valueOnlyToString() << " {fun: " << getFun()->getName() << "}";
146  rawstr << MSSAPHISVFGNode::toString();
147  return rawstr.str();
148 }
149 
151 {
152  std::string str;
153  std::stringstream rawstr(str);
154  rawstr << "IndirectSVFGEdge: " << getDstID() << "<--" << getSrcID() << "\n";
155  return rawstr.str();
156 }
157 
159 {
160  std::string str;
161  std::stringstream rawstr(str);
162  rawstr << "IntraIndSVFGEdge: " << getDstID() << "<--" << getSrcID() << "\n";
163  return rawstr.str();
164 }
165 
167 {
168  std::string str;
169  std::stringstream rawstr(str);
170  rawstr << "CallIndSVFGEdge CallSite ID: " << getCallSiteId() << " ";
171  rawstr << getDstID() << "<--" << getSrcID() << "\n";
172  return rawstr.str();
173 }
174 
176 {
177  std::string str;
178  std::stringstream rawstr(str);
179  rawstr << "RetIndSVFGEdge CallSite ID: " << getCallSiteId() << " ";
180  rawstr << getDstID() << "<--" << getSrcID() << "\n";
181  return rawstr.str();
182 }
183 
184 
186 {
187  std::string str;
188  std::stringstream rawstr(str);
189  rawstr << "ThreadMHPIndSVFGEdge: " << getDstID() << "<--" << getSrcID() << "\n";
190  return rawstr.str();
191 }
192 
193 
194 FormalOUTSVFGNode::FormalOUTSVFGNode(NodeID id, const MRVer* mrVer, const FunExitICFGNode* funExit): MRSVFGNode(id, FPOUT)
195 {
196  cpts = mrVer->getMR()->getPointsTo();
197  ver = mrVer;
198  funExitNode = funExit;
199 }
200 
204 SVFG::SVFG(std::unique_ptr<MemSSA> mssa, VFGK k): VFG(mssa->getPTA()->getCallGraph(),k),mssa(std::move(mssa)), pta(this->mssa->getPTA())
205 {
206  stat = new SVFGStat(this);
207 }
208 
213 {
214  delete stat;
215  stat = nullptr;
216  clearMSSA();
217 }
218 
229 {
230  DBOUT(DGENERAL, outs() << pasMsg("Build Sparse Value-Flow Graph \n"));
231 
232  stat->startClk();
233  if (!Options::ReadSVFG().empty())
234  {
236  }
237  else
238  {
239  DBOUT(DGENERAL, outs() << pasMsg("\tCreate SVFG Addr-taken Node\n"));
240  stat->ATVFNodeStart();
242  stat->ATVFNodeEnd();
243  DBOUT(DGENERAL, outs() << pasMsg("\tCreate SVFG Indirect Edge\n"));
244  stat->indVFEdgeStart();
246  stat->indVFEdgeEnd();
247  if (!Options::WriteSVFG().empty())
249  }
250 }
251 
252 /*
253  * Create SVFG nodes for address-taken variables
254  */
256 {
257 
258  // set defs for address-taken vars defined at store statements
260  for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter =
261  stores.end(); iter != eiter; ++iter)
262  {
263  StoreStmt* store = SVFUtil::cast<StoreStmt>(*iter);
264  const StmtSVFGNode* sNode = getStmtVFGNode(store);
265  for(CHISet::iterator pi = mssa->getCHISet(store).begin(), epi = mssa->getCHISet(store).end(); pi!=epi; ++pi)
266  setDef((*pi)->getResVer(),sNode);
267  }
268 
272  for(MemSSA::BBToPhiSetMap::iterator it = mssa->getBBToPhiSetMap().begin(),
273  eit = mssa->getBBToPhiSetMap().end(); it!=eit; ++it)
274  {
275  for(PHISet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi)
276  {
277  MemSSA::PHI* phi = *pi;
278  const ICFGNode* inst = phi->getBasicBlock()->front();
279  addIntraMSSAPHISVFGNode(const_cast<ICFGNode*>(inst), phi->opVerBegin(), phi->opVerEnd(),phi->getResVer(), totalVFGNode++);
280  }
281  }
283  for(MemSSA::FunToEntryChiSetMap::iterator it = mssa->getFunToEntryChiSetMap().begin(),
284  eit = mssa->getFunToEntryChiSetMap().end(); it!=eit; ++it)
285  {
286  for(CHISet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi)
287  {
288  const MemSSA::ENTRYCHI* chi = SVFUtil::cast<ENTRYCHI>(*pi);
290  }
291  }
293  for(MemSSA::FunToReturnMuSetMap::iterator it = mssa->getFunToRetMuSetMap().begin(),
294  eit = mssa->getFunToRetMuSetMap().end(); it!=eit; ++it)
295  {
296  for(MUSet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi)
297  {
298  const MemSSA::RETMU* mu = SVFUtil::cast<RETMU>(*pi);
300  }
301  }
303  for(MemSSA::CallSiteToMUSetMap::iterator it = mssa->getCallSiteToMuSetMap().begin(),
304  eit = mssa->getCallSiteToMuSetMap().end();
305  it!=eit; ++it)
306  {
307  for(MUSet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi)
308  {
309  const MemSSA::CALLMU* mu = SVFUtil::cast<CALLMU>(*pi);
311  }
312  }
314  for(MemSSA::CallSiteToCHISetMap::iterator it = mssa->getCallSiteToChiSetMap().begin(),
315  eit = mssa->getCallSiteToChiSetMap().end();
316  it!=eit; ++it)
317  {
318  for(CHISet::iterator pi = it->second.begin(), epi = it->second.end(); pi!=epi; ++pi)
319  {
320  const MemSSA::CALLCHI* chi = SVFUtil::cast<CALLCHI>(*pi);
322  }
323 
324  }
325 }
326 
327 /*
328  * Connect def-use chains for indirect value-flow, (value-flow of address-taken variables)
329  */
331 {
332 
333  for(iterator it = begin(), eit = end(); it!=eit; ++it)
334  {
335  NodeID nodeId = it->first;
336  const SVFGNode* node = it->second;
337  if(const LoadSVFGNode* loadNode = SVFUtil::dyn_cast<LoadSVFGNode>(node))
338  {
339  MUSet& muSet = mssa->getMUSet(SVFUtil::cast<LoadStmt>(loadNode->getPAGEdge()));
340  for(MUSet::iterator it = muSet.begin(), eit = muSet.end(); it!=eit; ++it)
341  {
342  if(LOADMU* mu = SVFUtil::dyn_cast<LOADMU>(*it))
343  {
344  NodeID def = getDef(mu->getMRVer());
345  addIntraIndirectVFEdge(def,nodeId, mu->getMRVer()->getMR()->getPointsTo());
346  }
347  }
348  }
349  else if(const StoreSVFGNode* storeNode = SVFUtil::dyn_cast<StoreSVFGNode>(node))
350  {
351  CHISet& chiSet = mssa->getCHISet(SVFUtil::cast<StoreStmt>(storeNode->getPAGEdge()));
352  for(CHISet::iterator it = chiSet.begin(), eit = chiSet.end(); it!=eit; ++it)
353  {
354  if(STORECHI* chi = SVFUtil::dyn_cast<STORECHI>(*it))
355  {
356  NodeID def = getDef(chi->getOpVer());
357  addIntraIndirectVFEdge(def,nodeId, chi->getOpVer()->getMR()->getPointsTo());
358  }
359  }
360  }
361  else if(const FormalINSVFGNode* formalIn = SVFUtil::dyn_cast<FormalINSVFGNode>(node))
362  {
363  PTACallGraphEdge::CallInstSet callInstSet;
364  mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalIn->getFun(),callInstSet);
365  for(PTACallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it!=eit; ++it)
366  {
367  const CallICFGNode* cs = *it;
368  if(!mssa->hasMU(cs))
369  continue;
370  ActualINSVFGNodeSet& actualIns = getActualINSVFGNodes(cs);
371  for(ActualINSVFGNodeSet::iterator ait = actualIns.begin(), aeit = actualIns.end(); ait!=aeit; ++ait)
372  {
373  const ActualINSVFGNode* actualIn = SVFUtil::cast<ActualINSVFGNode>(getSVFGNode(*ait));
374  addInterIndirectVFCallEdge(actualIn,formalIn,getCallSiteID(cs, formalIn->getFun()));
375  }
376  }
377  }
378  else if(const FormalOUTSVFGNode* formalOut = SVFUtil::dyn_cast<FormalOUTSVFGNode>(node))
379  {
380  PTACallGraphEdge::CallInstSet callInstSet;
381  // const MemSSA::RETMU* retMu = formalOut->getRetMU();
382  mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalOut->getFun(),callInstSet);
383  for(PTACallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it!=eit; ++it)
384  {
385  const CallICFGNode* cs = *it;
386  if(!mssa->hasCHI(cs))
387  continue;
389  for(ActualOUTSVFGNodeSet::iterator ait = actualOuts.begin(), aeit = actualOuts.end(); ait!=aeit; ++ait)
390  {
391  const ActualOUTSVFGNode* actualOut = SVFUtil::cast<ActualOUTSVFGNode>(getSVFGNode(*ait));
392  addInterIndirectVFRetEdge(formalOut,actualOut,getCallSiteID(cs, formalOut->getFun()));
393  }
394  }
395  NodeID def = getDef(formalOut->getMRVer());
396  addIntraIndirectVFEdge(def,nodeId, formalOut->getMRVer()->getMR()->getPointsTo());
397  }
398  else if(const ActualINSVFGNode* actualIn = SVFUtil::dyn_cast<ActualINSVFGNode>(node))
399  {
400  const MRVer* ver = actualIn->getMRVer();
401  NodeID def = getDef(ver);
402  addIntraIndirectVFEdge(def,nodeId, ver->getMR()->getPointsTo());
403  }
404  else if(SVFUtil::isa<ActualOUTSVFGNode>(node))
405  {
407  }
408  else if(const MSSAPHISVFGNode* phiNode = SVFUtil::dyn_cast<MSSAPHISVFGNode>(node))
409  {
410  for (MemSSA::PHI::OPVers::const_iterator it = phiNode->opVerBegin(), eit = phiNode->opVerEnd();
411  it != eit; it++)
412  {
413  const MRVer* op = it->second;
414  NodeID def = getDef(op);
415  addIntraIndirectVFEdge(def,nodeId, op->getMR()->getPointsTo());
416  }
417  }
418  }
419 
420 
422 }
423 
424 
429 {
430  const SVFFunction* mainFunc = SVFUtil::getProgEntryFunction();
431  FormalINSVFGNodeSet& formalIns = getFormalINSVFGNodes(mainFunc);
432  if (formalIns.empty())
433  return;
434 
435  for (GlobalVFGNodeSet::const_iterator storeIt = globalVFGNodes.begin(), storeEit = globalVFGNodes.end();
436  storeIt != storeEit; ++storeIt)
437  {
438  if (const StoreSVFGNode* store = SVFUtil::dyn_cast<StoreSVFGNode>(*storeIt))
439  {
441  const NodeBS& storePts = mssa->getPTA()->getPts(store->getPAGDstNodeID()).toNodeBS();
442 
443  for (FormalINSVFGNodeSet::iterator fiIt = formalIns.begin(), fiEit =
444  formalIns.end(); fiIt != fiEit; ++fiIt)
445  {
446  NodeID formalInID = *fiIt;
447  NodeBS formalInPts = ((FormalINSVFGNode*) getSVFGNode(formalInID))->getPointsTo();
448 
449  formalInPts &= storePts;
450  if (formalInPts.empty())
451  continue;
452 
454  addIntraIndirectVFEdge(store->getId(), formalInID, formalInPts);
455  }
456  }
457  }
458 }
459 
460 /*
461  * Add def-use edges of a memory region between two statements
462  */
464 {
465  SVFGNode* srcNode = getSVFGNode(srcId);
466  SVFGNode* dstNode = getSVFGNode(dstId);
467  checkIntraEdgeParents(srcNode, dstNode);
468  if(SVFGEdge* edge = hasIntraVFGEdge(srcNode,dstNode,SVFGEdge::IntraIndirectVF))
469  {
470  assert(SVFUtil::isa<IndirectSVFGEdge>(edge) && "this should be a indirect value flow edge!");
471  return (SVFUtil::cast<IndirectSVFGEdge>(edge)->addPointsTo(cpts) ? edge : nullptr);
472  }
473  else
474  {
475  IntraIndSVFGEdge* indirectEdge = new IntraIndSVFGEdge(srcNode,dstNode);
476  indirectEdge->addPointsTo(cpts);
477  return (addSVFGEdge(indirectEdge) ? indirectEdge : nullptr);
478  }
479 }
480 
481 
486 {
487  SVFGNode* srcNode = getSVFGNode(srcId);
488  SVFGNode* dstNode = getSVFGNode(dstId);
489  if(SVFGEdge* edge = hasThreadVFGEdge(srcNode,dstNode,SVFGEdge::TheadMHPIndirectVF))
490  {
491  assert(SVFUtil::isa<IndirectSVFGEdge>(edge) && "this should be a indirect value flow edge!");
492  return (SVFUtil::cast<IndirectSVFGEdge>(edge)->addPointsTo(cpts) ? edge : nullptr);
493  }
494  else
495  {
496  ThreadMHPIndSVFGEdge* indirectEdge = new ThreadMHPIndSVFGEdge(srcNode,dstNode);
497  indirectEdge->addPointsTo(cpts);
498  return (addSVFGEdge(indirectEdge) ? indirectEdge : nullptr);
499  }
500 }
501 
502 /*
503  * Add def-use call edges of a memory region between two statements
504  */
506 {
507  SVFGNode* srcNode = getSVFGNode(srcId);
508  SVFGNode* dstNode = getSVFGNode(dstId);
509  if(SVFGEdge* edge = hasInterVFGEdge(srcNode,dstNode,SVFGEdge::CallIndVF,csId))
510  {
511  assert(SVFUtil::isa<CallIndSVFGEdge>(edge) && "this should be a indirect value flow edge!");
512  return (SVFUtil::cast<CallIndSVFGEdge>(edge)->addPointsTo(cpts) ? edge : nullptr);
513  }
514  else
515  {
516  CallIndSVFGEdge* callEdge = new CallIndSVFGEdge(srcNode,dstNode,csId);
517  callEdge->addPointsTo(cpts);
518  return (addSVFGEdge(callEdge) ? callEdge : nullptr);
519  }
520 }
521 
522 /*
523  * Add def-use return edges of a memory region between two statements
524  */
526 {
527  SVFGNode* srcNode = getSVFGNode(srcId);
528  SVFGNode* dstNode = getSVFGNode(dstId);
529  if(SVFGEdge* edge = hasInterVFGEdge(srcNode,dstNode,SVFGEdge::RetIndVF,csId))
530  {
531  assert(SVFUtil::isa<RetIndSVFGEdge>(edge) && "this should be a indirect value flow edge!");
532  return (SVFUtil::cast<RetIndSVFGEdge>(edge)->addPointsTo(cpts) ? edge : nullptr);
533  }
534  else
535  {
536  RetIndSVFGEdge* retEdge = new RetIndSVFGEdge(srcNode,dstNode,csId);
537  retEdge->addPointsTo(cpts);
538  return (addSVFGEdge(retEdge) ? retEdge : nullptr);
539  }
540 }
541 
546 {
547  NodeBS cpts1 = src->getPointsTo();
548  NodeBS cpts2 = dst->getPointsTo();
549  if(cpts1.intersects(cpts2))
550  {
551  cpts1 &= cpts2;
552  return addCallIndirectVFEdge(src->getId(),dst->getId(),cpts1,csId);
553  }
554  return nullptr;
555 }
556 
561 {
562 
563  NodeBS cpts1 = src->getPointsTo();
564  NodeBS cpts2 = dst->getPointsTo();
565  if(cpts1.intersects(cpts2))
566  {
567  cpts1 &= cpts2;
568  return addRetIndirectVFEdge(src->getId(),dst->getId(),cpts1,csId);
569  }
570  return nullptr;
571 }
572 
576 void SVFG::dump(const std::string& file, bool simple)
577 {
578  GraphPrinter::WriteGraphToFile(outs(), file, this, simple);
579 }
580 
584 void SVFG::getInterVFEdgesForIndirectCallSite(const CallICFGNode* callICFGNode, const SVFFunction* callee, SVFGEdgeSetTy& edges)
585 {
586  CallSiteID csId = getCallSiteID(callICFGNode, callee);
587  const RetICFGNode* retICFGNode = callICFGNode->getRetICFGNode();
588 
589  // Find inter direct call edges between actual param and formal param.
590  if (pag->hasCallSiteArgsMap(callICFGNode) && pag->hasFunArgsList(callee))
591  {
592  const SVFIR::SVFVarList& csArgList = pag->getCallSiteArgsList(callICFGNode);
593  const SVFIR::SVFVarList& funArgList = pag->getFunArgsList(callee);
594  SVFIR::SVFVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end();
595  SVFIR::SVFVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end();
596  for (; funArgIt != funArgEit && csArgIt != csArgEit; funArgIt++, csArgIt++)
597  {
598  const PAGNode *cs_arg = *csArgIt;
599  const PAGNode *fun_arg = *funArgIt;
600  if (isInterestedPAGNode(fun_arg) && isInterestedPAGNode(cs_arg))
601  getInterVFEdgeAtIndCSFromAPToFP(cs_arg, fun_arg, callICFGNode, csId, edges);
602  }
603  assert(funArgIt == funArgEit && "function has more arguments than call site");
604  if (callee->isVarArg())
605  {
606  NodeID varFunArg = pag->getVarargNode(callee);
607  const PAGNode* varFunArgNode = pag->getGNode(varFunArg);
608  if (isInterestedPAGNode(varFunArgNode))
609  {
610  for (; csArgIt != csArgEit; csArgIt++)
611  {
612  const PAGNode *cs_arg = *csArgIt;
613  if (isInterestedPAGNode(cs_arg))
614  getInterVFEdgeAtIndCSFromAPToFP(cs_arg, varFunArgNode, callICFGNode, csId, edges);
615  }
616  }
617  }
618  }
619 
620  // Find inter direct return edges between actual return and formal return.
621  if (pag->funHasRet(callee) && pag->callsiteHasRet(retICFGNode))
622  {
623  const PAGNode* cs_return = pag->getCallSiteRet(retICFGNode);
624  const PAGNode* fun_return = pag->getFunRet(callee);
625  if (isInterestedPAGNode(cs_return) && isInterestedPAGNode(fun_return))
626  getInterVFEdgeAtIndCSFromFRToAR(fun_return, cs_return, csId, edges);
627  }
628 
629  // Find inter indirect call edges between actual-in and formal-in svfg nodes.
630  if (hasFuncEntryChi(callee) && hasCallSiteMu(callICFGNode))
631  {
632  SVFG::ActualINSVFGNodeSet& actualInNodes = getActualINSVFGNodes(callICFGNode);
633  for(SVFG::ActualINSVFGNodeSet::iterator ai_it = actualInNodes.begin(),
634  ai_eit = actualInNodes.end(); ai_it!=ai_eit; ++ai_it)
635  {
636  ActualINSVFGNode * actualIn = SVFUtil::cast<ActualINSVFGNode>(getSVFGNode(*ai_it));
637  getInterVFEdgeAtIndCSFromAInToFIn(actualIn, callee, edges);
638  }
639  }
640 
641  // Find inter indirect return edges between actual-out and formal-out svfg nodes.
642  if (hasFuncRetMu(callee) && hasCallSiteChi(callICFGNode))
643  {
644  SVFG::ActualOUTSVFGNodeSet& actualOutNodes = getActualOUTSVFGNodes(callICFGNode);
645  for(SVFG::ActualOUTSVFGNodeSet::iterator ao_it = actualOutNodes.begin(),
646  ao_eit = actualOutNodes.end(); ao_it!=ao_eit; ++ao_it)
647  {
648  ActualOUTSVFGNode* actualOut = SVFUtil::cast<ActualOUTSVFGNode>(getSVFGNode(*ao_it));
649  getInterVFEdgeAtIndCSFromFOutToAOut(actualOut, callee, edges);
650  }
651  }
652 }
653 
659 {
660  VFG::connectCallerAndCallee(cs,callee,edges);
661 
662  CallSiteID csId = getCallSiteID(cs, callee);
663 
664  // connect actual in and formal in
665  if (hasFuncEntryChi(callee) && hasCallSiteMu(cs))
666  {
667  SVFG::ActualINSVFGNodeSet& actualInNodes = getActualINSVFGNodes(cs);
668  const SVFG::FormalINSVFGNodeSet& formalInNodes = getFormalINSVFGNodes(callee);
669  for(SVFG::ActualINSVFGNodeSet::iterator ai_it = actualInNodes.begin(),
670  ai_eit = actualInNodes.end(); ai_it!=ai_eit; ++ai_it)
671  {
672  const ActualINSVFGNode * actualIn = SVFUtil::cast<ActualINSVFGNode>(getSVFGNode(*ai_it));
673  for(SVFG::FormalINSVFGNodeSet::iterator fi_it = formalInNodes.begin(),
674  fi_eit = formalInNodes.end(); fi_it!=fi_eit; ++fi_it)
675  {
676  const FormalINSVFGNode* formalIn = SVFUtil::cast<FormalINSVFGNode>(getSVFGNode(*fi_it));
677  connectAInAndFIn(actualIn, formalIn, csId, edges);
678  }
679  }
680  }
681 
682  // connect actual out and formal out
683  if (hasFuncRetMu(callee) && hasCallSiteChi(cs))
684  {
685  // connect formal out and actual out
686  const SVFG::FormalOUTSVFGNodeSet& formalOutNodes = getFormalOUTSVFGNodes(callee);
688  for(SVFG::FormalOUTSVFGNodeSet::iterator fo_it = formalOutNodes.begin(),
689  fo_eit = formalOutNodes.end(); fo_it!=fo_eit; ++fo_it)
690  {
691  const FormalOUTSVFGNode * formalOut = SVFUtil::cast<FormalOUTSVFGNode>(getSVFGNode(*fo_it));
692  for(SVFG::ActualOUTSVFGNodeSet::iterator ao_it = actualOutNodes.begin(),
693  ao_eit = actualOutNodes.end(); ao_it!=ao_eit; ++ao_it)
694  {
695  const ActualOUTSVFGNode* actualOut = SVFUtil::cast<ActualOUTSVFGNode>(getSVFGNode(*ao_it));
696  connectFOutAndAOut(formalOut, actualOut, csId, edges);
697  }
698  }
699  }
700 }
701 
702 
707 {
708  if(const FormalParmSVFGNode* fp = SVFUtil::dyn_cast<FormalParmSVFGNode>(node))
709  {
710  return fp->getFun();
711  }
712  else if(const InterPHISVFGNode* phi = SVFUtil::dyn_cast<InterPHISVFGNode>(node))
713  {
714  if(phi->isFormalParmPHI())
715  return phi->getFun();
716  }
717  else if(const FormalINSVFGNode* fi = SVFUtil::dyn_cast<FormalINSVFGNode>(node))
718  {
719  return fi->getFun();
720  }
721  else if(const InterMSSAPHISVFGNode* mphi = SVFUtil::dyn_cast<InterMSSAPHISVFGNode>(node))
722  {
723  if(mphi->isFormalINPHI())
724  return mphi->getFun();
725  }
726  return nullptr;
727 }
728 
733 {
734  if(const ActualRetSVFGNode* ar = SVFUtil::dyn_cast<ActualRetSVFGNode>(node))
735  {
736  return ar->getCallSite();
737  }
738  else if(const InterPHISVFGNode* phi = SVFUtil::dyn_cast<InterPHISVFGNode>(node))
739  {
740  if(phi->isActualRetPHI())
741  return phi->getCallSite();
742  }
743  else if(const ActualOUTSVFGNode* ao = SVFUtil::dyn_cast<ActualOUTSVFGNode>(node))
744  {
745  return ao->getCallSite();
746  }
747  else if(const InterMSSAPHISVFGNode* mphi = SVFUtil::dyn_cast<InterMSSAPHISVFGNode>(node))
748  {
749  if(mphi->isActualOUTPHI())
750  return mphi->getCallSite();
751  }
752  return nullptr;
753 }
754 
759 {
760  stat->performStat();
761 }
762 
766 namespace SVF
767 {
768 template<>
770 {
771 
773  DOTGraphTraits(bool isSimple = false) :
774  DOTGraphTraits<SVFIR*>(isSimple)
775  {
776  }
777 
780  {
781  return "SVFG";
782  }
783 
786  static bool isNodeHidden(SVFGNode *node, SVFG *)
787  {
788  if (Options::ShowHiddenNode()) return false;
789  else return node->getInEdges().empty() && node->getOutEdges().empty();
790  }
791 
793  {
794  if (isSimple())
795  return getSimpleNodeLabel(node, graph);
796  else
797  return getCompleteNodeLabel(node, graph);
798  }
799 
802  {
803  std::string str;
804  std::stringstream rawstr(str);
805  if(StmtSVFGNode* stmtNode = SVFUtil::dyn_cast<StmtSVFGNode>(node))
806  {
807  rawstr << stmtNode->toString();
808  }
809  else if(PHISVFGNode* tphi = SVFUtil::dyn_cast<PHISVFGNode>(node))
810  {
811  rawstr << tphi->toString();
812  }
813  else if(FormalParmSVFGNode* fp = SVFUtil::dyn_cast<FormalParmSVFGNode>(node))
814  {
815  rawstr << fp->toString();
816  }
817  else if(ActualParmSVFGNode* ap = SVFUtil::dyn_cast<ActualParmSVFGNode>(node))
818  {
819  rawstr << ap->toString();
820  }
821  else if (ActualRetSVFGNode* ar = SVFUtil::dyn_cast<ActualRetSVFGNode>(node))
822  {
823  rawstr << ar->toString();
824  }
825  else if (FormalRetSVFGNode* fr = SVFUtil::dyn_cast<FormalRetSVFGNode>(node))
826  {
827  rawstr << fr->toString();
828  }
829  else if(FormalINSVFGNode* fi = SVFUtil::dyn_cast<FormalINSVFGNode>(node))
830  {
831  rawstr << fi->toString();
832  }
833  else if(FormalOUTSVFGNode* fo = SVFUtil::dyn_cast<FormalOUTSVFGNode>(node))
834  {
835  rawstr << fo->toString();
836  }
837  else if(ActualINSVFGNode* ai = SVFUtil::dyn_cast<ActualINSVFGNode>(node))
838  {
839  rawstr << ai->toString();
840  }
841  else if(ActualOUTSVFGNode* ao = SVFUtil::dyn_cast<ActualOUTSVFGNode>(node))
842  {
843  rawstr << ao->toString();
844  }
845  else if(MSSAPHISVFGNode* mphi = SVFUtil::dyn_cast<MSSAPHISVFGNode>(node))
846  {
847  rawstr << mphi->toString();
848  }
849  else if(SVFUtil::isa<NullPtrSVFGNode>(node))
850  {
851  rawstr << "NullPtr";
852  }
853  else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
854  {
855  rawstr << bop->toString();
856  }
857  else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
858  {
859  rawstr << uop->toString();
860  }
861  else if(CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
862  {
863  rawstr << cmp->toString();
864  }
865  else
866  assert(false && "what else kinds of nodes do we have??");
867 
868  return rawstr.str();
869  }
870 
873  {
874 
875  std::string str;
876  std::stringstream rawstr(str);
877  if(StmtSVFGNode* stmtNode = SVFUtil::dyn_cast<StmtSVFGNode>(node))
878  {
879  rawstr << stmtNode->toString();
880  }
881  else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
882  {
883  rawstr << bop->toString();
884  }
885  else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
886  {
887  rawstr << uop->toString();
888  }
889  else if(CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
890  {
891  rawstr << cmp->toString();
892  }
893  else if(MSSAPHISVFGNode* mphi = SVFUtil::dyn_cast<MSSAPHISVFGNode>(node))
894  {
895  rawstr << mphi->toString();
896  }
897  else if(PHISVFGNode* tphi = SVFUtil::dyn_cast<PHISVFGNode>(node))
898  {
899  rawstr << tphi->toString();
900  }
901  else if(FormalINSVFGNode* fi = SVFUtil::dyn_cast<FormalINSVFGNode>(node))
902  {
903  rawstr << fi->toString();
904  }
905  else if(FormalOUTSVFGNode* fo = SVFUtil::dyn_cast<FormalOUTSVFGNode>(node))
906  {
907  rawstr << fo->toString();
908  }
909  else if(FormalParmSVFGNode* fp = SVFUtil::dyn_cast<FormalParmSVFGNode>(node))
910  {
911  rawstr << fp->toString();
912  }
913  else if(ActualINSVFGNode* ai = SVFUtil::dyn_cast<ActualINSVFGNode>(node))
914  {
915  rawstr << ai->toString();
916  }
917  else if(ActualOUTSVFGNode* ao = SVFUtil::dyn_cast<ActualOUTSVFGNode>(node))
918  {
919  rawstr << ao->toString();
920  }
921  else if(ActualParmSVFGNode* ap = SVFUtil::dyn_cast<ActualParmSVFGNode>(node))
922  {
923  rawstr << ap->toString();
924  }
925  else if(NullPtrSVFGNode* nptr = SVFUtil::dyn_cast<NullPtrSVFGNode>(node))
926  {
927  rawstr << nptr->toString();
928  }
929  else if (ActualRetSVFGNode* ar = SVFUtil::dyn_cast<ActualRetSVFGNode>(node))
930  {
931  rawstr << ar->toString();
932  }
933  else if (FormalRetSVFGNode* fr = SVFUtil::dyn_cast<FormalRetSVFGNode>(node))
934  {
935  rawstr << fr->toString();
936  }
937  else if (BranchVFGNode* br = SVFUtil::dyn_cast<BranchVFGNode>(node))
938  {
939  rawstr << br->toString();
940  }
941  else
942  assert(false && "what else kinds of nodes do we have??");
943 
944  return rawstr.str();
945  }
946 
948  {
949  std::string str;
950  std::stringstream rawstr(str);
951 
952  if(StmtSVFGNode* stmtNode = SVFUtil::dyn_cast<StmtSVFGNode>(node))
953  {
954  const PAGEdge* edge = stmtNode->getPAGEdge();
955  if (SVFUtil::isa<AddrStmt>(edge))
956  {
957  rawstr << "color=green";
958  }
959  else if (SVFUtil::isa<CopyStmt>(edge))
960  {
961  rawstr << "color=black";
962  }
963  else if (SVFUtil::isa<RetPE>(edge))
964  {
965  rawstr << "color=black,style=dotted";
966  }
967  else if (SVFUtil::isa<GepStmt>(edge))
968  {
969  rawstr << "color=purple";
970  }
971  else if (SVFUtil::isa<StoreStmt>(edge))
972  {
973  rawstr << "color=blue";
974  }
975  else if (SVFUtil::isa<LoadStmt>(edge))
976  {
977  rawstr << "color=red";
978  }
979  else
980  {
981  assert(0 && "No such kind edge!!");
982  }
983  rawstr << "";
984  }
985  else if(SVFUtil::isa<MSSAPHISVFGNode>(node))
986  {
987  rawstr << "color=black";
988  }
989  else if(SVFUtil::isa<PHISVFGNode>(node))
990  {
991  rawstr << "color=black";
992  }
993  else if(SVFUtil::isa<NullPtrSVFGNode>(node))
994  {
995  rawstr << "color=grey";
996  }
997  else if(SVFUtil::isa<FormalINSVFGNode>(node))
998  {
999  rawstr << "color=yellow,penwidth=2";
1000  }
1001  else if(SVFUtil::isa<FormalOUTSVFGNode>(node))
1002  {
1003  rawstr << "color=yellow,penwidth=2";
1004  }
1005  else if(SVFUtil::isa<FormalParmSVFGNode>(node))
1006  {
1007  rawstr << "color=yellow,penwidth=2";
1008  }
1009  else if(SVFUtil::isa<ActualINSVFGNode>(node))
1010  {
1011  rawstr << "color=yellow,penwidth=2";
1012  }
1013  else if(SVFUtil::isa<ActualOUTSVFGNode>(node))
1014  {
1015  rawstr << "color=yellow,penwidth=2";
1016  }
1017  else if(SVFUtil::isa<ActualParmSVFGNode>(node))
1018  {
1019  rawstr << "color=yellow,penwidth=2";
1020  }
1021  else if (SVFUtil::isa<ActualRetSVFGNode>(node))
1022  {
1023  rawstr << "color=yellow,penwidth=2";
1024  }
1025  else if (SVFUtil::isa<FormalRetSVFGNode>(node))
1026  {
1027  rawstr << "color=yellow,penwidth=2";
1028  }
1029  else if (SVFUtil::isa<BinaryOPVFGNode>(node))
1030  {
1031  rawstr << "color=black,penwidth=2";
1032  }
1033  else if (SVFUtil::isa<CmpVFGNode>(node))
1034  {
1035  rawstr << "color=black,penwidth=2";
1036  }
1037  else if (SVFUtil::isa<UnaryOPVFGNode>(node))
1038  {
1039  rawstr << "color=black,penwidth=2";
1040  }
1041  else if (SVFUtil::isa<BranchVFGNode>(node))
1042  {
1043  rawstr << "color=gold,penwidth=2";
1044  }
1045  else
1046  assert(false && "no such kind of node!!");
1047 
1049  if(graph->getStat()->isSource(node))
1050  {
1051  rawstr << ",style=filled, fillcolor=red";
1052  }
1053  else if(graph->getStat()->isSink(node))
1054  {
1055  rawstr << ",style=filled, fillcolor=blue";
1056  }
1057  else if(graph->getStat()->inBackwardSlice(node))
1058  {
1059  rawstr << ",style=filled, fillcolor=yellow";
1060  }
1061  else if(graph->getStat()->inForwardSlice(node))
1062  rawstr << ",style=filled, fillcolor=gray";
1063 
1064  rawstr << "";
1065 
1066  return rawstr.str();
1067  }
1068 
1069  template<class EdgeIter>
1070  static std::string getEdgeAttributes(NodeType*, EdgeIter EI, SVFG*)
1071  {
1072  SVFGEdge* edge = *(EI.getCurrent());
1073  assert(edge && "No edge found!!");
1074  if (SVFUtil::isa<DirectSVFGEdge>(edge))
1075  {
1076  if (SVFUtil::isa<CallDirSVFGEdge>(edge))
1077  return "style=solid,color=red";
1078  else if (SVFUtil::isa<RetDirSVFGEdge>(edge))
1079  return "style=solid,color=blue";
1080  else
1081  return "style=solid";
1082  }
1083  else if (SVFUtil::isa<IndirectSVFGEdge>(edge))
1084  {
1085  if (SVFUtil::isa<CallIndSVFGEdge>(edge))
1086  return "style=dashed,color=red";
1087  else if (SVFUtil::isa<RetIndSVFGEdge>(edge))
1088  return "style=dashed,color=blue";
1089  else
1090  return "style=dashed";
1091  }
1092  return "";
1093  }
1094 
1095  template<class EdgeIter>
1097  {
1098  SVFGEdge* edge = *(EI.getCurrent());
1099  assert(edge && "No edge found!!");
1100 
1101  std::string str;
1102  std::stringstream rawstr(str);
1103  if (CallDirSVFGEdge* dirCall = SVFUtil::dyn_cast<CallDirSVFGEdge>(edge))
1104  rawstr << dirCall->getCallSiteId();
1105  else if (RetDirSVFGEdge* dirRet = SVFUtil::dyn_cast<RetDirSVFGEdge>(edge))
1106  rawstr << dirRet->getCallSiteId();
1107  else if (CallIndSVFGEdge* indCall = SVFUtil::dyn_cast<CallIndSVFGEdge>(edge))
1108  rawstr << indCall->getCallSiteId();
1109  else if (RetIndSVFGEdge* indRet = SVFUtil::dyn_cast<RetIndSVFGEdge>(edge))
1110  rawstr << indRet->getCallSiteId();
1111 
1112  return rawstr.str();
1113  }
1114 };
1115 } // 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
const char *const string
Definition: cJSON.h:172
virtual const std::string toString() const
Definition: SVFG.cpp:78
virtual const std::string toString() const
Definition: SVFG.cpp:89
const CallICFGNode * getCallSite() const
Return callsite.
Definition: MSSAMuChi.h:544
const RetICFGNode * getRetICFGNode() const
Return callsite.
Definition: ICFGNode.h:457
virtual const std::string toString() const
Definition: SVFG.cpp:166
const CallICFGNode * getCallSite() const
Return callsite.
Definition: MSSAMuChi.h:241
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: SVFG.cpp:131
const SVFFunction * getFunction() const
Return function.
Definition: MSSAMuChi.h:595
virtual const std::string toString() const
Definition: SVFG.cpp:57
virtual const std::string toString() const
Definition: SVFG.cpp:68
FormalOUTSVFGNode(NodeID id, const MRVer *ver, const FunExitICFGNode *funExitNode)
Constructor.
Definition: SVFG.cpp:194
const MRVer * ver
Definition: SVFGNode.h:129
const FunExitICFGNode * funExitNode
Definition: SVFGNode.h:130
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
const GEdgeSetTy & getOutEdges() const
Definition: GenericGraph.h:430
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
virtual const SVFFunction * getFun() const
Return the function of this ICFGNode.
Definition: ICFGNode.h:76
FunEntryICFGNode * getFunEntryICFGNode(const SVFFunction *fun)
Add a function entry node.
Definition: ICFG.cpp:234
FunExitICFGNode * getFunExitICFGNode(const SVFFunction *fun)
Add a function exit node.
Definition: ICFG.cpp:241
NodeID getVarargNode(const SVFFunction *func) const
getVarargNode - Return the unique node representing the variadic argument of a variadic function.
Definition: IRGraph.h:157
virtual const std::string toString() const
Definition: SVFG.cpp:150
bool addPointsTo(const NodeBS &c)
Handle memory region.
Definition: SVFGEdge.h:56
virtual const std::string toString() const
Definition: SVFG.cpp:138
virtual const std::string toString() const
Definition: SVFG.cpp:158
virtual const std::string toString() const
Definition: SVFG.cpp:122
virtual const std::string toString() const override
Definition: SVFG.cpp:49
const NodeBS & getPointsTo() const
Return points-to of the MR.
Definition: SVFGNode.h:52
NodeBS cpts
Definition: SVFGNode.h:45
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition: SVFG.cpp:44
const MemRegion * getMR() const
Return the memory region.
Definition: MSSAMuChi.h:63
MRVer * getResVer() const
Set operand vers.
Definition: MSSAMuChi.h:373
MRVer * getMRVer() const
Get Ver.
Definition: MSSAMuChi.h:137
virtual const std::string toString() const
Definition: SVFG.cpp:101
OPVers::const_iterator opVerEnd() const
Definition: MSSAMuChi.h:677
OPVers::const_iterator opVerBegin() const
Operand ver iterators.
Definition: MSSAMuChi.h:673
const SVFBasicBlock * getBasicBlock() const
Return the basic block.
Definition: MSSAMuChi.h:684
const NodeBS & getPointsTo() const
Return points-to.
Definition: MemRegion.h:83
static const Option< std::string > ReadSVFG
Definition: Options.h:152
static const Option< std::string > WriteSVFG
Definition: Options.h:151
static const Option< bool > ShowHiddenNode
Definition: Options.h:228
Set< const CallICFGNode * > CallInstSet
Definition: PTACallGraph.h:55
virtual const std::string toString() const
Definition: SVFG.cpp:175
const SVFFunction * getFunction() const
Return function.
Definition: MSSAMuChi.h:292
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
const ICFGNode * front() const
Definition: SVFValue.h:594
bool isVarArg() const
Definition: SVFValue.cpp:181
virtual void performStat() override
Definition: SVFGStat.cpp:178
void ATVFNodeStart()
Definition: SVFGStat.h:139
bool inBackwardSlice(const SVFGNode *node) const
Definition: SVFGStat.h:257
bool isSource(const SVFGNode *node) const
Definition: SVFGStat.h:261
void indVFEdgeEnd()
Definition: SVFGStat.h:124
void ATVFNodeEnd()
Definition: SVFGStat.h:144
bool inForwardSlice(const SVFGNode *node) const
Definition: SVFGStat.h:253
void indVFEdgeStart()
Definition: SVFGStat.h:119
bool isSink(const SVFGNode *node) const
Definition: SVFGStat.h:265
Definition: SVFG.h:66
SVFG(std::unique_ptr< MemSSA > mssa, VFGK k)
Constructor.
Definition: SVFG.cpp:204
virtual void buildSVFG()
Start building SVFG.
Definition: SVFG.cpp:228
void connectIndirectSVFGEdges()
Connect direct SVFG edges between two SVFG nodes (value-flow of top address-taken variables)
Definition: SVFG.cpp:330
SVFGEdge * addThreadMHPIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts)
Definition: SVFG.cpp:485
bool hasFuncEntryChi(const SVFFunction *func) const
Has function for EntryCHI/RetMU/CallCHI/CallMU.
Definition: SVFG.h:449
FormalOUTSVFGNodeSet & getFormalOUTSVFGNodes(const SVFFunction *fun)
Definition: SVFG.h:225
bool hasFuncRetMu(const SVFFunction *func) const
Definition: SVFG.h:453
virtual void connectFOutAndAOut(const FormalOUTSVFGNode *formalOut, const ActualOUTSVFGNode *actualOut, CallSiteID csId, SVFGEdgeSetTy &edges)
Connect formal-out and actual-out.
Definition: SVFG.h:300
ActualINSVFGNodeSet & getActualINSVFGNodes(const CallICFGNode *cs)
Get SVFGNode set.
Definition: SVFG.h:210
void getInterVFEdgesForIndirectCallSite(const CallICFGNode *cs, const SVFFunction *callee, SVFGEdgeSetTy &edges)
Get all inter value flow edges of a indirect call site.
Definition: SVFG.cpp:584
SVFGEdge * addInterIndirectVFCallEdge(const ActualINSVFGNode *src, const FormalINSVFGNode *dst, CallSiteID csId)
Add inter VF edge from callsite mu to function entry chi.
Definition: SVFG.cpp:545
void connectFromGlobalToProgEntry()
Connect indirect SVFG edges from global initializers (store) to main function entry.
Definition: SVFG.cpp:428
ActualOUTSVFGNodeSet & getActualOUTSVFGNodes(const CallICFGNode *cs)
Definition: SVFG.h:215
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
Definition: SVFG.cpp:576
void addIntraMSSAPHISVFGNode(ICFGNode *BlockICFGNode, const Map< u32_t, const MRVer * >::const_iterator opVerBegin, const Map< u32_t, const MRVer * >::const_iterator opVerEnd, const MRVer *resVer, const NodeID nodeId)
Add memory SSA PHI SVFG node.
Definition: SVFG.h:437
bool addSVFGEdge(SVFGEdge *edge)
Add SVFG edge.
Definition: SVFG.h:249
void addActualOUTSVFGNode(const CallICFGNode *callsite, const MRVer *resVer, const NodeID nodeId)
Add memory callsite chi SVFG node.
Definition: SVFG.h:428
virtual void getInterVFEdgeAtIndCSFromFOutToAOut(ActualOUTSVFGNode *actualOut, const SVFFunction *callee, SVFGEdgeSetTy &edges)
Definition: SVFG.h:338
SVFGNode * getSVFGNode(NodeID id) const
Get a SVFG node.
Definition: SVFG.h:150
virtual void writeToFile(const std::string &filename)
void addFormalOUTSVFGNode(const FunExitICFGNode *funExit, const MRVer *ver, const NodeID nodeId)
Add memory Function return mu SVFG node.
Definition: SVFG.h:412
void destroy()
Clean up memory.
Definition: SVFG.cpp:212
bool hasCallSiteMu(const CallICFGNode *cs) const
Definition: SVFG.h:461
MemSSA::CHISet CHISet
Definition: SVFG.h:88
SVFGStat * getStat() const
Return statistics.
Definition: SVFG.h:126
SVFGEdge * addRetIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts, CallSiteID csId)
Definition: SVFG.cpp:525
void addActualINSVFGNode(const CallICFGNode *callsite, const MRVer *ver, const NodeID nodeId)
Add memory callsite mu SVFG node.
Definition: SVFG.h:420
FormalINSVFGNodeSet & getFormalINSVFGNodes(const SVFFunction *fun)
Definition: SVFG.h:220
virtual void readFile(const std::string &filename)
std::unique_ptr< MemSSA > mssa
Definition: SVFG.h:106
virtual void getInterVFEdgeAtIndCSFromFRToAR(const PAGNode *fun_ret, const PAGNode *cs_ret, CallSiteID csId, SVFGEdgeSetTy &edges)
Definition: SVFG.h:319
void addFormalINSVFGNode(const FunEntryICFGNode *funEntry, const MRVer *resVer, const NodeID nodeId)
Add memory Function entry chi SVFG node.
Definition: SVFG.h:403
NodeID getDef(const PAGNode *pagNode) const
Definition: SVFG.h:356
void addSVFGNodesForAddrTakenVars()
Create SVFG nodes for address-taken variables.
Definition: SVFG.cpp:255
virtual void getInterVFEdgeAtIndCSFromAPToFP(const PAGNode *cs_arg, const PAGNode *fun_arg, const CallICFGNode *, CallSiteID csId, SVFGEdgeSetTy &edges)
Get inter value flow edges between indirect call site and callee.
Definition: SVFG.h:310
SVFGEdge * addInterIndirectVFRetEdge(const FormalOUTSVFGNode *src, const ActualOUTSVFGNode *dst, CallSiteID csId)
Add inter VF edge from function exit mu to callsite chi.
Definition: SVFG.cpp:560
virtual void connectAInAndFIn(const ActualINSVFGNode *actualIn, const FormalINSVFGNode *formalIn, CallSiteID csId, SVFGEdgeSetTy &edges)
Connect SVFG nodes between caller and callee for indirect call site.
Definition: SVFG.h:293
void setDef(const PAGNode *pagNode, const SVFGNode *node)
Given a PAGNode, set/get its def SVFG node (definition of top level pointers)
Definition: SVFG.h:352
MemSSA::MUSet MUSet
Definition: SVFG.h:87
SVFGEdge * addIntraIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts)
Add indirect def-use edges of a memory region between two statements,.
Definition: SVFG.cpp:463
const CallICFGNode * isCallSiteRetSVFGNode(const SVFGNode *node) const
Whether a node is callsite return SVFGNode.
Definition: SVFG.cpp:732
SVFGStat * stat
Definition: SVFG.h:105
bool hasCallSiteChi(const CallICFGNode *cs) const
Definition: SVFG.h:457
void performStat()
Perform statistics.
Definition: SVFG.cpp:758
const SVFFunction * isFunEntrySVFGNode(const SVFGNode *node) const
Whether a node is function entry SVFGNode.
Definition: SVFG.cpp:706
void clearMSSA()
Clear MSSA.
Definition: SVFG.h:132
virtual void connectCallerAndCallee(const CallICFGNode *cs, const SVFFunction *callee, SVFGEdgeSetTy &edges)
Connect SVFG nodes between caller and callee for indirect call site.
Definition: SVFG.cpp:658
SVFGEdge * addCallIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts, CallSiteID csId)
Definition: SVFG.cpp:505
virtual void getInterVFEdgeAtIndCSFromAInToFIn(ActualINSVFGNode *actualIn, const SVFFunction *callee, SVFGEdgeSetTy &edges)
Definition: SVFG.h:328
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
const SVFVar * getFunRet(const SVFFunction *func) const
Get function return list.
Definition: SVFIR.h:320
std::vector< const SVFVar * > SVFVarList
Definition: SVFIR.h:59
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
ICFG * getICFG() const
Definition: SVFIR.h:171
bool hasFunArgsList(const SVFFunction *func) const
Function has arguments list.
Definition: SVFIR.h:265
bool funHasRet(const SVFFunction *func) const
Definition: SVFIR.h:326
virtual void startClk()
Definition: SVFStat.h:58
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
bool intersects(const SparseBitVector< ElementSize > *RHS) const
iterator end() const
void set(unsigned Idx)
iterator begin() const
virtual const std::string toString() const
Definition: SVFG.cpp:185
@ IntraIndirectVF
Definition: VFGEdge.h:54
@ TheadMHPIndirectVF
Definition: VFGEdge.h:59
Definition: VFG.h:51
SVFIR * pag
Definition: VFG.h:104
virtual SVFStmt::SVFStmtSetTy & getPAGEdgeSet(SVFStmt::PEDGEK kind)
Get PAGEdge set.
Definition: VFG.h:436
StmtVFGNode * getStmtVFGNode(const PAGEdge *pagEdge) const
Get an VFGNode.
Definition: VFG.h:199
void checkIntraEdgeParents(const VFGNode *srcNode, const VFGNode *dstNode)
sanitize Intra edges, verify that both nodes belong to the same function.
Definition: VFG.h:351
CallSiteID getCallSiteID(const CallICFGNode *cs, const SVFFunction *func) const
Get callsite given a callsiteID.
Definition: VFG.h:178
GlobalVFGNodeSet globalVFGNodes
set of global store VFG nodes
Definition: VFG.h:102
virtual bool isInterestedPAGNode(const SVFVar *node) const
Definition: VFG.h:444
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
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
VFGEdge::SVFGEdgeSetTy SVFGEdgeSetTy
Definition: VFG.h:78
NodeID totalVFGNode
Definition: VFG.h:88
VFGEdge * hasInterVFGEdge(VFGNode *src, VFGNode *dst, VFGEdge::VFGEdgeK kind, CallSiteID csId)
Definition: VFG.cpp:910
VFGEdge * hasThreadVFGEdge(VFGNode *src, VFGNode *dst, VFGEdge::VFGEdgeK kind)
Definition: VFG.cpp:893
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition: SVFUtil.cpp:99
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
Definition: SVFUtil.h:447
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
const SVFFunction * getProgEntryFunction()
Get program entry function.
Definition: SVFUtil.cpp:415
for isBitcode
Definition: BasicTypes.h:68
unsigned CallSiteID
Definition: GeneralType.h:58
u32_t NodeID
Definition: GeneralType.h:55
static std::string getGraphName(SVFG *)
Return name of the graph.
Definition: SVFG.cpp:779
std::string getNodeLabel(NodeType *node, SVFG *graph)
Definition: SVFG.cpp:792
static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
Definition: SVFG.cpp:1096
static std::string getSimpleNodeLabel(NodeType *node, SVFG *)
Return label of a VFG node without MemSSA information.
Definition: SVFG.cpp:801
static bool isNodeHidden(SVFGNode *node, SVFG *)
Definition: SVFG.cpp:786
DOTGraphTraits(bool isSimple=false)
Definition: SVFG.cpp:773
static std::string getNodeAttributes(NodeType *node, SVFG *graph)
Definition: SVFG.cpp:947
static std::string getCompleteNodeLabel(NodeType *node, SVFG *)
Return label of a VFG node with MemSSA information.
Definition: SVFG.cpp:872
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, SVFG *)
Definition: SVFG.cpp:1070