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