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"
41#include "Graphs/CallGraph.h"
42#include "Util/Options.h"
43#include "Util/SVFUtil.h"
44
45using namespace std;
46using namespace SVF;
47using namespace SVFUtil;
48using namespace LLVMUtil;
49
50
55{
56 double startTime = SVFStat::getClk(true);
57
58 DBOUT(DGENERAL, outs() << pasMsg("\t Building SVFIR ...\n"));
59
60 // We read SVFIR from a user-defined txt instead of parsing SVFIR from LLVM IR
62 {
64 return fileBuilder.build();
65 }
66
67 // If the SVFIR has been built before, then we return the unique SVFIR of the program
69 return pag;
70
71
73
76 pag->icfg = icfgbuilder.build();
77
85
86
87
90 std::vector<const FunObjVar*> funset;
91 for (const auto& item: llvmModuleSet()->getFunctionSet())
92 {
94 }
95 pag->callGraph = callGraphBuilder.buildSVFIRCallGraph(funset);
96
97 CHGraph* chg = new CHGraph();
99 chgbuilder.buildCHG();
100 pag->setCHG(chg);
101
104 {
105 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
106 {
107 const Function& fun = *F;
108 const FunObjVar* svffun = llvmModuleSet()->getFunObjVar(&fun);
110 if(!fun.isDeclaration())
111 {
117 if (fun.doesNotReturn() == false &&
118 fun.getReturnType()->isVoidTy() == false)
119 {
122 }
123
126 for (Function::const_arg_iterator I = fun.arg_begin(), E = fun.arg_end();
127 I != E; ++I)
128 {
129 setCurrentLocation(&*I,&fun.getEntryBlock());
131 // if this is the function does not have caller (e.g. main)
132 // or a dead function, shall we create a black hole address edge for it?
133 // it is (1) too conservative, and (2) make FormalParmVFGNode defined at blackhole address PAGEdge.
134 // if(SVFUtil::ArgInNoCallerFunction(&*I)) {
135 // if(I->getType()->isPointerTy())
136 // addBlackHoleAddrEdge(argValNodeId);
137 //}
139 }
140 }
141 for (Function::const_iterator bit = fun.begin(), ebit = fun.end();
142 bit != ebit; ++bit)
143 {
144 const BasicBlock& bb = *bit;
145 for (BasicBlock::const_iterator it = bb.begin(), eit = bb.end();
146 it != eit; ++it)
147 {
148 const Instruction& inst = *it;
149 setCurrentLocation(&inst,&bb);
150 visit(const_cast<Instruction&>(inst));
151 }
152 }
153 }
154 }
155
156 sanityCheck();
157
159
161
162 // dump SVFIR
164 pag->dump("svfir_initial");
165
166 // print to command line of the SVFIR graph
167 if (Options::PAGPrint())
168 pag->print();
169
170 // dump ICFG
171 if (Options::DumpICFG())
172 pag->getICFG()->dump("icfg_initial");
173
175 {
178 }
179
180 // dump SVFIR as JSON
181 if (!Options::DumpJson().empty())
182 {
183 assert(false && "please implement SVFIRWriter::writeJsonToPath");
184 }
185
186 double endTime = SVFStat::getClk(true);
187 SVFStat::timeOfBuildingSVFIR = (endTime - startTime) / TIMEINTERVAL;
188
189 return pag;
190}
191
193{
195 {
197 for (const Function& f : mod.functions())
198 {
201
202 if (!LLVMUtil::isExtCall(&f))
203 {
205 }
208 svffun->setRelDefFun(realfun == nullptr ? nullptr : llvmModuleSet()->getFunObjVar(realfun));
209 }
210 }
211
212 // Store annotations of functions in extapi.bc
213 for (const auto& pair : llvmModuleSet()->ExtFun2Annotations)
214 {
216 }
217
218}
219
221{
223 for (Function::const_iterator bit = func->begin(), ebit = func->end(); bit != ebit; ++bit)
224 {
225 const BasicBlock* bb = &*bit;
228 {
231 }
233 {
236 }
237
239 if (svfbb->getSuccessors().empty())
240 {
242 {
244 SVFUtil::isa<ReturnInst>(bb->back())) &&
245 "last inst must be return inst");
246 svfFun->setExitBlock(svfbb);
247 }
248 }
249 }
250 // For no return functions, we set the last block as exit BB
251 // This ensures that each function that has definition must have an exit BB
252 if (svfFun->hasBasicBlock() && svfFun->exitBlock == nullptr)
253 {
254 SVFBasicBlock* retBB = const_cast<SVFBasicBlock*>(svfFun->back());
256 SVFUtil::isa<ReturnInst>(&func->back().back())) &&
257 "last inst must be return inst");
258 svfFun->setExitBlock(retBB);
259 }
260}
261
262
264{
265 if (fun->isDeclaration())
266 return;
267 //process and stored dt & df
270 df.analyze(dt);
272 PostDominatorTree pdt = PostDominatorTree(const_cast<Function&>(*fun));
273 SVFLoopAndDomInfo* ld = svffun->getLoopAndDomInfo();
274
276 for (DominanceFrontierBase::const_iterator dfIter = df.begin(), eDfIter = df.end(); dfIter != eDfIter; dfIter++)
277 {
278 const BasicBlock* keyBB = dfIter->first;
279 const std::set<BasicBlock* >& domSet = dfIter->second;
281 for (const BasicBlock* bbValue:domSet)
282 {
284 }
285 }
286 std::vector<const SVFBasicBlock*> reachableBBs;
287 LLVMUtil::getFunReachableBBs(fun, reachableBBs);
288 ld->setReachableBBs(reachableBBs);
289
290 for (Function::const_iterator bit = fun->begin(), beit = fun->end(); bit!=beit; ++bit)
291 {
292 const BasicBlock &bb = *bit;
294 if (DomTreeNode* dtNode = dt.getNode(&bb))
295 {
296 SVFLoopAndDomInfo::BBSet& bbSet = ld->getDomTreeMap()[svfBB];
297 for (const auto domBB : *dtNode)
298 {
299 const auto* domSVFBB = llvmModuleSet()->getSVFBasicBlock(domBB->getBlock());
300 bbSet.insert(domSVFBB);
301 }
302 }
303
304 if (DomTreeNode* pdtNode = pdt.getNode(&bb))
305 {
306 u32_t level = pdtNode->getLevel();
307 ld->getBBPDomLevel()[svfBB] = level;
308 BasicBlock* idomBB = pdtNode->getIDom()->getBlock();
310 ld->getBB2PIdom()[svfBB] = idom;
311
312 SVFLoopAndDomInfo::BBSet& bbSet = ld->getPostDomTreeMap()[svfBB];
313 for (const auto domBB : *pdtNode)
314 {
315 const auto* domSVFBB = llvmModuleSet()->getSVFBasicBlock(domBB->getBlock());
316 bbSet.insert(domSVFBB);
317 }
318 }
319
320 if (const Loop* loop = loopInfo.getLoopFor(&bb))
321 {
322 for (const BasicBlock* loopBlock : loop->getBlocks())
323 {
325 ld->addToBB2LoopMap(svfBB, loopbb);
326 }
327 }
328 }
329}
330
332{
333 std::vector<FunObjVar*> funset;
334 // Iterate over all object symbols in the symbol table
335 for (const auto* fun: llvmModuleSet()->getFunctionSet())
336 {
337 u32_t id = llvmModuleSet()->objSyms()[fun];
338 // Debug output for adding object node
339 DBOUT(DPAGBuild, outs() << "add obj node " << id << "\n");
340
341 // Check if the value is a function and add a function object node
342 pag->addFunObjNode(id, pag->getObjTypeInfo(id), llvmModuleSet()->getSVFType(fun->getType()), nullptr);
344
345 FunObjVar *funObjVar = SVFUtil::cast<FunObjVar>(pag->getGNode(id));
346 funset.push_back(funObjVar);
347
348 funObjVar->initFunObjVar(fun->isDeclaration(), LLVMUtil::isIntrinsicFun(fun), fun->hasAddressTaken(),
350 SVFUtil::cast<SVFFunctionType>(llvmModuleSet()->getSVFType(fun->getFunctionType())),
351 new SVFLoopAndDomInfo, nullptr, nullptr,
352 {}, nullptr);
353 BasicBlockGraph* bbGraph = new BasicBlockGraph();
354 funObjVar->setBasicBlockGraph(bbGraph);
355
356
357 for (const BasicBlock& bb : *fun)
358 {
359 llvmModuleSet()->addBasicBlock(funObjVar, &bb);
360 }
361
363 for (auto& bb: *funObjVar->bbGraph)
364 {
365 bb.second->setFun(funObjVar);
366 }
368 }
369
371}
372
374{
375 // Iterate over all object symbols in the symbol table
376 for (LLVMModuleSet::ValueToIDMapTy::iterator iter =
377 llvmModuleSet()->objSyms().begin(); iter != llvmModuleSet()->objSyms().end();
378 ++iter)
379 {
380 // Debug output for adding object node
381 DBOUT(DPAGBuild, outs() << "add obj node " << iter->second << "\n");
382
383 // Skip blackhole and constant symbols
384 if(iter->second == pag->blackholeSymID() || iter->second == pag->constantSymID())
385 continue;
386
387 // Get the LLVM value corresponding to the symbol
388 const Value* llvmValue = iter->first;
389
390 const ICFGNode* icfgNode = nullptr;
391 if (const Instruction* inst = SVFUtil::dyn_cast<Instruction>(llvmValue))
392 {
393 if(llvmModuleSet()->hasICFGNode(inst))
394 icfgNode = llvmModuleSet()->getICFGNode(inst);
395 }
396
397 // Check if the value is a function and add a function object node
398 if (SVFUtil::dyn_cast<Function>(llvmValue))
399 {
400 // already one
401 }
402 // Check if the value is a heap object and add a heap object node
404 {
405 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
406 pag->addHeapObjNode(iter->second, pag->getObjTypeInfo(id), llvmModuleSet()->getSVFType(llvmValue->getType()), icfgNode);
407 }
408 // Check if the value is an alloca instruction and add a stack object node
410 {
411 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
412 pag->addStackObjNode(iter->second, pag->getObjTypeInfo(id), llvmModuleSet()->getSVFType(llvmValue->getType()), icfgNode);
413 }
414 else if (auto fpValue = SVFUtil::dyn_cast<ConstantFP>(llvmValue))
415 {
416 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
417 pag->addConstantFPObjNode(iter->second, pag->getObjTypeInfo(id), LLVMUtil::getDoubleValue(fpValue), llvmModuleSet()->getSVFType(llvmValue->getType()), icfgNode);
418 }
419 else if (auto intValue = SVFUtil::dyn_cast<ConstantInt>(llvmValue))
420 {
421 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
422 pag->addConstantIntObjNode(iter->second, pag->getObjTypeInfo(id), LLVMUtil::getIntegerValue(intValue), llvmModuleSet()->getSVFType(llvmValue->getType()), icfgNode);
423 }
424 else if (SVFUtil::isa<ConstantPointerNull>(llvmValue))
425 {
426 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
427 pag->addConstantNullPtrObjNode(iter->second, pag->getObjTypeInfo(id), llvmModuleSet()->getSVFType(llvmValue->getType()), icfgNode);
428 }
429 else if (SVFUtil::isa<GlobalValue>(llvmValue))
430 {
431 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
432 pag->addGlobalObjNode(iter->second,
433 pag->getObjTypeInfo(id),
434 llvmModuleSet()->getSVFType(llvmValue->getType()), icfgNode);
435 }
436 else if (SVFUtil::isa<ConstantData, MetadataAsValue, BlockAddress>(llvmValue))
437 {
438 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
439 pag->addConstantDataObjNode(iter->second, pag->getObjTypeInfo(id), llvmModuleSet()->getSVFType(llvmValue->getType()), icfgNode);
440 }
441 else if (SVFUtil::isa<ConstantAggregate>(llvmValue))
442 {
443 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
444 pag->addConstantAggObjNode(iter->second, pag->getObjTypeInfo(id), llvmModuleSet()->getSVFType(llvmValue->getType()), icfgNode);
445 }
446 // Add a generic object node for other types of values
447 else
448 {
449 NodeID id = llvmModuleSet()->getObjectNode(iter->first);
450 pag->addObjNode(iter->second,
451 pag->getObjTypeInfo(id), llvmModuleSet()->getSVFType(llvmValue->getType()), icfgNode);
452 }
454 }
455
456}
457
459{
460 // Iterate over all value symbols in the symbol table
461 for (LLVMModuleSet::ValueToIDMapTy::iterator iter =
462 llvmModuleSet()->valSyms().begin(); iter != llvmModuleSet()->valSyms().end();
463 ++iter)
464 {
465 // Debug output for adding value node
466 DBOUT(DPAGBuild, outs() << "add val node " << iter->second << "\n");
467
468 // Skip blackhole and null pointer symbols
469 if(iter->second == pag->blkPtrSymID() || iter->second == pag->nullPtrSymID())
470 continue;
471
472 const ICFGNode* icfgNode = nullptr;
473 auto llvmValue = iter->first;
474 if (const Instruction* inst =
475 SVFUtil::dyn_cast<Instruction>(llvmValue))
476 {
477 if (llvmModuleSet()->hasICFGNode(inst))
478 {
479 icfgNode = llvmModuleSet()->getICFGNode(inst);
480 }
481 }
482
483 // Check if the value is a function and get its call graph node
484 if (const Function* func = SVFUtil::dyn_cast<Function>(llvmValue))
485 {
486 // add value node representing the function
487 pag->addFunValNode(iter->second, icfgNode, llvmModuleSet()->getFunObjVar(func), llvmModuleSet()->getSVFType(llvmValue->getType()));
488 }
489 else if (auto argval = SVFUtil::dyn_cast<Argument>(llvmValue))
490 {
492 iter->second, argval->getArgNo(), icfgNode,
493 llvmModuleSet()->getFunObjVar(argval->getParent()),llvmModuleSet()->getSVFType(llvmValue->getType()));
494 if (!argval->hasName())
495 pag->getGNode(iter->second)->setName("arg_" + std::to_string(argval->getArgNo()));
496 }
497 else if (auto fpValue = SVFUtil::dyn_cast<ConstantFP>(llvmValue))
498 {
499 pag->addConstantFPValNode(iter->second, LLVMUtil::getDoubleValue(fpValue), icfgNode, llvmModuleSet()->getSVFType(llvmValue->getType()));
500 }
501 else if (auto intValue = SVFUtil::dyn_cast<ConstantInt>(llvmValue))
502 {
503 pag->addConstantIntValNode(iter->second, LLVMUtil::getIntegerValue(intValue), icfgNode, llvmModuleSet()->getSVFType(llvmValue->getType()));
504 }
505 else if (SVFUtil::isa<ConstantPointerNull>(llvmValue))
506 {
507 pag->addConstantNullPtrValNode(iter->second, icfgNode, llvmModuleSet()->getSVFType(llvmValue->getType()));
508 }
509 else if (SVFUtil::isa<GlobalValue>(llvmValue))
510 {
511 pag->addGlobalValNode(iter->second, icfgNode,
512 llvmModuleSet()->getSVFType(llvmValue->getType()));
513 }
514 else if (SVFUtil::isa<ConstantData, MetadataAsValue, BlockAddress>(llvmValue))
515 {
516 pag->addConstantDataValNode(iter->second, icfgNode, llvmModuleSet()->getSVFType(llvmValue->getType()));
517 }
518 else if (SVFUtil::isa<ConstantAggregate>(llvmValue))
519 {
520 pag->addConstantAggValNode(iter->second, icfgNode, llvmModuleSet()->getSVFType(llvmValue->getType()));
521 }
522 else
523 {
524 // Add value node to PAG
525 pag->addValNode(iter->second, llvmModuleSet()->getSVFType(llvmValue->getType()), icfgNode);
526 }
528 pag->getGNode(iter->second));
529 }
530}
531
532
533/*
534 * Initial all the nodes from symbol table
535 */
537{
538 DBOUT(DPAGBuild, outs() << "Initialise SVFIR Nodes ...\n");
539
540
545
548
549 for (LLVMModuleSet::FunToIDMapTy::iterator iter =
550 llvmModuleSet()->retSyms().begin(); iter != llvmModuleSet()->retSyms().end();
551 ++iter)
552 {
553 const Value* llvmValue = iter->first;
554 const ICFGNode* icfgNode = nullptr;
555 if (const Instruction* inst = SVFUtil::dyn_cast<Instruction>(llvmValue))
556 {
557 if(llvmModuleSet()->hasICFGNode(inst))
558 icfgNode = llvmModuleSet()->getICFGNode(inst);
559 }
560 DBOUT(DPAGBuild, outs() << "add ret node " << iter->second << "\n");
561 pag->addRetNode(iter->second,
562 llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(llvmValue)),
563 llvmModuleSet()->getSVFType(iter->first->getType()), icfgNode);
565 const FunObjVar* funObjVar = llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(llvmValue));
566 pag->returnFunObjSymMap[funObjVar] = iter->second;
567 }
568
569 for (LLVMModuleSet::FunToIDMapTy::iterator iter =
570 llvmModuleSet()->varargSyms().begin();
571 iter != llvmModuleSet()->varargSyms().end(); ++iter)
572 {
573 const Value* llvmValue = iter->first;
574
575 const ICFGNode *icfgNode = nullptr;
576 if (const Instruction *inst = SVFUtil::dyn_cast<Instruction>(llvmValue))
577 {
578 if (llvmModuleSet()->hasICFGNode(inst))
579 icfgNode = llvmModuleSet()->getICFGNode(inst);
580 }
581 DBOUT(DPAGBuild, outs() << "add vararg node " << iter->second << "\n");
582 pag->addVarargNode(iter->second,
583 llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(llvmValue)),
584 llvmModuleSet()->getSVFType(iter->first->getType()), icfgNode);
586 const FunObjVar* funObjVar = llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(llvmValue));
587 pag->varargFunObjSymMap[funObjVar] = iter->second;
588 }
589
591 for (LLVMModuleSet::ValueToIDMapTy::iterator iter =
592 llvmModuleSet()->objSyms().begin(); iter != llvmModuleSet()->objSyms().end(); ++iter)
593 {
594 DBOUT(DPAGBuild, outs() << "add address edges for constant node " << iter->second << "\n");
595 const Value* val = iter->first;
597 {
599 if(ptr!= pag->getBlkPtr() && ptr!= pag->getNullPtr())
600 {
602 addAddrEdge(iter->second, ptr);
603 }
604 }
605 }
606
608 && "not all node have been initialized!!!");
609
611 for (auto& fun: llvmModuleSet()->getFunctionSet())
612 {
613 for (const Argument& arg : fun->args())
614 {
615 const_cast<FunObjVar*>(llvmModuleSet()->getFunObjVar(fun))->addArgument(SVFUtil::cast<ArgValVar>(
617 }
618 }
619
620}
621
622/*
623 https://github.com/SVF-tools/SVF/issues/524
624 Handling single value types, for constant index, including pointer, integer, etc
625 e.g. field_idx = getelementptr i8, %i8* %p, i64 -4
626 We can obtain the field index by inferring the byteoffset if %p is casted from a pointer to a struct
627 For another example, the following can be an array access.
628 e.g. field_idx = getelementptr i8, %struct_type %p, i64 1
629
630*/
632{
633 return 0;
634}
635
643{
644 assert(V);
645
646 const llvm::GEPOperator *gepOp = SVFUtil::dyn_cast<const llvm::GEPOperator>(V);
647 DataLayout * dataLayout = getDataLayout(llvmModuleSet()->getMainLLVMModule());
648 llvm::APInt byteOffset(dataLayout->getIndexSizeInBits(gepOp->getPointerAddressSpace()),0,true);
649 if(gepOp && dataLayout && gepOp->accumulateConstantOffset(*dataLayout,byteOffset))
650 {
651 //s32_t bo = byteOffset.getSExtValue();
652 }
653
654 bool isConst = true;
655
656 bool prevPtrOperand = false;
657 for (bridge_gep_iterator gi = bridge_gep_begin(*V), ge = bridge_gep_end(*V);
658 gi != ge; ++gi)
659 {
660 const Type* gepTy = *gi;
662
663 assert((prevPtrOperand && svfGepTy->isPointerTy()) == false &&
664 "Expect no more than one gep operand to be of a pointer type");
665 if(!prevPtrOperand && svfGepTy->isPointerTy()) prevPtrOperand = true;
666 const Value* offsetVal = gi.getOperand();
667 assert(gepTy != offsetVal->getType() && "iteration and operand have the same type?");
669
670 //The int value of the current index operand
671 const ConstantInt* op = SVFUtil::dyn_cast<ConstantInt>(offsetVal);
672
673 // if Options::ModelConsts() is disabled. We will treat whole array as one,
674 // but we can distinguish different field of an array of struct, e.g. s[1].f1 is different from s[0].f2
675 if(const ArrayType* arrTy = SVFUtil::dyn_cast<ArrayType>(gepTy))
676 {
677 if(!op || (arrTy->getArrayNumElements() <= (u32_t)LLVMUtil::getIntegerValue(op).first))
678 continue;
682 }
683 else if (const StructType *ST = SVFUtil::dyn_cast<StructType>(gepTy))
684 {
685 assert(op && "non-const offset accessing a struct");
686 //The actual index
690 }
691 else if (gepTy->isSingleValueType())
692 {
693 // If it's a non-constant offset access
694 // If its point-to target is struct or array, it's likely an array accessing (%result = gep %struct.A* %a, i32 %non-const-index)
695 // If its point-to target is single value (pointer arithmetic), then it's a variant gep (%result = gep i8* %p, i32 %non-const-index)
696 if(!op && gepTy->isPointerTy() && gepOp->getSourceElementType()->isSingleValueType())
697 {
698 isConst = false;
699 }
700
701 // The actual index
702 //s32_t idx = op->getSExtValue();
703
704 // For pointer arithmetic we ignore the byte offset
705 // consider using inferFieldIdxFromByteOffset(geopOp,dataLayout,ap,idx)?
706 // ap.setFldIdx(ap.getConstantFieldIdx() + inferFieldIdxFromByteOffset(geopOp,idx));
707 }
708 }
709 return isConst;
710}
711
716{
717 if (const Constant* ref = SVFUtil::dyn_cast<Constant>(val))
718 {
720 {
721 DBOUT(DPAGBuild, outs() << "handle gep constant expression " << llvmModuleSet()->getSVFValue(ref)->toString() << "\n");
722 const Constant* opnd = gepce->getOperand(0);
723 // handle recursive constant express case (gep (bitcast (gep X 1)) 1)
725 auto &GEPOp = llvm::cast<llvm::GEPOperator>(*gepce);
726 Type *pType = GEPOp.getSourceElementType();
727 AccessPath ap(0, llvmModuleSet()->getSVFType(pType));
728 bool constGep = computeGepOffset(gepce, ap);
729 // must invoke pag methods here, otherwise it will be a dead recursion cycle
730 const Value* cval = getCurrentValue();
731 const SVFBasicBlock* cbb = getCurrentBB();
733 /*
734 * The gep edge created are like constexpr (same edge may appear at multiple callsites)
735 * so bb/inst of this edge may be rewritten several times, we treat it as global here.
736 */
739 }
740 else if (const ConstantExpr* castce = isCastConstantExpr(ref))
741 {
742 DBOUT(DPAGBuild, outs() << "handle cast constant expression " << llvmModuleSet()->getSVFValue(ref)->toString() << "\n");
743 const Constant* opnd = castce->getOperand(0);
745 const Value* cval = getCurrentValue();
746 const SVFBasicBlock* cbb = getCurrentBB();
750 }
752 {
753 DBOUT(DPAGBuild, outs() << "handle select constant expression " << llvmModuleSet()->getSVFValue(ref)->toString() << "\n");
754 const Constant* src1 = selectce->getOperand(1);
755 const Constant* src2 = selectce->getOperand(2);
758 const Value* cval = getCurrentValue();
759 const SVFBasicBlock* cbb = getCurrentBB();
761 NodeID cond = llvmModuleSet()->getValueNode(selectce->getOperand(0));
767 }
768 // if we meet a int2ptr, then it points-to black hole
770 {
771 const Constant* opnd = int2Ptrce->getOperand(0);
773 const SVFBasicBlock* cbb = getCurrentBB();
774 const Value* cval = getCurrentValue();
778 }
780 {
781 const Constant* opnd = ptr2Intce->getOperand(0);
783 const SVFBasicBlock* cbb = getCurrentBB();
784 const Value* cval = getCurrentValue();
788 }
790 {
791 // we don't handle trunc and cmp instruction for now
792 const Value* cval = getCurrentValue();
793 const SVFBasicBlock* cbb = getCurrentBB();
798 }
799 else if (isBinaryConstantExpr(ref))
800 {
801 // we don't handle binary constant expression like add(x,y) now
802 const Value* cval = getCurrentValue();
803 const SVFBasicBlock* cbb = getCurrentBB();
808 }
809 else if (isUnaryConstantExpr(ref))
810 {
811 // we don't handle unary constant expression like fneg(x) now
812 const Value* cval = getCurrentValue();
813 const SVFBasicBlock* cbb = getCurrentBB();
818 }
819 else if (SVFUtil::isa<ConstantAggregate>(ref))
820 {
821 // we don't handle constant aggregate like constant vectors
822 }
823 else if (SVFUtil::isa<BlockAddress>(ref))
824 {
825 // blockaddress instruction (e.g. i8* blockaddress(@run_vm, %182))
826 // is treated as constant data object for now, see LLVMUtil.h:397, SymbolTableInfo.cpp:674 and SVFIRBuilder.cpp:183-194
827 const Value* cval = getCurrentValue();
828 const SVFBasicBlock* cbb = getCurrentBB();
833 }
834 else
835 {
836 if(SVFUtil::isa<ConstantExpr>(val))
837 assert(false && "we don't handle all other constant expression for now!");
838 }
839 }
840}
847{
848
849 // if the global variable do not have any field needs to be initialized
850 if (offset == 0 && gvar->getInitializer()->getType()->isSingleValueType())
851 {
852 return getValueNode(gvar);
853 }
856 else
857 {
859 }
860}
861
862/*For global variable initialization
863 * Give a simple global variable
864 * int x = 10; // store 10 x (constant, non pointer) |
865 * int *y = &x; // store x y (pointer type)
866 * Given a struct
867 * struct Z { int s; int *t;};
868 * Global initialization:
869 * struct Z z = {10,&x}; // store x z.t (struct type)
870 * struct Z *m = &z; // store z m (pointer type)
871 * struct Z n = {10,&z.s}; // store z.s n , &z.s constant expression (constant expression)
872 */
875{
876 DBOUT(DPAGBuild, outs() << "global " << llvmModuleSet()->getSVFValue(gvar)->toString() << " constant initializer: " << llvmModuleSet()->getSVFValue(C)->toString() << "\n");
877 if (C->getType()->isSingleValueType())
878 {
879 NodeID src = getValueNode(C);
880 // get the field value if it is available, otherwise we create a dummy field node.
882 NodeID field = getGlobalVarField(gvar, offset, llvmModuleSet()->getSVFType(C->getType()));
883
884 if (SVFUtil::isa<GlobalVariable, Function>(C))
885 {
887 addStoreEdge(src, field);
888 }
889 else if (SVFUtil::isa<ConstantExpr>(C))
890 {
891 // add gep edge of C1 itself is a constant expression
892 processCE(C);
894 addStoreEdge(src, field);
895 }
896 else if (SVFUtil::isa<BlockAddress>(C))
897 {
898 // blockaddress instruction (e.g. i8* blockaddress(@run_vm, %182))
899 // is treated as constant data object for now, see LLVMUtil.h:397, SymbolTableInfo.cpp:674 and SVFIRBuilder.cpp:183-194
900 processCE(C);
903 }
904 else
905 {
907 addStoreEdge(src, field);
909 if (C->getType()->isPtrOrPtrVectorTy() && src != pag->getNullPtr())
911 }
912 }
913 else if (SVFUtil::isa<ConstantArray, ConstantStruct>(C))
914 {
916 return;
917 for (u32_t i = 0, e = C->getNumOperands(); i != e; i++)
918 {
920 InitialGlobal(gvar, SVFUtil::cast<Constant>(C->getOperand(i)), offset + off);
921 }
922 }
923 else if(ConstantData* data = SVFUtil::dyn_cast<ConstantData>(C))
924 {
926 {
927 if(ConstantDataSequential* seq = SVFUtil::dyn_cast<ConstantDataSequential>(data))
928 {
929 for(u32_t i = 0; i < seq->getNumElements(); i++)
930 {
931 u32_t off = pag->getFlattenedElemIdx(llvmModuleSet()->getSVFType(C->getType()), i);
932 Constant* ct = seq->getElementAsConstant(i);
934 }
935 }
936 else
937 {
938 assert((SVFUtil::isa<ConstantAggregateZero, UndefValue>(data)) && "Single value type data should have been handled!");
939 }
940 }
941 }
942 else
943 {
944 //TODO:assert(SVFUtil::isa<ConstantVector>(C),"what else do we have");
945 }
946}
947
952{
953
956 {
957 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
958 {
959 GlobalVariable *gvar = &*I;
962
965
966 if (gvar->hasInitializer())
967 {
968 Constant *C = gvar->getInitializer();
969 DBOUT(DPAGBuild, outs() << "add global var node " << llvmModuleSet()->getSVFValue(gvar)->toString() << "\n");
970 InitialGlobal(gvar, C, 0);
971 }
972 }
973
974
976 for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
977 {
978 const Function* fun = &*I;
979 NodeID idx = getValueNode(fun);
980 NodeID obj = getObjectNode(fun);
981
982 DBOUT(DPAGBuild, outs() << "add global function node " << fun->getName().str() << "\n");
983 setCurrentLocation(fun, (SVFBasicBlock*) nullptr);
985 }
986
987 // 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.
988 for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; I++)
989 {
990 const GlobalAlias* alias = &*I;
991 NodeID dst = llvmModuleSet()->getValueNode(alias);
992 NodeID src = llvmModuleSet()->getValueNode(alias->getAliasee());
993 processCE(alias->getAliasee());
994 setCurrentLocation(alias, (SVFBasicBlock*) nullptr);
996 }
997 }
998}
999
1005{
1006
1007 // AllocaInst should always be a pointer type
1008 assert(SVFUtil::isa<PointerType>(inst.getType()));
1009
1010 DBOUT(DPAGBuild, outs() << "process alloca " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
1011 NodeID dst = getValueNode(&inst);
1012
1013 NodeID src = getObjectNode(&inst);
1014
1015 addAddrWithStackArraySz(src, dst, inst);
1016
1017}
1018
1023{
1024
1025 DBOUT(DPAGBuild, outs() << "process phi " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
1026
1027 NodeID dst = getValueNode(&inst);
1028
1029 for (u32_t i = 0; i < inst.getNumIncomingValues(); ++i)
1030 {
1031 const Value* val = inst.getIncomingValue(i);
1032 const Instruction* incomingInst = SVFUtil::dyn_cast<Instruction>(val);
1033 bool matched = (incomingInst == nullptr ||
1034 incomingInst->getFunction() == inst.getFunction());
1035 (void) matched; // Suppress warning of unused variable under release build
1036 assert(matched && "incomingInst's Function incorrect");
1037 const Instruction* predInst = &inst.getIncomingBlock(i)->back();
1038 const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(predInst);
1039 NodeID src = getValueNode(val);
1040 addPhiStmt(dst,src,icfgNode);
1041 }
1042}
1043
1044/*
1045 * Visit load instructions
1046 */
1048{
1049 DBOUT(DPAGBuild, outs() << "process load " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
1050
1051 NodeID dst = getValueNode(&inst);
1052
1053 NodeID src = getValueNode(inst.getPointerOperand());
1054
1055 addLoadEdge(src, dst);
1056}
1057
1062{
1063 // StoreInst itself should always not be a pointer type
1064 assert(!SVFUtil::isa<PointerType>(inst.getType()));
1065
1066 DBOUT(DPAGBuild, outs() << "process store " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
1067
1068 NodeID dst = getValueNode(inst.getPointerOperand());
1069
1070 NodeID src = getValueNode(inst.getValueOperand());
1071
1072 addStoreEdge(src, dst);
1073
1074}
1075
1080{
1081
1082 NodeID dst = getValueNode(&inst);
1083 // GetElementPtrInst should always be a pointer or a vector contains pointers
1084 // for now we don't handle vector type here
1085 if(SVFUtil::isa<VectorType>(inst.getType()))
1086 {
1088 return;
1089 }
1090
1091 assert(SVFUtil::isa<PointerType>(inst.getType()));
1092
1093 DBOUT(DPAGBuild, outs() << "process gep " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
1094
1095 NodeID src = getValueNode(inst.getPointerOperand());
1096
1097 AccessPath ap(0, llvmModuleSet()->getSVFType(inst.getSourceElementType()));
1098 bool constGep = computeGepOffset(&inst, ap);
1099 addGepEdge(src, dst, ap, constGep);
1100}
1101
1102/*
1103 * Visit cast instructions
1104 */
1106{
1107
1108 DBOUT(DPAGBuild, outs() << "process cast " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
1109 NodeID dst = getValueNode(&inst);
1110
1111 const Value* opnd = inst.getOperand(0);
1112 NodeID src = getValueNode(opnd);
1113 addCopyEdge(src, dst, getCopyKind(&inst));
1114}
1115
1120{
1121 NodeID dst = getValueNode(&inst);
1122 assert(inst.getNumOperands() == 2 && "not two operands for BinaryOperator?");
1123 Value* op1 = inst.getOperand(0);
1125 Value* op2 = inst.getOperand(1);
1127 u32_t opcode = inst.getOpcode();
1128 addBinaryOPEdge(op1Node, op2Node, dst, opcode);
1129}
1130
1135{
1136 NodeID dst = getValueNode(&inst);
1137 assert(inst.getNumOperands() == 1 && "not one operand for Unary instruction?");
1138 Value* opnd = inst.getOperand(0);
1139 NodeID src = getValueNode(opnd);
1140 u32_t opcode = inst.getOpcode();
1141 addUnaryOPEdge(src, dst, opcode);
1142}
1143
1148{
1149 NodeID dst = getValueNode(&inst);
1150 assert(inst.getNumOperands() == 2 && "not two operands for compare instruction?");
1151 Value* op1 = inst.getOperand(0);
1153 Value* op2 = inst.getOperand(1);
1155 u32_t predicate = inst.getPredicate();
1156 addCmpEdge(op1Node, op2Node, dst, predicate);
1157}
1158
1159
1164{
1165
1166 DBOUT(DPAGBuild, outs() << "process select " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
1167
1168 NodeID dst = getValueNode(&inst);
1169 NodeID src1 = getValueNode(inst.getTrueValue());
1170 NodeID src2 = getValueNode(inst.getFalseValue());
1171 NodeID cond = getValueNode(inst.getCondition());
1173 addSelectStmt(dst,src1,src2, cond);
1174}
1175
1180
1185
1190
1191/*
1192 * Visit callsites
1193 */
1195{
1196
1197 // skip llvm intrinsics
1198 if(isIntrinsicInst(cs))
1199 return;
1200
1202 outs() << "process callsite " << svfcall->valueOnlyToString() << "\n");
1203
1204
1205 CallICFGNode* callBlockNode = llvmModuleSet()->getCallICFGNode(cs);
1207
1208 pag->addCallSite(callBlockNode);
1209
1211 for (u32_t i = 0; i < cs->arg_size(); i++)
1213 callBlockNode,
1214 SVFUtil::cast<ValVar>(pag->getGNode(getValueNode(cs->getArgOperand(i)))));
1215
1216 if(!cs->getType()->isVoidTy())
1218
1219 if (callBlockNode->isVirtualCall())
1220 {
1221 const Value* value = cppUtil::getVCallVtblPtr(cs);
1222 callBlockNode->setVtablePtr(pag->getGNode(getValueNode(value)));
1223 }
1224 if (const Function *callee = LLVMUtil::getCallee(cs))
1225 {
1227 {
1228 handleExtCall(cs, callee);
1229 }
1230 else
1231 {
1233 }
1234 }
1235 else
1236 {
1237 //If the callee was not identified as a function (null F), this is indirect.
1238 handleIndCall(cs);
1239 }
1240}
1241
1246{
1247
1248 // ReturnInst itself should always not be a pointer type
1249 assert(!SVFUtil::isa<PointerType>(inst.getType()));
1250
1251 DBOUT(DPAGBuild, outs() << "process return " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
1252
1253 if(Value* src = inst.getReturnValue())
1254 {
1255 const FunObjVar *F = llvmModuleSet()->getFunObjVar(inst.getParent()->getParent());
1256
1258 NodeID vnS = getValueNode(src);
1259 const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(&inst);
1260 //vnS may be null if src is a null ptr
1261 addPhiStmt(rnF,vnS,icfgNode);
1262 }
1263}
1264
1265
1279
1293
1299{
1300 NodeID brinst = getValueNode(&inst);
1301 NodeID cond;
1302 if (inst.isConditional())
1303 cond = getValueNode(inst.getCondition());
1304 else
1305 cond = pag->getNullPtr();
1306
1307 assert(inst.getNumSuccessors() <= 2 && "if/else has more than two branches?");
1308
1310 std::vector<const Instruction*> nextInsts;
1312 u32_t branchID = 0;
1313 for (const Instruction* succInst : nextInsts)
1314 {
1315 assert(branchID <= 1 && "if/else has more than two branches?");
1316 const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(succInst);
1317 successors.push_back(std::make_pair(icfgNode, 1-branchID));
1318 branchID++;
1319 }
1320 addBranchStmt(brinst, cond, successors);
1322 if (inst.isConditional())
1323 {
1324 for (auto& edge : llvmModuleSet()->getICFGNode(&inst)->getOutEdges())
1325 {
1326 if (IntraCFGEdge* intraEdge = SVFUtil::dyn_cast<IntraCFGEdge>(edge))
1327 {
1328 intraEdge->setConditionVar(pag->getGNode(cond));
1329 }
1330 }
1331 }
1332}
1333
1334
1378
1381{
1382 NodeID brinst = getValueNode(&inst);
1383 NodeID cond = getValueNode(inst.getCondition());
1384
1386 std::vector<const Instruction*> nextInsts;
1388 for (const Instruction* succInst : nextInsts)
1389 {
1391 const ConstantInt* condVal = inst.findCaseDest(const_cast<BasicBlock*>(succInst->getParent()));
1393 s64_t val = -1;
1394 if (condVal && condVal->getBitWidth() <= 64)
1396 const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(succInst);
1397 successors.push_back(std::make_pair(icfgNode, val));
1398 }
1399 addBranchStmt(brinst, cond, successors);
1401 for (auto& edge : llvmModuleSet()->getICFGNode(&inst)->getOutEdges())
1402 {
1403 if (IntraCFGEdge* intraEdge = SVFUtil::dyn_cast<IntraCFGEdge>(edge))
1404 {
1405 intraEdge->setConditionVar(pag->getGNode(cond));
1406 }
1407 }
1408}
1409
1410
1417{
1418 NodeID dst = getValueNode(&inst);
1419 Value* opnd = inst.getPointerOperand();
1420 NodeID src = getValueNode(opnd);
1421 addCopyEdge(src, dst, CopyStmt::COPYVAL);
1422}
1423
1429{
1430 NodeID dst = getValueNode(&inst);
1431 for (u32_t i = 0; i < inst.getNumOperands(); i++)
1432 {
1433 Value* opnd = inst.getOperand(i);
1434 NodeID src = getValueNode(opnd);
1435 addCopyEdge(src, dst, CopyStmt::COPYVAL);
1436 }
1437}
1438
1439
1444{
1445
1446 assert(F);
1450 outs() << "handle direct call " << LLVMUtil::dumpValue(cs) << " callee " << F->getName().str() << "\n");
1451
1452 //Only handle the ret.val. if it's used as a ptr.
1454 //Does it actually return a ptr?
1455 if (!cs->getType()->isVoidTy())
1456 {
1460 }
1461 //Iterators for the actual and formal parameters
1462 u32_t itA = 0, ieA = cs->arg_size();
1463 Function::const_arg_iterator itF = F->arg_begin(), ieF = F->arg_end();
1464 //Go through the fixed parameters.
1465 DBOUT(DPAGBuild, outs() << " args:");
1466 for (; itF != ieF; ++itA, ++itF)
1467 {
1468 //Some programs (e.g. Linux kernel) leave unneeded parameters empty.
1469 if (itA == ieA)
1470 {
1471 DBOUT(DPAGBuild, outs() << " !! not enough args\n");
1472 break;
1473 }
1474 const Value* AA = cs->getArgOperand(itA), *FA = &*itF; //current actual/formal arg
1475
1476 DBOUT(DPAGBuild, outs() << "process actual parm " << llvmModuleSet()->getSVFValue(AA)->toString() << " \n");
1477
1482 }
1483 //Any remaining actual args must be varargs.
1484 if (F->isVarArg())
1485 {
1487 DBOUT(DPAGBuild, outs() << "\n varargs:");
1488 for (; itA != ieA; ++itA)
1489 {
1490 const Value* AA = cs->getArgOperand(itA);
1494 }
1495 }
1496 if(itA != ieA)
1497 {
1500 writeWrnMsg("too many args to non-vararg func.");
1501 writeWrnMsg("(" + callICFGNode->getSourceLoc() + ")");
1502
1503 }
1504}
1505
1538{
1539 const Value* value = stripAllCasts(V);
1540 assert(value && "null ptr?");
1541 if(const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(value))
1542 {
1543 APOffset totalidx = 0;
1544 for (bridge_gep_iterator gi = bridge_gep_begin(gep), ge = bridge_gep_end(gep); gi != ge; ++gi)
1545 {
1546 if(const ConstantInt* op = SVFUtil::dyn_cast<ConstantInt>(gi.getOperand()))
1548 }
1549 if(totalidx == 0 && !SVFUtil::isa<StructType>(value->getType()))
1550 value = gep->getPointerOperand();
1551 }
1552 else if (const LoadInst* load = SVFUtil::dyn_cast<LoadInst>(value))
1553 {
1554 const Value* loadP = load->getPointerOperand();
1555 if (const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(loadP))
1556 {
1557 APOffset totalidx = 0;
1558 for (bridge_gep_iterator gi = bridge_gep_begin(gep), ge = bridge_gep_end(gep); gi != ge; ++gi)
1559 {
1560 if(const ConstantInt* op = SVFUtil::dyn_cast<ConstantInt>(gi.getOperand()))
1562 }
1563 const Value * pointer_operand = gep->getPointerOperand();
1564 if (auto *glob = SVFUtil::dyn_cast<GlobalVariable>(pointer_operand))
1565 {
1566 if (glob->hasInitializer())
1567 {
1568 if (auto *initializer = SVFUtil::dyn_cast<
1569 ConstantStruct>(glob->getInitializer()))
1570 {
1571 /*
1572 *@conststruct = internal global <{ [40 x i8], [4 x i8], [4 x i8], [2512 x i8] }>
1573 <{ [40 x i8] undef, [4 x i8] zeroinitializer, [4 x i8] undef, [2512 x i8] zeroinitializer }>, align 8
1574
1575 %0 = load ptr, ptr getelementptr inbounds (<{ [40 x i8], [4 x i8], [4 x i8], [2512 x i8] }>,
1576 ptr @conststruct, i64 0, i32 0, i64 16)
1577 in this case, totalidx is 16 while initializer->getNumOperands() is 4, so we return value as the base
1578 */
1579 if (totalidx >= initializer->getNumOperands()) return value;
1580 auto *ptrField = initializer->getOperand(totalidx);
1581 if (auto *ptrValue = SVFUtil::dyn_cast<llvm::GlobalVariable>(ptrField))
1582 {
1583 return ptrValue;
1584 }
1585 }
1586 }
1587 }
1588 }
1589 }
1590
1591 return value;
1592}
1593
1598{
1600 pag->addIndirectCallsites(cbn,llvmModuleSet()->getValueNode(cs->getCalledOperand()));
1601}
1602
1604{
1605 CallGraph::CallEdgeMap::const_iterator iter = callgraph->getIndCallMap().begin();
1606 CallGraph::CallEdgeMap::const_iterator eiter = callgraph->getIndCallMap().end();
1607 for (; iter != eiter; iter++)
1608 {
1609 const CallICFGNode* callBlock = iter->first;
1610 const CallBase* callbase = SVFUtil::cast<CallBase>(llvmModuleSet()->getLLVMValue(callBlock));
1611 assert(callBlock->isIndirectCall() && "this is not an indirect call?");
1612 const CallGraph::FunctionSet& functions = iter->second;
1613 for (CallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
1614 {
1615 const Function* callee = SVFUtil::cast<Function>(llvmModuleSet()->getLLVMValue(*func_iter));
1616
1617 if (isExtCall(*func_iter))
1618 {
1619 setCurrentLocation(callee, callee->empty() ? nullptr : &callee->getEntryBlock());
1621 }
1622 else
1623 {
1624 setCurrentLocation(llvmModuleSet()->getLLVMValue(callBlock), callBlock->getBB());
1625 handleDirectCall(const_cast<CallBase*>(callbase), callee);
1626 }
1627 }
1628 }
1629
1630 // dump SVFIR
1632 pag->dump("svfir_final");
1633}
1634
1635/*
1636 * TODO: more sanity checks might be needed here
1637 */
1639{
1640 for (SVFIR::iterator nIter = pag->begin(); nIter != pag->end(); ++nIter)
1641 {
1642 (void) pag->getGNode(nIter->first);
1643 //TODO::
1644 // (1) every source(root) node of a pag tree should be object node
1645 // if a node has no incoming edge, but has outgoing edges
1646 // then it has to be an object node.
1647 // (2) make sure every variable should be initialized
1648 // otherwise it causes the a null pointer, the aliasing relation may not be captured
1649 // when loading a pointer value should make sure
1650 // some value has been store into this pointer before
1651 // q = load p, some value should stored into p first like store w p;
1652 // (3) make sure PAGNode should not have a const expr value (pointer should have unique def)
1653 // (4) look closely into addComplexConsForExt, make sure program locations(e.g.,inst bb)
1654 // are set correctly for dummy gepval node
1655 // (5) reduce unnecessary copy edge (const casts) and ensure correctness.
1656 }
1657}
1658
1659
1665{
1666 NodeID base = getValueNode(val);
1668 if (gepval==UINT_MAX)
1669 {
1670 assert(((int) UINT_MAX)==-1 && "maximum limit of unsigned int is not -1?");
1671 /*
1672 * getGepValVar can only be called from two places:
1673 * 1. SVFIRBuilder::addComplexConsForExt to handle external calls
1674 * 2. SVFIRBuilder::getGlobalVarField to initialize global variable
1675 * so curVal can only be
1676 * 1. Instruction
1677 * 2. GlobalVariable
1678 */
1679 assert(
1680 (SVFUtil::isa<Instruction>(curVal) || SVFUtil::isa<GlobalVariable>(curVal)) && "curVal not an instruction or a globalvariable?");
1681
1682 // We assume every GepValNode and its GepEdge to the baseNode are unique across the whole program
1683 // We preserve the current BB information to restore it after creating the gepNode
1684 const Value* cval = getCurrentValue();
1685 const SVFBasicBlock* cbb = getCurrentBB();
1688 const ICFGNode* node = nullptr;
1689 if (const Instruction* inst = SVFUtil::dyn_cast<Instruction>(curVal))
1690 if (llvmmodule->hasICFGNode(inst))
1691 {
1692 node = llvmmodule->getICFGNode(inst);
1693 }
1695 NodeIDAllocator::get()->allocateValueId(),
1696 llvmmodule->getSVFType(PointerType::getUnqual(llvmmodule->getContext())), node);
1697 addGepEdge(base, gepNode, ap, true);
1699 return gepNode;
1700 }
1701 else
1702 return gepval;
1703}
1704
1705
1706/*
1707 * curVal <--------> PAGEdge
1708 * Instruction Any Edge
1709 * Argument CopyEdge (SVFIR::addFormalParamBlackHoleAddrEdge)
1710 * ConstantExpr CopyEdge (Int2PtrConstantExpr CastConstantExpr SVFIRBuilder::processCE)
1711 * GepEdge (GepConstantExpr SVFIRBuilder::processCE)
1712 * ConstantPointerNull CopyEdge (3-->2 NullPtr-->BlkPtr SVFIR::addNullPtrNode)
1713 * AddrEdge (0-->2 BlkObj-->BlkPtr SVFIR::addNullPtrNode)
1714 * GlobalVariable AddrEdge (SVFIRBuilder::visitGlobal)
1715 * GepEdge (SVFIRBuilder::getGlobalVarField)
1716 * Function AddrEdge (SVFIRBuilder::visitGlobal)
1717 * Constant StoreEdge (SVFIRBuilder::InitialGlobal)
1718 */
1720{
1722 return;
1723
1724 assert(curVal && "current Val is nullptr?");
1725 edge->setBB(curBB!=nullptr ? curBB : nullptr);
1727 ICFGNode* icfgNode = pag->getICFG()->getGlobalICFGNode();
1729 if (const Instruction* curInst = SVFUtil::dyn_cast<Instruction>(curVal))
1730 {
1731 const FunObjVar* srcFun = edge->getSrcNode()->getFunction();
1732 const FunObjVar* dstFun = edge->getDstNode()->getFunction();
1733 if(srcFun!=nullptr && !SVFUtil::isa<RetPE>(edge) && !SVFUtil::isa<FunValVar>(edge->getSrcNode()) && !SVFUtil::isa<FunObjVar>(edge->getSrcNode()))
1734 {
1735 assert(srcFun==llvmMS->getFunObjVar(curInst->getFunction()) && "SrcNode of the PAGEdge not in the same function?");
1736 }
1737 if(dstFun!=nullptr && !SVFUtil::isa<CallPE>(edge) && !SVFUtil::isa<RetValPN>(edge->getDstNode()))
1738 {
1739 assert(dstFun==llvmMS->getFunObjVar(curInst->getFunction()) && "DstNode of the PAGEdge not in the same function?");
1740 }
1741
1743 if (!(SVFUtil::isa<GepStmt>(edge) && SVFUtil::isa<GepValVar>(edge->getDstNode())))
1744 assert(curBB && "instruction does not have a basic block??");
1745
1747 if(SVFUtil::isa<ReturnInst>(curInst))
1748 {
1749 icfgNode = pag->getICFG()->getFunExitICFGNode(llvmMS->getFunObjVar(curInst->getFunction()));
1750 }
1751 else
1752 {
1753 if(SVFUtil::isa<RetPE>(edge))
1754 icfgNode = llvmMS->getRetICFGNode(SVFUtil::cast<Instruction>(curInst));
1755 else
1756 icfgNode = llvmMS->getICFGNode(SVFUtil::cast<Instruction>(curInst));
1757 }
1758 }
1759 else if (const Argument* arg = SVFUtil::dyn_cast<Argument>(curVal))
1760 {
1762 icfgNode = pag->getICFG()->getFunEntryICFGNode(
1763 llvmModuleSet()->getFunObjVar(SVFUtil::cast<Function>(arg->getParent())));
1764 }
1765 else if (SVFUtil::isa<Constant>(curVal) ||
1766 SVFUtil::isa<Function>(curVal) ||
1767 SVFUtil::isa<MetadataAsValue>(curVal))
1768 {
1769 if (!curBB)
1771 else
1772 {
1773 icfgNode = const_cast<ICFGNode*>(curBB->front());
1774 }
1775 }
1776 else
1777 {
1778 assert(false && "what else value can we have?");
1779 }
1780
1781 pag->addToSVFStmtList(icfgNode,edge);
1782 icfgNode->addSVFStmt(edge);
1783 if(const CallPE* callPE = SVFUtil::dyn_cast<CallPE>(edge))
1784 {
1785 CallICFGNode* callNode = const_cast<CallICFGNode*>(callPE->getCallSite());
1786 FunEntryICFGNode* entryNode = const_cast<FunEntryICFGNode*>(callPE->getFunEntryICFGNode());
1788 SVFUtil::cast<CallCFGEdge>(edge)->addCallPE(callPE);
1789 }
1790 else if(const RetPE* retPE = SVFUtil::dyn_cast<RetPE>(edge))
1791 {
1792 RetICFGNode* retNode = const_cast<RetICFGNode*>(retPE->getCallSite()->getRetICFGNode());
1793 FunExitICFGNode* exitNode = const_cast<FunExitICFGNode*>(retPE->getFunExitICFGNode());
1795 SVFUtil::cast<RetCFGEdge>(edge)->addRetPE(retPE);
1796 }
1797}
1798
1799
1807{
1808 SVFVar* node = pag->getGNode(nodeId);
1811 if(geps.empty())
1812 return AccessPath(0);
1813
1814 assert(geps.size()==1 && "one node can only be connected by at most one gep edge!");
1815 SVFVar::iterator it = geps.begin();
1816 const GepStmt* gepEdge = SVFUtil::cast<GepStmt>(*it);
1817 if(gepEdge->isVariantFieldGep())
1818 return AccessPath(0);
1819 else
1820 return gepEdge->getAccessPath();
1821}
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:512
#define TIMEINTERVAL
Definition SVFType.h:540
#define DGENERAL
Definition SVFType.h:518
#define DPAGBuild
Definition SVFType.h:520
buffer offset
Definition cJSON.cpp:1113
cJSON * item
Definition cJSON.h:222
bool addOffsetVarAndGepTypePair(const SVFVar *var, const SVFType *gepIterType)
APOffset getConstantStructFldIdx() const
Get methods.
Definition AccessPath.h:99
void setFldIdx(APOffset idx)
Definition AccessPath.h:103
std::vector< std::pair< const ICFGNode *, s32_t > > SuccAndCondPairVec
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
Definition CallGraph.h:319
Set< const FunObjVar * > FunctionSet
Definition CallGraph.h:244
bool isVirtualCall() const
Definition ICFGNode.h:521
void setVtablePtr(SVFVar *v)
Definition ICFGNode.h:526
static ExtAPI * getExtAPI()
Definition ExtAPI.cpp:44
void setExtFuncAnnotations(const FunObjVar *fun, const std::vector< std::string > &funcAnnotations)
Definition ExtAPI.cpp:223
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
iterator begin()
Iterators.
u32_t getTotalNodeNum() const
Get total number of node/edge.
IDToNodeMapTy::iterator iterator
Node Iterators.
NodeType * getGNode(NodeID id) const
Get a node.
GEdgeSetTy::iterator iterator
const GEdgeSetTy & getOutEdges() const
void addSVFStmt(const SVFStmt *edge)
Definition ICFGNode.h:112
FunExitICFGNode * getFunExitICFGNode(const FunObjVar *fun)
Add a function exit node.
Definition ICFG.cpp:249
ICFGEdge * hasInterICFGEdge(ICFGNode *src, ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
Definition ICFG.cpp:276
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
Definition ICFG.cpp:411
FunEntryICFGNode * getFunEntryICFGNode(const FunObjVar *fun)
Add a function entry node.
Definition ICFG.cpp:242
GlobalICFGNode * getGlobalICFGNode() const
Definition ICFG.h:230
NodeID constantSymID() const
Definition IRGraph.h:188
u32_t getFlattenedElemIdx(const SVFType *T, u32_t origId)
Flattened element idx of an array or struct by considering stride.
Definition IRGraph.cpp:144
u32_t getNodeNumAfterPAGBuild() const
Definition IRGraph.h:313
void dump(std::string name)
Dump SVFIR.
Definition IRGraph.cpp:310
NodeID getBlkPtr() const
Definition IRGraph.h:255
NodeID blkPtrSymID() const
Definition IRGraph.h:178
NodeID getNullPtr() const
Definition IRGraph.h:259
NodeID nullPtrSymID() const
Definition IRGraph.h:183
u32_t getTotalSymNum() const
Statistics.
Definition IRGraph.h:200
FunObjVarToIDMapTy varargFunObjSymMap
vararg map
Definition IRGraph.h:87
NodeID getReturnNode(const FunObjVar *func) const
GetReturnNode - Return the unique node representing the return value of a function.
Definition IRGraph.cpp:60
void setNodeNumAfterPAGBuild(u32_t num)
Definition IRGraph.h:317
NodeID blackholeSymID() const
Definition IRGraph.h:193
ObjTypeInfo * getObjTypeInfo(NodeID id) const
Definition IRGraph.h:234
NodeID getConstantNode() const
Definition IRGraph.h:251
FunObjVarToIDMapTy returnFunObjSymMap
return map
Definition IRGraph.h:86
virtual void build(ICFG *icfg)
Start from here.
NodeID getValueNode(const Value *V)
ValueToIDMapTy & valSyms()
Definition LLVMModule.h:207
FunToIDMapTy & retSyms()
Definition LLVMModule.h:274
const FunObjVar * getFunObjVar(const Function *fun) const
Definition LLVMModule.h:267
SVFBasicBlock * getSVFBasicBlock(const BasicBlock *bb)
Definition LLVMModule.h:298
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:99
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
bool hasICFGNode(const Instruction *inst)
ICFGNode * getICFGNode(const Instruction *inst)
Get a basic block ICFGNode.
CallICFGNode * getCallICFGNode(const Instruction *cs)
get a call node
Fun2AnnoMap ExtFun2Annotations
Record annotations of function in extapi.bc.
Definition LLVMModule.h:91
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:157
const Function * getRealDefFun(const Function *fun) const
Definition LLVMModule.h:185
ValueToIDMapTy & objSyms()
Definition LLVMModule.h:212
void addBasicBlock(FunObjVar *fun, const BasicBlock *bb)
Definition LLVMModule.h:232
FunToIDMapTy & varargSyms()
Definition LLVMModule.h:279
const FunctionSet & getFunctionSet() const
Definition LLVMModule.h:192
static NodeIDAllocator * get(void)
Return (singleton) allocator.
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:184
static const Option< bool > PAGPrint
Definition Options.h:124
static const Option< bool > VtableInSVFIR
Definition Options.h:214
static const Option< bool > LoopAnalysis
Definition Options.h:239
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.
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)
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 addObjNode(NodeID i, ObjTypeInfo *ti, const SVFType *type, const ICFGNode *node)
Add a memory obj node.
Definition SVFIR.h:619
NodeID addGlobalValNode(const NodeID i, const ICFGNode *icfgNode, const SVFType *svfType)
Definition SVFIR.h:599
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:522
NodeID addGlobalObjNode(const NodeID i, ObjTypeInfo *ti, const SVFType *type, const ICFGNode *node)
Definition SVFIR.h:676
void print()
Print SVFIR.
Definition SVFIR.cpp:557
NodeID addConstantFPObjNode(NodeID i, ObjTypeInfo *ti, double dval, const SVFType *type, const ICFGNode *node)
Definition SVFIR.h:652
NodeID addBlackholePtrNode()
Definition SVFIR.h:751
NodeID addBlackholeObjNode()
Definition SVFIR.h:743
void addFunArgs(const FunObjVar *fun, const SVFVar *arg)
Get/set method for function/callsite arguments and returns.
Definition SVFIR.h:523
NodeID addHeapObjNode(NodeID i, ObjTypeInfo *ti, const SVFType *type, const ICFGNode *node)
Definition SVFIR.h:627
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:403
void addFunRet(const FunObjVar *fun, const SVFVar *ret)
Add function returns.
Definition SVFIR.h:530
NodeID addFunObjNode(NodeID id, ObjTypeInfo *ti, const SVFType *type, const ICFGNode *node)
Definition SVFIR.h:644
NodeID addStackObjNode(NodeID i, ObjTypeInfo *ti, const SVFType *type, const ICFGNode *node)
Definition SVFIR.h:637
static std::string pagFileName()
Definition SVFIR.h:202
NodeID addConstantNullPtrValNode(const NodeID i, const ICFGNode *icfgNode, const SVFType *type)
Definition SVFIR.h:593
static bool pagReadFromTXT()
Definition SVFIR.h:207
CallGraph * callGraph
all the callsites of a program
Definition SVFIR.h:99
NodeID addConstantDataObjNode(const NodeID i, ObjTypeInfo *ti, const SVFType *type, const ICFGNode *node)
Definition SVFIR.h:688
void addToSVFStmtList(ICFGNode *inst, SVFStmt *edge)
Add a SVFStmt into instruction map.
Definition SVFIR.h:255
void addCallSiteRets(RetICFGNode *retBlockNode, const SVFVar *arg)
Add callsite returns.
Definition SVFIR.h:543
NodeID addConstantDataValNode(const NodeID i, const ICFGNode *icfgNode, const SVFType *type)
Definition SVFIR.h:611
void addCallSiteArgs(CallICFGNode *callBlockNode, const ValVar *arg)
Add callsite arguments.
Definition SVFIR.h:537
NodeID addConstantAggObjNode(const NodeID i, ObjTypeInfo *ti, const SVFType *type, const ICFGNode *node)
Definition SVFIR.h:682
NodeID addConstantIntValNode(NodeID i, const std::pair< s64_t, u64_t > &intValue, const ICFGNode *icfgNode, const SVFType *type)
Definition SVFIR.h:586
ICFG * getICFG() const
Definition SVFIR.h:163
NodeID addFunValNode(NodeID i, const ICFGNode *icfgNode, const FunObjVar *funObjVar, const SVFType *type)
Definition SVFIR.h:566
NodeID addConstantFPValNode(const NodeID i, double dval, const ICFGNode *icfgNode, const SVFType *type)
Definition SVFIR.h:579
NodeID addConstantAggValNode(const NodeID i, const ICFGNode *icfgNode, const SVFType *svfType)
Definition SVFIR.h:605
NodeID addConstantNullPtrObjNode(const NodeID i, ObjTypeInfo *ti, const SVFType *type, const ICFGNode *node)
Definition SVFIR.h:669
void addCallSite(const CallICFGNode *call)
Add callsites.
Definition SVFIR.h:792
NodeID addValNode(NodeID i, const SVFType *type, const ICFGNode *icfgNode)
add node into SVFIR
Definition SVFIR.h:560
NodeID addVarargNode(NodeID i, const FunObjVar *val, const SVFType *type, const ICFGNode *n)
Add a unique vararg node for a procedure.
Definition SVFIR.h:702
void setCHG(CommonCHGraph *c)
Set/Get CHG.
Definition SVFIR.h:169
ICFG * icfg
Definition SVFIR.h:96
NodeID addConstantIntObjNode(NodeID i, ObjTypeInfo *ti, const std::pair< s64_t, u64_t > &intValue, const SVFType *type, const ICFGNode *node)
Definition SVFIR.h:660
void addGlobalPAGEdge(const SVFStmt *edge)
Add global PAGEdges (not in a procedure)
Definition SVFIR.h:787
void addIndirectCallsites(const CallICFGNode *cs, NodeID funPtr)
Add indirect callsites.
Definition SVFIR.h:549
void initialiseCandidatePointers()
Initialize candidate pointers.
Definition SVFIR.cpp:642
NodeID addRetNode(NodeID i, const FunObjVar *callGraphNode, const SVFType *type, const ICFGNode *icn)
Add a unique return node for a procedure.
Definition SVFIR.h:696
NodeID addArgValNode(NodeID i, u32_t argNo, const ICFGNode *icfgNode, const FunObjVar *callGraphNode, const SVFType *type)
Definition SVFIR.h:572
NodeID addConstantObjNode()
Definition SVFIR.h:747
const Map< const SVFBasicBlock *, BBSet > & getDomFrontierMap() const
Set< const SVFBasicBlock * > BBSet
static double getClk(bool mark=false)
Definition SVFStat.cpp:48
static double timeOfBuildingSVFIR
Definition SVFStat.h:95
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
virtual void setName(const std::string &nameInfo)
Definition SVFValue.h:176
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:202
const ConstantExpr * isBinaryConstantExpr(const Value *val)
Definition LLVMUtil.h:290
bool isUncalledFunction(const Function *fun)
whether this is a function without any possible caller?
Definition LLVMUtil.cpp:157
double getDoubleValue(const ConstantFP *fpValue)
Definition LLVMUtil.h:54
bool isConstantObjSym(const Value *val)
Check whether this value points-to a constant object.
Definition CppUtil.cpp:672
const Value * stripAllCasts(const Value *val)
Strip off the all casts.
Definition LLVMUtil.cpp:249
const ConstantExpr * isInt2PtrConstantExpr(const Value *val)
Definition LLVMUtil.h:225
const ConstantExpr * isSelectConstantExpr(const Value *val)
Definition LLVMUtil.h:255
bool isIntrinsicFun(const Function *func)
Definition LLVMUtil.cpp:189
bool functionDoesNotRet(const Function *fun)
Definition LLVMUtil.cpp:122
const ConstantExpr * isTruncConstantExpr(const Value *val)
Definition LLVMUtil.h:265
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
Definition LLVMUtil.h:82
void getNextInsts(const Instruction *curInst, std::vector< const Instruction * > &instList)
Get the next instructions following control flow.
Definition LLVMUtil.cpp:573
const ConstantExpr * isPtr2IntConstantExpr(const Value *val)
Definition LLVMUtil.h:235
bool isHeapObj(const Value *val)
Definition LLVMUtil.cpp:682
const ConstantExpr * isUnaryConstantExpr(const Value *val)
Definition LLVMUtil.h:301
void getFunReachableBBs(const Function *svfFun, std::vector< const SVFBasicBlock * > &bbs)
Get reachable basic block from function entry.
Definition LLVMUtil.cpp:74
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition LLVMUtil.h:245
bool isExtCall(const Function *fun)
Definition LLVMUtil.cpp:383
bool basicBlockHasRetInst(const BasicBlock *bb)
Return true if the function has a return instruction.
Definition LLVMUtil.cpp:108
bool isStackObj(const Value *val)
Definition LLVMUtil.cpp:704
const ConstantExpr * isGepConstantExpr(const Value *val)
Return corresponding constant expression, otherwise return nullptr.
Definition LLVMUtil.h:215
static DataLayout * getDataLayout(Module *mod)
Definition LLVMUtil.h:313
const Function * getCallee(const CallBase *cs)
Definition LLVMUtil.h:97
const FunObjVar * getFunObjVar(const std::string &name)
Definition LLVMUtil.cpp:435
std::string dumpValue(const Value *val)
Definition LLVMUtil.cpp:600
const ConstantExpr * isCmpConstantExpr(const Value *val)
Definition LLVMUtil.h:279
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:101
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:68
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
LLVM_NODISCARD std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
Definition Casting.h:405
const Value * getVCallVtblPtr(const CallBase *cs)
Definition CppUtil.cpp:537
bool isValVtbl(const Value *val)
Definition CppUtil.cpp:336
for isBitcode
Definition BasicTypes.h:68
llvm::DataLayout DataLayout
Definition BasicTypes.h:108
llvm::GlobalVariable GlobalVariable
Definition BasicTypes.h:130
llvm::GlobalAlias GlobalAlias
Definition BasicTypes.h:128
llvm::ArrayType ArrayType
Definition BasicTypes.h:95
llvm::Type Type
Definition BasicTypes.h:83
llvm::CallBase CallBase
Definition BasicTypes.h:146
llvm::BasicBlock BasicBlock
Definition BasicTypes.h:86
llvm::UnaryOperator UnaryOperator
Definition BasicTypes.h:180
llvm::ConstantStruct ConstantStruct
Definition BasicTypes.h:106
llvm::StructType StructType
LLVM types.
Definition BasicTypes.h:94
llvm::succ_const_iterator succ_const_iterator
LLVM Iterators.
Definition BasicTypes.h:276
llvm::AllocaInst AllocaInst
Definition BasicTypes.h:150
llvm::SwitchInst SwitchInst
Definition BasicTypes.h:155
u32_t NodeID
Definition GeneralType.h:56
llvm::InvokeInst InvokeInst
Definition BasicTypes.h:163
llvm::Argument Argument
Definition BasicTypes.h:145
llvm::LoadInst LoadInst
Definition BasicTypes.h:149
s64_t APOffset
Definition GeneralType.h:60
llvm::const_pred_iterator const_pred_iterator
Definition BasicTypes.h:254
llvm::CmpInst CmpInst
Definition BasicTypes.h:159
llvm::Function Function
Definition BasicTypes.h:85
llvm::ConstantData ConstantData
Definition BasicTypes.h:116
llvm::LoopInfo LoopInfo
Definition BasicTypes.h:141
llvm::Instruction Instruction
Definition BasicTypes.h:87
llvm::Constant Constant
Definition BasicTypes.h:124
llvm::DomTreeNode DomTreeNode
Definition BasicTypes.h:134
llvm::ConstantDataSequential ConstantDataSequential
Definition BasicTypes.h:119
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:82
llvm::ConstantExpr ConstantExpr
Definition BasicTypes.h:120
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
llvm::CastInst CastInst
Definition BasicTypes.h:158
llvm::FreezeInst FreezeInst
Definition BasicTypes.h:169
llvm::Module Module
Definition BasicTypes.h:84
llvm::BinaryOperator BinaryOperator
Definition BasicTypes.h:179
llvm::PostDominatorTree PostDominatorTree
Definition BasicTypes.h:136
llvm::DominanceFrontier DominanceFrontier
Definition BasicTypes.h:135
llvm::StoreInst StoreInst
Definition BasicTypes.h:148
llvm::SelectInst SelectInst
Definition BasicTypes.h:174
llvm::VAArgInst VAArgInst
Definition BasicTypes.h:175
llvm::Loop Loop
LLVM Loop.
Definition BasicTypes.h:140
llvm::GetElementPtrInst GetElementPtrInst
Definition BasicTypes.h:162
llvm::CallBrInst CallBrInst
Definition BasicTypes.h:156
llvm::ReturnInst ReturnInst
Definition BasicTypes.h:157
llvm::PHINode PHINode
Definition BasicTypes.h:165
llvm::BranchInst BranchInst
Definition BasicTypes.h:154
llvm::ExtractValueInst ExtractValueInst
Definition BasicTypes.h:160
unsigned u32_t
Definition GeneralType.h:47
signed long long s64_t
Definition GeneralType.h:50
llvm::CallInst CallInst
Definition BasicTypes.h:147
llvm::ConstantInt ConstantInt
Definition BasicTypes.h:125
llvm::DominatorTree DominatorTree
LLVM Dominators.
Definition BasicTypes.h:133
llvm::ExtractElementInst ExtractElementInst
Definition BasicTypes.h:161
llvm::User User
Definition BasicTypes.h:142