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 * Refactored on: Jan 25, 2024
29 * Author: Xiao Cheng, Yulei Sui
30 */
31
33#include "SVF-LLVM/BasicTypes.h"
34#include "SVF-LLVM/CHGBuilder.h"
35#include "SVF-LLVM/CppUtil.h"
37#include "SVF-LLVM/LLVMUtil.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 // If the SVFIR has been built before, then we return the unique SVFIR of the program
63 return pag;
64
65
67
70 pag->icfg = icfgbuilder.build();
71
79
80
81
84 std::vector<const FunObjVar*> funset;
85 for (const auto& item: llvmModuleSet()->getFunctionSet())
86 {
88 }
89 pag->callGraph = callGraphBuilder.buildSVFIRCallGraph(funset);
90
91 CHGraph* chg = new CHGraph();
93 chgbuilder.buildCHG();
94 pag->setCHG(chg);
95
98 {
99 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
100 {
101 const Function& fun = *F;
102 const FunObjVar* svffun = llvmModuleSet()->getFunObjVar(&fun);
104 if(!fun.isDeclaration())
105 {
111 if (fun.doesNotReturn() == false &&
112 fun.getReturnType()->isVoidTy() == false)
113 {
116 }
117
120 for (Function::const_arg_iterator I = fun.arg_begin(), E = fun.arg_end();
121 I != E; ++I)
122 {
123 setCurrentLocation(&*I,&fun.getEntryBlock());
125 // if this is the function does not have caller (e.g. main)
126 // or a dead function, shall we create a black hole address edge for it?
127 // it is (1) too conservative, and (2) make FormalParmVFGNode defined at blackhole address PAGEdge.
128 // if(SVFUtil::ArgInNoCallerFunction(&*I)) {
129 // if(I->getType()->isPointerTy())
130 // addBlackHoleAddrEdge(argValNodeId);
131 //}
133 }
134 }
135 for (Function::const_iterator bit = fun.begin(), ebit = fun.end();
136 bit != ebit; ++bit)
137 {
138 const BasicBlock& bb = *bit;
139 for (BasicBlock::const_iterator it = bb.begin(), eit = bb.end();
140 it != eit; ++it)
141 {
142 const Instruction& inst = *it;
143 setCurrentLocation(&inst,&bb);
144 visit(const_cast<Instruction&>(inst));
145 }
146 }
147 }
148 }
149
150 sanityCheck();
151
153
155
156 // dump SVFIR
158 pag->dump("svfir_initial");
159
160 // print to command line of the SVFIR graph
161 if (Options::PAGPrint())
162 pag->print();
163
164 // dump ICFG
165 if (Options::DumpICFG())
166 pag->getICFG()->dump("icfg_initial");
167
169 {
172 }
173
174 // dump SVFIR as JSON
175 if (!Options::DumpJson().empty())
176 {
177 assert(false && "please implement SVFIRWriter::writeJsonToPath");
178 }
179
180 double endTime = SVFStat::getClk(true);
181 SVFStat::timeOfBuildingSVFIR = (endTime - startTime) / TIMEINTERVAL;
182
183 return pag;
184}
185
187{
189 {
191 for (const Function& f : mod.functions())
192 {
195
196 if (!LLVMUtil::isExtCall(&f))
197 {
199 }
202 svffun->setRelDefFun(realfun == nullptr ? nullptr : llvmModuleSet()->getFunObjVar(realfun));
203 }
204 }
205
206 // Store annotations of functions in extapi.bc
207 for (const auto& pair : llvmModuleSet()->ExtFun2Annotations)
208 {
210 }
211
212}
213
215{
217 for (Function::const_iterator bit = func->begin(), ebit = func->end(); bit != ebit; ++bit)
218 {
219 const BasicBlock* bb = &*bit;
222 {
225 }
227 {
230 }
231
233 if (svfbb->getSuccessors().empty())
234 {
236 {
238 SVFUtil::isa<ReturnInst>(bb->back())) &&
239 "last inst must be return inst");
240 svfFun->setExitBlock(svfbb);
241 }
242 }
243 }
244 // For no return functions, we set the last block as exit BB
245 // This ensures that each function that has definition must have an exit BB
246 if (svfFun->hasBasicBlock() && svfFun->exitBlock == nullptr)
247 {
248 SVFBasicBlock* retBB = const_cast<SVFBasicBlock*>(svfFun->back());
250 SVFUtil::isa<ReturnInst>(&func->back().back())) &&
251 "last inst must be return inst");
252 svfFun->setExitBlock(retBB);
253 }
254}
255
256
258{
259 if (fun->isDeclaration())
260 return;
261 //process and stored dt & df
264 df.analyze(dt);
266 PostDominatorTree pdt = PostDominatorTree(const_cast<Function&>(*fun));
267 SVFLoopAndDomInfo* ld = svffun->getLoopAndDomInfo();
268
270 for (DominanceFrontierBase::const_iterator dfIter = df.begin(), eDfIter = df.end(); dfIter != eDfIter; dfIter++)
271 {
272 const BasicBlock* keyBB = dfIter->first;
273#if LLVM_VERSION_MAJOR > 16
274 const llvm::SetVector<llvm::BasicBlock* >& domSet = dfIter->second;
275#else
276 const std::set<BasicBlock* >& domSet = dfIter->second;
277#endif
279 for (const BasicBlock* bbValue:domSet)
280 {
282 }
283 }
284 std::vector<const SVFBasicBlock*> reachableBBs;
285 LLVMUtil::getFunReachableBBs(fun, reachableBBs);
286 ld->setReachableBBs(reachableBBs);
287
288 for (Function::const_iterator bit = fun->begin(), beit = fun->end(); bit!=beit; ++bit)
289 {
290 const BasicBlock &bb = *bit;
292 if (DomTreeNode* dtNode = dt.getNode(&bb))
293 {
294 SVFLoopAndDomInfo::BBSet& bbSet = ld->getDomTreeMap()[svfBB];
295 for (const auto domBB : *dtNode)
296 {
297 const auto* domSVFBB = llvmModuleSet()->getSVFBasicBlock(domBB->getBlock());
298 bbSet.insert(domSVFBB);
299 }
300 }
301
302 if (DomTreeNode* pdtNode = pdt.getNode(&bb))
303 {
304 u32_t level = pdtNode->getLevel();
305 ld->getBBPDomLevel()[svfBB] = level;
306 BasicBlock* idomBB = pdtNode->getIDom()->getBlock();
308 ld->getBB2PIdom()[svfBB] = idom;
309
310 SVFLoopAndDomInfo::BBSet& bbSet = ld->getPostDomTreeMap()[svfBB];
311 for (const auto domBB : *pdtNode)
312 {
313 const auto* domSVFBB = llvmModuleSet()->getSVFBasicBlock(domBB->getBlock());
314 bbSet.insert(domSVFBB);
315 }
316 }
317
318 if (const Loop* loop = loopInfo.getLoopFor(&bb))
319 {
320 for (const BasicBlock* loopBlock : loop->getBlocks())
321 {
323 ld->addToBB2LoopMap(svfBB, loopbb);
324 }
325 }
326 }
327}
328
330{
331 std::vector<FunObjVar*> funset;
332 // Iterate over all object symbols in the symbol table
333 for (const auto* fun: llvmModuleSet()->getFunctionSet())
334 {
335 u32_t id = llvmModuleSet()->objSyms()[fun];
336 // Debug output for adding object node
337 DBOUT(DPAGBuild, outs() << "add obj node " << id << "\n");
338
339 // Check if the value is a function and add a function object node
340 pag->addFunObjNode(id, pag->getObjTypeInfo(id), nullptr);
342
343 FunObjVar *funObjVar = SVFUtil::cast<FunObjVar>(pag->getGNode(id));
344 funset.push_back(funObjVar);
345
346 funObjVar->initFunObjVar(fun->isDeclaration(), LLVMUtil::isIntrinsicFun(fun), fun->hasAddressTaken(),
348 SVFUtil::cast<SVFFunctionType>(llvmModuleSet()->getSVFType(fun->getFunctionType())),
349 new SVFLoopAndDomInfo, nullptr, nullptr,
350 {}, nullptr);
351 BasicBlockGraph* bbGraph = new BasicBlockGraph();
352 funObjVar->setBasicBlockGraph(bbGraph);
353
354
355 for (const BasicBlock& bb : *fun)
356 {
357 llvmModuleSet()->addBasicBlock(funObjVar, &bb);
358 }
359
361 for (auto& bb: *funObjVar->bbGraph)
362 {
363 bb.second->setFun(funObjVar);
364 }
366 }
367
369}
370
372{
373 // Iterate over all object symbols in the symbol table
374 for (LLVMModuleSet::ValueToIDMapTy::iterator iter =
375 llvmModuleSet()->objSyms().begin(); iter != llvmModuleSet()->objSyms().end();
376 ++iter)
377 {
378 // Debug output for adding object node
379 DBOUT(DPAGBuild, outs() << "add obj node " << iter->second << "\n");
380
381 // Skip blackhole and constant symbols
382 if(iter->second == pag->blackholeSymID() || iter->second == pag->constantSymID())
383 continue;
384
385 // Get the LLVM value corresponding to the symbol
386 const Value* llvmValue = iter->first;
387
388 const ICFGNode* icfgNode = nullptr;
389 if (const Instruction* inst = SVFUtil::dyn_cast<Instruction>(llvmValue))
390 {
391 if(llvmModuleSet()->hasICFGNode(inst))
392 icfgNode = llvmModuleSet()->getICFGNode(inst);
393 }
394
395 // Check if the value is a function and add a function object node
396 if (SVFUtil::dyn_cast<Function>(llvmValue))
397 {
398 // already one
399 }
400 // Check if the value is a heap object and add a heap object node
402 {
403 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
404 pag->addHeapObjNode(iter->second, pag->getObjTypeInfo(id), icfgNode);
405 }
406 // Check if the value is an alloca instruction and add a stack object node
408 {
409 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
410 pag->addStackObjNode(iter->second, pag->getObjTypeInfo(id), icfgNode);
411 }
412 else if (auto fpValue = SVFUtil::dyn_cast<ConstantFP>(llvmValue))
413 {
414 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
416 }
417 else if (auto intValue = SVFUtil::dyn_cast<ConstantInt>(llvmValue))
418 {
419 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
421 }
422 else if (SVFUtil::isa<ConstantPointerNull>(llvmValue))
423 {
424 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
425 pag->addConstantNullPtrObjNode(iter->second, pag->getObjTypeInfo(id), icfgNode);
426 }
427 else if (SVFUtil::isa<GlobalValue>(llvmValue))
428 {
429 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
430 pag->addGlobalObjNode(iter->second, pag->getObjTypeInfo(id), icfgNode);
431 }
432 else if (SVFUtil::isa<ConstantData, ConstantExpr, MetadataAsValue, BlockAddress, ConstantAggregate>(llvmValue))
433 {
434 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
435 pag->addConstantDataObjNode(iter->second, pag->getObjTypeInfo(id), icfgNode);
436 }
437 // Add a generic object node for other types of values
438 else
439 {
440 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
441 pag->addObjNode(iter->second, pag->getObjTypeInfo(id), icfgNode);
442 }
444 }
445
446}
447
449{
450 // Iterate over all value symbols in the symbol table
451 for (LLVMModuleSet::ValueToIDMapTy::iterator iter =
452 llvmModuleSet()->valSyms().begin(); iter != llvmModuleSet()->valSyms().end();
453 ++iter)
454 {
455 // Debug output for adding value node
456 DBOUT(DPAGBuild, outs() << "add val node " << iter->second << "\n");
457
458 // Skip blackhole and null pointer symbols
459 if(iter->second == pag->blkPtrSymID() || iter->second == pag->nullPtrSymID())
460 continue;
461
462 const ICFGNode* icfgNode = nullptr;
463 auto llvmValue = iter->first;
464
465 // Check if the value is a function and get its call graph node
466 if (const Function* func = SVFUtil::dyn_cast<Function>(llvmValue))
467 {
468 pag->addFunValNode(iter->second, icfgNode, llvmModuleSet()->getFunObjVar(func), llvmModuleSet()->getSVFType(llvmValue->getType()));
469 }
470 else if (auto argval = SVFUtil::dyn_cast<Argument>(llvmValue))
471 {
472 // Formal params are defined at FunEntryICFGNode (where CallPE copies actual args).
473 // External (declaration-only) functions have no entry node, so keep nullptr.
474 const FunObjVar* funObj = llvmModuleSet()->getFunObjVar(argval->getParent());
475 const ICFGNode* entryNode = funObj->isDeclaration() ? nullptr : pag->getICFG()->getFunEntryICFGNode(funObj);
477 iter->second, argval->getArgNo(), entryNode,
478 funObj, llvmModuleSet()->getSVFType(llvmValue->getType()));
479 if (!argval->hasName())
480 pag->getGNode(iter->second)->setName("arg_" + std::to_string(argval->getArgNo()));
481 }
482 else if (auto fpValue = SVFUtil::dyn_cast<ConstantFP>(llvmValue))
483 {
484 pag->addConstantFPValNode(iter->second, LLVMUtil::getDoubleValue(fpValue), icfgNode, llvmModuleSet()->getSVFType(llvmValue->getType()));
485 }
486 else if (auto intValue = SVFUtil::dyn_cast<ConstantInt>(llvmValue))
487 {
488 pag->addConstantIntValNode(iter->second, LLVMUtil::getIntegerValue(intValue), icfgNode, llvmModuleSet()->getSVFType(llvmValue->getType()));
489 }
490 else if (SVFUtil::isa<ConstantPointerNull>(llvmValue))
491 {
492 pag->addConstantNullPtrValNode(iter->second, icfgNode, llvmModuleSet()->getSVFType(llvmValue->getType()));
493 }
494 else if (SVFUtil::isa<GlobalValue>(llvmValue))
495 {
496 // Global variables are defined at the global ICFG node.
498 llvmModuleSet()->getSVFType(llvmValue->getType()));
499 }
500 else if (SVFUtil::isa<ConstantData, ConstantExpr, MetadataAsValue, BlockAddress, ConstantAggregate>(llvmValue))
501 {
502 pag->addConstantDataValNode(iter->second, icfgNode, llvmModuleSet()->getSVFType(llvmValue->getType()));
503 }
504 else if (SVFUtil::isa<InlineAsm>(llvmValue) ||
505 SVFUtil::isa<DSOLocalEquivalent>(llvmValue) ||
506 SVFUtil::isa<NoCFIValue>(llvmValue))
507 {
508 pag->addAsmPCValNode(iter->second, llvmModuleSet()->getSVFType(llvmValue->getType()));
509 }
510 else if (const Instruction* inst = SVFUtil::dyn_cast<Instruction>(llvmValue))
511 {
513 pag->addIntrinsicValNode(iter->second, llvmModuleSet()->getSVFType(llvmValue->getType()));
514 else
515 {
516 assert(llvmModuleSet()->hasICFGNode(inst) && "LLVM instruction is not associated with an ICFGNode");
517 icfgNode = llvmModuleSet()->getICFGNode(inst);
518 pag->addValNode(iter->second, llvmModuleSet()->getSVFType(llvmValue->getType()), icfgNode);
519 }
520 }
522 pag->getGNode(iter->second));
523 }
524}
525
526
527/*
528 * Initial all the nodes from symbol table
529 */
531{
532 DBOUT(DPAGBuild, outs() << "Initialise SVFIR Nodes ...\n");
533
534
539
542
543 for (LLVMModuleSet::FunToIDMapTy::iterator iter =
544 llvmModuleSet()->retSyms().begin(); iter != llvmModuleSet()->retSyms().end();
545 ++iter)
546 {
547 const Value* llvmValue = iter->first;
548 // retSyms keys are Function*, not Instruction, so dyn_cast<Instruction> always fails.
549 // RetValPN represents the callee's return value, defined at FunExitICFGNode.
550 // External functions have no exit node, so keep nullptr.
551 const FunObjVar* funObjVar = llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(llvmValue));
552 const ICFGNode* icfgNode = funObjVar->isDeclaration() ? nullptr : pag->getICFG()->getFunExitICFGNode(funObjVar);
553 DBOUT(DPAGBuild, outs() << "add ret node " << iter->second << "\n");
554 pag->addRetNode(iter->second,
555 funObjVar,
556 llvmModuleSet()->getSVFType(iter->first->getType()), icfgNode);
558 pag->returnFunObjSymMap[funObjVar] = iter->second;
559 }
560
561 for (LLVMModuleSet::FunToIDMapTy::iterator iter =
562 llvmModuleSet()->varargSyms().begin();
563 iter != llvmModuleSet()->varargSyms().end(); ++iter)
564 {
565 const Value* llvmValue = iter->first;
566 // varargSyms keys are Function*, not Instruction.
567 // Variadic arguments are received at the function entry point.
568 // External functions have no entry node, so keep nullptr.
569 const FunObjVar* funObjVar = llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(llvmValue));
570 const ICFGNode* icfgNode = funObjVar->isDeclaration() ? nullptr : pag->getICFG()->getFunEntryICFGNode(funObjVar);
571 DBOUT(DPAGBuild, outs() << "add vararg node " << iter->second << "\n");
572 pag->addVarargNode(iter->second,
573 funObjVar,
574 llvmModuleSet()->getSVFType(iter->first->getType()), icfgNode);
576 pag->varargFunObjSymMap[funObjVar] = iter->second;
577 }
578
580 for (LLVMModuleSet::ValueToIDMapTy::iterator iter =
581 llvmModuleSet()->objSyms().begin(); iter != llvmModuleSet()->objSyms().end(); ++iter)
582 {
583 DBOUT(DPAGBuild, outs() << "add address edges for constant node " << iter->second << "\n");
584 const Value* val = iter->first;
586 {
588 if(ptr!= pag->getBlkPtr() && ptr!= pag->getNullPtr())
589 {
591 addAddrEdge(iter->second, ptr);
592 }
593 }
594 }
595
597 && "not all node have been initialized!!!");
598
600 for (auto& fun: llvmModuleSet()->getFunctionSet())
601 {
602 for (const Argument& arg : fun->args())
603 {
604 const_cast<FunObjVar*>(llvmModuleSet()->getFunObjVar(fun))->addArgument(SVFUtil::cast<ArgValVar>(
606 }
607 }
608
609}
610
611/*
612 https://github.com/SVF-tools/SVF/issues/524
613 Handling single value types, for constant index, including pointer, integer, etc
614 e.g. field_idx = getelementptr i8, %i8* %p, i64 -4
615 We can obtain the field index by inferring the byteoffset if %p is casted from a pointer to a struct
616 For another example, the following can be an array access.
617 e.g. field_idx = getelementptr i8, %struct_type %p, i64 1
618
619*/
621{
622 return 0;
623}
624
632{
633 assert(V);
634
635 const llvm::GEPOperator *gepOp = SVFUtil::dyn_cast<const llvm::GEPOperator>(V);
636 DataLayout * dataLayout = getDataLayout(llvmModuleSet()->getMainLLVMModule());
637 llvm::APInt byteOffset(dataLayout->getIndexSizeInBits(gepOp->getPointerAddressSpace()),0,true);
638 if(gepOp && dataLayout && gepOp->accumulateConstantOffset(*dataLayout,byteOffset))
639 {
640 //s32_t bo = byteOffset.getSExtValue();
641 }
642
643 bool isConst = true;
644
645 bool prevPtrOperand = false;
646 for (bridge_gep_iterator gi = bridge_gep_begin(*V), ge = bridge_gep_end(*V);
647 gi != ge; ++gi)
648 {
649 const Type* gepTy = *gi;
651
652 assert((prevPtrOperand && svfGepTy->isPointerTy()) == false &&
653 "Expect no more than one gep operand to be of a pointer type");
654 if(!prevPtrOperand && svfGepTy->isPointerTy()) prevPtrOperand = true;
655 const Value* offsetVal = gi.getOperand();
656 assert(gepTy != offsetVal->getType() && "iteration and operand have the same type?");
657
658 const ArrayType* inferredPtrArrayTy = nullptr;
659 const SVFType* idxGepTy = svfGepTy;
660 if (svfGepTy->isPointerTy() && gepOp->getSourceElementType()->isSingleValueType())
661 {
662 const Type* baseObjType =
664 if (const auto* arrTy = SVFUtil::dyn_cast<ArrayType>(baseObjType))
665 {
666 if (arrTy->getElementType()->isPointerTy())
667 {
670 }
671 }
672 }
673
675
676 //The int value of the current index operand
677 const ConstantInt* op = SVFUtil::dyn_cast<ConstantInt>(offsetVal);
678
679 // if Options::ModelConsts() is disabled. We will treat whole array as one,
680 // but we can distinguish different field of an array of struct, e.g. s[1].f1 is different from s[0].f2
681 if(const ArrayType* arrTy = SVFUtil::dyn_cast<ArrayType>(gepTy))
682 {
683 if (!Options::ModelArrays() && arrTy->getElementType()->isPointerTy())
684 continue;
685 if(!op || (arrTy->getArrayNumElements() <= (u32_t)LLVMUtil::getIntegerValue(op).first))
686 continue;
690 }
691 else if (const StructType *ST = SVFUtil::dyn_cast<StructType>(gepTy))
692 {
693 assert(op && "non-const offset accessing a struct");
694 // guard against negative or out-of-bounds struct indices
695 // (e.g. rust hashbrown bucket back-offset: gep { ... }, ptr %p, i64 -1)
696 // a negative i64 wraps to a huge uint64_t that overflows u32_t,
697 // creating an invalid field index that severs points-to tracking
699 if (rawIdx >= ST->getNumElements())
700 {
701 isConst = false;
702 continue;
703 }
707 }
708 else if (gepTy->isSingleValueType())
709 {
711 {
712 if (!op || (inferredPtrArrayTy->getArrayNumElements() <= (u32_t)LLVMUtil::getIntegerValue(op).first))
713 continue;
717 continue;
718 }
719 // If it's a non-constant offset access
720 // If its point-to target is struct or array, it's likely an array accessing (%result = gep %struct.A* %a, i32 %non-const-index)
721 // If its point-to target is single value (pointer arithmetic), then it's a variant gep (%result = gep i8* %p, i32 %non-const-index)
722 if(!op && gepTy->isPointerTy() && gepOp->getSourceElementType()->isSingleValueType())
723 {
724 isConst = false;
725 }
726
727 // The actual index
728 //s32_t idx = op->getSExtValue();
729
730 // For pointer arithmetic we ignore the byte offset
731 // consider using inferFieldIdxFromByteOffset(geopOp,dataLayout,ap,idx)?
732 // ap.setFldIdx(ap.getConstantFieldIdx() + inferFieldIdxFromByteOffset(geopOp,idx));
733 }
734 }
735 return isConst;
736}
737
742{
743 if (const Constant* ref = SVFUtil::dyn_cast<Constant>(val))
744 {
746 {
747 DBOUT(DPAGBuild, outs() << "handle gep constant expression "
748 << LLVMUtil::dumpValue(ref) << "\n");
749 const Constant* opnd = gepce->getOperand(0);
750 // handle recursive constant express case (gep (bitcast (gep X 1)) 1)
752 auto &GEPOp = llvm::cast<llvm::GEPOperator>(*gepce);
753 Type *pType = GEPOp.getSourceElementType();
754 AccessPath ap(0, llvmModuleSet()->getSVFType(pType));
755 bool constGep = computeGepOffset(gepce, ap);
756 // must invoke pag methods here, otherwise it will be a dead recursion cycle
757 const Value* cval = getCurrentValue();
758 const SVFBasicBlock* cbb = getCurrentBB();
760 /*
761 * The gep edge created are like constexpr (same edge may appear at multiple callsites)
762 * so bb/inst of this edge may be rewritten several times, we treat it as global here.
763 */
766 }
767 else if (const ConstantExpr* castce = isCastConstantExpr(ref))
768 {
769 DBOUT(DPAGBuild, outs() << "handle cast constant expression "
770 << LLVMUtil::dumpValue(ref) << "\n");
771 const Constant* opnd = castce->getOperand(0);
773 const Value* cval = getCurrentValue();
774 const SVFBasicBlock* cbb = getCurrentBB();
778 }
780 {
781 DBOUT(DPAGBuild, outs() << "handle select constant expression "
782 << LLVMUtil::dumpValue(ref) << "\n");
783 const Constant* src1 = selectce->getOperand(1);
784 const Constant* src2 = selectce->getOperand(2);
787 const Value* cval = getCurrentValue();
788 const SVFBasicBlock* cbb = getCurrentBB();
790 NodeID cond = llvmModuleSet()->getValueNode(selectce->getOperand(0));
796 }
797 // if we meet a int2ptr, then it points-to black hole
799 {
800 const Constant* opnd = int2Ptrce->getOperand(0);
802 const SVFBasicBlock* cbb = getCurrentBB();
803 const Value* cval = getCurrentValue();
807 }
809 {
810 const Constant* opnd = ptr2Intce->getOperand(0);
812 const SVFBasicBlock* cbb = getCurrentBB();
813 const Value* cval = getCurrentValue();
817 }
819 {
820 // we don't handle trunc and cmp instruction for now
821 const Value* cval = getCurrentValue();
822 const SVFBasicBlock* cbb = getCurrentBB();
827 }
828 else if (isBinaryConstantExpr(ref))
829 {
830 // we don't handle binary constant expression like add(x,y) now
831 const Value* cval = getCurrentValue();
832 const SVFBasicBlock* cbb = getCurrentBB();
837 }
838 else if (isUnaryConstantExpr(ref))
839 {
840 // we don't handle unary constant expression like fneg(x) now
841 const Value* cval = getCurrentValue();
842 const SVFBasicBlock* cbb = getCurrentBB();
847 }
848 else if (SVFUtil::isa<ConstantAggregate>(ref))
849 {
850 // we don't handle constant aggregate like constant vectors
851 }
852 else if (SVFUtil::isa<BlockAddress>(ref))
853 {
854 // blockaddress instruction (e.g. i8* blockaddress(@run_vm, %182))
855 // is treated as constant data object for now, see LLVMUtil.h:397, SymbolTableInfo.cpp:674 and SVFIRBuilder.cpp:183-194
856 const Value* cval = getCurrentValue();
857 const SVFBasicBlock* cbb = getCurrentBB();
862 }
863 else
864 {
865 if(SVFUtil::isa<ConstantExpr>(val))
866 assert(false && "we don't handle all other constant expression for now!");
867 }
868 }
869}
876{
877
878 // if the global variable do not have any field needs to be initialized
879 if (offset == 0 && gvar->getInitializer()->getType()->isSingleValueType())
880 {
881 return getValueNode(gvar);
882 }
885 else
886 {
888 }
889}
890
891/*For global variable initialization
892 * Give a simple global variable
893 * int x = 10; // store 10 x (constant, non pointer) |
894 * int *y = &x; // store x y (pointer type)
895 * Given a struct
896 * struct Z { int s; int *t;};
897 * Global initialization:
898 * struct Z z = {10,&x}; // store x z.t (struct type)
899 * struct Z *m = &z; // store z m (pointer type)
900 * struct Z n = {10,&z.s}; // store z.s n , &z.s constant expression (constant expression)
901 */
904{
905 DBOUT(DPAGBuild, outs() << "global " << LLVMUtil::dumpValue(gvar)
906 << " constant initializer: "
907 << LLVMUtil::dumpValue(C) << "\n");
908 if (C->getType()->isSingleValueType())
909 {
910 NodeID src = getValueNode(C);
911 // get the field value if it is available, otherwise we create a dummy field node.
913 NodeID field = getGlobalVarField(gvar, offset, llvmModuleSet()->getSVFType(C->getType()));
914
915 if (SVFUtil::isa<GlobalVariable, Function>(C))
916 {
918 addStoreEdge(src, field);
919 }
920 else if (SVFUtil::isa<ConstantExpr>(C))
921 {
922 // add gep edge of C1 itself is a constant expression
923 processCE(C);
925 addStoreEdge(src, field);
926 }
927 else if (SVFUtil::isa<BlockAddress>(C))
928 {
929 // blockaddress instruction (e.g. i8* blockaddress(@run_vm, %182))
930 // is treated as constant data object for now, see LLVMUtil.h:397, SymbolTableInfo.cpp:674 and SVFIRBuilder.cpp:183-194
931 processCE(C);
934 }
935 else
936 {
938 addStoreEdge(src, field);
940 if (C->getType()->isPtrOrPtrVectorTy() && src != pag->getNullPtr())
942 }
943 }
944 else if (SVFUtil::isa<ConstantArray, ConstantStruct>(C))
945 {
947 return;
948 for (u32_t i = 0, e = C->getNumOperands(); i != e; i++)
949 {
951 InitialGlobal(gvar, SVFUtil::cast<Constant>(C->getOperand(i)), offset + off);
952 }
953 }
954 else if(ConstantData* data = SVFUtil::dyn_cast<ConstantData>(C))
955 {
957 {
958 if(ConstantDataSequential* seq = SVFUtil::dyn_cast<ConstantDataSequential>(data))
959 {
960 for(u32_t i = 0; i < seq->getNumElements(); i++)
961 {
962 u32_t off = pag->getFlattenedElemIdx(llvmModuleSet()->getSVFType(C->getType()), i);
963 Constant* ct = seq->getElementAsConstant(i);
965 }
966 }
967 else
968 {
969 assert((SVFUtil::isa<ConstantAggregateZero, UndefValue>(data)) && "Single value type data should have been handled!");
970 }
971 }
972 }
973 else
974 {
975 //TODO:assert(SVFUtil::isa<ConstantVector>(C),"what else do we have");
976 }
977}
978
983{
984
987 {
988 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
989 {
990 GlobalVariable *gvar = &*I;
993
996
997 if (gvar->hasInitializer())
998 {
999 Constant *C = gvar->getInitializer();
1000 DBOUT(DPAGBuild, outs() << "add global var node "
1001 << LLVMUtil::dumpValue(gvar) << "\n");
1002 InitialGlobal(gvar, C, 0);
1003 }
1004 }
1005
1006
1008 for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
1009 {
1010 const Function* fun = &*I;
1011 NodeID idx = getValueNode(fun);
1012 NodeID obj = getObjectNode(fun);
1013
1014 DBOUT(DPAGBuild, outs() << "add global function node " << fun->getName().str() << "\n");
1015 setCurrentLocation(fun, (SVFBasicBlock*) nullptr);
1017 }
1018
1019 // 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.
1020 for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; I++)
1021 {
1022 const GlobalAlias* alias = &*I;
1023 NodeID dst = llvmModuleSet()->getValueNode(alias);
1024 NodeID src = llvmModuleSet()->getValueNode(alias->getAliasee());
1025 processCE(alias->getAliasee());
1026 setCurrentLocation(alias, (SVFBasicBlock*) nullptr);
1027 addCopyEdge(src, dst, CopyStmt::COPYVAL);
1028 }
1029 }
1030}
1031
1037{
1038
1039 // AllocaInst should always be a pointer type
1040 assert(SVFUtil::isa<PointerType>(inst.getType()));
1041
1043 outs() << "process alloca " << LLVMUtil::dumpValue(&inst) << "\n");
1044 NodeID dst = getValueNode(&inst);
1045
1046 NodeID src = getObjectNode(&inst);
1047
1048 addAddrWithStackArraySz(src, dst, inst);
1049
1050}
1051
1056{
1057
1059 outs() << "process phi " << LLVMUtil::dumpValue(&inst) << "\n");
1060
1061 NodeID dst = getValueNode(&inst);
1062
1063 for (u32_t i = 0; i < inst.getNumIncomingValues(); ++i)
1064 {
1065 const Value* val = inst.getIncomingValue(i);
1066 const Instruction* incomingInst = SVFUtil::dyn_cast<Instruction>(val);
1067 bool matched = (incomingInst == nullptr ||
1068 incomingInst->getFunction() == inst.getFunction());
1069 (void) matched; // Suppress warning of unused variable under release build
1070 assert(matched && "incomingInst's Function incorrect");
1071 const Instruction* predInst = &inst.getIncomingBlock(i)->back();
1072 const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(predInst);
1073 NodeID src = getValueNode(val);
1074 addPhiStmt(dst,src,icfgNode);
1075 }
1076}
1077
1078/*
1079 * Visit load instructions
1080 */
1082{
1084 outs() << "process load " << LLVMUtil::dumpValue(&inst) << "\n");
1085
1086 NodeID dst = getValueNode(&inst);
1087
1088 NodeID src = getValueNode(inst.getPointerOperand());
1089 const Type* loadedTy = inst.getType();
1090 if (NodeID fieldZero = getDirectAccessFieldZeroValVar(inst.getPointerOperand(), loadedTy))
1091 src = fieldZero;
1092
1093 addLoadEdge(src, dst);
1094}
1095
1100{
1101 // StoreInst itself should always not be a pointer type
1102 assert(!SVFUtil::isa<PointerType>(inst.getType()));
1103
1105 outs() << "process store " << LLVMUtil::dumpValue(&inst) << "\n");
1106
1107 NodeID dst = getValueNode(inst.getPointerOperand());
1108 const Type* storedTy = inst.getValueOperand()->getType();
1109 if (NodeID fieldZero = getDirectAccessFieldZeroValVar(inst.getPointerOperand(), storedTy))
1110 dst = fieldZero;
1111
1112 NodeID src = getValueNode(inst.getValueOperand());
1113
1114 addStoreEdge(src, dst);
1115
1116}
1117
1122{
1123
1124 NodeID dst = getValueNode(&inst);
1125 // GetElementPtrInst should always be a pointer or a vector contains pointers
1126 // for now we don't handle vector type here
1127 if(SVFUtil::isa<VectorType>(inst.getType()))
1128 {
1130 return;
1131 }
1132
1133 assert(SVFUtil::isa<PointerType>(inst.getType()));
1134
1136 outs() << "process gep " << LLVMUtil::dumpValue(&inst) << "\n");
1137
1138 NodeID src = getValueNode(inst.getPointerOperand());
1139
1140 AccessPath ap(0, llvmModuleSet()->getSVFType(inst.getSourceElementType()));
1141 bool constGep = computeGepOffset(&inst, ap);
1143 {
1144 const Type* baseObjType =
1145 LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->inferObjType(inst.getPointerOperand());
1146 if (const auto* arrTy = SVFUtil::dyn_cast<ArrayType>(baseObjType))
1147 {
1148 if (arrTy->getElementType()->isPointerTy())
1149 {
1150 addCopyEdge(src, dst, CopyStmt::COPYVAL);
1151 return;
1152 }
1153 }
1154 }
1155 addGepEdge(src, dst, ap, constGep);
1156}
1157
1158/*
1159 * Visit cast instructions
1160 */
1162{
1163
1165 outs() << "process cast " << LLVMUtil::dumpValue(&inst) << "\n");
1166 NodeID dst = getValueNode(&inst);
1167
1168 const Value* opnd = inst.getOperand(0);
1169 NodeID src = getValueNode(opnd);
1170 addCopyEdge(src, dst, getCopyKind(&inst));
1171}
1172
1177{
1178 NodeID dst = getValueNode(&inst);
1179 assert(inst.getNumOperands() == 2 && "not two operands for BinaryOperator?");
1180 Value* op1 = inst.getOperand(0);
1182 Value* op2 = inst.getOperand(1);
1184 u32_t opcode = inst.getOpcode();
1185 addBinaryOPEdge(op1Node, op2Node, dst, opcode);
1186}
1187
1192{
1193 NodeID dst = getValueNode(&inst);
1194 assert(inst.getNumOperands() == 1 && "not one operand for Unary instruction?");
1195 Value* opnd = inst.getOperand(0);
1196 NodeID src = getValueNode(opnd);
1197 u32_t opcode = inst.getOpcode();
1198 addUnaryOPEdge(src, dst, opcode);
1199}
1200
1205{
1206 NodeID dst = getValueNode(&inst);
1207 assert(inst.getNumOperands() == 2 && "not two operands for compare instruction?");
1208 Value* op1 = inst.getOperand(0);
1210 Value* op2 = inst.getOperand(1);
1212 u32_t predicate = inst.getPredicate();
1213 addCmpEdge(op1Node, op2Node, dst, predicate);
1214}
1215
1216
1221{
1222
1224 outs() << "process select " << LLVMUtil::dumpValue(&inst) << "\n");
1225
1226 NodeID dst = getValueNode(&inst);
1227 NodeID src1 = getValueNode(inst.getTrueValue());
1228 NodeID src2 = getValueNode(inst.getFalseValue());
1229 NodeID cond = getValueNode(inst.getCondition());
1231 addSelectStmt(dst,src1,src2, cond);
1232}
1233
1238
1243
1248
1249/*
1250 * Visit callsites
1251 */
1253{
1254
1255 // skip llvm intrinsics
1256 if(isIntrinsicInst(cs))
1257 return;
1258
1260 outs() << "process callsite " << LLVMUtil::dumpValue(cs) << "\n");
1261
1262 CallICFGNode* callBlockNode = llvmModuleSet()->getCallICFGNode(cs);
1264
1265 pag->addCallSite(callBlockNode);
1266
1268 for (u32_t i = 0; i < cs->arg_size(); i++)
1270 callBlockNode,
1271 pag->getValVar(getValueNode(cs->getArgOperand(i))));
1272
1273 if(!cs->getType()->isVoidTy())
1275
1276 if (callBlockNode->isVirtualCall())
1277 {
1278 const Value* value = cppUtil::getVCallVtblPtr(cs);
1279 callBlockNode->setVtablePtr(pag->getGNode(getValueNode(value)));
1280 }
1281 if (const Function *callee = LLVMUtil::getCallee(cs))
1282 {
1284 {
1285 handleExtCall(cs, callee);
1286 }
1287 else
1288 {
1290 }
1291 }
1292 else
1293 {
1294 //If the callee was not identified as a function (null F), this is indirect.
1295 handleIndCall(cs);
1296 }
1297}
1298
1303{
1304
1305 // ReturnInst itself should always not be a pointer type
1306 assert(!SVFUtil::isa<PointerType>(inst.getType()));
1307
1309 outs() << "process return " << LLVMUtil::dumpValue(&inst) << "\n");
1310
1311 if(Value* src = inst.getReturnValue())
1312 {
1313 const FunObjVar *F = llvmModuleSet()->getFunObjVar(inst.getParent()->getParent());
1314
1316 NodeID vnS = getValueNode(src);
1317 const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(&inst);
1318 //vnS may be null if src is a null ptr
1319 addPhiStmt(rnF,vnS,icfgNode);
1320 }
1321}
1322
1323
1337
1351
1357{
1358 NodeID brinst = getValueNode(&inst);
1359 NodeID cond;
1360 if (inst.isConditional())
1361 cond = getValueNode(inst.getCondition());
1362 else
1363 cond = pag->getNullPtr();
1364
1365 assert(inst.getNumSuccessors() <= 2 && "if/else has more than two branches?");
1366
1368 std::vector<const Instruction*> nextInsts;
1370 u32_t branchID = 0;
1371 for (const Instruction* succInst : nextInsts)
1372 {
1373 assert(branchID <= 1 && "if/else has more than two branches?");
1374 const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(succInst);
1375 successors.push_back(std::make_pair(icfgNode, 1-branchID));
1376 branchID++;
1377 }
1378 addBranchStmt(brinst, cond, successors);
1380 if (inst.isConditional())
1381 {
1382 for (auto& edge : llvmModuleSet()->getICFGNode(&inst)->getOutEdges())
1383 {
1384 if (IntraCFGEdge* intraEdge = SVFUtil::dyn_cast<IntraCFGEdge>(edge))
1385 {
1386 intraEdge->setConditionVar(pag->getGNode(cond));
1387 }
1388 }
1389 }
1390}
1391
1392
1436
1439{
1440 NodeID brinst = getValueNode(&inst);
1441 NodeID cond = getValueNode(inst.getCondition());
1442
1444 std::vector<const Instruction*> nextInsts;
1446 for (const Instruction* succInst : nextInsts)
1447 {
1449 const ConstantInt* condVal = inst.findCaseDest(const_cast<BasicBlock*>(succInst->getParent()));
1451 s64_t val = -1;
1452 if (condVal && condVal->getBitWidth() <= 64)
1454 const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(succInst);
1455 successors.push_back(std::make_pair(icfgNode, val));
1456 }
1457 addBranchStmt(brinst, cond, successors);
1459 for (auto& edge : llvmModuleSet()->getICFGNode(&inst)->getOutEdges())
1460 {
1461 if (IntraCFGEdge* intraEdge = SVFUtil::dyn_cast<IntraCFGEdge>(edge))
1462 {
1463 intraEdge->setConditionVar(pag->getGNode(cond));
1464 }
1465 }
1466}
1467
1468
1475{
1476 NodeID dst = getValueNode(&inst);
1477 Value* opnd = inst.getPointerOperand();
1478 NodeID src = getValueNode(opnd);
1479 addCopyEdge(src, dst, CopyStmt::COPYVAL);
1480}
1481
1487{
1488 NodeID dst = getValueNode(&inst);
1489 for (u32_t i = 0; i < inst.getNumOperands(); i++)
1490 {
1491 Value* opnd = inst.getOperand(i);
1492 NodeID src = getValueNode(opnd);
1493 addCopyEdge(src, dst, CopyStmt::COPYVAL);
1494 }
1495}
1496
1497
1502{
1503
1504 assert(F);
1507 DBOUT(DPAGBuild, outs() << "handle direct call " << LLVMUtil::dumpValue(cs)
1508 << " callee " << F->getName().str() << "\n");
1509
1510 //Only handle the ret.val. if it's used as a ptr.
1512 //Does it actually return a ptr?
1513 if (!cs->getType()->isVoidTy())
1514 {
1518 }
1519 //Iterators for the actual and formal parameters
1520 u32_t itA = 0, ieA = cs->arg_size();
1521 Function::const_arg_iterator itF = F->arg_begin(), ieF = F->arg_end();
1522 //Go through the fixed parameters.
1523 DBOUT(DPAGBuild, outs() << " args:");
1524 for (; itF != ieF; ++itA, ++itF)
1525 {
1526 //Some programs (e.g. Linux kernel) leave unneeded parameters empty.
1527 if (itA == ieA)
1528 {
1529 DBOUT(DPAGBuild, outs() << " !! not enough args\n");
1530 break;
1531 }
1532 const Value* AA = cs->getArgOperand(itA), *FA = &*itF; //current actual/formal arg
1533
1534 DBOUT(DPAGBuild, outs() << "process actual parm "
1535 << LLVMUtil::dumpValue(AA) << "\n");
1536
1541 }
1542 //Any remaining actual args must be varargs.
1543 if (F->isVarArg())
1544 {
1546 DBOUT(DPAGBuild, outs() << "\n varargs:");
1547 for (; itA != ieA; ++itA)
1548 {
1549 const Value* AA = cs->getArgOperand(itA);
1553 }
1554 }
1555 if(itA != ieA)
1556 {
1559 writeWrnMsg("too many args to non-vararg func.");
1560 writeWrnMsg("(" + callICFGNode->getSourceLoc() + ")");
1561
1562 }
1563}
1564
1597{
1598 const Value* value = stripAllCasts(V);
1599 assert(value && "null ptr?");
1601 [this](const GlobalVariable* glob, int64_t byteOffset) -> const Value*
1602 {
1603 if (!glob || !glob->hasInitializer())
1604 return nullptr;
1605
1606 auto* initializer = SVFUtil::dyn_cast<ConstantStruct>(glob->getInitializer());
1607 auto* structType = SVFUtil::dyn_cast<StructType>(glob->getValueType());
1608 if (!initializer || !structType)
1609 return nullptr;
1610
1611 DataLayout* dataLayout = getDataLayout(llvmModuleSet()->getMainLLVMModule());
1612 const StructLayout* layout =
1613 dataLayout->getStructLayout(const_cast<StructType*>(structType));
1614 for (u32_t fieldIdx = 0; fieldIdx < initializer->getNumOperands(); ++fieldIdx)
1615 {
1616 if (layout->getElementOffset(fieldIdx) != static_cast<uint64_t>(byteOffset))
1617 continue;
1618 if (auto* ptrValue =
1619 SVFUtil::dyn_cast<llvm::GlobalVariable>(initializer->getOperand(fieldIdx)))
1620 return ptrValue;
1621 return nullptr;
1622 }
1623 return nullptr;
1624 };
1625
1626 if(const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(value))
1627 {
1628 APOffset totalidx = 0;
1629 for (bridge_gep_iterator gi = bridge_gep_begin(gep), ge = bridge_gep_end(gep); gi != ge; ++gi)
1630 {
1631 if(const ConstantInt* op = SVFUtil::dyn_cast<ConstantInt>(gi.getOperand()))
1633 }
1634 if(totalidx == 0 && !SVFUtil::isa<StructType>(value->getType()))
1635 value = gep->getPointerOperand();
1636 }
1637 else if (const LoadInst* load = SVFUtil::dyn_cast<LoadInst>(value))
1638 {
1639 const Value* loadP = load->getPointerOperand();
1640 if (const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(loadP))
1641 {
1642 DataLayout* dataLayout = getDataLayout(llvmModuleSet()->getMainLLVMModule());
1643 llvm::APInt byteOffset(dataLayout->getIndexSizeInBits(gep->getPointerAddressSpace()), 0, true);
1644 const bool hasByteOffset = dataLayout && gep->accumulateConstantOffset(*dataLayout, byteOffset);
1645
1646 const Value * pointer_operand = gep->getPointerOperand();
1647 if (auto *glob = SVFUtil::dyn_cast<GlobalVariable>(pointer_operand))
1648 {
1649 if (hasByteOffset)
1650 {
1651 if (const Value* ptrValue = getGlobalFieldFromByteOffset(glob, byteOffset.getSExtValue()))
1652 return ptrValue;
1653 }
1654 }
1655 else if (hasByteOffset && !byteOffset.isNegative() &&
1656 SVFUtil::isa<AllocaInst>(pointer_operand) && load->getType()->isPointerTy())
1657 {
1658 const u64_t offset = byteOffset.getZExtValue();
1659 const u64_t accessBytes = dataLayout->getPointerSize(gep->getPointerAddressSpace());
1660
1661 auto isCoveredByMemcpy = [offset, accessBytes](const CallBase* cs) -> bool
1662 {
1663 if (cs->arg_size() < 3)
1664 return false;
1665
1666 const auto* copySize = SVFUtil::dyn_cast<ConstantInt>(cs->getArgOperand(2));
1667 if (!copySize)
1668 {
1669 return false;
1670 }
1671
1672 const u64_t copyBytes = copySize->getZExtValue();
1674 };
1675
1676 auto hasInterveningWrite = [load](const Instruction* from) -> bool
1677 {
1678 if (from->getParent() != load->getParent() || !from->comesBefore(load))
1679 return true;
1680
1681 auto it = from->getIterator();
1682 const auto end = load->getIterator();
1683 while (++it != end)
1684 {
1685 if (it->mayWriteToMemory())
1686 return true;
1687 }
1688 return false;
1689 };
1690
1691 for (const auto& use : pointer_operand->users())
1692 {
1693 const auto* cs = SVFUtil::dyn_cast<CallBase>(use);
1694 if (!cs || cs->getParent() != load->getParent() ||
1695 cs->arg_size() < 1 ||
1696 stripAllCasts(cs->getArgOperand(0)) != pointer_operand)
1697 continue;
1698
1699 const Function* calledFun = cs->getCalledFunction();
1702 continue;
1703
1704 const Value* copiedFrom = getBaseValueForExtArg(cs->getArgOperand(1));
1705 if (const auto* copiedGlob = SVFUtil::dyn_cast<GlobalVariable>(copiedFrom))
1706 {
1707 if (const Value* ptrValue =
1708 getGlobalFieldFromByteOffset(copiedGlob, byteOffset.getSExtValue()))
1709 return ptrValue;
1710 }
1711 }
1712 }
1713 }
1714 }
1715
1716 return value;
1717}
1718
1723{
1725 NodeID indFunPtrId = llvmModuleSet()->getValueNode(cs->getCalledOperand());
1726 const_cast<CallICFGNode*>(cbn)->setIndFunPtr(pag->getGNode(indFunPtrId));
1728}
1729
1731{
1732 CallGraph::CallEdgeMap::const_iterator iter = callgraph->getIndCallMap().begin();
1733 CallGraph::CallEdgeMap::const_iterator eiter = callgraph->getIndCallMap().end();
1734 for (; iter != eiter; iter++)
1735 {
1736 const CallICFGNode* callBlock = iter->first;
1737 const CallBase* callbase = SVFUtil::cast<CallBase>(llvmModuleSet()->getLLVMValue(callBlock));
1738 assert(callBlock->isIndirectCall() && "this is not an indirect call?");
1739 const CallGraph::FunctionSet& functions = iter->second;
1740 for (CallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
1741 {
1742 const Function* callee = SVFUtil::cast<Function>(llvmModuleSet()->getLLVMValue(*func_iter));
1743
1744 if (isExtCall(*func_iter))
1745 {
1746 setCurrentLocation(callee, callee->empty() ? nullptr : &callee->getEntryBlock());
1748 }
1749 else
1750 {
1751 setCurrentLocation(llvmModuleSet()->getLLVMValue(callBlock), callBlock->getBB());
1752 handleDirectCall(const_cast<CallBase*>(callbase), callee);
1753 }
1754 }
1755 }
1756
1757 // dump SVFIR
1759 pag->dump("svfir_final");
1760}
1761
1762/*
1763 * TODO: more sanity checks might be needed here
1764 */
1766{
1767 for (SVFIR::iterator nIter = pag->begin(); nIter != pag->end(); ++nIter)
1768 {
1769 (void) pag->getGNode(nIter->first);
1770 //TODO::
1771 // (1) every source(root) node of a pag tree should be object node
1772 // if a node has no incoming edge, but has outgoing edges
1773 // then it has to be an object node.
1774 // (2) make sure every variable should be initialized
1775 // otherwise it causes the a null pointer, the aliasing relation may not be captured
1776 // when loading a pointer value should make sure
1777 // some value has been store into this pointer before
1778 // q = load p, some value should stored into p first like store w p;
1779 // (3) make sure PAGNode should not have a const expr value (pointer should have unique def)
1780 // (4) look closely into addComplexConsForExt, make sure program locations(e.g.,inst bb)
1781 // are set correctly for dummy gepval node
1782 // (5) reduce unnecessary copy edge (const casts) and ensure correctness.
1783 }
1784}
1785
1786
1791NodeID SVFIRBuilder::getGepValVar(const Value* val, const AccessPath& ap, const SVFType* elementType)
1792{
1793 NodeID base = getValueNode(val);
1795 if (gepval==UINT_MAX)
1796 {
1797 assert(((int) UINT_MAX)==-1 && "maximum limit of unsigned int is not -1?");
1798 /*
1799 * getGepValVar can only be called from two places:
1800 * 1. SVFIRBuilder::addComplexConsForExt to handle external calls
1801 * 2. SVFIRBuilder::getGlobalVarField to initialize global variable
1802 * so curVal can only be
1803 * 1. Instruction
1804 * 2. GlobalVariable
1805 */
1806 assert(
1807 (SVFUtil::isa<Instruction>(curVal) || SVFUtil::isa<GlobalVariable>(curVal)) && "curVal not an instruction or a globalvariable?");
1808
1809 // We assume every GepValNode and its GepEdge to the baseNode are unique across the whole program
1810 // We preserve the current BB information to restore it after creating the gepNode
1811 const Value* cval = getCurrentValue();
1812 const SVFBasicBlock* cbb = getCurrentBB();
1815 const ICFGNode* node = nullptr;
1816 if (const Instruction* inst = SVFUtil::dyn_cast<Instruction>(curVal))
1817 {
1818 if (llvmmodule->hasICFGNode(inst))
1819 {
1820 node = llvmmodule->getICFGNode(inst);
1821 }
1822 }
1823 else if (SVFUtil::isa<GlobalVariable>(curVal))
1824 {
1825 // GEP on a global variable: the resulting GepValVar belongs to the global ICFG node.
1826 node = pag->getICFG()->getGlobalICFGNode();
1827 }
1829 NodeIDAllocator::get()->allocateValueId(),
1830 llvmmodule->getSVFType(PointerType::getUnqual(llvmmodule->getContext())), node);
1831 addGepEdge(base, gepNode, ap, true);
1833 return gepNode;
1834 }
1835 else
1836 return gepval;
1837}
1838
1840{
1841 if (!Options::ModelArrays() || SVFUtil::isa<llvm::GEPOperator>(ptr))
1842 return 0;
1843
1844 const Type* objTy =
1846 const ArrayType* arrTy = SVFUtil::dyn_cast<ArrayType>(objTy);
1847 if (!arrTy || !arrTy->getElementType()->isPointerTy() ||
1848 arrTy->getElementType() != accessTy)
1849 return 0;
1850
1851 AccessPath ap(0, llvmModuleSet()->getSVFType(arrTy));
1852 return getGepValVar(ptr, ap, llvmModuleSet()->getSVFType(accessTy));
1853}
1854
1855
1856/*
1857 * curVal <--------> PAGEdge
1858 * Instruction Any Edge
1859 * Argument CopyEdge (SVFIR::addFormalParamBlackHoleAddrEdge)
1860 * ConstantExpr CopyEdge (Int2PtrConstantExpr CastConstantExpr SVFIRBuilder::processCE)
1861 * GepEdge (GepConstantExpr SVFIRBuilder::processCE)
1862 * ConstantPointerNull CopyEdge (3-->2 NullPtr-->BlkPtr SVFIR::addNullPtrNode)
1863 * AddrEdge (0-->2 BlkObj-->BlkPtr SVFIR::addNullPtrNode)
1864 * GlobalVariable AddrEdge (SVFIRBuilder::visitGlobal)
1865 * GepEdge (SVFIRBuilder::getGlobalVarField)
1866 * Function AddrEdge (SVFIRBuilder::visitGlobal)
1867 * Constant StoreEdge (SVFIRBuilder::InitialGlobal)
1868 */
1870{
1872 return;
1873
1874 assert(curVal && "current Val is nullptr?");
1875 edge->setBB(curBB!=nullptr ? curBB : nullptr);
1877 ICFGNode* icfgNode = pag->getICFG()->getGlobalICFGNode();
1879 if (const Instruction* curInst = SVFUtil::dyn_cast<Instruction>(curVal))
1880 {
1881 const FunObjVar* srcFun = edge->getSrcNode()->getFunction();
1882 const FunObjVar* dstFun = edge->getDstNode()->getFunction();
1883 if(srcFun!=nullptr && !SVFUtil::isa<RetPE>(edge) && !SVFUtil::isa<FunValVar>(edge->getSrcNode()) && !SVFUtil::isa<FunObjVar>(edge->getSrcNode()))
1884 {
1885 assert(srcFun==llvmMS->getFunObjVar(curInst->getFunction()) && "SrcNode of the PAGEdge not in the same function?");
1886 }
1887 if(dstFun!=nullptr && !SVFUtil::isa<CallPE>(edge) && !SVFUtil::isa<RetValPN>(edge->getDstNode()))
1888 {
1889 assert(dstFun==llvmMS->getFunObjVar(curInst->getFunction()) && "DstNode of the PAGEdge not in the same function?");
1890 }
1891
1893 if (!(SVFUtil::isa<GepStmt>(edge) && SVFUtil::isa<GepValVar>(edge->getDstNode())))
1894 assert(curBB && "instruction does not have a basic block??");
1895
1897 if(SVFUtil::isa<ReturnInst>(curInst))
1898 {
1899 icfgNode = pag->getICFG()->getFunExitICFGNode(llvmMS->getFunObjVar(curInst->getFunction()));
1900 }
1901 else if(const CallPE* callPE = SVFUtil::dyn_cast<CallPE>(edge))
1902 {
1904 icfgNode = const_cast<FunEntryICFGNode*>(callPE->getFunEntryICFGNode());
1905 }
1906 else if(SVFUtil::isa<RetPE>(edge))
1907 {
1908 icfgNode = llvmMS->getRetICFGNode(SVFUtil::cast<Instruction>(curInst));
1909 }
1910 else
1911 {
1912 icfgNode = llvmMS->getICFGNode(SVFUtil::cast<Instruction>(curInst));
1913 }
1914 }
1915 else if (const Argument* arg = SVFUtil::dyn_cast<Argument>(curVal))
1916 {
1918 icfgNode = pag->getICFG()->getFunEntryICFGNode(
1919 llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(arg->getParent())));
1920 }
1921 else if (SVFUtil::isa<Constant>(curVal) ||
1922 SVFUtil::isa<Function>(curVal) ||
1923 SVFUtil::isa<MetadataAsValue>(curVal))
1924 {
1925 if (!curBB)
1927 else
1928 {
1929 icfgNode = const_cast<ICFGNode*>(curBB->front());
1930 }
1931 }
1932 else
1933 {
1934 assert(false && "what else value can we have?");
1935 }
1936
1937 pag->addToSVFStmtList(icfgNode,edge);
1938 icfgNode->addSVFStmt(edge);
1939 if(const CallPE* callPE = SVFUtil::dyn_cast<CallPE>(edge))
1940 {
1943 FunEntryICFGNode* entryNode = const_cast<FunEntryICFGNode*>(callPE->getFunEntryICFGNode());
1944 for(u32_t i = 0; i < callPE->getOpVarNum(); i++)
1945 {
1946 CallICFGNode* callNode = const_cast<CallICFGNode*>(callPE->getOpCallICFGNode(i));
1948 SVFUtil::cast<CallCFGEdge>(icfgEdge)->addCallPE(callPE);
1949 }
1950 }
1951 else if(const RetPE* retPE = SVFUtil::dyn_cast<RetPE>(edge))
1952 {
1953 RetICFGNode* retNode = const_cast<RetICFGNode*>(retPE->getCallSite()->getRetICFGNode());
1954 FunExitICFGNode* exitNode = const_cast<FunExitICFGNode*>(retPE->getFunExitICFGNode());
1956 SVFUtil::cast<RetCFGEdge>(edge)->addRetPE(retPE);
1957 }
1958}
1959
1960
1968{
1969 SVFVar* node = pag->getGNode(nodeId);
1972 if(geps.empty())
1973 return AccessPath(0);
1974
1975 assert(geps.size()==1 && "one node can only be connected by at most one gep edge!");
1976 SVFVar::iterator it = geps.begin();
1977 const GepStmt* gepEdge = SVFUtil::cast<GepStmt>(*it);
1978 if(gepEdge->isVariantFieldGep())
1979 return AccessPath(0);
1980 else
1981 return gepEdge->getAccessPath();
1982}
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define TIMEINTERVAL
Definition SVFType.h:604
#define DGENERAL
Definition SVFType.h:582
#define DPAGBuild
Definition SVFType.h:584
buffer offset
Definition cJSON.cpp:1113
cJSON * item
Definition cJSON.h:222
APOffset getConstantStructFldIdx() const
Get methods.
Definition AccessPath.h:102
void setFldIdx(APOffset idx)
Definition AccessPath.h:106
bool addOffsetVarAndGepTypePair(const ValVar *var, const SVFType *gepIterType)
std::vector< std::pair< const ICFGNode *, s32_t > > SuccAndCondPairVec
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
Definition CallGraph.h:331
Set< const FunObjVar * > FunctionSet
Definition CallGraph.h:247
bool isVirtualCall() const
Definition ICFGNode.h:510
void setVtablePtr(SVFVar *v)
Definition ICFGNode.h:515
static ExtAPI * getExtAPI()
Definition ExtAPI.cpp:44
void setExtFuncAnnotations(const FunObjVar *fun, const std::vector< std::string > &funcAnnotations)
Definition ExtAPI.cpp:242
virtual const FunObjVar * getFunction() const
Get containing function, or null for globals/constants.
const SVFBasicBlock * getEntryBlock() const
void setBasicBlockGraph(BasicBlockGraph *graph)
void initFunObjVar(bool decl, bool intrinc, bool addr, bool uncalled, bool notret, bool vararg, const SVFFunctionType *ft, SVFLoopAndDomInfo *ld, const FunObjVar *real, BasicBlockGraph *bbg, const std::vector< const ArgValVar * > &allarg, const SVFBasicBlock *exit)
BasicBlockGraph * bbGraph
the definition of a function across multiple modules
bool isDeclaration() const
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:111
FunExitICFGNode * getFunExitICFGNode(const FunObjVar *fun)
Add a function exit node.
Definition ICFG.cpp:250
ICFGEdge * hasInterICFGEdge(ICFGNode *src, ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
Definition ICFG.cpp:277
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
Definition ICFG.cpp:412
FunEntryICFGNode * getFunEntryICFGNode(const FunObjVar *fun)
Add a function entry node.
Definition ICFG.cpp:243
GlobalICFGNode * getGlobalICFGNode() const
Definition ICFG.h:244
NodeID constantSymID() const
Definition IRGraph.h:187
u32_t getFlattenedElemIdx(const SVFType *T, u32_t origId)
Flattened element idx of an array or struct by considering stride.
Definition IRGraph.cpp:148
u32_t getNodeNumAfterPAGBuild() const
Definition IRGraph.h:320
void dump(std::string name)
Dump SVFIR.
Definition IRGraph.cpp:320
NodeID getBlkPtr() const
Definition IRGraph.h:254
NodeID blkPtrSymID() const
Definition IRGraph.h:177
NodeID getNullPtr() const
Definition IRGraph.h:258
NodeID nullPtrSymID() const
Definition IRGraph.h:182
u32_t getTotalSymNum() const
Statistics.
Definition IRGraph.h:199
FunObjVarToIDMapTy varargFunObjSymMap
vararg map
Definition IRGraph.h:85
NodeID getReturnNode(const FunObjVar *func) const
GetReturnNode - Return the unique node representing the return value of a function.
Definition IRGraph.cpp:64
void setNodeNumAfterPAGBuild(u32_t num)
Definition IRGraph.h:324
NodeID blackholeSymID() const
Definition IRGraph.h:192
ObjTypeInfo * getObjTypeInfo(NodeID id) const
Definition IRGraph.h:233
NodeID getConstantNode() const
Definition IRGraph.h:250
FunObjVarToIDMapTy returnFunObjSymMap
return map
Definition IRGraph.h:84
virtual void build(ICFG *icfg)
Start from here.
NodeID getValueNode(const Value *V)
ValueToIDMapTy & valSyms()
Definition LLVMModule.h:210
FunToIDMapTy & retSyms()
Definition LLVMModule.h:277
const FunObjVar * getFunObjVar(const Function *fun) const
Definition LLVMModule.h:270
static LLVMModuleSet * getLLVMModuleSet()
Definition LLVMModule.h:133
SVFBasicBlock * getSVFBasicBlock(const BasicBlock *bb)
Definition LLVMModule.h:301
DominatorTree & getDomTree(const Function *fun)
void addToSVFVar2LLVMValueMap(const Value *val, SVFValue *svfBaseNode)
LLVMFun2FunObjVarMap LLVMFun2FunObjVar
Map an LLVM Function to an SVF Funobjvar.
Definition LLVMModule.h:101
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
ICFGNode * getICFGNode(const Instruction *inst)
Get a basic block ICFGNode.
CallICFGNode * getCallICFGNode(const Instruction *cs)
get a call node
Fun2AnnoMap ExtFun2Annotations
Record annotations of function in extapi.bc.
Definition LLVMModule.h:93
NodeID getObjectNode(const Value *V)
RetICFGNode * getRetICFGNode(const Instruction *cs)
get a return node
const std::vector< std::reference_wrapper< Module > > & getLLVMModules() const
Definition LLVMModule.h:160
const Function * getRealDefFun(const Function *fun) const
Definition LLVMModule.h:188
ValueToIDMapTy & objSyms()
Definition LLVMModule.h:215
void addBasicBlock(FunObjVar *fun, const BasicBlock *bb)
Definition LLVMModule.h:235
FunToIDMapTy & varargSyms()
Definition LLVMModule.h:282
const FunctionSet & getFunctionSet() const
Definition LLVMModule.h:195
ObjTypeInference * getTypeInference()
static NodeIDAllocator * get(void)
Return (singleton) allocator.
const Type * inferObjType(const Value *var)
get or infer the type of the object pointed by the value
static Option< bool > ModelArrays
Definition Options.h:178
static const Option< bool > PAGDotGraph
Definition Options.h:117
static const Option< std::string > DumpJson
Definition Options.h:120
static Option< bool > ModelConsts
Definition Options.h:177
static const Option< bool > PAGPrint
Definition Options.h:123
static const Option< bool > VtableInSVFIR
Definition Options.h:207
static const Option< bool > LoopAnalysis
Definition Options.h:232
static const Option< bool > DumpICFG
Definition Options.h:119
const FunObjVar * getParent() const
void addPredBasicBlock(const SVFBasicBlock *pred2)
void addSuccBasicBlock(const SVFBasicBlock *succ2)
const ICFGNode * front() const
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)
NodeID getVarargNode(const FunObjVar *func)
getVarargNode - Return the node representing the unique variadic argument of a function.
void addPhiStmt(NodeID res, NodeID opnd, const ICFGNode *pred)
Add Copy edge.
void updateCallGraph(CallGraph *callgraph)
connect PAG edges based on callgraph
void initSVFBasicBlock(const Function *func)
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.
void visitCallInst(CallInst &I)
void addLoadEdge(NodeID src, NodeID dst)
Add Load edge.
virtual void handleExtCall(const CallBase *cs, const Function *callee)
void visitGetElementPtrInst(GetElementPtrInst &I)
void visitBranchInst(BranchInst &I)
virtual void visitAllocaInst(AllocaInst &AI)
Our visit overrides.
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 getReturnNode(const FunObjVar *func)
getReturnNode - Return the node representing the unique return value of a function.
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.
const Value * curVal
Current Value during SVFIR construction when visiting the module.
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)
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 initDomTree(FunObjVar *func, const Function *f)
void addRetEdge(NodeID src, NodeID dst, const CallICFGNode *cs, const FunExitICFGNode *exit)
Add Return edge.
void addBlackHoleAddrEdge(NodeID node)
NodeID getDirectAccessFieldZeroValVar(const Value *ptr, const Type *accessTy)
void visitGlobal()
Handle globals including (global variable and functions)
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)
const Value * getCurrentValue() const
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)
void initialiseNodes()
Initialize nodes and edges.
NodeID getGlobalVarField(const GlobalVariable *gvar, u32_t offset, SVFType *tpy)
NodeID addGlobalValNode(const NodeID i, const ICFGNode *icfgNode, const SVFType *svfType)
Definition SVFIR.h:704
void addFunArgs(const FunObjVar *fun, const ValVar *arg)
Get/set method for function/callsite arguments and returns.
Definition SVFIR.h:618
NodeID getGepValVar(NodeID curInst, NodeID base, const AccessPath &ap) const
Due to constraint expression, curInst is used to distinguish different instructions (e....
Definition SVFIR.cpp:614
void print()
Print SVFIR.
Definition SVFIR.cpp:649
NodeID addBlackholePtrNode()
Definition SVFIR.h:835
NodeID addBlackholeObjNode()
Definition SVFIR.h:827
NodeID addGlobalObjNode(const NodeID i, ObjTypeInfo *ti, const ICFGNode *node)
Definition SVFIR.h:769
NodeID addGepValNode(NodeID curInst, const ValVar *base, const AccessPath &ap, NodeID i, const SVFType *type, const ICFGNode *node)
Add a temp field value node, this method can only invoked by getGepValVar.
Definition SVFIR.cpp:486
NodeID addConstantDataObjNode(const NodeID i, ObjTypeInfo *ti, const ICFGNode *node)
Definition SVFIR.h:774
NodeID addConstantFPObjNode(NodeID i, ObjTypeInfo *ti, double dval, const ICFGNode *node)
Definition SVFIR.h:748
NodeID addObjNode(NodeID i, ObjTypeInfo *ti, const ICFGNode *node)
Add a memory obj node.
Definition SVFIR.h:718
void addFunRet(const FunObjVar *fun, const ValVar *ret)
Add function returns.
Definition SVFIR.h:630
NodeID addConstantNullPtrValNode(const NodeID i, const ICFGNode *icfgNode, const SVFType *type)
Definition SVFIR.h:698
NodeID addHeapObjNode(NodeID i, ObjTypeInfo *ti, const ICFGNode *node)
Definition SVFIR.h:726
static bool pagReadFromTXT()
Definition SVFIR.h:280
CallGraph * callGraph
all the callsites of a program
Definition SVFIR.h:103
void addToSVFStmtList(ICFGNode *inst, SVFStmt *edge)
Add a SVFStmt into instruction map.
Definition SVFIR.h:328
NodeID addConstantNullPtrObjNode(const NodeID i, ObjTypeInfo *ti, const ICFGNode *node)
Definition SVFIR.h:763
NodeID addConstantDataValNode(const NodeID i, const ICFGNode *icfgNode, const SVFType *type)
Definition SVFIR.h:710
NodeID addIntrinsicValNode(NodeID i, const SVFType *type)
Definition SVFIR.h:839
void addCallSiteArgs(CallICFGNode *callBlockNode, const ValVar *arg)
Add callsite arguments.
Definition SVFIR.h:642
NodeID addStackObjNode(NodeID i, ObjTypeInfo *ti, const ICFGNode *node)
Definition SVFIR.h:735
NodeID addConstantIntValNode(NodeID i, const std::pair< s64_t, u64_t > &intValue, const ICFGNode *icfgNode, const SVFType *type)
Definition SVFIR.h:691
ICFG * getICFG() const
Definition SVFIR.h:231
NodeID addFunValNode(NodeID i, const ICFGNode *icfgNode, const FunObjVar *funObjVar, const SVFType *type)
Definition SVFIR.h:671
NodeID addConstantFPValNode(const NodeID i, double dval, const ICFGNode *icfgNode, const SVFType *type)
Definition SVFIR.h:684
void addCallSite(const CallICFGNode *call)
Add callsites.
Definition SVFIR.h:870
NodeID addValNode(NodeID i, const SVFType *type, const ICFGNode *icfgNode)
add node into SVFIR
Definition SVFIR.h:665
NodeID addVarargNode(NodeID i, const FunObjVar *val, const SVFType *type, const ICFGNode *n)
Add a unique vararg node for a procedure.
Definition SVFIR.h:787
NodeID addAsmPCValNode(NodeID i, const SVFType *type)
Definition SVFIR.h:843
void setCHG(CommonCHGraph *c)
Set/Get CHG.
Definition SVFIR.h:237
NodeID addFunObjNode(NodeID id, ObjTypeInfo *ti, const ICFGNode *node)
Definition SVFIR.h:741
ICFG * icfg
Definition SVFIR.h:100
NodeID addConstantIntObjNode(NodeID i, ObjTypeInfo *ti, const std::pair< s64_t, u64_t > &intValue, const ICFGNode *node)
Definition SVFIR.h:755
void addGlobalPAGEdge(const SVFStmt *edge)
Add global PAGEdges (not in a procedure)
Definition SVFIR.h:865
const ValVar * getValVar(NodeID id) const
Definition SVFIR.h:139
void addIndirectCallsites(const CallICFGNode *cs, NodeID funPtr)
Add indirect callsites.
Definition SVFIR.h:654
void initialiseCandidatePointers()
Initialize candidate pointers.
Definition SVFIR.cpp:734
NodeID addRetNode(NodeID i, const FunObjVar *callGraphNode, const SVFType *type, const ICFGNode *icn)
Add a unique return node for a procedure.
Definition SVFIR.h:781
NodeID addArgValNode(NodeID i, u32_t argNo, const ICFGNode *icfgNode, const FunObjVar *callGraphNode, const SVFType *type)
Definition SVFIR.h:677
void addCallSiteRets(RetICFGNode *retBlockNode, const ValVar *arg)
Add callsite returns.
Definition SVFIR.h:648
NodeID addConstantObjNode()
Definition SVFIR.h:831
const Map< const SVFBasicBlock *, BBSet > & getDomFrontierMap() const
Set< const SVFBasicBlock * > BBSet
static double getClk(bool mark=false)
Definition SVFStat.cpp:51
static double timeOfBuildingSVFIR
Definition SVFStat.h:98
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
virtual void setName(const std::string &nameInfo)
Definition SVFValue.h:174
SVFStmt::SVFStmtSetTy & getIncomingEdges(SVFStmt::PEDGEK kind)
Edge accessors and checkers.
#define NULL
Definition extapi.c:5
bool isIntrinsicInst(const Instruction *inst)
Return true if it is an intrinsic instruction.
Definition LLVMUtil.cpp:204
const ConstantExpr * isBinaryConstantExpr(const Value *val)
Definition LLVMUtil.h:296
bool isUncalledFunction(const Function *fun)
whether this is a function without any possible caller?
Definition LLVMUtil.cpp:159
double getDoubleValue(const ConstantFP *fpValue)
Definition LLVMUtil.h:57
bool isConstantObjSym(const Value *val)
Check whether this value points-to a constant object.
Definition CppUtil.cpp:747
const Value * stripAllCasts(const Value *val)
Strip off the all casts.
Definition LLVMUtil.cpp:251
const ConstantExpr * isInt2PtrConstantExpr(const Value *val)
Definition LLVMUtil.h:231
const ConstantExpr * isSelectConstantExpr(const Value *val)
Definition LLVMUtil.h:261
bool isMemcpyExtFun(const Function *fun)
Definition LLVMUtil.cpp:390
bool isIntrinsicFun(const Function *func)
Definition LLVMUtil.cpp:191
bool functionDoesNotRet(const Function *fun)
Definition LLVMUtil.cpp:124
const ConstantExpr * isTruncConstantExpr(const Value *val)
Definition LLVMUtil.h:271
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
Definition LLVMUtil.h:85
void getNextInsts(const Instruction *curInst, std::vector< const Instruction * > &instList)
Get the next instructions following control flow.
Definition LLVMUtil.cpp:579
const ConstantExpr * isPtr2IntConstantExpr(const Value *val)
Definition LLVMUtil.h:241
bool isHeapObj(const Value *val)
Definition LLVMUtil.cpp:688
const ConstantExpr * isUnaryConstantExpr(const Value *val)
Definition LLVMUtil.h:307
void getFunReachableBBs(const Function *svfFun, std::vector< const SVFBasicBlock * > &bbs)
Get reachable basic block from function entry.
Definition LLVMUtil.cpp:76
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition LLVMUtil.h:251
bool isExtCall(const Function *fun)
Definition LLVMUtil.cpp:385
bool basicBlockHasRetInst(const BasicBlock *bb)
Return true if the function has a return instruction.
Definition LLVMUtil.cpp:110
bool isStackObj(const Value *val)
Definition LLVMUtil.cpp:710
const ConstantExpr * isGepConstantExpr(const Value *val)
Return corresponding constant expression, otherwise return nullptr.
Definition LLVMUtil.h:221
static DataLayout * getDataLayout(Module *mod)
Definition LLVMUtil.h:319
const Function * getCallee(const CallBase *cs)
Definition LLVMUtil.h:100
const FunObjVar * getFunObjVar(const std::string &name)
Definition LLVMUtil.cpp:437
std::string dumpValue(const Value *val)
Definition LLVMUtil.cpp:606
const ConstantExpr * isCmpConstantExpr(const Value *val)
Definition LLVMUtil.h:285
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:105
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:72
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
const Value * getVCallVtblPtr(const CallBase *cs)
Definition CppUtil.cpp:612
bool isValVtbl(const Value *val)
Definition CppUtil.cpp:336
for isBitcode
Definition BasicTypes.h:70
llvm::DataLayout DataLayout
Definition BasicTypes.h:112
llvm::GlobalVariable GlobalVariable
Definition BasicTypes.h:137
llvm::GlobalAlias GlobalAlias
Definition BasicTypes.h:135
llvm::ArrayType ArrayType
Definition BasicTypes.h:99
llvm::Type Type
Definition BasicTypes.h:87
llvm::CallBase CallBase
Definition BasicTypes.h:153
llvm::BasicBlock BasicBlock
Definition BasicTypes.h:90
llvm::UnaryOperator UnaryOperator
Definition BasicTypes.h:187
llvm::StructType StructType
LLVM types.
Definition BasicTypes.h:98
llvm::succ_const_iterator succ_const_iterator
LLVM Iterators.
Definition BasicTypes.h:287
unsigned long long u64_t
Definition GeneralType.h:69
llvm::AllocaInst AllocaInst
Definition BasicTypes.h:157
llvm::SwitchInst SwitchInst
Definition BasicTypes.h:162
u32_t NodeID
Definition GeneralType.h:76
llvm::StructLayout StructLayout
Definition BasicTypes.h:109
llvm::InvokeInst InvokeInst
Definition BasicTypes.h:170
llvm::Argument Argument
Definition BasicTypes.h:152
llvm::LoadInst LoadInst
Definition BasicTypes.h:156
s64_t APOffset
Definition GeneralType.h:80
llvm::const_pred_iterator const_pred_iterator
Definition BasicTypes.h:265
llvm::CmpInst CmpInst
Definition BasicTypes.h:166
llvm::Function Function
Definition BasicTypes.h:89
llvm::ConstantData ConstantData
Definition BasicTypes.h:120
llvm::LoopInfo LoopInfo
Definition BasicTypes.h:148
llvm::Instruction Instruction
Definition BasicTypes.h:91
llvm::Constant Constant
Definition BasicTypes.h:128
llvm::DomTreeNode DomTreeNode
Definition BasicTypes.h:141
llvm::ConstantDataSequential ConstantDataSequential
Definition BasicTypes.h:123
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:86
llvm::ConstantExpr ConstantExpr
Definition BasicTypes.h:124
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
llvm::CastInst CastInst
Definition BasicTypes.h:165
llvm::FreezeInst FreezeInst
Definition BasicTypes.h:176
llvm::Module Module
Definition BasicTypes.h:88
llvm::BinaryOperator BinaryOperator
Definition BasicTypes.h:186
llvm::PostDominatorTree PostDominatorTree
Definition BasicTypes.h:143
llvm::DominanceFrontier DominanceFrontier
Definition BasicTypes.h:142
llvm::StoreInst StoreInst
Definition BasicTypes.h:155
llvm::SelectInst SelectInst
Definition BasicTypes.h:181
llvm::VAArgInst VAArgInst
Definition BasicTypes.h:182
llvm::Loop Loop
LLVM Loop.
Definition BasicTypes.h:147
llvm::GetElementPtrInst GetElementPtrInst
Definition BasicTypes.h:169
llvm::CallBrInst CallBrInst
Definition BasicTypes.h:163
llvm::ReturnInst ReturnInst
Definition BasicTypes.h:164
llvm::PHINode PHINode
Definition BasicTypes.h:172
llvm::BranchInst BranchInst
Definition BasicTypes.h:161
llvm::ExtractValueInst ExtractValueInst
Definition BasicTypes.h:167
unsigned u32_t
Definition GeneralType.h:67
signed long long s64_t
Definition GeneralType.h:70
llvm::CallInst CallInst
Definition BasicTypes.h:154
llvm::ConstantInt ConstantInt
Definition BasicTypes.h:129
llvm::DominatorTree DominatorTree
LLVM Dominators.
Definition BasicTypes.h:140
llvm::ExtractElementInst ExtractElementInst
Definition BasicTypes.h:168
llvm::User User
Definition BasicTypes.h:149