Static Value-Flow Analysis
Loading...
Searching...
No Matches
SVFIRBuilder.cpp
Go to the documentation of this file.
1//===- SVFIRBuilder.cpp -- SVFIR builder-----------------------------------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-2017> <Yulei Sui>
6//
7
8// This program is free software: you can redistribute it and/or modify
9// it under the terms of the GNU Affero General Public License as published by
10// the Free Software Foundation, either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU Affero General Public License for more details.
17
18// You should have received a copy of the GNU Affero General Public License
19// along with this program. If not, see <http://www.gnu.org/licenses/>.
20//
21//===----------------------------------------------------------------------===//
22
23/*
24 * SVFIRBuilder.cpp
25 *
26 * Created on: Nov 1, 2013
27 * Author: Yulei Sui
28 */
29
31#include "SVF-LLVM/BasicTypes.h"
32#include "SVF-LLVM/CHGBuilder.h"
33#include "SVF-LLVM/CppUtil.h"
35#include "SVF-LLVM/LLVMUtil.h"
38#include "SVFIR/SVFFileSystem.h"
39#include "SVFIR/SVFModule.h"
40#include "SVFIR/SVFValue.h"
42#include "Graphs/CallGraph.h"
43#include "Util/Options.h"
44#include "Util/SVFUtil.h"
45
46using namespace std;
47using namespace SVF;
48using namespace SVFUtil;
49using namespace LLVMUtil;
50
51
56{
57 double startTime = SVFStat::getClk(true);
58
59 DBOUT(DGENERAL, outs() << pasMsg("\t Building SVFIR ...\n"));
60
61 // Set SVFModule from SVFIRBuilder
63
64 // Build ICFG
65 pag->setICFG(llvmModuleSet()->getICFG());
66
67 // Set callgraph
68 pag->setCallGraph(llvmModuleSet()->callgraph);
69
70 // Set icfgnode in memobj
72 {
73 if(!it.second->getValue())
74 continue;
75 if (const Instruction* inst =
76 SVFUtil::dyn_cast<Instruction>(llvmModuleSet()->getLLVMValue(
77 it.second->getValue())))
78 {
79 if(llvmModuleSet()->hasICFGNode(inst))
80 it.second->gNode = llvmModuleSet()->getICFGNode(inst);
81 }
82 else if (const Function* func = SVFUtil::dyn_cast<Function>(llvmModuleSet()->getLLVMValue(
83 it.second->getValue())))
84 {
85 it.second->gNode = llvmModuleSet()->getCallGraphNode(func);
86 }
87 }
88
89 CHGraph* chg = new CHGraph(pag->getModule());
91 chgbuilder.buildCHG();
92 pag->setCHG(chg);
93
94 // We read SVFIR from a user-defined txt instead of parsing SVFIR from LLVM IR
96 {
98 return fileBuilder.build();
99 }
100
101 // If the SVFIR has been built before, then we return the unique SVFIR of the program
103 return pag;
104
112
115 {
116 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
117 {
118 const Function& fun = *F;
121 if(!fun.isDeclaration())
122 {
128 if (fun.doesNotReturn() == false &&
129 fun.getReturnType()->isVoidTy() == false)
130 {
133 }
134
137 for (Function::const_arg_iterator I = fun.arg_begin(), E = fun.arg_end();
138 I != E; ++I)
139 {
140 setCurrentLocation(&*I,&fun.getEntryBlock());
141 NodeID argValNodeId = pag->getValueNode(llvmModuleSet()->getSVFValue(&*I));
142 // if this is the function does not have caller (e.g. main)
143 // or a dead function, shall we create a black hole address edge for it?
144 // it is (1) too conservative, and (2) make FormalParmVFGNode defined at blackhole address PAGEdge.
145 // if(SVFUtil::ArgInNoCallerFunction(&*I)) {
146 // if(I->getType()->isPointerTy())
147 // addBlackHoleAddrEdge(argValNodeId);
148 //}
150 }
151 }
152 for (Function::const_iterator bit = fun.begin(), ebit = fun.end();
153 bit != ebit; ++bit)
154 {
155 const BasicBlock& bb = *bit;
156 for (BasicBlock::const_iterator it = bb.begin(), eit = bb.end();
157 it != eit; ++it)
158 {
159 const Instruction& inst = *it;
160 setCurrentLocation(&inst,&bb);
161 visit(const_cast<Instruction&>(inst));
162 }
163 }
164 }
165 }
166
167 sanityCheck();
168
170
172
173 // dump SVFIR
175 pag->dump("svfir_initial");
176
177 // print to command line of the SVFIR graph
178 if (Options::PAGPrint())
179 pag->print();
180
181 // dump ICFG
182 if (Options::DumpICFG())
183 pag->getICFG()->dump("icfg_initial");
184
186 {
189 }
190
191 // dump SVFIR as JSON
192 if (!Options::DumpJson().empty())
193 {
195 }
196
197 double endTime = SVFStat::getClk(true);
198 SVFStat::timeOfBuildingSVFIR = (endTime - startTime) / TIMEINTERVAL;
199
200 return pag;
201}
202
203/*
204 * Initial all the nodes from symbol table
205 */
207{
208 DBOUT(DPAGBuild, outs() << "Initialise SVFIR Nodes ...\n");
209
211
216
217 // Iterate over all value symbols in the symbol table
218 for (SymbolTableInfo::ValueToIDMapTy::iterator iter =
219 symTable->valSyms().begin(); iter != symTable->valSyms().end();
220 ++iter)
221 {
222 // Debug output for adding value node
223 DBOUT(DPAGBuild, outs() << "add val node " << iter->second << "\n");
224
225 // Skip blackhole and null pointer symbols
226 if(iter->second == symTable->blkPtrSymID() || iter->second == symTable->nullPtrSymID())
227 continue;
228
229 const ICFGNode* icfgNode = nullptr;
230 auto llvmValue = llvmModuleSet()->getLLVMValue(iter->first);
231 if (const Instruction* inst =
232 SVFUtil::dyn_cast<Instruction>(llvmValue))
233 {
234 if (llvmModuleSet()->hasICFGNode(inst))
235 {
236 icfgNode = llvmModuleSet()->getICFGNode(inst);
237 }
238 }
239
240 // Check if the value is a function and get its call graph node
241 if (const Function* func =
242 SVFUtil::dyn_cast<Function>(llvmValue))
243 {
245 // add value node representing the function
246 pag->addFunValNode(cgn, iter->second, icfgNode);
247 }
248 else if (auto fpValue = SVFUtil::dyn_cast<ConstantFP>(llvmValue))
249 {
252 fpValue, pag->getGNode(iter->second));
253 }
254 else if (auto intValue = SVFUtil::dyn_cast<ConstantInt>(llvmValue))
255 {
258 intValue, pag->getGNode(iter->second));
259 }
260 else if (auto nullValue = SVFUtil::dyn_cast<ConstantPointerNull>(llvmValue))
261 {
262 pag->addConstantNullPtrValNode(iter->first, iter->second, icfgNode);
264 nullValue, pag->getGNode(iter->second));
265 }
266 else if (auto globalValue = SVFUtil::dyn_cast<GlobalValue>(llvmValue))
267 {
268 pag->addGlobalValueValNode(iter->first, iter->second, icfgNode);
270 globalValue, pag->getGNode(iter->second));
271 }
272 else if (auto dataValue = SVFUtil::dyn_cast<ConstantData>(llvmValue))
273 {
274 pag->addConstantDataValNode(iter->first, iter->second, icfgNode);
276 dataValue, pag->getGNode(iter->second));
277 }
278 else
279 {
280 // Add value node to PAG
281 pag->addValNode(iter->first, iter->second, icfgNode);
282 }
283 }
284
285 // Iterate over all object symbols in the symbol table
286 for (SymbolTableInfo::ValueToIDMapTy::iterator iter =
287 symTable->objSyms().begin(); iter != symTable->objSyms().end();
288 ++iter)
289 {
290 // Debug output for adding object node
291 DBOUT(DPAGBuild, outs() << "add obj node " << iter->second << "\n");
292
293 // Skip blackhole and constant symbols
294 if(iter->second == symTable->blackholeSymID() || iter->second == symTable->constantSymID())
295 continue;
296
297 // Get the LLVM value corresponding to the symbol
298 const Value* llvmValue = llvmModuleSet()->getLLVMValue(iter->first);
299
300 // Check if the value is a function and add a function object node
301 if (const Function* func = SVFUtil::dyn_cast<Function>(llvmValue))
302 {
303 pag->addFunObjNode(llvmModuleSet()->getCallGraphNode(func), iter->second);
304 }
305 // Check if the value is a heap object and add a heap object node
307 {
308 const SVFFunction* f =
309 SVFUtil::cast<SVFInstruction>(iter->first)->getFunction();
310 pag->addHeapObjNode(iter->first, f, iter->second);
312 llvmValue, pag->getGNode(iter->second));
313 }
314 // Check if the value is an alloca instruction and add a stack object node
316 {
317 const SVFFunction* f =
318 SVFUtil::cast<SVFInstruction>(iter->first)->getFunction();
319 pag->addStackObjNode(iter->first, f, iter->second);
321 llvmValue, pag->getGNode(iter->second));
322 }
323 else if (auto fpValue = SVFUtil::dyn_cast<ConstantFP>(llvmValue))
324 {
327 fpValue, pag->getGNode(iter->second));
328 }
329 else if (auto intValue = SVFUtil::dyn_cast<ConstantInt>(llvmValue))
330 {
333 intValue, pag->getGNode(iter->second));
334 }
335 else if (auto nullValue = SVFUtil::dyn_cast<ConstantPointerNull>(llvmValue))
336 {
337 pag->addConstantNullPtrObjNode(iter->first, iter->second);
339 nullValue, pag->getGNode(iter->second));
340 }
341 else if (auto globalValue = SVFUtil::dyn_cast<GlobalValue>(llvmValue))
342 {
343 pag->addGlobalValueObjNode(iter->first, iter->second);
345 globalValue, pag->getGNode(iter->second));
346 }
347 else if (auto dataValue = SVFUtil::dyn_cast<ConstantData>(llvmValue))
348 {
349 pag->addConstantDataObjNode(iter->first, iter->second);
351 dataValue, pag->getGNode(iter->second));
352 }
353 // Add a generic object node for other types of values
354 else
355 {
356 pag->addObjNode(iter->first, iter->second);
357 }
358 }
359
360 for (SymbolTableInfo::FunToIDMapTy::iterator iter =
361 symTable->retSyms().begin(); iter != symTable->retSyms().end();
362 ++iter)
363 {
364 DBOUT(DPAGBuild, outs() << "add ret node " << iter->second << "\n");
366 llvmModuleSet()->getCallGraphNode(SVFUtil::cast<Function>(
367 llvmModuleSet()->getLLVMValue(iter->first))),
368 iter->second);
369 }
370
371 for (SymbolTableInfo::FunToIDMapTy::iterator iter =
372 symTable->varargSyms().begin();
373 iter != symTable->varargSyms().end(); ++iter)
374 {
375 DBOUT(DPAGBuild, outs() << "add vararg node " << iter->second << "\n");
377 llvmModuleSet()->getCallGraphNode(SVFUtil::cast<Function>(
378 llvmModuleSet()->getLLVMValue(iter->first))),
379 iter->second);
380 }
381
383 for (SymbolTableInfo::ValueToIDMapTy::iterator iter =
384 symTable->objSyms().begin(); iter != symTable->objSyms().end(); ++iter)
385 {
386 DBOUT(DPAGBuild, outs() << "add address edges for constant node " << iter->second << "\n");
387 const SVFValue* val = iter->first;
389 {
391 if(ptr!= pag->getBlkPtr() && ptr!= pag->getNullPtr())
392 {
393 setCurrentLocation(val, nullptr);
394 addAddrEdge(iter->second, ptr);
395 }
396 }
397 }
398
399 assert(pag->getTotalNodeNum() >= symTable->getTotalSymNum()
400 && "not all node have been initialized!!!");
401
402}
403
404/*
405 https://github.com/SVF-tools/SVF/issues/524
406 Handling single value types, for constant index, including pointer, integer, etc
407 e.g. field_idx = getelementptr i8, %i8* %p, i64 -4
408 We can obtain the field index by inferring the byteoffset if %p is casted from a pointer to a struct
409 For another example, the following can be an array access.
410 e.g. field_idx = getelementptr i8, %struct_type %p, i64 1
411
412*/
414{
415 return 0;
416}
417
425{
426 assert(V);
427
428 const llvm::GEPOperator *gepOp = SVFUtil::dyn_cast<const llvm::GEPOperator>(V);
429 DataLayout * dataLayout = getDataLayout(llvmModuleSet()->getMainLLVMModule());
430 llvm::APInt byteOffset(dataLayout->getIndexSizeInBits(gepOp->getPointerAddressSpace()),0,true);
431 if(gepOp && dataLayout && gepOp->accumulateConstantOffset(*dataLayout,byteOffset))
432 {
433 //s32_t bo = byteOffset.getSExtValue();
434 }
435
436 bool isConst = true;
437
438 bool prevPtrOperand = false;
439 for (bridge_gep_iterator gi = bridge_gep_begin(*V), ge = bridge_gep_end(*V);
440 gi != ge; ++gi)
441 {
442 const Type* gepTy = *gi;
444
445 assert((prevPtrOperand && svfGepTy->isPointerTy()) == false &&
446 "Expect no more than one gep operand to be of a pointer type");
447 if(!prevPtrOperand && svfGepTy->isPointerTy()) prevPtrOperand = true;
448 const Value* offsetVal = gi.getOperand();
450 assert(gepTy != offsetVal->getType() && "iteration and operand have the same type?");
452
453 //The int value of the current index operand
454 const ConstantInt* op = SVFUtil::dyn_cast<ConstantInt>(offsetVal);
455
456 // if Options::ModelConsts() is disabled. We will treat whole array as one,
457 // but we can distinguish different field of an array of struct, e.g. s[1].f1 is different from s[0].f2
458 if(const ArrayType* arrTy = SVFUtil::dyn_cast<ArrayType>(gepTy))
459 {
460 if(!op || (arrTy->getArrayNumElements() <= (u32_t)LLVMUtil::getIntegerValue(op).first))
461 continue;
465 }
466 else if (const StructType *ST = SVFUtil::dyn_cast<StructType>(gepTy))
467 {
468 assert(op && "non-const offset accessing a struct");
469 //The actual index
473 }
474 else if (gepTy->isSingleValueType())
475 {
476 // If it's a non-constant offset access
477 // If its point-to target is struct or array, it's likely an array accessing (%result = gep %struct.A* %a, i32 %non-const-index)
478 // If its point-to target is single value (pointer arithmetic), then it's a variant gep (%result = gep i8* %p, i32 %non-const-index)
479 if(!op && gepTy->isPointerTy() && gepOp->getSourceElementType()->isSingleValueType())
480 {
481 isConst = false;
482 }
483
484 // The actual index
485 //s32_t idx = op->getSExtValue();
486
487 // For pointer arithmetic we ignore the byte offset
488 // consider using inferFieldIdxFromByteOffset(geopOp,dataLayout,ap,idx)?
489 // ap.setFldIdx(ap.getConstantFieldIdx() + inferFieldIdxFromByteOffset(geopOp,idx));
490 }
491 }
492 return isConst;
493}
494
499{
500 if (const Constant* ref = SVFUtil::dyn_cast<Constant>(val))
501 {
503 {
504 DBOUT(DPAGBuild, outs() << "handle gep constant expression " << llvmModuleSet()->getSVFValue(ref)->toString() << "\n");
505 const Constant* opnd = gepce->getOperand(0);
506 // handle recursive constant express case (gep (bitcast (gep X 1)) 1)
508 auto &GEPOp = llvm::cast<llvm::GEPOperator>(*gepce);
509 Type *pType = GEPOp.getSourceElementType();
510 AccessPath ap(0, llvmModuleSet()->getSVFType(pType));
511 bool constGep = computeGepOffset(gepce, ap);
512 // must invoke pag methods here, otherwise it will be a dead recursion cycle
513 const SVFValue* cval = getCurrentValue();
514 const SVFBasicBlock* cbb = getCurrentBB();
515 setCurrentLocation(gepce, nullptr);
516 /*
517 * The gep edge created are like constexpr (same edge may appear at multiple callsites)
518 * so bb/inst of this edge may be rewritten several times, we treat it as global here.
519 */
520 addGepEdge(pag->getValueNode(llvmModuleSet()->getSVFValue(opnd)), pag->getValueNode(llvmModuleSet()->getSVFValue(gepce)), ap, constGep);
522 }
523 else if (const ConstantExpr* castce = isCastConstantExpr(ref))
524 {
525 DBOUT(DPAGBuild, outs() << "handle cast constant expression " << llvmModuleSet()->getSVFValue(ref)->toString() << "\n");
526 const Constant* opnd = castce->getOperand(0);
528 const SVFValue* cval = getCurrentValue();
529 const SVFBasicBlock* cbb = getCurrentBB();
530 setCurrentLocation(castce, nullptr);
533 }
535 {
536 DBOUT(DPAGBuild, outs() << "handle select constant expression " << llvmModuleSet()->getSVFValue(ref)->toString() << "\n");
537 const Constant* src1 = selectce->getOperand(1);
538 const Constant* src2 = selectce->getOperand(2);
541 const SVFValue* cval = getCurrentValue();
542 const SVFBasicBlock* cbb = getCurrentBB();
544 NodeID cond = pag->getValueNode(llvmModuleSet()->getSVFValue(selectce->getOperand(0)));
545 NodeID nsrc1 = pag->getValueNode(llvmModuleSet()->getSVFValue(src1));
546 NodeID nsrc2 = pag->getValueNode(llvmModuleSet()->getSVFValue(src2));
547 NodeID nres = pag->getValueNode(llvmModuleSet()->getSVFValue(selectce));
550 }
551 // if we meet a int2ptr, then it points-to black hole
553 {
554 const Constant* opnd = int2Ptrce->getOperand(0);
556 const SVFBasicBlock* cbb = getCurrentBB();
557 const SVFValue* cval = getCurrentValue();
561 }
563 {
564 const Constant* opnd = ptr2Intce->getOperand(0);
566 const SVFBasicBlock* cbb = getCurrentBB();
567 const SVFValue* cval = getCurrentValue();
571 }
573 {
574 // we don't handle trunc and cmp instruction for now
575 const SVFValue* cval = getCurrentValue();
576 const SVFBasicBlock* cbb = getCurrentBB();
577 setCurrentLocation(ref, nullptr);
578 NodeID dst = pag->getValueNode(llvmModuleSet()->getSVFValue(ref));
581 }
582 else if (isBinaryConstantExpr(ref))
583 {
584 // we don't handle binary constant expression like add(x,y) now
585 const SVFValue* cval = getCurrentValue();
586 const SVFBasicBlock* cbb = getCurrentBB();
587 setCurrentLocation(ref, nullptr);
588 NodeID dst = pag->getValueNode(llvmModuleSet()->getSVFValue(ref));
591 }
592 else if (isUnaryConstantExpr(ref))
593 {
594 // we don't handle unary constant expression like fneg(x) now
595 const SVFValue* cval = getCurrentValue();
596 const SVFBasicBlock* cbb = getCurrentBB();
597 setCurrentLocation(ref, nullptr);
598 NodeID dst = pag->getValueNode(llvmModuleSet()->getSVFValue(ref));
601 }
602 else if (SVFUtil::isa<ConstantAggregate>(ref))
603 {
604 // we don't handle constant aggregate like constant vectors
605 }
606 else if (SVFUtil::isa<BlockAddress>(ref))
607 {
608 // blockaddress instruction (e.g. i8* blockaddress(@run_vm, %182))
609 // is treated as constant data object for now, see LLVMUtil.h:397, SymbolTableInfo.cpp:674 and SVFIRBuilder.cpp:183-194
610 const SVFValue* cval = getCurrentValue();
611 const SVFBasicBlock* cbb = getCurrentBB();
612 setCurrentLocation(ref, nullptr);
613 NodeID dst = pag->getValueNode(llvmModuleSet()->getSVFValue(ref));
616 }
617 else
618 {
619 if(SVFUtil::isa<ConstantExpr>(val))
620 assert(false && "we don't handle all other constant expression for now!");
621 }
622 }
623}
630{
631
632 // if the global variable do not have any field needs to be initialized
633 if (offset == 0 && gvar->getInitializer()->getType()->isSingleValueType())
634 {
635 return getValueNode(gvar);
636 }
639 else
640 {
642 }
643}
644
645/*For global variable initialization
646 * Give a simple global variable
647 * int x = 10; // store 10 x (constant, non pointer) |
648 * int *y = &x; // store x y (pointer type)
649 * Given a struct
650 * struct Z { int s; int *t;};
651 * Global initialization:
652 * struct Z z = {10,&x}; // store x z.t (struct type)
653 * struct Z *m = &z; // store z m (pointer type)
654 * struct Z n = {10,&z.s}; // store z.s n , &z.s constant expression (constant expression)
655 */
658{
659 DBOUT(DPAGBuild, outs() << "global " << llvmModuleSet()->getSVFValue(gvar)->toString() << " constant initializer: " << llvmModuleSet()->getSVFValue(C)->toString() << "\n");
660 if (C->getType()->isSingleValueType())
661 {
662 NodeID src = getValueNode(C);
663 // get the field value if it is available, otherwise we create a dummy field node.
664 setCurrentLocation(gvar, nullptr);
665 NodeID field = getGlobalVarField(gvar, offset, llvmModuleSet()->getSVFType(C->getType()));
666
667 if (SVFUtil::isa<GlobalVariable, Function>(C))
668 {
669 setCurrentLocation(C, nullptr);
670 addStoreEdge(src, field);
671 }
672 else if (SVFUtil::isa<ConstantExpr>(C))
673 {
674 // add gep edge of C1 itself is a constant expression
675 processCE(C);
676 setCurrentLocation(C, nullptr);
677 addStoreEdge(src, field);
678 }
679 else if (SVFUtil::isa<BlockAddress>(C))
680 {
681 // blockaddress instruction (e.g. i8* blockaddress(@run_vm, %182))
682 // is treated as constant data object for now, see LLVMUtil.h:397, SymbolTableInfo.cpp:674 and SVFIRBuilder.cpp:183-194
683 processCE(C);
684 setCurrentLocation(C, nullptr);
686 }
687 else
688 {
689 setCurrentLocation(C, nullptr);
690 addStoreEdge(src, field);
692 if (C->getType()->isPtrOrPtrVectorTy() && src != pag->getNullPtr())
694 }
695 }
696 else if (SVFUtil::isa<ConstantArray, ConstantStruct>(C))
697 {
699 return;
700 for (u32_t i = 0, e = C->getNumOperands(); i != e; i++)
701 {
703 InitialGlobal(gvar, SVFUtil::cast<Constant>(C->getOperand(i)), offset + off);
704 }
705 }
706 else if(ConstantData* data = SVFUtil::dyn_cast<ConstantData>(C))
707 {
709 {
710 if(ConstantDataSequential* seq = SVFUtil::dyn_cast<ConstantDataSequential>(data))
711 {
712 for(u32_t i = 0; i < seq->getNumElements(); i++)
713 {
714 u32_t off = pag->getSymbolInfo()->getFlattenedElemIdx(llvmModuleSet()->getSVFType(C->getType()), i);
715 Constant* ct = seq->getElementAsConstant(i);
717 }
718 }
719 else
720 {
721 assert((SVFUtil::isa<ConstantAggregateZero, UndefValue>(data)) && "Single value type data should have been handled!");
722 }
723 }
724 }
725 else
726 {
727 //TODO:assert(SVFUtil::isa<ConstantVector>(C),"what else do we have");
728 }
729}
730
735{
736
739 {
740 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
741 {
742 GlobalVariable *gvar = &*I;
745
746 setCurrentLocation(gvar, nullptr);
748
749 if (gvar->hasInitializer())
750 {
751 Constant *C = gvar->getInitializer();
752 DBOUT(DPAGBuild, outs() << "add global var node " << llvmModuleSet()->getSVFValue(gvar)->toString() << "\n");
753 InitialGlobal(gvar, C, 0);
754 }
755 }
756
757
759 for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
760 {
761 const Function* fun = &*I;
762 NodeID idx = getValueNode(fun);
763 NodeID obj = getObjectNode(fun);
764
765 DBOUT(DPAGBuild, outs() << "add global function node " << fun->getName().str() << "\n");
766 setCurrentLocation(fun, nullptr);
768 }
769
770 // Handle global aliases (due to linkage of multiple bc files), e.g., @x = internal alias @y. We need to add a copy from y to x.
771 for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; I++)
772 {
773 const GlobalAlias* alias = &*I;
775 NodeID src = pag->getValueNode(llvmModuleSet()->getSVFValue(alias->getAliasee()));
776 processCE(alias->getAliasee());
777 setCurrentLocation(alias, nullptr);
779 }
780 }
781}
782
788{
789
790 // AllocaInst should always be a pointer type
791 assert(SVFUtil::isa<PointerType>(inst.getType()));
792
793 DBOUT(DPAGBuild, outs() << "process alloca " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
794 NodeID dst = getValueNode(&inst);
795
796 NodeID src = getObjectNode(&inst);
797
798 addAddrWithStackArraySz(src, dst, inst);
799
800}
801
806{
807
808 DBOUT(DPAGBuild, outs() << "process phi " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
809
810 NodeID dst = getValueNode(&inst);
811
812 for (u32_t i = 0; i < inst.getNumIncomingValues(); ++i)
813 {
814 const Value* val = inst.getIncomingValue(i);
815 const Instruction* incomingInst = SVFUtil::dyn_cast<Instruction>(val);
816 bool matched = (incomingInst == nullptr ||
817 incomingInst->getFunction() == inst.getFunction());
818 (void) matched; // Suppress warning of unused variable under release build
819 assert(matched && "incomingInst's Function incorrect");
820 const Instruction* predInst = &inst.getIncomingBlock(i)->back();
821 const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(predInst);
822 NodeID src = getValueNode(val);
823 addPhiStmt(dst,src,icfgNode);
824 }
825}
826
827/*
828 * Visit load instructions
829 */
831{
832 DBOUT(DPAGBuild, outs() << "process load " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
833
834 NodeID dst = getValueNode(&inst);
835
836 NodeID src = getValueNode(inst.getPointerOperand());
837
838 addLoadEdge(src, dst);
839}
840
845{
846 // StoreInst itself should always not be a pointer type
847 assert(!SVFUtil::isa<PointerType>(inst.getType()));
848
849 DBOUT(DPAGBuild, outs() << "process store " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
850
851 NodeID dst = getValueNode(inst.getPointerOperand());
852
853 NodeID src = getValueNode(inst.getValueOperand());
854
855 addStoreEdge(src, dst);
856
857}
858
863{
864
865 NodeID dst = getValueNode(&inst);
866 // GetElementPtrInst should always be a pointer or a vector contains pointers
867 // for now we don't handle vector type here
868 if(SVFUtil::isa<VectorType>(inst.getType()))
869 {
871 return;
872 }
873
874 assert(SVFUtil::isa<PointerType>(inst.getType()));
875
876 DBOUT(DPAGBuild, outs() << "process gep " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
877
878 NodeID src = getValueNode(inst.getPointerOperand());
879
880 AccessPath ap(0, llvmModuleSet()->getSVFType(inst.getSourceElementType()));
881 bool constGep = computeGepOffset(&inst, ap);
882 addGepEdge(src, dst, ap, constGep);
883}
884
885/*
886 * Visit cast instructions
887 */
889{
890
891 DBOUT(DPAGBuild, outs() << "process cast " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
892 NodeID dst = getValueNode(&inst);
893
894 const Value* opnd = inst.getOperand(0);
895 NodeID src = getValueNode(opnd);
896 addCopyEdge(src, dst, getCopyKind(&inst));
897}
898
903{
904 NodeID dst = getValueNode(&inst);
905 assert(inst.getNumOperands() == 2 && "not two operands for BinaryOperator?");
906 Value* op1 = inst.getOperand(0);
908 Value* op2 = inst.getOperand(1);
910 u32_t opcode = inst.getOpcode();
911 addBinaryOPEdge(op1Node, op2Node, dst, opcode);
912}
913
918{
919 NodeID dst = getValueNode(&inst);
920 assert(inst.getNumOperands() == 1 && "not one operand for Unary instruction?");
921 Value* opnd = inst.getOperand(0);
922 NodeID src = getValueNode(opnd);
923 u32_t opcode = inst.getOpcode();
924 addUnaryOPEdge(src, dst, opcode);
925}
926
931{
932 NodeID dst = getValueNode(&inst);
933 assert(inst.getNumOperands() == 2 && "not two operands for compare instruction?");
934 Value* op1 = inst.getOperand(0);
936 Value* op2 = inst.getOperand(1);
938 u32_t predicate = inst.getPredicate();
939 addCmpEdge(op1Node, op2Node, dst, predicate);
940}
941
942
947{
948
949 DBOUT(DPAGBuild, outs() << "process select " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
950
951 NodeID dst = getValueNode(&inst);
952 NodeID src1 = getValueNode(inst.getTrueValue());
953 NodeID src2 = getValueNode(inst.getFalseValue());
954 NodeID cond = getValueNode(inst.getCondition());
956 addSelectStmt(dst,src1,src2, cond);
957}
958
963
968
973
974/*
975 * Visit callsites
976 */
978{
979
980 // skip llvm intrinsics
981 if(isIntrinsicInst(cs))
982 return;
983
985 outs() << "process callsite " << svfcall->valueOnlyToString() << "\n");
986
987
988 CallICFGNode* callBlockNode = llvmModuleSet()->getCallICFGNode(cs);
990
991 pag->addCallSite(callBlockNode);
992
994 for (u32_t i = 0; i < cs->arg_size(); i++)
996 callBlockNode,
997 SVFUtil::cast<ValVar>(pag->getGNode(getValueNode(cs->getArgOperand(i)))));
998
999 if(!cs->getType()->isVoidTy())
1001
1002 if (callBlockNode->isVirtualCall())
1003 {
1004 const Value* value = cppUtil::getVCallVtblPtr(cs);
1005 callBlockNode->setVtablePtr(pag->getGNode(getValueNode(value)));
1006 }
1007 if (const Function *callee = LLVMUtil::getCallee(cs))
1008 {
1010 if (isExtCall(svfcallee))
1011 {
1013 }
1014 else
1015 {
1017 }
1018 }
1019 else
1020 {
1021 //If the callee was not identified as a function (null F), this is indirect.
1022 handleIndCall(cs);
1023 }
1024}
1025
1030{
1031
1032 // ReturnInst itself should always not be a pointer type
1033 assert(!SVFUtil::isa<PointerType>(inst.getType()));
1034
1035 DBOUT(DPAGBuild, outs() << "process return " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
1036
1037 if(Value* src = inst.getReturnValue())
1038 {
1039 const SVFFunction *F = llvmModuleSet()->getSVFFunction(inst.getParent()->getParent());
1040
1042 NodeID vnS = getValueNode(src);
1043 const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(&inst);
1044 //vnS may be null if src is a null ptr
1045 addPhiStmt(rnF,vnS,icfgNode);
1046 }
1047}
1048
1049
1063
1077
1083{
1084 NodeID brinst = getValueNode(&inst);
1085 NodeID cond;
1086 if (inst.isConditional())
1087 cond = getValueNode(inst.getCondition());
1088 else
1089 cond = pag->getNullPtr();
1090
1091 assert(inst.getNumSuccessors() <= 2 && "if/else has more than two branches?");
1092
1094 std::vector<const Instruction*> nextInsts;
1096 u32_t branchID = 0;
1097 for (const Instruction* succInst : nextInsts)
1098 {
1099 assert(branchID <= 1 && "if/else has more than two branches?");
1100 const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(succInst);
1101 successors.push_back(std::make_pair(icfgNode, 1-branchID));
1102 branchID++;
1103 }
1104 addBranchStmt(brinst, cond, successors);
1106 if (inst.isConditional())
1107 {
1108 for (auto& edge : llvmModuleSet()->getICFGNode(&inst)->getOutEdges())
1109 {
1110 if (IntraCFGEdge* intraEdge = SVFUtil::dyn_cast<IntraCFGEdge>(edge))
1111 {
1112 intraEdge->setConditionVar(pag->getGNode(cond));
1113 }
1114 }
1115 }
1116}
1117
1118
1162
1165{
1166 NodeID brinst = getValueNode(&inst);
1167 NodeID cond = getValueNode(inst.getCondition());
1168
1170 std::vector<const Instruction*> nextInsts;
1172 for (const Instruction* succInst : nextInsts)
1173 {
1175 const ConstantInt* condVal = inst.findCaseDest(const_cast<BasicBlock*>(succInst->getParent()));
1177 s64_t val = -1;
1178 if (condVal && condVal->getBitWidth() <= 64)
1180 const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(succInst);
1181 successors.push_back(std::make_pair(icfgNode, val));
1182 }
1183 addBranchStmt(brinst, cond, successors);
1185 for (auto& edge : llvmModuleSet()->getICFGNode(&inst)->getOutEdges())
1186 {
1187 if (IntraCFGEdge* intraEdge = SVFUtil::dyn_cast<IntraCFGEdge>(edge))
1188 {
1189 intraEdge->setConditionVar(pag->getGNode(cond));
1190 }
1191 }
1192}
1193
1194
1201{
1202 NodeID dst = getValueNode(&inst);
1203 Value* opnd = inst.getPointerOperand();
1204 NodeID src = getValueNode(opnd);
1205 addCopyEdge(src, dst, CopyStmt::COPYVAL);
1206}
1207
1213{
1214 NodeID dst = getValueNode(&inst);
1215 for (u32_t i = 0; i < inst.getNumOperands(); i++)
1216 {
1217 Value* opnd = inst.getOperand(i);
1218 NodeID src = getValueNode(opnd);
1219 addCopyEdge(src, dst, CopyStmt::COPYVAL);
1220 }
1221}
1222
1223
1228{
1229
1230 assert(F);
1234 outs() << "handle direct call " << LLVMUtil::dumpValue(cs) << " callee " << F->getName().str() << "\n");
1235
1236 //Only handle the ret.val. if it's used as a ptr.
1238 //Does it actually return a ptr?
1239 if (!cs->getType()->isVoidTy())
1240 {
1244 }
1245 //Iterators for the actual and formal parameters
1246 u32_t itA = 0, ieA = cs->arg_size();
1247 Function::const_arg_iterator itF = F->arg_begin(), ieF = F->arg_end();
1248 //Go through the fixed parameters.
1249 DBOUT(DPAGBuild, outs() << " args:");
1250 for (; itF != ieF; ++itA, ++itF)
1251 {
1252 //Some programs (e.g. Linux kernel) leave unneeded parameters empty.
1253 if (itA == ieA)
1254 {
1255 DBOUT(DPAGBuild, outs() << " !! not enough args\n");
1256 break;
1257 }
1258 const Value* AA = cs->getArgOperand(itA), *FA = &*itF; //current actual/formal arg
1259
1260 DBOUT(DPAGBuild, outs() << "process actual parm " << llvmModuleSet()->getSVFValue(AA)->toString() << " \n");
1261
1266 }
1267 //Any remaining actual args must be varargs.
1268 if (F->isVarArg())
1269 {
1271 DBOUT(DPAGBuild, outs() << "\n varargs:");
1272 for (; itA != ieA; ++itA)
1273 {
1274 const Value* AA = cs->getArgOperand(itA);
1278 }
1279 }
1280 if(itA != ieA)
1281 {
1284 writeWrnMsg("too many args to non-vararg func.");
1285 writeWrnMsg("(" + callICFGNode->getSourceLoc() + ")");
1286
1287 }
1288}
1289
1291{
1292 const Value* value = stripAllCasts(V);
1293 assert(value && "null ptr?");
1294 if(const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(value))
1295 {
1296 APOffset totalidx = 0;
1297 for (bridge_gep_iterator gi = bridge_gep_begin(gep), ge = bridge_gep_end(gep); gi != ge; ++gi)
1298 {
1299 if(const ConstantInt* op = SVFUtil::dyn_cast<ConstantInt>(gi.getOperand()))
1301 }
1302 if(totalidx == 0 && !SVFUtil::isa<StructType>(value->getType()))
1303 value = gep->getPointerOperand();
1304 }
1305 return value;
1306}
1307
1318
1320{
1321 PTACallGraph::CallEdgeMap::const_iterator iter = callgraph->getIndCallMap().begin();
1322 PTACallGraph::CallEdgeMap::const_iterator eiter = callgraph->getIndCallMap().end();
1323 for (; iter != eiter; iter++)
1324 {
1325 const CallICFGNode* callBlock = iter->first;
1326 const CallBase* callbase = SVFUtil::cast<CallBase>(llvmModuleSet()->getLLVMValue(callBlock));
1327 assert(callBlock->isIndirectCall() && "this is not an indirect call?");
1328 const PTACallGraph::FunctionSet& functions = iter->second;
1329 for (PTACallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
1330 {
1331 const Function* callee = SVFUtil::cast<Function>(llvmModuleSet()->getLLVMValue(*func_iter));
1332
1333 if (isExtCall(*func_iter))
1334 {
1335 setCurrentLocation(callee, callee->empty() ? nullptr : &callee->getEntryBlock());
1338 }
1339 else
1340 {
1341 setCurrentLocation(llvmModuleSet()->getSVFValue(llvmModuleSet()->getLLVMValue(callBlock)), callBlock->getBB());
1342 handleDirectCall(const_cast<CallBase*>(callbase), callee);
1343 }
1344 }
1345 }
1346
1347 // dump SVFIR
1349 pag->dump("svfir_final");
1350}
1351
1352/*
1353 * TODO: more sanity checks might be needed here
1354 */
1356{
1357 for (SVFIR::iterator nIter = pag->begin(); nIter != pag->end(); ++nIter)
1358 {
1359 (void) pag->getGNode(nIter->first);
1360 //TODO::
1361 // (1) every source(root) node of a pag tree should be object node
1362 // if a node has no incoming edge, but has outgoing edges
1363 // then it has to be an object node.
1364 // (2) make sure every variable should be initialized
1365 // otherwise it causes the a null pointer, the aliasing relation may not be captured
1366 // when loading a pointer value should make sure
1367 // some value has been store into this pointer before
1368 // q = load p, some value should stored into p first like store w p;
1369 // (3) make sure PAGNode should not have a const expr value (pointer should have unique def)
1370 // (4) look closely into addComplexConsForExt, make sure program locations(e.g.,inst bb)
1371 // are set correctly for dummy gepval node
1372 // (5) reduce unnecessary copy edge (const casts) and ensure correctness.
1373 }
1374}
1375
1376
1382{
1383 NodeID base = getValueNode(val);
1384 NodeID gepval = pag->getGepValVar(curVal, base, ap);
1385 if (gepval==UINT_MAX)
1386 {
1387 assert(((int) UINT_MAX)==-1 && "maximum limit of unsigned int is not -1?");
1388 /*
1389 * getGepValVar can only be called from two places:
1390 * 1. SVFIRBuilder::addComplexConsForExt to handle external calls
1391 * 2. SVFIRBuilder::getGlobalVarField to initialize global variable
1392 * so curVal can only be
1393 * 1. Instruction
1394 * 2. GlobalVariable
1395 */
1396 assert((SVFUtil::isa<SVFInstruction, SVFGlobalValue>(curVal)) && "curVal not an instruction or a globalvariable?");
1397
1398 // We assume every GepValNode and its GepEdge to the baseNode are unique across the whole program
1399 // We preserve the current BB information to restore it after creating the gepNode
1400 const SVFValue* cval = getCurrentValue();
1401 const SVFBasicBlock* cbb = getCurrentBB();
1402 setCurrentLocation(curVal, nullptr);
1404 NodeID gepNode = pag->addGepValNode(curVal, llvmmodule->getSVFValue(val), ap,
1406 llvmmodule->getSVFType(PointerType::getUnqual(llvmmodule->getContext())));
1407 addGepEdge(base, gepNode, ap, true);
1409 return gepNode;
1410 }
1411 else
1412 return gepval;
1413}
1414
1415
1416/*
1417 * curVal <--------> PAGEdge
1418 * Instruction Any Edge
1419 * Argument CopyEdge (SVFIR::addFormalParamBlackHoleAddrEdge)
1420 * ConstantExpr CopyEdge (Int2PtrConstantExpr CastConstantExpr SVFIRBuilder::processCE)
1421 * GepEdge (GepConstantExpr SVFIRBuilder::processCE)
1422 * ConstantPointerNull CopyEdge (3-->2 NullPtr-->BlkPtr SVFIR::addNullPtrNode)
1423 * AddrEdge (0-->2 BlkObj-->BlkPtr SVFIR::addNullPtrNode)
1424 * GlobalVariable AddrEdge (SVFIRBuilder::visitGlobal)
1425 * GepEdge (SVFIRBuilder::getGlobalVarField)
1426 * Function AddrEdge (SVFIRBuilder::visitGlobal)
1427 * Constant StoreEdge (SVFIRBuilder::InitialGlobal)
1428 */
1430{
1432 return;
1433
1434 assert(curVal && "current Val is nullptr?");
1435 edge->setBB(curBB!=nullptr ? curBB : nullptr);
1436 edge->setValue(curVal);
1437 // backmap in valuToEdgeMap
1439 ICFGNode* icfgNode = pag->getICFG()->getGlobalICFGNode();
1441 if (const SVFInstruction* curInst = SVFUtil::dyn_cast<SVFInstruction>(curVal))
1442 {
1443 const SVFFunction* srcFun = edge->getSrcNode()->getFunction();
1444 const SVFFunction* dstFun = edge->getDstNode()->getFunction();
1445 if(srcFun!=nullptr && !SVFUtil::isa<RetPE>(edge) && edge->getSrcNode()->hasValue() && !SVFUtil::isa<SVFFunction>(edge->getSrcNode()->getValue()))
1446 {
1447 assert(srcFun==curInst->getFunction() && "SrcNode of the PAGEdge not in the same function?");
1448 }
1449 if(dstFun!=nullptr && !SVFUtil::isa<CallPE>(edge) && !SVFUtil::isa<RetPN>(edge->getDstNode()))
1450 {
1451 assert(dstFun==curInst->getFunction() && "DstNode of the PAGEdge not in the same function?");
1452 }
1453
1455 if (!(SVFUtil::isa<GepStmt>(edge) && SVFUtil::isa<GepValVar>(edge->getDstNode())))
1456 assert(curBB && "instruction does not have a basic block??");
1457
1459 if(curInst->isRetInst())
1460 {
1461 icfgNode = pag->getICFG()->getFunExitICFGNode(curInst->getFunction());
1462 }
1463 else
1464 {
1465 if(SVFUtil::isa<RetPE>(edge))
1466 icfgNode = llvmMS->getRetICFGNode(SVFUtil::cast<Instruction>(llvmMS->getLLVMValue(curInst)));
1467 else
1468 icfgNode = llvmMS->getICFGNode(SVFUtil::cast<Instruction>(llvmMS->getLLVMValue(curInst)));
1469 }
1470 }
1471 else if (const SVFArgument* arg = SVFUtil::dyn_cast<SVFArgument>(curVal))
1472 {
1474 icfgNode = pag->getICFG()->getFunEntryICFGNode(arg->getParent());
1475 }
1476 else if (SVFUtil::isa<SVFConstant>(curVal) ||
1477 SVFUtil::isa<SVFFunction>(curVal) ||
1478 SVFUtil::isa<SVFMetadataAsValue>(curVal))
1479 {
1480 if (!curBB)
1482 else
1483 {
1484 icfgNode = const_cast<ICFGNode*>(curBB->front());
1485 }
1486 }
1487 else
1488 {
1489 assert(false && "what else value can we have?");
1490 }
1491
1492 pag->addToSVFStmtList(icfgNode,edge);
1493 icfgNode->addSVFStmt(edge);
1494 if(const CallPE* callPE = SVFUtil::dyn_cast<CallPE>(edge))
1495 {
1496 CallICFGNode* callNode = const_cast<CallICFGNode*>(callPE->getCallSite());
1497 FunEntryICFGNode* entryNode = const_cast<FunEntryICFGNode*>(callPE->getFunEntryICFGNode());
1499 SVFUtil::cast<CallCFGEdge>(edge)->addCallPE(callPE);
1500 }
1501 else if(const RetPE* retPE = SVFUtil::dyn_cast<RetPE>(edge))
1502 {
1503 RetICFGNode* retNode = const_cast<RetICFGNode*>(retPE->getCallSite()->getRetICFGNode());
1504 FunExitICFGNode* exitNode = const_cast<FunExitICFGNode*>(retPE->getFunExitICFGNode());
1506 SVFUtil::cast<RetCFGEdge>(edge)->addRetPE(retPE);
1507 }
1508}
1509
1510
1518{
1519 SVFVar* node = pag->getGNode(nodeId);
1522 if(geps.empty())
1523 return AccessPath(0);
1524
1525 assert(geps.size()==1 && "one node can only be connected by at most one gep edge!");
1526 SVFVar::iterator it = geps.begin();
1527 const GepStmt* gepEdge = SVFUtil::cast<GepStmt>(*it);
1528 if(gepEdge->isVariantFieldGep())
1529 return AccessPath(0);
1530 else
1531 return gepEdge->getAccessPath();
1532}
#define F(f)
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:484
#define TIMEINTERVAL
Definition SVFType.h:512
#define DGENERAL
Definition SVFType.h:490
#define DPAGBuild
Definition SVFType.h:492
buffer offset
Definition cJSON.cpp:1113
bool addOffsetVarAndGepTypePair(const SVFVar *var, const SVFType *gepIterType)
APOffset getConstantStructFldIdx() const
Get methods.
Definition AccessPath.h:100
void setFldIdx(APOffset idx)
Definition AccessPath.h:104
std::vector< std::pair< const ICFGNode *, s32_t > > SuccAndCondPairVec
bool isVirtualCall() const
Definition ICFGNode.h:527
void setVtablePtr(SVFVar *v)
Definition ICFGNode.h:532
iterator begin()
Iterators.
u32_t getTotalNodeNum() const
Get total number of node/edge.
IDToNodeMapTy::iterator iterator
Node Iterators.
NodeType * getGNode(NodeID id) const
Get a node.
GEdgeSetTy::iterator iterator
const GEdgeSetTy & getOutEdges() const
void addSVFStmt(const SVFStmt *edge)
Definition ICFGNode.h:112
FunEntryICFGNode * getFunEntryICFGNode(const SVFFunction *fun)
Add a function entry node.
Definition ICFG.cpp:234
ICFGEdge * hasInterICFGEdge(ICFGNode *src, ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
Definition ICFG.cpp:268
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
Definition ICFG.cpp:403
GlobalICFGNode * getGlobalICFGNode() const
Definition ICFG.h:236
FunExitICFGNode * getFunExitICFGNode(const SVFFunction *fun)
Add a function exit node.
Definition ICFG.cpp:241
u32_t getNodeNumAfterPAGBuild() const
Definition IRGraph.h:194
void dump(std::string name)
Dump SVFIR.
Definition IRGraph.cpp:102
NodeID getBlkPtr() const
Definition IRGraph.h:169
NodeID getNullPtr() const
Definition IRGraph.h:173
NodeID getValueNode(const SVFValue *V)
Definition IRGraph.h:137
void mapValueToEdge(const SVFValue *V, SVFStmt *edge)
Map a value to a set of edges.
Definition IRGraph.h:89
void setNodeNumAfterPAGBuild(u32_t num)
Definition IRGraph.h:198
SymbolTableInfo * getSymbolInfo() const
Definition IRGraph.h:114
NodeID getReturnNode(const SVFFunction *func) const
GetReturnNode - Return the unique node representing the return value of a function.
Definition IRGraph.h:152
NodeID getConstantNode() const
Definition IRGraph.h:165
virtual void build(ICFG *icfg)
Start from here.
void addToLLVMVal2SVFVarMap(const Value *val, SVFBaseNode *svfBaseNode)
CallGraphNode * getCallGraphNode(const Function *fun) const
Definition LLVMModule.h:253
const Value * getLLVMValue(const SVFValue *value) const
Definition LLVMModule.h:239
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
bool hasICFGNode(const Instruction *inst)
ICFGNode * getICFGNode(const Instruction *inst)
Get a basic block ICFGNode.
CallICFGNode * getCallICFGNode(const Instruction *cs)
get a call node
RetICFGNode * getRetICFGNode(const Instruction *cs)
get a return node
SVFFunction * getSVFFunction(const Function *fun) const
Definition LLVMModule.h:260
const std::vector< std::reference_wrapper< Module > > & getLLVMModules() const
Definition LLVMModule.h:153
SVFValue * getSVFValue(const Value *value)
NodeID allocateValueId(void)
Allocate a value ID as determined by the strategy.
static NodeIDAllocator * get(void)
Return (singleton) allocator.
static const Option< bool > ModelConsts
Definition Options.h:187
static const Option< bool > PAGDotGraph
Definition Options.h:121
static const Option< std::string > DumpJson
Definition Options.h:124
static const Option< bool > PAGPrint
Definition Options.h:127
static const Option< bool > VtableInSVFIR
Definition Options.h:217
static const Option< bool > LoopAnalysis
Definition Options.h:242
static const Option< bool > DumpICFG
Definition Options.h:123
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
Set< const SVFFunction * > FunctionSet
const SVFFunction * getParent() const
Definition SVFValue.h:595
const ICFGNode * front() const
Definition SVFValue.h:605
const SVFBasicBlock * getEntryBlock() const
Definition SVFValue.h:420
u32_t inferFieldIdxFromByteOffset(const llvm::GEPOperator *gepOp, DataLayout *dl, AccessPath &ap, APOffset idx)
Infer field index from byteoffset.
CopyStmt::CopyKind getCopyKind(const Value *val)
void sanityCheck()
Sanity check for SVFIR.
SVFIR * getPAG() const
Return SVFIR.
void setCurrentLocation(const Value *val, const BasicBlock *bb)
Set current basic block in order to keep track of control flow information.
NodeID addNullPtrNode()
Add NullPtr PAGNode.
void visitLoadInst(LoadInst &I)
void updateCallGraph(PTACallGraph *callgraph)
connect PAG edges based on callgraph
void addPhiStmt(NodeID res, NodeID opnd, const ICFGNode *pred)
Add Copy edge.
void addStoreEdge(NodeID src, NodeID dst)
Add Store edge.
AddrStmt * addAddrEdge(NodeID src, NodeID dst)
Add Address edge.
void visitInvokeInst(InvokeInst &II)
void handleDirectCall(CallBase *cs, const Function *F)
Handle direct call.
void addBinaryOPEdge(NodeID op1, NodeID op2, NodeID dst, u32_t opcode)
Add Copy edge.
NodeID getVarargNode(const SVFFunction *func)
getVarargNode - Return the node representing the unique variadic argument of a function.
void visitCallInst(CallInst &I)
void addLoadEdge(NodeID src, NodeID dst)
Add Load edge.
void visitGetElementPtrInst(GetElementPtrInst &I)
void visitBranchInst(BranchInst &I)
virtual void visitAllocaInst(AllocaInst &AI)
Our visit overrides.
void visitGlobal(SVFModule *svfModule)
Handle globals including (global variable and functions)
void addGepEdge(NodeID src, NodeID dst, const AccessPath &ap, bool constGep)
Add Gep edge.
void addCmpEdge(NodeID op1, NodeID op2, NodeID dst, u32_t predict)
Add Copy edge.
LLVMModuleSet * llvmModuleSet()
void visitStoreInst(StoreInst &I)
NodeID getObjectNode(const Value *V)
GetObject - Return the object node (stack/global/heap/function) according to a LLVM Value.
void visitCallSite(CallBase *cs)
void processCE(const Value *val)
Process constant expression.
void handleIndCall(CallBase *cs)
Handle indirect call.
void addSelectStmt(NodeID res, NodeID op1, NodeID op2, NodeID cond)
Add SelectStmt.
void addBranchStmt(NodeID br, NodeID cond, const BranchStmt::SuccAndCondPairVec &succs)
Add Branch statement.
virtual SVFIR * build()
Start building SVFIR here.
void visitCallBrInst(CallBrInst &I)
SVFModule * svfModule
void visitExtractValueInst(ExtractValueInst &EVI)
AccessPath getAccessPathFromBaseNode(NodeID nodeId)
const SVFBasicBlock * curBB
Current basic block during SVFIR construction when visiting the module.
void visitSwitchInst(SwitchInst &I)
The following implementation follows ICFGBuilder::processFunBody.
void visitFreezeInst(FreezeInst &I)
const Value * getBaseValueForExtArg(const Value *V)
Get the base value of (i8* src and i8* dst) for external argument (e.g. memcpy(i8* dst,...
void addRetEdge(NodeID src, NodeID dst, const CallICFGNode *cs, const FunExitICFGNode *exit)
Add Return edge.
virtual void handleExtCall(const CallBase *cs, const SVFFunction *svfCallee)
void addBlackHoleAddrEdge(NodeID node)
const SVFValue * getCurrentValue() const
void addUnaryOPEdge(NodeID src, NodeID dst, u32_t opcode)
Add Unary edge.
const SVFBasicBlock * getCurrentBB() const
void visitPHINode(PHINode &I)
CopyStmt * addCopyEdge(NodeID src, NodeID dst, CopyStmt::CopyKind kind)
void addCallEdge(NodeID src, NodeID dst, const CallICFGNode *cs, const FunEntryICFGNode *entry)
Add Call edge.
void setCurrentBBAndValueForPAGEdge(PAGEdge *edge)
void visitSelectInst(SelectInst &I)
void visitVAArgInst(VAArgInst &)
void visitCmpInst(CmpInst &I)
void visitExtractElementInst(ExtractElementInst &I)
bool computeGepOffset(const User *V, AccessPath &ap)
Compute offset of a gep instruction or gep constant expression.
void visitReturnInst(ReturnInst &I)
NodeID getValueNode(const Value *V)
Get different kinds of node.
void visitCastInst(CastInst &I)
AddrStmt * addAddrWithStackArraySz(NodeID src, NodeID dst, llvm::AllocaInst &inst)
Add Address edge from allocinst with arraysize like "%4 = alloca i8, i64 3".
NodeID getGepValVar(const Value *val, const AccessPath &ap, const SVFType *elementType)
void InitialGlobal(const GlobalVariable *gvar, Constant *C, u32_t offset)
void visitUnaryOperator(UnaryOperator &I)
void visitBinaryOperator(BinaryOperator &I)
const SVFValue * curVal
Current Value during SVFIR construction when visiting the module.
void initialiseNodes()
Initialize nodes and edges.
NodeID getGlobalVarField(const GlobalVariable *gvar, u32_t offset, SVFType *tpy)
NodeID getReturnNode(const SVFFunction *func)
getReturnNode - Return the node representing the unique return value of a function.
static void writeJsonToPath(const SVFIR *svfir, const std::string &path)
NodeID addStackObjNode(const SVFValue *val, const SVFFunction *f, NodeID i)
Definition SVFIR.h:637
NodeID addObjNode(const SVFValue *val, NodeID i)
Add a memory obj node.
Definition SVFIR.h:615
NodeID addGlobalValueObjNode(const SVFValue *curInst, const NodeID i)
Definition SVFIR.h:679
void print()
Print SVFIR.
Definition SVFIR.cpp:566
NodeID addConstantIntObjNode(const SVFValue *curInst, const std::pair< s64_t, u64_t > &intValue, const NodeID i)
Definition SVFIR.h:659
NodeID addBlackholePtrNode()
Definition SVFIR.h:746
NodeID addBlackholeObjNode()
Definition SVFIR.h:734
NodeID addConstantIntValNode(const SVFValue *curInst, const std::pair< s64_t, u64_t > &intValue, const NodeID i, const ICFGNode *icfgNode)
Definition SVFIR.h:588
NodeID addGlobalValueValNode(const SVFValue *curInst, const NodeID i, const ICFGNode *icfgNode)
Definition SVFIR.h:601
void setModule(SVFModule *mod)
Set/Get LLVM Module.
Definition SVFIR.h:158
void addFunRet(const SVFFunction *fun, const SVFVar *ret)
Add function returns.
Definition SVFIR.h:539
NodeID addGepValNode(const SVFValue *curInst, const SVFValue *val, const AccessPath &ap, NodeID i, const SVFType *type)
Add a temp field value node, this method can only invoked by getGepValVar.
Definition SVFIR.cpp:387
NodeID addConstantFPObjNode(const SVFValue *curInst, double dval, const NodeID i)
Definition SVFIR.h:649
NodeID addConstantNullPtrObjNode(const SVFValue *curInst, const NodeID i)
Definition SVFIR.h:670
NodeID addValNode(const SVFValue *val, NodeID i, const ICFGNode *icfgNode)
add node into SVFIR
Definition SVFIR.h:569
NodeID addConstantFPValNode(const SVFValue *curInst, double dval, const NodeID i, const ICFGNode *icfgNode)
Definition SVFIR.h:581
void addToSVFStmtList(ICFGNode *inst, SVFStmt *edge)
Add a SVFStmt into instruction map.
Definition SVFIR.h:232
NodeID addFunValNode(const CallGraphNode *callGraphNode, NodeID i, const ICFGNode *icfgNode)
Definition SVFIR.h:575
void addCallSiteRets(RetICFGNode *retBlockNode, const SVFVar *arg)
Add callsite returns.
Definition SVFIR.h:552
void setICFG(ICFG *i)
Set/Get ICFG.
Definition SVFIR.h:168
void addCallSiteArgs(CallICFGNode *callBlockNode, const ValVar *arg)
Add callsite arguments.
Definition SVFIR.h:546
ICFG * getICFG() const
Definition SVFIR.h:172
NodeID addConstantNullPtrValNode(const SVFValue *curInst, const NodeID i, const ICFGNode *icfgNode)
Definition SVFIR.h:595
void addCallSite(const CallICFGNode *call)
Add callsites.
Definition SVFIR.h:785
NodeID addRetNode(const CallGraphNode *callGraphNode, NodeID i)
Add a unique return node for a procedure.
Definition SVFIR.h:698
void setCHG(CommonCHGraph *c)
Set/Get CHG.
Definition SVFIR.h:178
SVFModule * getModule()
Definition SVFIR.h:162
NodeID addVarargNode(const CallGraphNode *val, NodeID i)
Add a unique vararg node for a procedure.
Definition SVFIR.h:704
NodeID addHeapObjNode(const SVFValue *val, const SVFFunction *f, NodeID i)
Definition SVFIR.h:625
void addFunArgs(const SVFFunction *fun, const SVFVar *arg)
Get/set method for function/callsite arguments and returns.
Definition SVFIR.h:532
NodeID addConstantDataValNode(const SVFValue *curInst, const NodeID i, const ICFGNode *icfgNode)
Definition SVFIR.h:607
void setCallGraph(CallGraph *c)
Set/Get CG.
Definition SVFIR.h:189
NodeID addConstantDataObjNode(const SVFValue *curInst, const NodeID i)
Definition SVFIR.h:688
NodeID getGepValVar(const SVFValue *curInst, NodeID base, const AccessPath &ap) const
Due to constraint expression, curInst is used to distinguish different instructions (e....
Definition SVFIR.cpp:529
NodeID addFunObjNode(const CallGraphNode *callGraphNode, NodeID id)
Definition SVFIR.cpp:475
void addGlobalPAGEdge(const SVFStmt *edge)
Add global PAGEdges (not in a procedure)
Definition SVFIR.h:780
void addIndirectCallsites(const CallICFGNode *cs, NodeID funPtr)
Add indirect callsites.
Definition SVFIR.h:558
void initialiseCandidatePointers()
Initialize candidate pointers.
Definition SVFIR.cpp:651
NodeID addConstantObjNode()
Definition SVFIR.h:740
static bool pagReadFromTXT()
Definition SVFModule.h:98
static std::string pagFileName()
Definition SVFModule.h:93
static double getClk(bool mark=false)
Definition SVFStat.cpp:48
static double timeOfBuildingSVFIR
Definition SVFStat.h:95
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
SVFStmt::SVFStmtSetTy & getIncomingEdges(SVFStmt::PEDGEK kind)
Get incoming SVFIR statements (edges)
u32_t getFlattenedElemIdx(const SVFType *T, u32_t origId)
Flattened element idx of an array or struct by considering stride.
static SymbolTableInfo * SymbolInfo()
Singleton design here to make sure we only have one instance during any analysis.
IDToMemMapTy & idToObjMap()
bool isIntrinsicInst(const Instruction *inst)
Return true if it is an intrinsic instruction.
Definition LLVMUtil.cpp:203
const ConstantExpr * isBinaryConstantExpr(const Value *val)
Definition LLVMUtil.h:291
double getDoubleValue(const ConstantFP *fpValue)
Definition LLVMUtil.h:55
const Value * stripAllCasts(const Value *val)
Strip off the all casts.
Definition LLVMUtil.cpp:250
const ConstantExpr * isInt2PtrConstantExpr(const Value *val)
Definition LLVMUtil.h:226
const ConstantExpr * isSelectConstantExpr(const Value *val)
Definition LLVMUtil.h:256
const ConstantExpr * isTruncConstantExpr(const Value *val)
Definition LLVMUtil.h:266
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
Definition LLVMUtil.h:83
void getNextInsts(const Instruction *curInst, std::vector< const Instruction * > &instList)
Get the next instructions following control flow.
Definition LLVMUtil.cpp:550
const ConstantExpr * isPtr2IntConstantExpr(const Value *val)
Definition LLVMUtil.h:236
bool isHeapObj(const Value *val)
Definition LLVMUtil.cpp:669
const ConstantExpr * isUnaryConstantExpr(const Value *val)
Definition LLVMUtil.h:302
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition LLVMUtil.h:246
bool isStackObj(const Value *val)
Definition LLVMUtil.cpp:691
bool isConstantObjSym(const SVFValue *val)
Check whether this value points-to a constant object.
Definition LLVMUtil.cpp:578
const ConstantExpr * isGepConstantExpr(const Value *val)
Return corresponding constant expression, otherwise return nullptr.
Definition LLVMUtil.h:216
static DataLayout * getDataLayout(Module *mod)
Definition LLVMUtil.h:314
const Function * getCallee(const CallBase *cs)
Definition LLVMUtil.h:98
std::string dumpValue(const Value *val)
Definition LLVMUtil.cpp:584
const ConstantExpr * isCmpConstantExpr(const Value *val)
Definition LLVMUtil.h:280
bool isExtCall(const SVFFunction *fun)
Definition SVFUtil.h:278
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:100
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:67
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50
const Value * getVCallVtblPtr(const CallBase *cs)
Definition CppUtil.cpp:537
bool isValVtbl(const Value *val)
Definition CppUtil.cpp:336
for isBitcode
Definition BasicTypes.h:68
llvm::DataLayout DataLayout
Definition BasicTypes.h:108
llvm::GlobalVariable GlobalVariable
Definition BasicTypes.h:130
llvm::GlobalAlias GlobalAlias
Definition BasicTypes.h:128
llvm::ArrayType ArrayType
Definition BasicTypes.h:95
llvm::Type Type
Definition BasicTypes.h:83
llvm::CallBase CallBase
Definition BasicTypes.h:146
llvm::BasicBlock BasicBlock
Definition BasicTypes.h:86
llvm::UnaryOperator UnaryOperator
Definition BasicTypes.h:180
llvm::StructType StructType
LLVM types.
Definition BasicTypes.h:94
llvm::AllocaInst AllocaInst
Definition BasicTypes.h:150
llvm::SwitchInst SwitchInst
Definition BasicTypes.h:155
u32_t NodeID
Definition GeneralType.h:55
llvm::InvokeInst InvokeInst
Definition BasicTypes.h:163
llvm::LoadInst LoadInst
Definition BasicTypes.h:149
s64_t APOffset
Definition GeneralType.h:60
llvm::CmpInst CmpInst
Definition BasicTypes.h:159
llvm::Function Function
Definition BasicTypes.h:85
llvm::ConstantData ConstantData
Definition BasicTypes.h:116
llvm::Instruction Instruction
Definition BasicTypes.h:87
llvm::Constant Constant
Definition BasicTypes.h:124
llvm::ConstantDataSequential ConstantDataSequential
Definition BasicTypes.h:119
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:82
llvm::ConstantExpr ConstantExpr
Definition BasicTypes.h:120
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
llvm::CastInst CastInst
Definition BasicTypes.h:158
llvm::FreezeInst FreezeInst
Definition BasicTypes.h:169
llvm::Module Module
Definition BasicTypes.h:84
llvm::BinaryOperator BinaryOperator
Definition BasicTypes.h:179
llvm::StoreInst StoreInst
Definition BasicTypes.h:148
llvm::SelectInst SelectInst
Definition BasicTypes.h:174
llvm::VAArgInst VAArgInst
Definition BasicTypes.h:175
llvm::GetElementPtrInst GetElementPtrInst
Definition BasicTypes.h:162
llvm::CallBrInst CallBrInst
Definition BasicTypes.h:156
llvm::ReturnInst ReturnInst
Definition BasicTypes.h:157
llvm::PHINode PHINode
Definition BasicTypes.h:165
llvm::BranchInst BranchInst
Definition BasicTypes.h:154
llvm::ExtractValueInst ExtractValueInst
Definition BasicTypes.h:160
unsigned u32_t
Definition GeneralType.h:46
signed long long s64_t
Definition GeneralType.h:49
llvm::CallInst CallInst
Definition BasicTypes.h:147
llvm::ConstantInt ConstantInt
Definition BasicTypes.h:125
llvm::ExtractElementInst ExtractElementInst
Definition BasicTypes.h:161
llvm::User User
Definition BasicTypes.h:142