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
80
81
82
85 std::vector<const FunObjVar*> funset;
86 for (const auto& item: llvmModuleSet()->getFunctionSet())
87 {
89 }
90 pag->callGraph = callGraphBuilder.buildSVFIRCallGraph(funset);
91
92 CHGraph* chg = new CHGraph();
94 chgbuilder.buildCHG();
95 pag->setCHG(chg);
96
99 {
100 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
101 {
102 const Function& fun = *F;
103 const FunObjVar* svffun = llvmModuleSet()->getFunObjVar(&fun);
105 if(!fun.isDeclaration())
106 {
112 if (fun.doesNotReturn() == false &&
113 fun.getReturnType()->isVoidTy() == false)
114 {
117 }
118
121 for (Function::const_arg_iterator I = fun.arg_begin(), E = fun.arg_end();
122 I != E; ++I)
123 {
124 setCurrentLocation(&*I,&fun.getEntryBlock());
126 // if this is the function does not have caller (e.g. main)
127 // or a dead function, shall we create a black hole address edge for it?
128 // it is (1) too conservative, and (2) make FormalParmVFGNode defined at blackhole address PAGEdge.
129 // if(SVFUtil::ArgInNoCallerFunction(&*I)) {
130 // if(I->getType()->isPointerTy())
131 // addBlackHoleAddrEdge(argValNodeId);
132 //}
134 }
135 auto returns = aggregateReturnParams.find(&fun);
136 if (returns != aggregateReturnParams.end())
137 for (const auto& field : returns->second)
139 }
140 for (Function::const_iterator bit = fun.begin(), ebit = fun.end();
141 bit != ebit; ++bit)
142 {
143 const BasicBlock& bb = *bit;
144 for (BasicBlock::const_iterator it = bb.begin(), eit = bb.end();
145 it != eit; ++it)
146 {
147 const Instruction& inst = *it;
148 setCurrentLocation(&inst,&bb);
149 visit(const_cast<Instruction&>(inst));
150 }
151 }
152 }
153 }
154
155 sanityCheck();
156
158
160
161 // dump SVFIR
163 pag->dump("svfir_initial");
164
165 // print to command line of the SVFIR graph
166 if (Options::PAGPrint())
167 pag->print();
168
169 // dump ICFG
170 if (Options::DumpICFG())
171 pag->getICFG()->dump("icfg_initial");
172
174 {
177 }
178
179 // dump SVFIR as JSON
180 if (!Options::DumpJson().empty())
181 {
182 assert(false && "please implement SVFIRWriter::writeJsonToPath");
183 }
184
185 double endTime = SVFStat::getClk(true);
186 SVFStat::timeOfBuildingSVFIR = (endTime - startTime) / TIMEINTERVAL;
187
188 return pag;
189}
190
192{
194 {
196 for (const Function& f : mod.functions())
197 {
200
201 if (!LLVMUtil::isExtCall(&f))
202 {
204 }
207 svffun->setRelDefFun(realfun == nullptr ? nullptr : llvmModuleSet()->getFunObjVar(realfun));
208 }
209 }
210
211 // Store annotations of functions in extapi.bc
212 for (const auto& pair : llvmModuleSet()->ExtFun2Annotations)
213 {
215 }
216
217}
218
220{
222 for (Function::const_iterator bit = func->begin(), ebit = func->end(); bit != ebit; ++bit)
223 {
224 const BasicBlock* bb = &*bit;
227 {
230 }
232 {
235 }
236
238 if (svfbb->getSuccessors().empty())
239 {
241 {
243 SVFUtil::isa<ReturnInst>(bb->back())) &&
244 "last inst must be return inst");
245 svfFun->setExitBlock(svfbb);
246 }
247 }
248 }
249 // For no return functions, we set the last block as exit BB
250 // This ensures that each function that has definition must have an exit BB
251 if (svfFun->hasBasicBlock() && svfFun->exitBlock == nullptr)
252 {
253 SVFBasicBlock* retBB = const_cast<SVFBasicBlock*>(svfFun->back());
255 SVFUtil::isa<ReturnInst>(&func->back().back())) &&
256 "last inst must be return inst");
257 svfFun->setExitBlock(retBB);
258 }
259}
260
261
263{
264 if (fun->isDeclaration())
265 return;
266 //process and stored dt & df
269 df.analyze(dt);
271 PostDominatorTree pdt = PostDominatorTree(const_cast<Function&>(*fun));
272 SVFLoopAndDomInfo* ld = svffun->getLoopAndDomInfo();
273
275 for (DominanceFrontierBase::const_iterator dfIter = df.begin(), eDfIter = df.end(); dfIter != eDfIter; dfIter++)
276 {
277 const BasicBlock* keyBB = dfIter->first;
278#if LLVM_VERSION_MAJOR > 16
279 const llvm::SetVector<llvm::BasicBlock* >& domSet = dfIter->second;
280#else
281 const std::set<BasicBlock* >& domSet = dfIter->second;
282#endif
284 for (const BasicBlock* bbValue:domSet)
285 {
287 }
288 }
289 std::vector<const SVFBasicBlock*> reachableBBs;
290 LLVMUtil::getFunReachableBBs(fun, reachableBBs);
291 ld->setReachableBBs(reachableBBs);
292
293 for (Function::const_iterator bit = fun->begin(), beit = fun->end(); bit!=beit; ++bit)
294 {
295 const BasicBlock &bb = *bit;
297 if (DomTreeNode* dtNode = dt.getNode(&bb))
298 {
299 SVFLoopAndDomInfo::BBSet& bbSet = ld->getDomTreeMap()[svfBB];
300 for (const auto domBB : *dtNode)
301 {
302 const auto* domSVFBB = llvmModuleSet()->getSVFBasicBlock(domBB->getBlock());
303 bbSet.insert(domSVFBB);
304 }
305 }
306
307 if (DomTreeNode* pdtNode = pdt.getNode(&bb))
308 {
309 u32_t level = pdtNode->getLevel();
310 ld->getBBPDomLevel()[svfBB] = level;
311 BasicBlock* idomBB = pdtNode->getIDom()->getBlock();
313 ld->getBB2PIdom()[svfBB] = idom;
314
315 SVFLoopAndDomInfo::BBSet& bbSet = ld->getPostDomTreeMap()[svfBB];
316 for (const auto domBB : *pdtNode)
317 {
318 const auto* domSVFBB = llvmModuleSet()->getSVFBasicBlock(domBB->getBlock());
319 bbSet.insert(domSVFBB);
320 }
321 }
322
323 if (const Loop* loop = loopInfo.getLoopFor(&bb))
324 {
325 for (const BasicBlock* loopBlock : loop->getBlocks())
326 {
328 ld->addToBB2LoopMap(svfBB, loopbb);
329 }
330 }
331 }
332}
333
335{
336 std::vector<FunObjVar*> funset;
337 // Iterate over all object symbols in the symbol table
338 for (const auto* fun: llvmModuleSet()->getFunctionSet())
339 {
340 u32_t id = llvmModuleSet()->objSyms()[fun];
341 // Debug output for adding object node
342 DBOUT(DPAGBuild, outs() << "add obj node " << id << "\n");
343
344 // Check if the value is a function and add a function object node
345 pag->addFunObjNode(id, pag->getObjTypeInfo(id), nullptr);
347
348 FunObjVar *funObjVar = SVFUtil::cast<FunObjVar>(pag->getGNode(id));
349 funset.push_back(funObjVar);
350
351 funObjVar->initFunObjVar(fun->isDeclaration(), LLVMUtil::isIntrinsicFun(fun), fun->hasAddressTaken(),
353 SVFUtil::cast<SVFFunctionType>(llvmModuleSet()->getSVFType(fun->getFunctionType())),
354 new SVFLoopAndDomInfo, nullptr, nullptr,
355 {}, nullptr);
356 BasicBlockGraph* bbGraph = new BasicBlockGraph();
357 funObjVar->setBasicBlockGraph(bbGraph);
358
359
360 for (const BasicBlock& bb : *fun)
361 {
362 llvmModuleSet()->addBasicBlock(funObjVar, &bb);
363 }
364
366 for (auto& bb: *funObjVar->bbGraph)
367 {
368 bb.second->setFun(funObjVar);
369 }
371 }
372
374}
375
377{
378 // Iterate over all object symbols in the symbol table
379 for (LLVMModuleSet::ValueToIDMapTy::iterator iter =
380 llvmModuleSet()->objSyms().begin(); iter != llvmModuleSet()->objSyms().end();
381 ++iter)
382 {
383 // Debug output for adding object node
384 DBOUT(DPAGBuild, outs() << "add obj node " << iter->second << "\n");
385
386 // Skip blackhole and constant symbols
387 if(iter->second == pag->blackholeSymID() || iter->second == pag->constantSymID())
388 continue;
389
390 // Get the LLVM value corresponding to the symbol
391 const Value* llvmValue = iter->first;
392
393 const ICFGNode* icfgNode = nullptr;
394 if (const Instruction* inst = SVFUtil::dyn_cast<Instruction>(llvmValue))
395 {
396 if(llvmModuleSet()->hasICFGNode(inst))
397 icfgNode = llvmModuleSet()->getICFGNode(inst);
398 }
399
400 // Check if the value is a function and add a function object node
401 if (SVFUtil::dyn_cast<Function>(llvmValue))
402 {
403 // already one
404 }
405 // Check if the value is a heap object and add a heap object node
407 {
408 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
409 pag->addHeapObjNode(iter->second, pag->getObjTypeInfo(id), icfgNode);
410 }
411 // Check if the value is an alloca instruction and add a stack object node
413 {
414 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
415 pag->addStackObjNode(iter->second, pag->getObjTypeInfo(id), icfgNode);
416 }
417 else if (auto fpValue = SVFUtil::dyn_cast<ConstantFP>(llvmValue))
418 {
419 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
421 }
422 else if (auto intValue = SVFUtil::dyn_cast<ConstantInt>(llvmValue))
423 {
424 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
426 }
427 else if (SVFUtil::isa<ConstantPointerNull>(llvmValue))
428 {
429 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
430 pag->addConstantNullPtrObjNode(iter->second, pag->getObjTypeInfo(id), icfgNode);
431 }
432 else if (SVFUtil::isa<GlobalValue>(llvmValue))
433 {
434 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
435 pag->addGlobalObjNode(iter->second, pag->getObjTypeInfo(id), icfgNode);
436 }
437 else if (SVFUtil::isa<ConstantData, ConstantExpr, MetadataAsValue, BlockAddress, ConstantAggregate>(llvmValue))
438 {
439 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
440 pag->addConstantDataObjNode(iter->second, pag->getObjTypeInfo(id), icfgNode);
441 }
442 // Add a generic object node for other types of values
443 else
444 {
445 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
446 pag->addObjNode(iter->second, pag->getObjTypeInfo(id), icfgNode);
447 }
449 }
450
451}
452
454{
455 // Iterate over all value symbols in the symbol table
456 for (LLVMModuleSet::ValueToIDMapTy::iterator iter =
457 llvmModuleSet()->valSyms().begin(); iter != llvmModuleSet()->valSyms().end();
458 ++iter)
459 {
460 // Debug output for adding value node
461 DBOUT(DPAGBuild, outs() << "add val node " << iter->second << "\n");
462
463 // Skip blackhole and null pointer symbols
464 if(iter->second == pag->blkPtrSymID() || iter->second == pag->nullPtrSymID())
465 continue;
466
467 const ICFGNode* icfgNode = nullptr;
468 auto llvmValue = iter->first;
469
470 // Check if the value is a function and get its call graph node
471 if (const Function* func = SVFUtil::dyn_cast<Function>(llvmValue))
472 {
473 pag->addFunValNode(iter->second, icfgNode, llvmModuleSet()->getFunObjVar(func), llvmModuleSet()->getSVFType(llvmValue->getType()));
474 }
475 else if (auto argval = SVFUtil::dyn_cast<Argument>(llvmValue))
476 {
477 // Formal params are defined at FunEntryICFGNode (where CallPE copies actual args).
478 // External (declaration-only) functions have no entry node, so keep nullptr.
479 const FunObjVar* funObj = llvmModuleSet()->getFunObjVar(argval->getParent());
480 const ICFGNode* entryNode = funObj->isDeclaration() ? nullptr : pag->getICFG()->getFunEntryICFGNode(funObj);
482 iter->second, argval->getArgNo(), entryNode,
483 funObj, llvmModuleSet()->getSVFType(llvmValue->getType()));
484 if (!argval->hasName())
485 pag->getGNode(iter->second)->setName("arg_" + std::to_string(argval->getArgNo()));
486 }
487 else if (auto fpValue = SVFUtil::dyn_cast<ConstantFP>(llvmValue))
488 {
489 pag->addConstantFPValNode(iter->second, LLVMUtil::getDoubleValue(fpValue), icfgNode, llvmModuleSet()->getSVFType(llvmValue->getType()));
490 }
491 else if (auto intValue = SVFUtil::dyn_cast<ConstantInt>(llvmValue))
492 {
493 pag->addConstantIntValNode(iter->second, LLVMUtil::getIntegerValue(intValue), icfgNode, llvmModuleSet()->getSVFType(llvmValue->getType()));
494 }
495 else if (SVFUtil::isa<ConstantPointerNull>(llvmValue))
496 {
497 pag->addConstantNullPtrValNode(iter->second, icfgNode, llvmModuleSet()->getSVFType(llvmValue->getType()));
498 }
499 else if (SVFUtil::isa<GlobalValue>(llvmValue))
500 {
501 // Global variables are defined at the global ICFG node.
503 llvmModuleSet()->getSVFType(llvmValue->getType()));
504 }
505 else if (SVFUtil::isa<ConstantData, ConstantExpr, MetadataAsValue, BlockAddress, ConstantAggregate>(llvmValue))
506 {
507 pag->addConstantDataValNode(iter->second, icfgNode, llvmModuleSet()->getSVFType(llvmValue->getType()));
508 }
509 else if (SVFUtil::isa<InlineAsm>(llvmValue) ||
510 SVFUtil::isa<DSOLocalEquivalent>(llvmValue) ||
511 SVFUtil::isa<NoCFIValue>(llvmValue))
512 {
513 pag->addAsmPCValNode(iter->second, llvmModuleSet()->getSVFType(llvmValue->getType()));
514 }
515 else if (const Instruction* inst = SVFUtil::dyn_cast<Instruction>(llvmValue))
516 {
518 pag->addIntrinsicValNode(iter->second, llvmModuleSet()->getSVFType(llvmValue->getType()));
519 else
520 {
521 assert(llvmModuleSet()->hasICFGNode(inst) && "LLVM instruction is not associated with an ICFGNode");
522 icfgNode = llvmModuleSet()->getICFGNode(inst);
523 pag->addValNode(iter->second, llvmModuleSet()->getSVFType(llvmValue->getType()), icfgNode);
524 }
525 }
527 pag->getGNode(iter->second));
528 }
529}
530
531
532/*
533 * Initial all the nodes from symbol table
534 */
536{
537 DBOUT(DPAGBuild, outs() << "Initialise SVFIR Nodes ...\n");
538
539
544
547
548 for (LLVMModuleSet::FunToIDMapTy::iterator iter =
549 llvmModuleSet()->retSyms().begin(); iter != llvmModuleSet()->retSyms().end();
550 ++iter)
551 {
552 const Value* llvmValue = iter->first;
553 // retSyms keys are Function*, not Instruction, so dyn_cast<Instruction> always fails.
554 // RetValPN represents the callee's return value, defined at FunExitICFGNode.
555 // External functions have no exit node, so keep nullptr.
556 const FunObjVar* funObjVar = llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(llvmValue));
557 const ICFGNode* icfgNode = funObjVar->isDeclaration() ? nullptr : pag->getICFG()->getFunExitICFGNode(funObjVar);
558 DBOUT(DPAGBuild, outs() << "add ret node " << iter->second << "\n");
559 pag->addRetNode(iter->second,
560 funObjVar,
561 llvmModuleSet()->getSVFType(iter->first->getType()), icfgNode);
563 pag->returnFunObjSymMap[funObjVar] = iter->second;
564 }
565
566 for (LLVMModuleSet::FunToIDMapTy::iterator iter =
567 llvmModuleSet()->varargSyms().begin();
568 iter != llvmModuleSet()->varargSyms().end(); ++iter)
569 {
570 const Value* llvmValue = iter->first;
571 // varargSyms keys are Function*, not Instruction.
572 // Variadic arguments are received at the function entry point.
573 // External functions have no entry node, so keep nullptr.
574 const FunObjVar* funObjVar = llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(llvmValue));
575 const ICFGNode* icfgNode = funObjVar->isDeclaration() ? nullptr : pag->getICFG()->getFunEntryICFGNode(funObjVar);
576 DBOUT(DPAGBuild, outs() << "add vararg node " << iter->second << "\n");
577 pag->addVarargNode(iter->second,
578 funObjVar,
579 llvmModuleSet()->getSVFType(iter->first->getType()), icfgNode);
581 pag->varargFunObjSymMap[funObjVar] = iter->second;
582 }
583
585 for (LLVMModuleSet::ValueToIDMapTy::iterator iter =
586 llvmModuleSet()->objSyms().begin(); iter != llvmModuleSet()->objSyms().end(); ++iter)
587 {
588 DBOUT(DPAGBuild, outs() << "add address edges for constant node " << iter->second << "\n");
589 const Value* val = iter->first;
591 {
593 if(ptr!= pag->getBlkPtr() && ptr!= pag->getNullPtr())
594 {
596 addAddrEdge(iter->second, ptr);
597 }
598 }
599 }
600
602 && "not all node have been initialized!!!");
603
605 for (auto& fun: llvmModuleSet()->getFunctionSet())
606 {
607 for (const Argument& arg : fun->args())
608 {
609 const_cast<FunObjVar*>(llvmModuleSet()->getFunObjVar(fun))->addArgument(SVFUtil::cast<ArgValVar>(
611 }
612 }
613
614}
615
616/*
617 https://github.com/SVF-tools/SVF/issues/524
618 Handling single value types, for constant index, including pointer, integer, etc
619 e.g. field_idx = getelementptr i8, %i8* %p, i64 -4
620 We can obtain the field index by inferring the byteoffset if %p is casted from a pointer to a struct
621 For another example, the following can be an array access.
622 e.g. field_idx = getelementptr i8, %struct_type %p, i64 1
623
624*/
626{
627 return 0;
628}
629
637{
638 assert(V);
639
640 const llvm::GEPOperator *gepOp = SVFUtil::dyn_cast<const llvm::GEPOperator>(V);
641 DataLayout * dataLayout = getDataLayout(llvmModuleSet()->getMainLLVMModule());
642 llvm::APInt byteOffset(dataLayout->getIndexSizeInBits(gepOp->getPointerAddressSpace()),0,true);
643 if(gepOp && dataLayout && gepOp->accumulateConstantOffset(*dataLayout,byteOffset))
644 {
645 //s32_t bo = byteOffset.getSExtValue();
646 }
647
648 bool isConst = true;
649
650 bool prevPtrOperand = false;
651 for (bridge_gep_iterator gi = bridge_gep_begin(*V), ge = bridge_gep_end(*V);
652 gi != ge; ++gi)
653 {
654 const Type* gepTy = *gi;
656
657 assert((prevPtrOperand && svfGepTy->isPointerTy()) == false &&
658 "Expect no more than one gep operand to be of a pointer type");
659 if(!prevPtrOperand && svfGepTy->isPointerTy()) prevPtrOperand = true;
660 const Value* offsetVal = gi.getOperand();
661 assert(gepTy != offsetVal->getType() && "iteration and operand have the same type?");
662
663 const ArrayType* inferredPtrArrayTy = nullptr;
664 const SVFType* idxGepTy = svfGepTy;
665 if (svfGepTy->isPointerTy() && gepOp->getSourceElementType()->isSingleValueType())
666 {
667 const Type* baseObjType =
669 if (const auto* arrTy = SVFUtil::dyn_cast<ArrayType>(baseObjType))
670 {
671 if (arrTy->getElementType()->isPointerTy())
672 {
675 }
676 }
677 }
678
680
681 //The int value of the current index operand
682 const ConstantInt* op = SVFUtil::dyn_cast<ConstantInt>(offsetVal);
683
684 // if Options::ModelConsts() is disabled. We will treat whole array as one,
685 // but we can distinguish different field of an array of struct, e.g. s[1].f1 is different from s[0].f2
686 if(const ArrayType* arrTy = SVFUtil::dyn_cast<ArrayType>(gepTy))
687 {
688 if (!Options::ModelArrays() && arrTy->getElementType()->isPointerTy())
689 continue;
690 if(!op || (arrTy->getArrayNumElements() <= (u32_t)LLVMUtil::getIntegerValue(op).first))
691 continue;
695 }
696 else if (const StructType *ST = SVFUtil::dyn_cast<StructType>(gepTy))
697 {
698 assert(op && "non-const offset accessing a struct");
699 // guard against negative or out-of-bounds struct indices
700 // (e.g. rust hashbrown bucket back-offset: gep { ... }, ptr %p, i64 -1)
701 // a negative i64 wraps to a huge uint64_t that overflows u32_t,
702 // creating an invalid field index that severs points-to tracking
704 if (rawIdx >= ST->getNumElements())
705 {
706 isConst = false;
707 continue;
708 }
712 }
713 else if (gepTy->isSingleValueType())
714 {
716 {
717 if (!op || (inferredPtrArrayTy->getArrayNumElements() <= (u32_t)LLVMUtil::getIntegerValue(op).first))
718 continue;
722 continue;
723 }
724 // If it's a non-constant offset access
725 // If its point-to target is struct or array, it's likely an array accessing (%result = gep %struct.A* %a, i32 %non-const-index)
726 // If its point-to target is single value (pointer arithmetic), then it's a variant gep (%result = gep i8* %p, i32 %non-const-index)
727 if(!op && gepTy->isPointerTy() && gepOp->getSourceElementType()->isSingleValueType())
728 {
729 isConst = false;
730 }
731
732 // The actual index
733 //s32_t idx = op->getSExtValue();
734
735 // For pointer arithmetic we ignore the byte offset
736 // consider using inferFieldIdxFromByteOffset(geopOp,dataLayout,ap,idx)?
737 // ap.setFldIdx(ap.getConstantFieldIdx() + inferFieldIdxFromByteOffset(geopOp,idx));
738 }
739 }
740 return isConst;
741}
742
747{
748 if (const Constant* ref = SVFUtil::dyn_cast<Constant>(val))
749 {
751 {
752 DBOUT(DPAGBuild, outs() << "handle gep constant expression "
753 << LLVMUtil::dumpValue(ref) << "\n");
754 const Constant* opnd = gepce->getOperand(0);
755 // handle recursive constant express case (gep (bitcast (gep X 1)) 1)
757 auto &GEPOp = llvm::cast<llvm::GEPOperator>(*gepce);
758 Type *pType = GEPOp.getSourceElementType();
759 AccessPath ap(0, llvmModuleSet()->getSVFType(pType));
760 bool constGep = computeGepOffset(gepce, ap);
761 // must invoke pag methods here, otherwise it will be a dead recursion cycle
762 const Value* cval = getCurrentValue();
763 const SVFBasicBlock* cbb = getCurrentBB();
765 /*
766 * The gep edge created are like constexpr (same edge may appear at multiple callsites)
767 * so bb/inst of this edge may be rewritten several times, we treat it as global here.
768 */
771 }
772 else if (const ConstantExpr* castce = isCastConstantExpr(ref))
773 {
774 DBOUT(DPAGBuild, outs() << "handle cast constant expression "
775 << LLVMUtil::dumpValue(ref) << "\n");
776 const Constant* opnd = castce->getOperand(0);
778 const Value* cval = getCurrentValue();
779 const SVFBasicBlock* cbb = getCurrentBB();
783 }
785 {
786 DBOUT(DPAGBuild, outs() << "handle select constant expression "
787 << LLVMUtil::dumpValue(ref) << "\n");
788 const Constant* src1 = selectce->getOperand(1);
789 const Constant* src2 = selectce->getOperand(2);
792 const Value* cval = getCurrentValue();
793 const SVFBasicBlock* cbb = getCurrentBB();
795 NodeID cond = llvmModuleSet()->getValueNode(selectce->getOperand(0));
801 }
802 // if we meet a int2ptr, then it points-to black hole
804 {
805 const Constant* opnd = int2Ptrce->getOperand(0);
807 const SVFBasicBlock* cbb = getCurrentBB();
808 const Value* cval = getCurrentValue();
812 }
814 {
815 const Constant* opnd = ptr2Intce->getOperand(0);
817 const SVFBasicBlock* cbb = getCurrentBB();
818 const Value* cval = getCurrentValue();
822 }
824 {
825 // we don't handle trunc and cmp instruction for now
826 const Value* cval = getCurrentValue();
827 const SVFBasicBlock* cbb = getCurrentBB();
832 }
833 else if (isBinaryConstantExpr(ref))
834 {
835 // we don't handle binary constant expression like add(x,y) now
836 const Value* cval = getCurrentValue();
837 const SVFBasicBlock* cbb = getCurrentBB();
842 }
843 else if (isUnaryConstantExpr(ref))
844 {
845 // we don't handle unary constant expression like fneg(x) now
846 const Value* cval = getCurrentValue();
847 const SVFBasicBlock* cbb = getCurrentBB();
852 }
853 else if (SVFUtil::isa<ConstantAggregate>(ref))
854 {
855 // we don't handle constant aggregate like constant vectors
856 }
857 else if (SVFUtil::isa<BlockAddress>(ref))
858 {
859 // blockaddress instruction (e.g. i8* blockaddress(@run_vm, %182))
860 // is treated as constant data object for now, see LLVMUtil.h:397, SymbolTableInfo.cpp:674 and SVFIRBuilder.cpp:183-194
861 const Value* cval = getCurrentValue();
862 const SVFBasicBlock* cbb = getCurrentBB();
867 }
868 else
869 {
870 if(SVFUtil::isa<ConstantExpr>(val))
871 assert(false && "we don't handle all other constant expression for now!");
872 }
873 }
874}
881{
882
883 // if the global variable do not have any field needs to be initialized
884 if (offset == 0 && gvar->getInitializer()->getType()->isSingleValueType())
885 {
886 return getValueNode(gvar);
887 }
890 else
891 {
893 }
894}
895
896/*For global variable initialization
897 * Give a simple global variable
898 * int x = 10; // store 10 x (constant, non pointer) |
899 * int *y = &x; // store x y (pointer type)
900 * Given a struct
901 * struct Z { int s; int *t;};
902 * Global initialization:
903 * struct Z z = {10,&x}; // store x z.t (struct type)
904 * struct Z *m = &z; // store z m (pointer type)
905 * struct Z n = {10,&z.s}; // store z.s n , &z.s constant expression (constant expression)
906 */
909{
910 DBOUT(DPAGBuild, outs() << "global " << LLVMUtil::dumpValue(gvar)
911 << " constant initializer: "
912 << LLVMUtil::dumpValue(C) << "\n");
913 if (C->getType()->isSingleValueType())
914 {
915 NodeID src = getValueNode(C);
916 // get the field value if it is available, otherwise we create a dummy field node.
918 NodeID field = getGlobalVarField(gvar, offset, llvmModuleSet()->getSVFType(C->getType()));
919
920 if (SVFUtil::isa<GlobalVariable, Function>(C))
921 {
923 addStoreEdge(src, field);
924 }
925 else if (SVFUtil::isa<ConstantExpr>(C))
926 {
927 // add gep edge of C1 itself is a constant expression
928 processCE(C);
930 addStoreEdge(src, field);
931 }
932 else if (SVFUtil::isa<BlockAddress>(C))
933 {
934 // blockaddress instruction (e.g. i8* blockaddress(@run_vm, %182))
935 // is treated as constant data object for now, see LLVMUtil.h:397, SymbolTableInfo.cpp:674 and SVFIRBuilder.cpp:183-194
936 processCE(C);
939 }
940 else
941 {
943 addStoreEdge(src, field);
945 if (C->getType()->isPtrOrPtrVectorTy() && src != pag->getNullPtr())
947 }
948 }
949 else if (SVFUtil::isa<ConstantArray, ConstantStruct>(C))
950 {
952 return;
953 for (u32_t i = 0, e = C->getNumOperands(); i != e; i++)
954 {
956 InitialGlobal(gvar, SVFUtil::cast<Constant>(C->getOperand(i)), offset + off);
957 }
958 }
959 else if(ConstantData* data = SVFUtil::dyn_cast<ConstantData>(C))
960 {
962 {
963 if(ConstantDataSequential* seq = SVFUtil::dyn_cast<ConstantDataSequential>(data))
964 {
965 for(u32_t i = 0; i < seq->getNumElements(); i++)
966 {
967 u32_t off = pag->getFlattenedElemIdx(llvmModuleSet()->getSVFType(C->getType()), i);
968 Constant* ct = seq->getElementAsConstant(i);
970 }
971 }
972 else
973 {
974 assert((SVFUtil::isa<ConstantAggregateZero, UndefValue>(data)) && "Single value type data should have been handled!");
975 }
976 }
977 }
978 else
979 {
980 //TODO:assert(SVFUtil::isa<ConstantVector>(C),"what else do we have");
981 }
982}
983
988{
989
992 {
993 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
994 {
995 GlobalVariable *gvar = &*I;
998
1001
1002 if (gvar->hasInitializer())
1003 {
1004 Constant *C = gvar->getInitializer();
1005 DBOUT(DPAGBuild, outs() << "add global var node "
1006 << LLVMUtil::dumpValue(gvar) << "\n");
1007 InitialGlobal(gvar, C, 0);
1008 }
1009 }
1010
1011
1013 for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
1014 {
1015 const Function* fun = &*I;
1016 NodeID idx = getValueNode(fun);
1017 NodeID obj = getObjectNode(fun);
1018
1019 DBOUT(DPAGBuild, outs() << "add global function node " << fun->getName().str() << "\n");
1020 setCurrentLocation(fun, (SVFBasicBlock*) nullptr);
1022 }
1023
1024 // 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.
1025 for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; I++)
1026 {
1027 const GlobalAlias* alias = &*I;
1028 NodeID dst = llvmModuleSet()->getValueNode(alias);
1029 NodeID src = llvmModuleSet()->getValueNode(alias->getAliasee());
1030 processCE(alias->getAliasee());
1031 setCurrentLocation(alias, (SVFBasicBlock*) nullptr);
1032 addCopyEdge(src, dst, CopyStmt::COPYVAL);
1033 }
1034 }
1035}
1036
1042{
1043
1044 // AllocaInst should always be a pointer type
1045 assert(SVFUtil::isa<PointerType>(inst.getType()));
1046
1048 outs() << "process alloca " << LLVMUtil::dumpValue(&inst) << "\n");
1049 NodeID dst = getValueNode(&inst);
1050
1051 NodeID src = getObjectNode(&inst);
1052
1053 addAddrWithStackArraySz(src, dst, inst);
1054
1055}
1056
1061{
1062
1064 outs() << "process phi " << LLVMUtil::dumpValue(&inst) << "\n");
1065
1066 NodeID dst = getValueNode(&inst);
1067
1068 for (u32_t i = 0; i < inst.getNumIncomingValues(); ++i)
1069 {
1070 const Value* val = inst.getIncomingValue(i);
1071 const Instruction* incomingInst = SVFUtil::dyn_cast<Instruction>(val);
1072 bool matched = (incomingInst == nullptr ||
1073 incomingInst->getFunction() == inst.getFunction());
1074 (void) matched; // Suppress warning of unused variable under release build
1075 assert(matched && "incomingInst's Function incorrect");
1076 const Instruction* predInst = &inst.getIncomingBlock(i)->back();
1077 const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(predInst);
1078 NodeID src = getValueNode(val);
1079 addPhiStmt(dst,src,icfgNode);
1080 }
1081}
1082
1083/*
1084 * Visit load instructions
1085 */
1087{
1089 outs() << "process load " << LLVMUtil::dumpValue(&inst) << "\n");
1090
1091 NodeID dst = getValueNode(&inst);
1092
1093 NodeID src = getValueNode(inst.getPointerOperand());
1094 const Type* loadedTy = inst.getType();
1095 if (NodeID fieldZero = getDirectAccessFieldZeroValVar(inst.getPointerOperand(), loadedTy))
1096 src = fieldZero;
1097
1098 addLoadEdge(src, dst);
1099}
1100
1105{
1106 // StoreInst itself should always not be a pointer type
1107 assert(!SVFUtil::isa<PointerType>(inst.getType()));
1108
1110 outs() << "process store " << LLVMUtil::dumpValue(&inst) << "\n");
1111
1112 NodeID dst = getValueNode(inst.getPointerOperand());
1113 const Type* storedTy = inst.getValueOperand()->getType();
1114 if (NodeID fieldZero = getDirectAccessFieldZeroValVar(inst.getPointerOperand(), storedTy))
1115 dst = fieldZero;
1116
1117 NodeID src = getValueNode(inst.getValueOperand());
1118
1119 addStoreEdge(src, dst);
1120
1121}
1122
1127{
1128
1129 NodeID dst = getValueNode(&inst);
1130 // GetElementPtrInst should always be a pointer or a vector contains pointers
1131 // for now we don't handle vector type here
1132 if(SVFUtil::isa<VectorType>(inst.getType()))
1133 {
1135 return;
1136 }
1137
1138 assert(SVFUtil::isa<PointerType>(inst.getType()));
1139
1141 outs() << "process gep " << LLVMUtil::dumpValue(&inst) << "\n");
1142
1143 NodeID src = getValueNode(inst.getPointerOperand());
1144
1145 AccessPath ap(0, llvmModuleSet()->getSVFType(inst.getSourceElementType()));
1146 bool constGep = computeGepOffset(&inst, ap);
1148 {
1149 const Type* baseObjType =
1150 LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->inferObjType(inst.getPointerOperand());
1151 if (const auto* arrTy = SVFUtil::dyn_cast<ArrayType>(baseObjType))
1152 {
1153 if (arrTy->getElementType()->isPointerTy())
1154 {
1155 addCopyEdge(src, dst, CopyStmt::COPYVAL);
1156 return;
1157 }
1158 }
1159 }
1160 addGepEdge(src, dst, ap, constGep);
1161}
1162
1163/*
1164 * Visit cast instructions
1165 */
1167{
1168
1170 outs() << "process cast " << LLVMUtil::dumpValue(&inst) << "\n");
1171 NodeID dst = getValueNode(&inst);
1172
1173 const Value* opnd = inst.getOperand(0);
1174 NodeID src = getValueNode(opnd);
1175 addCopyEdge(src, dst, getCopyKind(&inst));
1176}
1177
1182{
1183 NodeID dst = getValueNode(&inst);
1184 assert(inst.getNumOperands() == 2 && "not two operands for BinaryOperator?");
1185 Value* op1 = inst.getOperand(0);
1187 Value* op2 = inst.getOperand(1);
1189 u32_t opcode = inst.getOpcode();
1190 addBinaryOPEdge(op1Node, op2Node, dst, opcode);
1191}
1192
1197{
1198 NodeID dst = getValueNode(&inst);
1199 assert(inst.getNumOperands() == 1 && "not one operand for Unary instruction?");
1200 Value* opnd = inst.getOperand(0);
1201 NodeID src = getValueNode(opnd);
1202 u32_t opcode = inst.getOpcode();
1203 addUnaryOPEdge(src, dst, opcode);
1204}
1205
1210{
1211 NodeID dst = getValueNode(&inst);
1212 assert(inst.getNumOperands() == 2 && "not two operands for compare instruction?");
1213 Value* op1 = inst.getOperand(0);
1215 Value* op2 = inst.getOperand(1);
1217 u32_t predicate = inst.getPredicate();
1218 addCmpEdge(op1Node, op2Node, dst, predicate);
1219}
1220
1221
1226{
1227
1229 outs() << "process select " << LLVMUtil::dumpValue(&inst) << "\n");
1230
1231 NodeID dst = getValueNode(&inst);
1232 NodeID src1 = getValueNode(inst.getTrueValue());
1233 NodeID src2 = getValueNode(inst.getFalseValue());
1234 NodeID cond = getValueNode(inst.getCondition());
1236 addSelectStmt(dst,src1,src2, cond);
1237}
1238
1243
1248
1253
1254/*
1255 * Visit callsites
1256 */
1258{
1259
1260 // skip llvm intrinsics
1261 if(isIntrinsicInst(cs))
1262 return;
1263
1265 outs() << "process callsite " << LLVMUtil::dumpValue(cs) << "\n");
1266
1267 CallICFGNode* callBlockNode = llvmModuleSet()->getCallICFGNode(cs);
1269
1270 pag->addCallSite(callBlockNode);
1271
1273 for (u32_t i = 0; i < cs->arg_size(); i++)
1275 callBlockNode,
1276 pag->getValVar(getValueNode(cs->getArgOperand(i))));
1277
1278 if(!cs->getType()->isVoidTy())
1280
1281 if (const auto* call = SVFUtil::dyn_cast<CallInst>(cs))
1283
1284 if (callBlockNode->isVirtualCall())
1285 {
1286 const Value* value = cppUtil::getVCallVtblPtr(cs);
1287 callBlockNode->setVtablePtr(pag->getGNode(getValueNode(value)));
1288 }
1289 if (const Function *callee = LLVMUtil::getCallee(cs))
1290 {
1292 {
1293 handleExtCall(cs, callee);
1294 }
1295 else
1296 {
1298 }
1299 }
1300 else
1301 {
1302 //If the callee was not identified as a function (null F), this is indirect.
1303 handleIndCall(cs);
1304 }
1305}
1306
1311{
1312
1313 // ReturnInst itself should always not be a pointer type
1314 assert(!SVFUtil::isa<PointerType>(inst.getType()));
1315
1317 outs() << "process return " << LLVMUtil::dumpValue(&inst) << "\n");
1318
1320
1321 if(Value* src = inst.getReturnValue())
1322 {
1323 const FunObjVar *F = llvmModuleSet()->getFunObjVar(inst.getParent()->getParent());
1324
1326 NodeID vnS = getValueNode(src);
1327 const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(&inst);
1328 //vnS may be null if src is a null ptr
1329 addPhiStmt(rnF,vnS,icfgNode);
1330 }
1331}
1332
1333
1336 const std::vector<unsigned>& indices)
1337{
1338 for (unsigned index : indices)
1339 {
1340 if (const auto* structure = SVFUtil::dyn_cast<StructType>(type))
1341 {
1342 if (index >= structure->getNumElements())
1343 return nullptr;
1344 type = structure->getElementType(index);
1345 }
1346 else if (const auto* array = SVFUtil::dyn_cast<ArrayType>(type))
1347 {
1348 if (index >= array->getNumElements())
1349 return nullptr;
1350 type = array->getElementType();
1351 }
1352 else if (const auto* vector = SVFUtil::dyn_cast<llvm::FixedVectorType>(type))
1353 {
1354 if (index >= vector->getNumElements())
1355 return nullptr;
1356 type = vector->getElementType();
1357 }
1358 else
1359 return nullptr;
1360 }
1361 return type;
1362}
1363
1366 std::vector<AggregateFieldKey>& operands)
1367{
1368 const Value* value = field.first;
1369 const AggregateField& path = field.second;
1370 if (path.empty())
1371 return value->getType()->isPointerTy() && !SVFUtil::isa<ConstantExpr>(value) &&
1372 !SVFUtil::isa<UndefValue>(value) && llvmModuleSet()->hasValueNode(value);
1373 if (const auto* insert = SVFUtil::dyn_cast<InsertValueInst>(value))
1374 {
1375 const auto insertedPath = insert->getIndices();
1376 const size_t commonLength = std::min(insertedPath.size(), path.size());
1377 if (!std::equal(insertedPath.begin(), insertedPath.begin() + commonLength, path.begin()))
1378 operands.emplace_back(insert->getAggregateOperand(), path);
1379 else if (insertedPath.size() <= path.size())
1380 operands.emplace_back(insert->getInsertedValueOperand(),
1381 AggregateField(path.begin() + insertedPath.size(), path.end()));
1382 else
1383 return false;
1384 }
1385 else if (const auto* extract = SVFUtil::dyn_cast<ExtractValueInst>(value))
1386 {
1387 AggregateField outer(extract->idx_begin(), extract->idx_end());
1388 outer.insert(outer.end(), path.begin(), path.end());
1389 operands.emplace_back(extract->getAggregateOperand(), std::move(outer));
1390 }
1391 else if (const auto* phi = SVFUtil::dyn_cast<PHINode>(value))
1392 {
1393 for (const Value* incoming : phi->incoming_values())
1394 operands.emplace_back(incoming, path);
1395 }
1396 else if (const auto* select = SVFUtil::dyn_cast<SelectInst>(value))
1397 {
1398 if (!select->getCondition()->getType()->isIntegerTy(1))
1399 return false;
1400 operands.emplace_back(select->getTrueValue(), path);
1401 operands.emplace_back(select->getFalseValue(), path);
1402 }
1403 else if (const auto* freeze = SVFUtil::dyn_cast<FreezeInst>(value))
1404 operands.emplace_back(freeze->getOperand(0), path);
1405 else if (const auto* insert = SVFUtil::dyn_cast<InsertElementInst>(value))
1406 {
1407 const auto* vector = SVFUtil::dyn_cast<llvm::FixedVectorType>(insert->getType());
1408 const auto* index = SVFUtil::dyn_cast<ConstantInt>(insert->getOperand(2));
1409 if (!vector || path.size() != 1 || !index ||
1410 index->getValue().uge(vector->getNumElements()))
1411 return false;
1412 if (index->getZExtValue() == path.front())
1413 operands.emplace_back(insert->getOperand(1), AggregateField{});
1414 else
1415 operands.emplace_back(insert->getOperand(0), path);
1416 }
1417 else if (const auto* shuffle = SVFUtil::dyn_cast<ShuffleVectorInst>(value))
1418 {
1419 const auto* vector = SVFUtil::dyn_cast<llvm::FixedVectorType>(shuffle->getOperand(0)->getType());
1420 if (!vector || path.size() != 1)
1421 return false;
1422 int index = shuffle->getMaskValue(path.front());
1423 if (index < 0)
1424 return false;
1425 unsigned width = vector->getNumElements();
1426 operands.emplace_back(shuffle->getOperand(static_cast<unsigned>(index) / width),
1427 AggregateField{static_cast<unsigned>(index) % width});
1428 }
1429 else if (const auto* constant = SVFUtil::dyn_cast<Constant>(value))
1430 {
1431 for (unsigned index : path)
1432 {
1433 constant = constant->getAggregateElement(index);
1434 if (!constant)
1435 return false;
1436 }
1437 operands.emplace_back(constant, AggregateField{});
1438 }
1439 else
1440 // Aggregate arguments, calls and loads need their own field interfaces.
1441 return false;
1442 return !operands.empty();
1443}
1444
1457 const AggregateField& indices, NodeID& node)
1458{
1459 const AggregateFieldKey root{aggregate, indices};
1461 std::vector<AggregateFieldKey> worklist{root};
1462 while (!worklist.empty())
1463 {
1464 AggregateFieldKey field = std::move(worklist.back());
1465 worklist.pop_back();
1466 if (aggregateFieldNodes.count(field) || definitions.count(field))
1467 continue;
1468 const Type* type = getAggregateFieldType(field.first->getType(), field.second);
1469 if (!type || !type->isPointerTy())
1470 return false;
1471 auto& operands = definitions[field];
1473 return false;
1474 worklist.insert(worklist.end(), operands.begin(), operands.end());
1475 }
1476
1477 // Validate the entire dependency graph before changing SVFIR. Allocate every
1478 // field before wiring definitions, including loop-carried Phi/Select cycles.
1479 for (const auto& definition : definitions)
1480 {
1481 const AggregateFieldKey& field = definition.first;
1482 NodeID id;
1483 if (field.second.empty())
1484 id = getValueNode(field.first);
1485 else if (SVFUtil::isa<Constant>(field.first))
1486 id = getValueNode(definition.second.front().first);
1487 else
1488 {
1489 const auto* producer = SVFUtil::cast<Instruction>(field.first);
1490 const Type* type = getAggregateFieldType(producer->getType(), field.second);
1492 pag->addValNode(id, llvmModuleSet()->getSVFType(type),
1493 llvmModuleSet()->getICFGNode(producer));
1495 }
1496 aggregateFieldNodes.emplace(field, id);
1497 }
1498
1499 const Value* savedValue = curVal;
1500 const SVFBasicBlock* savedBB = curBB;
1501 for (const auto& definition : definitions)
1502 {
1503 const AggregateFieldKey& field = definition.first;
1504 if (field.second.empty() || SVFUtil::isa<Constant>(field.first))
1505 continue;
1506 const auto* producer = SVFUtil::cast<Instruction>(field.first);
1507 const auto& operands = definition.second;
1509 setCurrentLocation(producer, producer->getParent());
1510 if (const auto* phi = SVFUtil::dyn_cast<PHINode>(producer))
1511 {
1512 for (unsigned i = 0; i < operands.size(); ++i)
1514 llvmModuleSet()->getICFGNode(phi->getIncomingBlock(i)->getTerminator()));
1515 }
1516 else if (const auto* select = SVFUtil::dyn_cast<SelectInst>(producer))
1518 aggregateFieldNodes.at(operands[1]), getValueNode(select->getCondition()));
1519 else
1521 }
1523 node = aggregateFieldNodes.at(root);
1524 return true;
1525}
1526
1529static bool canModelAggregateReturn(const Function* fun)
1530{
1531 if (!fun || LLVMUtil::isExtCall(fun) || fun->isVarArg() ||
1532 fun->doesNotReturn() || !fun->getReturnType()->isAggregateType() ||
1533 fun->hasAddressTaken())
1534 return false;
1535 for (const User* user : fun->users())
1536 {
1537 const auto* call = SVFUtil::dyn_cast<CallInst>(user);
1538 if (!call || call->getCalledFunction() != fun ||
1539 call->getFunctionType() != fun->getFunctionType())
1540 return false;
1541 }
1542 return true;
1543}
1544
1548{
1549 std::vector<AggregateFieldKey> worklist;
1551 for (const Function& fun : module)
1552 for (const BasicBlock& bb : fun)
1553 for (const Instruction& inst : bb)
1554 {
1555 if (const auto* extract = SVFUtil::dyn_cast<ExtractValueInst>(&inst))
1556 {
1557 if (extract->getType()->isPointerTy())
1558 worklist.emplace_back(extract->getAggregateOperand(),
1559 AggregateField(extract->idx_begin(), extract->idx_end()));
1560 }
1561 else if (const auto* extract = SVFUtil::dyn_cast<ExtractElementInst>(&inst))
1562 {
1563 const auto* vector = SVFUtil::dyn_cast<llvm::FixedVectorType>(extract->getVectorOperandType());
1564 const auto* index = SVFUtil::dyn_cast<ConstantInt>(extract->getIndexOperand());
1565 if (extract->getType()->isPointerTy() && vector && index &&
1566 index->getValue().ult(vector->getNumElements()))
1567 worklist.emplace_back(extract->getVectorOperand(),
1568 AggregateField{static_cast<unsigned>(index->getZExtValue())});
1569 }
1570 }
1571
1572 // Discover callee demands without materializing local field definitions.
1573 // Calls cross into return operands; other producers use the shared grammar.
1574 Set<AggregateFieldKey> visited;
1575 while (!worklist.empty())
1576 {
1577 AggregateFieldKey field = std::move(worklist.back());
1578 worklist.pop_back();
1579 if (!visited.insert(field).second || field.second.empty())
1580 continue;
1581 if (const auto* call = SVFUtil::dyn_cast<CallInst>(field.first))
1582 {
1583 const Function* callee = call->getCalledFunction();
1585 !aggregateReturnParams[callee].emplace(field.second, 0).second)
1586 continue;
1587 for (const BasicBlock& bb : *callee)
1588 if (const auto* ret = SVFUtil::dyn_cast<ReturnInst>(bb.getTerminator()))
1589 if (ret->getReturnValue())
1590 worklist.emplace_back(ret->getReturnValue(), field.second);
1591 }
1592 else
1593 {
1594 std::vector<AggregateFieldKey> operands;
1596 worklist.insert(worklist.end(), operands.begin(), operands.end());
1597 }
1598 }
1599
1601 PointerType::getUnqual(llvmModuleSet()->getContext()));
1602 const Value* savedValue = curVal;
1603 const SVFBasicBlock* savedBB = curBB;
1604 // Serialized points-to sets use NodeIDs. Allocate in function order,
1605 // independent of pointer-keyed hash table iteration.
1606 for (const Function* fun : llvmModuleSet()->getFunctionSet())
1607 {
1608 auto found = aggregateReturnParams.find(fun);
1609 if (found == aggregateReturnParams.end())
1610 continue;
1611 auto& fields = found->second;
1612 FunObjVar* svfFun = const_cast<FunObjVar*>(llvmModuleSet()->getFunObjVar(fun));
1614 for (auto& field : fields)
1615 {
1617 pag->addArgValNode(id, svfFun->arg_size(), entry, svfFun, pointerType);
1618 auto* arg = SVFUtil::cast<ArgValVar>(pag->getGNode(id));
1619 svfFun->addArgument(arg);
1620 // Like RetValPN, the synthetic parameter uses its function as a
1621 // diagnostic source; it does not add or replace an LLVM argument.
1623 arg->setName("aggregate_return_" + std::to_string(arg->getArgNo()));
1624 field.second = id;
1625 }
1626 // LLVM use-list order can change on bitcode reload. Order calls by
1627 // their ICFG IDs so each call receives the same slot IDs on readback.
1628 std::vector<const CallInst*> calls;
1629 for (const User* user : fun->users())
1630 calls.push_back(SVFUtil::cast<CallInst>(user));
1631 std::sort(calls.begin(), calls.end(), [this](const CallInst* lhs,
1632 const CallInst* rhs)
1633 {
1634 return llvmModuleSet()->getCallICFGNode(lhs)->getId() <
1635 llvmModuleSet()->getCallICFGNode(rhs)->getId();
1636 });
1637 // Include calls with unused results to keep actual/formal lists aligned.
1638 for (const CallInst* call : calls)
1639 {
1640 std::vector<const Instruction*> next;
1642 assert(next.size() == 1 && "ordinary call must have one continuation");
1644 model.continuation = next.front();
1647 setCurrentLocation(model.continuation, model.continuation->getParent());
1648 for (const auto& field : fields)
1649 {
1650 // DummyObjVar keeps the static slot nonlocal to the callee in MemSSA.
1651 // Later extracts read the SSA snapshot, not the reused slot contents.
1653 pag->getAllFieldsObjVars(object).set(object);
1654 pag->getObjTypeInfo(object)->setNumOfElements(1);
1655 pag->getObjTypeInfo(object)->setByteSizeOfObj(pointerType->getByteSize());
1658 model.fields.emplace(field.first, AggregateCallField{object, address, value});
1659 // Call fields use the same identity as local aggregate fields.
1660 aggregateFieldNodes.emplace(AggregateFieldKey{call, field.first}, value);
1661 // Snapshots must precede field statements at the continuation,
1662 // even when LLVM block order differs from dominance order.
1663 addLoadEdge(address, value);
1664 }
1665 }
1666 }
1667 setCurrentLocation(savedValue, savedBB);
1668}
1669
1673{
1674 auto found = aggregateCalls.find(call);
1675 if (found == aggregateCalls.end())
1676 return;
1677 const AggregateCall& model = found->second;
1679 const FunObjVar* callee = llvmModuleSet()->getFunObjVar(call->getCalledFunction());
1681 const auto& params = aggregateReturnParams.at(call->getCalledFunction());
1682 for (const auto& field : model.fields)
1683 {
1684 const AggregateCallField& nodes = field.second;
1685 addAddrEdge(nodes.object, nodes.address);
1687 addCallEdge(nodes.address, params.at(field.first), callNode, entry);
1688 }
1689}
1690
1694{
1695 auto found = aggregateReturnParams.find(inst.getFunction());
1696 if (found == aggregateReturnParams.end() || !inst.getReturnValue())
1697 return;
1698 // Keep each store on its own return path, before the shared function exit.
1700 for (const auto& field : found->second)
1701 {
1702 NodeID value;
1703 if (!getAggregateFieldNode(inst.getReturnValue(), field.first, value))
1704 {
1706 addBlackHoleAddrEdge(value);
1707 }
1708 addStoreEdge(value, field.second);
1709 }
1710}
1711
1726{
1727 NodeID dst = getValueNode(&inst);
1728 NodeID field;
1729 if (inst.getType()->isPointerTy() &&
1730 getAggregateFieldNode(inst.getAggregateOperand(),
1731 AggregateField(inst.idx_begin(), inst.idx_end()), field))
1733 else
1735}
1736
1750{
1751 NodeID dst = getValueNode(&inst);
1752 NodeID field;
1753 const auto* vector = SVFUtil::dyn_cast<llvm::FixedVectorType>(inst.getVectorOperandType());
1754 const auto* index = SVFUtil::dyn_cast<ConstantInt>(inst.getIndexOperand());
1755 if (inst.getType()->isPointerTy() && vector && index &&
1756 index->getValue().ult(vector->getNumElements()) &&
1757 getAggregateFieldNode(inst.getVectorOperand(),
1758 AggregateField{static_cast<unsigned>(index->getZExtValue())}, field))
1760 else
1762}
1763
1769{
1770 NodeID brinst = getValueNode(&inst);
1771 NodeID cond;
1772 if (inst.isConditional())
1773 cond = getValueNode(inst.getCondition());
1774 else
1775 cond = pag->getNullPtr();
1776
1777 assert(inst.getNumSuccessors() <= 2 && "if/else has more than two branches?");
1778
1780 std::vector<const Instruction*> nextInsts;
1782 u32_t branchID = 0;
1783 for (const Instruction* succInst : nextInsts)
1784 {
1785 assert(branchID <= 1 && "if/else has more than two branches?");
1786 const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(succInst);
1787 successors.push_back(std::make_pair(icfgNode, 1-branchID));
1788 branchID++;
1789 }
1790 addBranchStmt(brinst, cond, successors);
1792 if (inst.isConditional())
1793 {
1794 for (auto& edge : llvmModuleSet()->getICFGNode(&inst)->getOutEdges())
1795 {
1796 if (IntraCFGEdge* intraEdge = SVFUtil::dyn_cast<IntraCFGEdge>(edge))
1797 {
1798 intraEdge->setConditionVar(pag->getGNode(cond));
1799 }
1800 }
1801 }
1802}
1803
1804
1848
1851{
1852 NodeID brinst = getValueNode(&inst);
1853 NodeID cond = getValueNode(inst.getCondition());
1854
1856 std::vector<const Instruction*> nextInsts;
1858 for (const Instruction* succInst : nextInsts)
1859 {
1861 const ConstantInt* condVal = inst.findCaseDest(const_cast<BasicBlock*>(succInst->getParent()));
1863 s64_t val = -1;
1864 if (condVal && condVal->getBitWidth() <= 64)
1866 const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(succInst);
1867 successors.push_back(std::make_pair(icfgNode, val));
1868 }
1869 addBranchStmt(brinst, cond, successors);
1871 for (auto& edge : llvmModuleSet()->getICFGNode(&inst)->getOutEdges())
1872 {
1873 if (IntraCFGEdge* intraEdge = SVFUtil::dyn_cast<IntraCFGEdge>(edge))
1874 {
1875 intraEdge->setConditionVar(pag->getGNode(cond));
1876 }
1877 }
1878}
1879
1880
1887{
1888 NodeID dst = getValueNode(&inst);
1889 Value* opnd = inst.getPointerOperand();
1890 NodeID src = getValueNode(opnd);
1891 addCopyEdge(src, dst, CopyStmt::COPYVAL);
1892}
1893
1899{
1900 NodeID dst = getValueNode(&inst);
1901 for (u32_t i = 0; i < inst.getNumOperands(); i++)
1902 {
1903 Value* opnd = inst.getOperand(i);
1904 NodeID src = getValueNode(opnd);
1905 addCopyEdge(src, dst, CopyStmt::COPYVAL);
1906 }
1907}
1908
1909
1914{
1915
1916 assert(F);
1919 DBOUT(DPAGBuild, outs() << "handle direct call " << LLVMUtil::dumpValue(cs)
1920 << " callee " << F->getName().str() << "\n");
1921
1922 //Only handle the ret.val. if it's used as a ptr.
1924 //Does it actually return a ptr?
1925 if (!cs->getType()->isVoidTy())
1926 {
1930 }
1931 //Iterators for the actual and formal parameters
1932 u32_t itA = 0, ieA = cs->arg_size();
1933 Function::const_arg_iterator itF = F->arg_begin(), ieF = F->arg_end();
1934 //Go through the fixed parameters.
1935 DBOUT(DPAGBuild, outs() << " args:");
1936 for (; itF != ieF; ++itA, ++itF)
1937 {
1938 //Some programs (e.g. Linux kernel) leave unneeded parameters empty.
1939 if (itA == ieA)
1940 {
1941 DBOUT(DPAGBuild, outs() << " !! not enough args\n");
1942 break;
1943 }
1944 const Value* AA = cs->getArgOperand(itA), *FA = &*itF; //current actual/formal arg
1945
1946 DBOUT(DPAGBuild, outs() << "process actual parm "
1947 << LLVMUtil::dumpValue(AA) << "\n");
1948
1953 }
1954 //Any remaining actual args must be varargs.
1955 if (F->isVarArg())
1956 {
1958 DBOUT(DPAGBuild, outs() << "\n varargs:");
1959 for (; itA != ieA; ++itA)
1960 {
1961 const Value* AA = cs->getArgOperand(itA);
1965 }
1966 }
1967 if(itA != ieA)
1968 {
1971 writeWrnMsg("too many args to non-vararg func.");
1972 writeWrnMsg("(" + callICFGNode->getSourceLoc() + ")");
1973
1974 }
1975}
1976
2009{
2010 const Value* value = stripAllCasts(V);
2011 assert(value && "null ptr?");
2013 [this](const GlobalVariable* glob, int64_t byteOffset) -> const Value*
2014 {
2015 if (!glob || !glob->hasInitializer())
2016 return nullptr;
2017
2018 auto* initializer = SVFUtil::dyn_cast<ConstantStruct>(glob->getInitializer());
2019 auto* structType = SVFUtil::dyn_cast<StructType>(glob->getValueType());
2020 if (!initializer || !structType)
2021 return nullptr;
2022
2023 DataLayout* dataLayout = getDataLayout(llvmModuleSet()->getMainLLVMModule());
2024 const StructLayout* layout =
2025 dataLayout->getStructLayout(const_cast<StructType*>(structType));
2026 for (u32_t fieldIdx = 0; fieldIdx < initializer->getNumOperands(); ++fieldIdx)
2027 {
2028 if (layout->getElementOffset(fieldIdx) != static_cast<uint64_t>(byteOffset))
2029 continue;
2030 if (auto* ptrValue =
2031 SVFUtil::dyn_cast<llvm::GlobalVariable>(initializer->getOperand(fieldIdx)))
2032 return ptrValue;
2033 return nullptr;
2034 }
2035 return nullptr;
2036 };
2037
2038 if(const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(value))
2039 {
2040 APOffset totalidx = 0;
2041 for (bridge_gep_iterator gi = bridge_gep_begin(gep), ge = bridge_gep_end(gep); gi != ge; ++gi)
2042 {
2043 if(const ConstantInt* op = SVFUtil::dyn_cast<ConstantInt>(gi.getOperand()))
2045 }
2046 if(totalidx == 0 && !SVFUtil::isa<StructType>(value->getType()))
2047 value = gep->getPointerOperand();
2048 }
2049 else if (const LoadInst* load = SVFUtil::dyn_cast<LoadInst>(value))
2050 {
2051 const Value* loadP = load->getPointerOperand();
2052 if (const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(loadP))
2053 {
2054 DataLayout* dataLayout = getDataLayout(llvmModuleSet()->getMainLLVMModule());
2055 llvm::APInt byteOffset(dataLayout->getIndexSizeInBits(gep->getPointerAddressSpace()), 0, true);
2056 const bool hasByteOffset = dataLayout && gep->accumulateConstantOffset(*dataLayout, byteOffset);
2057
2058 const Value * pointer_operand = gep->getPointerOperand();
2059 if (auto *glob = SVFUtil::dyn_cast<GlobalVariable>(pointer_operand))
2060 {
2061 if (hasByteOffset)
2062 {
2063 if (const Value* ptrValue = getGlobalFieldFromByteOffset(glob, byteOffset.getSExtValue()))
2064 return ptrValue;
2065 }
2066 }
2067 else if (hasByteOffset && !byteOffset.isNegative() &&
2068 SVFUtil::isa<AllocaInst>(pointer_operand) && load->getType()->isPointerTy())
2069 {
2070 const u64_t offset = byteOffset.getZExtValue();
2071 const u64_t accessBytes = dataLayout->getPointerSize(gep->getPointerAddressSpace());
2072
2073 auto isCoveredByMemcpy = [offset, accessBytes](const CallBase* cs) -> bool
2074 {
2075 if (cs->arg_size() < 3)
2076 return false;
2077
2078 const auto* copySize = SVFUtil::dyn_cast<ConstantInt>(cs->getArgOperand(2));
2079 if (!copySize)
2080 {
2081 return false;
2082 }
2083
2084 const u64_t copyBytes = copySize->getZExtValue();
2086 };
2087
2088 auto hasInterveningWrite = [load](const Instruction* from) -> bool
2089 {
2090 if (from->getParent() != load->getParent() || !from->comesBefore(load))
2091 return true;
2092
2093 auto it = from->getIterator();
2094 const auto end = load->getIterator();
2095 while (++it != end)
2096 {
2097 if (it->mayWriteToMemory())
2098 return true;
2099 }
2100 return false;
2101 };
2102
2103 for (const auto& use : pointer_operand->users())
2104 {
2105 const auto* cs = SVFUtil::dyn_cast<CallBase>(use);
2106 if (!cs || cs->getParent() != load->getParent() ||
2107 cs->arg_size() < 1 ||
2108 stripAllCasts(cs->getArgOperand(0)) != pointer_operand)
2109 continue;
2110
2111 const Function* calledFun = cs->getCalledFunction();
2114 continue;
2115
2116 const Value* copiedFrom = getBaseValueForExtArg(cs->getArgOperand(1));
2117 if (const auto* copiedGlob = SVFUtil::dyn_cast<GlobalVariable>(copiedFrom))
2118 {
2119 if (const Value* ptrValue =
2120 getGlobalFieldFromByteOffset(copiedGlob, byteOffset.getSExtValue()))
2121 return ptrValue;
2122 }
2123 }
2124 }
2125 }
2126 }
2127
2128 return value;
2129}
2130
2135{
2137 NodeID indFunPtrId = llvmModuleSet()->getValueNode(cs->getCalledOperand());
2138 const_cast<CallICFGNode*>(cbn)->setIndFunPtr(pag->getGNode(indFunPtrId));
2140}
2141
2143{
2144 CallGraph::CallEdgeMap::const_iterator iter = callgraph->getIndCallMap().begin();
2145 CallGraph::CallEdgeMap::const_iterator eiter = callgraph->getIndCallMap().end();
2146 for (; iter != eiter; iter++)
2147 {
2148 const CallICFGNode* callBlock = iter->first;
2149 const CallBase* callbase = SVFUtil::cast<CallBase>(llvmModuleSet()->getLLVMValue(callBlock));
2150 assert(callBlock->isIndirectCall() && "this is not an indirect call?");
2151 const CallGraph::FunctionSet& functions = iter->second;
2152 for (CallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
2153 {
2154 const Function* callee = SVFUtil::cast<Function>(llvmModuleSet()->getLLVMValue(*func_iter));
2155
2156 if (isExtCall(*func_iter))
2157 {
2158 setCurrentLocation(callee, callee->empty() ? nullptr : &callee->getEntryBlock());
2160 }
2161 else
2162 {
2163 setCurrentLocation(llvmModuleSet()->getLLVMValue(callBlock), callBlock->getBB());
2164 handleDirectCall(const_cast<CallBase*>(callbase), callee);
2165 }
2166 }
2167 }
2168
2169 // dump SVFIR
2171 pag->dump("svfir_final");
2172}
2173
2174/*
2175 * TODO: more sanity checks might be needed here
2176 */
2178{
2179 for (SVFIR::iterator nIter = pag->begin(); nIter != pag->end(); ++nIter)
2180 {
2181 (void) pag->getGNode(nIter->first);
2182 //TODO::
2183 // (1) every source(root) node of a pag tree should be object node
2184 // if a node has no incoming edge, but has outgoing edges
2185 // then it has to be an object node.
2186 // (2) make sure every variable should be initialized
2187 // otherwise it causes the a null pointer, the aliasing relation may not be captured
2188 // when loading a pointer value should make sure
2189 // some value has been store into this pointer before
2190 // q = load p, some value should stored into p first like store w p;
2191 // (3) make sure PAGNode should not have a const expr value (pointer should have unique def)
2192 // (4) look closely into addComplexConsForExt, make sure program locations(e.g.,inst bb)
2193 // are set correctly for dummy gepval node
2194 // (5) reduce unnecessary copy edge (const casts) and ensure correctness.
2195 }
2196}
2197
2198
2203NodeID SVFIRBuilder::getGepValVar(const Value* val, const AccessPath& ap, const SVFType* elementType)
2204{
2205 NodeID base = getValueNode(val);
2207 if (gepval==UINT_MAX)
2208 {
2209 assert(((int) UINT_MAX)==-1 && "maximum limit of unsigned int is not -1?");
2210 /*
2211 * getGepValVar can only be called from two places:
2212 * 1. SVFIRBuilder::addComplexConsForExt to handle external calls
2213 * 2. SVFIRBuilder::getGlobalVarField to initialize global variable
2214 * so curVal can only be
2215 * 1. Instruction
2216 * 2. GlobalVariable
2217 */
2218 assert(
2219 (SVFUtil::isa<Instruction>(curVal) || SVFUtil::isa<GlobalVariable>(curVal)) && "curVal not an instruction or a globalvariable?");
2220
2221 // We assume every GepValNode and its GepEdge to the baseNode are unique across the whole program
2222 // We preserve the current BB information to restore it after creating the gepNode
2223 const Value* cval = getCurrentValue();
2224 const SVFBasicBlock* cbb = getCurrentBB();
2227 const ICFGNode* node = nullptr;
2228 if (const Instruction* inst = SVFUtil::dyn_cast<Instruction>(curVal))
2229 {
2230 if (llvmmodule->hasICFGNode(inst))
2231 {
2232 node = llvmmodule->getICFGNode(inst);
2233 }
2234 }
2235 else if (SVFUtil::isa<GlobalVariable>(curVal))
2236 {
2237 // GEP on a global variable: the resulting GepValVar belongs to the global ICFG node.
2238 node = pag->getICFG()->getGlobalICFGNode();
2239 }
2241 NodeIDAllocator::get()->allocateValueId(),
2242 llvmmodule->getSVFType(PointerType::getUnqual(llvmmodule->getContext())), node);
2243 addGepEdge(base, gepNode, ap, true);
2245 return gepNode;
2246 }
2247 else
2248 return gepval;
2249}
2250
2252{
2253 if (!Options::ModelArrays() || SVFUtil::isa<llvm::GEPOperator>(ptr))
2254 return 0;
2255
2256 const Type* objTy =
2258 const ArrayType* arrTy = SVFUtil::dyn_cast<ArrayType>(objTy);
2259 if (!arrTy || !arrTy->getElementType()->isPointerTy() ||
2260 arrTy->getElementType() != accessTy)
2261 return 0;
2262
2263 AccessPath ap(0, llvmModuleSet()->getSVFType(arrTy));
2264 return getGepValVar(ptr, ap, llvmModuleSet()->getSVFType(accessTy));
2265}
2266
2267
2268/*
2269 * curVal <--------> PAGEdge
2270 * Instruction Any Edge
2271 * Argument CopyEdge (SVFIR::addFormalParamBlackHoleAddrEdge)
2272 * ConstantExpr CopyEdge (Int2PtrConstantExpr CastConstantExpr SVFIRBuilder::processCE)
2273 * GepEdge (GepConstantExpr SVFIRBuilder::processCE)
2274 * ConstantPointerNull CopyEdge (3-->2 NullPtr-->BlkPtr SVFIR::addNullPtrNode)
2275 * AddrEdge (0-->2 BlkObj-->BlkPtr SVFIR::addNullPtrNode)
2276 * GlobalVariable AddrEdge (SVFIRBuilder::visitGlobal)
2277 * GepEdge (SVFIRBuilder::getGlobalVarField)
2278 * Function AddrEdge (SVFIRBuilder::visitGlobal)
2279 * Constant StoreEdge (SVFIRBuilder::InitialGlobal)
2280 */
2282{
2284 return;
2285
2286 assert(curVal && "current Val is nullptr?");
2287 edge->setBB(curBB!=nullptr ? curBB : nullptr);
2289 ICFGNode* icfgNode = pag->getICFG()->getGlobalICFGNode();
2291 if (const Instruction* curInst = SVFUtil::dyn_cast<Instruction>(curVal))
2292 {
2293 const FunObjVar* srcFun = edge->getSrcNode()->getFunction();
2294 const FunObjVar* dstFun = edge->getDstNode()->getFunction();
2295 if(srcFun!=nullptr && !SVFUtil::isa<RetPE>(edge) && !SVFUtil::isa<FunValVar>(edge->getSrcNode()) && !SVFUtil::isa<FunObjVar>(edge->getSrcNode()))
2296 {
2297 assert(srcFun==llvmMS->getFunObjVar(curInst->getFunction()) && "SrcNode of the PAGEdge not in the same function?");
2298 }
2299 if(dstFun!=nullptr && !SVFUtil::isa<CallPE>(edge) && !SVFUtil::isa<RetValPN>(edge->getDstNode()))
2300 {
2301 assert(dstFun==llvmMS->getFunObjVar(curInst->getFunction()) && "DstNode of the PAGEdge not in the same function?");
2302 }
2303
2305 if (!(SVFUtil::isa<GepStmt>(edge) && SVFUtil::isa<GepValVar>(edge->getDstNode())))
2306 assert(curBB && "instruction does not have a basic block??");
2307
2311 if(SVFUtil::isa<ReturnInst>(curInst) && SVFUtil::isa<PhiStmt>(edge))
2312 {
2313 icfgNode = pag->getICFG()->getFunExitICFGNode(llvmMS->getFunObjVar(curInst->getFunction()));
2314 }
2315 else if(const CallPE* callPE = SVFUtil::dyn_cast<CallPE>(edge))
2316 {
2318 icfgNode = const_cast<FunEntryICFGNode*>(callPE->getFunEntryICFGNode());
2319 }
2320 else if(SVFUtil::isa<RetPE>(edge))
2321 {
2322 icfgNode = llvmMS->getRetICFGNode(SVFUtil::cast<Instruction>(curInst));
2323 }
2324 else
2325 {
2326 icfgNode = llvmMS->getICFGNode(SVFUtil::cast<Instruction>(curInst));
2327 }
2328 }
2329 else if (const Argument* arg = SVFUtil::dyn_cast<Argument>(curVal))
2330 {
2332 icfgNode = pag->getICFG()->getFunEntryICFGNode(
2333 llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(arg->getParent())));
2334 }
2335 else if (SVFUtil::isa<Constant>(curVal) ||
2336 SVFUtil::isa<Function>(curVal) ||
2337 SVFUtil::isa<MetadataAsValue>(curVal))
2338 {
2339 if (!curBB)
2341 else
2342 {
2343 icfgNode = const_cast<ICFGNode*>(curBB->front());
2344 }
2345 }
2346 else
2347 {
2348 assert(false && "what else value can we have?");
2349 }
2350
2351 pag->addToSVFStmtList(icfgNode,edge);
2352 icfgNode->addSVFStmt(edge);
2353 if(const CallPE* callPE = SVFUtil::dyn_cast<CallPE>(edge))
2354 {
2357 FunEntryICFGNode* entryNode = const_cast<FunEntryICFGNode*>(callPE->getFunEntryICFGNode());
2358 for(u32_t i = 0; i < callPE->getOpVarNum(); i++)
2359 {
2360 CallICFGNode* callNode = const_cast<CallICFGNode*>(callPE->getOpCallICFGNode(i));
2362 SVFUtil::cast<CallCFGEdge>(icfgEdge)->addCallPE(callPE);
2363 }
2364 }
2365 else if(const RetPE* retPE = SVFUtil::dyn_cast<RetPE>(edge))
2366 {
2367 RetICFGNode* retNode = const_cast<RetICFGNode*>(retPE->getCallSite()->getRetICFGNode());
2368 FunExitICFGNode* exitNode = const_cast<FunExitICFGNode*>(retPE->getFunExitICFGNode());
2370 SVFUtil::cast<RetCFGEdge>(edge)->addRetPE(retPE);
2371 }
2372}
2373
2374
2382{
2383 SVFVar* node = pag->getGNode(nodeId);
2386 if(geps.empty())
2387 return AccessPath(0);
2388
2389 assert(geps.size()==1 && "one node can only be connected by at most one gep edge!");
2390 SVFVar::iterator it = geps.begin();
2391 const GepStmt* gepEdge = SVFUtil::cast<GepStmt>(*it);
2392 if(gepEdge->isVariantFieldGep())
2393 return AccessPath(0);
2394 else
2395 return gepEdge->getAccessPath();
2396}
static const Type * getAggregateFieldType(const Type *type, const std::vector< unsigned > &indices)
Return the type at a constant aggregate path, including fixed vector lanes.
static bool canModelAggregateReturn(const Function *fun)
#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
item next
Definition cJSON.cpp:2224
newitem type
Definition cJSON.cpp:2739
buffer offset
Definition cJSON.cpp:1113
int index
Definition cJSON.h:170
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:43
void setExtFuncAnnotations(const FunObjVar *fun, const std::vector< std::string > &funcAnnotations)
Definition ExtAPI.cpp:199
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:192
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:325
void dump(std::string name)
Dump SVFIR.
Definition IRGraph.cpp:333
NodeID getBlkPtr() const
Definition IRGraph.h:259
NodeID blkPtrSymID() const
Definition IRGraph.h:182
NodeID getNullPtr() const
Definition IRGraph.h:263
NodeID nullPtrSymID() const
Definition IRGraph.h:187
u32_t getTotalSymNum() const
Statistics.
Definition IRGraph.h:204
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:329
NodeID blackholeSymID() const
Definition IRGraph.h:197
ObjTypeInfo * getObjTypeInfo(NodeID id) const
Definition IRGraph.h:238
NodeID getConstantNode() const
Definition IRGraph.h:255
FunObjVarToIDMapTy returnFunObjSymMap
return map
Definition IRGraph.h:84
virtual void build(ICFG *icfg)
Start from here.
bool hasValueNode(const Value *V)
NodeID getValueNode(const Value *V)
ValueToIDMapTy & valSyms()
Definition LLVMModule.h:214
FunToIDMapTy & retSyms()
Definition LLVMModule.h:281
const FunObjVar * getFunObjVar(const Function *fun) const
Definition LLVMModule.h:274
static LLVMModuleSet * getLLVMModuleSet()
Definition LLVMModule.h:137
SVFBasicBlock * getSVFBasicBlock(const BasicBlock *bb)
Definition LLVMModule.h:305
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:105
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:97
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:164
const Function * getRealDefFun(const Function *fun) const
Definition LLVMModule.h:192
ValueToIDMapTy & objSyms()
Definition LLVMModule.h:219
void addBasicBlock(FunObjVar *fun, const BasicBlock *bb)
Definition LLVMModule.h:239
FunToIDMapTy & varargSyms()
Definition LLVMModule.h:286
const FunctionSet & getFunctionSet() const
Definition LLVMModule.h:199
ObjTypeInference * getTypeInference()
NodeID allocateValueId(void)
Allocate a value ID as determined by the strategy.
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
void setByteSizeOfObj(u32_t size)
Set the byte size of this object.
void setNumOfElements(u32_t num)
Set the number of elements of this object.
static Option< bool > ModelArrays
Definition Options.h:179
static const Option< bool > PAGDotGraph
Definition Options.h:118
static const Option< std::string > DumpJson
Definition Options.h:121
static Option< bool > ModelConsts
Definition Options.h:178
static const Option< bool > PAGPrint
Definition Options.h:124
static const Option< bool > VtableInSVFIR
Definition Options.h:208
static const Option< bool > LoopAnalysis
Definition Options.h:233
static const Option< bool > DumpICFG
Definition Options.h:120
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.
Map< AggregateFieldKey, NodeID > aggregateFieldNodes
Reuse the same scalar SVFIR node for repeated requests for a field.
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 addAggregateCallFields(const CallInst *call)
std::vector< unsigned > AggregateField
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)
std::pair< const Value *, AggregateField > AggregateFieldKey
Identify a field by its LLVM value and path, rather than by its type alone.
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)
void addAggregateReturnStores(ReturnInst &inst)
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.
void initialiseAggregateReturns()
const SVFBasicBlock * getCurrentBB() const
void visitPHINode(PHINode &I)
CopyStmt * addCopyEdge(NodeID src, NodeID dst, CopyStmt::CopyKind kind)
bool getAggregateFieldOperands(const AggregateFieldKey &field, std::vector< AggregateFieldKey > &operands)
Describe one field definition without emitting any SVFIR statements.
bool getAggregateFieldNode(const Value *aggregate, const AggregateField &indices, NodeID &node)
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)
Map< const Function *, std::map< AggregateField, NodeID > > aggregateReturnParams
Demanded field paths to output-parameter IDs, ordered per callee.
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)
Map< const CallInst *, AggregateCall > aggregateCalls
All calls to a modeled callee, including calls with unused results.
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:281
CallGraph * callGraph
all the callsites of a program
Definition SVFIR.h:104
void addToSVFStmtList(ICFGNode *inst, SVFStmt *edge)
Add a SVFStmt into instruction map.
Definition SVFIR.h:329
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:232
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
NodeBS & getAllFieldsObjVars(const BaseObjVar *obj)
Get all fields of an object.
Definition SVFIR.cpp:573
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:238
NodeID addDummyValNode()
Definition SVFIR.h:566
NodeID addFunObjNode(NodeID id, ObjTypeInfo *ti, const ICFGNode *node)
Definition SVFIR.h:741
ICFG * icfg
Definition SVFIR.h:101
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:140
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 addDummyObjNode(const SVFType *type)
Definition SVFIR.h:570
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:52
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.
void set(unsigned Idx)
#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:310
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:71
bool isConstantObjSym(const Value *val)
Check whether this value points-to a constant object.
Definition CppUtil.cpp:684
const Value * stripAllCasts(const Value *val)
Strip off the all casts.
Definition LLVMUtil.cpp:251
const ConstantExpr * isInt2PtrConstantExpr(const Value *val)
Definition LLVMUtil.h:245
const ConstantExpr * isSelectConstantExpr(const Value *val)
Definition LLVMUtil.h:275
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:285
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
Definition LLVMUtil.h:99
void getNextInsts(const Instruction *curInst, std::vector< const Instruction * > &instList)
Get the next instructions following control flow.
Definition LLVMUtil.cpp:589
const ConstantExpr * isPtr2IntConstantExpr(const Value *val)
Definition LLVMUtil.h:255
bool isHeapObj(const Value *val)
Definition LLVMUtil.cpp:698
const ConstantExpr * isUnaryConstantExpr(const Value *val)
Definition LLVMUtil.h:321
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:265
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:720
const ConstantExpr * isGepConstantExpr(const Value *val)
Return corresponding constant expression, otherwise return nullptr.
Definition LLVMUtil.h:235
static DataLayout * getDataLayout(Module *mod)
Definition LLVMUtil.h:333
const Function * getCallee(const CallBase *cs)
Definition LLVMUtil.h:114
const FunObjVar * getFunObjVar(const std::string &name)
Definition LLVMUtil.cpp:437
std::string dumpValue(const Value *val)
Definition LLVMUtil.cpp:616
const ConstantExpr * isCmpConstantExpr(const Value *val)
Definition LLVMUtil.h:299
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:121
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:88
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:58
const Value * getVCallVtblPtr(const CallBase *cs)
Definition CppUtil.cpp:549
bool isValVtbl(const Value *val)
A carefully crafted input such as FakeVTable _ZTV1A = {{nullptr, nullptr}}; can forge a vtable; detec...
Definition CppUtil.cpp:274
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
iter_range< typename GenericGraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)
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
Continuation and field nodes for one call; see the example above.
const Instruction * continuation