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/CallGraph.h"
32#include "Graphs/GraphPrinter.h"
33#include "Graphs/SVFGNode.h"
34#include "Graphs/VFG.h"
35#include "Util/GeneralType.h"
36#include "Util/Options.h"
37#include "Util/SVFUtil.h"
38
39using namespace SVF;
40using namespace SVFUtil;
41
42const std::string VFGNode::toString() const
43{
44 std::string str;
45 std::stringstream rawstr(str);
46 rawstr << "VFGNode ID: " << getId() << " ";
47 return rawstr.str();
48}
49
50const std::string StmtVFGNode::toString() const
51{
52 std::string str;
53 std::stringstream rawstr(str);
54 rawstr << "StmtVFGNode ID: " << getId() << " ";
56 return rawstr.str();
57}
58
60{
61 NodeBS nb;
63 return nb;
64}
65
66const std::string LoadVFGNode::toString() const
67{
68 std::string str;
69 std::stringstream rawstr(str);
70 rawstr << "LoadVFGNode ID: " << getId() << " ";
72 return rawstr.str();
73}
74
76{
77 NodeBS nb;
78 for (auto edge: getOutEdges())
79 {
80 if (IndirectSVFGEdge *iedge = SVFUtil::dyn_cast<IndirectSVFGEdge>(edge))
81 {
82 nb |= iedge->getPointsTo();
83 }
84 }
85 return nb;
86}
87
88const std::string StoreVFGNode::toString() const
89{
90 std::string str;
91 std::stringstream rawstr(str);
92 rawstr << "StoreVFGNode ID: " << getId() << " ";
94 return rawstr.str();
95}
96
98{
99 NodeBS nb;
101 return nb;
102}
103
104const std::string CopyVFGNode::toString() const
105{
106 std::string str;
107 std::stringstream rawstr(str);
108 rawstr << "CopyVFGNode ID: " << getId() << " ";
109 rawstr << getSVFStmt()->toString();
110 return rawstr.str();
111}
112
114{
115 NodeBS nb;
116 nb.set(getRes()->getId());
117 return nb;
118}
119
120const std::string CmpVFGNode::toString() const
121{
122 std::string str;
123 std::stringstream rawstr(str);
124 rawstr << "CmpVFGNode ID: " << getId() << " ";
125 rawstr << "SVFStmt: [" << res->getId() << " = cmp(";
126 for(CmpVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd();
127 it != eit; it++)
128 rawstr << it->second->getId() << ", ";
129 rawstr << ")]\n";
130 rawstr << " " << res->valueOnlyToString();
131 return rawstr.str();
132}
133
135{
136 NodeBS nb;
137 nb.set(getRes()->getId());
138 return nb;
139}
140
141const std::string BinaryOPVFGNode::toString() const
142{
143 std::string str;
144 std::stringstream rawstr(str);
145 rawstr << "BinaryOPVFGNode ID: " << getId() << " ";
146 rawstr << "SVFStmt: [" << res->getId() << " = Binary(";
147 for(BinaryOPVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd();
148 it != eit; it++)
149 rawstr << it->second->getId() << ", ";
150 rawstr << ")]\t";
151 rawstr << " " << res->valueOnlyToString();
152 return rawstr.str();
153}
154
156{
157 NodeBS nb;
158 nb.set(getRes()->getId());
159 return nb;
160}
161
162const std::string UnaryOPVFGNode::toString() const
163{
164 std::string str;
165 std::stringstream rawstr(str);
166 rawstr << "UnaryOPVFGNode ID: " << getId() << " ";
167 rawstr << "SVFStmt: [" << res->getId() << " = Unary(";
168 for(UnaryOPVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd();
169 it != eit; it++)
170 rawstr << it->second->getId() << ", ";
171 rawstr << ")]\t";
172 rawstr << " " << res->valueOnlyToString();
173 return rawstr.str();
174}
175
177{
178 return NodeBS();
179}
180
181const std::string BranchVFGNode::toString() const
182{
183 std::string str;
184 std::stringstream rawstr(str);
185 rawstr << "BranchVFGNode ID: " << getId() << " ";
186 rawstr << "SVFStmt: [" << brstmt->toString() << "\t";
187 return rawstr.str();
188}
189
191{
192 NodeBS nb;
194 return nb;
195}
196
197const std::string GepVFGNode::toString() const
198{
199 std::string str;
200 std::stringstream rawstr(str);
201 rawstr << "GepVFGNode ID: " << getId() << " ";
202 rawstr << getSVFStmt()->toString();
203 return rawstr.str();
204}
205
207{
208 NodeBS nb;
209 nb.set(getRes()->getId());
210 return nb;
211}
212
213const std::string PHIVFGNode::toString() const
214{
215 std::string str;
216 std::stringstream rawstr(str);
217 rawstr << "PHIVFGNode ID: " << getId() << " ";
218 rawstr << "SVFVar: [" << res->getId() << " = PHI(";
219 for(PHIVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd();
220 it != eit; it++)
221 rawstr << it->second->getId() << ", ";
222 rawstr << ")]\t";
223 rawstr << " " << res->valueOnlyToString();
224 return rawstr.str();
225}
226
227
228const std::string IntraPHIVFGNode::toString() const
229{
230 std::string str;
231 std::stringstream rawstr(str);
232 rawstr << "IntraPHIVFGNode ID: " << getId() << " ";
233 rawstr << "SVFVar: [" << res->getId() << " = PHI(";
234 for(PHIVFGNode::OPVers::const_iterator it = opVerBegin(), eit = opVerEnd();
235 it != eit; it++)
236 rawstr << it->second->getId() << ", ";
237 rawstr << ")]\t";
238 rawstr << " " << res->valueOnlyToString();
239 return rawstr.str();
240}
241
243{
244 NodeBS nb;
246 return nb;
247}
248
249const std::string AddrVFGNode::toString() const
250{
251 std::string str;
252 std::stringstream rawstr(str);
253 rawstr << "AddrVFGNode ID: " << getId() << " ";
254 rawstr << getSVFStmt()->toString();
255 return rawstr.str();
256}
257
258
259const std::string ArgumentVFGNode::toString() const
260{
261 std::string str;
262 std::stringstream rawstr(str);
263 rawstr << "ArgumentVFGNode ID: " << getId() << " ";
264 rawstr << param->toString();
265 return rawstr.str();
266}
267
269{
270 NodeBS nb;
271 nb.set(getParam()->getId());
272 return nb;
273}
274
275const std::string ActualParmVFGNode::toString() const
276{
277 std::string str;
278 std::stringstream rawstr(str);
279 rawstr << "ActualParmVFGNode ID: " << getId() << " ";
280 rawstr << "CS[" << getCallSite()->getSourceLoc() << "]";
281 rawstr << param->toString();
282 return rawstr.str();
283}
284
286{
287 NodeBS nb;
288 nb.set(getParam()->getId());
289 return nb;
290}
291
292const std::string FormalParmVFGNode::toString() const
293{
294 std::string str;
295 std::stringstream rawstr(str);
296 rawstr << "FormalParmVFGNode ID: " << getId() << " ";
297 rawstr << "Fun[" << getFun()->getName() << "]";
298 rawstr << param->toString();
299 return rawstr.str();
300}
301
303{
304 NodeBS nb;
305 nb.set(getRev()->getId());
306 return nb;
307}
308
309const std::string ActualRetVFGNode::toString() const
310{
311 std::string str;
312 std::stringstream rawstr(str);
313 rawstr << "ActualRetVFGNode ID: " << getId() << " ";
314 rawstr << "CS[" << getCallSite()->getSourceLoc() << "]";
315 rawstr << param->toString();
316 return rawstr.str();
317}
318
319
321{
322 NodeBS nb;
323 nb.set(getRet()->getId());
324 return nb;
325}
326
327const std::string FormalRetVFGNode::toString() const
328{
329 std::string str;
330 std::stringstream rawstr(str);
331 rawstr << "FormalRetVFGNode ID: " << getId() << " ";
332 rawstr << "Fun[" << getFun()->getName() << "]";
333 rawstr << param->toString();
334 return rawstr.str();
335}
336
337
338const std::string InterPHIVFGNode::toString() const
339{
340 std::string str;
341 std::stringstream rawstr(str);
342 if(isFormalParmPHI())
343 rawstr << "FormalParmPHI ID: " << getId() << " SVFVar ID: " << res->getId() << "\n" << res->valueOnlyToString();
344 else
345 rawstr << "ActualRetPHI ID: " << getId() << " SVFVar ID: " << res->getId() << "\n" << res->valueOnlyToString();
346 return rawstr.str();
347}
348
350{
351 NodeBS nb;
352 nb.set(getSVFVar()->getId());
353 return nb;
354}
355
356const std::string NullPtrVFGNode::toString() const
357{
358 std::string str;
359 std::stringstream rawstr(str);
360 rawstr << "NullPtrVFGNode ID: " << getId();
361 rawstr << " SVFVar ID: " << node->getId() << "\n";
362 return rawstr.str();
363}
364
365
366const std::string VFGEdge::toString() const
367{
368 std::string str;
369 std::stringstream rawstr(str);
370 rawstr << "VFGEdge: [" << getDstID() << "<--" << getSrcID() << "]\t";
371 return rawstr.str();
372}
373
374const std::string DirectSVFGEdge::toString() const
375{
376 std::string str;
377 std::stringstream rawstr(str);
378 rawstr << "DirectVFGEdge: [" << getDstID() << "<--" << getSrcID() << "]\t";
379 return rawstr.str();
380}
381
382const std::string IntraDirSVFGEdge::toString() const
383{
384 std::string str;
385 std::stringstream rawstr(str);
386 rawstr << "IntraDirSVFGEdge: [" << getDstID() << "<--" << getSrcID() << "]\t";
387 return rawstr.str();
388}
389
390const std::string CallDirSVFGEdge::toString() const
391{
392 std::string str;
393 std::stringstream rawstr(str);
394 rawstr << "CallDirSVFGEdge CallSite ID: " << getCallSiteId() << " [";
395 rawstr << getDstID() << "<--" << getSrcID() << "]\t";
396 return rawstr.str();
397}
398
399const std::string RetDirSVFGEdge::toString() const
400{
401 std::string str;
402 std::stringstream rawstr(str);
403 rawstr << "RetDirSVFGEdge CallSite ID: " << getCallSiteId() << " [";
404 rawstr << getDstID() << "<--" << getSrcID() << "]\t";
405 return rawstr.str();
406}
407
408
409
411 ArgumentVFGNode(id, n, FRet), fun(f)
412{
413}
414
416{
417
418}
419
428VFG::VFG(CallGraph* cg, VFGK k): totalVFGNode(0), callgraph(cg), pag(SVFIR::getPAG()), kind(k)
429{
430
431 DBOUT(DGENERAL, outs() << pasMsg("\tCreate VFG Top Level Node\n"));
432 addVFGNodes();
433
434 DBOUT(DGENERAL, outs() << pasMsg("\tCreate SVFG Direct Edge\n"));
436}
437
442{
443 pag = nullptr;
444}
445
446
451{
452
453 // initialize dummy definition null pointers in order to uniform the construction
454 // to be noted for black hole pointer it has already has address edge connected,
455 // and its definition will be set when processing addr SVFIR edge.
457
458 // initialize address nodes
460 for (SVFStmt::SVFStmtSetTy::iterator iter = addrs.begin(), eiter =
461 addrs.end(); iter != eiter; ++iter)
462 {
463 addAddrVFGNode(SVFUtil::cast<AddrStmt>(*iter));
464 }
465
466 // initialize copy nodes
468 for (SVFStmt::SVFStmtSetTy::iterator iter = copys.begin(), eiter =
469 copys.end(); iter != eiter; ++iter)
470 {
471 const CopyStmt* edge = SVFUtil::cast<CopyStmt>(*iter);
472 assert(!isPhiCopyEdge(edge) && "Copy edges can not be a PhiNode (or from PhiNode)");
474 }
475
476 // initialize gep nodes
478 for (SVFStmt::SVFStmtSetTy::iterator iter = ngeps.begin(), eiter =
479 ngeps.end(); iter != eiter; ++iter)
480 {
481 addGepVFGNode(SVFUtil::cast<GepStmt>(*iter));
482 }
483
484 // initialize load nodes
486 for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter =
487 loads.end(); iter != eiter; ++iter)
488 {
489 addLoadVFGNode(SVFUtil::cast<LoadStmt>(*iter));
490 }
491
492 // initialize store nodes
494 for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter =
495 stores.end(); iter != eiter; ++iter)
496 {
497 addStoreVFGNode(SVFUtil::cast<StoreStmt>(*iter));
498 }
499
501 for (SVFStmt::SVFStmtSetTy::iterator iter = forks.begin(), eiter =
502 forks.end(); iter != eiter; ++iter)
503 {
504 TDForkPE* forkedge = SVFUtil::cast<TDForkPE>(*iter);
505 for(u32_t i = 0; i < forkedge->getOpVarNum(); i++)
506 addActualParmVFGNode(forkedge->getOpVar(i), forkedge->getOpCallICFGNode(i));
507 }
508
509 // initialize actual parameter nodes
510 for(SVFIR::CSToArgsListMap::iterator it = pag->getCallSiteArgsMap().begin(), eit = pag->getCallSiteArgsMap().end(); it !=eit; ++it)
511 {
512
513 for(SVFIR::ValVarList::iterator pit = it->second.begin(), epit = it->second.end(); pit!=epit; ++pit)
514 {
515 const ValVar* svfVar = *pit;
517 addActualParmVFGNode(svfVar,it->first);
518 }
519 }
520
521 // initialize actual return nodes (callsite return)
522 for(SVFIR::CSToRetMap::iterator it = pag->getCallSiteRets().begin(), eit = pag->getCallSiteRets().end(); it !=eit; ++it)
523 {
524
528 if(isInterestedSVFVar(it->second) == false || hasDef(it->second))
529 continue;
530
531 addActualRetVFGNode(it->second,it->first->getCallICFGNode());
532 }
533
534 // initialize formal parameter nodes
535 for(SVFIR::FunToArgsListMap::iterator it = pag->getFunArgsMap().begin(), eit = pag->getFunArgsMap().end(); it !=eit; ++it)
536 {
537 const FunObjVar* func = it->first;
538
539 for(SVFIR::ValVarList::iterator pit = it->second.begin(), epit = it->second.end(); pit!=epit; ++pit)
540 {
541 const ValVar* param = *pit;
542 if (isInterestedSVFVar(param) == false || hasBlackHoleConstObjAddrAsDef(param))
543 continue;
544
545 const CallPE* callPE = pag->getCallPEForFormalParm(param);
546 addFormalParmVFGNode(param,func,callPE);
547 }
548
549 if (func->isVarArg())
550 {
553 continue;
554
557 }
558 }
559
560 // initialize formal return nodes (callee return)
561 for (SVFIR::FunToRetMap::iterator it = pag->getFunRets().begin(), eit = pag->getFunRets().end(); it != eit; ++it)
562 {
563 const FunObjVar* func = it->first;
564
565 const ValVar* uniqueFunRetNode = it->second;
566
567 RetPESet retPEs;
568 if (uniqueFunRetNode->hasOutgoingEdges(SVFStmt::Ret))
569 {
570 for (SVFStmt::SVFStmtSetTy::const_iterator cit = uniqueFunRetNode->getOutgoingEdgesBegin(SVFStmt::Ret),
571 ecit = uniqueFunRetNode->getOutgoingEdgesEnd(SVFStmt::Ret);
572 cit != ecit; ++cit)
573 {
574 const RetPE* retPE = SVFUtil::cast<RetPE>(*cit);
575 if (isInterestedSVFVar(retPE->getLHSVar()))
576 retPEs.insert(retPE);
577 }
578 }
579
582 }
583
584 // initialize llvm phi nodes (phi of top level pointers)
586 for (SVFStmt::SVFStmtSetTy::iterator iter = phis.begin(), eiter =
587 phis.end(); iter != eiter; ++iter)
588 {
589 const PhiStmt* edge = SVFUtil::cast<PhiStmt>(*iter);
590 if(isInterestedSVFVar(edge->getRes()))
592 }
593 // initialize select statement
595 for (SVFStmt::SVFStmtSetTy::iterator iter = selects.begin(), eiter =
596 selects.end(); iter != eiter; ++iter)
597 {
598 const MultiOpndStmt* edge = SVFUtil::cast<MultiOpndStmt>(*iter);
599 if(isInterestedSVFVar(edge->getRes()))
601 }
602 // initialize llvm binary nodes (binary operators)
604 for (SVFStmt::SVFStmtSetTy::iterator iter = binaryops.begin(), eiter =
605 binaryops.end(); iter != eiter; ++iter)
606 {
607 const BinaryOPStmt* edge = SVFUtil::cast<BinaryOPStmt>(*iter);
608 if(isInterestedSVFVar(edge->getRes()))
610 }
611 // initialize llvm unary nodes (unary operators)
613 for (SVFStmt::SVFStmtSetTy::iterator iter = unaryops.begin(), eiter =
614 unaryops.end(); iter != eiter; ++iter)
615 {
616 const UnaryOPStmt* edge = SVFUtil::cast<UnaryOPStmt>(*iter);
617 if(isInterestedSVFVar(edge->getRes()))
619 }
620 // initialize llvm unary nodes (unary operators)
622 for (SVFStmt::SVFStmtSetTy::iterator iter = brs.begin(), eiter =
623 brs.end(); iter != eiter; ++iter)
624 {
625 const BranchStmt* edge = SVFUtil::cast<BranchStmt>(*iter);
626 if(isInterestedSVFVar(edge->getBranchInst()))
628 }
629 // initialize llvm cmp nodes (comparison)
631 for (SVFStmt::SVFStmtSetTy::iterator iter = cmps.begin(), eiter =
632 cmps.end(); iter != eiter; ++iter)
633 {
634 const CmpStmt* edge = SVFUtil::cast<CmpStmt>(*iter);
635 if(isInterestedSVFVar(edge->getRes()))
637 }
638}
639
644{
649 if (edge != nullptr)
650 {
651 assert(edge->isDirectVFGEdge() && "this should be a direct value flow edge!");
652 return nullptr;
653 }
654 else
655 {
656 if(srcNode!=dstNode)
657 {
659 return (addVFGEdge(directEdge) ? directEdge : nullptr);
660 }
661 else
662 return nullptr;
663 }
664}
665
670{
674 if (edge != nullptr)
675 {
676 assert(edge->isCallDirectVFGEdge() && "this should be a direct value flow edge!");
677 return nullptr;
678 }
679 else
680 {
682 return (addVFGEdge(callEdge) ? callEdge : nullptr);
683 }
684}
685
690{
694 if (edge != nullptr)
695 {
696 assert(edge->isRetDirectVFGEdge() && "this should be a direct value flow edge!");
697 return nullptr;
698 }
699 else
700 {
702 return (addVFGEdge(retEdge) ? retEdge : nullptr);
703 }
704}
705
706
711{
712
713 for(iterator it = begin(), eit = end(); it!=eit; ++it)
714 {
715 NodeID nodeId = it->first;
716 VFGNode* node = it->second;
717
718 if(StmtVFGNode* stmtNode = SVFUtil::dyn_cast<StmtVFGNode>(node))
719 {
721 if(SVFUtil::isa<AddrVFGNode>(stmtNode))
722 continue;
724 if (stmtNode->getSrcNode()->isConstDataOrAggDataButNotNullPtr() == false)
725 // for ptr vfg, we skip src node of integer type if it is at a int2ptr copystmt
726 if(isInterestedSVFVar(stmtNode->getSrcNode()))
727 addIntraDirectVFEdge(getDef(SVFUtil::cast<ValVar>(stmtNode->getSrcNode())), nodeId);
728 if (const GepStmt* gepStmt = SVFUtil::dyn_cast<GepStmt>(stmtNode->getSVFStmt()))
729 {
730 for (const auto &varType: gepStmt->getOffsetVarAndGepTypePairVec())
731 {
732 if(varType.first->isConstDataOrAggDataButNotNullPtr() || isInterestedSVFVar(varType.first) == false)
733 continue;
735 }
736 }
738 if(SVFUtil::isa<StoreVFGNode>(stmtNode) && (stmtNode->getDstNode()->isConstDataOrAggDataButNotNullPtr() == false))
739 {
740 addIntraDirectVFEdge(getDef(SVFUtil::cast<ValVar>(stmtNode->getDstNode())), nodeId);
741 }
742
743 }
744 else if(PHIVFGNode* phiNode = SVFUtil::dyn_cast<PHIVFGNode>(node))
745 {
746 for (PHIVFGNode::OPVers::const_iterator it = phiNode->opVerBegin(), eit = phiNode->opVerEnd(); it != eit; it++)
747 {
748 if (it->second->isConstDataOrAggDataButNotNullPtr() == false)
749 addIntraDirectVFEdge(getDef(it->second), nodeId);
750 }
751 }
752 else if(BinaryOPVFGNode* binaryNode = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
753 {
754 for (BinaryOPVFGNode::OPVers::const_iterator it = binaryNode->opVerBegin(), eit = binaryNode->opVerEnd(); it != eit; it++)
755 {
756 if (it->second->isConstDataOrAggDataButNotNullPtr() == false)
757 addIntraDirectVFEdge(getDef(it->second), nodeId);
758 }
759 }
760 else if(UnaryOPVFGNode* unaryNode = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
761 {
762 for (UnaryOPVFGNode::OPVers::const_iterator it = unaryNode->opVerBegin(), eit = unaryNode->opVerEnd(); it != eit; it++)
763 {
764 if (it->second->isConstDataOrAggDataButNotNullPtr() == false)
765 addIntraDirectVFEdge(getDef(it->second), nodeId);
766 }
767 }
768 else if(CmpVFGNode* cmpNode = SVFUtil::dyn_cast<CmpVFGNode>(node))
769 {
770 for (CmpVFGNode::OPVers::const_iterator it = cmpNode->opVerBegin(), eit = cmpNode->opVerEnd(); it != eit; it++)
771 {
772 if (it->second->isConstDataOrAggDataButNotNullPtr() == false)
773 addIntraDirectVFEdge(getDef(it->second), nodeId);
774 }
775 }
776 else if(BranchVFGNode* branchNode = SVFUtil::dyn_cast<BranchVFGNode>(node))
777 {
778 const ValVar* cond = branchNode->getBranchStmt()->getCondition();
779 if (cond->isConstDataOrAggDataButNotNullPtr() == false)
781 }
782 else if(ActualParmVFGNode* actualParm = SVFUtil::dyn_cast<ActualParmVFGNode>(node))
783 {
784 if (actualParm->getParam()->isConstDataOrAggDataButNotNullPtr() == false)
786 }
787 else if(FormalParmVFGNode* formalParm = SVFUtil::dyn_cast<FormalParmVFGNode>(node))
788 {
789 if(const CallPE* callPE = formalParm->getCallPE())
790 {
791 for(u32_t i = 0; i < callPE->getOpVarNum(); i++)
792 {
793 if(isInterestedSVFVar(callPE->getOpVar(i)))
794 {
795 const CallICFGNode* cs = callPE->getOpCallICFGNode(i);
796 ActualParmVFGNode* acutalParm = getActualParmVFGNode(callPE->getOpVar(i), cs);
798 }
799 }
800 }
801 }
802 else if(FormalRetVFGNode* calleeRet = SVFUtil::dyn_cast<FormalRetVFGNode>(node))
803 {
806
808 for(RetPESet::const_iterator it = calleeRet->retPEBegin(), eit = calleeRet->retPEEnd(); it!=eit; ++it)
809 {
810 ActualRetVFGNode* callsiteRev = getActualRetVFGNode((*it)->getLHSVar());
811 const CallICFGNode* callBlockNode = (*it)->getCallSite();
813 }
814 }
817 }
818
821 {
824 for (SVFStmt::SVFStmtSetTy::iterator iter = forks.begin(), eiter =
825 forks.end(); iter != eiter; ++iter)
826 {
827 TDForkPE* forkedge = SVFUtil::cast<TDForkPE>(*iter);
829 for(u32_t i = 0; i < forkedge->getOpVarNum(); i++)
830 {
831 if(isInterestedSVFVar(forkedge->getOpVar(i)))
832 {
833 const CallICFGNode* cs = forkedge->getOpCallICFGNode(i);
836 }
837 }
838 }
841 for (SVFStmt::SVFStmtSetTy::iterator iter = joins.begin(), eiter =
842 joins.end(); iter != eiter; ++iter)
843 {
844 TDJoinPE* joinedge = SVFUtil::cast<TDJoinPE>(*iter);
845 NodeID callsiteRev = getDef(joinedge->getLHSVar());
847 addRetEdge(calleeRet->getId(),callsiteRev, getCallSiteID(joinedge->getCallSite(), calleeRet->getFun()));
848 }
849 }
850}
851
856{
857 VFGEdge edge(src,dst,kind);
860 if (outEdge && inEdge)
861 {
862 assert(outEdge == inEdge && "edges not match");
863 return outEdge;
864 }
865 else
866 return nullptr;
867}
868
869
874{
875 VFGEdge edge(src,dst,kind);
878 if (outEdge && inEdge)
879 {
880 assert(outEdge == inEdge && "edges not match");
881 return outEdge;
882 }
883 else
884 return nullptr;
885}
886
891{
895 if (outEdge && inEdge)
896 {
897 assert(outEdge == inEdge && "edges not match");
898 return outEdge;
899 }
900 else
901 return nullptr;
902}
903
904
909{
910 return hasIntraVFGEdge(const_cast<VFGNode*>(src),const_cast<VFGNode*>(dst),kind);
911}
912
913
917void VFG::dump(const std::string& file, bool simple)
918{
920}
921
926{
927 SVF::ViewGraph(this, "Value Flow Graph");
928}
929
930
932{
933 VFGEdgeSetTy vfEdgesAtIndCallSite;
934 CallGraph::CallEdgeMap::const_iterator iter = pta->getIndCallMap().begin();
935 CallGraph::CallEdgeMap::const_iterator eiter = pta->getIndCallMap().end();
936 for (; iter != eiter; iter++)
937 {
938 const CallICFGNode* newcs = iter->first;
939 assert(newcs->isIndirectCall() && "this is not an indirect call?");
941 for (PointerAnalysis::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
942 {
943 const FunObjVar* func = *func_iter;
944 connectCallerAndCallee(newcs, func, vfEdgesAtIndCallSite);
945 }
946 }
947}
948
954{
955 SVFIR * pag = SVFIR::getPAG();
956 CallSiteID csId = getCallSiteID(callBlockNode, callee);
957 const RetICFGNode* retBlockNode = callBlockNode->getRetICFGNode();
958 // connect actual and formal param
959 if (pag->hasCallSiteArgsMap(callBlockNode) && pag->hasFunArgsList(callee) &&
960 matchArgs(callBlockNode, callee))
961 {
962 const SVFIR::ValVarList& csArgList = pag->getCallSiteArgsList(callBlockNode);
964 SVFIR::ValVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end();
965 SVFIR::ValVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end();
966 for (; funArgIt != funArgEit && csArgIt != csArgEit; funArgIt++, csArgIt++)
967 {
968 const ValVar *cs_arg = *csArgIt;
969 const ValVar *fun_arg = *funArgIt;
971 connectAParamAndFParam(cs_arg, fun_arg, callBlockNode, csId, edges);
972 }
973 assert(funArgIt == funArgEit && "function has more arguments than call site");
974
975 if (callee->isVarArg())
976 {
980 {
981 for (; csArgIt != csArgEit; csArgIt++)
982 {
983 const ValVar *cs_arg = *csArgIt;
985 connectAParamAndFParam(cs_arg, varFunArgNode, callBlockNode, csId, edges);
986 }
987 }
988 }
989 }
990
991 // connect actual return and formal return
993 {
998 }
999}
1000
1004const SVFVar* VFG::getLHSTopLevPtr(const VFGNode* node) const
1005{
1006
1007 if(const AddrVFGNode* addr = SVFUtil::dyn_cast<AddrVFGNode>(node))
1008 return addr->getDstNode();
1009 else if(const CopyVFGNode* copy = SVFUtil::dyn_cast<CopyVFGNode>(node))
1010 return copy->getDstNode();
1011 else if(const GepVFGNode* gep = SVFUtil::dyn_cast<GepVFGNode>(node))
1012 return gep->getDstNode();
1013 else if(const LoadVFGNode* load = SVFUtil::dyn_cast<LoadVFGNode>(node))
1014 return load->getDstNode();
1015 else if(const PHIVFGNode* phi = SVFUtil::dyn_cast<PHIVFGNode>(node))
1016 return phi->getRes();
1017 else if(const CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
1018 return cmp->getRes();
1019 else if(const BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
1020 return bop->getRes();
1021 else if(const UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
1022 return uop->getRes();
1023 else if(const ActualParmVFGNode* ap = SVFUtil::dyn_cast<ActualParmVFGNode>(node))
1024 return ap->getParam();
1025 else if(const FormalParmVFGNode*fp = SVFUtil::dyn_cast<FormalParmVFGNode>(node))
1026 return fp->getParam();
1027 else if(const ActualRetVFGNode* ar = SVFUtil::dyn_cast<ActualRetVFGNode>(node))
1028 return ar->getRev();
1029 else if(const FormalRetVFGNode* fr = SVFUtil::dyn_cast<FormalRetVFGNode>(node))
1030 return fr->getRet();
1031 else if(const NullPtrVFGNode* nullVFG = SVFUtil::dyn_cast<NullPtrVFGNode>(node))
1032 return nullVFG->getSVFVar();
1033 else
1034 assert(false && "unexpected node kind!");
1035 return nullptr;
1036}
1037
1042{
1043 if(const FormalParmVFGNode* fp = SVFUtil::dyn_cast<FormalParmVFGNode>(node))
1044 {
1045 return fp->getFun();
1046 }
1047 else if(const InterPHIVFGNode* phi = SVFUtil::dyn_cast<InterPHIVFGNode>(node))
1048 {
1049 if(phi->isFormalParmPHI())
1050 return phi->getFun();
1051 }
1052 return nullptr;
1053}
1054
1055
1057{
1058 return getSVFStmt()->getValue();
1059}
1060
1062{
1063 return getRes();
1064}
1065
1067{
1068 return getRes();
1069}
1070
1072{
1073 return getRes();
1074}
1075
1077{
1078 return param;
1079}
1080
1084namespace SVF
1085{
1086template<>
1088{
1089
1091 DOTGraphTraits(bool isSimple = false) :
1092 DOTGraphTraits<SVFIR*>(isSimple)
1093 {
1094 }
1095
1097 static std::string getGraphName(VFG*)
1098 {
1099 return "VFG";
1100 }
1101
1102 std::string getNodeLabel(NodeType *node, VFG *graph)
1103 {
1104 if (isSimple())
1105 return getSimpleNodeLabel(node, graph);
1106 else
1107 return getCompleteNodeLabel(node, graph);
1108 }
1109
1111 static std::string getSimpleNodeLabel(NodeType *node, VFG*)
1112 {
1113 std::string str;
1114 std::stringstream rawstr(str);
1115 if(StmtVFGNode* stmtNode = SVFUtil::dyn_cast<StmtVFGNode>(node))
1116 {
1117 rawstr << stmtNode->toString();
1118 }
1119 else if(PHIVFGNode* tphi = SVFUtil::dyn_cast<PHIVFGNode>(node))
1120 {
1121 rawstr << tphi->toString();
1122 }
1123 else if(FormalParmVFGNode* fp = SVFUtil::dyn_cast<FormalParmVFGNode>(node))
1124 {
1125 rawstr << fp->toString();
1126 }
1127 else if(ActualParmVFGNode* ap = SVFUtil::dyn_cast<ActualParmVFGNode>(node))
1128 {
1129 rawstr << ap->toString();
1130 }
1131 else if (ActualRetVFGNode* ar = SVFUtil::dyn_cast<ActualRetVFGNode>(node))
1132 {
1133 rawstr << ar->toString();
1134 }
1135 else if (FormalRetVFGNode* fr = SVFUtil::dyn_cast<FormalRetVFGNode>(node))
1136 {
1137 rawstr << fr->toString();
1138 }
1139 else if(SVFUtil::isa<NullPtrVFGNode>(node))
1140 {
1141 rawstr << "NullPtr";
1142 }
1143 else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
1144 {
1145 rawstr << bop->toString();
1146 }
1147 else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
1148 {
1149 rawstr << uop->toString();
1150 }
1151 else if(CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
1152 {
1153 rawstr << cmp->toString();;
1154 }
1155 else if (BranchVFGNode* branchNode = SVFUtil::dyn_cast<BranchVFGNode>(node))
1156 {
1157 rawstr << branchNode->toString();
1158 }
1159 else
1160 assert(false && "what else kinds of nodes do we have??");
1161
1162 return rawstr.str();
1163 }
1164
1166 static std::string getCompleteNodeLabel(NodeType *node, VFG*)
1167 {
1168
1169 std::string str;
1170 std::stringstream rawstr(str);
1171 if(StmtVFGNode* stmtNode = SVFUtil::dyn_cast<StmtVFGNode>(node))
1172 {
1173 rawstr << stmtNode->toString();
1174 }
1175 else if(BinaryOPVFGNode* bop = SVFUtil::dyn_cast<BinaryOPVFGNode>(node))
1176 {
1177 rawstr << bop->toString();
1178 }
1179 else if(UnaryOPVFGNode* uop = SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
1180 {
1181 rawstr << uop->toString();
1182 }
1183 else if(CmpVFGNode* cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
1184 {
1185 rawstr << cmp->toString();
1186 }
1187 else if(PHIVFGNode* phi = SVFUtil::dyn_cast<PHIVFGNode>(node))
1188 {
1189 rawstr << phi->toString();
1190 }
1191 else if(FormalParmVFGNode* fp = SVFUtil::dyn_cast<FormalParmVFGNode>(node))
1192 {
1193 rawstr << fp->toString();
1194 }
1195 else if(ActualParmVFGNode* ap = SVFUtil::dyn_cast<ActualParmVFGNode>(node))
1196 {
1197 rawstr << ap->toString();
1198 }
1199 else if(NullPtrVFGNode* nptr = SVFUtil::dyn_cast<NullPtrVFGNode>(node))
1200 {
1201 rawstr << nptr->toString();
1202 }
1203 else if (ActualRetVFGNode* ar = SVFUtil::dyn_cast<ActualRetVFGNode>(node))
1204 {
1205 rawstr << ar->toString();
1206 }
1207 else if (FormalRetVFGNode* fr = SVFUtil::dyn_cast<FormalRetVFGNode>(node))
1208 {
1209 rawstr << fr->toString();
1210 }
1211 else if (MRSVFGNode* mr = SVFUtil::dyn_cast<MRSVFGNode>(node))
1212 {
1213 rawstr << mr->toString();
1214 }
1215 else if (BranchVFGNode* branchNode = SVFUtil::dyn_cast<BranchVFGNode>(node))
1216 {
1217 rawstr << branchNode->toString();
1218 }
1219 else
1220 assert(false && "what else kinds of nodes do we have??");
1221
1222 return rawstr.str();
1223 }
1224
1225 static std::string getNodeAttributes(NodeType *node, VFG*)
1226 {
1227 std::string str;
1228 std::stringstream rawstr(str);
1229
1230 rawstr << "shape=record";
1231
1232 if(StmtVFGNode* stmtNode = SVFUtil::dyn_cast<StmtVFGNode>(node))
1233 {
1234 const SVFStmt* edge = stmtNode->getSVFStmt();
1235 if (SVFUtil::isa<AddrStmt>(edge))
1236 {
1237 rawstr << ",color=green";
1238 }
1239 else if (SVFUtil::isa<CopyStmt>(edge))
1240 {
1241 rawstr << ",color=black";
1242 }
1243 else if (SVFUtil::isa<RetPE>(edge))
1244 {
1245 rawstr << ",color=black,style=dotted";
1246 }
1247 else if (SVFUtil::isa<GepStmt>(edge))
1248 {
1249 rawstr << ",color=\"purple:purple\"";
1250 }
1251 else if (SVFUtil::isa<StoreStmt>(edge))
1252 {
1253 rawstr << ",color=blue";
1254 }
1255 else if (SVFUtil::isa<LoadStmt>(edge))
1256 {
1257 rawstr << ",color=red";
1258 }
1259 else
1260 {
1261 assert(0 && "No such kind edge!!");
1262 }
1263 rawstr << "";
1264 }
1265 else if (SVFUtil::isa<CmpVFGNode>(node))
1266 {
1267 rawstr << ",color=grey";
1268 }
1269 else if (SVFUtil::isa<BinaryOPVFGNode>(node))
1270 {
1271 rawstr << ",color=grey";
1272 }
1273 else if (SVFUtil::isa<UnaryOPVFGNode>(node))
1274 {
1275 rawstr << ",color=grey";
1276 }
1277 else if(SVFUtil::isa<PHIVFGNode>(node))
1278 {
1279 rawstr << ",color=black";
1280 }
1281 else if(SVFUtil::isa<NullPtrVFGNode>(node))
1282 {
1283 rawstr << ",color=grey";
1284 }
1285 else if(SVFUtil::isa<FormalParmVFGNode>(node))
1286 {
1287 rawstr << ",color=yellow,penwidth=2";
1288 }
1289 else if(SVFUtil::isa<ActualParmVFGNode>(node))
1290 {
1291 rawstr << ",color=yellow,penwidth=2";
1292 }
1293 else if (SVFUtil::isa<ActualRetVFGNode>(node))
1294 {
1295 rawstr << ",color=yellow,penwidth=2";
1296 }
1297 else if (SVFUtil::isa<FormalRetVFGNode>(node))
1298 {
1299 rawstr << ",color=yellow,penwidth=2";
1300 }
1301 else if (SVFUtil::isa<MRSVFGNode>(node))
1302 {
1303 rawstr << ",color=orange,penwidth=2";
1304 }
1305 else if (SVFUtil::isa<BranchVFGNode>(node))
1306 {
1307 rawstr << ",color=gold,penwidth=2";
1308 }
1309 else
1310 assert(false && "no such kind of node!!");
1311
1312 return rawstr.str();
1313 }
1314
1315 template<class EdgeIter>
1316 static std::string getEdgeAttributes(NodeType*, EdgeIter EI, VFG*)
1317 {
1318 VFGEdge* edge = *(EI.getCurrent());
1319 assert(edge && "No edge found!!");
1320 if (SVFUtil::isa<DirectSVFGEdge>(edge))
1321 {
1322 if (SVFUtil::isa<CallDirSVFGEdge>(edge))
1323 return "style=solid,color=red";
1324 else if (SVFUtil::isa<RetDirSVFGEdge>(edge))
1325 return "style=solid,color=blue";
1326 else
1327 return "style=solid";
1328 }
1329 else if (SVFUtil::isa<IndirectSVFGEdge>(edge))
1330 {
1331 if (SVFUtil::isa<CallIndSVFGEdge>(edge))
1332 return "style=dashed,color=red";
1333 else if (SVFUtil::isa<RetIndSVFGEdge>(edge))
1334 return "style=dashed,color=blue";
1335 else
1336 return "style=dashed";
1337 }
1338 else
1339 {
1340 assert(false && "what else edge we have?");
1341 }
1342 return "";
1343 }
1344
1345 template<class EdgeIter>
1347 {
1348 VFGEdge* edge = *(EI.getCurrent());
1349 assert(edge && "No edge found!!");
1350
1351 std::string str;
1352 std::stringstream rawstr(str);
1353 if (CallDirSVFGEdge* dirCall = SVFUtil::dyn_cast<CallDirSVFGEdge>(edge))
1354 rawstr << dirCall->getCallSiteId();
1355 else if (RetDirSVFGEdge* dirRet = SVFUtil::dyn_cast<RetDirSVFGEdge>(edge))
1356 rawstr << dirRet->getCallSiteId();
1357
1358 return rawstr.str();
1359 }
1360};
1361} // End namespace llvm
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define DGENERAL
Definition SVFType.h:582
copy
Definition cJSON.cpp:414
cJSON * n
Definition cJSON.cpp:2558
const std::string toString() const override
Definition VFG.cpp:275
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:268
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:309
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:302
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:242
const std::string toString() const override
Definition VFG.cpp:249
const std::string toString() const override
Definition VFG.cpp:259
const ValVar * param
Definition VFGNode.h:930
const SVFVar * getValue() const override
Return the corresponding LLVM value, if possible, nullptr otherwise.
Definition VFG.cpp:1076
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:134
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:1066
const std::string toString() const override
Definition VFG.cpp:141
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:181
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:176
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:390
const RetICFGNode * getRetICFGNode() const
Return callsite.
Definition ICFGNode.h:440
const std::string getSourceLoc() const override
Definition ICFGNode.h:571
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:120
const ValVar * getRes() const
Definition VFGNode.h:432
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:113
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:1061
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:97
const std::string toString() const override
Definition VFG.cpp:104
virtual const std::string toString() const
Definition VFG.cpp:374
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:285
const std::string toString() const override
Definition VFG.cpp:292
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:320
const std::string toString() const override
Definition VFG.cpp:327
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:190
const std::string toString() const override
Definition VFG.cpp:197
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:75
NodeID getNullPtr() const
Definition IRGraph.h:258
NodeID getVarargNode(const FunObjVar *func) const
getVarargNode - Return the unique node representing the variadic argument of a variadic function.
Definition IRGraph.cpp:71
bool isFormalParmPHI() const
Definition VFGNode.h:1236
const std::string toString() const override
Definition VFG.cpp:338
virtual const std::string toString() const
Definition VFG.cpp:382
const std::string toString() const override
Definition VFG.cpp:228
const std::string toString() const override
Definition VFG.cpp:66
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:59
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:356
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:349
static const Option< bool > EnableThreadCallGraph
Definition Options.h:128
OPVers::const_iterator opVerBegin() const
Definition VFGNode.h:773
PHIVFGNode(NodeID id, const ValVar *r, VFGNodeK k=TPhi)
Constructor.
Definition VFG.cpp:415
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:206
const std::string toString() const override
Definition VFG.cpp:213
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:1071
Set< const FunObjVar * > FunctionSet
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
virtual const std::string toString() const
Definition VFG.cpp:399
CallSiteID getCallSiteId() const
Return callsite ID.
Definition VFGEdge.h:266
const ValVar * getLHSVar() const
CSToArgsListMap & getCallSiteArgsMap()
Get callsite argument list.
Definition SVFIR.h:390
bool funHasRet(const FunObjVar *func) const
Definition SVFIR.h:429
bool hasFunArgsList(const FunObjVar *func) const
Function has arguments list.
Definition SVFIR.h:368
const ValVar * getCallSiteRet(const RetICFGNode *cs) const
Get callsite return.
Definition SVFIR.h:407
const ValVarList & getFunArgsList(const FunObjVar *func) const
Get function arguments list.
Definition SVFIR.h:378
std::vector< const ValVar * > ValVarList
Definition SVFIR.h:60
CSToRetMap & getCallSiteRets()
Get callsite return.
Definition SVFIR.h:402
FunToRetMap & getFunRets()
Get function return list.
Definition SVFIR.h:418
bool hasCallSiteArgsMap(const CallICFGNode *cs) const
Callsite has argument list.
Definition SVFIR.h:385
bool callsiteHasRet(const RetICFGNode *cs) const
Definition SVFIR.h:413
const ValVar * getFunRet(const FunObjVar *func) const
Get function return list.
Definition SVFIR.h:423
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:120
const ValVarList & getCallSiteArgsList(const CallICFGNode *cs) const
Get callsite argument list.
Definition SVFIR.h:395
const ValVar * getValVar(NodeID id) const
Definition SVFIR.h:139
CallPE * getCallPEForFormalParm(const SVFVar *param) const
Get the CallPE for a formal parameter (phi-like, nullptr if not found)
Definition SVFIR.h:361
FunToArgsListMap & getFunArgsMap()
Get function arguments list.
Definition SVFIR.h:373
const SVFVar * getValue() const
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
virtual const std::string toString() const
NodeID getId() const
Get ID.
Definition SVFValue.h:158
virtual const std::string & getName() const
Definition SVFValue.h:184
const std::string valueOnlyToString() const
Definition LLVMUtil.cpp:741
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:1056
const SVFStmt * getSVFStmt() const
Definition VFGNode.h:147
const std::string toString() const override
Definition VFG.cpp:50
NodeID getDstNodeID() const
Definition VFGNode.h:157
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:75
const std::string toString() const override
Definition VFG.cpp:88
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
Definition VFG.cpp:155
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:162
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:366
virtual const std::string toString() const
Definition VFG.cpp:42
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:931
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:1004
VFGNodeIDToNodeMapTy::iterator iterator
Definition VFG.h:80
SVFIR * pag
Definition VFG.h:104
VFGEdge * addRetEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
Definition VFG.cpp:689
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:450
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:643
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:1041
VFG(CallGraph *callgraph, VFGK k=FULLSVFG)
Constructor.
Definition VFG.cpp:428
VFGEdge * addCallEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
Definition VFG.cpp:669
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:855
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:890
virtual bool isInterestedSVFVar(const SVFVar *node) const
Definition VFG.h:506
void connectDirectVFGEdges()
Create edges between VFG nodes within a function.
Definition VFG.cpp:710
VFGEdge * getIntraVFGEdge(const VFGNode *src, const VFGNode *dst, VFGEdge::VFGEdgeK kind)
Get a SVFG edge according to src and dst.
Definition VFG.cpp:908
ActualRetVFGNode * getActualRetVFGNode(const SVFVar *aret) const
Definition VFG.h:303
void view()
Dump graph into dot file.
Definition VFG.cpp:925
VFGEdge * hasThreadVFGEdge(VFGNode *src, VFGNode *dst, VFGEdge::VFGEdgeK kind)
Definition VFG.cpp:873
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
Definition VFG.cpp:917
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:953
void destroy()
Clean up memory.
Definition VFG.cpp:441
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:78
u32_t NodeID
Definition GeneralType.h:76
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:82
unsigned u32_t
Definition GeneralType.h:67
static std::string getCompleteNodeLabel(NodeType *node, VFG *)
Return label of a VFG node with MemSSA information.
Definition VFG.cpp:1166
static std::string getNodeAttributes(NodeType *node, VFG *)
Definition VFG.cpp:1225
static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
Definition VFG.cpp:1346
DOTGraphTraits(bool isSimple=false)
Definition VFG.cpp:1091
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, VFG *)
Definition VFG.cpp:1316
std::string getNodeLabel(NodeType *node, VFG *graph)
Definition VFG.cpp:1102
static std::string getSimpleNodeLabel(NodeType *node, VFG *)
Return label of a VFG node without MemSSA information.
Definition VFG.cpp:1111
static std::string getGraphName(VFG *)
Return name of the graph.
Definition VFG.cpp:1097