62 if(
pag->getNodeNumAfterPAGBuild() > 1)
85 std::vector<const FunObjVar*> funset;
100 for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
105 if(!fun.isDeclaration())
112 if (fun.doesNotReturn() ==
false &&
113 fun.getReturnType()->isVoidTy() ==
false)
115 pag->addFunRet(svffun,
116 pag->getValVar(
pag->getReturnNode(svffun)));
121 for (Function::const_arg_iterator I = fun.arg_begin(), E = fun.arg_end();
133 pag->addFunArgs(svffun,
pag->getValVar(argValNodeId));
137 for (
const auto& field : returns->second)
138 pag->addFunArgs(svffun,
pag->getValVar(field.second));
140 for (Function::const_iterator bit = fun.begin(), ebit = fun.end();
144 for (BasicBlock::const_iterator it = bb.begin(), eit = bb.end();
157 pag->initialiseCandidatePointers();
159 pag->setNodeNumAfterPAGBuild(
pag->getTotalNodeNum());
163 pag->dump(
"svfir_initial");
171 pag->getICFG()->dump(
"icfg_initial");
182 assert(
false &&
"please implement SVFIRWriter::writeJsonToPath");
196 for (
const Function& f : mod.functions())
222 for (Function::const_iterator bit = func->begin(), ebit = func->end(); bit != ebit; ++bit)
244 "last inst must be return inst");
256 "last inst must be return inst");
264 if (fun->isDeclaration())
275 for (DominanceFrontierBase::const_iterator dfIter = df.begin(), eDfIter = df.end(); dfIter != eDfIter; dfIter++)
278 const llvm::SetVector<llvm::BasicBlock* >& domSet = dfIter->second;
282 valueBasicBlocks.insert(
llvmModuleSet()->getSVFBasicBlock(bbValue));
285 std::vector<const SVFBasicBlock*> reachableBBs;
289 for (Function::const_iterator bit = fun->begin(), beit = fun->end(); bit!=beit; ++bit)
296 for (
const auto domBB : *dtNode)
299 bbSet.insert(domSVFBB);
305 u32_t level = pdtNode->getLevel();
307 BasicBlock* idomBB = pdtNode->getIDom()->getBlock();
312 for (
const auto domBB : *pdtNode)
315 bbSet.insert(domSVFBB);
319 if (
const Loop* loop = loopInfo.getLoopFor(&bb))
321 for (
const BasicBlock* loopBlock : loop->getBlocks())
332 std::vector<FunObjVar*> funset;
341 pag->addFunObjNode(
id,
pag->getObjTypeInfo(
id),
nullptr);
345 funset.push_back(funObjVar);
362 for (
auto& bb: *funObjVar->
bbGraph)
364 bb.second->setFun(funObjVar);
375 for (LLVMModuleSet::ValueToIDMapTy::iterator iter =
383 if(iter->second ==
pag->blackholeSymID() || iter->second ==
pag->constantSymID())
387 const Value* llvmValue = iter->first;
405 pag->addHeapObjNode(iter->second,
pag->getObjTypeInfo(
id), icfgNode);
411 pag->addStackObjNode(iter->second,
pag->getObjTypeInfo(
id), icfgNode);
426 pag->addConstantNullPtrObjNode(iter->second,
pag->getObjTypeInfo(
id), icfgNode);
431 pag->addGlobalObjNode(iter->second,
pag->getObjTypeInfo(
id), icfgNode);
436 pag->addConstantDataObjNode(iter->second,
pag->getObjTypeInfo(
id), icfgNode);
442 pag->addObjNode(iter->second,
pag->getObjTypeInfo(
id), icfgNode);
452 for (LLVMModuleSet::ValueToIDMapTy::iterator iter =
460 if(iter->second ==
pag->blkPtrSymID() || iter->second ==
pag->nullPtrSymID())
464 auto llvmValue = iter->first;
478 iter->second, argval->getArgNo(), entryNode,
480 if (!argval->hasName())
481 pag->getGNode(iter->second)->setName(
"arg_" + std::to_string(argval->getArgNo()));
493 pag->addConstantNullPtrValNode(iter->second, icfgNode,
llvmModuleSet()->getSVFType(llvmValue->getType()));
498 pag->addGlobalValNode(iter->second,
pag->getICFG()->getGlobalICFGNode(),
503 pag->addConstantDataValNode(iter->second, icfgNode,
llvmModuleSet()->getSVFType(llvmValue->getType()));
509 pag->addAsmPCValNode(iter->second,
llvmModuleSet()->getSVFType(llvmValue->getType()));
514 pag->addIntrinsicValNode(iter->second,
llvmModuleSet()->getSVFType(llvmValue->getType()));
517 assert(
llvmModuleSet()->hasICFGNode(inst) &&
"LLVM instruction is not associated with an ICFGNode");
519 pag->addValNode(iter->second,
llvmModuleSet()->getSVFType(llvmValue->getType()), icfgNode);
523 pag->getGNode(iter->second));
536 pag->addBlackholeObjNode();
537 pag->addConstantObjNode();
538 pag->addBlackholePtrNode();
544 for (LLVMModuleSet::FunToIDMapTy::iterator iter =
548 const Value* llvmValue = iter->first;
555 pag->addRetNode(iter->second,
557 llvmModuleSet()->getSVFType(iter->first->getType()), icfgNode);
559 pag->returnFunObjSymMap[funObjVar] = iter->second;
562 for (LLVMModuleSet::FunToIDMapTy::iterator iter =
566 const Value* llvmValue = iter->first;
573 pag->addVarargNode(iter->second,
575 llvmModuleSet()->getSVFType(iter->first->getType()), icfgNode);
577 pag->varargFunObjSymMap[funObjVar] = iter->second;
581 for (LLVMModuleSet::ValueToIDMapTy::iterator iter =
584 DBOUT(
DPAGBuild,
outs() <<
"add address edges for constant node " << iter->second <<
"\n");
585 const Value* val = iter->first;
589 if(ptr!=
pag->getBlkPtr() && ptr!=
pag->getNullPtr())
597 assert(
pag->getTotalNodeNum() >=
pag->getTotalSymNum()
598 &&
"not all node have been initialized!!!");
603 for (
const Argument& arg : fun->args())
638 llvm::APInt byteOffset(dataLayout->getIndexSizeInBits(gepOp->getPointerAddressSpace()),0,
true);
639 if(gepOp && dataLayout && gepOp->accumulateConstantOffset(*dataLayout,byteOffset))
646 bool prevPtrOperand =
false;
650 const Type* gepTy = *gi;
653 assert((prevPtrOperand && svfGepTy->
isPointerTy()) ==
false &&
654 "Expect no more than one gep operand to be of a pointer type");
655 if(!prevPtrOperand && svfGepTy->
isPointerTy()) prevPtrOperand =
true;
656 const Value* offsetVal = gi.getOperand();
657 assert(gepTy != offsetVal->getType() &&
"iteration and operand have the same type?");
659 const ArrayType* inferredPtrArrayTy =
nullptr;
660 const SVFType* idxGepTy = svfGepTy;
661 if (svfGepTy->
isPointerTy() && gepOp->getSourceElementType()->isSingleValueType())
663 const Type* baseObjType =
667 if (arrTy->getElementType()->isPointerTy())
669 inferredPtrArrayTy = arrTy;
694 assert(op &&
"non-const offset accessing a struct");
700 if (rawIdx >= ST->getNumElements())
709 else if (gepTy->isSingleValueType())
711 if (inferredPtrArrayTy)
723 if(!op && gepTy->isPointerTy() && gepOp->getSourceElementType()->isSingleValueType())
750 const Constant* opnd = gepce->getOperand(0);
753 auto &GEPOp = llvm::cast<llvm::GEPOperator>(*gepce);
754 Type *pType = GEPOp.getSourceElementType();
772 const Constant* opnd = castce->getOperand(0);
784 const Constant* src1 = selectce->getOperand(1);
785 const Constant* src2 = selectce->getOperand(2);
801 const Constant* opnd = int2Ptrce->getOperand(0);
811 const Constant* opnd = ptr2Intce->getOperand(0);
867 assert(
false &&
"we don't handle all other constant expression for now!");
880 if (
offset == 0 && gvar->getInitializer()->getType()->isSingleValueType())
907 <<
" constant initializer: "
909 if (C->getType()->isSingleValueType())
941 if (C->getType()->isPtrOrPtrVectorTy() && src !=
pag->getNullPtr())
949 for (
u32_t i = 0, e = C->getNumOperands(); i != e; i++)
961 for(
u32_t i = 0; i < seq->getNumElements(); i++)
964 Constant* ct = seq->getElementAsConstant(i);
989 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
998 if (gvar->hasInitializer())
1000 Constant *C = gvar->getInitializer();
1009 for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
1015 DBOUT(
DPAGBuild,
outs() <<
"add global function node " << fun->getName().str() <<
"\n");
1021 for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; I++)
1064 for (
u32_t i = 0; i < inst.getNumIncomingValues(); ++i)
1066 const Value* val = inst.getIncomingValue(i);
1068 bool matched = (incomingInst ==
nullptr ||
1069 incomingInst->getFunction() == inst.getFunction());
1071 assert(matched &&
"incomingInst's Function incorrect");
1072 const Instruction* predInst = &inst.getIncomingBlock(i)->back();
1090 const Type* loadedTy = inst.getType();
1109 const Type* storedTy = inst.getValueOperand()->getType();
1145 const Type* baseObjType =
1149 if (arrTy->getElementType()->isPointerTy())
1169 const Value* opnd = inst.getOperand(0);
1180 assert(inst.getNumOperands() == 2 &&
"not two operands for BinaryOperator?");
1181 Value* op1 = inst.getOperand(0);
1183 Value* op2 = inst.getOperand(1);
1185 u32_t opcode = inst.getOpcode();
1195 assert(inst.getNumOperands() == 1 &&
"not one operand for Unary instruction?");
1196 Value* opnd = inst.getOperand(0);
1198 u32_t opcode = inst.getOpcode();
1208 assert(inst.getNumOperands() == 2 &&
"not two operands for compare instruction?");
1209 Value* op1 = inst.getOperand(0);
1211 Value* op2 = inst.getOperand(1);
1213 u32_t predicate = inst.getPredicate();
1214 addCmpEdge(op1Node, op2Node, dst, predicate);
1266 pag->addCallSite(callBlockNode);
1269 for (
u32_t i = 0; i < cs->arg_size(); i++)
1270 pag->addCallSiteArgs(
1274 if(!cs->getType()->isVoidTy())
1317 if(
Value* src = inst.getReturnValue())
1332 const std::vector<unsigned>& indices)
1334 for (
unsigned index : indices)
1338 if (
index >= structure->getNumElements())
1340 type = structure->getElementType(
index);
1344 if (
index >= array->getNumElements())
1346 type = array->getElementType();
1350 if (
index >= vector->getNumElements())
1352 type = vector->getElementType();
1367 if (!vector || !constant ||
1368 constant->getValue().uge(vector->getNumElements()))
1369 return std::nullopt;
1370 return static_cast<unsigned>(constant->getZExtValue());
1375 std::vector<AggregateFieldKey>& operands)
1377 const Value* value = field.first;
1385 const Value* original =
nullptr;
1386 const Value* inserted =
nullptr;
1390 original = insert->getAggregateOperand();
1391 inserted = insert->getInsertedValueOperand();
1392 insertedPath.assign(insert->idx_begin(), insert->idx_end());
1397 insert->getOperand(2));
1400 original = insert->getOperand(0);
1401 inserted = insert->getOperand(1);
1402 insertedPath = {*lane};
1407 const size_t commonLength = std::min(insertedPath.size(), path.size());
1408 if (!std::equal(insertedPath.begin(), insertedPath.begin() + commonLength, path.begin()))
1409 operands.emplace_back(original, path);
1410 else if (insertedPath.size() <= path.size())
1411 operands.emplace_back(inserted,
1419 outer.insert(outer.end(), path.begin(), path.end());
1420 operands.emplace_back(extract->getAggregateOperand(), std::move(outer));
1424 for (
const Value* incoming : phi->incoming_values())
1425 operands.emplace_back(incoming, path);
1429 if (!select->getCondition()->getType()->isIntegerTy(1))
1431 operands.emplace_back(select->getTrueValue(), path);
1432 operands.emplace_back(select->getFalseValue(), path);
1435 operands.emplace_back(freeze->getOperand(0), path);
1439 if (!vector || path.size() != 1)
1441 int index = shuffle->getMaskValue(path.front());
1444 unsigned width = vector->getNumElements();
1445 operands.emplace_back(shuffle->getOperand(
static_cast<unsigned>(
index) / width),
1450 for (
unsigned index : path)
1452 constant = constant->getAggregateElement(
index);
1461 return !operands.empty();
1481 std::vector<std::pair<AggregateFieldKey, std::vector<AggregateFieldKey>>>
1484 std::vector<AggregateFieldKey> worklist{root};
1485 while (!worklist.empty())
1488 worklist.pop_back();
1490 !discovered.insert(field).second)
1495 definitions.emplace_back(field, std::vector<AggregateFieldKey>());
1496 auto& operands = definitions.back().second;
1499 worklist.insert(worklist.end(), operands.begin(), operands.end());
1504 for (
const auto& definition : definitions)
1508 if (field.second.empty())
1526 for (
const auto& definition : definitions)
1532 const auto& operands = definition.second;
1537 for (
unsigned i = 0; i < operands.size(); ++i)
1539 llvmModuleSet()->getICFGNode(phi->getIncomingBlock(i)->getTerminator()));
1557 fun->doesNotReturn() || !fun->getReturnType()->isAggregateType() ||
1558 fun->hasAddressTaken())
1560 for (
const User* user : fun->users())
1563 if (!call || call->getCalledFunction() != fun ||
1564 call->getFunctionType() != fun->getFunctionType())
1582 auto found = demands.find(fun);
1583 if (found == demands.end())
1597 std::vector<AggregateFieldKey> worklist;
1604 worklist.push_back(std::move(*field));
1611 while (!worklist.empty())
1614 worklist.pop_back();
1615 if (!visited.insert(field).second || field.second.empty())
1619 const Function* callee = call->getCalledFunction();
1621 !demands[callee].insert(field.second).second)
1625 if (ret->getReturnValue())
1626 worklist.emplace_back(ret->getReturnValue(), field.second);
1630 std::vector<AggregateFieldKey> operands;
1632 worklist.insert(worklist.end(), operands.begin(), operands.end());
1642 const std::set<AggregateField>& fields,
const SVFType* pointerType)
1651 pag->addArgValNode(
id, svfFun->
arg_size(), entry, svfFun, pointerType);
1657 arg->setName(
"aggregate_return_" + std::to_string(arg->getArgNo()));
1658 params.emplace(field,
id);
1672 std::vector<const CallInst*> calls;
1673 for (
const User* user : fun->users())
1675 std::sort(calls.begin(), calls.end(), [
this](
const CallInst* lhs,
1678 return llvmModuleSet()->getCallICFGNode(lhs)->getId() <
1679 llvmModuleSet()->getCallICFGNode(rhs)->getId();
1686 std::vector<const Instruction*>
next;
1688 assert(
next.size() == 1 &&
"ordinary call must have one continuation");
1693 for (
const auto& param : params)
1698 NodeID object =
pag->addDummyObjNode(pointerType);
1699 pag->getAllFieldsObjVars(
object).set(
object);
1700 pag->getObjTypeInfo(
object)->setNumOfElements(1);
1701 pag->getObjTypeInfo(
object)->setByteSizeOfObj(
1707 args.emplace(param.first, address);
1710 "call field registered twice");
1736 for (
const auto& arg : found->second)
1738 pag->addCallSiteArgs(callNode,
pag->getValVar(arg.second));
1739 addCallEdge(arg.second, params.at(arg.first), callNode, entry);
1752 for (
const auto& field : found->second)
1768std::optional<SVFIRBuilder::AggregateFieldKey>
1771 if (!inst.getType()->isPointerTy())
1772 return std::nullopt;
1777 extract->getAggregateOperand(),
1782 return std::nullopt;
1784 extract->getIndexOperand());
1786 return std::nullopt;
1847 if (inst.isConditional())
1850 cond =
pag->getNullPtr();
1852 assert(inst.getNumSuccessors() <= 2 &&
"if/else has more than two branches?");
1855 std::vector<const Instruction*> nextInsts;
1860 assert(branchID <= 1 &&
"if/else has more than two branches?");
1862 successors.push_back(std::make_pair(icfgNode, 1-branchID));
1867 if (inst.isConditional())
1869 for (
auto& edge :
llvmModuleSet()->getICFGNode(&inst)->getOutEdges())
1873 intraEdge->setConditionVar(
pag->getGNode(cond));
1928 std::vector<const Instruction*> nextInsts;
1933 successors.emplace_back(
llvmModuleSet()->getICFGNode(nextInsts.front()), -1);
1944 for (
const auto& switchCase : inst.cases())
1946 const ConstantInt* condVal = switchCase.getCaseValue();
1948 if (condVal->getBitWidth() <= 64)
1951 const Instruction* succInst = nextInsts[switchCase.getSuccessorIndex()];
1953 successors.push_back(std::make_pair(icfgNode, val));
1957 for (
auto& edge :
llvmModuleSet()->getICFGNode(&inst)->getOutEdges())
1961 intraEdge->setConditionVar(
pag->getGNode(cond));
1975 Value* opnd = inst.getPointerOperand();
1987 for (
u32_t i = 0; i < inst.getNumOperands(); i++)
1989 Value* opnd = inst.getOperand(i);
2006 <<
" callee " << F->getName().str() <<
"\n");
2011 if (!cs->getType()->isVoidTy())
2015 addRetEdge(srcret, dstrec,callICFGNode, exitICFGNode);
2018 u32_t itA = 0, ieA = cs->arg_size();
2019 Function::const_arg_iterator itF = F->arg_begin(), ieF = F->arg_end();
2022 for (; itF != ieF; ++itA, ++itF)
2030 const Value* AA = cs->getArgOperand(itA), *FA = &*itF;
2045 for (; itA != ieA; ++itA)
2047 const Value* AA = cs->getArgOperand(itA);
2097 assert(value &&
"null ptr?");
2098 auto getGlobalFieldFromByteOffset =
2101 if (!glob || !glob->hasInitializer())
2106 if (!initializer || !structType)
2111 dataLayout->getStructLayout(
const_cast<StructType*
>(structType));
2112 for (
u32_t fieldIdx = 0; fieldIdx < initializer->getNumOperands(); ++fieldIdx)
2114 if (layout->getElementOffset(fieldIdx) !=
static_cast<uint64_t
>(byteOffset))
2116 if (
auto* ptrValue =
2127 for (
bridge_gep_iterator gi = bridge_gep_begin(gep), ge = bridge_gep_end(gep); gi != ge; ++gi)
2133 value = gep->getPointerOperand();
2137 const Value* loadP = load->getPointerOperand();
2141 llvm::APInt byteOffset(dataLayout->getIndexSizeInBits(gep->getPointerAddressSpace()), 0,
true);
2142 const bool hasByteOffset = dataLayout && gep->accumulateConstantOffset(*dataLayout, byteOffset);
2144 const Value * pointer_operand = gep->getPointerOperand();
2149 if (
const Value* ptrValue = getGlobalFieldFromByteOffset(glob, byteOffset.getSExtValue()))
2153 else if (hasByteOffset && !byteOffset.isNegative() &&
2157 const u64_t accessBytes = dataLayout->getPointerSize(gep->getPointerAddressSpace());
2159 auto isCoveredByMemcpy = [
offset, accessBytes](
const CallBase* cs) ->
bool
2161 if (cs->arg_size() < 3)
2170 const u64_t copyBytes = copySize->getZExtValue();
2171 return copyBytes >= accessBytes && copyBytes - accessBytes >=
offset;
2174 auto hasInterveningWrite = [load](
const Instruction* from) ->
bool
2176 if (from->getParent() != load->getParent() || !from->comesBefore(load))
2179 auto it = from->getIterator();
2180 const auto end = load->getIterator();
2183 if (it->mayWriteToMemory())
2189 for (
const auto& use : pointer_operand->users())
2192 if (!cs || cs->getParent() != load->getParent() ||
2193 cs->arg_size() < 1 ||
2197 const Function* calledFun = cs->getCalledFunction();
2199 hasInterveningWrite(cs))
2205 if (
const Value* ptrValue =
2206 getGlobalFieldFromByteOffset(copiedGlob, byteOffset.getSExtValue()))
2224 const_cast<CallICFGNode*
>(cbn)->setIndFunPtr(
pag->getGNode(indFunPtrId));
2225 pag->addIndirectCallsites(cbn,indFunPtrId);
2230 CallGraph::CallEdgeMap::const_iterator iter = callgraph->
getIndCallMap().begin();
2231 CallGraph::CallEdgeMap::const_iterator eiter = callgraph->
getIndCallMap().end();
2232 for (; iter != eiter; iter++)
2236 assert(callBlock->
isIndirectCall() &&
"this is not an indirect call?");
2238 for (CallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
2257 pag->dump(
"svfir_final");
2267 (void)
pag->getGNode(nIter->first);
2293 if (gepval==UINT_MAX)
2295 assert(((
int) UINT_MAX)==-1 &&
"maximum limit of unsigned int is not -1?");
2324 node =
pag->getICFG()->getGlobalICFGNode();
2345 if (!arrTy || !arrTy->getElementType()->isPointerTy() ||
2346 arrTy->getElementType() != accessTy)
2372 assert(
curVal &&
"current Val is nullptr?");
2375 ICFGNode* icfgNode =
pag->getICFG()->getGlobalICFGNode();
2383 assert(srcFun==llvmMS->
getFunObjVar(curInst->getFunction()) &&
"SrcNode of the PAGEdge not in the same function?");
2387 assert(dstFun==llvmMS->
getFunObjVar(curInst->getFunction()) &&
"DstNode of the PAGEdge not in the same function?");
2392 assert(
curBB &&
"instruction does not have a basic block??");
2399 icfgNode =
pag->getICFG()->getFunExitICFGNode(llvmMS->
getFunObjVar(curInst->getFunction()));
2418 icfgNode =
pag->getICFG()->getFunEntryICFGNode(
2426 pag->addGlobalPAGEdge(edge);
2434 assert(
false &&
"what else value can we have?");
2437 pag->addToSVFStmtList(icfgNode,edge);
2444 for(
u32_t i = 0; i < callPE->getOpVarNum(); i++)
2475 assert(geps.size()==1 &&
"one node can only be connected by at most one gep edge!");
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 std::optional< unsigned > getFixedVectorLane(const Type *type, const Value *index)
static bool canModelAggregateReturn(const Function *fun)
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
APOffset getConstantStructFldIdx() const
Get methods.
void setFldIdx(APOffset idx)
bool addOffsetVarAndGepTypePair(const ValVar *var, const SVFType *gepIterType)
std::vector< std::pair< const ICFGNode *, s64_t > > SuccAndCondPairVec
CallGraph * buildSVFIRCallGraph(const std::vector< const FunObjVar * > &funset)
Buidl SVFIR callgraoh.
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
Set< const FunObjVar * > FunctionSet
const std::string getSourceLoc() const override
bool isIndirectCall() const
Return true if this is an indirect call.
bool isVirtualCall() const
void setVtablePtr(SVFVar *v)
static ExtAPI * getExtAPI()
void setExtFuncAnnotations(const FunObjVar *fun, const std::vector< std::string > &funcAnnotations)
void addArgument(const ArgValVar *arg)
const SVFBasicBlock * back() const
const SVFBasicBlock * exitBlock
all formal arguments of this function
void setBasicBlockGraph(BasicBlockGraph *graph)
void setExitBlock(SVFBasicBlock *bb)
SVFLoopAndDomInfo * getLoopAndDomInfo() const
void setRelDefFun(const FunObjVar *real)
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)
bool hasBasicBlock() const
BasicBlockGraph * bbGraph
the definition of a function across multiple modules
bool isDeclaration() const
NodeType * getSrcNode() const
NodeType * getDstNode() const
IDToNodeMapTy::iterator iterator
GEdgeSetTy::iterator iterator
bool isVariantFieldGep() const
Gep statement with a variant field index (pointer arithmetic) for struct field access.
const AccessPath & getAccessPath() const
void addSVFStmt(const SVFStmt *edge)
virtual const SVFBasicBlock * getBB() const
Return the basic block of this ICFGNode.
virtual void build(ICFG *icfg)
Start from here.
bool hasValueNode(const Value *V)
NodeID getValueNode(const Value *V)
ValueToIDMapTy & valSyms()
const FunObjVar * getFunObjVar(const Function *fun) const
static LLVMModuleSet * getLLVMModuleSet()
SVFBasicBlock * getSVFBasicBlock(const BasicBlock *bb)
DominatorTree & getDomTree(const Function *fun)
void addToSVFVar2LLVMValueMap(const Value *val, SVFValue *svfBaseNode)
LLVMFun2FunObjVarMap LLVMFun2FunObjVar
Map an LLVM Function to an SVF Funobjvar.
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
NodeID getObjectNode(const Value *V)
RetICFGNode * getRetICFGNode(const Instruction *cs)
get a return node
LLVMContext & getContext() const
const Function * getRealDefFun(const Function *fun) const
ValueToIDMapTy & objSyms()
void addBasicBlock(FunObjVar *fun, const BasicBlock *bb)
FunToIDMapTy & varargSyms()
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
static Option< bool > ModelArrays
static const Option< bool > PAGDotGraph
static const Option< std::string > DumpJson
static Option< bool > ModelConsts
static const Option< bool > PAGPrint
static const Option< bool > VtableInSVFIR
static const Option< bool > LoopAnalysis
static const Option< bool > DumpICFG
void addPredBasicBlock(const SVFBasicBlock *pred2)
void addSuccBasicBlock(const SVFBasicBlock *succ2)
std::vector< const SVFBasicBlock * > getSuccessors() 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)
Map< const CallInst *, std::map< AggregateField, NodeID > > aggregateCallArgs
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)
Preserve LLVM switch destinations and case values in BranchStmt.
static std::optional< AggregateFieldKey > getExtractedField(const Instruction &inst)
Decode a pointer extraction; unsupported instructions have no field.
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 createAggregateCallSlots(const Function *fun, const SVFType *pointerType)
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 addExtractedFieldCopy(Instruction &inst)
void addCallEdge(NodeID src, NodeID dst, const CallICFGNode *cs, const FunEntryICFGNode *entry)
Add Call edge.
void setCurrentBBAndValueForPAGEdge(PAGEdge *edge)
void visitSelectInst(SelectInst &I)
AggregateReturnFields discoverAggregateReturnFields()
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
Output parameters of each modeled callee, in field-path order.
AddrStmt * addAddrWithStackArraySz(NodeID src, NodeID dst, llvm::AllocaInst &inst)
Add Address edge from allocinst with arraysize like "%4 = alloca i8, i64 3".
Map< const Function *, std::set< AggregateField > > AggregateReturnFields
Field paths extracted from each callee's returned aggregate.
NodeID getGepValVar(const Value *val, const AccessPath &ap, const SVFType *elementType)
void initialiseBaseObjVars()
void InitialGlobal(const GlobalVariable *gvar, Constant *C, u32_t offset)
void visitUnaryOperator(UnaryOperator &I)
void visitBinaryOperator(BinaryOperator &I)
void createAggregateReturnParams(const Function *fun, const std::set< AggregateField > &fields, const SVFType *pointerType)
void initialiseNodes()
Initialize nodes and edges.
NodeID getGlobalVarField(const GlobalVariable *gvar, u32_t offset, SVFType *tpy)
static bool pagReadFromTXT()
const Map< const SVFBasicBlock *, BBSet > & getPostDomTreeMap() const
const Map< const SVFBasicBlock *, BBSet > & getDomFrontierMap() const
Map< const SVFBasicBlock *, BBSet > & getDomTreeMap()
const Map< const SVFBasicBlock *, u32_t > & getBBPDomLevel() const
const Map< const SVFBasicBlock *, const SVFBasicBlock * > & getBB2PIdom() const
void setReachableBBs(BBList &bbs)
Set< const SVFBasicBlock * > BBSet
void addToBB2LoopMap(const SVFBasicBlock *bb, const SVFBasicBlock *loopBB)
static double getClk(bool mark=false)
static double timeOfBuildingSVFIR
void setBB(const SVFBasicBlock *bb)
void setValue(const SVFVar *val)
Get/set methods for llvm instruction.
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
u32_t getByteSize() const
SVFStmt::SVFStmtSetTy & getIncomingEdges(SVFStmt::PEDGEK kind)
Edge accessors and checkers.
virtual const FunObjVar * getFunction() const
Get containing function, or null for globals/constants.
bool isIntrinsicInst(const Instruction *inst)
Return true if it is an intrinsic instruction.
const ConstantExpr * isBinaryConstantExpr(const Value *val)
bool isUncalledFunction(const Function *fun)
whether this is a function without any possible caller?
double getDoubleValue(const ConstantFP *fpValue)
bool isConstantObjSym(const Value *val)
Check whether this value points-to a constant object.
const Value * stripAllCasts(const Value *val)
Strip off the all casts.
const ConstantExpr * isInt2PtrConstantExpr(const Value *val)
const ConstantExpr * isSelectConstantExpr(const Value *val)
bool isMemcpyExtFun(const Function *fun)
bool isIntrinsicFun(const Function *func)
bool functionDoesNotRet(const Function *fun)
const ConstantExpr * isTruncConstantExpr(const Value *val)
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
void getNextInsts(const Instruction *curInst, std::vector< const Instruction * > &instList)
Get the next instructions following control flow.
const ConstantExpr * isPtr2IntConstantExpr(const Value *val)
bool isHeapObj(const Value *val)
const ConstantExpr * isUnaryConstantExpr(const Value *val)
void getFunReachableBBs(const Function *svfFun, std::vector< const SVFBasicBlock * > &bbs)
Get reachable basic block from function entry.
const ConstantExpr * isCastConstantExpr(const Value *val)
bool isExtCall(const Function *fun)
bool basicBlockHasRetInst(const BasicBlock *bb)
Return true if the function has a return instruction.
bool isStackObj(const Value *val)
const ConstantExpr * isGepConstantExpr(const Value *val)
Return corresponding constant expression, otherwise return nullptr.
static DataLayout * getDataLayout(Module *mod)
const Function * getCallee(const CallBase *cs)
const FunObjVar * getFunObjVar(const std::string &name)
std::string dumpValue(const Value *val)
const ConstantExpr * isCmpConstantExpr(const Value *val)
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > cast(const Y &Val)
LLVM_NODISCARD bool isa(const Y &Val)
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
std::ostream & outs()
Overwrite llvm::outs().
LLVM_NODISCARD std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
const Value * getVCallVtblPtr(const CallBase *cs)
bool isValVtbl(const Value *val)
A carefully crafted input such as FakeVTable _ZTV1A = {{nullptr, nullptr}}; can forge a vtable; detec...
llvm::DataLayout DataLayout
llvm::GlobalVariable GlobalVariable
llvm::GlobalAlias GlobalAlias
llvm::const_succ_iterator succ_const_iterator
LLVM Iterators.
llvm::ArrayType ArrayType
llvm::BasicBlock BasicBlock
llvm::UnaryOperator UnaryOperator
llvm::StructType StructType
LLVM types.
llvm::bridge_gep_iterator bridge_gep_iterator
llvm::AllocaInst AllocaInst
llvm::SwitchInst SwitchInst
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
llvm::StructLayout StructLayout
llvm::InvokeInst InvokeInst
llvm::const_pred_iterator const_pred_iterator
llvm::ConstantData ConstantData
llvm::Instruction Instruction
llvm::DomTreeNode DomTreeNode
llvm::ConstantDataSequential ConstantDataSequential
llvm::Value Value
LLVM Basic classes.
llvm::ConstantExpr ConstantExpr
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
llvm::FreezeInst FreezeInst
llvm::BinaryOperator BinaryOperator
llvm::PostDominatorTree PostDominatorTree
llvm::DominanceFrontier DominanceFrontier
llvm::StoreInst StoreInst
llvm::SelectInst SelectInst
llvm::VAArgInst VAArgInst
llvm::Loop Loop
LLVM Loop.
llvm::GetElementPtrInst GetElementPtrInst
llvm::CallBrInst CallBrInst
llvm::ReturnInst ReturnInst
llvm::BranchInst BranchInst
llvm::ExtractValueInst ExtractValueInst
llvm::ConstantInt ConstantInt
llvm::DominatorTree DominatorTree
LLVM Dominators.
llvm::ExtractElementInst ExtractElementInst