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
31#include <Graphs/SVFGNode.h>
32#include "Graphs/CallGraph.h"
33#include "Graphs/VFG.h"
34#include "Util/Options.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 << getSVFStmt()->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 << "SVFStmt: [" << 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 rawstr << " " << res->valueOnlyToString();
129 return rawstr.str();
130}
131
133{
134 NodeBS nb;
135 nb.set(getRes()->getId());
136 return nb;
137}
138
139const std::string BinaryOPVFGNode::toString() const
140{
141 std::string str;
142 std::stringstream rawstr(str);
143 rawstr << "BinaryOPVFGNode ID: " << getId() << " ";
144 rawstr << "SVFStmt: [" << res->getId() << " = Binary(";
145 for(BinaryOPVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd();
146 it != eit; it++)
147 rawstr << it->second->getId() << ", ";
148 rawstr << ")]\t";
149 rawstr << " " << res->valueOnlyToString();
150 return rawstr.str();
151}
152
154{
155 NodeBS nb;
156 nb.set(getRes()->getId());
157 return nb;
158}
159
160const std::string UnaryOPVFGNode::toString() const
161{
162 std::string str;
163 std::stringstream rawstr(str);
164 rawstr << "UnaryOPVFGNode ID: " << getId() << " ";
165 rawstr << "SVFStmt: [" << res->getId() << " = Unary(";
166 for(UnaryOPVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd();
167 it != eit; it++)
168 rawstr << it->second->getId() << ", ";
169 rawstr << ")]\t";
170 rawstr << " " << res->valueOnlyToString();
171 return rawstr.str();
172}
173
175{
176 return NodeBS();
177}
178
179const std::string BranchVFGNode::toString() const
180{
181 std::string str;
182 std::stringstream rawstr(str);
183 rawstr << "BranchVFGNode ID: " << getId() << " ";
184 rawstr << "SVFStmt: [" << brstmt->toString() << "\t";
185 return rawstr.str();
186}
187
189{
190 NodeBS nb;
192 return nb;
193}
194
195const std::string GepVFGNode::toString() const
196{
197 std::string str;
198 std::stringstream rawstr(str);
199 rawstr << "GepVFGNode ID: " << getId() << " ";
200 rawstr << getSVFStmt()->toString();
201 return rawstr.str();
202}
203
205{
206 NodeBS nb;
207 nb.set(getRes()->getId());
208 return nb;
209}
210
211const std::string PHIVFGNode::toString() const
212{
213 std::string str;
214 std::stringstream rawstr(str);
215 rawstr << "PHIVFGNode ID: " << getId() << " ";
216 rawstr << "SVFVar: [" << res->getId() << " = PHI(";
217 for(PHIVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd();
218 it != eit; it++)
219 rawstr << it->second->getId() << ", ";
220 rawstr << ")]\t";
221 rawstr << " " << res->valueOnlyToString();
222 return rawstr.str();
223}
224
225
226const std::string IntraPHIVFGNode::toString() const
227{
228 std::string str;
229 std::stringstream rawstr(str);
230 rawstr << "IntraPHIVFGNode ID: " << getId() << " ";
231 rawstr << "SVFVar: [" << res->getId() << " = PHI(";
232 for(PHIVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd();
233 it != eit; it++)
234 rawstr << it->second->getId() << ", ";
235 rawstr << ")]\t";
236 rawstr << " " << res->valueOnlyToString();
237 return rawstr.str();
238}
239
241{
242 NodeBS nb;
244 return nb;
245}
246
247const std::string AddrVFGNode::toString() const
248{
249 std::string str;
250 std::stringstream rawstr(str);
251 rawstr << "AddrVFGNode ID: " << getId() << " ";
252 rawstr << getSVFStmt()->toString();
253 return rawstr.str();
254}
255
256
257const std::string ArgumentVFGNode::toString() const
258{
259 std::string str;
260 std::stringstream rawstr(str);
261 rawstr << "ArgumentVFGNode ID: " << getId() << " ";
262 rawstr << param->toString();
263 return rawstr.str();
264}
265
267{
268 NodeBS nb;
269 nb.set(getParam()->getId());
270 return nb;
271}
272
273const std::string ActualParmVFGNode::toString() const
274{
275 std::string str;
276 std::stringstream rawstr(str);
277 rawstr << "ActualParmVFGNode ID: " << getId() << " ";
278 rawstr << "CS[" << getCallSite()->getSourceLoc() << "]";
279 rawstr << param->toString();
280 return rawstr.str();
281}
282
284{
285 NodeBS nb;
286 nb.set(getParam()->getId());
287 return nb;
288}
289
290const std::string FormalParmVFGNode::toString() const
291{
292 std::string str;
293 std::stringstream rawstr(str);
294 rawstr << "FormalParmVFGNode ID: " << getId() << " ";
295 rawstr << "Fun[" << getFun()->getName() << "]";
296 rawstr << param->toString();
297 return rawstr.str();
298}
299
301{
302 NodeBS nb;
303 nb.set(getRev()->getId());
304 return nb;
305}
306
307const std::string ActualRetVFGNode::toString() const
308{
309 std::string str;
310 std::stringstream rawstr(str);
311 rawstr << "ActualRetVFGNode ID: " << getId() << " ";
312 rawstr << "CS[" << getCallSite()->getSourceLoc() << "]";
313 rawstr << param->toString();
314 return rawstr.str();
315}
316
317
319{
320 NodeBS nb;
321 nb.set(getRet()->getId());
322 return nb;
323}
324
325const std::string FormalRetVFGNode::toString() const
326{
327 std::string str;
328 std::stringstream rawstr(str);
329 rawstr << "FormalRetVFGNode ID: " << getId() << " ";
330 rawstr << "Fun[" << getFun()->getName() << "]";
331 rawstr << param->toString();
332 return rawstr.str();
333}
334
335
336const std::string InterPHIVFGNode::toString() const
337{
338 std::string str;
339 std::stringstream rawstr(str);
340 if(isFormalParmPHI())
341 rawstr << "FormalParmPHI ID: " << getId() << " SVFVar ID: " << res->getId() << "\n" << res->valueOnlyToString();
342 else
343 rawstr << "ActualRetPHI ID: " << getId() << " SVFVar ID: " << res->getId() << "\n" << res->valueOnlyToString();
344 return rawstr.str();
345}
346
348{
349 NodeBS nb;
350 nb.set(getSVFVar()->getId());
351 return nb;
352}
353
354const std::string NullPtrVFGNode::toString() const
355{
356 std::string str;
357 std::stringstream rawstr(str);
358 rawstr << "NullPtrVFGNode ID: " << getId();
359 rawstr << " SVFVar ID: " << node->getId() << "\n";
360 return rawstr.str();
361}
362
363
364const std::string VFGEdge::toString() const
365{
366 std::string str;
367 std::stringstream rawstr(str);
368 rawstr << "VFGEdge: [" << getDstID() << "<--" << getSrcID() << "]\t";
369 return rawstr.str();
370}
371
372const std::string DirectSVFGEdge::toString() const
373{
374 std::string str;
375 std::stringstream rawstr(str);
376 rawstr << "DirectVFGEdge: [" << getDstID() << "<--" << getSrcID() << "]\t";
377 return rawstr.str();
378}
379
380const std::string IntraDirSVFGEdge::toString() const
381{
382 std::string str;
383 std::stringstream rawstr(str);
384 rawstr << "IntraDirSVFGEdge: [" << getDstID() << "<--" << getSrcID() << "]\t";
385 return rawstr.str();
386}
387
388const std::string CallDirSVFGEdge::toString() const
389{
390 std::string str;
391 std::stringstream rawstr(str);
392 rawstr << "CallDirSVFGEdge CallSite ID: " << getCallSiteId() << " [";
393 rawstr << getDstID() << "<--" << getSrcID() << "]\t";
394 return rawstr.str();
395}
396
397const std::string RetDirSVFGEdge::toString() const
398{
399 std::string str;
400 std::stringstream rawstr(str);
401 rawstr << "RetDirSVFGEdge CallSite ID: " << getCallSiteId() << " [";
402 rawstr << getDstID() << "<--" << getSrcID() << "]\t";
403 return rawstr.str();
404}
405
406
407
409 ArgumentVFGNode(id, n, FRet), fun(f)
410{
411}
412
414{
415
416}
417
426VFG::VFG(CallGraph* cg, VFGK k): totalVFGNode(0), callgraph(cg), pag(SVFIR::getPAG()), kind(k)
427{
428
429 DBOUT(DGENERAL, outs() << pasMsg("\tCreate VFG Top Level Node\n"));
430 addVFGNodes();
431
432 DBOUT(DGENERAL, outs() << pasMsg("\tCreate SVFG Direct Edge\n"));
434}
435
440{
441 pag = nullptr;
442}
443
444
449{
450
451 // initialize dummy definition null pointers in order to uniform the construction
452 // to be noted for black hole pointer it has already has address edge connected,
453 // and its definition will be set when processing addr SVFIR edge.
455
456 // initialize address nodes
458 for (SVFStmt::SVFStmtSetTy::iterator iter = addrs.begin(), eiter =
459 addrs.end(); iter != eiter; ++iter)
460 {
461 addAddrVFGNode(SVFUtil::cast<AddrStmt>(*iter));
462 }
463
464 // initialize copy nodes
466 for (SVFStmt::SVFStmtSetTy::iterator iter = copys.begin(), eiter =
467 copys.end(); iter != eiter; ++iter)
468 {
469 const CopyStmt* edge = SVFUtil::cast<CopyStmt>(*iter);
470 assert(!isPhiCopyEdge(edge) && "Copy edges can not be a PhiNode (or from PhiNode)");
472 }
473
474 // initialize gep nodes
476 for (SVFStmt::SVFStmtSetTy::iterator iter = ngeps.begin(), eiter =
477 ngeps.end(); iter != eiter; ++iter)
478 {
479 addGepVFGNode(SVFUtil::cast<GepStmt>(*iter));
480 }
481
482 // initialize load nodes
484 for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter =
485 loads.end(); iter != eiter; ++iter)
486 {
487 addLoadVFGNode(SVFUtil::cast<LoadStmt>(*iter));
488 }
489
490 // initialize store nodes
492 for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter =
493 stores.end(); iter != eiter; ++iter)
494 {
495 addStoreVFGNode(SVFUtil::cast<StoreStmt>(*iter));
496 }
497
499 for (SVFStmt::SVFStmtSetTy::iterator iter = forks.begin(), eiter =
500 forks.end(); iter != eiter; ++iter)
501 {
502 TDForkPE* forkedge = SVFUtil::cast<TDForkPE>(*iter);
503 for(u32_t i = 0; i < forkedge->getOpVarNum(); i++)
504 addActualParmVFGNode(forkedge->getOpVar(i), forkedge->getOpCallICFGNode(i));
505 }
506
507 // initialize actual parameter nodes
508 for(SVFIR::CSToArgsListMap::iterator it = pag->getCallSiteArgsMap().begin(), eit = pag->getCallSiteArgsMap().end(); it !=eit; ++it)
509 {
510
511 for(SVFIR::ValVarList::iterator pit = it->second.begin(), epit = it->second.end(); pit!=epit; ++pit)
512 {
513 const ValVar* svfVar = *pit;
516 }
517 }
518
519 // initialize actual return nodes (callsite return)
520 for(SVFIR::CSToRetMap::iterator it = pag->getCallSiteRets().begin(), eit = pag->getCallSiteRets().end(); it !=eit; ++it)
521 {
522
526 if(isInterestedSVFVar(it->second) == false || hasDef(it->second))
527 continue;
528
529 addActualRetVFGNode(it->second,it->first->getCallICFGNode());
530 }
531
532 // initialize formal parameter nodes
533 for(SVFIR::FunToArgsListMap::iterator it = pag->getFunArgsMap().begin(), eit = pag->getFunArgsMap().end(); it !=eit; ++it)
534 {
535 const FunObjVar* func = it->first;
536
537 for(SVFIR::ValVarList::iterator pit = it->second.begin(), epit = it->second.end(); pit!=epit; ++pit)
538 {
539 const ValVar* param = *pit;
540 if (isInterestedSVFVar(param) == false || hasBlackHoleConstObjAddrAsDef(param))
541 continue;
542
543 const CallPE* callPE = pag->getCallPEForFormalParm(param);
544 addFormalParmVFGNode(param,func,callPE);
545 }
546
547 if (func->isVarArg())
548 {
551 continue;
552
555 }
556 }
557
558 // initialize formal return nodes (callee return)
559 for (SVFIR::FunToRetMap::iterator it = pag->getFunRets().begin(), eit = pag->getFunRets().end(); it != eit; ++it)
560 {
561 const FunObjVar* func = it->first;
562
563 const ValVar* uniqueFunRetNode = it->second;
564
565 RetPESet retPEs;
566 if (uniqueFunRetNode->hasOutgoingEdges(SVFStmt::Ret))
567 {
568 for (SVFStmt::SVFStmtSetTy::const_iterator cit = uniqueFunRetNode->getOutgoingEdgesBegin(SVFStmt::Ret),
569 ecit = uniqueFunRetNode->getOutgoingEdgesEnd(SVFStmt::Ret);
570 cit != ecit; ++cit)
571 {
572 const RetPE* retPE = SVFUtil::cast<RetPE>(*cit);
573 if (isInterestedSVFVar(retPE->getLHSVar()))
574 retPEs.insert(retPE);
575 }
576 }
577
580 }
581
582 // initialize llvm phi nodes (phi of top level pointers)
584 for (SVFStmt::SVFStmtSetTy::iterator iter = phis.begin(), eiter =
585 phis.end(); iter != eiter; ++iter)
586 {
587 const PhiStmt* edge = SVFUtil::cast<PhiStmt>(*iter);
588 if(isInterestedSVFVar(edge->getRes()))
590 }
591 // initialize select statement
593 for (SVFStmt::SVFStmtSetTy::iterator iter = selects.begin(), eiter =
594 selects.end(); iter != eiter; ++iter)
595 {
596 const MultiOpndStmt* edge = SVFUtil::cast<MultiOpndStmt>(*iter);
597 if(isInterestedSVFVar(edge->getRes()))
599 }
600 // initialize llvm binary nodes (binary operators)
602 for (SVFStmt::SVFStmtSetTy::iterator iter = binaryops.begin(), eiter =
603 binaryops.end(); iter != eiter; ++iter)
604 {
605 const BinaryOPStmt* edge = SVFUtil::cast<BinaryOPStmt>(*iter);
606 if(isInterestedSVFVar(edge->getRes()))
608 }
609 // initialize llvm unary nodes (unary operators)
611 for (SVFStmt::SVFStmtSetTy::iterator iter = unaryops.begin(), eiter =
612 unaryops.end(); iter != eiter; ++iter)
613 {
614 const UnaryOPStmt* edge = SVFUtil::cast<UnaryOPStmt>(*iter);
615 if(isInterestedSVFVar(edge->getRes()))
617 }
618 // initialize llvm unary nodes (unary operators)
620 for (SVFStmt::SVFStmtSetTy::iterator iter = brs.begin(), eiter =
621 brs.end(); iter != eiter; ++iter)
622 {
623 const BranchStmt* edge = SVFUtil::cast<BranchStmt>(*iter);
624 if(isInterestedSVFVar(edge->getBranchInst()))
626 }
627 // initialize llvm cmp nodes (comparison)
629 for (SVFStmt::SVFStmtSetTy::iterator iter = cmps.begin(), eiter =
630 cmps.end(); iter != eiter; ++iter)
631 {
632 const CmpStmt* edge = SVFUtil::cast<CmpStmt>(*iter);
633 if(isInterestedSVFVar(edge->getRes()))
635 }
636}
637
642{
647 if (edge != nullptr)
648 {
649 assert(edge->isDirectVFGEdge() && "this should be a direct value flow edge!");
650 return nullptr;
651 }
652 else
653 {
654 if(srcNode!=dstNode)
655 {
657 return (addVFGEdge(directEdge) ? directEdge : nullptr);
658 }
659 else
660 return nullptr;
661 }
662}
663
668{
672 if (edge != nullptr)
673 {
674 assert(edge->isCallDirectVFGEdge() && "this should be a direct value flow edge!");
675 return nullptr;
676 }
677 else
678 {
680 return (addVFGEdge(callEdge) ? callEdge : nullptr);
681 }
682}
683
688{
692 if (edge != nullptr)
693 {
694 assert(edge->isRetDirectVFGEdge() && "this should be a direct value flow edge!");
695 return nullptr;
696 }
697 else
698 {
700 return (addVFGEdge(retEdge) ? retEdge : nullptr);
701 }
702}
703
704
709{
710
711 for(iterator it = begin(), eit = end(); it!=eit; ++it)
712 {
713 NodeID nodeId = it->first;
714 VFGNode* node = it->second;
715
716 if(StmtVFGNode* stmtNode = SVFUtil::dyn_cast<StmtVFGNode>(node))
717 {
719 if(SVFUtil::isa<AddrVFGNode>(stmtNode))
720 continue;
722 if (stmtNode->getSrcNode()->isConstDataOrAggDataButNotNullPtr() == false)
723 // for ptr vfg, we skip src node of integer type if it is at a int2ptr copystmt
724 if(isInterestedSVFVar(stmtNode->getSrcNode()))
725 addIntraDirectVFEdge(getDef(SVFUtil::cast<ValVar>(stmtNode->getSrcNode())), nodeId);
726 if (const GepStmt* gepStmt = SVFUtil::dyn_cast<GepStmt>(stmtNode->getSVFStmt()))
727 {
728 for (const auto &varType: gepStmt->getOffsetVarAndGepTypePairVec())
729 {
730 if(varType.first->isConstDataOrAggDataButNotNullPtr() || isInterestedSVFVar(varType.first) == false)
731 continue;
733 }
734 }
736 if(SVFUtil::isa<StoreVFGNode>(stmtNode) && (stmtNode->getDstNode()->isConstDataOrAggDataButNotNullPtr() == false))
737 {
738 addIntraDirectVFEdge(getDef(SVFUtil::cast<ValVar>(stmtNode->getDstNode())), nodeId);
739 }
740
741 }
742 else if(PHIVFGNode* phiNode = SVFUtil::dyn_cast<PHIVFGNode>(node))
743 {
744 for (PHIVFGNode::OPVers::const_iterator it = phiNode->opVerBegin(), eit = phiNode->opVerEnd(); it != eit; it++)
745 {
746 if (it->second->isConstDataOrAggDataButNotNullPtr() == false)
748 }
749 }
750 else if(BinaryOPVFGNode* binaryNode = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
751 {
752 for (BinaryOPVFGNode::OPVers::const_iterator it = binaryNode->opVerBegin(), eit = binaryNode->opVerEnd(); it != eit; it++)
753 {
754 if (it->second->isConstDataOrAggDataButNotNullPtr() == false)
756 }
757 }
758 else if(UnaryOPVFGNode* unaryNode = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
759 {
760 for (UnaryOPVFGNode::OPVers::const_iterator it = unaryNode->opVerBegin(), eit = unaryNode->opVerEnd(); it != eit; it++)
761 {
762 if (it->second->isConstDataOrAggDataButNotNullPtr() == false)
764 }
765 }
766 else if(CmpVFGNode* cmpNode = SVFUtil::dyn_cast<CmpVFGNode>(node))
767 {
768 for (CmpVFGNode::OPVers::const_iterator it = cmpNode->opVerBegin(), eit = cmpNode->opVerEnd(); it != eit; it++)
769 {
770 if (it->second->isConstDataOrAggDataButNotNullPtr() == false)
772 }
773 }
774 else if(BranchVFGNode* branchNode = SVFUtil::dyn_cast<BranchVFGNode>(node))
775 {
776 const ValVar* cond = branchNode->getBranchStmt()->getCondition();
777 if (cond->isConstDataOrAggDataButNotNullPtr() == false)
779 }
780 else if(ActualParmVFGNode* actualParm = SVFUtil::dyn_cast<ActualParmVFGNode>(node))
781 {
782 if (actualParm->getParam()->isConstDataOrAggDataButNotNullPtr() == false)
784 }
785 else if(FormalParmVFGNode* formalParm = SVFUtil::dyn_cast<FormalParmVFGNode>(node))
786 {
787 if(const CallPE* callPE = formalParm->getCallPE())
788 {
789 for(u32_t i = 0; i < callPE->getOpVarNum(); i++)
790 {
791 if(isInterestedSVFVar(callPE->getOpVar(i)))
792 {
793 const CallICFGNode* cs = callPE->getOpCallICFGNode(i);
794 ActualParmVFGNode* acutalParm = getActualParmVFGNode(callPE->getOpVar(i), cs);
796 }
797 }
798 }
799 }
800 else if(FormalRetVFGNode* calleeRet = SVFUtil::dyn_cast<FormalRetVFGNode>(node))
801 {
804
806 for(RetPESet::const_iterator it = calleeRet->retPEBegin(), eit = calleeRet->retPEEnd(); it!=eit; ++it)
807 {
808 ActualRetVFGNode* callsiteRev = getActualRetVFGNode((*it)->getLHSVar());
809 const CallICFGNode* callBlockNode = (*it)->getCallSite();
811 }
812 }
815 }
816
819 {
822 for (SVFStmt::SVFStmtSetTy::iterator iter = forks.begin(), eiter =
823 forks.end(); iter != eiter; ++iter)
824 {
825 TDForkPE* forkedge = SVFUtil::cast<TDForkPE>(*iter);
827 for(u32_t i = 0; i < forkedge->getOpVarNum(); i++)
828 {
829 if(isInterestedSVFVar(forkedge->getOpVar(i)))
830 {
831 const CallICFGNode* cs = forkedge->getOpCallICFGNode(i);
834 }
835 }
836 }
839 for (SVFStmt::SVFStmtSetTy::iterator iter = joins.begin(), eiter =
840 joins.end(); iter != eiter; ++iter)
841 {
842 TDJoinPE* joinedge = SVFUtil::cast<TDJoinPE>(*iter);
843 NodeID callsiteRev = getDef(joinedge->getLHSVar());
845 addRetEdge(calleeRet->getId(),callsiteRev, getCallSiteID(joinedge->getCallSite(), calleeRet->getFun()));
846 }
847 }
848}
849
854{
855 VFGEdge edge(src,dst,kind);
858 if (outEdge && inEdge)
859 {
860 assert(outEdge == inEdge && "edges not match");
861 return outEdge;
862 }
863 else
864 return nullptr;
865}
866
867
872{
873 VFGEdge edge(src,dst,kind);
876 if (outEdge && inEdge)
877 {
878 assert(outEdge == inEdge && "edges not match");
879 return outEdge;
880 }
881 else
882 return nullptr;
883}
884
889{
893 if (outEdge && inEdge)
894 {
895 assert(outEdge == inEdge && "edges not match");
896 return outEdge;
897 }
898 else
899 return nullptr;
900}
901
902
907{
908 return hasIntraVFGEdge(const_cast<VFGNode*>(src),const_cast<VFGNode*>(dst),kind);
909}
910
911
915void VFG::dump(const std::string& file, bool simple)
916{
918}
919
924{
925 SVF::ViewGraph(this, "Value Flow Graph");
926}
927
928
930{
931 VFGEdgeSetTy vfEdgesAtIndCallSite;
932 CallGraph::CallEdgeMap::const_iterator iter = pta->getIndCallMap().begin();
933 CallGraph::CallEdgeMap::const_iterator eiter = pta->getIndCallMap().end();
934 for (; iter != eiter; iter++)
935 {
936 const CallICFGNode* newcs = iter->first;
937 assert(newcs->isIndirectCall() && "this is not an indirect call?");
939 for (PointerAnalysis::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
940 {
941 const FunObjVar* func = *func_iter;
942 connectCallerAndCallee(newcs, func, vfEdgesAtIndCallSite);
943 }
944 }
945}
946
952{
953 SVFIR * pag = SVFIR::getPAG();
954 CallSiteID csId = getCallSiteID(callBlockNode, callee);
955 const RetICFGNode* retBlockNode = callBlockNode->getRetICFGNode();
956 // connect actual and formal param
957 if (pag->hasCallSiteArgsMap(callBlockNode) && pag->hasFunArgsList(callee) &&
958 matchArgs(callBlockNode, callee))
959 {
960 const SVFIR::ValVarList& csArgList = pag->getCallSiteArgsList(callBlockNode);
962 SVFIR::ValVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end();
963 SVFIR::ValVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end();
964 for (; funArgIt != funArgEit && csArgIt != csArgEit; funArgIt++, csArgIt++)
965 {
966 const ValVar *cs_arg = *csArgIt;
967 const ValVar *fun_arg = *funArgIt;
969 connectAParamAndFParam(cs_arg, fun_arg, callBlockNode, csId, edges);
970 }
971 assert(funArgIt == funArgEit && "function has more arguments than call site");
972
973 if (callee->isVarArg())
974 {
978 {
979 for (; csArgIt != csArgEit; csArgIt++)
980 {
981 const ValVar *cs_arg = *csArgIt;
983 connectAParamAndFParam(cs_arg, varFunArgNode, callBlockNode, csId, edges);
984 }
985 }
986 }
987 }
988
989 // connect actual return and formal return
991 {
996 }
997}
998
1002const SVFVar* VFG::getLHSTopLevPtr(const VFGNode* node) const
1003{
1004
1005 if(const AddrVFGNode* addr = SVFUtil::dyn_cast<AddrVFGNode>(node))
1006 return addr->getDstNode();
1007 else if(const CopyVFGNode* copy = SVFUtil::dyn_cast<CopyVFGNode>(node))
1008 return copy->getDstNode();
1009 else if(const GepVFGNode* gep = SVFUtil::dyn_cast<GepVFGNode>(node))
1010 return gep->getDstNode();
1011 else if(const LoadVFGNode* load = SVFUtil::dyn_cast<LoadVFGNode>(node))
1012 return load->getDstNode();
1013 else if(const PHIVFGNode* phi = SVFUtil::dyn_cast<PHIVFGNode>(node))
1014 return phi->getRes();
1015 else if(const CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
1016 return cmp->getRes();
1017 else if(const BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
1018 return bop->getRes();
1019 else if(const UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
1020 return uop->getRes();
1021 else if(const ActualParmVFGNode* ap = SVFUtil::dyn_cast<ActualParmVFGNode>(node))
1022 return ap->getParam();
1023 else if(const FormalParmVFGNode*fp = SVFUtil::dyn_cast<FormalParmVFGNode>(node))
1024 return fp->getParam();
1025 else if(const ActualRetVFGNode* ar = SVFUtil::dyn_cast<ActualRetVFGNode>(node))
1026 return ar->getRev();
1027 else if(const FormalRetVFGNode* fr = SVFUtil::dyn_cast<FormalRetVFGNode>(node))
1028 return fr->getRet();
1029 else if(const NullPtrVFGNode* nullVFG = SVFUtil::dyn_cast<NullPtrVFGNode>(node))
1030 return nullVFG->getSVFVar();
1031 else
1032 assert(false && "unexpected node kind!");
1033 return nullptr;
1034}
1035
1040{
1041 if(const FormalParmVFGNode* fp = SVFUtil::dyn_cast<FormalParmVFGNode>(node))
1042 {
1043 return fp->getFun();
1044 }
1045 else if(const InterPHIVFGNode* phi = SVFUtil::dyn_cast<InterPHIVFGNode>(node))
1046 {
1047 if(phi->isFormalParmPHI())
1048 return phi->getFun();
1049 }
1050 return nullptr;
1051}
1052
1053
1055{
1056 return getSVFStmt()->getValue();
1057}
1058
1060{
1061 return getRes();
1062}
1063
1065{
1066 return getRes();
1067}
1068
1070{
1071 return getRes();
1072}
1073
1075{
1076 return param;
1077}
1078
1082namespace SVF
1083{
1084template<>
1086{
1087
1089 DOTGraphTraits(bool isSimple = false) :
1090 DOTGraphTraits<SVFIR*>(isSimple)
1091 {
1092 }
1093
1095 static std::string getGraphName(VFG*)
1096 {
1097 return "VFG";
1098 }
1099
1100 std::string getNodeLabel(NodeType *node, VFG *graph)
1101 {
1102 if (isSimple())
1103 return getSimpleNodeLabel(node, graph);
1104 else
1105 return getCompleteNodeLabel(node, graph);
1106 }
1107
1109 static std::string getSimpleNodeLabel(NodeType *node, VFG*)
1110 {
1111 std::string str;
1112 std::stringstream rawstr(str);
1113 if(StmtVFGNode* stmtNode = SVFUtil::dyn_cast<StmtVFGNode>(node))
1114 {
1115 rawstr << stmtNode->toString();
1116 }
1117 else if(PHIVFGNode* tphi = SVFUtil::dyn_cast<PHIVFGNode>(node))
1118 {
1119 rawstr << tphi->toString();
1120 }
1121 else if(FormalParmVFGNode* fp = SVFUtil::dyn_cast<FormalParmVFGNode>(node))
1122 {
1123 rawstr << fp->toString();
1124 }
1125 else if(ActualParmVFGNode* ap = SVFUtil::dyn_cast<ActualParmVFGNode>(node))
1126 {
1127 rawstr << ap->toString();
1128 }
1129 else if (ActualRetVFGNode* ar = SVFUtil::dyn_cast<ActualRetVFGNode>(node))
1130 {
1131 rawstr << ar->toString();
1132 }
1133 else if (FormalRetVFGNode* fr = SVFUtil::dyn_cast<FormalRetVFGNode>(node))
1134 {
1135 rawstr << fr->toString();
1136 }
1137 else if(SVFUtil::isa<NullPtrVFGNode>(node))
1138 {
1139 rawstr << "NullPtr";
1140 }
1141 else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
1142 {
1143 rawstr << bop->toString();
1144 }
1145 else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
1146 {
1147 rawstr << uop->toString();
1148 }
1149 else if(CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
1150 {
1151 rawstr << cmp->toString();;
1152 }
1153 else if (BranchVFGNode* branchNode = SVFUtil::dyn_cast<BranchVFGNode>(node))
1154 {
1155 rawstr << branchNode->toString();
1156 }
1157 else
1158 assert(false && "what else kinds of nodes do we have??");
1159
1160 return rawstr.str();
1161 }
1162
1164 static std::string getCompleteNodeLabel(NodeType *node, VFG*)
1165 {
1166
1167 std::string str;
1168 std::stringstream rawstr(str);
1169 if(StmtVFGNode* stmtNode = SVFUtil::dyn_cast<StmtVFGNode>(node))
1170 {
1171 rawstr << stmtNode->toString();
1172 }
1173 else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
1174 {
1175 rawstr << bop->toString();
1176 }
1177 else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
1178 {
1179 rawstr << uop->toString();
1180 }
1181 else if(CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
1182 {
1183 rawstr << cmp->toString();
1184 }
1185 else if(PHIVFGNode* phi = SVFUtil::dyn_cast<PHIVFGNode>(node))
1186 {
1187 rawstr << phi->toString();
1188 }
1189 else if(FormalParmVFGNode* fp = SVFUtil::dyn_cast<FormalParmVFGNode>(node))
1190 {
1191 rawstr << fp->toString();
1192 }
1193 else if(ActualParmVFGNode* ap = SVFUtil::dyn_cast<ActualParmVFGNode>(node))
1194 {
1195 rawstr << ap->toString();
1196 }
1197 else if(NullPtrVFGNode* nptr = SVFUtil::dyn_cast<NullPtrVFGNode>(node))
1198 {
1199 rawstr << nptr->toString();
1200 }
1201 else if (ActualRetVFGNode* ar = SVFUtil::dyn_cast<ActualRetVFGNode>(node))
1202 {
1203 rawstr << ar->toString();
1204 }
1205 else if (FormalRetVFGNode* fr = SVFUtil::dyn_cast<FormalRetVFGNode>(node))
1206 {
1207 rawstr << fr->toString();
1208 }
1209 else if (MRSVFGNode* mr = SVFUtil::dyn_cast<MRSVFGNode>(node))
1210 {
1211 rawstr << mr->toString();
1212 }
1213 else if (BranchVFGNode* branchNode = SVFUtil::dyn_cast<BranchVFGNode>(node))
1214 {
1215 rawstr << branchNode->toString();
1216 }
1217 else
1218 assert(false && "what else kinds of nodes do we have??");
1219
1220 return rawstr.str();
1221 }
1222
1223 static std::string getNodeAttributes(NodeType *node, VFG*)
1224 {
1225 std::string str;
1226 std::stringstream rawstr(str);
1227
1228 rawstr << "shape=record";
1229
1230 if(StmtVFGNode* stmtNode = SVFUtil::dyn_cast<StmtVFGNode>(node))
1231 {
1232 const SVFStmt* edge = stmtNode->getSVFStmt();
1233 if (SVFUtil::isa<AddrStmt>(edge))
1234 {
1235 rawstr << ",color=green";
1236 }
1237 else if (SVFUtil::isa<CopyStmt>(edge))
1238 {
1239 rawstr << ",color=black";
1240 }
1241 else if (SVFUtil::isa<RetPE>(edge))
1242 {
1243 rawstr << ",color=black,style=dotted";
1244 }
1245 else if (SVFUtil::isa<GepStmt>(edge))
1246 {
1247 rawstr << ",color=purple";
1248 }
1249 else if (SVFUtil::isa<StoreStmt>(edge))
1250 {
1251 rawstr << ",color=blue";
1252 }
1253 else if (SVFUtil::isa<LoadStmt>(edge))
1254 {
1255 rawstr << ",color=red";
1256 }
1257 else
1258 {
1259 assert(0 && "No such kind edge!!");
1260 }
1261 rawstr << "";
1262 }
1263 else if (SVFUtil::isa<CmpVFGNode>(node))
1264 {
1265 rawstr << ",color=grey";
1266 }
1267 else if (SVFUtil::isa<BinaryOPVFGNode>(node))
1268 {
1269 rawstr << ",color=grey";
1270 }
1271 else if (SVFUtil::isa<UnaryOPVFGNode>(node))
1272 {
1273 rawstr << ",color=grey";
1274 }
1275 else if(SVFUtil::isa<PHIVFGNode>(node))
1276 {
1277 rawstr << ",color=black";
1278 }
1279 else if(SVFUtil::isa<NullPtrVFGNode>(node))
1280 {
1281 rawstr << ",color=grey";
1282 }
1283 else if(SVFUtil::isa<FormalParmVFGNode>(node))
1284 {
1285 rawstr << ",color=yellow,penwidth=2";
1286 }
1287 else if(SVFUtil::isa<ActualParmVFGNode>(node))
1288 {
1289 rawstr << ",color=yellow,penwidth=2";
1290 }
1291 else if (SVFUtil::isa<ActualRetVFGNode>(node))
1292 {
1293 rawstr << ",color=yellow,penwidth=2";
1294 }
1295 else if (SVFUtil::isa<FormalRetVFGNode>(node))
1296 {
1297 rawstr << ",color=yellow,penwidth=2";
1298 }
1299 else if (SVFUtil::isa<MRSVFGNode>(node))
1300 {
1301 rawstr << ",color=orange,penwidth=2";
1302 }
1303 else if (SVFUtil::isa<BranchVFGNode>(node))
1304 {
1305 rawstr << ",color=gold,penwidth=2";
1306 }
1307 else
1308 assert(false && "no such kind of node!!");
1309
1310 return rawstr.str();
1311 }
1312
1313 template<class EdgeIter>
1314 static std::string getEdgeAttributes(NodeType*, EdgeIter EI, VFG*)
1315 {
1316 VFGEdge* edge = *(EI.getCurrent());
1317 assert(edge && "No edge found!!");
1318 if (SVFUtil::isa<DirectSVFGEdge>(edge))
1319 {
1320 if (SVFUtil::isa<CallDirSVFGEdge>(edge))
1321 return "style=solid,color=red";
1322 else if (SVFUtil::isa<RetDirSVFGEdge>(edge))
1323 return "style=solid,color=blue";
1324 else
1325 return "style=solid";
1326 }
1327 else if (SVFUtil::isa<IndirectSVFGEdge>(edge))
1328 {
1329 if (SVFUtil::isa<CallIndSVFGEdge>(edge))
1330 return "style=dashed,color=red";
1331 else if (SVFUtil::isa<RetIndSVFGEdge>(edge))
1332 return "style=dashed,color=blue";
1333 else
1334 return "style=dashed";
1335 }
1336 else
1337 {
1338 assert(false && "what else edge we have?");
1339 }
1340 return "";
1341 }
1342
1343 template<class EdgeIter>
1345 {
1346 VFGEdge* edge = *(EI.getCurrent());
1347 assert(edge && "No edge found!!");
1348
1349 std::string str;
1350 std::stringstream rawstr(str);
1351 if (CallDirSVFGEdge* dirCall = SVFUtil::dyn_cast<CallDirSVFGEdge>(edge))
1352 rawstr << dirCall->getCallSiteId();
1353 else if (RetDirSVFGEdge* dirRet = SVFUtil::dyn_cast<RetDirSVFGEdge>(edge))
1354 rawstr << dirRet->getCallSiteId();
1355
1356 return rawstr.str();
1357 }
1358};
1359} // 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
copy
Definition cJSON.cpp:414
cJSON * n
Definition cJSON.cpp:2558
const std::string toString() const override
Definition VFG.cpp:273
const ValVar * getParam() const
Return parameter.
Definition VFGNode.h:989
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:266
const CallICFGNode * getCallSite() const
Return callsite.
Definition VFGNode.h:983
const CallICFGNode * getCallSite() const
Return callsite.
Definition VFGNode.h:1111
const std::string toString() const override
Definition VFG.cpp:307
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:300
const ValVar * getRev() const
Receive parameter at callsite.
Definition VFGNode.h:1121
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:240
const std::string toString() const override
Definition VFG.cpp:247
const std::string toString() const override
Definition VFG.cpp:257
const ValVar * param
Definition VFGNode.h:930
const SVFVar * getValue() const override
Return the corresponding LLVM value, if possible, nullptr otherwise.
Definition VFG.cpp:1074
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:132
const ValVar * getRes() const
Definition VFGNode.h:509
const SVFVar * getValue() const override
Return the corresponding LLVM value, if possible, nullptr otherwise.
Definition VFG.cpp:1064
const std::string toString() const override
Definition VFG.cpp:139
const ValVar * res
Definition VFGNode.h:467
OPVers::const_iterator opVerBegin() const
Definition VFGNode.h:517
OPVers::const_iterator opVerEnd() const
Definition VFGNode.h:521
virtual const std::string toString() const override
virtual const std::string toString() const override
Definition VFG.cpp:179
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:174
const BranchStmt * brstmt
Definition VFGNode.h:620
CallSiteID getCallSiteId() const
Return callsite ID.
Definition VFGEdge.h:223
virtual const std::string toString() const
Definition VFG.cpp:388
const RetICFGNode * getRetICFGNode() const
Return callsite.
Definition ICFGNode.h:439
const std::string getSourceLoc() const override
Definition ICFGNode.h:570
OPVers::const_iterator opVerBegin() const
Definition VFGNode.h:440
const ValVar * res
Definition VFGNode.h:390
const std::string toString() const override
Definition VFG.cpp:118
const ValVar * getRes() const
Definition VFGNode.h:432
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:111
OPVers::const_iterator opVerEnd() const
Definition VFGNode.h:444
const SVFVar * getValue() const override
Return the corresponding LLVM value, if possible, nullptr otherwise.
Definition VFG.cpp:1059
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:372
const ValVar * getParam() const
Return parameter.
Definition VFGNode.h:1041
const FunObjVar * getFun() const override
Return function.
Definition VFGNode.h:1047
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:283
const std::string toString() const override
Definition VFG.cpp:290
FormalRetVFGNode()
place holder
const FunObjVar * getFun() const override
Function.
Definition VFGNode.h:1177
const ValVar * getRet() const
Return value at callee.
Definition VFGNode.h:1172
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:318
const std::string toString() const override
Definition VFG.cpp:325
NodeID getDstID() const
NodeID getSrcID() const
get methods of the components
iterator begin()
Iterators.
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:188
const std::string toString() const override
Definition VFG.cpp:195
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
NodeID getNullPtr() const
Definition IRGraph.h:259
NodeID getVarargNode(const FunObjVar *func) const
getVarargNode - Return the unique node representing the variadic argument of a variadic function.
Definition IRGraph.cpp:67
bool isFormalParmPHI() const
Definition VFGNode.h:1236
const std::string toString() const override
Definition VFG.cpp:336
virtual const std::string toString() const
Definition VFG.cpp:380
const std::string toString() const override
Definition VFG.cpp:226
const std::string toString() const override
Definition VFG.cpp:64
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:57
const SVFVar * getSVFVar() const
Return corresponding SVFVar.
Definition VFGNode.h:1310
const SVFVar * node
Definition VFGNode.h:1297
const std::string toString() const override
Definition VFG.cpp:354
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:347
static const Option< bool > EnableThreadCallGraph
Definition Options.h:129
OPVers::const_iterator opVerBegin() const
Definition VFGNode.h:773
PHIVFGNode(NodeID id, const ValVar *r, VFGNodeK k=TPhi)
Constructor.
Definition VFG.cpp:413
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:204
const std::string toString() const override
Definition VFG.cpp:211
const ValVar * res
Definition VFGNode.h:740
OPVers::const_iterator opVerEnd() const
Definition VFGNode.h:777
const ValVar * getRes() const
Definition VFGNode.h:765
const SVFVar * getValue() const override
Return the corresponding LLVM value, if possible, nullptr otherwise.
Definition VFG.cpp:1069
Set< const FunObjVar * > FunctionSet
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
virtual const std::string toString() const
Definition VFG.cpp:397
CallSiteID getCallSiteId() const
Return callsite ID.
Definition VFGEdge.h:266
const ValVar * getLHSVar() const
CSToArgsListMap & getCallSiteArgsMap()
Get callsite argument list.
Definition SVFIR.h:388
bool funHasRet(const FunObjVar *func) const
Definition SVFIR.h:427
bool hasFunArgsList(const FunObjVar *func) const
Function has arguments list.
Definition SVFIR.h:366
const ValVar * getCallSiteRet(const RetICFGNode *cs) const
Get callsite return.
Definition SVFIR.h:405
const ValVarList & getFunArgsList(const FunObjVar *func) const
Get function arguments list.
Definition SVFIR.h:376
std::vector< const ValVar * > ValVarList
Definition SVFIR.h:58
CSToRetMap & getCallSiteRets()
Get callsite return.
Definition SVFIR.h:400
FunToRetMap & getFunRets()
Get function return list.
Definition SVFIR.h:416
bool hasCallSiteArgsMap(const CallICFGNode *cs) const
Callsite has argument list.
Definition SVFIR.h:383
bool callsiteHasRet(const RetICFGNode *cs) const
Definition SVFIR.h:411
const ValVar * getFunRet(const FunObjVar *func) const
Get function return list.
Definition SVFIR.h:421
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:118
const ValVarList & getCallSiteArgsList(const CallICFGNode *cs) const
Get callsite argument list.
Definition SVFIR.h:393
const ValVar * getValVar(NodeID id) const
Definition SVFIR.h:137
CallPE * getCallPEForFormalParm(const SVFVar *param) const
Get the CallPE for a formal parameter (phi-like, nullptr if not found)
Definition SVFIR.h:359
FunToArgsListMap & getFunArgsMap()
Get function arguments list.
Definition SVFIR.h:371
const SVFVar * getValue() const
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
virtual const std::string toString() const
NodeID getId() const
Get ID.
Definition SVFValue.h:161
virtual const std::string & getName() const
Definition SVFValue.h:187
const std::string valueOnlyToString() const
Definition LLVMUtil.cpp:740
virtual bool isConstDataOrAggDataButNotNullPtr() const
Check if this variable represents constant data/metadata but not null pointer.
void set(unsigned Idx)
const SVFVar * getValue() const override
Return the corresponding LLVM value, if possible, nullptr otherwise.
Definition VFG.cpp:1054
const SVFStmt * getSVFStmt() const
Definition VFGNode.h:147
const std::string toString() const override
Definition VFG.cpp:48
NodeID getDstNodeID() const
Definition VFGNode.h:157
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 NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:153
const ValVar * getRes() const
Definition VFGNode.h:583
OPVers::const_iterator opVerBegin() const
Definition VFGNode.h:596
const ValVar * res
Definition VFGNode.h:541
virtual const std::string toString() const override
Definition VFG.cpp:160
OPVers::const_iterator opVerEnd() const
Definition VFGNode.h:600
@ 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:364
virtual const std::string toString() const
Definition VFG.cpp:40
Definition VFG.h:51
FormalRetVFGNode * getFormalRetVFGNode(const SVFVar *fret) const
Definition VFG.h:315
VFGEdge::VFGEdgeSetTy VFGEdgeSetTy
Definition VFG.h:77
void updateCallGraph(PointerAnalysis *pta)
Update VFG based on pointer analysis results.
Definition VFG.cpp:929
NodeID getDef(const ValVar *valVar) const
Definition VFG.h:482
VFGEdge * addInterEdgeFromAPToFP(ActualParmVFGNode *src, FormalParmVFGNode *dst, CallSiteID csId)
Add inter VF edge from actual to formal parameters.
Definition VFG.h:424
void addStoreVFGNode(const StoreStmt *store)
Definition VFG.h:583
VFGEdge * addInterEdgeFromFRToAR(FormalRetVFGNode *src, ActualRetVFGNode *dst, CallSiteID csId)
Add inter VF edge from callee return to callsite receive parameter.
Definition VFG.h:429
void addBranchVFGNode(const BranchStmt *edge)
Add a BranchVFGNode.
Definition VFG.h:690
ActualParmVFGNode * getActualParmVFGNode(const SVFVar *aparm, const CallICFGNode *cs) const
Definition VFG.h:297
const SVFVar * getLHSTopLevPtr(const VFGNode *node) const
Definition VFG.cpp:1002
VFGNodeIDToNodeMapTy::iterator iterator
Definition VFG.h:80
SVFIR * pag
Definition VFG.h:104
VFGEdge * addRetEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
Definition VFG.cpp:687
virtual void connectAParamAndFParam(const ValVar *csArg, const ValVar *funArg, const CallICFGNode *cbn, CallSiteID csId, VFGEdgeSetTy &edges)
Connect VFG nodes between caller and callee for indirect call site.
Definition VFG.h:448
void addVFGNodes()
Create VFG nodes.
Definition VFG.cpp:448
void addLoadVFGNode(const LoadStmt *load)
Add a Load VFG node.
Definition VFG.h:575
CallSiteID getCallSiteID(const CallICFGNode *cs, const FunObjVar *func) const
Get callsite given a callsiteID.
Definition VFG.h:178
VFGK kind
Definition VFG.h:105
VFGEdge * addIntraDirectVFEdge(NodeID srcId, NodeID dstId)
Definition VFG.cpp:641
void checkIntraEdgeParents(const VFGNode *srcNode, const VFGNode *dstNode)
sanitize Intra edges, verify that both nodes belong to the same function.
Definition VFG.h:413
void addCopyVFGNode(const CopyStmt *copy)
Add a Copy VFG node.
Definition VFG.h:561
void addGepVFGNode(const GepStmt *gep)
Add a Gep VFG node.
Definition VFG.h:568
bool isPhiCopyEdge(const SVFStmt *copy) const
Definition VFG.h:520
bool hasDef(const ValVar *valVar) const
Definition VFG.h:488
void addFormalParmVFGNode(const ValVar *fparm, const FunObjVar *fun, const CallPE *callPE)
Add a formal parameter VFG node.
Definition VFG.h:600
virtual void connectFRetAndARet(const ValVar *funReturn, const ValVar *csReturn, CallSiteID csId, VFGEdgeSetTy &edges)
Connect formal-ret and actual ret.
Definition VFG.h:457
void addUnaryOPVFGNode(const UnaryOPStmt *edge)
Add a UnaryOperator VFG node.
Definition VFG.h:681
void addCmpVFGNode(const CmpStmt *edge)
Add a Compare VFG node.
Definition VFG.h:653
FormalParmVFGNode * getFormalParmVFGNode(const SVFVar *fparm) const
Definition VFG.h:309
bool addVFGEdge(VFGEdge *edge)
Add VFG edge.
Definition VFG.h:401
VFGNode * getVFGNode(NodeID id) const
Get a VFG node.
Definition VFG.h:145
void addActualParmVFGNode(const ValVar *aparm, const CallICFGNode *cs)
Definition VFG.h:592
const FunObjVar * isFunEntryVFGNode(const VFGNode *node) const
Whether a node is function entry VFGNode.
Definition VFG.cpp:1039
VFG(CallGraph *callgraph, VFGK k=FULLSVFG)
Constructor.
Definition VFG.cpp:426
VFGEdge * addCallEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
Definition VFG.cpp:667
void addNullPtrVFGNode(const ValVar *svfVar)
Definition VFG.h:547
virtual SVFStmt::SVFStmtSetTy & getSVFStmtSet(SVFStmt::PEDGEK kind)
Get SVFStmt set.
Definition VFG.h:498
void addFormalRetVFGNode(const ValVar *uniqueFunRet, const FunObjVar *fun, RetPESet &retPEs)
Definition VFG.h:612
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:853
void addBinaryOPVFGNode(const BinaryOPStmt *edge)
Add a BinaryOperator VFG node.
Definition VFG.h:667
void addAddrVFGNode(const AddrStmt *addr)
Add an Address VFG node.
Definition VFG.h:554
void addActualRetVFGNode(const ValVar *ret, const CallICFGNode *cs)
Add a callsite Receive VFG node.
Definition VFG.h:631
VFGEdge * hasInterVFGEdge(VFGNode *src, VFGNode *dst, VFGEdge::VFGEdgeK kind, CallSiteID csId)
Definition VFG.cpp:888
virtual bool isInterestedSVFVar(const SVFVar *node) const
Definition VFG.h:506
void connectDirectVFGEdges()
Create edges between VFG nodes within a function.
Definition VFG.cpp:708
VFGEdge * getIntraVFGEdge(const VFGNode *src, const VFGNode *dst, VFGEdge::VFGEdgeK kind)
Get a SVFG edge according to src and dst.
Definition VFG.cpp:906
ActualRetVFGNode * getActualRetVFGNode(const SVFVar *aret) const
Definition VFG.h:303
void view()
Dump graph into dot file.
Definition VFG.cpp:923
VFGEdge * hasThreadVFGEdge(VFGNode *src, VFGNode *dst, VFGEdge::VFGEdgeK kind)
Definition VFG.cpp:871
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
Definition VFG.cpp:915
bool hasBlackHoleConstObjAddrAsDef(const ValVar *valVar) const
Whether a SVFVar has a blackhole or const object as its definition.
Definition VFG.h:327
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:951
void destroy()
Clean up memory.
Definition VFG.cpp:439
void addIntraPHIVFGNode(const MultiOpndStmt *edge)
Add an llvm PHI VFG node.
Definition VFG.h:639
virtual const std::string toString() const
Get string representation.
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:105
bool matchArgs(const CallICFGNode *cs, const FunObjVar *callee)
Definition SVFUtil.cpp:312
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
for isBitcode
Definition BasicTypes.h:70
unsigned CallSiteID
Definition GeneralType.h:58
u32_t NodeID
Definition GeneralType.h:56
void ViewGraph(const GraphType &G, const std::string &name, bool ShortNames=false, GraphProgram::Name Program=GraphProgram::DOT)
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
SparseBitVector NodeBS
Definition GeneralType.h:62
unsigned u32_t
Definition GeneralType.h:47
static std::string getCompleteNodeLabel(NodeType *node, VFG *)
Return label of a VFG node with MemSSA information.
Definition VFG.cpp:1164
static std::string getNodeAttributes(NodeType *node, VFG *)
Definition VFG.cpp:1223
static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
Definition VFG.cpp:1344
DOTGraphTraits(bool isSimple=false)
Definition VFG.cpp:1089
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, VFG *)
Definition VFG.cpp:1314
std::string getNodeLabel(NodeType *node, VFG *graph)
Definition VFG.cpp:1100
static std::string getSimpleNodeLabel(NodeType *node, VFG *)
Return label of a VFG node without MemSSA information.
Definition VFG.cpp:1109
static std::string getGraphName(VFG *)
Return name of the graph.
Definition VFG.cpp:1095