Static Value-Flow Analysis
Loading...
Searching...
No Matches
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
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
41using namespace SVF;
42using namespace SVFUtil;
43
45{
46 return getPointsTo();
47}
48
49const std::string MRSVFGNode::toString() const
50{
51 std::string str;
52 std::stringstream rawstr(str);
53 rawstr << "MRSVFGNode ID: " << getId();
54 return rawstr.str();
55}
56
57const std::string FormalINSVFGNode::toString() const
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
68const std::string FormalOUTSVFGNode::toString() const
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
78const std::string ActualINSVFGNode::toString() const
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
89const std::string ActualOUTSVFGNode::toString() const
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
101const std::string MSSAPHISVFGNode::toString() const
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
122const std::string IntraMSSAPHISVFGNode::toString() const
123{
124 std::string str;
125 std::stringstream rawstr(str);
126 rawstr << "IntraMSSAPHISVFGNode ID: " << getId() << " {fun: " << getFun()->getName() << "}";
128 return rawstr.str();
129}
130
132{
133 NodeBS nb;
134 nb.set(object);
135 return nb;
136}
137
138const std::string InterMSSAPHISVFGNode::toString() const
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() << "}";
147 return rawstr.str();
148}
149
150const std::string IndirectSVFGEdge::toString() const
151{
152 std::string str;
153 std::stringstream rawstr(str);
154 rawstr << "IndirectSVFGEdge: " << getDstID() << "<--" << getSrcID() << "\n";
155 return rawstr.str();
156}
157
158const std::string IntraIndSVFGEdge::toString() const
159{
160 std::string str;
161 std::stringstream rawstr(str);
162 rawstr << "IntraIndSVFGEdge: " << getDstID() << "<--" << getSrcID() << "\n";
163 return rawstr.str();
164}
165
166const std::string CallIndSVFGEdge::toString() const
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
175const std::string RetIndSVFGEdge::toString() const
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
185const std::string ThreadMHPIndSVFGEdge::toString() const
186{
187 std::string str;
188 std::stringstream rawstr(str);
189 rawstr << "ThreadMHPIndSVFGEdge: " << getDstID() << "<--" << getSrcID() << "\n";
190 return rawstr.str();
191}
192
193
195{
196 cpts = mrVer->getMR()->getPointsTo();
197 ver = mrVer;
199}
200
204SVFG::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"));
242 stat->ATVFNodeEnd();
243 DBOUT(DGENERAL, outs() << pasMsg("\tCreate SVFG Indirect Edge\n"));
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);
289 addFormalINSVFGNode(pag->getICFG()->getFunEntryICFGNode(chi->getFunction()), chi->getResVer(), totalVFGNode++);
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);
299 addFormalOUTSVFGNode(pag->getICFG()->getFunExitICFGNode(mu->getFunction()), mu->getMRVer(), totalVFGNode++);
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);
310 addActualINSVFGNode(mu->getCallSite(), mu->getMRVer(), totalVFGNode++);
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);
321 addActualOUTSVFGNode(chi->getCallSite(), chi->getResVer(), totalVFGNode++);
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->getSVFStmt()));
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->getSVFStmt()));
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 {
364 mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalIn->getFun(),callInstSet);
365 for(CallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it!=eit; ++it)
366 {
367 const CallICFGNode* cs = *it;
368 if(!mssa->hasMU(cs))
369 continue;
372 {
373 const ActualINSVFGNode* actualIn = SVFUtil::cast<ActualINSVFGNode>(getSVFGNode(*ait));
375 }
376 }
377 }
378 else if(const FormalOUTSVFGNode* formalOut = SVFUtil::dyn_cast<FormalOUTSVFGNode>(node))
379 {
381 // const MemSSA::RETMU* retMu = formalOut->getRetMU();
382 mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalOut->getFun(),callInstSet);
383 for(CallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it!=eit; ++it)
384 {
385 const CallICFGNode* cs = *it;
386 if(!mssa->hasCHI(cs))
387 continue;
390 {
391 const ActualOUTSVFGNode* actualOut = SVFUtil::cast<ActualOUTSVFGNode>(getSVFGNode(*ait));
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);
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{
432 if (formalIns.empty())
433 return;
434
435 for (GlobalVFGNodeSet::const_iterator storeIt = globalVFGNodes.begin(), storeEit = globalVFGNodes.end();
437 {
438 if (const StoreSVFGNode* store = SVFUtil::dyn_cast<StoreSVFGNode>(*storeIt))
439 {
441 const NodeBS& storePts = mssa->getPTA()->getPts(store->getDstNodeID()).toNodeBS();
442
444 formalIns.end(); fiIt != fiEit; ++fiIt)
445 {
448
450 if (formalInPts.empty())
451 continue;
452
455 }
456 }
457 }
458}
459
460/*
461 * Add def-use edges of a memory region between two statements
462 */
464{
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 {
476 indirectEdge->addPointsTo(cpts);
477 return (addSVFGEdge(indirectEdge) ? indirectEdge : nullptr);
478 }
479}
480
481
486{
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 {
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{
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 {
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{
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 {
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
576void SVFG::dump(const std::string& file, bool simple)
577{
579}
580
585{
587 const RetICFGNode* retICFGNode = callICFGNode->getRetICFGNode();
588
589 // Find inter direct call edges between actual param and formal param.
591 {
594 SVFIR::ValVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end();
595 SVFIR::ValVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end();
596 for (; funArgIt != funArgEit && csArgIt != csArgEit; funArgIt++, csArgIt++)
597 {
598 const ValVar *cs_arg = *csArgIt;
599 const ValVar *fun_arg = *funArgIt;
602 }
603 assert(funArgIt == funArgEit && "function has more arguments than call site");
604 if (callee->isVarArg())
605 {
609 {
610 for (; csArgIt != csArgEit; csArgIt++)
611 {
612 const ValVar *cs_arg = *csArgIt;
615 }
616 }
617 }
618 }
619
620 // Find inter direct return edges between actual return and formal return.
622 {
627 }
628
629 // Find inter indirect call edges between actual-in and formal-in svfg nodes.
631 {
635 {
636 ActualINSVFGNode * actualIn = SVFUtil::cast<ActualINSVFGNode>(getSVFGNode(*ai_it));
638 }
639 }
640
641 // Find inter indirect return edges between actual-out and formal-out svfg nodes.
643 {
647 {
648 ActualOUTSVFGNode* actualOut = SVFUtil::cast<ActualOUTSVFGNode>(getSVFGNode(*ao_it));
650 }
651 }
652}
653
659{
661
662 CallSiteID csId = getCallSiteID(cs, callee);
663
664 // connect actual in and formal in
666 {
671 {
672 const ActualINSVFGNode * actualIn = SVFUtil::cast<ActualINSVFGNode>(getSVFGNode(*ai_it));
675 {
676 const FormalINSVFGNode* formalIn = SVFUtil::cast<FormalINSVFGNode>(getSVFGNode(*fi_it));
678 }
679 }
680 }
681
682 // connect actual out and formal out
684 {
685 // connect formal out and actual out
690 {
691 const FormalOUTSVFGNode * formalOut = SVFUtil::cast<FormalOUTSVFGNode>(getSVFGNode(*fo_it));
694 {
695 const ActualOUTSVFGNode* actualOut = SVFUtil::cast<ActualOUTSVFGNode>(getSVFGNode(*ao_it));
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{
767 return getDefSVFGNode(var)->getICFGNode();
768}
769
772const ICFGNode* SVFG::getDefSiteOfObjVar(const ObjVar* obj, const ICFGNode* node) const
773{
774 const ICFGNode* defSite = nullptr;
775 NodeID objId = obj->getId();
776 for (const VFGNode* vNode : node->getVFGNodes())
777 {
778 for (auto it = vNode->InEdgeBegin(), eit = vNode->InEdgeEnd(); it != eit; ++it)
779 {
780 if (const IndirectSVFGEdge* indEdge = SVFUtil::dyn_cast<IndirectSVFGEdge>(*it))
781 {
782 if (indEdge->getPointsTo().test(objId))
783 {
784 assert(defSite == nullptr && "ObjVar should have a unique indirect definition!");
785 defSite = indEdge->getSrcNode()->getICFGNode();
786 }
787 }
788 }
789 }
790 return defSite;
791}
792
796{
799 for (auto it = defNode->OutEdgeBegin(), eit = defNode->OutEdgeEnd(); it != eit; ++it)
800 {
801 const VFGEdge* edge = *it;
802 if (edge->isDirectVFGEdge())
803 {
804 if (const ICFGNode* icfgNode = edge->getDstNode()->getICFGNode())
805 useSites.insert(icfgNode);
806 else
807 assert(false && "The destination node of a direct VFG edge should have an ICFG node!");
808 }
809 }
810 return useSites;
811}
812
816{
818 NodeID objId = obj->getId();
819 for (const VFGNode* vNode : node->getVFGNodes())
820 {
821 for (auto it = vNode->OutEdgeBegin(), eit = vNode->OutEdgeEnd(); it != eit; ++it)
822 {
823 if (const IndirectSVFGEdge* indEdge = SVFUtil::dyn_cast<IndirectSVFGEdge>(*it))
824 {
825 if (indEdge->getPointsTo().test(objId))
826 {
827 if (const ICFGNode* icfgNode = indEdge->getDstNode()->getICFGNode())
828 useSites.insert(icfgNode);
829 else
830 assert(false && "The destination node of an indirect SVFG edge should have an ICFG node!");
831 }
832 }
833 }
834 }
835 return useSites;
836}
837
841namespace SVF
842{
843template<>
845{
846
848 DOTGraphTraits(bool isSimple = false) :
849 DOTGraphTraits<SVFIR*>(isSimple)
850 {
851 }
852
854 static std::string getGraphName(SVFG*)
855 {
856 return "SVFG";
857 }
858
861 static bool isNodeHidden(SVFGNode *node, SVFG *)
862 {
863 if (Options::ShowHiddenNode()) return false;
864 else return node->getInEdges().empty() && node->getOutEdges().empty();
865 }
866
867 std::string getNodeLabel(NodeType *node, SVFG *graph)
868 {
869 if (isSimple())
870 return getSimpleNodeLabel(node, graph);
871 else
872 return getCompleteNodeLabel(node, graph);
873 }
874
876 static std::string getSimpleNodeLabel(NodeType *node, SVFG*)
877 {
878 std::string str;
879 std::stringstream rawstr(str);
880 if(StmtSVFGNode* stmtNode = SVFUtil::dyn_cast<StmtSVFGNode>(node))
881 {
882 rawstr << stmtNode->toString();
883 }
884 else if(PHISVFGNode* tphi = SVFUtil::dyn_cast<PHISVFGNode>(node))
885 {
886 rawstr << tphi->toString();
887 }
888 else if(FormalParmSVFGNode* fp = SVFUtil::dyn_cast<FormalParmSVFGNode>(node))
889 {
890 rawstr << fp->toString();
891 }
892 else if(ActualParmSVFGNode* ap = SVFUtil::dyn_cast<ActualParmSVFGNode>(node))
893 {
894 rawstr << ap->toString();
895 }
896 else if (ActualRetSVFGNode* ar = SVFUtil::dyn_cast<ActualRetSVFGNode>(node))
897 {
898 rawstr << ar->toString();
899 }
900 else if (FormalRetSVFGNode* fr = SVFUtil::dyn_cast<FormalRetSVFGNode>(node))
901 {
902 rawstr << fr->toString();
903 }
904 else if(FormalINSVFGNode* fi = SVFUtil::dyn_cast<FormalINSVFGNode>(node))
905 {
906 rawstr << fi->toString();
907 }
908 else if(FormalOUTSVFGNode* fo = SVFUtil::dyn_cast<FormalOUTSVFGNode>(node))
909 {
910 rawstr << fo->toString();
911 }
912 else if(ActualINSVFGNode* ai = SVFUtil::dyn_cast<ActualINSVFGNode>(node))
913 {
914 rawstr << ai->toString();
915 }
916 else if(ActualOUTSVFGNode* ao = SVFUtil::dyn_cast<ActualOUTSVFGNode>(node))
917 {
918 rawstr << ao->toString();
919 }
920 else if(MSSAPHISVFGNode* mphi = SVFUtil::dyn_cast<MSSAPHISVFGNode>(node))
921 {
922 rawstr << mphi->toString();
923 }
924 else if(SVFUtil::isa<NullPtrSVFGNode>(node))
925 {
926 rawstr << "NullPtr";
927 }
928 else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
929 {
930 rawstr << bop->toString();
931 }
932 else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
933 {
934 rawstr << uop->toString();
935 }
936 else if(CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
937 {
938 rawstr << cmp->toString();
939 }
940 else
941 assert(false && "what else kinds of nodes do we have??");
942
943 return rawstr.str();
944 }
945
947 static std::string getCompleteNodeLabel(NodeType *node, SVFG*)
948 {
949
950 std::string str;
951 std::stringstream rawstr(str);
952 if(StmtSVFGNode* stmtNode = SVFUtil::dyn_cast<StmtSVFGNode>(node))
953 {
954 rawstr << stmtNode->toString();
955 }
956 else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
957 {
958 rawstr << bop->toString();
959 }
960 else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
961 {
962 rawstr << uop->toString();
963 }
964 else if(CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
965 {
966 rawstr << cmp->toString();
967 }
968 else if(MSSAPHISVFGNode* mphi = SVFUtil::dyn_cast<MSSAPHISVFGNode>(node))
969 {
970 rawstr << mphi->toString();
971 }
972 else if(PHISVFGNode* tphi = SVFUtil::dyn_cast<PHISVFGNode>(node))
973 {
974 rawstr << tphi->toString();
975 }
976 else if(FormalINSVFGNode* fi = SVFUtil::dyn_cast<FormalINSVFGNode>(node))
977 {
978 rawstr << fi->toString();
979 }
980 else if(FormalOUTSVFGNode* fo = SVFUtil::dyn_cast<FormalOUTSVFGNode>(node))
981 {
982 rawstr << fo->toString();
983 }
984 else if(FormalParmSVFGNode* fp = SVFUtil::dyn_cast<FormalParmSVFGNode>(node))
985 {
986 rawstr << fp->toString();
987 }
988 else if(ActualINSVFGNode* ai = SVFUtil::dyn_cast<ActualINSVFGNode>(node))
989 {
990 rawstr << ai->toString();
991 }
992 else if(ActualOUTSVFGNode* ao = SVFUtil::dyn_cast<ActualOUTSVFGNode>(node))
993 {
994 rawstr << ao->toString();
995 }
996 else if(ActualParmSVFGNode* ap = SVFUtil::dyn_cast<ActualParmSVFGNode>(node))
997 {
998 rawstr << ap->toString();
999 }
1000 else if(NullPtrSVFGNode* nptr = SVFUtil::dyn_cast<NullPtrSVFGNode>(node))
1001 {
1002 rawstr << nptr->toString();
1003 }
1004 else if (ActualRetSVFGNode* ar = SVFUtil::dyn_cast<ActualRetSVFGNode>(node))
1005 {
1006 rawstr << ar->toString();
1007 }
1008 else if (FormalRetSVFGNode* fr = SVFUtil::dyn_cast<FormalRetSVFGNode>(node))
1009 {
1010 rawstr << fr->toString();
1011 }
1012 else if (BranchVFGNode* br = SVFUtil::dyn_cast<BranchVFGNode>(node))
1013 {
1014 rawstr << br->toString();
1015 }
1016 else
1017 assert(false && "what else kinds of nodes do we have??");
1018
1019 return rawstr.str();
1020 }
1021
1022 static std::string getNodeAttributes(NodeType *node, SVFG *graph)
1023 {
1024 std::string str;
1025 std::stringstream rawstr(str);
1026
1027 if(StmtSVFGNode* stmtNode = SVFUtil::dyn_cast<StmtSVFGNode>(node))
1028 {
1029 const SVFStmt* edge = stmtNode->getSVFStmt();
1030 if (SVFUtil::isa<AddrStmt>(edge))
1031 {
1032 rawstr << "color=green";
1033 }
1034 else if (SVFUtil::isa<CopyStmt>(edge))
1035 {
1036 rawstr << "color=black";
1037 }
1038 else if (SVFUtil::isa<RetPE>(edge))
1039 {
1040 rawstr << "color=black,style=dotted";
1041 }
1042 else if (SVFUtil::isa<GepStmt>(edge))
1043 {
1044 rawstr << "color=purple";
1045 }
1046 else if (SVFUtil::isa<StoreStmt>(edge))
1047 {
1048 rawstr << "color=blue";
1049 }
1050 else if (SVFUtil::isa<LoadStmt>(edge))
1051 {
1052 rawstr << "color=red";
1053 }
1054 else
1055 {
1056 assert(0 && "No such kind edge!!");
1057 }
1058 rawstr << "";
1059 }
1060 else if(SVFUtil::isa<MSSAPHISVFGNode>(node))
1061 {
1062 rawstr << "color=black";
1063 }
1064 else if(SVFUtil::isa<PHISVFGNode>(node))
1065 {
1066 rawstr << "color=black";
1067 }
1068 else if(SVFUtil::isa<NullPtrSVFGNode>(node))
1069 {
1070 rawstr << "color=grey";
1071 }
1072 else if(SVFUtil::isa<FormalINSVFGNode>(node))
1073 {
1074 rawstr << "color=yellow,penwidth=2";
1075 }
1076 else if(SVFUtil::isa<FormalOUTSVFGNode>(node))
1077 {
1078 rawstr << "color=yellow,penwidth=2";
1079 }
1080 else if(SVFUtil::isa<FormalParmSVFGNode>(node))
1081 {
1082 rawstr << "color=yellow,penwidth=2";
1083 }
1084 else if(SVFUtil::isa<ActualINSVFGNode>(node))
1085 {
1086 rawstr << "color=yellow,penwidth=2";
1087 }
1088 else if(SVFUtil::isa<ActualOUTSVFGNode>(node))
1089 {
1090 rawstr << "color=yellow,penwidth=2";
1091 }
1092 else if(SVFUtil::isa<ActualParmSVFGNode>(node))
1093 {
1094 rawstr << "color=yellow,penwidth=2";
1095 }
1096 else if (SVFUtil::isa<ActualRetSVFGNode>(node))
1097 {
1098 rawstr << "color=yellow,penwidth=2";
1099 }
1100 else if (SVFUtil::isa<FormalRetSVFGNode>(node))
1101 {
1102 rawstr << "color=yellow,penwidth=2";
1103 }
1104 else if (SVFUtil::isa<BinaryOPVFGNode>(node))
1105 {
1106 rawstr << "color=black,penwidth=2";
1107 }
1108 else if (SVFUtil::isa<CmpVFGNode>(node))
1109 {
1110 rawstr << "color=black,penwidth=2";
1111 }
1112 else if (SVFUtil::isa<UnaryOPVFGNode>(node))
1113 {
1114 rawstr << "color=black,penwidth=2";
1115 }
1116 else if (SVFUtil::isa<BranchVFGNode>(node))
1117 {
1118 rawstr << "color=gold,penwidth=2";
1119 }
1120 else
1121 assert(false && "no such kind of node!!");
1122
1124 if(graph->getStat()->isSource(node))
1125 {
1126 rawstr << ",style=filled, fillcolor=red";
1127 }
1128 else if(graph->getStat()->isSink(node))
1129 {
1130 rawstr << ",style=filled, fillcolor=blue";
1131 }
1132 else if(graph->getStat()->inBackwardSlice(node))
1133 {
1134 rawstr << ",style=filled, fillcolor=yellow";
1135 }
1136 else if(graph->getStat()->inForwardSlice(node))
1137 rawstr << ",style=filled, fillcolor=gray";
1138
1139 rawstr << "";
1140
1141 return rawstr.str();
1142 }
1143
1144 template<class EdgeIter>
1146 {
1147 SVFGEdge* edge = *(EI.getCurrent());
1148 assert(edge && "No edge found!!");
1149 if (SVFUtil::isa<DirectSVFGEdge>(edge))
1150 {
1151 if (SVFUtil::isa<CallDirSVFGEdge>(edge))
1152 return "style=solid,color=red";
1153 else if (SVFUtil::isa<RetDirSVFGEdge>(edge))
1154 return "style=solid,color=blue";
1155 else
1156 return "style=solid";
1157 }
1158 else if (SVFUtil::isa<IndirectSVFGEdge>(edge))
1159 {
1160 if (SVFUtil::isa<CallIndSVFGEdge>(edge))
1161 return "style=dashed,color=red";
1162 else if (SVFUtil::isa<RetIndSVFGEdge>(edge))
1163 return "style=dashed,color=blue";
1164 else
1165 return "style=dashed";
1166 }
1167 return "";
1168 }
1169
1170 template<class EdgeIter>
1172 {
1173 SVFGEdge* edge = *(EI.getCurrent());
1174 assert(edge && "No edge found!!");
1175
1176 std::string str;
1177 std::stringstream rawstr(str);
1178 if (CallDirSVFGEdge* dirCall = SVFUtil::dyn_cast<CallDirSVFGEdge>(edge))
1179 rawstr << dirCall->getCallSiteId();
1180 else if (RetDirSVFGEdge* dirRet = SVFUtil::dyn_cast<RetDirSVFGEdge>(edge))
1181 rawstr << dirRet->getCallSiteId();
1182 else if (CallIndSVFGEdge* indCall = SVFUtil::dyn_cast<CallIndSVFGEdge>(edge))
1183 rawstr << indCall->getCallSiteId();
1184 else if (RetIndSVFGEdge* indRet = SVFUtil::dyn_cast<RetIndSVFGEdge>(edge))
1185 rawstr << indRet->getCallSiteId();
1186
1187 return rawstr.str();
1188 }
1189};
1190} // End namespace llvm
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:593
#define DGENERAL
Definition SVFType.h:599
const MRVer * getMRVer() const
Ver.
Definition SVFGNode.h:188
virtual const std::string toString() const
Definition SVFG.cpp:78
const CallICFGNode * getCallSite() const
Callsite.
Definition SVFGNode.h:182
const CallICFGNode * getCallSite() const
Callsite.
Definition SVFGNode.h:232
virtual const std::string toString() const
Definition SVFG.cpp:89
const MRVer * getMRVer() const
Ver.
Definition SVFGNode.h:237
Set< const CallICFGNode * > CallInstSet
Definition CallGraph.h:55
const std::string getSourceLoc() const override
Definition ICFGNode.h:570
virtual const std::string toString() const
Definition SVFG.cpp:166
CallSiteID getCallSiteId() const
Definition SVFGEdge.h:136
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition SVFG.cpp:131
const MRVer * getMRVer() const
Definition SVFGNode.h:95
virtual const std::string toString() const
Definition SVFG.cpp:57
virtual const std::string toString() const
Definition SVFG.cpp:68
const MRVer * getMRVer() const
Definition SVFGNode.h:141
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
NodeID getDstID() const
NodeID getSrcID() const
get methods of the components
iterator begin()
Iterators.
const GEdgeSetTy & getOutEdges() const
const GEdgeSetTy & getInEdges() const
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType &GT, bool simple=false)
virtual const FunObjVar * getFun() const
Return the function of this ICFGNode.
Definition ICFGNode.h:74
const VFGNodeList & getVFGNodes() const
Definition ICFGNode.h:102
FunExitICFGNode * getFunExitICFGNode(const FunObjVar *fun)
Add a function exit node.
Definition ICFG.cpp:249
FunEntryICFGNode * getFunEntryICFGNode(const FunObjVar *fun)
Add a function entry node.
Definition ICFG.cpp:242
NodeID getVarargNode(const FunObjVar *func) const
getVarargNode - Return the unique node representing the variadic argument of a variadic function.
Definition IRGraph.cpp:67
virtual const std::string toString() const
Definition SVFG.cpp:150
virtual const std::string toString() const
Definition SVFG.cpp:138
bool isFormalINPHI() const
Definition SVFGNode.h:401
const FunObjVar * getFun() const
Get the function of this SVFGNode.
Definition SVFGNode.h:411
const CallICFGNode * getCallSite() const
Definition SVFGNode.h:417
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
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition SVFG.cpp:44
MRVERSION getSSAVersion() const
Return SSA version.
Definition MSSAMuChi.h:69
const MemRegion * getMR() const
Return the memory region.
Definition MSSAMuChi.h:63
virtual const std::string toString() const
Definition SVFG.cpp:101
OPVers::const_iterator opVerEnd() const
Definition SVFGNode.h:305
const MRVer * getResVer() const
Ver.
Definition SVFGNode.h:281
OPVers::const_iterator opVerBegin() const
Definition SVFGNode.h:301
MRID getMRID() const
Return memory region ID.
Definition MemRegion.h:78
const NodeBS & getPointsTo() const
Return points-to.
Definition MemRegion.h:83
std::string dumpStr() const
Dump string.
Definition MemRegion.h:93
CallCHI< Condition > CALLCHI
Definition MemSSA.h:66
EntryCHI< Condition > ENTRYCHI
Definition MemSSA.h:64
CallMU< Condition > CALLMU
Definition MemSSA.h:62
RetMU< Condition > RETMU
Definition MemSSA.h:60
static const Option< std::string > ReadSVFG
Definition Options.h:149
static const Option< std::string > WriteSVFG
Definition Options.h:148
static const Option< bool > ShowHiddenNode
Definition Options.h:225
CallSiteID getCallSiteId() const
Definition SVFGEdge.h:175
virtual const std::string toString() const
Definition SVFG.cpp:175
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
virtual void getInterVFEdgeAtIndCSFromFOutToAOut(ActualOUTSVFGNode *actualOut, const FunObjVar *callee, SVFGEdgeSetTy &edges)
Definition SVFG.h:354
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
ActualOUTSVFGNodeSet & getActualOUTSVFGNodes(const CallICFGNode *cs)
Definition SVFG.h:231
FormalOUTSVFGNodeSet & getFormalOUTSVFGNodes(const FunObjVar *fun)
Definition SVFG.h:241
FormalINSVFGNodeSet & getFormalINSVFGNodes(const FunObjVar *fun)
Definition SVFG.h:236
SVFGStat * getStat() const
Return statistics.
Definition SVFG.h:126
virtual void connectFOutAndAOut(const FormalOUTSVFGNode *formalOut, const ActualOUTSVFGNode *actualOut, CallSiteID csId, SVFGEdgeSetTy &edges)
Connect formal-out and actual-out.
Definition SVFG.h:316
virtual void getInterVFEdgeAtIndCSFromAPToFP(const ValVar *cs_arg, const ValVar *fun_arg, const CallICFGNode *, CallSiteID csId, SVFGEdgeSetTy &edges)
Get inter value flow edges between indirect call site and callee.
Definition SVFG.h:326
const ICFGNode * getDefSiteOfValVar(const ValVar *var) const
Definition SVFG.cpp:765
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
virtual void getInterVFEdgeAtIndCSFromAInToFIn(ActualINSVFGNode *actualIn, const FunObjVar *callee, SVFGEdgeSetTy &edges)
Definition SVFG.h:344
void connectFromGlobalToProgEntry()
Connect indirect SVFG edges from global initializers (store) to main function entry.
Definition SVFG.cpp:428
SVFGNode * getSVFGNode(NodeID id) const
Get a SVFG node.
Definition SVFG.h:150
void getInterVFEdgesForIndirectCallSite(const CallICFGNode *cs, const FunObjVar *callee, SVFGEdgeSetTy &edges)
Get all inter value flow edges of a indirect call site.
Definition SVFG.cpp:584
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:453
ActualINSVFGNodeSet & getActualINSVFGNodes(const CallICFGNode *cs)
Get SVFGNode set.
Definition SVFG.h:226
bool addSVFGEdge(SVFGEdge *edge)
Add SVFG edge.
Definition SVFG.h:265
void addActualOUTSVFGNode(const CallICFGNode *callsite, const MRVer *resVer, const NodeID nodeId)
Add memory callsite chi SVFG node.
Definition SVFG.h:444
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:428
void destroy()
Clean up memory.
Definition SVFG.cpp:212
virtual void connectCallerAndCallee(const CallICFGNode *cs, const FunObjVar *callee, SVFGEdgeSetTy &edges)
Connect SVFG nodes between caller and callee for indirect call site.
Definition SVFG.cpp:658
bool hasCallSiteMu(const CallICFGNode *cs) const
Definition SVFG.h:477
MemSSA::LOADMU LOADMU
Definition SVFG.h:92
MemSSA::CHISet CHISet
Definition SVFG.h:88
void setDef(const ValVar *valVar, const SVFGNode *node)
Given a ValVar, set/get its def SVFG node (definition of top level pointers)
Definition SVFG.h:368
SVFGEdge * addRetIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts, CallSiteID csId)
Definition SVFG.cpp:525
const Set< const ICFGNode * > getUseSitesOfValVar(const ValVar *var) const
Definition SVFG.cpp:795
void addActualINSVFGNode(const CallICFGNode *callsite, const MRVer *ver, const NodeID nodeId)
Add memory callsite mu SVFG node.
Definition SVFG.h:436
bool hasFuncRetMu(const FunObjVar *func) const
Definition SVFG.h:469
NodeID getDef(const ValVar *valVar) const
Definition SVFG.h:372
virtual void readFile(const std::string &filename)
std::unique_ptr< MemSSA > mssa
Definition SVFG.h:106
const ICFGNode * getDefSiteOfObjVar(const ObjVar *obj, const ICFGNode *node) const
Definition SVFG.cpp:772
void addFormalINSVFGNode(const FunEntryICFGNode *funEntry, const MRVer *resVer, const NodeID nodeId)
Add memory Function entry chi SVFG node.
Definition SVFG.h:419
void addSVFGNodesForAddrTakenVars()
Create SVFG nodes for address-taken variables.
Definition SVFG.cpp:255
virtual void getInterVFEdgeAtIndCSFromFRToAR(const ValVar *fun_ret, const ValVar *cs_ret, CallSiteID csId, SVFGEdgeSetTy &edges)
Definition SVFG.h:335
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:309
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
MemSSA::STORECHI STORECHI
Definition SVFG.h:93
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:473
bool hasFuncEntryChi(const FunObjVar *func) const
Has function for EntryCHI/RetMU/CallCHI/CallMU.
Definition SVFG.h:465
void performStat()
Perform statistics.
Definition SVFG.cpp:758
const FunObjVar * isFunEntrySVFGNode(const SVFGNode *node) const
Whether a node is function entry SVFGNode.
Definition SVFG.cpp:706
const Set< const ICFGNode * > getUseSitesOfObjVar(const ObjVar *obj, const ICFGNode *node) const
Definition SVFG.cpp:815
void clearMSSA()
Clear MSSA.
Definition SVFG.h:132
const SVFGNode * getDefSVFGNode(const ValVar *valVar) const
Given a valVar, return its definition site.
Definition SVFG.h:171
SVFGEdge * addCallIndirectVFEdge(NodeID srcId, NodeID dstId, const NodeBS &cpts, CallSiteID csId)
Definition SVFG.cpp:505
bool funHasRet(const FunObjVar *func) const
Definition SVFIR.h:419
bool hasFunArgsList(const FunObjVar *func) const
Function has arguments list.
Definition SVFIR.h:358
const ValVar * getCallSiteRet(const RetICFGNode *cs) const
Get callsite return.
Definition SVFIR.h:397
const ValVarList & getFunArgsList(const FunObjVar *func) const
Get function arguments list.
Definition SVFIR.h:368
std::vector< const ValVar * > ValVarList
Definition SVFIR.h:58
ICFG * getICFG() const
Definition SVFIR.h:227
bool hasCallSiteArgsMap(const CallICFGNode *cs) const
Callsite has argument list.
Definition SVFIR.h:375
bool callsiteHasRet(const RetICFGNode *cs) const
Definition SVFIR.h:403
const ValVar * getFunRet(const FunObjVar *func) const
Get function return list.
Definition SVFIR.h:413
const ValVarList & getCallSiteArgsList(const CallICFGNode *cs) const
Get callsite argument list.
Definition SVFIR.h:385
const ValVar * getValVar(NodeID id) const
Definition SVFIR.h:135
virtual void startClk()
Definition SVFStat.h:58
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
NodeID getId() const
Get ID.
Definition SVFValue.h:163
virtual const std::string & getName() const
Definition SVFValue.h:189
const std::string valueOnlyToString() const
Definition LLVMUtil.cpp:739
void set(unsigned Idx)
virtual const std::string toString() const
Definition SVFG.cpp:185
@ IntraIndirectVF
Definition VFGEdge.h:54
@ TheadMHPIndirectVF
Definition VFGEdge.h:59
virtual const FunObjVar * getFun() const
Get the function of this SVFGNode.
Definition VFGNode.h:79
virtual const ICFGNode * getICFGNode() const
Return corresponding ICFG node.
Definition VFGNode.h:67
Definition VFG.h:51
VFGNodeIDToNodeMapTy::iterator iterator
Definition VFG.h:80
SVFIR * pag
Definition VFG.h:104
CallSiteID getCallSiteID(const CallICFGNode *cs, const FunObjVar *func) const
Get callsite given a callsiteID.
Definition VFG.h:178
void checkIntraEdgeParents(const VFGNode *srcNode, const VFGNode *dstNode)
sanitize Intra edges, verify that both nodes belong to the same function.
Definition VFG.h:413
GlobalVFGNodeSet globalVFGNodes
set of global store VFG nodes
Definition VFG.h:102
StmtVFGNode * getStmtVFGNode(const SVFStmt *svfStmt) const
Get an VFGNode.
Definition VFG.h:261
virtual SVFStmt::SVFStmtSetTy & getSVFStmtSet(SVFStmt::PEDGEK kind)
Get SVFStmt set.
Definition VFG.h:498
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:859
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:894
virtual bool isInterestedSVFVar(const SVFVar *node) const
Definition VFG.h:506
VFGEdge * hasThreadVFGEdge(VFGNode *src, VFGNode *dst, VFGEdge::VFGEdgeK kind)
Definition VFG.cpp:877
virtual void connectCallerAndCallee(const CallICFGNode *cs, const FunObjVar *callee, VFGEdgeSetTy &edges)
Connect VFG nodes between caller and callee for indirect call site.
Definition VFG.cpp:957
const FunObjVar * getProgEntryFunction()
Get program entry function.
Definition SVFUtil.cpp:410
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:101
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
Definition SVFUtil.h:420
for isBitcode
Definition BasicTypes.h:70
unsigned CallSiteID
Definition GeneralType.h:58
u32_t NodeID
Definition GeneralType.h:56
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
static std::string getGraphName(SVFG *)
Return name of the graph.
Definition SVFG.cpp:854
std::string getNodeLabel(NodeType *node, SVFG *graph)
Definition SVFG.cpp:867
static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
Definition SVFG.cpp:1171
static std::string getSimpleNodeLabel(NodeType *node, SVFG *)
Return label of a VFG node without MemSSA information.
Definition SVFG.cpp:876
static bool isNodeHidden(SVFGNode *node, SVFG *)
Definition SVFG.cpp:861
DOTGraphTraits(bool isSimple=false)
Definition SVFG.cpp:848
static std::string getNodeAttributes(NodeType *node, SVFG *graph)
Definition SVFG.cpp:1022
static std::string getCompleteNodeLabel(NodeType *node, SVFG *)
Return label of a VFG node with MemSSA information.
Definition SVFG.cpp:947
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, SVFG *)
Definition SVFG.cpp:1145