diff --git a/svf-llvm/include/SVF-LLVM/LLVMModule.h b/svf-llvm/include/SVF-LLVM/LLVMModule.h index 718a442e59..98f046729a 100644 --- a/svf-llvm/include/SVF-LLVM/LLVMModule.h +++ b/svf-llvm/include/SVF-LLVM/LLVMModule.h @@ -50,10 +50,9 @@ class LLVMModuleSet public: typedef std::vector FunctionSetType; - typedef Map FunDeclToDefMapTy; - typedef Map FunDefToDeclsMapTy; typedef Map GlobalDefToRepMapTy; + typedef Map CGN2SVFFunMap; typedef Map LLVMFun2SVFFunMap; typedef Map LLVMFun2CallGraphNodeMap; typedef Map LLVMBB2SVFBBMap; @@ -113,6 +112,7 @@ class LLVMModuleSet FunToFunEntryNodeMapTy FunToFunEntryNodeMap; ///< map a function to its FunExitICFGNode FunToFunExitNodeMapTy FunToFunExitNodeMap; ///< map a function to its FunEntryICFGNode CallGraph* callgraph; + CGN2SVFFunMap CallGraphNode2SVFFunMap; Map FunToDominatorTree; @@ -218,7 +218,7 @@ class LLVMModuleSet setValueAttr(func,svfFunc); } - void addFunctionMap(const Function* func, CallGraphNode* svfFunc); + void addFunctionMap(const Function* func, CallGraphNode* node); // create a SVFBasicBlock according to LLVM BasicBlock, then add it to SVFFunction's BasicBlockGraph inline void addBasicBlock(SVFFunction* fun, const BasicBlock* bb) @@ -366,6 +366,22 @@ class LLVMModuleSet return nullptr; } + inline const CallGraphNode* getFunctionNode(const std::string& name) + { + Function* fun = nullptr; + + for (u32_t i = 0; i < llvmModuleSet->getModuleNum(); ++i) + { + Module* mod = llvmModuleSet->getModule(i); + fun = mod->getFunction(name); + if (fun) + { + return llvmModuleSet->getCallGraphNode(fun); + } + } + return nullptr; + } + ICFGNode* getICFGNode(const Instruction* inst); bool hasICFGNode(const Instruction* inst); diff --git a/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h b/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h index bdf2dac5ed..f5c38b45a1 100644 --- a/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +++ b/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h @@ -102,13 +102,13 @@ class SVFIRBuilder: public llvm::InstVisitor } /// getReturnNode - Return the node representing the unique return value of a function. - inline NodeID getReturnNode(const SVFFunction *func) + inline NodeID getReturnNode(const CallGraphNode *func) { return pag->getReturnNode(func); } /// getVarargNode - Return the node representing the unique variadic argument of a function. - inline NodeID getVarargNode(const SVFFunction *func) + inline NodeID getVarargNode(const CallGraphNode *func) { return pag->getVarargNode(func); } @@ -234,7 +234,7 @@ class SVFIRBuilder: public llvm::InstVisitor //@{ virtual const Type *getBaseTypeAndFlattenedFields(const Value *V, std::vector &fields, const Value* szValue); virtual void addComplexConsForExt(Value *D, Value *S, const Value* sz); - virtual void handleExtCall(const CallBase* cs, const SVFFunction* svfCallee); + virtual void handleExtCall(const CallBase* cs, const CallGraphNode* svfCallee); //@} /// Set current basic block in order to keep track of control flow information diff --git a/svf-llvm/lib/CHGBuilder.cpp b/svf-llvm/lib/CHGBuilder.cpp index 25505e944e..11c8e1b9cd 100644 --- a/svf-llvm/lib/CHGBuilder.cpp +++ b/svf-llvm/lib/CHGBuilder.cpp @@ -539,7 +539,7 @@ void CHGBuilder::analyzeVTables(const Module &M) { for (int i = 0; i < null_ptr_num; ++i) { - const SVFFunction* fun = virtualFunctions[i]; + const CallGraphNode* fun = virtualFunctions[i]; virtualFunctions.insert(virtualFunctions.begin(), fun); } } @@ -607,7 +607,7 @@ void CHGBuilder::buildVirtualFunctionToIDMap() /* * get all virtual functions in a specific group */ - set virtualFunctions; + set virtualFunctions; for (CHGraph::CHNodeSetTy::iterator it = group.begin(), eit = group.end(); it != eit; ++it) { @@ -615,7 +615,7 @@ void CHGBuilder::buildVirtualFunctionToIDMap() for (vector::const_iterator vit = vecs.begin(), veit = vecs.end(); vit != veit; ++vit) { - for (vector::const_iterator fit = (*vit).begin(), + for (vector::const_iterator fit = (*vit).begin(), feit = (*vit).end(); fit != feit; ++fit) { virtualFunctions.insert(*fit); @@ -638,15 +638,15 @@ void CHGBuilder::buildVirtualFunctionToIDMap() * <~C, C::~C> * ... */ - set > fNameSet; - for (set::iterator fit = virtualFunctions.begin(), + set > fNameSet; + for (set::iterator fit = virtualFunctions.begin(), feit = virtualFunctions.end(); fit != feit; ++fit) { - const SVFFunction* f = *fit; + const CallGraphNode* f = *fit; struct DemangledName dname = demangle(f->getName()); - fNameSet.insert(pair(dname.funcName, f)); + fNameSet.insert(pair(dname.funcName, f)); } - for (set>::iterator it = fNameSet.begin(), + for (set>::iterator it = fNameSet.begin(), eit = fNameSet.end(); it != eit; ++it) { chg->virtualFunctionToIDMap[it->second] = chg->vfID++; @@ -742,15 +742,15 @@ void CHGBuilder::addFuncToFuncVector(CHNode::FuncVector &v, const Function *lf) { if (const auto* tf = cppUtil::getThunkTarget(lf)) { - SVFFunction* pFunction = - llvmModuleSet()->getSVFFunction(tf); + CallGraphNode* pFunction = + llvmModuleSet()->getCallGraphNode(tf); v.push_back(pFunction); } } else { - SVFFunction* pFunction = - llvmModuleSet()->getSVFFunction(lf); + CallGraphNode* pFunction = + llvmModuleSet()->getCallGraphNode(lf); v.push_back(pFunction); } } diff --git a/svf-llvm/lib/DCHG.cpp b/svf-llvm/lib/DCHG.cpp index e4f1fa9d57..1fbad8262a 100644 --- a/svf-llvm/lib/DCHG.cpp +++ b/svf-llvm/lib/DCHG.cpp @@ -640,7 +640,7 @@ void DCHGraph::getVFnsFromVtbls(const CallICFGNode* callsite, const VTableSet &v */ if (funName.size() == 0) { - virtualFunctions.insert(LLVMUtil::getFunction(callee->getName().str())); + virtualFunctions.insert(LLVMUtil::getFunction(callee->getName().str())->getCallGraphNode()); } else if (funName[0] == '~') { @@ -656,7 +656,7 @@ void DCHGraph::getVFnsFromVtbls(const CallICFGNode* callsite, const VTableSet &v */ if (calleeName[0] == '~') { - virtualFunctions.insert(LLVMUtil::getFunction(callee->getName().str())); + virtualFunctions.insert(LLVMUtil::getFunction(callee->getName().str())->getCallGraphNode()); } } else @@ -667,7 +667,7 @@ void DCHGraph::getVFnsFromVtbls(const CallICFGNode* callsite, const VTableSet &v */ if (funName.compare(calleeName) == 0) { - virtualFunctions.insert(LLVMUtil::getFunction(callee->getName().str())); + virtualFunctions.insert(LLVMUtil::getFunction(callee->getName().str())->getCallGraphNode()); } } } diff --git a/svf-llvm/lib/ICFGBuilder.cpp b/svf-llvm/lib/ICFGBuilder.cpp index 9ad6ac6c7a..0b2a27cee4 100644 --- a/svf-llvm/lib/ICFGBuilder.cpp +++ b/svf-llvm/lib/ICFGBuilder.cpp @@ -241,16 +241,11 @@ InterICFGNode* ICFGBuilder::addInterBlockICFGNode(const Instruction* inst) assert(llvmModuleSet()->getCallBlock(inst)==nullptr && "duplicate CallICFGNode"); const CallBase* cb = SVFUtil::dyn_cast(inst); bool isvcall = cppUtil::isVirtualCallSite(cb); - SVFFunction* calledFunc = nullptr; + const CallGraphNode* calledFunc = nullptr; auto called_llvmval = cb->getCalledOperand()->stripPointerCasts(); if (const Function* called_llvmfunc = SVFUtil::dyn_cast(called_llvmval)) { - calledFunc = llvmModuleSet()->getSVFFunction(called_llvmfunc); - } - else - { - calledFunc = SVFUtil::dyn_cast( - llvmModuleSet()->getSVFValue(called_llvmval)); + calledFunc = llvmModuleSet()->getCallGraphNode(called_llvmfunc); } SVFBasicBlock* bb = llvmModuleSet()->getSVFBasicBlock(inst->getParent()); @@ -282,8 +277,8 @@ void ICFGBuilder::addICFGInterEdges(const Instruction* cs, const Function* calle /// direct call if(callee) { - SVFFunction* svfFun = - llvmModuleSet()->getSVFFunction(callee); + CallGraphNode* svfFun = + llvmModuleSet()->getCallGraphNode(callee); /// if this is an external function (no function body) if (SVFUtil::isExtCall(svfFun)) { @@ -352,11 +347,11 @@ IntraICFGNode* ICFGBuilder::addIntraBlockICFGNode(const Instruction* inst) FunEntryICFGNode* ICFGBuilder::addFunEntryBlock(const Function* fun) { return llvmModuleSet()->FunToFunEntryNodeMap[fun] = - icfg->addFunEntryICFGNode(llvmModuleSet()->getSVFFunction(fun)); + icfg->addFunEntryICFGNode(llvmModuleSet()->getCallGraphNode(fun)); } inline FunExitICFGNode* ICFGBuilder::addFunExitBlock(const Function* fun) { return llvmModuleSet()->FunToFunExitNodeMap[fun] = - icfg->addFunExitICFGNode(llvmModuleSet()->getSVFFunction(fun)); + icfg->addFunExitICFGNode(llvmModuleSet()->getCallGraphNode(fun)); } \ No newline at end of file diff --git a/svf-llvm/lib/LLVMLoopAnalysis.cpp b/svf-llvm/lib/LLVMLoopAnalysis.cpp index c2a9d842e7..4136bb4815 100644 --- a/svf-llvm/lib/LLVMLoopAnalysis.cpp +++ b/svf-llvm/lib/LLVMLoopAnalysis.cpp @@ -54,7 +54,7 @@ void LLVMLoopAnalysis::buildLLVMLoops(SVFModule *mod, ICFG* icfg) for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F) { const Function* func = &*F; - const SVFFunction* svffun = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(func); + const CallGraphNode* svffun = LLVMModuleSet::getLLVMModuleSet()->getCallGraphNode(func); if (func->isDeclaration()) continue; // do not analyze external call if (SVFUtil::isExtCall(svffun)) continue; diff --git a/svf-llvm/lib/LLVMModule.cpp b/svf-llvm/lib/LLVMModule.cpp index 5c4a719ddc..d61f69574e 100644 --- a/svf-llvm/lib/LLVMModule.cpp +++ b/svf-llvm/lib/LLVMModule.cpp @@ -91,6 +91,11 @@ LLVMModuleSet::~LLVMModuleSet() item.second = nullptr; } + for (auto& item : CallGraphNode2SVFFunMap){ + delete item.second; + } + + for (auto& item: LLVMArgument2SVFArgument) { delete item.second; @@ -182,27 +187,39 @@ void LLVMModuleSet::build() if (Options::SVFMain()) addSVFMain(); + CallGraphBuilder callGraphBuilder; + callgraph = callGraphBuilder.createSVFIRCallGraph(); + createSVFDataStructure(); initSVFFunction(); + for (auto& item : CallGraphNode2SVFFunMap) + { + CallGraphNode* callNode = const_cast(item.first); + SVFFunction* fun = item.second; + callNode->init(fun->getFunctionType(), + fun->isUncalledFunction(), + !(fun->hasReturn()), + fun->isDeclaration(), + fun->isIntrinsic(), + fun->hasAddressTaken(), + fun->isVarArg(), + fun->getLoopAndDomInfo(), + const_cast(fun->getDefFunForMultipleModule()->getCallGraphNode()), + const_cast(fun->getBasicBlockGraph()), + fun->getArgsList(), + fun->hasBasicBlock()? const_cast(fun->getExitBB()) : nullptr + ); + } ICFGBuilder icfgbuilder; icfg = icfgbuilder.build(); - CallGraphBuilder callGraphBuilder; - callgraph = callGraphBuilder.buildSVFIRCallGraph(svfModule); - for (const auto& func : svfModule->getFunctionSet()) - { - SVFFunction* svffunc = const_cast(func); - svffunc->setCallGraphNode(callgraph->getCallGraphNode(func)); - } - for (const auto& it : *callgraph) - { - addFunctionMap( - SVFUtil::cast(getLLVMValue(it.second->getFunction())), - it.second); - } + + callGraphBuilder.addSVFIRCallGraphEdges(callgraph); + + } void LLVMModuleSet::createSVFDataStructure() @@ -242,8 +259,8 @@ void LLVMModuleSet::createSVFDataStructure() // Store annotations of functions in extapi.bc for (const auto& pair : ExtFun2Annotations) { - const SVFFunction* svffun = getSVFFunction(pair.first); - ExtAPI::getExtAPI()->setExtFuncAnnotations(svffun, pair.second); + const CallGraphNode* funNode = getFunctionNode(pair.first); + ExtAPI::getExtAPI()->setExtFuncAnnotations(funNode, pair.second); } /// then traverse candidate sets @@ -286,10 +303,19 @@ void LLVMModuleSet::createSVFFunction(const Function* func) getSVFType(func->getFunctionType())), func->isDeclaration(), LLVMUtil::isIntrinsicFun(func), func->hasAddressTaken(), func->isVarArg(), new SVFLoopAndDomInfo); - BasicBlockGraph* bbGraph = new BasicBlockGraph(svfFunc); + CallGraphNode* funcNode = callgraph->addCallGraphNode(getSVFType(func->getType()), + SVFUtil::cast( + getSVFType(func->getFunctionType())), + func->isDeclaration(), LLVMUtil::isIntrinsicFun(func), + func->hasAddressTaken(), func->isVarArg(), nullptr); + svfFunc->setCallGraphNode(funcNode); + BasicBlockGraph* bbGraph = new BasicBlockGraph(funcNode); svfFunc->setBasicBlockGraph(bbGraph); - svfModule->addFunctionSet(svfFunc); + svfModule->addFunctionSet(funcNode); + addFunctionMap(func, funcNode); addFunctionMap(func, svfFunc); + CallGraphNode2SVFFunMap[funcNode] = svfFunc; + for (const Argument& arg : func->args()) { @@ -339,7 +365,7 @@ void LLVMModuleSet::initSVFFunction() SVFFunction* svffun = getSVFFunction(&f); initSVFBasicBlock(&f); - if (!SVFUtil::isExtCall(svffun)) + if (!SVFUtil::isExtCall(svffun->getCallGraphNode())) { initDomTree(svffun, &f); } @@ -1294,10 +1320,10 @@ void LLVMModuleSet::dumpSymTable() SVFUtil::outs() << "}\n"; } -void LLVMModuleSet::addFunctionMap(const Function* func, CallGraphNode* svfFunc) +void LLVMModuleSet::addFunctionMap(const Function* func, CallGraphNode* node) { - LLVMFunc2CallGraphNode[func] = svfFunc; - addToSVFVar2LLVMValueMap(func, svfFunc); + LLVMFunc2CallGraphNode[func] = node; + addToSVFVar2LLVMValueMap(func, node); } void LLVMModuleSet::setValueAttr(const Value* val, SVFValue* svfvalue) diff --git a/svf-llvm/lib/LLVMUtil.cpp b/svf-llvm/lib/LLVMUtil.cpp index 4f46278a63..717f65452c 100644 --- a/svf-llvm/lib/LLVMUtil.cpp +++ b/svf-llvm/lib/LLVMUtil.cpp @@ -73,7 +73,7 @@ bool LLVMUtil::isObject(const Value* ref) */ void LLVMUtil::getFunReachableBBs (const Function* fun, std::vector &reachableBBs) { - assert(!SVFUtil::isExtCall(LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(fun)) && "The calling function cannot be an external function."); + assert(!SVFUtil::isExtCall(LLVMModuleSet::getLLVMModuleSet()->getCallGraphNode(fun)) && "The calling function cannot be an external function."); //initial DominatorTree DominatorTree& dt = LLVMModuleSet::getLLVMModuleSet()->getDomTree(fun); @@ -121,8 +121,8 @@ bool LLVMUtil::basicBlockHasRetInst(const BasicBlock* bb) */ bool LLVMUtil::functionDoesNotRet(const Function* fun) { - const SVFFunction* svffun = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(fun); - if (SVFUtil::isExtCall(svffun)) + const CallGraphNode* cgn = LLVMModuleSet::getLLVMModuleSet()->getCallGraphNode(fun); + if (SVFUtil::isExtCall(cgn)) { return fun->getReturnType()->isVoidTy(); } @@ -623,8 +623,8 @@ bool LLVMUtil::isHeapAllocExtCallViaRet(const Instruction* inst) { const Function* fun = call->getCalledFunction(); return fun && isPtrTy && - (extApi->is_alloc(pSet->getSVFFunction(fun)) || - extApi->is_realloc(pSet->getSVFFunction(fun))); + (extApi->is_alloc(pSet->getCallGraphNode(fun)) || + extApi->is_realloc(pSet->getCallGraphNode(fun))); } else return false; @@ -637,7 +637,7 @@ bool LLVMUtil::isHeapAllocExtCallViaArg(const Instruction* inst) const Function* fun = call->getCalledFunction(); return fun && ExtAPI::getExtAPI()->is_arg_alloc( - LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(fun)); + LLVMModuleSet::getLLVMModuleSet()->getCallGraphNode(fun)); } else { @@ -654,7 +654,7 @@ bool LLVMUtil::isStackAllocExtCallViaRet(const Instruction *inst) { const Function* fun = call->getCalledFunction(); return fun && isPtrTy && - extApi->is_alloc_stack_ret(pSet->getSVFFunction(fun)); + extApi->is_alloc_stack_ret(pSet->getCallGraphNode(fun)); } else return false; @@ -757,7 +757,7 @@ const std::string SVFBaseNode::valueOnlyToString() const llvm::raw_string_ostream rawstr(str); if (const SVF::PTACallGraphNode* fun = SVFUtil::dyn_cast(this)) { - rawstr << "Function: " << fun->getFunction()->getName() << " "; + rawstr << "Function: " << fun->getCallGraphNode()->getName() << " "; } else { diff --git a/svf-llvm/lib/SVFIRBuilder.cpp b/svf-llvm/lib/SVFIRBuilder.cpp index 3c31a16224..5b5e4cb9d3 100644 --- a/svf-llvm/lib/SVFIRBuilder.cpp +++ b/svf-llvm/lib/SVFIRBuilder.cpp @@ -96,7 +96,7 @@ SVFIR* SVFIRBuilder::build() for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F) { const Function& fun = *F; - const SVFFunction* svffun = llvmModuleSet()->getSVFFunction(&fun); + const CallGraphNode* cgn = llvmModuleSet()->getCallGraphNode(&fun); /// collect return node of function fun if(!fun.isDeclaration()) { @@ -108,8 +108,8 @@ SVFIR* SVFIRBuilder::build() if (fun.doesNotReturn() == false && fun.getReturnType()->isVoidTy() == false) { - pag->addFunRet(svffun, - pag->getGNode(pag->getReturnNode(svffun))); + pag->addFunRet(cgn, + pag->getGNode(pag->getReturnNode(cgn))); } /// To be noted, we do not record arguments which are in declared function without body @@ -126,7 +126,7 @@ SVFIR* SVFIRBuilder::build() // if(I->getType()->isPointerTy()) // addBlackHoleAddrEdge(argValNodeId); //} - pag->addFunArgs(svffun,pag->getGNode(argValNodeId)); + pag->addFunArgs(cgn,pag->getGNode(argValNodeId)); } } for (Function::const_iterator bit = fun.begin(), ebit = fun.end(); @@ -291,7 +291,7 @@ void SVFIRBuilder::initialiseNodes() // Check if the value is a function and add a function object node if (const Function* func = SVFUtil::dyn_cast(llvmValue)) { - NodeID id = llvmModuleSet()->getObjectNode(llvmModuleSet()->getCallGraphNode(func)->getFunction()); + NodeID id = llvmModuleSet()->getObjectNode(llvmModuleSet()->getSVFValue(func)); pag->addFunObjNode(iter->second, pag->getObjTypeInfo(id), llvmModuleSet()->getCallGraphNode(func), iter->first->getType(), icfgNode); } // Check if the value is a heap object and add a heap object node @@ -410,7 +410,7 @@ void SVFIRBuilder::initialiseNodes() const Function* llvmFun = SVFUtil::cast(llvmModuleSet()->getLLVMValue(fun)); for (const Argument& arg : llvmFun->args()) { - const_cast(fun)->addArgument( + fun->addArgument( SVFUtil::cast( pag->getGNode(llvmModuleSet()->getValueNode(llvmModuleSet()->getSVFArgument(&arg))))); } @@ -1023,10 +1023,10 @@ void SVFIRBuilder::visitCallSite(CallBase* cs) } if (const Function *callee = LLVMUtil::getCallee(cs)) { - const SVFFunction* svfcallee = llvmModuleSet()->getSVFFunction(callee); - if (isExtCall(svfcallee)) + const CallGraphNode* calleeNode = llvmModuleSet()->getCallGraphNode(callee); + if (isExtCall(calleeNode)) { - handleExtCall(cs, svfcallee); + handleExtCall(cs, calleeNode); } else { @@ -1053,7 +1053,7 @@ void SVFIRBuilder::visitReturnInst(ReturnInst &inst) if(Value* src = inst.getReturnValue()) { - const SVFFunction *F = llvmModuleSet()->getSVFFunction(inst.getParent()->getParent()); + const CallGraphNode *F = llvmModuleSet()->getCallGraphNode(inst.getParent()->getParent()); NodeID rnF = getReturnNode(F); NodeID vnS = getValueNode(src); @@ -1246,7 +1246,7 @@ void SVFIRBuilder::handleDirectCall(CallBase* cs, const Function *F) assert(F); CallICFGNode* callICFGNode = llvmModuleSet()->getCallICFGNode(cs); - const SVFFunction* svffun = llvmModuleSet()->getSVFFunction(F); + const CallGraphNode* cgn = llvmModuleSet()->getCallGraphNode(F); DBOUT(DPAGBuild, outs() << "handle direct call " << LLVMUtil::dumpValue(cs) << " callee " << F->getName().str() << "\n"); @@ -1255,8 +1255,8 @@ void SVFIRBuilder::handleDirectCall(CallBase* cs, const Function *F) //Does it actually return a ptr? if (!cs->getType()->isVoidTy()) { - NodeID srcret = getReturnNode(svffun); - FunExitICFGNode* exitICFGNode = pag->getICFG()->getFunExitICFGNode(svffun); + NodeID srcret = getReturnNode(cgn); + FunExitICFGNode* exitICFGNode = pag->getICFG()->getFunExitICFGNode(cgn); addRetEdge(srcret, dstrec,callICFGNode, exitICFGNode); } //Iterators for the actual and formal parameters @@ -1278,19 +1278,19 @@ void SVFIRBuilder::handleDirectCall(CallBase* cs, const Function *F) NodeID dstFA = getValueNode(FA); NodeID srcAA = getValueNode(AA); - FunEntryICFGNode* entry = pag->getICFG()->getFunEntryICFGNode(svffun); + FunEntryICFGNode* entry = pag->getICFG()->getFunEntryICFGNode(cgn); addCallEdge(srcAA, dstFA, callICFGNode, entry); } //Any remaining actual args must be varargs. if (F->isVarArg()) { - NodeID vaF = getVarargNode(svffun); + NodeID vaF = getVarargNode(cgn); DBOUT(DPAGBuild, outs() << "\n varargs:"); for (; itA != ieA; ++itA) { const Value* AA = cs->getArgOperand(itA); NodeID vnAA = getValueNode(AA); - FunEntryICFGNode* entry = pag->getICFG()->getFunEntryICFGNode(svffun); + FunEntryICFGNode* entry = pag->getICFG()->getFunEntryICFGNode(cgn); addCallEdge(vnAA,vaF, callICFGNode,entry); } } @@ -1350,7 +1350,7 @@ void SVFIRBuilder::updateCallGraph(PTACallGraph* callgraph) if (isExtCall(*func_iter)) { setCurrentLocation(callee, callee->empty() ? nullptr : &callee->getEntryBlock()); - const SVFFunction* svfcallee = llvmModuleSet()->getSVFFunction(callee); + const CallGraphNode* svfcallee = llvmModuleSet()->getCallGraphNode(callee); handleExtCall(callbase, svfcallee); } else @@ -1461,8 +1461,8 @@ void SVFIRBuilder::setCurrentBBAndValueForPAGEdge(PAGEdge* edge) LLVMModuleSet* llvmMS = llvmModuleSet(); if (const SVFInstruction* curInst = SVFUtil::dyn_cast(curVal)) { - const SVFFunction* srcFun = edge->getSrcNode()->getFunction(); - const SVFFunction* dstFun = edge->getDstNode()->getFunction(); + const CallGraphNode* srcFun = edge->getSrcNode()->getFunction(); + const CallGraphNode* dstFun = edge->getDstNode()->getFunction(); if(srcFun!=nullptr && !SVFUtil::isa(edge) && !SVFUtil::isa(edge->getSrcNode()) && !SVFUtil::isa(edge->getSrcNode())) { assert(srcFun==curInst->getFunction() && "SrcNode of the PAGEdge not in the same function?"); @@ -1492,7 +1492,7 @@ void SVFIRBuilder::setCurrentBBAndValueForPAGEdge(PAGEdge* edge) else if (const SVFArgument* arg = SVFUtil::dyn_cast(curVal)) { assert(curBB && (curBB->getParent()->getEntryBlock() == curBB)); - icfgNode = pag->getICFG()->getFunEntryICFGNode(arg->getParent()); + icfgNode = pag->getICFG()->getFunEntryICFGNode(arg->getParent()->getCallGraphNode()); } else if (SVFUtil::isa(curVal) || SVFUtil::isa(curVal) || diff --git a/svf-llvm/lib/SVFIRExtAPI.cpp b/svf-llvm/lib/SVFIRExtAPI.cpp index 2141c4d0b9..dd1a7fa7ce 100644 --- a/svf-llvm/lib/SVFIRExtAPI.cpp +++ b/svf-llvm/lib/SVFIRExtAPI.cpp @@ -126,7 +126,7 @@ void SVFIRBuilder::addComplexConsForExt(Value *D, Value *S, const Value* szValue } } -void SVFIRBuilder::handleExtCall(const CallBase* cs, const SVFFunction* svfCallee) +void SVFIRBuilder::handleExtCall(const CallBase* cs, const CallGraphNode* svfCallee) { const SVFInstruction* svfInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(cs); const SVFCallInst* svfCall = SVFUtil::cast(svfInst); @@ -264,7 +264,7 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const SVFFunction* svfCalle const ValVar* valVar = getForkedFun(callICFGNode); if (const FunValVar* funcValVar = SVFUtil::dyn_cast(valVar)) { - const SVFFunction* forkedFun = funcValVar->getCallGraphNode()->getFunction() + const CallGraphNode* forkedFun = funcValVar->getCallGraphNode() ->getDefFunForMultipleModule(); const SVFVar* actualParm = getActualParmAtForkSite(callICFGNode); /// pthread_create has 1 arg. diff --git a/svf-llvm/lib/SymbolTableBuilder.cpp b/svf-llvm/lib/SymbolTableBuilder.cpp index 54dc2e630c..c089e335c4 100644 --- a/svf-llvm/lib/SymbolTableBuilder.cpp +++ b/svf-llvm/lib/SymbolTableBuilder.cpp @@ -352,8 +352,8 @@ void SymbolTableBuilder::collectObj(const Value* val) */ void SymbolTableBuilder::collectRet(const Function* val) { - const SVFFunction* svffun = - llvmModuleSet()->getSVFFunction(val); + const CallGraphNode* svffun = + llvmModuleSet()->getCallGraphNode(val); IRGraph::FunToIDMapTy::iterator iter = svfir->returnSymMap.find(svffun); if (iter == svfir->returnSymMap.end()) @@ -369,8 +369,8 @@ void SymbolTableBuilder::collectRet(const Function* val) */ void SymbolTableBuilder::collectVararg(const Function* val) { - const SVFFunction* svffun = - llvmModuleSet()->getSVFFunction(val); + const CallGraphNode* svffun = + llvmModuleSet()->getCallGraphNode(val); IRGraph::FunToIDMapTy::iterator iter = svfir->varargSymMap.find(svffun); if (iter == svfir->varargSymMap.end()) @@ -607,7 +607,7 @@ const Type* SymbolTableBuilder::inferTypeOfHeapObjOrStaticObj(const Instruction else if(LLVMUtil::isHeapAllocExtCallViaArg(inst)) { const CallBase* cs = LLVMUtil::getLLVMCallSite(inst); - u32_t arg_pos = SVFUtil::getHeapAllocHoldingArgPosition(SVFUtil::cast(svfinst)->getCalledFunction()); + u32_t arg_pos = SVFUtil::getHeapAllocHoldingArgPosition(SVFUtil::cast(svfinst)->getCalledFunction()->getCallGraphNode()); const Value* arg = cs->getArgOperand(arg_pos); originalPType = SVFUtil::dyn_cast(arg->getType()); inferedType = inferObjType(startValue = arg); @@ -747,7 +747,7 @@ u32_t SymbolTableBuilder::analyzeHeapAllocByteSize(const Value* val) calledFunction); std::vector args; // Heap alloc functions have annoation like "AllocSize:Arg1" - for (std::string annotation : ExtAPI::getExtAPI()->getExtFuncAnnotations(svfFunction)) + for (std::string annotation : ExtAPI::getExtAPI()->getExtFuncAnnotations(svfFunction->getCallGraphNode())) { if (annotation.find("AllocSize:") != std::string::npos) { diff --git a/svf/include/CFL/CFLAlias.h b/svf/include/CFL/CFLAlias.h index c349e29461..522378bbb2 100644 --- a/svf/include/CFL/CFLAlias.h +++ b/svf/include/CFL/CFLAlias.h @@ -135,7 +135,7 @@ class CFLAlias : public CFLBase virtual void onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites, CallEdgeMap& newEdges); /// Connect formal and actual parameters for indirect callsites - void connectCaller2CalleeParams(const CallICFGNode* cs, const SVFFunction* F); + void connectCaller2CalleeParams(const CallICFGNode* cs, const CallGraphNode* F); void heapAllocatorViaIndCall(const CallICFGNode* cs); diff --git a/svf/include/DDA/ContextDDA.h b/svf/include/DDA/ContextDDA.h index 5aa8dc9e16..586a190356 100644 --- a/svf/include/DDA/ContextDDA.h +++ b/svf/include/DDA/ContextDDA.h @@ -110,7 +110,7 @@ class ContextDDA : public CondPTAImpl, public DDAVFSolver, public DDAVFSolvergetCallerOfCallSite(csId); - const SVFFunction* callee = getCallGraph()->getCalleeOfCallSite(csId); + const CallGraphNode* caller = getCallGraph()->getCallerOfCallSite(csId); + const CallGraphNode* callee = getCallGraph()->getCalleeOfCallSite(csId); return inSameCallGraphSCC(caller, callee); } /// Update call graph. @@ -149,7 +149,7 @@ class ContextDDA : public CondPTAImpl, public DDAVFSolversecond; for (FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++) { - const SVFFunction* func = *func_iter; + const CallGraphNode* func = *func_iter; getSVFG()->connectCallerAndCallee(newcs, func, svfgEdges); } } @@ -159,8 +159,8 @@ class ContextDDA : public CondPTAImpl, public DDAVFSolvergetSrcNode()->getFun(); - const SVFFunction* dstfun = edge->getDstNode()->getFun(); + const CallGraphNode* srcfun = edge->getSrcNode()->getFun(); + const CallGraphNode* dstfun = edge->getDstNode()->getFun(); if(srcfun && dstfun) return inSameCallGraphSCC(srcfun,dstfun); diff --git a/svf/include/DDA/DDAVFSolver.h b/svf/include/DDA/DDAVFSolver.h index f76e73b701..c2b5651557 100644 --- a/svf/include/DDA/DDAVFSolver.h +++ b/svf/include/DDA/DDAVFSolver.h @@ -475,9 +475,10 @@ class DDAVFSolver assert(baseObj && "base object is null??"); if(SVFUtil::isa(baseObj)) { - if(const SVFFunction* svffun = _pag->getGNode(id)->getFunction()) + if(const CallGraphNode* svffun = _pag->getGNode(id)->getFunction()) { - return _callGraphSCC->isInCycle(_callGraph->getCallGraphNode(svffun)->getId()); + return _callGraphSCC->isInCycle( + svffun->getId()); } } return false; @@ -501,7 +502,7 @@ class DDAVFSolver findPT(funPtrDpm); } } - else if(const SVFFunction* fun = getSVFG()->isFunEntrySVFGNode(dpm.getLoc())) + else if(const CallGraphNode* fun = getSVFG()->isFunEntrySVFGNode(dpm.getLoc())) { CallInstSet csSet; /// use pre-analysis call graph to approximate all potential callsites diff --git a/svf/include/DDA/FlowDDA.h b/svf/include/DDA/FlowDDA.h index ed4d304412..1df574a193 100644 --- a/svf/include/DDA/FlowDDA.h +++ b/svf/include/DDA/FlowDDA.h @@ -80,7 +80,7 @@ class FlowDDA : public BVDataPTAImpl, public DDAVFSolversecond; for (FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++) { - const SVFFunction* func = *func_iter; + const CallGraphNode* func = *func_iter; getSVFG()->connectCallerAndCallee(newcs, func, svfgEdges); } } diff --git a/svf/include/Graphs/BasicBlockG.h b/svf/include/Graphs/BasicBlockG.h index df59dfce99..bb63cb779c 100644 --- a/svf/include/Graphs/BasicBlockG.h +++ b/svf/include/Graphs/BasicBlockG.h @@ -39,7 +39,7 @@ namespace SVF class SVFBasicBlock; class BasicBlockEdge; class ICFGNode; -class SVFFunction; +class CallGraphNode; typedef GenericEdge GenericBasicBlockEdgeTy; class BasicBlockEdge: public GenericBasicBlockEdgeTy { @@ -75,7 +75,6 @@ class SVFBasicBlock : public GenericBasicBlockNodeTy friend class SVFIRWriter; friend class SVFIRReader; friend class SVFIRBuilder; - friend class SVFFunction; friend class ICFGBuilder; friend class ICFG; @@ -86,7 +85,7 @@ class SVFBasicBlock : public GenericBasicBlockNodeTy private: std::vector allICFGNodes; ///< all ICFGNodes in this BasicBlock - const SVFFunction* fun; /// Function where this BasicBlock is + const CallGraphNode* fun; /// Function where this BasicBlock is @@ -104,7 +103,7 @@ class SVFBasicBlock : public GenericBasicBlockNodeTy public: /// Constructor without name - SVFBasicBlock(NodeID id, const SVFFunction* f): GenericBasicBlockNodeTy(id, BasicBlockKd), fun(f) + SVFBasicBlock(NodeID id, const CallGraphNode* f): GenericBasicBlockNodeTy(id, BasicBlockKd), fun(f) { } @@ -181,12 +180,12 @@ class SVFBasicBlock : public GenericBasicBlockNodeTy pred->succBBs.push_back(this); } - inline const SVFFunction* getParent() const + inline const CallGraphNode* getParent() const { return fun; } - inline const SVFFunction* getFunction() const + inline const CallGraphNode* getFunction() const { return fun; } @@ -287,10 +286,10 @@ class BasicBlockGraph: public GenericBasicBlockGraphTy { private: NodeID id{0}; - const SVFFunction* fun; + const CallGraphNode* fun; public: /// Constructor - BasicBlockGraph(const SVFFunction* f): fun(f) + BasicBlockGraph(const CallGraphNode* f): fun(f) { } diff --git a/svf/include/Graphs/CDG.h b/svf/include/Graphs/CDG.h index 394b825d41..0c457b26fe 100644 --- a/svf/include/Graphs/CDG.h +++ b/svf/include/Graphs/CDG.h @@ -31,6 +31,7 @@ #define SVF_CONTROLDG_H #include "SVFIR/SVFIR.h" +#include "Graphs/CallGraph.h" namespace SVF { diff --git a/svf/include/Graphs/CHG.h b/svf/include/Graphs/CHG.h index 87a014c4fa..1ae8ff2a7a 100644 --- a/svf/include/Graphs/CHG.h +++ b/svf/include/Graphs/CHG.h @@ -45,7 +45,7 @@ class CHNode; class GlobalObjVar; typedef Set VTableSet; -typedef Set VFunSet; +typedef Set VFunSet; /// Common base for class hierarchy graph. Only implements what PointerAnalysis needs. class CommonCHGraph @@ -119,7 +119,7 @@ class CHNode: public GenericCHNodeTy TEMPLATE = 0x04 // template class } CLASSATTR; - typedef std::vector FuncVector; + typedef std::vector FuncVector; CHNode (const std::string& name, NodeID i = 0, GNodeK k = CHNodeKd): GenericCHNodeTy(i, k), vtable(nullptr), className(name), flags(0) @@ -267,18 +267,18 @@ class CHGraph: public CommonCHGraph, public GenericCHGraphTy void view(); void printCH(); - inline u32_t getVirtualFunctionID(const SVFFunction* vfn) const + inline u32_t getVirtualFunctionID(const CallGraphNode* vfn) const { - Map::const_iterator it = + Map::const_iterator it = virtualFunctionToIDMap.find(vfn); if (it != virtualFunctionToIDMap.end()) return it->second; else return -1; } - inline const SVFFunction* getVirtualFunctionBasedonID(u32_t id) const + inline const CallGraphNode* getVirtualFunctionBasedonID(u32_t id) const { - Map::const_iterator it, eit; + Map::const_iterator it, eit; for (it = virtualFunctionToIDMap.begin(), eit = virtualFunctionToIDMap.end(); it != eit; ++it) { @@ -329,7 +329,7 @@ class CHGraph: public CommonCHGraph, public GenericCHGraphTy NameToCHNodesMap templateNameToInstancesMap; CallNodeToCHNodesMap callNodeToClassesMap; - Map virtualFunctionToIDMap; + Map virtualFunctionToIDMap; CallNodeToVTableSetMap callNodeToCHAVtblsMap; CallNodeToVFunSetMap callNodeToCHAVFnsMap; diff --git a/svf/include/Graphs/CallGraph.h b/svf/include/Graphs/CallGraph.h index 25e6683b84..2c83508615 100644 --- a/svf/include/Graphs/CallGraph.h +++ b/svf/include/Graphs/CallGraph.h @@ -113,24 +113,238 @@ class CallGraphEdge : public GenericCallGraphEdgeTy typedef GenericNode GenericCallGraphNodeTy; class CallGraphNode : public GenericCallGraphNodeTy { + +public: + typedef CallGraphEdge::CallGraphEdgeSet CallGraphEdgeSet; + typedef CallGraphEdge::CallGraphEdgeSet::iterator iterator; + typedef CallGraphEdge::CallGraphEdgeSet::const_iterator const_iterator; + typedef SVFLoopAndDomInfo::BBSet BBSet; + typedef SVFLoopAndDomInfo::BBList BBList; + typedef SVFLoopAndDomInfo::LoopBBs LoopBBs; + + typedef BasicBlockGraph::IDToNodeMapTy::const_iterator const_bb_iterator; + + private: - const SVFFunction* fun; + bool isDecl; /// return true if this function does not have a body + bool intrinsic; /// return true if this function is an intrinsic function (e.g., llvm.dbg), which does not reside in the application code + bool addrTaken; /// return true if this function is address-taken (for indirect call purposes) + bool isUncalled; /// return true if this function is never called + bool isNotRet; /// return true if this function never returns + bool varArg; /// return true if this function supports variable arguments + const SVFFunctionType* funcType; /// FunctionType, which is different from the type (PointerType) of this SVF Function + SVFLoopAndDomInfo* loopAndDom; /// the loop and dominate information + const CallGraphNode * realDefFun{nullptr}; /// the definition of a function across multiple modules + BasicBlockGraph* bbGraph; /// the basic block graph of this function + std::vector allArgs; /// all formal arguments of this function + SVFBasicBlock *exitBlock{nullptr}; /// a 'single' basic block having no successors and containing return instruction in a function public: /// Constructor - CallGraphNode(NodeID i, const SVFFunction* f) : GenericCallGraphNodeTy(i,CallNodeKd), fun(f) + CallGraphNode(NodeID i, const SVFType* ty, + const SVFFunctionType* ft, bool declare, bool intrinsic, + bool addrTaken, bool varg, SVFLoopAndDomInfo* ld); + + ~CallGraphNode(){ + } + + void init(const SVFFunctionType* ft, bool uncalled, bool notRet, bool declare, bool intr, bool adt, + bool varg, SVFLoopAndDomInfo* ld, CallGraphNode* cgn, BasicBlockGraph* bbG, + std::vector allArg, SVFBasicBlock* eBb); + + inline void addArgument(const ArgValVar* arg) { + allArgs.push_back(arg); } - inline const std::string &getName() const + inline bool isDeclaration() const + { + return isDecl; + } + + inline bool isIntrinsic() const + { + return intrinsic; + } + + inline bool hasAddressTaken() const + { + return addrTaken; + } + + inline bool isVarArg() const + { + return varArg; + } + + inline bool isUncalledFunction() const + { + return isUncalled; + } + + inline bool hasReturn() const + { + return !isNotRet; + } + + /// Returns the FunctionType + inline const SVFFunctionType* getFunctionType() const + { + return funcType; + } + + /// Returns the FunctionType + inline const SVFType* getReturnType() const + { + return funcType->getReturnType(); + } + + inline SVFLoopAndDomInfo* getLoopAndDomInfo() { - return fun->getName(); + return loopAndDom; } - /// Get function of this call node - inline const SVFFunction* getFunction() const + inline const std::vector& getReachableBBs() const { - return fun; + return loopAndDom->getReachableBBs(); + } + + inline void getExitBlocksOfLoop(const SVFBasicBlock* bb, BBList& exitbbs) const + { + return loopAndDom->getExitBlocksOfLoop(bb,exitbbs); + } + + inline bool hasLoopInfo(const SVFBasicBlock* bb) const + { + return loopAndDom->hasLoopInfo(bb); + } + + const LoopBBs& getLoopInfo(const SVFBasicBlock* bb) const + { + return loopAndDom->getLoopInfo(bb); + } + + inline const SVFBasicBlock* getLoopHeader(const BBList& lp) const + { + return loopAndDom->getLoopHeader(lp); + } + + inline bool loopContainsBB(const BBList& lp, const SVFBasicBlock* bb) const + { + return loopAndDom->loopContainsBB(lp,bb); + } + + inline const Map& getDomTreeMap() const + { + return loopAndDom->getDomTreeMap(); + } + + inline const Map& getDomFrontierMap() const + { + return loopAndDom->getDomFrontierMap(); + } + + inline bool isLoopHeader(const SVFBasicBlock* bb) const + { + return loopAndDom->isLoopHeader(bb); + } + + inline bool dominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const + { + return loopAndDom->dominate(bbKey,bbValue); + } + + inline bool postDominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const + { + return loopAndDom->postDominate(bbKey,bbValue); + } + + inline const CallGraphNode* getDefFunForMultipleModule() const + { + if(realDefFun==nullptr) + return this; + return realDefFun; + } + + void setBasicBlockGraph(BasicBlockGraph* graph) + { + this->bbGraph = graph; + } + + BasicBlockGraph* getBasicBlockGraph() + { + return bbGraph; + } + + const BasicBlockGraph* getBasicBlockGraph() const + { + return bbGraph; + } + + inline bool hasBasicBlock() const + { + return bbGraph && bbGraph->begin() != bbGraph->end(); + } + + inline const SVFBasicBlock* getEntryBlock() const + { + assert(hasBasicBlock() && "function does not have any Basicblock, external function?"); + assert(bbGraph->begin()->second->getInEdges().size() == 0 && "the first basic block is not entry block"); + return bbGraph->begin()->second; + } + + inline const SVFBasicBlock* getExitBB() const + { + assert(hasBasicBlock() && "function does not have any Basicblock, external function?"); + assert(exitBlock && "must have an exitBlock"); + return exitBlock; + } + + inline void setExitBlock(SVFBasicBlock *bb) + { + assert(!exitBlock && "have already set exit Basicblock!"); + exitBlock = bb; + } + + + u32_t inline arg_size() const + { + return allArgs.size(); + } + + inline const ArgValVar* getArg(u32_t idx) const + { + assert (idx < allArgs.size() && "getArg() out of range!"); + return allArgs[idx]; + } + + inline const SVFBasicBlock* front() const + { + return getEntryBlock(); + } + + inline const SVFBasicBlock* back() const + { + assert(hasBasicBlock() && "function does not have any Basicblock, external function?"); + /// Carefully! 'back' is just the last basic block of function, + /// but not necessarily a exit basic block + /// more refer to: https://github.com/SVF-tools/SVF/pull/1262 + return std::prev(bbGraph->end())->second; + } + + inline const_bb_iterator begin() const + { + return bbGraph->begin(); + } + + inline const_bb_iterator end() const + { + return bbGraph->end(); + } + + inline const std::string &getName() const + { + return name; } @@ -174,13 +388,8 @@ class CallGraph : public GenericCallGraphTy public: typedef CallGraphEdge::CallGraphEdgeSet CallGraphEdgeSet; - typedef Map FunToCallGraphNodeMap; typedef Map CallInstToCallGraphEdgesMap; - typedef Set FunctionSet; - typedef OrderedMap CallEdgeMap; - protected: - FunToCallGraphNodeMap funToCallGraphNodeMap; ///< Call Graph node map CallInstToCallGraphEdgesMap callinstToCallGraphEdgesMap; ///< Map a call instruction to its corresponding call edges NodeID callGraphNodeNum; @@ -200,7 +409,9 @@ class CallGraph : public GenericCallGraphTy /// Constructor CallGraph(); - void addCallGraphNode(const SVFFunction* fun); + CallGraphNode* addCallGraphNode( const SVFType* ty, + const SVFFunctionType* ft, bool declare, bool intrinsic, + bool addrTaken, bool varg, SVFLoopAndDomInfo* ld); const CallGraphNode* getCallGraphNode(const std::string& name); @@ -216,13 +427,6 @@ class CallGraph : public GenericCallGraphTy { return getGNode(id); } - inline CallGraphNode* getCallGraphNode(const SVFFunction* fun) const - { - FunToCallGraphNodeMap::const_iterator it = funToCallGraphNodeMap.find(fun); - assert(it!=funToCallGraphNodeMap.end() && "call graph node not found!!"); - return it->second; - } - //@} /// Whether we have already created this call graph edge @@ -230,7 +434,7 @@ class CallGraph : public GenericCallGraphTy const CallICFGNode* callIcfgNode) const; /// Add direct call edges - void addDirectCallGraphEdge(const CallICFGNode* call, const SVFFunction* callerFun, const SVFFunction* calleeFun); + void addDirectCallGraphEdge(const CallICFGNode* call, CallGraphNode* callerFun, CallGraphNode* calleeFun); /// Dump the graph void dump(const std::string& filename); diff --git a/svf/include/Graphs/ConsG.h b/svf/include/Graphs/ConsG.h index 715347d778..b2c0a8a7f2 100644 --- a/svf/include/Graphs/ConsG.h +++ b/svf/include/Graphs/ConsG.h @@ -76,12 +76,12 @@ class ConstraintGraph : public GenericGraph /// Wrappers used internally, not expose to Andersen Pass //@{ - inline NodeID getReturnNode(const SVFFunction* value) const + inline NodeID getReturnNode(const CallGraphNode* value) const { return pag->getReturnNode(value); } - inline NodeID getVarargNode(const SVFFunction* value) const + inline NodeID getVarargNode(const CallGraphNode* value) const { return pag->getVarargNode(value); } diff --git a/svf/include/Graphs/ICFG.h b/svf/include/Graphs/ICFG.h index 33d67bbe1b..5be398d5cf 100644 --- a/svf/include/Graphs/ICFG.h +++ b/svf/include/Graphs/ICFG.h @@ -58,8 +58,8 @@ class ICFG : public GenericICFGTy typedef ICFGNodeIDToNodeMapTy::iterator iterator; typedef ICFGNodeIDToNodeMapTy::const_iterator const_iterator; - typedef Map FunToFunEntryNodeMapTy; - typedef Map FunToFunExitNodeMapTy; + typedef Map FunToFunEntryNodeMapTy; + typedef Map FunToFunExitNodeMapTy; typedef std::vector SVFLoopVec; typedef Map ICFGNodeToSVFLoopVec; @@ -164,8 +164,8 @@ class ICFG : public GenericICFGTy /// sanitize Intra edges, verify that both nodes belong to the same function. inline void checkIntraEdgeParents(const ICFGNode *srcNode, const ICFGNode *dstNode) { - const SVFFunction* srcfun = srcNode->getFun(); - const SVFFunction* dstfun = dstNode->getFun(); + const CallGraphNode* srcfun = srcNode->getFun(); + const CallGraphNode* dstfun = dstNode->getFun(); if(srcfun != nullptr && dstfun != nullptr) { assert((srcfun == dstfun) && "src and dst nodes of an intra edge should in the same function!" ); @@ -182,7 +182,7 @@ class ICFG : public GenericICFGTy virtual inline CallICFGNode* addCallICFGNode( const SVFBasicBlock* bb, const SVFType* ty, - const SVFFunction* calledFunc, bool isVararg, bool isvcall, + const CallGraphNode* calledFunc, bool isVararg, bool isvcall, s32_t vcallIdx, const std::string& funNameOfVcall) { @@ -201,18 +201,18 @@ class ICFG : public GenericICFGTy return retICFGNode; } - virtual inline FunEntryICFGNode* addFunEntryICFGNode(const SVFFunction* svfFunc) + virtual inline FunEntryICFGNode* addFunEntryICFGNode(const CallGraphNode* cgn) { - FunEntryICFGNode* sNode = new FunEntryICFGNode(totalICFGNode++,svfFunc); + FunEntryICFGNode* sNode = new FunEntryICFGNode(totalICFGNode++, cgn); addICFGNode(sNode); - return FunToFunEntryNodeMap[svfFunc] = sNode; + return FunToFunEntryNodeMap[cgn] = sNode; } - virtual inline FunExitICFGNode* addFunExitICFGNode(const SVFFunction* svfFunc) + virtual inline FunExitICFGNode* addFunExitICFGNode(const CallGraphNode* cgn) { - FunExitICFGNode* sNode = new FunExitICFGNode(totalICFGNode++, svfFunc); + FunExitICFGNode* sNode = new FunExitICFGNode(totalICFGNode++, cgn); addICFGNode(sNode); - return FunToFunExitNodeMap[svfFunc] = sNode; + return FunToFunExitNodeMap[cgn] = sNode; } /// Add a ICFG node @@ -229,9 +229,9 @@ class ICFG : public GenericICFGTy //@{ - FunEntryICFGNode* getFunEntryICFGNode(const SVFFunction* fun); + FunEntryICFGNode* getFunEntryICFGNode(const CallGraphNode* fun); - FunExitICFGNode* getFunExitICFGNode(const SVFFunction* fun); + FunExitICFGNode* getFunExitICFGNode(const CallGraphNode* fun); inline GlobalICFGNode* getGlobalICFGNode() const { @@ -284,7 +284,7 @@ class ICFG : public GenericICFGTy } /// Get/Add a function entry node - inline FunEntryICFGNode* getFunEntryBlock(const SVFFunction* fun) + inline FunEntryICFGNode* getFunEntryBlock(const CallGraphNode* fun) { FunToFunEntryNodeMapTy::const_iterator it = FunToFunEntryNodeMap.find(fun); if (it == FunToFunEntryNodeMap.end()) @@ -293,7 +293,7 @@ class ICFG : public GenericICFGTy } /// Get/Add a function exit node - inline FunExitICFGNode* getFunExitBlock(const SVFFunction* fun) + inline FunExitICFGNode* getFunExitBlock(const CallGraphNode* fun) { FunToFunExitNodeMapTy::const_iterator it = FunToFunExitNodeMap.find(fun); if (it == FunToFunExitNodeMap.end()) diff --git a/svf/include/Graphs/ICFGNode.h b/svf/include/Graphs/ICFGNode.h index 0336601872..a94c9a46ed 100644 --- a/svf/include/Graphs/ICFGNode.h +++ b/svf/include/Graphs/ICFGNode.h @@ -73,7 +73,7 @@ class ICFGNode : public GenericICFGNodeTy } /// Return the function of this ICFGNode - virtual const SVFFunction* getFun() const + virtual const CallGraphNode* getFun() const { return fun; } @@ -145,7 +145,7 @@ class ICFGNode : public GenericICFGNodeTy protected: - const SVFFunction* fun; + const CallGraphNode* fun; const SVFBasicBlock* bb; VFGNodeList VFGNodes; //< a list of VFGNodes SVFStmtList pagEdges; //< a list of PAGEdges @@ -289,10 +289,10 @@ class FunEntryICFGNode : public InterICFGNode FunEntryICFGNode(NodeID id) : InterICFGNode(id, FunEntryBlock) {} public: - FunEntryICFGNode(NodeID id, const SVFFunction* f); + FunEntryICFGNode(NodeID id, const CallGraphNode* f); /// Return function - inline const SVFFunction* getFun() const override + inline const CallGraphNode* getFun() const override { return fun; } @@ -339,10 +339,8 @@ class FunEntryICFGNode : public InterICFGNode const std::string toString() const override; - const std::string getSourceLoc() const override - { - return "function entry: " + fun->getSourceLoc(); - } + const std::string getSourceLoc() const override; + }; /*! @@ -360,10 +358,10 @@ class FunExitICFGNode : public InterICFGNode FunExitICFGNode(NodeID id) : InterICFGNode(id, FunExitBlock), formalRet{} {} public: - FunExitICFGNode(NodeID id, const SVFFunction* f); + FunExitICFGNode(NodeID id, const CallGraphNode* f); /// Return function - inline const SVFFunction* getFun() const override + inline const CallGraphNode* getFun() const override { return fun; } @@ -410,10 +408,7 @@ class FunExitICFGNode : public InterICFGNode const std::string toString() const override; - const std::string getSourceLoc() const override - { - return "function ret: " + fun->getSourceLoc(); - } + const std::string getSourceLoc() const override; }; /*! @@ -430,7 +425,7 @@ class CallICFGNode : public InterICFGNode protected: const RetICFGNode* ret; ActualParmNodeVec APNodes; /// arguments - const SVFFunction* calledFunc; /// called function + const CallGraphNode* calledFunc; /// called function bool isvararg; /// is variable argument bool isVirCallInst; /// is virtual call inst SVFVar* vtabPtr; /// virtual table pointer @@ -442,7 +437,7 @@ class CallICFGNode : public InterICFGNode public: CallICFGNode(NodeID id, const SVFBasicBlock* b, const SVFType* ty, - const SVFFunction* cf, bool iv, bool ivc, s32_t vfi, + const CallGraphNode* cf, bool iv, bool ivc, s32_t vfi, const std::string& fnv) : InterICFGNode(id, FunCallBlock), ret(nullptr), calledFunc(cf), isvararg(iv), isVirCallInst(ivc), vtabPtr(nullptr), @@ -467,7 +462,7 @@ class CallICFGNode : public InterICFGNode } /// Return callsite - inline const SVFFunction* getCaller() const + inline const CallGraphNode* getCaller() const { return getFun(); } @@ -515,7 +510,7 @@ class CallICFGNode : public InterICFGNode { return arg_size(); } - inline const SVFFunction* getCalledFunction() const + inline const CallGraphNode* getCalledFunction() const { return calledFunc; } diff --git a/svf/include/Graphs/IRGraph.h b/svf/include/Graphs/IRGraph.h index 65f6e6e0fd..379eea0db1 100644 --- a/svf/include/Graphs/IRGraph.h +++ b/svf/include/Graphs/IRGraph.h @@ -75,7 +75,7 @@ class IRGraph : public GenericGraph typedef OrderedMap IDToTypeInfoMapTy; /// function to sym id map - typedef OrderedMap FunToIDMapTy; + typedef OrderedMap FunToIDMapTy; /// struct type to struct info map typedef Set SVFTypeSet; //@} @@ -237,10 +237,10 @@ class IRGraph : public GenericGraph } /// GetReturnNode - Return the unique node representing the return value of a function - NodeID getReturnNode(const SVFFunction* func) const; + NodeID getReturnNode(const CallGraphNode* func) const; /// getVarargNode - Return the unique node representing the variadic argument of a variadic function. - NodeID getVarargNode(const SVFFunction* func) const; + NodeID getVarargNode(const CallGraphNode* func) const; inline NodeID getBlackHoleNode() const { diff --git a/svf/include/Graphs/PTACallGraph.h b/svf/include/Graphs/PTACallGraph.h index 1cbc93351b..98bedc9ef4 100644 --- a/svf/include/Graphs/PTACallGraph.h +++ b/svf/include/Graphs/PTACallGraph.h @@ -33,6 +33,7 @@ #include "Graphs/GenericGraph.h" #include "SVFIR/SVFValue.h" #include "Graphs/ICFG.h" +#include "Graphs/CallGraph.h" #include namespace SVF @@ -175,11 +176,11 @@ typedef GenericNode GenericPTACallGraphNodeT class PTACallGraphNode : public GenericPTACallGraphNodeTy { private: - const SVFFunction* fun; + const CallGraphNode* fun; public: /// Constructor - PTACallGraphNode(NodeID i, const SVFFunction* f) : GenericPTACallGraphNodeTy(i,CallNodeKd), fun(f) + PTACallGraphNode(NodeID i, const CallGraphNode* f) : GenericPTACallGraphNodeTy(i,CallNodeKd), fun(f) { } @@ -190,7 +191,7 @@ class PTACallGraphNode : public GenericPTACallGraphNodeTy } /// Get function of this call node - inline const SVFFunction* getFunction() const + inline const CallGraphNode* getCallGraphNode() const { return fun; } @@ -238,12 +239,12 @@ class PTACallGraph : public GenericPTACallGraphTy public: typedef PTACallGraphEdge::CallGraphEdgeSet CallGraphEdgeSet; - typedef Map FunToCallGraphNodeMap; + typedef Map CgNodeToPTACallGraphNodeMap; typedef Map CallInstToCallGraphEdgesMap; - typedef std::pair CallSitePair; + typedef std::pair CallSitePair; typedef Map CallSiteToIdMap; typedef Map IdToCallSiteMap; - typedef Set FunctionSet; + typedef Set FunctionSet; typedef OrderedMap CallEdgeMap; typedef CallGraphEdgeSet::iterator CallGraphEdgeIter; typedef CallGraphEdgeSet::const_iterator CallGraphEdgeConstIter; @@ -263,7 +264,7 @@ class PTACallGraph : public GenericPTACallGraphTy static CallSiteID totalCallSiteNum; ///< CallSiteIDs, start from 1; protected: - FunToCallGraphNodeMap funToCallGraphNodeMap; ///< Call Graph node map + CgNodeToPTACallGraphNodeMap cgNodeToPtaCallGraphNodeMap; ///< Call Graph node map CallInstToCallGraphEdgesMap callinstToCallGraphEdgesMap; ///< Map a call instruction to its corresponding call edges NodeID callGraphNodeNum; @@ -275,9 +276,9 @@ class PTACallGraph : public GenericPTACallGraphTy protected: /// Add CallSiteID - inline CallSiteID addCallSite(const CallICFGNode* cs, const SVFFunction* callee) + inline CallSiteID addCallSite(const CallICFGNode* cs, const CallGraphNode* callee) { - std::pair newCS(std::make_pair(cs, callee)); + std::pair newCS(std::make_pair(cs, callee)); CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS); //assert(it == csToIdMap.end() && "cannot add a callsite twice"); if(it == csToIdMap.end()) @@ -357,10 +358,12 @@ class PTACallGraph : public GenericPTACallGraphTy { return getGNode(id); } - inline PTACallGraphNode* getCallGraphNode(const SVFFunction* fun) const + + inline PTACallGraphNode* getPTACallGraphNode(const CallGraphNode* fun) const { - FunToCallGraphNodeMap::const_iterator it = funToCallGraphNodeMap.find(fun); - assert(it!=funToCallGraphNodeMap.end() && "call graph node not found!!"); + CgNodeToPTACallGraphNodeMap::const_iterator it = + cgNodeToPtaCallGraphNodeMap.find(fun); + assert(it!= cgNodeToPtaCallGraphNodeMap.end() && "call graph node not found!!"); return it->second; } @@ -368,14 +371,14 @@ class PTACallGraph : public GenericPTACallGraphTy /// Get CallSiteID //@{ - inline CallSiteID getCallSiteID(const CallICFGNode* cs, const SVFFunction* callee) const + inline CallSiteID getCallSiteID(const CallICFGNode* cs, const CallGraphNode* callee) const { CallSitePair newCS(std::make_pair(cs, callee)); CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS); assert(it != csToIdMap.end() && "callsite id not found! This maybe a partially resolved callgraph, please check the indCallEdge limit"); return it->second; } - inline bool hasCallSiteID(const CallICFGNode* cs, const SVFFunction* callee) const + inline bool hasCallSiteID(const CallICFGNode* cs, const CallGraphNode* callee) const { CallSitePair newCS(std::make_pair(cs, callee)); CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS); @@ -391,11 +394,11 @@ class PTACallGraph : public GenericPTACallGraphTy { return getCallSitePair(id).first; } - inline const SVFFunction* getCallerOfCallSite(CallSiteID id) const + inline const CallGraphNode* getCallerOfCallSite(CallSiteID id) const { return getCallSite(id)->getCaller(); } - inline const SVFFunction* getCalleeOfCallSite(CallSiteID id) const + inline const CallGraphNode* getCalleeOfCallSite(CallSiteID id) const { return getCallSitePair(id).second; } @@ -415,7 +418,7 @@ class PTACallGraph : public GenericPTACallGraphTy for (CallGraphEdgeSet::const_iterator it = getCallEdgeBegin(cs), eit = getCallEdgeEnd(cs); it != eit; ++it) { - callees.insert((*it)->getDstNode()->getFunction()); + callees.insert((*it)->getDstNode()->getCallGraphNode()); } } } @@ -446,18 +449,18 @@ class PTACallGraph : public GenericPTACallGraphTy /// Add indirect call edges //@{ - void addIndirectCallGraphEdge(const CallICFGNode* cs,const SVFFunction* callerFun, const SVFFunction* calleeFun); + void addIndirectCallGraphEdge(const CallICFGNode* cs,const CallGraphNode* callerFun, const CallGraphNode* calleeFun); //@} /// Get callsites invoking the callee //@{ - void getAllCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet); - void getDirCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet); - void getIndCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet); + void getAllCallSitesInvokingCallee(const CallGraphNode* callee, PTACallGraphEdge::CallInstSet& csSet); + void getDirCallSitesInvokingCallee(const CallGraphNode* callee, PTACallGraphEdge::CallInstSet& csSet); + void getIndCallSitesInvokingCallee(const CallGraphNode* callee, PTACallGraphEdge::CallInstSet& csSet); //@} /// Whether its reachable between two functions - bool isReachableBetweenFunctions(const SVFFunction* srcFn, const SVFFunction* dstFn) const; + bool isReachableBetweenFunctions(const CallGraphNode* srcFn, const CallGraphNode* dstFn) const; /// Dump the graph void dump(const std::string& filename); diff --git a/svf/include/Graphs/SVFG.h b/svf/include/Graphs/SVFG.h index dad7fe3ba8..ca760596d1 100644 --- a/svf/include/Graphs/SVFG.h +++ b/svf/include/Graphs/SVFG.h @@ -82,8 +82,8 @@ class SVFG : public VFG typedef NodeBS FormalOUTSVFGNodeSet; typedef Map CallSiteToActualINsMapTy; typedef Map CallSiteToActualOUTsMapTy; - typedef Map FunctionToFormalINsMapTy; - typedef Map FunctionToFormalOUTsMapTy; + typedef Map FunctionToFormalINsMapTy; + typedef Map FunctionToFormalOUTsMapTy; typedef MemSSA::MUSet MUSet; typedef MemSSA::CHISet CHISet; typedef MemSSA::PHISet PHISet; @@ -159,13 +159,13 @@ class SVFG : public VFG } /// Get all inter value flow edges of a indirect call site - void getInterVFEdgesForIndirectCallSite(const CallICFGNode* cs, const SVFFunction* callee, SVFGEdgeSetTy& edges); + void getInterVFEdgesForIndirectCallSite(const CallICFGNode* cs, const CallGraphNode* callee, SVFGEdgeSetTy& edges); /// Dump graph into dot file void dump(const std::string& file, bool simple = false); /// Connect SVFG nodes between caller and callee for indirect call site - virtual void connectCallerAndCallee(const CallICFGNode* cs, const SVFFunction* callee, SVFGEdgeSetTy& edges); + virtual void connectCallerAndCallee(const CallICFGNode* cs, const CallGraphNode* callee, SVFGEdgeSetTy& edges); /// Given a pagNode, return its definition site inline const SVFGNode* getDefSVFGNode(const PAGNode* pagNode) const @@ -194,12 +194,12 @@ class SVFG : public VFG return callSiteToActualOUTMap.find(cs)!=callSiteToActualOUTMap.end(); } - inline bool hasFormalINSVFGNodes(const SVFFunction* fun) const + inline bool hasFormalINSVFGNodes(const CallGraphNode* fun) const { return funToFormalINMap.find(fun)!=funToFormalINMap.end(); } - inline bool hasFormalOUTSVFGNodes(const SVFFunction* fun) const + inline bool hasFormalOUTSVFGNodes(const CallGraphNode* fun) const { return funToFormalOUTMap.find(fun)!=funToFormalOUTMap.end(); } @@ -217,19 +217,19 @@ class SVFG : public VFG return callSiteToActualOUTMap[cs]; } - inline FormalINSVFGNodeSet& getFormalINSVFGNodes(const SVFFunction* fun) + inline FormalINSVFGNodeSet& getFormalINSVFGNodes(const CallGraphNode* fun) { return funToFormalINMap[fun]; } - inline FormalOUTSVFGNodeSet& getFormalOUTSVFGNodes(const SVFFunction* fun) + inline FormalOUTSVFGNodeSet& getFormalOUTSVFGNodes(const CallGraphNode* fun) { return funToFormalOUTMap[fun]; } //@} /// Whether a node is function entry SVFGNode - const SVFFunction* isFunEntrySVFGNode(const SVFGNode* node) const; + const CallGraphNode* isFunEntrySVFGNode(const SVFGNode* node) const; /// Whether a node is callsite return SVFGNode const CallICFGNode* isCallSiteRetSVFGNode(const SVFGNode* node) const; @@ -325,7 +325,7 @@ class SVFG : public VFG edges.insert(edge); } - virtual inline void getInterVFEdgeAtIndCSFromAInToFIn(ActualINSVFGNode* actualIn, const SVFFunction* callee, SVFGEdgeSetTy& edges) + virtual inline void getInterVFEdgeAtIndCSFromAInToFIn(ActualINSVFGNode* actualIn, const CallGraphNode* callee, SVFGEdgeSetTy& edges) { for (SVFGNode::const_iterator outIt = actualIn->OutEdgeBegin(), outEit = actualIn->OutEdgeEnd(); outIt != outEit; ++outIt) { @@ -335,7 +335,7 @@ class SVFG : public VFG } } - virtual inline void getInterVFEdgeAtIndCSFromFOutToAOut(ActualOUTSVFGNode* actualOut, const SVFFunction* callee, SVFGEdgeSetTy& edges) + virtual inline void getInterVFEdgeAtIndCSFromFOutToAOut(ActualOUTSVFGNode* actualOut, const CallGraphNode* callee, SVFGEdgeSetTy& edges) { for (SVFGNode::const_iterator inIt = actualOut->InEdgeBegin(), inEit = actualOut->InEdgeEnd(); inIt != inEit; ++inIt) { @@ -446,11 +446,11 @@ class SVFG : public VFG /// Has function for EntryCHI/RetMU/CallCHI/CallMU //@{ - inline bool hasFuncEntryChi(const SVFFunction* func) const + inline bool hasFuncEntryChi(const CallGraphNode* func) const { return (funToFormalINMap.find(func) != funToFormalINMap.end()); } - inline bool hasFuncRetMu(const SVFFunction* func) const + inline bool hasFuncRetMu(const CallGraphNode* func) const { return (funToFormalOUTMap.find(func) != funToFormalOUTMap.end()); } diff --git a/svf/include/Graphs/SVFGNode.h b/svf/include/Graphs/SVFGNode.h index 97d87a3849..feb5608117 100644 --- a/svf/include/Graphs/SVFGNode.h +++ b/svf/include/Graphs/SVFGNode.h @@ -408,7 +408,7 @@ class InterMSSAPHISVFGNode : public MSSAPHISVFGNode return (fun==nullptr) && (callInst != nullptr); } - inline const SVFFunction* getFun() const + inline const CallGraphNode* getFun() const { assert(isFormalINPHI() && "expect a formal parameter phi"); return fun; @@ -447,7 +447,7 @@ class InterMSSAPHISVFGNode : public MSSAPHISVFGNode virtual const std::string toString() const; private: - const SVFFunction* fun; + const CallGraphNode* fun; const CallICFGNode* callInst; }; diff --git a/svf/include/Graphs/ThreadCallGraph.h b/svf/include/Graphs/ThreadCallGraph.h index ba48e0e9c8..05d3963092 100644 --- a/svf/include/Graphs/ThreadCallGraph.h +++ b/svf/include/Graphs/ThreadCallGraph.h @@ -73,8 +73,8 @@ class ThreadForkEdge: public PTACallGraphEdge std::stringstream rawstr(str); rawstr << "ThreadForkEdge "; rawstr << "CallSiteID: " << getCallSiteID(); - rawstr << " srcNodeID " << getSrcID() << " (fun: " << getSrcNode()->getFunction()->getName() << ")"; - rawstr << " dstNodeID " << getDstID() << " (fun: " << getDstNode()->getFunction()->getName() << ")"; + rawstr << " srcNodeID " << getSrcID() << " (fun: " << getSrcNode()->getCallGraphNode()->getName() << ")"; + rawstr << " dstNodeID " << getDstID() << " (fun: " << getDstNode()->getCallGraphNode()->getName() << ")"; return rawstr.str(); } @@ -113,8 +113,8 @@ class ThreadJoinEdge: public PTACallGraphEdge std::stringstream rawstr(str); rawstr << "ThreadJoinEdge "; rawstr << "CallSiteID: " << getCallSiteID(); - rawstr << " srcNodeID " << getSrcID() << " (fun: " << getSrcNode()->getFunction()->getName() << ")"; - rawstr << " dstNodeID " << getDstID() << " (fun: " << getDstNode()->getFunction()->getName() << ")"; + rawstr << " srcNodeID " << getSrcID() << " (fun: " << getSrcNode()->getCallGraphNode()->getName() << ")"; + rawstr << " dstNodeID " << getDstID() << " (fun: " << getDstNode()->getCallGraphNode()->getName() << ")"; return rawstr.str(); } @@ -350,7 +350,7 @@ class ThreadCallGraph: public PTACallGraph /// Add direct/indirect thread fork edges //@{ bool addDirectForkEdge(const CallICFGNode* cs); - bool addIndirectForkEdge(const CallICFGNode* cs, const SVFFunction* callee); + bool addIndirectForkEdge(const CallICFGNode* cs, const CallGraphNode* callee); //@} /// Add thread join edges diff --git a/svf/include/Graphs/VFG.h b/svf/include/Graphs/VFG.h index 63f2d3cec3..78d7091c18 100644 --- a/svf/include/Graphs/VFG.h +++ b/svf/include/Graphs/VFG.h @@ -70,7 +70,7 @@ class VFG : public GenericVFGTy typedef Map PAGNodeToUnaryOPVFGNodeMapTy; typedef Map PAGNodeToBranchVFGNodeMapTy; typedef Map PAGNodeToCmpVFGNodeMapTy; - typedef Map FunToVFGNodesMapTy; + typedef Map FunToVFGNodesMapTy; typedef FormalParmVFGNode::CallPESet CallPESet; typedef FormalRetVFGNode::RetPESet RetPESet; @@ -171,11 +171,11 @@ class VFG : public GenericVFGTy void updateCallGraph(PointerAnalysis* pta); /// Connect VFG nodes between caller and callee for indirect call site - virtual void connectCallerAndCallee(const CallICFGNode* cs, const SVFFunction* callee, VFGEdgeSetTy& edges); + virtual void connectCallerAndCallee(const CallICFGNode* cs, const CallGraphNode* callee, VFGEdgeSetTy& edges); /// Get callsite given a callsiteID //@{ - inline CallSiteID getCallSiteID(const CallICFGNode* cs, const SVFFunction* func) const + inline CallSiteID getCallSiteID(const CallICFGNode* cs, const CallGraphNode* func) const { return callgraph->getCallSiteID(cs, func); } @@ -259,7 +259,7 @@ class VFG : public GenericVFGTy //@} /// Whether a node is function entry VFGNode - const SVFFunction* isFunEntryVFGNode(const VFGNode* node) const; + const CallGraphNode* isFunEntryVFGNode(const VFGNode* node) const; /// Whether a PAGNode has a blackhole or const object as its definition inline bool hasBlackHoleConstObjAddrAsDef(const PAGNode* pagNode) const @@ -283,25 +283,25 @@ class VFG : public GenericVFGTy /// Return all the VFGNodes of a function ///@{ - inline VFGNodeSet& getVFGNodes(const SVFFunction *fun) + inline VFGNodeSet& getVFGNodes(const CallGraphNode *fun) { return funToVFGNodesMap[fun]; } - inline bool hasVFGNodes(const SVFFunction *fun) const + inline bool hasVFGNodes(const CallGraphNode *fun) const { return funToVFGNodesMap.find(fun) != funToVFGNodesMap.end(); } - inline bool VFGNodes(const SVFFunction *fun) const + inline bool VFGNodes(const CallGraphNode *fun) const { return funToVFGNodesMap.find(fun) != funToVFGNodesMap.end(); } - inline VFGNodeSet::const_iterator getVFGNodeBegin(const SVFFunction *fun) const + inline VFGNodeSet::const_iterator getVFGNodeBegin(const CallGraphNode *fun) const { FunToVFGNodesMapTy::const_iterator it = funToVFGNodesMap.find(fun); assert(it != funToVFGNodesMap.end() && "this function does not have any VFGNode"); return it->second.begin(); } - inline VFGNodeSet::const_iterator getVFGNodeEnd(const SVFFunction *fun) const + inline VFGNodeSet::const_iterator getVFGNodeEnd(const CallGraphNode *fun) const { FunToVFGNodesMapTy::const_iterator it = funToVFGNodesMap.find(fun); assert(it != funToVFGNodesMap.end() && "this function does not have any VFGNode"); @@ -350,8 +350,8 @@ class VFG : public GenericVFGTy /// sanitize Intra edges, verify that both nodes belong to the same function. inline void checkIntraEdgeParents(const VFGNode *srcNode, const VFGNode *dstNode) { - const SVFFunction *srcfun = srcNode->getFun(); - const SVFFunction *dstfun = dstNode->getFun(); + const CallGraphNode *srcfun = srcNode->getFun(); + const CallGraphNode *dstfun = dstNode->getFun(); if(srcfun != nullptr && dstfun != nullptr) { assert((srcfun == dstfun) && "src and dst nodes of an intra VFG edge are not in the same function?"); @@ -453,7 +453,7 @@ class VFG : public GenericVFGTy void connectDirectVFGEdges(); /// Create edges between VFG nodes across functions - void addVFGInterEdges(const CallICFGNode* cs, const SVFFunction* callee); + void addVFGInterEdges(const CallICFGNode* cs, const CallGraphNode* callee); inline bool isPhiCopyEdge(const PAGEdge* copy) const { @@ -467,8 +467,8 @@ class VFG : public GenericVFGTy vfgNode->setICFGNode(icfgNode); icfgNode->addVFGNode(vfgNode); - if(const SVFFunction* fun = icfgNode->getFun()) - funToVFGNodesMap[fun].insert(vfgNode); + if(const CallGraphNode* cgn = icfgNode->getFun()) + funToVFGNodesMap[cgn].insert(vfgNode); else globalVFGNodes.insert(vfgNode); } @@ -535,7 +535,7 @@ class VFG : public GenericVFGTy /// do not set def here, this node is not a variable definition } /// Add a formal parameter VFG node - inline void addFormalParmVFGNode(const PAGNode* fparm, const SVFFunction* fun, CallPESet& callPEs) + inline void addFormalParmVFGNode(const PAGNode* fparm, const CallGraphNode* fun, CallPESet& callPEs) { FormalParmVFGNode* sNode = new FormalParmVFGNode(totalVFGNode++,fparm,fun); addVFGNode(sNode, pag->getICFG()->getFunEntryICFGNode(fun)); @@ -549,7 +549,7 @@ class VFG : public GenericVFGTy /// Add a callee Return VFG node /// To be noted that here we assume returns of a procedure have already been unified into one /// Otherwise, we need to handle formalRet using pair to find FormalRetVFG node same as handling actual parameters - inline void addFormalRetVFGNode(const PAGNode* uniqueFunRet, const SVFFunction* fun, RetPESet& retPEs) + inline void addFormalRetVFGNode(const PAGNode* uniqueFunRet, const CallGraphNode* fun, RetPESet& retPEs) { FormalRetVFGNode *sNode = new FormalRetVFGNode(totalVFGNode++, uniqueFunRet, fun); addVFGNode(sNode, pag->getICFG()->getFunExitICFGNode(fun)); diff --git a/svf/include/Graphs/VFGNode.h b/svf/include/Graphs/VFGNode.h index ea06d56a44..ee0ba38e57 100644 --- a/svf/include/Graphs/VFGNode.h +++ b/svf/include/Graphs/VFGNode.h @@ -76,7 +76,7 @@ class VFGNode : public GenericVFGNodeTy } /// Get the function of this SVFGNode - virtual const SVFFunction* getFun() const + virtual const CallGraphNode* getFun() const { return icfgNode->getFun(); } @@ -947,12 +947,12 @@ class ActualParmVFGNode : public ArgumentVFGNode class FormalParmVFGNode : public ArgumentVFGNode { private: - const SVFFunction* fun; + const CallGraphNode* fun; CallPESet callPEs; public: /// Constructor - FormalParmVFGNode(NodeID id, const PAGNode* n, const SVFFunction* f): + FormalParmVFGNode(NodeID id, const PAGNode* n, const CallGraphNode* f): ArgumentVFGNode(id, n, FParm), fun(f) { } @@ -964,7 +964,7 @@ class FormalParmVFGNode : public ArgumentVFGNode } /// Return function - inline const SVFFunction* getFun() const override + inline const CallGraphNode* getFun() const override { return fun; } @@ -1038,7 +1038,7 @@ class ActualRetVFGNode: public ArgumentVFGNode return cs; } /// Receive parameter at callsite - inline const SVFFunction* getCaller() const + inline const CallGraphNode* getCaller() const { return cs->getCaller(); } @@ -1082,7 +1082,7 @@ class ActualRetVFGNode: public ArgumentVFGNode class FormalRetVFGNode: public ArgumentVFGNode { private: - const SVFFunction* fun; + const CallGraphNode* fun; RetPESet retPEs; FormalRetVFGNode(); ///< place holder @@ -1091,7 +1091,7 @@ class FormalRetVFGNode: public ArgumentVFGNode public: /// Constructor - FormalRetVFGNode(NodeID id, const PAGNode* n, const SVFFunction* f); + FormalRetVFGNode(NodeID id, const PAGNode* n, const CallGraphNode* f); /// Return value at callee inline const PAGNode* getRet() const @@ -1099,7 +1099,7 @@ class FormalRetVFGNode: public ArgumentVFGNode return param; } /// Function - inline const SVFFunction* getFun() const override + inline const CallGraphNode* getFun() const override { return fun; } @@ -1168,7 +1168,7 @@ class InterPHIVFGNode : public PHIVFGNode return (fun!=nullptr) && (callInst != nullptr); } - inline const SVFFunction* getFun() const override + inline const CallGraphNode* getFun() const override { assert((isFormalParmPHI() || isActualRetPHI()) && "expect a formal parameter phi"); return fun; @@ -1207,7 +1207,7 @@ class InterPHIVFGNode : public PHIVFGNode const std::string toString() const override; private: - const SVFFunction* fun; + const CallGraphNode* fun; const CallICFGNode* callInst; }; diff --git a/svf/include/MSSA/MSSAMuChi.h b/svf/include/MSSA/MSSAMuChi.h index 1e5dc0e413..62daa03757 100644 --- a/svf/include/MSSA/MSSAMuChi.h +++ b/svf/include/MSSA/MSSAMuChi.h @@ -277,11 +277,11 @@ template class RetMU : public MSSAMU { private: - const SVFFunction* fun; + const CallGraphNode* fun; public: /// Constructor/Destructor for MU //@{ - RetMU(const SVFFunction* f, const MemRegion* m, Cond c = true) : + RetMU(const CallGraphNode* f, const MemRegion* m, Cond c = true) : MSSAMU(MSSAMU::RetMSSAMU,m,c), fun(f) { } @@ -289,7 +289,7 @@ class RetMU : public MSSAMU //@} /// Return function - inline const SVFFunction* getFunction() const + inline const CallGraphNode* getFunction() const { return fun; } @@ -578,11 +578,11 @@ template class EntryCHI : public MSSACHI { private: - const SVFFunction* fun; + const CallGraphNode* fun; public: /// Constructors for EntryCHI //@{ - EntryCHI(const SVFFunction* f, const MemRegion* m, Cond c = true) : + EntryCHI(const CallGraphNode* f, const MemRegion* m, Cond c = true) : MSSACHI(MSSADEF::EntryMSSACHI,m,c),fun(f) { } @@ -592,7 +592,7 @@ class EntryCHI : public MSSACHI //@} /// Return function - inline const SVFFunction* getFunction() const + inline const CallGraphNode* getFunction() const { return fun; } diff --git a/svf/include/MSSA/MemPartition.h b/svf/include/MSSA/MemPartition.h index 3138f7b585..d74c72e933 100644 --- a/svf/include/MSSA/MemPartition.h +++ b/svf/include/MSSA/MemPartition.h @@ -57,13 +57,13 @@ class DistinctMRG : public MRGenerator virtual void partitionMRs(); /// Get memory region at a load - virtual void getMRsForLoad(MRSet& aliasMRs, const NodeBS& cpts, const SVFFunction* fun); + virtual void getMRsForLoad(MRSet& aliasMRs, const NodeBS& cpts, const CallGraphNode* fun); /// Get memory regions to be inserted at a load statement. - virtual void getMRsForCallSiteRef(MRSet& aliasMRs, const NodeBS& cpts, const SVFFunction* fun); + virtual void getMRsForCallSiteRef(MRSet& aliasMRs, const NodeBS& cpts, const CallGraphNode* fun); private: /// Create memory regions for each points-to target. - void createDistinctMR(const SVFFunction* func, const NodeBS& cpts); + void createDistinctMR(const CallGraphNode* func, const NodeBS& cpts); }; @@ -74,8 +74,8 @@ class IntraDisjointMRG : public MRGenerator { public: typedef OrderedMap PtsToSubPtsMap; - typedef Map FunToPtsMap; - typedef Map FunToInterMap; + typedef Map FunToPtsMap; + typedef Map FunToInterMap; IntraDisjointMRG(BVDataPTAImpl* p, bool ptrOnly) : MRGenerator(p, ptrOnly) {} @@ -94,7 +94,7 @@ class IntraDisjointMRG : public MRGenerator * @param mrs Memory region set contains all possible target memory regions. */ virtual inline void getMRsForLoad(MRSet& aliasMRs, const NodeBS& cpts, - const SVFFunction* fun) + const CallGraphNode* fun) { const PointsToList& inters = getIntersList(fun); getMRsForLoadFromInterList(aliasMRs, cpts, inters); @@ -103,26 +103,26 @@ class IntraDisjointMRG : public MRGenerator void getMRsForLoadFromInterList(MRSet& mrs, const NodeBS& cpts, const PointsToList& inters); /// Get memory regions to be inserted at a load statement. - virtual void getMRsForCallSiteRef(MRSet& aliasMRs, const NodeBS& cpts, const SVFFunction* fun); + virtual void getMRsForCallSiteRef(MRSet& aliasMRs, const NodeBS& cpts, const CallGraphNode* fun); /// Create disjoint memory region - void createDisjointMR(const SVFFunction* func, const NodeBS& cpts); + void createDisjointMR(const CallGraphNode* func, const NodeBS& cpts); /// Compute intersections between cpts and computed cpts intersections before. void computeIntersections(const NodeBS& cpts, PointsToList& inters); private: - inline PtsToSubPtsMap& getPtsSubSetMap(const SVFFunction* func) + inline PtsToSubPtsMap& getPtsSubSetMap(const CallGraphNode* func) { return funcToPtsMap[func]; } - inline PointsToList& getIntersList(const SVFFunction* func) + inline PointsToList& getIntersList(const CallGraphNode* func) { return funcToInterMap[func]; } - inline const PtsToSubPtsMap& getPtsSubSetMap(const SVFFunction* func) const + inline const PtsToSubPtsMap& getPtsSubSetMap(const CallGraphNode* func) const { FunToPtsMap::const_iterator it = funcToPtsMap.find(func); assert(it != funcToPtsMap.end() && "can not find pts map for specified function"); @@ -155,7 +155,7 @@ class InterDisjointMRG : public IntraDisjointMRG * @param mrs Memory region set contains all possible target memory regions. */ virtual inline void getMRsForLoad(MRSet& aliasMRs, const NodeBS& cpts, - const SVFFunction*) + const CallGraphNode*) { getMRsForLoadFromInterList(aliasMRs, cpts, inters); } diff --git a/svf/include/MSSA/MemRegion.h b/svf/include/MSSA/MemRegion.h index d7afe3a82d..807a477127 100644 --- a/svf/include/MSSA/MemRegion.h +++ b/svf/include/MSSA/MemRegion.h @@ -139,14 +139,14 @@ class MRGenerator //@} ///Define mem region set typedef OrderedSet MRSet; - typedef Map PAGEdgeToFunMap; + typedef Map PAGEdgeToFunMap; typedef OrderedSet PointsToList; - typedef Map FunToPointsToMap; - typedef Map FunToPointsTosMap; + typedef Map FunToPointsToMap; + typedef Map FunToPointsTosMap; typedef OrderedMap PtsToRepPtsSetMap; /// Map a function to its region set - typedef Map FunToMRsMap; + typedef Map FunToMRsMap; /// Map loads/stores to its mem regions, /// TODO:visitAtomicCmpXchgInst, visitAtomicRMWInst?? //@{ @@ -165,7 +165,7 @@ class MRGenerator /// Maps Mod-Ref analysis //@{ /// Map a function to its indirect refs/mods of memory objects - typedef Map FunToNodeBSMap; + typedef Map FunToNodeBSMap; /// Map a callsite to its indirect refs/mods of memory objects typedef Map CallSiteToNodeBSMap; //@} @@ -263,7 +263,7 @@ class MRGenerator } /// Whether the object node is a non-local object /// including global, heap, and stack variable in recursions - bool isNonLocalObject(NodeID id, const SVFFunction* curFun) const; + bool isNonLocalObject(NodeID id, const CallGraphNode* curFun) const; /// Get all the objects in callee's modref escaped via global objects (the chain pts of globals) void getEscapObjviaGlobals(NodeBS& globs, const NodeBS& pts); @@ -278,7 +278,7 @@ class MRGenerator PtsToRepPtsSetMap cptsToRepCPtsMap; /// Generate a memory region and put in into functions which use it - void createMR(const SVFFunction* fun, const NodeBS& cpts); + void createMR(const CallGraphNode* fun, const NodeBS& cpts); /// Collect all global variables for later escape analysis void collectGlobals(); @@ -304,7 +304,7 @@ class MRGenerator return mr->getPointsTo().intersects(cpts); } /// Get all aliased mem regions from function fun according to cpts - virtual inline void getAliasMemRegions(MRSet& aliasMRs, const NodeBS& cpts, const SVFFunction* fun) + virtual inline void getAliasMemRegions(MRSet& aliasMRs, const NodeBS& cpts, const CallGraphNode* fun) { for(MRSet::const_iterator it = funToMRsMap[fun].begin(), eit = funToMRsMap[fun].end(); it!=eit; ++it) { @@ -314,14 +314,14 @@ class MRGenerator } /// Get memory regions for a load statement according to cpts. - virtual inline void getMRsForLoad(MRSet& aliasMRs, const NodeBS& cpts, const SVFFunction*) + virtual inline void getMRsForLoad(MRSet& aliasMRs, const NodeBS& cpts, const CallGraphNode*) { const MemRegion* mr = getMR(cpts); aliasMRs.insert(mr); } /// Get memory regions for call site ref according to cpts. - virtual inline void getMRsForCallSiteRef(MRSet& aliasMRs, const NodeBS& cpts, const SVFFunction*) + virtual inline void getMRsForCallSiteRef(MRSet& aliasMRs, const NodeBS& cpts, const CallGraphNode*) { const MemRegion* mr = getMR(cpts); aliasMRs.insert(mr); @@ -331,18 +331,18 @@ class MRGenerator virtual void modRefAnalysis(PTACallGraphNode* callGraphNode, WorkList& worklist); /// Get Mod-Ref of a callee function - virtual bool handleCallsiteModRef(NodeBS& mod, NodeBS& ref, const CallICFGNode* cs, const SVFFunction* fun); + virtual bool handleCallsiteModRef(NodeBS& mod, NodeBS& ref, const CallICFGNode* cs, const CallGraphNode* fun); /// Add cpts to store/load //@{ - inline void addCPtsToStore(NodeBS& cpts, const StoreStmt *st, const SVFFunction* fun) + inline void addCPtsToStore(NodeBS& cpts, const StoreStmt *st, const CallGraphNode* fun) { storesToPointsToMap[st] = cpts; funToPointsToMap[fun].insert(cpts); addModSideEffectOfFunction(fun,cpts); } - inline void addCPtsToLoad(NodeBS& cpts, const LoadStmt *ld, const SVFFunction* fun) + inline void addCPtsToLoad(NodeBS& cpts, const LoadStmt *ld, const CallGraphNode* fun) { loadsToPointsToMap[ld] = cpts; funToPointsToMap[fun].insert(cpts); @@ -358,11 +358,11 @@ class MRGenerator callsiteToModPointsToMap[cs] |= cpts; funToPointsToMap[cs->getCaller()].insert(cpts); } - inline bool hasCPtsList(const SVFFunction* fun) const + inline bool hasCPtsList(const CallGraphNode* fun) const { return funToPointsToMap.find(fun)!=funToPointsToMap.end(); } - inline PointsToList& getPointsToList(const SVFFunction* fun) + inline PointsToList& getPointsToList(const CallGraphNode* fun) { return funToPointsToMap[fun]; } @@ -374,21 +374,21 @@ class MRGenerator /// Add/Get methods for side-effect of functions and callsites //@{ /// Add indirect uses an memory object in the function - void addRefSideEffectOfFunction(const SVFFunction* fun, const NodeBS& refs); + void addRefSideEffectOfFunction(const CallGraphNode* fun, const NodeBS& refs); /// Add indirect def an memory object in the function - void addModSideEffectOfFunction(const SVFFunction* fun, const NodeBS& mods); + void addModSideEffectOfFunction(const CallGraphNode* fun, const NodeBS& mods); /// Add indirect uses an memory object in the function bool addRefSideEffectOfCallSite(const CallICFGNode* cs, const NodeBS& refs); /// Add indirect def an memory object in the function bool addModSideEffectOfCallSite(const CallICFGNode* cs, const NodeBS& mods); /// Get indirect refs of a function - inline const NodeBS& getRefSideEffectOfFunction(const SVFFunction* fun) + inline const NodeBS& getRefSideEffectOfFunction(const CallGraphNode* fun) { return funToRefsMap[fun]; } /// Get indirect mods of a function - inline const NodeBS& getModSideEffectOfFunction(const SVFFunction* fun) + inline const NodeBS& getModSideEffectOfFunction(const CallGraphNode* fun) { return funToModsMap[fun]; } @@ -430,7 +430,7 @@ class MRGenerator virtual void generateMRs(); /// Get the function which SVFIR Edge located - const SVFFunction* getFunction(const PAGEdge* pagEdge) const + const CallGraphNode* getFunction(const PAGEdge* pagEdge) const { PAGEdgeToFunMap::const_iterator it = pagEdgeToFunMap.find(pagEdge); assert(it!=pagEdgeToFunMap.end() && "can not find its function, it is a global SVFIR edge"); @@ -438,7 +438,7 @@ class MRGenerator } /// Get Memory Region set //@{ - inline MRSet& getFunMRSet(const SVFFunction* fun) + inline MRSet& getFunMRSet(const CallGraphNode* fun) { return funToMRsMap[fun]; } diff --git a/svf/include/MSSA/MemSSA.h b/svf/include/MSSA/MemSSA.h index 3424095a65..cc5b5c47b4 100644 --- a/svf/include/MSSA/MemSSA.h +++ b/svf/include/MSSA/MemSSA.h @@ -85,8 +85,8 @@ class MemSSA //@} /// Map from fun to its entry chi set and return mu set - typedef Map FunToEntryChiSetMap; - typedef Map FunToReturnMuSetMap; + typedef Map FunToEntryChiSetMap; + typedef Map FunToReturnMuSetMap; /// For phi insertion //@{ @@ -123,11 +123,11 @@ class MemSSA MemSSAStat* stat; /// Create mu chi for candidate regions in a function - virtual void createMUCHI(const SVFFunction& fun); + virtual void createMUCHI(const CallGraphNode& fun); /// Insert phi for candidate regions in a function - virtual void insertPHI(const SVFFunction& fun); + virtual void insertPHI(const CallGraphNode& fun); /// SSA rename for a function - virtual void SSARename(const SVFFunction& fun); + virtual void SSARename(const CallGraphNode& fun); /// SSA rename for a basic block virtual void SSARenameBB(const SVFBasicBlock& bb); private: @@ -315,7 +315,7 @@ class MemSSA return mrGen; } /// We start from here - virtual void buildMemSSA(const SVFFunction& fun); + virtual void buildMemSSA(const CallGraphNode& fun); /// Perform statistics void performStat(); @@ -357,20 +357,20 @@ class MemSSA /// Has function entry chi or return mu //@{ - inline bool hasFuncEntryChi(const SVFFunction * fun) const + inline bool hasFuncEntryChi(const CallGraphNode * fun) const { return (funToEntryChiSetMap.find(fun) != funToEntryChiSetMap.end()); } - inline bool hasReturnMu(const SVFFunction * fun) const + inline bool hasReturnMu(const CallGraphNode * fun) const { return (funToReturnMuSetMap.find(fun) != funToReturnMuSetMap.end()); } - inline CHISet& getFuncEntryChiSet(const SVFFunction * fun) + inline CHISet& getFuncEntryChiSet(const CallGraphNode * fun) { return funToEntryChiSetMap[fun]; } - inline MUSet& getReturnMuSet(const SVFFunction * fun) + inline MUSet& getReturnMuSet(const CallGraphNode * fun) { return funToReturnMuSetMap[fun]; } diff --git a/svf/include/MTA/LockAnalysis.h b/svf/include/MTA/LockAnalysis.h index 6fa47bd093..dea99f7194 100644 --- a/svf/include/MTA/LockAnalysis.h +++ b/svf/include/MTA/LockAnalysis.h @@ -61,7 +61,7 @@ class LockAnalysis typedef Set InstSet; typedef InstSet CISpan; typedef MapCILockToSpan; - typedef Set FunSet; + typedef Set FunSet; typedef Map InstToInstSetMap; typedef Map CxtStmtToLockFlagMap; typedef FIFOWorkList CxtStmtWorkList; @@ -192,7 +192,7 @@ class LockAnalysis //@} /// Return true if it is a candidate function - inline bool isLockCandidateFun(const SVFFunction* fun) const + inline bool isLockCandidateFun(const CallGraphNode* fun) const { return lockcandidateFuncSet.find(fun)!=lockcandidateFuncSet.end(); } @@ -430,9 +430,9 @@ class LockAnalysis //@} /// Push calling context - void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee); + void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const CallGraphNode* callee); /// Match context - bool matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee); + bool matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const CallGraphNode* callee); /// Whether it is a lock site inline bool isTDFork(const ICFGNode* call) diff --git a/svf/include/MTA/MHP.h b/svf/include/MTA/MHP.h index df4aef72ec..d93c738af0 100644 --- a/svf/include/MTA/MHP.h +++ b/svf/include/MTA/MHP.h @@ -46,7 +46,7 @@ class MHP { public: - typedef Set FunSet; + typedef Set FunSet; typedef FIFOWorkList CxtThreadStmtWorkList; typedef Set CxtThreadStmtSet; typedef Map ThreadStmtToThreadInterleav; @@ -55,7 +55,7 @@ class MHP typedef Set LockSpan; - typedef std::pair FuncPair; + typedef std::pair FuncPair; typedef Map FuncPairToBool; /// Constructor @@ -83,7 +83,7 @@ class MHP } /// Whether the function is connected from main function in thread call graph - bool isConnectedfromMain(const SVFFunction* fun); + bool isConnectedfromMain(const CallGraphNode* fun); // LockSpan getSpanfromCxtLock(NodeID l); /// Interface to query whether two instructions may happen-in-parallel @@ -202,12 +202,12 @@ class MHP return tct->getTCTNode(curTid)->isMultiforked(); } /// Push calling context - inline void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee) + inline void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const CallGraphNode* callee) { tct->pushCxt(cxt,call,callee); } /// Match context - inline bool matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee) + inline bool matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const CallGraphNode* callee) { return tct->matchCxt(cxt,call,callee); } @@ -342,7 +342,7 @@ class ForkJoinAnalysis { NodeID parentTid = tct->getParentThread(tid); const CxtThread& parentct = tct->getTCTNode(parentTid)->getCxtThread(); - const SVFFunction* parentRoutine = tct->getStartRoutineOfCxtThread(parentct); + const CallGraphNode* parentRoutine = tct->getStartRoutineOfCxtThread(parentct); return parentRoutine->getExitBB()->back(); } @@ -450,12 +450,12 @@ class ForkJoinAnalysis //@} /// Push calling context - inline void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee) + inline void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const CallGraphNode* callee) { tct->pushCxt(cxt,call,callee); } /// Match context - inline bool matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee) + inline bool matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const CallGraphNode* callee) { return tct->matchCxt(cxt,call,callee); } diff --git a/svf/include/MTA/TCT.h b/svf/include/MTA/TCT.h index 05eca06a16..6a34616e09 100644 --- a/svf/include/MTA/TCT.h +++ b/svf/include/MTA/TCT.h @@ -157,13 +157,13 @@ class TCT: public GenericThreadCreateTreeTy typedef SVFLoopAndDomInfo::LoopBBs LoopBBs; typedef TCTEdge::ThreadCreateEdgeSet ThreadCreateEdgeSet; typedef ThreadCreateEdgeSet::iterator TCTNodeIter; - typedef Set FunSet; + typedef Set FunSet; typedef std::vector InstVec; typedef Set InstSet; typedef Set PTACGNodeSet; typedef Map CxtThreadToNodeMap; typedef Map CxtThreadToForkCxt; - typedef Map CxtThreadToFun; + typedef Map CxtThreadToFun; typedef Map InstToLoopMap; typedef FIFOWorkList CxtThreadProcVec; typedef Set CxtThreadProcSet; @@ -293,12 +293,12 @@ class TCT: public GenericThreadCreateTreeTy for(PTACallGraph::FunctionSet::const_iterator cit = callees.begin(), ecit = callees.end(); cit!=ecit; cit++) { - if(candidateFuncSet.find((*cit))!=candidateFuncSet.end()) + if(candidateFuncSet.find(*cit)!=candidateFuncSet.end()) return true; } return false; } - inline bool isCandidateFun(const SVFFunction* fun) const + inline bool isCandidateFun(const CallGraphNode* fun) const { return candidateFuncSet.find(fun)!=candidateFuncSet.end(); } @@ -374,7 +374,7 @@ class TCT: public GenericThreadCreateTreeTy } /// get the start routine function of a thread - const SVFFunction* getStartRoutineOfCxtThread(const CxtThread& ct) const + const CallGraphNode* getStartRoutineOfCxtThread(const CxtThread& ct) const { CxtThreadToFun::const_iterator it = ctToRoutineFunMap.find(ct); assert(it!=ctToRoutineFunMap.end() && "Cxt Thread not found!!"); @@ -399,7 +399,7 @@ class TCT: public GenericThreadCreateTreeTy bool hasLoop(const SVFBasicBlock* bb) const { - const SVFFunction* fun = bb->getFunction(); + const CallGraphNode* fun = bb->getFunction(); return fun->hasLoopInfo(bb); } bool hasLoop(const ICFGNode* inst) const @@ -414,9 +414,9 @@ class TCT: public GenericThreadCreateTreeTy const LoopBBs& getLoop(const SVFBasicBlock* bb); /// Push calling context - void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee); + void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const CallGraphNode* callee); /// Match context - bool matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee); + bool matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const CallGraphNode* callee); inline void pushCxt(CallStrCxt& cxt, CallSiteID csId) { @@ -477,7 +477,7 @@ class TCT: public GenericThreadCreateTreeTy /// Mark relevant procedures that are backward reachable from any fork/join site //@{ void markRelProcs(); - void markRelProcs(const SVFFunction* fun); + void markRelProcs(const CallGraphNode* cgFun); //@} /// Get entry functions that are neither called by other functions nor extern functions @@ -510,7 +510,7 @@ class TCT: public GenericThreadCreateTreeTy /// Get or create a tct node based on CxtThread //@{ - inline TCTNode* getOrCreateTCTNode(const CallStrCxt& cxt, const ICFGNode* fork,const CallStrCxt& oldCxt, const SVFFunction* routine) + inline TCTNode* getOrCreateTCTNode(const CallStrCxt& cxt, const ICFGNode* fork,const CallStrCxt& oldCxt, const CallGraphNode* routine) { CxtThread ct(cxt,fork); CxtThreadToNodeMap::const_iterator it = ctpToNodeMap.find(ct); @@ -551,7 +551,7 @@ class TCT: public GenericThreadCreateTreeTy ctToForkCxtMap[ct] = cxt; } /// Add start routine function of a cxt thread - void addStartRoutineOfCxtThread(const SVFFunction* fun, const CxtThread& ct) + void addStartRoutineOfCxtThread(const CallGraphNode* fun, const CxtThread& ct) { ctToRoutineFunMap[ct] = fun; } diff --git a/svf/include/MemoryModel/PointerAnalysis.h b/svf/include/MemoryModel/PointerAnalysis.h index 62b402ccf9..2a783d751a 100644 --- a/svf/include/MemoryModel/PointerAnalysis.h +++ b/svf/include/MemoryModel/PointerAnalysis.h @@ -101,11 +101,11 @@ class PointerAnalysis //@{ typedef Set CallSiteSet; typedef SVFIR::CallSiteToFunPtrMap CallSiteToFunPtrMap; - typedef Set FunctionSet; + typedef Set FunctionSet; typedef OrderedMap CallEdgeMap; typedef SCCDetection CallGraphSCC; typedef Set VTableSet; - typedef Set VFunSet; + typedef Set VFunSet; //@} static const std::string aliasTestMayAlias; @@ -396,15 +396,18 @@ class PointerAnalysis return callGraphSCC->repNode(id); } /// Return TRUE if this edge is inside a PTACallGraph SCC, i.e., src node and dst node are in the same SCC on the SVFG. - inline bool inSameCallGraphSCC(const SVFFunction* fun1,const SVFFunction* fun2) + inline bool inSameCallGraphSCC(const CallGraphNode* fun1,const CallGraphNode* fun2) { - const PTACallGraphNode* src = callgraph->getCallGraphNode(fun1); - const PTACallGraphNode* dst = callgraph->getCallGraphNode(fun2); + const PTACallGraphNode* src = + callgraph->getPTACallGraphNode(fun1); + const PTACallGraphNode* dst = + callgraph->getPTACallGraphNode(fun2); return (getCallGraphSCCRepNode(src->getId()) == getCallGraphSCCRepNode(dst->getId())); } - inline bool isInRecursion(const SVFFunction* fun) const + inline bool isInRecursion(const CallGraphNode* fun) const { - return callGraphSCC->isInCycle(callgraph->getCallGraphNode(fun)->getId()); + return callGraphSCC->isInCycle( + fun->getId()); } /// Whether a local variable is in function recursions bool isLocalVarInRecursiveFun(NodeID id) const; diff --git a/svf/include/SABER/DoubleFreeChecker.h b/svf/include/SABER/DoubleFreeChecker.h index 786a49db8e..1ec064be1a 100644 --- a/svf/include/SABER/DoubleFreeChecker.h +++ b/svf/include/SABER/DoubleFreeChecker.h @@ -67,8 +67,8 @@ class DoubleFreeChecker : public LeakChecker /// Validate test cases for regression test purpose void testsValidation(ProgSlice* slice); - void validateSuccessTests(ProgSlice* slice, const SVFFunction* fun); - void validateExpectedFailureTests(ProgSlice* slice, const SVFFunction* fun); + void validateSuccessTests(ProgSlice* slice, const CallGraphNode* fun); + void validateExpectedFailureTests(ProgSlice* slice, const CallGraphNode* fun); }; } // End namespace SVF diff --git a/svf/include/SABER/FileChecker.h b/svf/include/SABER/FileChecker.h index ddcc1d4e2e..44097796a0 100644 --- a/svf/include/SABER/FileChecker.h +++ b/svf/include/SABER/FileChecker.h @@ -62,12 +62,12 @@ class FileChecker : public LeakChecker return false; } - inline bool isSourceLikeFun(const SVFFunction* fun) + inline bool isSourceLikeFun(const CallGraphNode* fun) { return SaberCheckerAPI::getCheckerAPI()->isFOpen(fun); } /// Whether the function is a heap deallocator (free/release memory) - inline bool isSinkLikeFun(const SVFFunction* fun) + inline bool isSinkLikeFun(const CallGraphNode* fun) { return SaberCheckerAPI::getCheckerAPI()->isFClose(fun); } diff --git a/svf/include/SABER/LeakChecker.h b/svf/include/SABER/LeakChecker.h index 2328adaa6f..232b69c470 100644 --- a/svf/include/SABER/LeakChecker.h +++ b/svf/include/SABER/LeakChecker.h @@ -78,12 +78,12 @@ class LeakChecker : public SrcSnkDDA virtual void initSrcs() override; virtual void initSnks() override; /// Whether the function is a heap allocator/reallocator (allocate memory) - virtual inline bool isSourceLikeFun(const SVFFunction* fun) override + virtual inline bool isSourceLikeFun(const CallGraphNode* fun) override { return SaberCheckerAPI::getCheckerAPI()->isMemAlloc(fun); } /// Whether the function is a heap deallocator (free/release memory) - virtual inline bool isSinkLikeFun(const SVFFunction* fun) override + virtual inline bool isSinkLikeFun(const CallGraphNode* fun) override { return SaberCheckerAPI::getCheckerAPI()->isMemDealloc(fun); } @@ -97,8 +97,8 @@ class LeakChecker : public SrcSnkDDA /// Validate test cases for regression test purpose void testsValidation(const ProgSlice* slice); - void validateSuccessTests(const SVFGNode* source, const SVFFunction* fun); - void validateExpectedFailureTests(const SVFGNode* source, const SVFFunction* fun); + void validateSuccessTests(const SVFGNode* source, const CallGraphNode* fun); + void validateExpectedFailureTests(const SVFGNode* source, const CallGraphNode* fun); /// Record a source to its callsite //@{ diff --git a/svf/include/SABER/SaberCheckerAPI.h b/svf/include/SABER/SaberCheckerAPI.h index 812506445c..bb73f741de 100644 --- a/svf/include/SABER/SaberCheckerAPI.h +++ b/svf/include/SABER/SaberCheckerAPI.h @@ -73,16 +73,7 @@ class SaberCheckerAPI static SaberCheckerAPI* ckAPI; /// Get the function type of a function - inline CHECKER_TYPE getType(const SVFFunction* F) const - { - if(F) - { - TDAPIMap::const_iterator it= tdAPIMap.find(F->getName()); - if(it != tdAPIMap.end()) - return it->second; - } - return CK_DUMMY; - } + CHECKER_TYPE getType(const CallGraphNode* F) const; public: /// Return a static reference @@ -97,7 +88,7 @@ class SaberCheckerAPI /// Return true if this call is a memory allocation //@{ - inline bool isMemAlloc(const SVFFunction* fun) const + inline bool isMemAlloc(const CallGraphNode* fun) const { return getType(fun) == CK_ALLOC; } @@ -109,7 +100,7 @@ class SaberCheckerAPI /// Return true if this call is a memory deallocation //@{ - inline bool isMemDealloc(const SVFFunction* fun) const + inline bool isMemDealloc(const CallGraphNode* fun) const { return getType(fun) == CK_FREE; } @@ -121,7 +112,7 @@ class SaberCheckerAPI /// Return true if this call is a file open //@{ - inline bool isFOpen(const SVFFunction* fun) const + inline bool isFOpen(const CallGraphNode* fun) const { return getType(fun) == CK_FOPEN; } @@ -133,7 +124,7 @@ class SaberCheckerAPI /// Return true if this call is a file close //@{ - inline bool isFClose(const SVFFunction* fun) const + inline bool isFClose(const CallGraphNode* fun) const { return getType(fun) == CK_FCLOSE; } diff --git a/svf/include/SABER/SaberCondAllocator.h b/svf/include/SABER/SaberCondAllocator.h index a90088f721..36a0833e03 100644 --- a/svf/include/SABER/SaberCondAllocator.h +++ b/svf/include/SABER/SaberCondAllocator.h @@ -53,7 +53,7 @@ class SaberCondAllocator typedef Map CondPosMap; ///< map a branch to its Condition typedef Map BBCondMap; /// map bb to a Condition typedef Set BasicBlockSet; - typedef Map FunToExitBBsMap; ///< map a function to all its basic blocks calling program exit + typedef Map FunToExitBBsMap; ///< map a function to all its basic blocks calling program exit typedef Map BBToCondMap; ///< map a basic block to its condition during control-flow guard computation typedef FIFOWorkList CFWorkList; ///< worklist for control-flow guard computation typedef Map> SVFGNodeToSVFGNodeSetMap; @@ -146,8 +146,8 @@ class SaberCondAllocator inline bool postDominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const { - const SVFFunction* keyFunc = bbKey->getParent(); - const SVFFunction* valueFunc = bbValue->getParent(); + const CallGraphNode* keyFunc = bbKey->getParent(); + const CallGraphNode* valueFunc = bbValue->getParent(); bool funcEq = (keyFunc == valueFunc); (void)funcEq; // Suppress warning of unused variable under release build assert(funcEq && "two basicblocks should be in the same function!"); @@ -156,8 +156,8 @@ class SaberCondAllocator inline bool dominate(const SVFBasicBlock* bbKey, const SVFBasicBlock* bbValue) const { - const SVFFunction* keyFunc = bbKey->getParent(); - const SVFFunction* valueFunc = bbValue->getParent(); + const CallGraphNode* keyFunc = bbKey->getParent(); + const CallGraphNode* valueFunc = bbValue->getParent(); bool funcEq = (keyFunc == valueFunc); (void)funcEq; // Suppress warning of unused variable under release build assert(funcEq && "two basicblocks should be in the same function!"); diff --git a/svf/include/SABER/SrcSnkDDA.h b/svf/include/SABER/SrcSnkDDA.h index 150946b472..0c191dafe9 100644 --- a/svf/include/SABER/SrcSnkDDA.h +++ b/svf/include/SABER/SrcSnkDDA.h @@ -174,12 +174,12 @@ class SrcSnkDDA : public CFLSrcSnkSolver ///@{ virtual void initSrcs() = 0; virtual void initSnks() = 0; - virtual bool isSourceLikeFun(const SVFFunction* fun) + virtual bool isSourceLikeFun(const CallGraphNode* fun) { return false; } - virtual bool isSinkLikeFun(const SVFFunction* fun) + virtual bool isSinkLikeFun(const CallGraphNode* fun) { return false; } diff --git a/svf/include/SVFIR/SVFIR.h b/svf/include/SVFIR/SVFIR.h index 61d8c98c08..fb0855e605 100644 --- a/svf/include/SVFIR/SVFIR.h +++ b/svf/include/SVFIR/SVFIR.h @@ -58,12 +58,12 @@ class SVFIR : public IRGraph typedef std::vector SVFStmtList; typedef std::vector SVFVarList; typedef Map PHINodeMap; - typedef Map FunToArgsListMap; + typedef Map FunToArgsListMap; typedef Map CSToArgsListMap; typedef Map CSToRetMap; - typedef Map FunToRetMap; + typedef Map FunToRetMap; typedef Map FunToFunObjVarMap; - typedef Map FunToPAGEdgeSetMap; + typedef Map FunToPAGEdgeSetMap; typedef Map ICFGNode2SVFStmtsMap; typedef Map NodeToNodeMap; typedef std::pair NodeOffset; @@ -264,7 +264,7 @@ class SVFIR : public IRGraph } /// Function has arguments list - inline bool hasFunArgsList(const SVFFunction* func) const + inline bool hasFunArgsList(const CallGraphNode* func) const { return (funArgsListMap.find(func) != funArgsListMap.end()); } @@ -274,7 +274,7 @@ class SVFIR : public IRGraph return funArgsListMap; } /// Get function arguments list - inline const SVFVarList& getFunArgsList(const SVFFunction* func) const + inline const SVFVarList& getFunArgsList(const CallGraphNode* func) const { FunToArgsListMap::const_iterator it = funArgsListMap.find(func); assert(it != funArgsListMap.end() && "this function doesn't have arguments"); @@ -319,13 +319,13 @@ class SVFIR : public IRGraph return funRetMap; } /// Get function return list - inline const SVFVar* getFunRet(const SVFFunction* func) const + inline const SVFVar* getFunRet(const CallGraphNode* func) const { FunToRetMap::const_iterator it = funRetMap.find(func); assert(it != funRetMap.end() && "this function doesn't have return"); return it->second; } - inline bool funHasRet(const SVFFunction* func) const + inline bool funHasRet(const CallGraphNode* func) const { return funRetMap.find(func) != funRetMap.end(); } @@ -504,14 +504,14 @@ class SVFIR : public IRGraph /// Get/set method for function/callsite arguments and returns //@{ /// Add function arguments - inline void addFunArgs(const SVFFunction* fun, const SVFVar* arg) + inline void addFunArgs(const CallGraphNode* fun, const SVFVar* arg) { FunEntryICFGNode* funEntryBlockNode = icfg->getFunEntryICFGNode(fun); funEntryBlockNode->addFormalParms(arg); funArgsListMap[fun].push_back(arg); } /// Add function returns - inline void addFunRet(const SVFFunction* fun, const SVFVar* ret) + inline void addFunRet(const CallGraphNode* fun, const SVFVar* ret) { FunExitICFGNode* funExitBlockNode = icfg->getFunExitICFGNode(fun); funExitBlockNode->addFormalRet(ret); @@ -763,7 +763,7 @@ class SVFIR : public IRGraph return addNode(node); } /// Add a unique vararg node for a procedure - inline NodeID addVarargNode(const SVFFunction*, SVFVar *node) + inline NodeID addVarargNode(const CallGraphNode*, SVFVar *node) { return addNode(node); } diff --git a/svf/include/SVFIR/SVFModule.h b/svf/include/SVFIR/SVFModule.h index c4735cb197..12970c5d23 100644 --- a/svf/include/SVFIR/SVFModule.h +++ b/svf/include/SVFIR/SVFModule.h @@ -43,7 +43,7 @@ class SVFModule friend class SVFIRReader; public: - typedef std::vector FunctionSetType; + typedef std::vector FunctionSetType; typedef std::vector GlobalSetType; typedef std::vector AliasSetType; typedef std::vector ConstantType; @@ -100,10 +100,10 @@ class SVFModule return !pagReadFromTxt.empty(); } - const SVFFunction* getSVFFunction(const std::string& name); + const CallGraphNode* getSVFFunction(const std::string& name); ///@{ - inline void addFunctionSet(SVFFunction* svfFunc) + inline void addFunctionSet(CallGraphNode* svfFunc) { FunctionSet.push_back(svfFunc); } diff --git a/svf/include/SVFIR/SVFValue.h b/svf/include/SVFIR/SVFValue.h index f14ce91d8f..ae5b025197 100644 --- a/svf/include/SVFIR/SVFValue.h +++ b/svf/include/SVFIR/SVFValue.h @@ -324,7 +324,7 @@ class SVFFunction : public SVFValue BasicBlockGraph* bbGraph; /// the basic block graph of this function protected: - inline void setCallGraphNode(CallGraphNode *cgn) + inline void setCallGraphNode(const CallGraphNode *cgn) { callGraphNode = cgn; } @@ -365,7 +365,7 @@ class SVFFunction : public SVFValue return node->getKind() == SVFFunc; } - inline SVFLoopAndDomInfo* getLoopAndDomInfo() + inline SVFLoopAndDomInfo* getLoopAndDomInfo() const { return loopAndDom; } @@ -421,6 +421,10 @@ class SVFFunction : public SVFValue u32_t arg_size() const; const ArgValVar* getArg(u32_t idx) const; bool isVarArg() const; + inline const std::vector getArgsList() const + { + return allArgs; + } inline bool hasBasicBlock() const { @@ -561,7 +565,7 @@ class SVFInstruction : public SVFValue return bb; } - inline const SVFFunction* getFunction() const + inline const CallGraphNode* getFunction() const { return bb->getParent(); } @@ -640,7 +644,7 @@ class SVFCallInst : public SVFInstruction { return SVFUtil::dyn_cast(calledVal); } - inline const SVFFunction* getCaller() const + inline const CallGraphNode* getCaller() const { return getFunction(); } diff --git a/svf/include/SVFIR/SVFVariables.h b/svf/include/SVFIR/SVFVariables.h index 3a4900c44d..f10bf970fe 100644 --- a/svf/include/SVFIR/SVFVariables.h +++ b/svf/include/SVFIR/SVFVariables.h @@ -101,7 +101,7 @@ class SVFVar : public GenericPAGNodeTy virtual const std::string getValueName() const = 0; /// Get containing function, or null for globals/constants - virtual inline const SVFFunction* getFunction() const + virtual inline const CallGraphNode* getFunction() const { return nullptr; } @@ -183,17 +183,7 @@ class SVFVar : public GenericPAGNodeTy } /// Check if this pointer is in an uncalled function - inline virtual bool ptrInUncalledFunction() const - { - if (const SVFFunction* fun = getFunction()) - { - return fun->isUncalledFunction(); - } - else - { - return false; - } - } + virtual bool ptrInUncalledFunction() const; /// Check if this variable represents constant/aggregate data virtual bool isConstDataOrAggData() const @@ -302,7 +292,7 @@ class ValVar: public SVFVar return icfgNode; } - virtual const SVFFunction* getFunction() const; + virtual const CallGraphNode* getFunction() const; virtual const std::string toString() const; }; @@ -408,9 +398,9 @@ class ArgValVar: public ValVar return getName() + " (argument valvar)"; } - virtual const SVFFunction* getFunction() const; + virtual const CallGraphNode* getFunction() const; - const SVFFunction* getParent() const; + const CallGraphNode* getParent() const; /// Return the index of this formal argument in its containing function. /// For example in "void foo(int a, float b)" a is 0 and b is 1. @@ -419,10 +409,7 @@ class ArgValVar: public ValVar return argNo; } - inline bool isArgOfUncalledFunction() const - { - return getFunction()->isUncalledFunction(); - } + bool isArgOfUncalledFunction() const; virtual bool isPointer() const; @@ -506,7 +493,7 @@ class GepValVar: public ValVar return gepValType; } - virtual const SVFFunction* getFunction() const + virtual const CallGraphNode* getFunction() const { return base->getFunction(); } @@ -725,7 +712,7 @@ class BaseObjVar : public ObjVar typeInfo = nullptr; } - virtual const SVFFunction* getFunction() const; + virtual const CallGraphNode* getFunction() const; }; @@ -807,7 +794,7 @@ class GepObjVar: public ObjVar return getName() + "_" + std::to_string(apOffset); } - virtual const SVFFunction* getFunction() const + virtual const CallGraphNode* getFunction() const { return base->getFunction(); } @@ -1061,7 +1048,7 @@ class FunObjVar : public BaseObjVar return callGraphNode; } - virtual const SVFFunction* getFunction() const; + virtual const CallGraphNode* getFunction() const; virtual bool isPointer() const; @@ -1820,7 +1807,7 @@ class RetValPN : public ValVar return callGraphNode; } - virtual const SVFFunction* getFunction() const; + virtual const CallGraphNode* getFunction() const; virtual bool isPointer() const; @@ -1874,7 +1861,7 @@ class VarArgValPN : public ValVar { } - virtual const SVFFunction* getFunction() const; + virtual const CallGraphNode* getFunction() const; /// Return name of a LLVM value const std::string getValueName() const; diff --git a/svf/include/Util/CDGBuilder.h b/svf/include/Util/CDGBuilder.h index d7135f1756..a76bd32ae1 100644 --- a/svf/include/Util/CDGBuilder.h +++ b/svf/include/Util/CDGBuilder.h @@ -67,7 +67,7 @@ class CDGBuilder /// extract basic block edges to be processed static void - extractBBS(const SVFFunction *func, + extractBBS(const CallGraphNode *func, Map> &res); /// extract nodes between two nodes in pdom tree diff --git a/svf/include/Util/CallGraphBuilder.h b/svf/include/Util/CallGraphBuilder.h index 337d30e223..15a09627ed 100644 --- a/svf/include/Util/CallGraphBuilder.h +++ b/svf/include/Util/CallGraphBuilder.h @@ -47,7 +47,9 @@ class CallGraphBuilder CallGraphBuilder()=default; /// Buidl SVFIR callgraoh - CallGraph* buildSVFIRCallGraph(SVFModule* svfModule); + CallGraph* createSVFIRCallGraph(); + + void addSVFIRCallGraphEdges(CallGraph* callGraph); /// Buidl PTA callgraoh PTACallGraph* buildPTACallGraph(); diff --git a/svf/include/Util/CxtStmt.h b/svf/include/Util/CxtStmt.h index edcf7811cd..7b23d447ab 100644 --- a/svf/include/Util/CxtStmt.h +++ b/svf/include/Util/CxtStmt.h @@ -310,7 +310,7 @@ class CxtProc { public: /// Constructor - CxtProc(const CallStrCxt& c, const SVFFunction* f) : + CxtProc(const CallStrCxt& c, const CallGraphNode* f) : cxt(c), fun(f) { } @@ -324,7 +324,7 @@ class CxtProc { } /// Return current procedure - inline const SVFFunction* getProc() const + inline const CallGraphNode* getProc() const { return fun; } @@ -383,7 +383,7 @@ class CxtProc protected: CallStrCxt cxt; - const SVFFunction* fun; + const CallGraphNode* fun; }; @@ -397,7 +397,7 @@ class CxtThreadProc : public CxtProc { public: /// Constructor - CxtThreadProc(NodeID t, const CallStrCxt& c, const SVFFunction* f) :CxtProc(c,f),tid(t) + CxtThreadProc(NodeID t, const CallStrCxt& c, const CallGraphNode* f) :CxtProc(c,f),tid(t) { } /// Copy constructor @@ -494,8 +494,8 @@ template <> struct std::hash { size_t operator()(const SVF::CxtProc& cs) const { - std::hash h; - SVF::SVFFunction* fun = const_cast (cs.getProc()); + std::hash h; + SVF::CallGraphNode* fun = const_cast (cs.getProc()); return h(fun); } }; diff --git a/svf/include/Util/ExtAPI.h b/svf/include/Util/ExtAPI.h index d948628779..aa2b2731e0 100644 --- a/svf/include/Util/ExtAPI.h +++ b/svf/include/Util/ExtAPI.h @@ -48,8 +48,8 @@ class ExtAPI static ExtAPI *extOp; - // Map SVFFunction to its annotations - Map> func2Annotations; + // Map CallGraphNode to its annotations + Map> func2Annotations; // extapi.bc file path static std::string extBcPath; @@ -69,44 +69,44 @@ class ExtAPI std::string getExtBcPath(); // Get the annotation of (F) - std::string getExtFuncAnnotation(const SVFFunction* fun, const std::string& funcAnnotation); + std::string getExtFuncAnnotation(const CallGraphNode* fun, const std::string& funcAnnotation); - const std::vector& getExtFuncAnnotations(const SVFFunction* fun); + const std::vector& getExtFuncAnnotations(const CallGraphNode* fun); // Does (F) have some annotation? - bool hasExtFuncAnnotation(const SVFFunction* fun, const std::string& funcAnnotation); + bool hasExtFuncAnnotation(const CallGraphNode* fun, const std::string& funcAnnotation); // Does (F) have a static var X (unavailable to us) that its return points to? - bool has_static(const SVFFunction *F); + bool has_static(const CallGraphNode *F); // Does (F) have a memcpy_like operation? - bool is_memcpy(const SVFFunction *F); + bool is_memcpy(const CallGraphNode *F); // Does (F) have a memset_like operation? - bool is_memset(const SVFFunction *F); + bool is_memset(const CallGraphNode *F); // Does (F) allocate a new object and return it? - bool is_alloc(const SVFFunction *F); + bool is_alloc(const CallGraphNode *F); // Does (F) allocate a new object and assign it to one of its arguments? - bool is_arg_alloc(const SVFFunction *F); + bool is_arg_alloc(const CallGraphNode *F); // Does (F) allocate a new stack object and return it? - bool is_alloc_stack_ret(const SVFFunction *F); + bool is_alloc_stack_ret(const CallGraphNode *F); // Get the position of argument which holds the new object - s32_t get_alloc_arg_pos(const SVFFunction *F); + s32_t get_alloc_arg_pos(const CallGraphNode *F); // Does (F) reallocate a new object? - bool is_realloc(const SVFFunction *F); + bool is_realloc(const CallGraphNode *F); // Should (F) be considered "external" (either not defined in the program // or a user-defined version of a known alloc or no-op)? - bool is_ext(const SVFFunction *F); + bool is_ext(const CallGraphNode *F); private: // Set the annotation of (F) - void setExtFuncAnnotations(const SVFFunction* fun, const std::vector& funcAnnotations); + void setExtFuncAnnotations(const CallGraphNode* fun, const std::vector& funcAnnotations); }; } // End namespace SVF diff --git a/svf/include/Util/SVFUtil.h b/svf/include/Util/SVFUtil.h index ec42d4e633..70cd7b5741 100644 --- a/svf/include/Util/SVFUtil.h +++ b/svf/include/Util/SVFUtil.h @@ -187,7 +187,7 @@ inline bool isNonInstricCallSite(const ICFGNode* inst) /// Match arguments for callsite at caller and callee /// if the arg size does not match then we do not need to connect this parameter /// unless the callee is a variadic function (the first parameter of variadic function is its parameter number) -bool matchArgs(const CallICFGNode* cs, const SVFFunction* callee); +bool matchArgs(const CallICFGNode* cs, const CallGraphNode* callee); /// Split into two substrings around the first occurrence of a separator string. @@ -266,17 +266,15 @@ void stopAnalysisLimitTimer(bool limitTimerSet); /// Return true if the call is an external call (external library in function summary table) /// If the library function is redefined in the application code (e.g., memcpy), it will return false and will not be treated as an external call. //@{ -inline bool isExtCall(const SVFFunction* fun) -{ - return fun && ExtAPI::getExtAPI()->is_ext(fun); -} -inline bool isMemcpyExtFun(const SVFFunction* fun) +bool isExtCall(const CallGraphNode* fun); + +inline bool isMemcpyExtFun(const CallGraphNode* fun) { return fun && ExtAPI::getExtAPI()->is_memcpy(fun); } -inline bool isMemsetExtFun(const SVFFunction* fun) +inline bool isMemsetExtFun(const CallGraphNode* fun) { return fun && ExtAPI::getExtAPI()->is_memset(fun); } @@ -284,20 +282,20 @@ inline bool isMemsetExtFun(const SVFFunction* fun) /// Return true if the call is a heap allocator/reallocator //@{ /// note that these two functions are not suppose to be used externally -inline bool isHeapAllocExtFunViaRet(const SVFFunction* fun) +inline bool isHeapAllocExtFunViaRet(const CallGraphNode* fun) { return fun && (ExtAPI::getExtAPI()->is_alloc(fun) || ExtAPI::getExtAPI()->is_realloc(fun)); } -inline bool isHeapAllocExtFunViaArg(const SVFFunction* fun) +inline bool isHeapAllocExtFunViaArg(const CallGraphNode* fun) { return fun && ExtAPI::getExtAPI()->is_arg_alloc(fun); } /// Get the position of argument that holds an allocated heap object. //@{ -inline u32_t getHeapAllocHoldingArgPosition(const SVFFunction* fun) +inline u32_t getHeapAllocHoldingArgPosition(const CallGraphNode* fun) { return ExtAPI::getExtAPI()->get_alloc_arg_pos(fun); } @@ -305,7 +303,7 @@ inline u32_t getHeapAllocHoldingArgPosition(const SVFFunction* fun) /// Return true if the call is a heap reallocator //@{ /// note that this function is not suppose to be used externally -inline bool isReallocExtFun(const SVFFunction* fun) +inline bool isReallocExtFun(const CallGraphNode* fun) { return fun && (ExtAPI::getExtAPI()->is_realloc(fun)); } @@ -313,25 +311,17 @@ inline bool isReallocExtFun(const SVFFunction* fun) /// Program entry function e.g. main //@{ /// Return true if this is a program entry function (e.g. main) -inline bool isProgEntryFunction(const SVFFunction* fun) -{ - return fun && fun->getName() == "main"; -} +bool isProgEntryFunction(const CallGraphNode* fun); /// Get program entry function from function name. -const SVFFunction* getProgFunction(const std::string& funName); +const CallGraphNode* getProgFunction(const std::string& funName); /// Get program entry function. -const SVFFunction* getProgEntryFunction(); +const CallGraphNode* getProgEntryFunction(); /// Return true if this is a program exit function call //@{ -inline bool isProgExitFunction (const SVFFunction * fun) -{ - return fun && (fun->getName() == "exit" || - fun->getName() == "__assert_rtn" || - fun->getName() == "__assert_fail" ); -} +bool isProgExitFunction (const CallGraphNode * fun); bool isArgOfUncalledFunction(const SVFVar* svfvar); diff --git a/svf/include/Util/ThreadAPI.h b/svf/include/Util/ThreadAPI.h index 3acb042b54..87408ddec6 100644 --- a/svf/include/Util/ThreadAPI.h +++ b/svf/include/Util/ThreadAPI.h @@ -91,16 +91,7 @@ class ThreadAPI static ThreadAPI* tdAPI; /// Get the function type if it is a threadAPI function - inline TD_TYPE getType(const SVFFunction* F) const - { - if(F) - { - TDAPIMap::const_iterator it= tdAPIMap.find(F->getName()); - if(it != tdAPIMap.end()) - return it->second; - } - return TD_DUMMY; - } + TD_TYPE getType(const CallGraphNode* F) const; public: /// Return a static reference @@ -136,7 +127,7 @@ class ThreadAPI const ValVar* getActualParmAtForkSite(const CallICFGNode *inst) const; /// Return the formal parm of forked function (the first arg in pthread) - const SVFVar* getFormalParmOfForkedFun(const SVFFunction* F) const; + const SVFVar* getFormalParmOfForkedFun(const CallGraphNode* F) const; //@} diff --git a/svf/include/WPA/Andersen.h b/svf/include/WPA/Andersen.h index 1bcb7e069e..462128c26f 100644 --- a/svf/include/WPA/Andersen.h +++ b/svf/include/WPA/Andersen.h @@ -93,11 +93,11 @@ class AndersenBase: public WPAConstraintSolver, public BVDataPTAImpl virtual bool updateThreadCallGraph(const CallSiteToFunPtrMap&, NodePairSet&); /// Connect formal and actual parameters for indirect forksites - virtual void connectCaller2ForkedFunParams(const CallICFGNode* cs, const SVFFunction* F, + virtual void connectCaller2ForkedFunParams(const CallICFGNode* cs, const CallGraphNode* cgNode, NodePairSet& cpySrcNodes); /// Connect formal and actual parameters for indirect callsites - virtual void connectCaller2CalleeParams(const CallICFGNode* cs, const SVFFunction* F, + virtual void connectCaller2CalleeParams(const CallICFGNode* cs, const CallGraphNode* F, NodePairSet& cpySrcNodes); /// Methods for support type inquiry through isa, cast, and dyn_cast: diff --git a/svf/lib/AE/Svfexe/AEDetector.cpp b/svf/lib/AE/Svfexe/AEDetector.cpp index 7420e8fb0c..cdef7b9576 100644 --- a/svf/lib/AE/Svfexe/AEDetector.cpp +++ b/svf/lib/AE/Svfexe/AEDetector.cpp @@ -28,6 +28,7 @@ #include #include #include +#include "Graphs/CallGraph.h" using namespace SVF; @@ -219,7 +220,7 @@ void BufOverflowDetector::initExtAPIBufOverflowCheckRules() void BufOverflowDetector::detectExtAPI(AbstractState& as, const CallICFGNode* call) { - assert(call->getCalledFunction() && "SVFFunction* is nullptr"); + assert(call->getCalledFunction() && "CallGraphNode* is nullptr"); AbsExtAPI::ExtAPIType extType = AbsExtAPI::UNCLASSIFIED; diff --git a/svf/lib/AE/Svfexe/AbsExtAPI.cpp b/svf/lib/AE/Svfexe/AbsExtAPI.cpp index bc212af96c..1c3ab97899 100644 --- a/svf/lib/AE/Svfexe/AbsExtAPI.cpp +++ b/svf/lib/AE/Svfexe/AbsExtAPI.cpp @@ -26,6 +26,7 @@ // #include "AE/Svfexe/AbsExtAPI.h" #include "AE/Svfexe/AbstractInterpretation.h" +#include "Graphs/CallGraph.h" using namespace SVF; AbsExtAPI::AbsExtAPI(Map& traces): abstractTrace(traces) @@ -386,11 +387,11 @@ std::string AbsExtAPI::strRead(AbstractState& as, const SVFVar* rhs) void AbsExtAPI::handleExtAPI(const CallICFGNode *call) { AbstractState& as = getAbsStateFromTrace(call); - const SVFFunction *fun = call->getCalledFunction(); - assert(fun && "SVFFunction* is nullptr"); + const CallGraphNode *cgNode = call->getCalledFunction(); + assert(cgNode && "CallGraphNode* is nullptr"); ExtAPIType extType = UNCLASSIFIED; // get type of mem api - for (const std::string &annotation: ExtAPI::getExtAPI()->getExtFuncAnnotations(fun)) + for (const std::string &annotation: ExtAPI::getExtAPI()->getExtFuncAnnotations(cgNode)) { if (annotation.find("MEMCPY") != std::string::npos) extType = MEMCPY; @@ -403,9 +404,9 @@ void AbsExtAPI::handleExtAPI(const CallICFGNode *call) } if (extType == UNCLASSIFIED) { - if (func_map.find(fun->getName()) != func_map.end()) + if (func_map.find(cgNode->getName()) != func_map.end()) { - func_map[fun->getName()](call); + func_map[cgNode->getName()](call); } else { @@ -546,7 +547,7 @@ void AbsExtAPI::handleStrcat(const SVF::CallICFGNode *call) // __strcat_chk, strcat, __wcscat_chk, wcscat, __strncat_chk, strncat, __wcsncat_chk, wcsncat // to check it is strcat group or strncat group AbstractState& as = getAbsStateFromTrace(call); - const SVFFunction *fun = call->getCalledFunction(); + const CallGraphNode *fun = call->getCalledFunction(); const std::vector strcatGroup = {"__strcat_chk", "strcat", "__wcscat_chk", "wcscat"}; const std::vector strncatGroup = {"__strncat_chk", "strncat", "__wcsncat_chk", "wcsncat"}; if (std::find(strcatGroup.begin(), strcatGroup.end(), fun->getName()) != strcatGroup.end()) diff --git a/svf/lib/AE/Svfexe/AbstractInterpretation.cpp b/svf/lib/AE/Svfexe/AbstractInterpretation.cpp index c047095a37..6f3042da76 100644 --- a/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +++ b/svf/lib/AE/Svfexe/AbstractInterpretation.cpp @@ -92,9 +92,9 @@ void AbstractInterpretation::initWTO() // Check if the current function is part of a cycle if (callGraphScc->isInCycle(it->second->getId())) recursiveFuns.insert(it->second); // Mark the function as recursive - if (it->second->getFunction()->isDeclaration()) + if (it->second->isDeclaration()) continue; - auto* wto = new ICFGWTO(icfg, icfg->getFunEntryICFGNode(it->second->getFunction())); + auto* wto = new ICFGWTO(icfg, icfg->getFunEntryICFGNode(it->second)); wto->init(); funcToWTO[it->second] = wto; } @@ -565,7 +565,10 @@ void AbstractInterpretation::handleCallSite(const ICFGNode* node) bool AbstractInterpretation::isExtCall(const SVF::CallICFGNode *callNode) { - return SVFUtil::isExtCall(callNode->getCalledFunction()); + if (callNode->getCalledFunction()) + return SVFUtil::isExtCall(callNode->getCalledFunction()); + else + return false; } void AbstractInterpretation::extCallPass(const SVF::CallICFGNode *callNode) @@ -581,11 +584,8 @@ void AbstractInterpretation::extCallPass(const SVF::CallICFGNode *callNode) bool AbstractInterpretation::isRecursiveCall(const SVF::CallICFGNode *callNode) { - const SVFFunction *callfun = callNode->getCalledFunction(); - if (!callfun) - return false; - else - return recursiveFuns.find(callfun->getCallGraphNode()) != recursiveFuns.end(); + const CallGraphNode *callfun = callNode->getCalledFunction(); + return callfun && recursiveFuns.find(callfun) != recursiveFuns.end(); } void AbstractInterpretation::recursiveCallPass(const SVF::CallICFGNode *callNode) @@ -609,11 +609,8 @@ void AbstractInterpretation::recursiveCallPass(const SVF::CallICFGNode *callNode bool AbstractInterpretation::isDirectCall(const SVF::CallICFGNode *callNode) { - const SVFFunction *callfun =callNode->getCalledFunction(); - if (!callfun) - return false; - else - return funcToWTO.find(callfun->getCallGraphNode()) != funcToWTO.end(); + const CallGraphNode *callfun =callNode->getCalledFunction(); + return callfun && funcToWTO.find(callfun) != funcToWTO.end(); } void AbstractInterpretation::directCallFunPass(const SVF::CallICFGNode *callNode) { @@ -622,8 +619,8 @@ void AbstractInterpretation::directCallFunPass(const SVF::CallICFGNode *callNode abstractTrace[callNode] = as; - const SVFFunction *callfun =callNode->getCalledFunction(); - ICFGWTO* wto = funcToWTO[callfun->getCallGraphNode()]; + const CallGraphNode *callfun =callNode->getCalledFunction(); + ICFGWTO* wto = funcToWTO[callfun]; handleWTOComponents(wto->getWTOComponents()); callSiteStack.pop_back(); @@ -854,7 +851,7 @@ void AEStat::finializeStat() generalNumMap["ICFG_Node_Num"] = _ae->svfir->getICFG()->nodeNum; u32_t callSiteNum = 0; u32_t extCallSiteNum = 0; - Set funs; + Set funs; for (const auto &it: *_ae->svfir->getICFG()) { if (it.second->getFun()) @@ -928,7 +925,7 @@ void AbstractInterpretation::collectCheckPoint() const ICFGNode* node = it->second; if (const CallICFGNode *call = SVFUtil::dyn_cast(node)) { - if (const SVFFunction *fun = call->getCalledFunction()) + if (const CallGraphNode *fun = call->getCalledFunction()) { if (ae_checkpoint_names.find(fun->getName()) != ae_checkpoint_names.end()) diff --git a/svf/lib/CFL/CFLAlias.cpp b/svf/lib/CFL/CFLAlias.cpp index 2ed412b387..33159b42b4 100644 --- a/svf/lib/CFL/CFLAlias.cpp +++ b/svf/lib/CFL/CFLAlias.cpp @@ -28,6 +28,7 @@ */ #include "CFL/CFLAlias.h" +#include "Graphs/CallGraph.h" using namespace SVF; using namespace SVFUtil; @@ -59,7 +60,7 @@ void CFLAlias::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites, Call * Connect formal and actual parameters for indirect callsites */ -void CFLAlias::connectCaller2CalleeParams(const CallICFGNode* cs, const SVFFunction* F) +void CFLAlias::connectCaller2CalleeParams(const CallICFGNode* cs, const CallGraphNode* F) { assert(F); diff --git a/svf/lib/DDA/ContextDDA.cpp b/svf/lib/DDA/ContextDDA.cpp index 5497c7ecb4..6f13f110b4 100644 --- a/svf/lib/DDA/ContextDDA.cpp +++ b/svf/lib/DDA/ContextDDA.cpp @@ -186,7 +186,7 @@ CxtPtSet ContextDDA::processGepPts(const GepSVFGNode* gep, const CxtPtSet& srcPt return tmpDstPts; } -bool ContextDDA::testIndCallReachability(CxtLocDPItem& dpm, const SVFFunction* callee, const CallICFGNode* cs) +bool ContextDDA::testIndCallReachability(CxtLocDPItem& dpm, const CallGraphNode* callee, const CallICFGNode* cs) { if(getPAG()->isIndirectCallSites(cs)) { @@ -195,7 +195,7 @@ bool ContextDDA::testIndCallReachability(CxtLocDPItem& dpm, const SVFFunction* c CxtVar funptrVar(dpm.getCondVar().get_cond(), id); CxtLocDPItem funptrDpm = getDPIm(funptrVar,getDefSVFGNode(node)); PointsTo pts = getBVPointsTo(findPT(funptrDpm)); - if(pts.test(getPAG()->getFunObjVar(callee->getCallGraphNode())->getId())) + if(pts.test(getPAG()->getFunObjVar(callee)->getId())) return true; else return false; @@ -217,7 +217,7 @@ CallSiteID ContextDDA::getCSIDAtCall(CxtLocDPItem&, const SVFGEdge* edge) svfg_csId = SVFUtil::cast(edge)->getCallSiteId(); const CallICFGNode* cbn = getSVFG()->getCallSite(svfg_csId); - const SVFFunction* callee = edge->getDstNode()->getFun(); + const CallGraphNode* callee = edge->getDstNode()->getFun(); if(getCallGraph()->hasCallSiteID(cbn,callee)) { @@ -241,7 +241,7 @@ CallSiteID ContextDDA::getCSIDAtRet(CxtLocDPItem&, const SVFGEdge* edge) svfg_csId = SVFUtil::cast(edge)->getCallSiteId(); const CallICFGNode* cbn = getSVFG()->getCallSite(svfg_csId); - const SVFFunction* callee = edge->getSrcNode()->getFun(); + const CallGraphNode* callee = edge->getSrcNode()->getFun(); if(getCallGraph()->hasCallSiteID(cbn,callee)) { @@ -358,7 +358,7 @@ bool ContextDDA::isHeapCondMemObj(const CxtVar& var, const StoreSVFGNode*) } else if(const ICFGNode* node = obj->getICFGNode()) { - const SVFFunction* svfFun = node->getFun(); + const CallGraphNode* svfFun = node->getFun(); if(_ander->isInRecursion(svfFun)) return true; if(var.get_cond().isConcreteCxt() == false) diff --git a/svf/lib/DDA/DDAClient.cpp b/svf/lib/DDA/DDAClient.cpp index 5f159f34ec..d069f98a28 100644 --- a/svf/lib/DDA/DDAClient.cpp +++ b/svf/lib/DDA/DDAClient.cpp @@ -138,8 +138,8 @@ void FunptrDDAClient::performStat(PointerAnalysis* pta) if(ddaPts.count() >= anderPts.count() || ddaPts.empty()) continue; - Set ander_vfns; - Set dda_vfns; + Set ander_vfns; + Set dda_vfns; ander->getVFnsFromPts(cbn,anderPts, ander_vfns); pta->getVFnsFromPts(cbn,ddaPts, dda_vfns); diff --git a/svf/lib/DDA/DDAPass.cpp b/svf/lib/DDA/DDAPass.cpp index 886df583c8..c831322fd2 100644 --- a/svf/lib/DDA/DDAPass.cpp +++ b/svf/lib/DDA/DDAPass.cpp @@ -177,8 +177,8 @@ bool DDAPass::edgeInSVFGSCC(const SVFGSCC* svfgSCC,const SVFGEdge* edge) */ bool DDAPass::edgeInCallGraphSCC(PointerAnalysis* pta,const SVFGEdge* edge) { - const SVFFunction* srcFun = edge->getSrcNode()->getICFGNode()->getFun(); - const SVFFunction* dstFun = edge->getDstNode()->getICFGNode()->getFun(); + const CallGraphNode* srcFun = edge->getSrcNode()->getICFGNode()->getFun(); + const CallGraphNode* dstFun = edge->getDstNode()->getICFGNode()->getFun(); if(srcFun && dstFun) { @@ -234,13 +234,17 @@ void DDAPass::collectCxtInsenEdgeForVFCycle(PointerAnalysis* pta, const SVFG* sv if(this->edgeInSVFGSCC(svfgSCC,edge)) { - const SVFFunction* srcFun = edge->getSrcNode()->getICFGNode()->getFun(); - const SVFFunction* dstFun = edge->getDstNode()->getICFGNode()->getFun(); + const CallGraphNode* srcFun = edge->getSrcNode()->getICFGNode()->getFun(); + const CallGraphNode* dstFun = edge->getDstNode()->getICFGNode()->getFun(); if(srcFun && dstFun) { - NodeID src = pta->getCallGraph()->getCallGraphNode(srcFun)->getId(); - NodeID dst = pta->getCallGraph()->getCallGraphNode(dstFun)->getId(); + NodeID src = pta->getCallGraph() + ->getPTACallGraphNode( + srcFun)->getId(); + NodeID dst = pta->getCallGraph() + ->getPTACallGraphNode( + dstFun)->getId(); insensitvefunPairs.insert(std::make_pair(src,dst)); insensitvefunPairs.insert(std::make_pair(dst,src)); } @@ -261,13 +265,13 @@ void DDAPass::collectCxtInsenEdgeForVFCycle(PointerAnalysis* pta, const SVFG* sv if(edge->isCallVFGEdge() || edge->isRetVFGEdge()) { - const SVFFunction* srcFun = edge->getSrcNode()->getICFGNode()->getFun(); - const SVFFunction* dstFun = edge->getDstNode()->getICFGNode()->getFun(); + const CallGraphNode* srcFun = edge->getSrcNode()->getICFGNode()->getFun(); + const CallGraphNode* dstFun = edge->getDstNode()->getICFGNode()->getFun(); if(srcFun && dstFun) { - NodeID src = pta->getCallGraph()->getCallGraphNode(srcFun)->getId(); - NodeID dst = pta->getCallGraph()->getCallGraphNode(dstFun)->getId(); + NodeID src = srcFun->getId(); + NodeID dst = dstFun->getId(); if(insensitvefunPairs.find(std::make_pair(src,dst))!=insensitvefunPairs.end()) insensitveEdges.insert(edge); else if(insensitvefunPairs.find(std::make_pair(dst,src))!=insensitvefunPairs.end()) diff --git a/svf/lib/DDA/FlowDDA.cpp b/svf/lib/DDA/FlowDDA.cpp index d7a746835a..7d2e868a45 100644 --- a/svf/lib/DDA/FlowDDA.cpp +++ b/svf/lib/DDA/FlowDDA.cpp @@ -78,7 +78,7 @@ void FlowDDA::handleOutOfBudgetDpm(const LocDPItem& dpm) addOutOfBudgetDpm(dpm); } -bool FlowDDA::testIndCallReachability(LocDPItem&, const SVFFunction* callee, CallSiteID csId) +bool FlowDDA::testIndCallReachability(LocDPItem&, const CallGraphNode* callee, CallSiteID csId) { const CallICFGNode* cbn = getSVFG()->getCallSite(csId); @@ -102,36 +102,6 @@ bool FlowDDA::testIndCallReachability(LocDPItem&, const SVFFunction* callee, Cal bool FlowDDA::handleBKCondition(LocDPItem& dpm, const SVFGEdge* edge) { _client->handleStatement(edge->getSrcNode(), dpm.getCurNodeID()); -// CallSiteID csId = 0; -// -// if (edge->isCallVFGEdge()) { -// /// we don't handle context in recursions, they treated as assignments -// if (const CallDirSVFGEdge* callEdge = SVFUtil::dyn_cast(edge)) -// csId = callEdge->getCallSiteId(); -// else -// csId = SVFUtil::cast(edge)->getCallSiteId(); -// -// const SVFFunction* callee = edge->getDstNode()->getBB()->getParent(); -// if(testIndCallReachability(dpm,callee,csId)==false){ -// return false; -// } -// -// } -// -// else if (edge->isRetVFGEdge()) { -// /// we don't handle context in recursions, they treated as assignments -// if (const RetDirSVFGEdge* retEdge = SVFUtil::dyn_cast(edge)) -// csId = retEdge->getCallSiteId(); -// else -// csId = SVFUtil::cast(edge)->getCallSiteId(); -// -// const SVFFunction* callee = edge->getSrcNode()->getBB()->getParent(); -// if(testIndCallReachability(dpm,callee,csId)==false){ -// return false; -// } -// -// } - return true; } @@ -179,18 +149,6 @@ bool FlowDDA::isHeapCondMemObj(const NodeID& var, const StoreSVFGNode*) const BaseObjVar* pVar = _pag->getBaseObject(getPtrNodeID(var)); if(pVar && SVFUtil::isa(pVar)) { -// if(const Instruction* mallocSite = SVFUtil::dyn_cast(mem->getValue())) { -// const SVFFunction* fun = mallocSite->getParent()->getParent(); -// const SVFFunction* curFun = store->getBB() ? store->getBB()->getParent() : nullptr; -// if(fun!=curFun) -// return true; -// if(_callGraphSCC->isInCycle(_callGraph->getCallGraphNode(fun)->getId())) -// return true; -// if(_pag->getICFG()->isInLoop(mallocSite)) -// return true; -// -// return false; -// } return true; } return false; diff --git a/svf/lib/Graphs/CHG.cpp b/svf/lib/Graphs/CHG.cpp index 0673c63a6f..232e8ce9cf 100644 --- a/svf/lib/Graphs/CHG.cpp +++ b/svf/lib/Graphs/CHG.cpp @@ -31,6 +31,7 @@ #include "Util/SVFUtil.h" #include "Graphs/ICFG.h" #include "SVFIR/SVFIR.h" +#include "Graphs/CallGraph.h" using namespace SVF; using namespace SVFUtil; @@ -50,7 +51,7 @@ static bool hasEdge(const CHNode *src, const CHNode *dst, return false; } -static bool checkArgTypes(const CallICFGNode* cs, const SVFFunction* fn) +static bool checkArgTypes(const CallICFGNode* cs, const CallGraphNode* fn) { // here we skip the first argument (i.e., this pointer) @@ -137,7 +138,7 @@ void CHGraph::getVFnsFromVtbls(const CallICFGNode* callsite, const VTableSet &vt for (CHNode::FuncVector::const_iterator fit = vfns.begin(), feit = vfns.end(); fit != feit; ++fit) { - const SVFFunction* callee = *fit; + const CallGraphNode* callee = *fit; if (callsite->arg_size() == callee->arg_size() || (callsite->isVarArg() && callee->isVarArg())) { diff --git a/svf/lib/Graphs/CallGraph.cpp b/svf/lib/Graphs/CallGraph.cpp index 00ca4d54ee..38a6f8b422 100644 --- a/svf/lib/Graphs/CallGraph.cpp +++ b/svf/lib/Graphs/CallGraph.cpp @@ -57,11 +57,39 @@ const std::string CallGraphEdge::toString() const return rawstr.str(); } + +void CallGraphNode::init(const SVFFunctionType* ft, bool uncalled, bool notRet, bool declare, bool intr, bool adt, + bool varg, SVFLoopAndDomInfo* ld, CallGraphNode* cgn, BasicBlockGraph* bbG, std::vector allArg, SVFBasicBlock* eBb) +{ + this->isUncalled = uncalled; + this->isNotRet = notRet; + this->isDecl = declare; + this->intrinsic = intr; + this->addrTaken =adt; + this->varArg = varg; + this->funcType = ft; + this->loopAndDom = ld; + this->realDefFun = cgn; + this->bbGraph = bbG; + this->allArgs = allArg; + this->exitBlock = eBb; +} + +CallGraphNode::CallGraphNode(NodeID i, + const SVFType* ty, const SVFFunctionType* ft, + bool declare, bool intrinsic, bool adt, + bool varg, SVFLoopAndDomInfo* ld) + : GenericNode(i,CallNodeKd,ty),isDecl(declare), intrinsic(intrinsic), + addrTaken(adt), isUncalled(false), isNotRet(false), varArg(varg), + funcType(ft), loopAndDom(ld), realDefFun(nullptr), exitBlock(nullptr) +{ +} + const std::string CallGraphNode::toString() const { std::string str; std::stringstream rawstr(str); - rawstr << "CallGraphNode ID: " << getId() << " {fun: " << fun->getName() << "}"; + rawstr << "CallGraphNode ID: " << getId() << " {fun: " << getName() << "}"; return rawstr.str(); } @@ -83,13 +111,15 @@ void CallGraph::destroy() /*! * Add call graph node */ -void CallGraph::addCallGraphNode(const SVFFunction* fun) +CallGraphNode* CallGraph::addCallGraphNode(const SVFType* ty, const SVFFunctionType* ft, + bool declare, bool intrinsic, bool adt, + bool varg, SVFLoopAndDomInfo* ld) { NodeID id = callGraphNodeNum; - CallGraphNode*callGraphNode = new CallGraphNode(id, fun); + CallGraphNode *callGraphNode = new CallGraphNode(id, ty, ft, declare, intrinsic, adt, varg, ld); addGNode(id, callGraphNode); - funToCallGraphNodeMap[callGraphNode->getFunction()] = callGraphNode; callGraphNodeNum++; + return callGraphNode; } /*! @@ -114,13 +144,8 @@ CallGraphEdge* CallGraph::hasGraphEdge(CallGraphNode* src, /*! * Add direct call edges */ -void CallGraph::addDirectCallGraphEdge(const CallICFGNode* cs,const SVFFunction* callerFun, const SVFFunction* calleeFun) +void CallGraph::addDirectCallGraphEdge(const CallICFGNode* cs, CallGraphNode* caller, CallGraphNode* callee) { - - CallGraphNode* caller = getCallGraphNode(callerFun); - CallGraphNode* callee = getCallGraphNode(calleeFun); - - if(!hasGraphEdge(caller,callee, cs)) { CallGraphEdge* edge = new CallGraphEdge(caller,callee, cs); @@ -183,8 +208,7 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits static std::string getNodeAttributes(CallGraphNode*node, CallGraph*) { - const SVFFunction* fun = node->getFunction(); - if (!SVFUtil::isExtCall(fun)) + if (!SVFUtil::isExtCall(node)) { return "shape=box"; } diff --git a/svf/lib/Graphs/ICFG.cpp b/svf/lib/Graphs/ICFG.cpp index 533cb21292..ef2241b273 100644 --- a/svf/lib/Graphs/ICFG.cpp +++ b/svf/lib/Graphs/ICFG.cpp @@ -37,7 +37,7 @@ using namespace SVF; using namespace SVFUtil; -FunEntryICFGNode::FunEntryICFGNode(NodeID id, const SVFFunction* f) : InterICFGNode(id, FunEntryBlock) +FunEntryICFGNode::FunEntryICFGNode(NodeID id, const CallGraphNode* f) : InterICFGNode(id, FunEntryBlock) { fun = f; // if function is implemented @@ -47,7 +47,7 @@ FunEntryICFGNode::FunEntryICFGNode(NodeID id, const SVFFunction* f) : InterICFGN } } -FunExitICFGNode::FunExitICFGNode(NodeID id, const SVFFunction* f) +FunExitICFGNode::FunExitICFGNode(NodeID id, const CallGraphNode* f) : InterICFGNode(id, FunExitBlock), formalRet(nullptr) { fun = f; @@ -110,9 +110,14 @@ const std::string FunEntryICFGNode::toString() const return rawstr.str(); } +const std::string FunEntryICFGNode::getSourceLoc() const +{ + return "function entry: " + fun->getSourceLoc(); +} + const std::string FunExitICFGNode::toString() const { - const SVFFunction *fun = getFun(); + const CallGraphNode *fun = getFun(); std::string str; std::stringstream rawstr(str); rawstr << "FunExitICFGNode" << getId(); @@ -127,6 +132,10 @@ const std::string FunExitICFGNode::toString() const return rawstr.str(); } +const std::string FunExitICFGNode::getSourceLoc() const +{ + return "function ret: " + fun->getSourceLoc(); +} const std::string CallICFGNode::toString() const { @@ -231,14 +240,14 @@ ICFG::~ICFG() /// Add a function entry node -FunEntryICFGNode* ICFG::getFunEntryICFGNode(const SVFFunction* fun) +FunEntryICFGNode* ICFG::getFunEntryICFGNode(const CallGraphNode* fun) { FunEntryICFGNode* entry = getFunEntryBlock(fun); assert (entry && "fun entry not created in ICFGBuilder?"); return entry; } /// Add a function exit node -FunExitICFGNode* ICFG::getFunExitICFGNode(const SVFFunction* fun) +FunExitICFGNode* ICFG::getFunExitICFGNode(const CallGraphNode* fun) { FunExitICFGNode* exit = getFunExitBlock(fun); assert (exit && "fun exit not created in ICFGBuilder?"); @@ -427,7 +436,7 @@ void ICFG::updateCallGraph(PTACallGraph* callgraph) const PTACallGraph::FunctionSet & functions = iter->second; for (PTACallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++) { - const SVFFunction* callee = *func_iter; + const CallGraphNode* callee = *func_iter; RetICFGNode* retBlockNode = const_cast(callBlockNode->getRetICFGNode()); /// if this is an external function (no function body), connect calleeEntryNode to calleeExitNode if (isExtCall(callee)) diff --git a/svf/lib/Graphs/IRGraph.cpp b/svf/lib/Graphs/IRGraph.cpp index a3b4b2013f..0c7196b457 100644 --- a/svf/lib/Graphs/IRGraph.cpp +++ b/svf/lib/Graphs/IRGraph.cpp @@ -56,14 +56,14 @@ IRGraph::~IRGraph() destorySymTable(); } -NodeID IRGraph::getReturnNode(const SVFFunction *func) const +NodeID IRGraph::getReturnNode(const CallGraphNode *func) const { FunToIDMapTy::const_iterator iter = returnSymMap.find(func); assert(iter!=returnSymMap.end() && "ret sym not found"); return iter->second; } -NodeID IRGraph::getVarargNode(const SVFFunction *func) const +NodeID IRGraph::getVarargNode(const CallGraphNode *func) const { FunToIDMapTy::const_iterator iter = varargSymMap.find(func); assert(iter!=varargSymMap.end() && "vararg sym not found"); diff --git a/svf/lib/Graphs/PTACallGraph.cpp b/svf/lib/Graphs/PTACallGraph.cpp index 7d24d7644e..af36b14859 100644 --- a/svf/lib/Graphs/PTACallGraph.cpp +++ b/svf/lib/Graphs/PTACallGraph.cpp @@ -91,7 +91,7 @@ bool PTACallGraphNode::isReachableFromProgEntry() const PTACallGraphNode* node = const_cast(nodeStack.top()); nodeStack.pop(); - if (SVFUtil::isProgEntryFunction(node->getFunction())) + if (SVFUtil::isProgEntryFunction(node->getCallGraphNode())) return true; for (const_iterator it = node->InEdgeBegin(), eit = node->InEdgeEnd(); it != eit; ++it) @@ -124,9 +124,9 @@ PTACallGraph::PTACallGraph(const CallGraph& other) for (const auto& item : other) { const CallGraphNode* cgn = item.second; - PTACallGraphNode* callGraphNode = new PTACallGraphNode(cgn->getId(), cgn->getFunction()); + PTACallGraphNode* callGraphNode = new PTACallGraphNode(cgn->getId(), cgn); addGNode(cgn->getId(),callGraphNode); - funToCallGraphNodeMap[cgn->getFunction()] = callGraphNode; + cgNodeToPtaCallGraphNodeMap[cgn] = callGraphNode; } /// copy edges @@ -137,7 +137,7 @@ PTACallGraph::PTACallGraph(const CallGraph& other) { PTACallGraphNode* src = getCallGraphNode(edge->getSrcID()); PTACallGraphNode* dst = getCallGraphNode(edge->getDstID()); - CallSiteID csId = addCallSite(cs, dst->getFunction()); + CallSiteID csId = addCallSite(cs, dst->getCallGraphNode()); PTACallGraphEdge* newEdge = new PTACallGraphEdge(src,dst, PTACallGraphEdge::CallRetEdge,csId); newEdge->addDirectCallSite(cs); @@ -195,15 +195,17 @@ PTACallGraphEdge* PTACallGraph::getGraphEdge(PTACallGraphNode* src, /*! * Add indirect call edge to update call graph */ -void PTACallGraph::addIndirectCallGraphEdge(const CallICFGNode* cs,const SVFFunction* callerFun, const SVFFunction* calleeFun) +void PTACallGraph::addIndirectCallGraphEdge(const CallICFGNode* cs,const CallGraphNode* callerFun, const CallGraphNode* calleeFun) { - PTACallGraphNode* caller = getCallGraphNode(callerFun); - PTACallGraphNode* callee = getCallGraphNode(calleeFun); + PTACallGraphNode* caller = + getPTACallGraphNode(callerFun); + PTACallGraphNode* callee = + getPTACallGraphNode(calleeFun); numOfResolvedIndCallEdge++; - CallSiteID csId = addCallSite(cs, callee->getFunction()); + CallSiteID csId = addCallSite(cs, callee->getCallGraphNode()); if(!hasGraphEdge(caller,callee, PTACallGraphEdge::CallRetEdge,csId)) { @@ -217,9 +219,10 @@ void PTACallGraph::addIndirectCallGraphEdge(const CallICFGNode* cs,const SVFFunc /*! * Get all callsite invoking this callee */ -void PTACallGraph::getAllCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet) +void PTACallGraph::getAllCallSitesInvokingCallee(const CallGraphNode* callee, PTACallGraphEdge::CallInstSet& csSet) { - PTACallGraphNode* callGraphNode = getCallGraphNode(callee); + PTACallGraphNode* callGraphNode = + getPTACallGraphNode(callee); for(PTACallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); it!=eit; ++it) { @@ -239,9 +242,10 @@ void PTACallGraph::getAllCallSitesInvokingCallee(const SVFFunction* callee, PTAC /*! * Get direct callsite invoking this callee */ -void PTACallGraph::getDirCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet) +void PTACallGraph::getDirCallSitesInvokingCallee(const CallGraphNode* callee, PTACallGraphEdge::CallInstSet& csSet) { - PTACallGraphNode* callGraphNode = getCallGraphNode(callee); + PTACallGraphNode* callGraphNode = + getPTACallGraphNode(callee); for(PTACallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); it!=eit; ++it) { @@ -256,9 +260,10 @@ void PTACallGraph::getDirCallSitesInvokingCallee(const SVFFunction* callee, PTAC /*! * Get indirect callsite invoking this callee */ -void PTACallGraph::getIndCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet) +void PTACallGraph::getIndCallSitesInvokingCallee(const CallGraphNode* callee, PTACallGraphEdge::CallInstSet& csSet) { - PTACallGraphNode* callGraphNode = getCallGraphNode(callee); + PTACallGraphNode* callGraphNode = + getPTACallGraphNode(callee); for(PTACallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); it!=eit; ++it) { @@ -283,8 +288,8 @@ void PTACallGraph::verifyCallGraph() if (targets.empty() == false) { const CallICFGNode* cs = it->first; - const SVFFunction* func = cs->getCaller(); - if (getCallGraphNode(func)->isReachableFromProgEntry() == false) + const CallGraphNode* func = cs->getCaller(); + if (getPTACallGraphNode(func)->isReachableFromProgEntry() == false) writeWrnMsg(func->getName() + " has indirect call site but not reachable from main"); } } @@ -293,9 +298,9 @@ void PTACallGraph::verifyCallGraph() /*! * Whether its reachable between two functions */ -bool PTACallGraph::isReachableBetweenFunctions(const SVFFunction* srcFn, const SVFFunction* dstFn) const +bool PTACallGraph::isReachableBetweenFunctions(const CallGraphNode* srcFn, const CallGraphNode* dstFn) const { - PTACallGraphNode* dstNode = getCallGraphNode(dstFn); + PTACallGraphNode* dstNode = getPTACallGraphNode(dstFn); std::stack nodeStack; NodeBS visitedNodes; @@ -307,7 +312,7 @@ bool PTACallGraph::isReachableBetweenFunctions(const SVFFunction* srcFn, const S PTACallGraphNode* node = const_cast(nodeStack.top()); nodeStack.pop(); - if (node->getFunction() == srcFn) + if (node->getCallGraphNode() == srcFn) return true; for (CallGraphEdgeConstIter it = node->InEdgeBegin(), eit = node->InEdgeEnd(); it != eit; ++it) @@ -364,7 +369,7 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits static std::string getNodeAttributes(PTACallGraphNode*node, PTACallGraph*) { - const SVFFunction* fun = node->getFunction(); + const CallGraphNode* fun = node->getCallGraphNode(); if (!SVFUtil::isExtCall(fun)) { return "shape=box"; diff --git a/svf/lib/Graphs/SVFG.cpp b/svf/lib/Graphs/SVFG.cpp index da55360dee..967fdc9c29 100644 --- a/svf/lib/Graphs/SVFG.cpp +++ b/svf/lib/Graphs/SVFG.cpp @@ -427,7 +427,9 @@ void SVFG::connectIndirectSVFGEdges() */ void SVFG::connectFromGlobalToProgEntry() { - const SVFFunction* mainFunc = SVFUtil::getProgEntryFunction(); + const CallGraphNode* mainFunc = SVFUtil::getProgEntryFunction(); + if (!mainFunc) + return; FormalINSVFGNodeSet& formalIns = getFormalINSVFGNodes(mainFunc); if (formalIns.empty()) return; @@ -581,7 +583,7 @@ void SVFG::dump(const std::string& file, bool simple) /** * Get all inter value flow edges at this indirect call site, including call and return edges. */ -void SVFG::getInterVFEdgesForIndirectCallSite(const CallICFGNode* callICFGNode, const SVFFunction* callee, SVFGEdgeSetTy& edges) +void SVFG::getInterVFEdgesForIndirectCallSite(const CallICFGNode* callICFGNode, const CallGraphNode* callee, SVFGEdgeSetTy& edges) { CallSiteID csId = getCallSiteID(callICFGNode, callee); const RetICFGNode* retICFGNode = callICFGNode->getRetICFGNode(); @@ -655,7 +657,7 @@ void SVFG::getInterVFEdgesForIndirectCallSite(const CallICFGNode* callICFGNode, * Connect actual params/return to formal params/return for top-level variables. * Also connect indirect actual in/out and formal in/out. */ -void SVFG::connectCallerAndCallee(const CallICFGNode* cs, const SVFFunction* callee, SVFGEdgeSetTy& edges) +void SVFG::connectCallerAndCallee(const CallICFGNode* cs, const CallGraphNode* callee, SVFGEdgeSetTy& edges) { VFG::connectCallerAndCallee(cs,callee,edges); @@ -703,7 +705,7 @@ void SVFG::connectCallerAndCallee(const CallICFGNode* cs, const SVFFunction* cal /*! * Whether this is an function entry SVFGNode (formal parameter, formal In) */ -const SVFFunction* SVFG::isFunEntrySVFGNode(const SVFGNode* node) const +const CallGraphNode* SVFG::isFunEntrySVFGNode(const SVFGNode* node) const { if(const FormalParmSVFGNode* fp = SVFUtil::dyn_cast(node)) { diff --git a/svf/lib/Graphs/ThreadCallGraph.cpp b/svf/lib/Graphs/ThreadCallGraph.cpp index 0d5d6848e3..630bde143c 100644 --- a/svf/lib/Graphs/ThreadCallGraph.cpp +++ b/svf/lib/Graphs/ThreadCallGraph.cpp @@ -66,7 +66,7 @@ void ThreadCallGraph::updateCallGraph(PointerAnalysis* pta) for (PTACallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++) { - const SVFFunction* callee = *func_iter; + const CallGraphNode* callee = *func_iter; this->addIndirectCallGraphEdge(cs, cs->getCaller(), callee); } } @@ -86,7 +86,7 @@ void ThreadCallGraph::updateCallGraph(PointerAnalysis* pta) const BaseObjVar* obj = pag->getBaseObject(objPN->getId()); if(obj->isFunction()) { - const SVFFunction* svfCallee = SVFUtil::cast(obj)->getFunction(); + const CallGraphNode* svfCallee = SVFUtil::cast(obj)->getCallGraphNode(); this->addIndirectForkEdge(*it, svfCallee); } } @@ -126,16 +126,18 @@ void ThreadCallGraph::updateJoinEdge(PointerAnalysis* pta) bool ThreadCallGraph::addDirectForkEdge(const CallICFGNode* cs) { - PTACallGraphNode* caller = getCallGraphNode(cs->getCaller()); - const SVFFunction* forkee = SVFUtil::dyn_cast(tdAPI->getForkedFun(cs)) - ->getCallGraphNode()->getFunction(); + PTACallGraphNode* caller = + getPTACallGraphNode(cs->getCaller()); + const CallGraphNode* forkee = SVFUtil::dyn_cast(tdAPI->getForkedFun(cs)) + ->getCallGraphNode(); assert(forkee && "callee does not exist"); - PTACallGraphNode* callee = getCallGraphNode(forkee->getDefFunForMultipleModule()); - CallSiteID csId = addCallSite(cs, callee->getFunction()); + PTACallGraphNode* callee = getPTACallGraphNode( + forkee->getDefFunForMultipleModule()); + CallSiteID csId = addCallSite(cs, callee->getCallGraphNode()); if (!hasGraphEdge(caller, callee, PTACallGraphEdge::TDForkEdge, csId)) { - assert(cs->getCaller() == caller->getFunction() && "callee instruction not inside caller??"); + assert(cs->getCaller() == caller->getCallGraphNode() && "callee instruction not inside caller??"); ThreadForkEdge* edge = new ThreadForkEdge(caller, callee, csId); edge->addDirectCallSite(cs); @@ -151,16 +153,18 @@ bool ThreadCallGraph::addDirectForkEdge(const CallICFGNode* cs) /*! * Add indirect fork edge to update call graph */ -bool ThreadCallGraph::addIndirectForkEdge(const CallICFGNode* cs, const SVFFunction* calleefun) +bool ThreadCallGraph::addIndirectForkEdge(const CallICFGNode* cs, const CallGraphNode* calleefun) { - PTACallGraphNode* caller = getCallGraphNode(cs->getCaller()); - PTACallGraphNode* callee = getCallGraphNode(calleefun); + PTACallGraphNode* caller = + getPTACallGraphNode(cs->getCaller()); + PTACallGraphNode* callee = + getPTACallGraphNode(calleefun); - CallSiteID csId = addCallSite(cs, callee->getFunction()); + CallSiteID csId = addCallSite(cs, callee->getCallGraphNode()); if (!hasGraphEdge(caller, callee, PTACallGraphEdge::TDForkEdge, csId)) { - assert(cs->getCaller() == caller->getFunction() && "callee instruction not inside caller??"); + assert(cs->getCaller() == caller->getCallGraphNode() && "callee instruction not inside caller??"); ThreadForkEdge* edge = new ThreadForkEdge(caller, callee, csId); edge->addInDirectCallSite(cs); @@ -182,22 +186,23 @@ bool ThreadCallGraph::addIndirectForkEdge(const CallICFGNode* cs, const SVFFunct void ThreadCallGraph::addDirectJoinEdge(const CallICFGNode* cs,const CallSiteSet& forkset) { - PTACallGraphNode* joinFunNode = getCallGraphNode(cs->getCaller()); + PTACallGraphNode* joinFunNode = + getPTACallGraphNode(cs->getCaller()); for (CallSiteSet::const_iterator it = forkset.begin(), eit = forkset.end(); it != eit; ++it) { - const SVFFunction* threadRoutineFun = + const CallGraphNode* threadRoutineFun = SVFUtil::dyn_cast(tdAPI->getForkedFun(*it)) - ->getCallGraphNode() - ->getFunction(); + ->getCallGraphNode(); assert(threadRoutineFun && "thread routine function does not exist"); - PTACallGraphNode* threadRoutineFunNode = getCallGraphNode(threadRoutineFun); + PTACallGraphNode* threadRoutineFunNode = + getPTACallGraphNode(threadRoutineFun); CallSiteID csId = addCallSite(cs, threadRoutineFun); if (!hasThreadJoinEdge(cs,joinFunNode,threadRoutineFunNode, csId)) { - assert(cs->getCaller() == joinFunNode->getFunction() && "callee instruction not inside caller??"); + assert(cs->getCaller() == joinFunNode->getCallGraphNode() && "callee instruction not inside caller??"); ThreadJoinEdge* edge = new ThreadJoinEdge(joinFunNode,threadRoutineFunNode,csId); edge->addDirectCallSite(cs); diff --git a/svf/lib/Graphs/VFG.cpp b/svf/lib/Graphs/VFG.cpp index 6c73bab184..917ad7f06a 100644 --- a/svf/lib/Graphs/VFG.cpp +++ b/svf/lib/Graphs/VFG.cpp @@ -405,7 +405,7 @@ const std::string RetDirSVFGEdge::toString() const -FormalRetVFGNode::FormalRetVFGNode(NodeID id, const PAGNode* n, const SVFFunction* f) : +FormalRetVFGNode::FormalRetVFGNode(NodeID id, const PAGNode* n, const CallGraphNode* f) : ArgumentVFGNode(id, n, FRet), fun(f) { } @@ -531,7 +531,7 @@ void VFG::addVFGNodes() // initialize formal parameter nodes for(SVFIR::FunToArgsListMap::iterator it = pag->getFunArgsMap().begin(), eit = pag->getFunArgsMap().end(); it !=eit; ++it) { - const SVFFunction* func = it->first; + const CallGraphNode* func = it->first; for(SVFIR::SVFVarList::iterator pit = it->second.begin(), epit = it->second.end(); pit!=epit; ++pit) { @@ -577,7 +577,7 @@ void VFG::addVFGNodes() // initialize formal return nodes (callee return) for (SVFIR::FunToRetMap::iterator it = pag->getFunRets().begin(), eit = pag->getFunRets().end(); it != eit; ++it) { - const SVFFunction* func = it->first; + const CallGraphNode* func = it->first; const PAGNode* uniqueFunRetNode = it->second; @@ -945,7 +945,7 @@ void VFG::updateCallGraph(PointerAnalysis* pta) const PointerAnalysis::FunctionSet & functions = iter->second; for (PointerAnalysis::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++) { - const SVFFunction* func = *func_iter; + const CallGraphNode* func = *func_iter; connectCallerAndCallee(newcs, func, vfEdgesAtIndCallSite); } } @@ -955,7 +955,7 @@ void VFG::updateCallGraph(PointerAnalysis* pta) * Connect actual params/return to formal params/return for top-level variables. * Also connect indirect actual in/out and formal in/out. */ -void VFG::connectCallerAndCallee(const CallICFGNode* callBlockNode, const SVFFunction* callee, VFGEdgeSetTy& edges) +void VFG::connectCallerAndCallee(const CallICFGNode* callBlockNode, const CallGraphNode* callee, VFGEdgeSetTy& edges) { SVFIR * pag = SVFIR::getPAG(); CallSiteID csId = getCallSiteID(callBlockNode, callee); @@ -1043,7 +1043,7 @@ const PAGNode* VFG::getLHSTopLevPtr(const VFGNode* node) const /*! * Whether this is an function entry VFGNode (formal parameter, formal In) */ -const SVFFunction* VFG::isFunEntryVFGNode(const VFGNode* node) const +const CallGraphNode* VFG::isFunEntryVFGNode(const VFGNode* node) const { if(const FormalParmVFGNode* fp = SVFUtil::dyn_cast(node)) { diff --git a/svf/lib/MSSA/MemPartition.cpp b/svf/lib/MSSA/MemPartition.cpp index 48a4810487..c4304d3980 100644 --- a/svf/lib/MSSA/MemPartition.cpp +++ b/svf/lib/MSSA/MemPartition.cpp @@ -44,7 +44,7 @@ void DistinctMRG::partitionMRs() for(FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), eit = getFunToPointsToList().end(); it!=eit; ++it) { - const SVFFunction* fun = it->first; + const CallGraphNode* fun = it->first; /// Collect all points-to target in a function scope. NodeBS mergePts; for(PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit) @@ -61,7 +61,7 @@ void DistinctMRG::partitionMRs() * 1. collect all points-to targets in a function scope. * 2. create memory region for each point-to target. */ -void DistinctMRG::createDistinctMR(const SVFFunction* func, const NodeBS& pts) +void DistinctMRG::createDistinctMR(const CallGraphNode* func, const NodeBS& pts) { /// Create memory regions for each points-to target. @@ -88,7 +88,7 @@ void DistinctMRG::createDistinctMR(const SVFFunction* func, const NodeBS& pts) * @param fun The function being analyzed. * @param mrs Memory region set contains all possible target memory regions. */ -void DistinctMRG::getMRsForLoad(MRSet& mrs, const NodeBS& pts, const SVFFunction*) +void DistinctMRG::getMRsForLoad(MRSet& mrs, const NodeBS& pts, const CallGraphNode*) { /// Get memory regions for each points-to element in cpts. @@ -112,7 +112,7 @@ void DistinctMRG::getMRsForLoad(MRSet& mrs, const NodeBS& pts, const SVFFunction * Get memory regions to be inserted at a load statement. * Just process as getMRsForLoad(). */ -void DistinctMRG::getMRsForCallSiteRef(MRSet& aliasMRs, const NodeBS& cpts, const SVFFunction* fun) +void DistinctMRG::getMRsForCallSiteRef(MRSet& aliasMRs, const NodeBS& cpts, const CallGraphNode* fun) { getMRsForLoad(aliasMRs, cpts, fun); } @@ -124,7 +124,7 @@ void IntraDisjointMRG::partitionMRs() for(FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), eit = getFunToPointsToList().end(); it!=eit; ++it) { - const SVFFunction* fun = it->first; + const CallGraphNode* fun = it->first; for(PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit) @@ -229,7 +229,7 @@ void IntraDisjointMRG::computeIntersections(const NodeBS& cpts, PointsToList& in /** * Create memory regions for each points-to target. */ -void IntraDisjointMRG::createDisjointMR(const SVFFunction* func, const NodeBS& cpts) +void IntraDisjointMRG::createDisjointMR(const CallGraphNode* func, const NodeBS& cpts) { // set the rep cpts as itself. cptsToRepCPtsMap[cpts] = cpts; @@ -259,7 +259,7 @@ void IntraDisjointMRG::getMRsForLoadFromInterList(MRSet& mrs, const NodeBS& cpts * Get memory regions to be inserted at a load statement. * Just process as getMRsForLoad(). */ -void IntraDisjointMRG::getMRsForCallSiteRef(MRSet& aliasMRs, const NodeBS& cpts, const SVFFunction* fun) +void IntraDisjointMRG::getMRsForCallSiteRef(MRSet& aliasMRs, const NodeBS& cpts, const CallGraphNode* fun) { getMRsForLoad(aliasMRs, cpts, fun); } @@ -285,7 +285,7 @@ void InterDisjointMRG::partitionMRs() for(FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), eit = getFunToPointsToList().end(); it!=eit; ++it) { - const SVFFunction* fun = it->first; + const CallGraphNode* fun = it->first; for(PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit) diff --git a/svf/lib/MSSA/MemRegion.cpp b/svf/lib/MSSA/MemRegion.cpp index 1fd173a0c2..1b2c24d6b1 100644 --- a/svf/lib/MSSA/MemRegion.cpp +++ b/svf/lib/MSSA/MemRegion.cpp @@ -67,7 +67,7 @@ void MRGenerator::destroy() /*! * Generate a memory region and put in into functions which use it */ -void MRGenerator::createMR(const SVFFunction* fun, const NodeBS& cpts) +void MRGenerator::createMR(const CallGraphNode* fun, const NodeBS& cpts) { const NodeBS& repCPts = getRepPointsTo(cpts); MemRegion mr(repCPts); @@ -177,13 +177,13 @@ void MRGenerator::collectModRefForLoadStore() CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); for (const auto& item: *svfirCallGraph) { - const SVFFunction& fun = *item.second->getFunction(); + const CallGraphNode& fun = *item.second; /// if this function does not have any caller, then we do not care its MSSA if (Options::IgnoreDeadFun() && fun.isUncalledFunction()) continue; - for (SVFFunction::const_iterator iter = fun.begin(), eiter = fun.end(); + for (CallGraphNode::const_bb_iterator iter = fun.begin(), eiter = fun.end(); iter != eiter; ++iter) { const SVFBasicBlock* bb = iter->second; @@ -331,7 +331,7 @@ void MRGenerator::partitionMRs() for(FunToPointsTosMap::iterator it = getFunToPointsToList().begin(), eit = getFunToPointsToList().end(); it!=eit; ++it) { - const SVFFunction* fun = it->first; + const CallGraphNode* fun = it->first; for(PointsToList::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit) { createMR(fun,*cit); @@ -350,7 +350,7 @@ void MRGenerator::updateAliasMRs() for(StoresToPointsToMap::const_iterator it = storesToPointsToMap.begin(), eit = storesToPointsToMap.end(); it!=eit; ++it) { MRSet aliasMRs; - const SVFFunction* fun = getFunction(it->first); + const CallGraphNode* fun = getFunction(it->first); const NodeBS& storeCPts = it->second; getAliasMemRegions(aliasMRs,storeCPts,fun); for(MRSet::iterator ait = aliasMRs.begin(), eait = aliasMRs.end(); ait!=eait; ++ait) @@ -362,7 +362,7 @@ void MRGenerator::updateAliasMRs() for(LoadsToPointsToMap::const_iterator it = loadsToPointsToMap.begin(), eit = loadsToPointsToMap.end(); it!=eit; ++it) { MRSet aliasMRs; - const SVFFunction* fun = getFunction(it->first); + const CallGraphNode* fun = getFunction(it->first); const NodeBS& loadCPts = it->second; getMRsForLoad(aliasMRs, loadCPts, fun); for(MRSet::iterator ait = aliasMRs.begin(), eait = aliasMRs.end(); ait!=eait; ++ait) @@ -375,7 +375,7 @@ void MRGenerator::updateAliasMRs() for(CallSiteToPointsToMap::const_iterator it = callsiteToModPointsToMap.begin(), eit = callsiteToModPointsToMap.end(); it!=eit; ++it) { - const SVFFunction* fun = it->first->getCaller(); + const CallGraphNode* fun = it->first->getCaller(); MRSet aliasMRs; const NodeBS& callsiteModCPts = it->second; getAliasMemRegions(aliasMRs,callsiteModCPts,fun); @@ -387,7 +387,7 @@ void MRGenerator::updateAliasMRs() for(CallSiteToPointsToMap::const_iterator it = callsiteToRefPointsToMap.begin(), eit = callsiteToRefPointsToMap.end(); it!=eit; ++it) { - const SVFFunction* fun = it->first->getCaller(); + const CallGraphNode* fun = it->first->getCaller(); MRSet aliasMRs; const NodeBS& callsiteRefCPts = it->second; getMRsForCallSiteRef(aliasMRs, callsiteRefCPts, fun); @@ -402,7 +402,7 @@ void MRGenerator::updateAliasMRs() /*! * Add indirect uses an memory object in the function */ -void MRGenerator::addRefSideEffectOfFunction(const SVFFunction* fun, const NodeBS& refs) +void MRGenerator::addRefSideEffectOfFunction(const CallGraphNode* fun, const NodeBS& refs) { for(NodeBS::iterator it = refs.begin(), eit = refs.end(); it!=eit; ++it) { @@ -414,7 +414,7 @@ void MRGenerator::addRefSideEffectOfFunction(const SVFFunction* fun, const NodeB /*! * Add indirect def an memory object in the function */ -void MRGenerator::addModSideEffectOfFunction(const SVFFunction* fun, const NodeBS& mods) +void MRGenerator::addModSideEffectOfFunction(const CallGraphNode* fun, const NodeBS& mods) { for(NodeBS::iterator it = mods.begin(), eit = mods.end(); it!=eit; ++it) { @@ -558,7 +558,7 @@ void MRGenerator::getEscapObjviaGlobals(NodeBS& globs, const NodeBS& calleeModRe * Whether the object node is a non-local object * including global, heap, and stack variable in recursions */ -bool MRGenerator::isNonLocalObject(NodeID id, const SVFFunction* curFun) const +bool MRGenerator::isNonLocalObject(NodeID id, const CallGraphNode* curFun) const { //ABTest const BaseObjVar* obj = pta->getPAG()->getBaseObject(id); @@ -572,12 +572,12 @@ bool MRGenerator::isNonLocalObject(NodeID id, const SVFFunction* curFun) const /// or a local variable is in function recursion cycles else if(SVFUtil::isa(pVar)) { - if(const SVFFunction* svffun = pVar->getFunction()) + if(const CallGraphNode* svffun = pVar->getFunction()) { if(svffun!=curFun) return true; else - return callGraphSCC->isInCycle(callGraph->getCallGraphNode(svffun)->getId()); + return callGraphSCC->isInCycle(svffun->getId()); } } @@ -587,7 +587,7 @@ bool MRGenerator::isNonLocalObject(NodeID id, const SVFFunction* curFun) const /*! * Get Mod-Ref of a callee function */ -bool MRGenerator::handleCallsiteModRef(NodeBS& mod, NodeBS& ref, const CallICFGNode* cs, const SVFFunction* callee) +bool MRGenerator::handleCallsiteModRef(NodeBS& mod, NodeBS& ref, const CallICFGNode* cs, const CallGraphNode* callee) { /// if a callee is a heap allocator function, then its mod set of this callsite is the heap object. if(isHeapAllocExtCall(cs)) @@ -634,7 +634,7 @@ void MRGenerator::modRefAnalysis(PTACallGraphNode* callGraphNode, WorkList& work { NodeBS mod, ref; const CallICFGNode* cs = (*cit); - bool modrefchanged = handleCallsiteModRef(mod, ref, cs, callGraphNode->getFunction()); + bool modrefchanged = handleCallsiteModRef(mod, ref, cs, callGraphNode->getCallGraphNode()); if(modrefchanged) worklist.push(edge->getSrcID()); } @@ -644,7 +644,7 @@ void MRGenerator::modRefAnalysis(PTACallGraphNode* callGraphNode, WorkList& work { NodeBS mod, ref; const CallICFGNode* cs = (*cit); - bool modrefchanged = handleCallsiteModRef(mod, ref, cs, callGraphNode->getFunction()); + bool modrefchanged = handleCallsiteModRef(mod, ref, cs, callGraphNode->getCallGraphNode()); if(modrefchanged) worklist.push(edge->getSrcID()); } diff --git a/svf/lib/MSSA/MemSSA.cpp b/svf/lib/MSSA/MemSSA.cpp index 6e189ad22b..148993a5aa 100644 --- a/svf/lib/MSSA/MemSSA.cpp +++ b/svf/lib/MSSA/MemSSA.cpp @@ -77,7 +77,7 @@ SVFIR* MemSSA::getPAG() /*! * Start building memory SSA */ -void MemSSA::buildMemSSA(const SVFFunction& fun) +void MemSSA::buildMemSSA(const CallGraphNode& fun) { assert(!isExtCall(&fun) && "we do not build memory ssa for external functions"); @@ -112,7 +112,7 @@ void MemSSA::buildMemSSA(const SVFFunction& fun) * Create mu/chi according to memory regions * collect used mrs in usedRegs and construction map from region to BB for prune SSA phi insertion */ -void MemSSA::createMUCHI(const SVFFunction& fun) +void MemSSA::createMUCHI(const CallGraphNode& fun) { @@ -198,7 +198,7 @@ void MemSSA::createMUCHI(const SVFFunction& fun) /* * Insert phi node */ -void MemSSA::insertPHI(const SVFFunction& fun) +void MemSSA::insertPHI(const CallGraphNode& fun) { DBOUT(DMSSA, @@ -246,7 +246,7 @@ void MemSSA::insertPHI(const SVFFunction& fun) /*! * SSA construction algorithm */ -void MemSSA::SSARename(const SVFFunction& fun) +void MemSSA::SSARename(const CallGraphNode& fun) { DBOUT(DMSSA, @@ -307,7 +307,7 @@ void MemSSA::SSARenameBB(const SVFBasicBlock& bb) } else if(isRetInstNode(pNode)) { - const SVFFunction* fun = bb.getParent(); + const CallGraphNode* fun = bb.getParent(); RenameMuSet(getReturnMuSet(fun)); } } @@ -322,7 +322,7 @@ void MemSSA::SSARenameBB(const SVFBasicBlock& bb) } // for succ basic block in dominator tree - const SVFFunction* fun = bb.getParent(); + const CallGraphNode* fun = bb.getParent(); const Map>& dtBBsMap = fun->getDomTreeMap(); Map>::const_iterator mapIter = dtBBsMap.find(&bb); if (mapIter != dtBBsMap.end()) @@ -579,7 +579,7 @@ void MemSSA::dumpMSSA(OutStream& Out) CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); for (const auto& item: *svfirCallGraph) { - const SVFFunction* fun = item.second->getFunction(); + const CallGraphNode* fun = item.second; if(Options::MSSAFun()!="" && Options::MSSAFun()!=fun->getName()) continue; @@ -594,7 +594,7 @@ void MemSSA::dumpMSSA(OutStream& Out) } } - for (SVFFunction::const_iterator bit = fun->begin(), ebit = fun->end(); + for (CallGraphNode::const_bb_iterator bit = fun->begin(), ebit = fun->end(); bit != ebit; ++bit) { const SVFBasicBlock* bb = bit->second; diff --git a/svf/lib/MSSA/SVFGBuilder.cpp b/svf/lib/MSSA/SVFGBuilder.cpp index 95a181f3c8..833d73d90e 100644 --- a/svf/lib/MSSA/SVFGBuilder.cpp +++ b/svf/lib/MSSA/SVFGBuilder.cpp @@ -107,11 +107,11 @@ std::unique_ptr SVFGBuilder::buildMSSA(BVDataPTAImpl* pta, bool ptrOnlyM for (const auto& item: *svfirCallGraph) { - const SVFFunction *fun = item.second->getFunction(); + const CallGraphNode *fun = item.second; if (isExtCall(fun)) continue; - mssa->buildMemSSA(*fun); + mssa->buildMemSSA(*(fun)); } mssa->performStat(); diff --git a/svf/lib/MTA/LockAnalysis.cpp b/svf/lib/MTA/LockAnalysis.cpp index abbec87929..c916e76d3c 100644 --- a/svf/lib/MTA/LockAnalysis.cpp +++ b/svf/lib/MTA/LockAnalysis.cpp @@ -70,7 +70,7 @@ void LockAnalysis::collectLockUnlocksites() { ThreadCallGraph* tcg=tct->getThreadCallGraph(); - for (const SVFFunction* F : tct->getSVFModule()->getFunctionSet()) + for (const CallGraphNode* F : tct->getSVFModule()->getFunctionSet()) { for (auto it : *F) { @@ -103,8 +103,9 @@ void LockAnalysis::buildCandidateFuncSetforLock() for (InstSet::iterator it = locksites.begin(), eit = locksites.end(); it != eit; ++it) { - const SVFFunction* fun=(*it)->getFun(); - PTACallGraphNode* cgnode = tcg->getCallGraphNode(fun); + const CallGraphNode* fun=(*it)->getFun(); + PTACallGraphNode* cgnode = + tcg->getPTACallGraphNode(fun); if (visited.find(cgnode) == visited.end()) { worklist.push(cgnode); @@ -113,8 +114,9 @@ void LockAnalysis::buildCandidateFuncSetforLock() } for (InstSet::iterator it = unlocksites.begin(), eit = unlocksites.end(); it != eit; ++it) { - const SVFFunction* fun = (*it)->getFun(); - PTACallGraphNode* cgnode = tcg->getCallGraphNode(fun); + const CallGraphNode* fun = (*it)->getFun(); + PTACallGraphNode* cgnode = + tcg->getPTACallGraphNode(fun); if (visited.find(cgnode) == visited.end()) { worklist.push(cgnode); @@ -124,7 +126,7 @@ void LockAnalysis::buildCandidateFuncSetforLock() while (!worklist.empty()) { const PTACallGraphNode* node = worklist.pop(); - lockcandidateFuncSet.insert(node->getFunction()); + lockcandidateFuncSet.insert(node->getCallGraphNode()); for (PTACallGraphNode::const_iterator nit = node->InEdgeBegin(), neit = node->InEdgeEnd(); nit != neit; nit++) { const PTACallGraphNode* srcNode = (*nit)->getSrcNode(); @@ -172,7 +174,7 @@ void LockAnalysis::analyzeIntraProcedualLock() bool LockAnalysis::intraForwardTraverse(const ICFGNode* lockSite, InstSet& unlockSet, InstSet& forwardInsts) { - const SVFFunction* svfFun = lockSite->getFun(); + const CallGraphNode* svfFun = lockSite->getFun(); InstVec worklist; worklist.push_back(lockSite); @@ -272,9 +274,10 @@ void LockAnalysis::collectCxtLock() while (!clpList.empty()) { CxtLockProc clp = popFromCTPWorkList(); - PTACallGraphNode* cgNode = getTCG()->getCallGraphNode(clp.getProc()); + PTACallGraphNode* cgNode = + getTCG()->getPTACallGraphNode(clp.getProc()); // lzh TODO. - if (!isLockCandidateFun(cgNode->getFunction())) + if (!isLockCandidateFun(cgNode->getCallGraphNode())) continue; for (PTACallGraphNode::const_iterator nit = cgNode->OutEdgeBegin(), neit = cgNode->OutEdgeEnd(); nit != neit; nit++) @@ -316,7 +319,7 @@ void LockAnalysis::handleCallRelation(CxtLockProc& clp, const PTACallGraphEdge* addCxtLock(cxt,curNode); return; } - const SVFFunction* svfcallee = cgEdge->getDstNode()->getFunction(); + const CallGraphNode* svfcallee = cgEdge->getDstNode()->getCallGraphNode(); pushCxt(cxt, SVFUtil::cast(curNode), svfcallee); CxtLockProc newclp(cxt, svfcallee); @@ -414,7 +417,8 @@ void LockAnalysis::handleFork(const CxtStmt& cts) for (ThreadCallGraph::ForkEdgeSet::const_iterator cgIt = getTCG()->getForkEdgeBegin(call), ecgIt = getTCG()->getForkEdgeEnd(call); cgIt != ecgIt; ++cgIt) { - const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction(); + const CallGraphNode* svfcallee = + (*cgIt)->getDstNode()->getCallGraphNode(); CallStrCxt newCxt = curCxt; pushCxt(newCxt,call,svfcallee); const ICFGNode* svfInst = svfcallee->getEntryBlock()->front(); @@ -436,7 +440,8 @@ void LockAnalysis::handleCall(const CxtStmt& cts) for (PTACallGraph::CallGraphEdgeSet::const_iterator cgIt = getTCG()->getCallEdgeBegin(call), ecgIt = getTCG()->getCallEdgeEnd(call); cgIt != ecgIt; ++cgIt) { - const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction(); + const CallGraphNode* svfcallee = + (*cgIt)->getDstNode()->getCallGraphNode(); if (SVFUtil::isExtCall(svfcallee)) continue; CallStrCxt newCxt = curCxt; @@ -454,8 +459,9 @@ void LockAnalysis::handleRet(const CxtStmt& cts) const ICFGNode* curInst = cts.getStmt(); const CallStrCxt& curCxt = cts.getContext(); - const SVFFunction* svffun = curInst->getFun(); - PTACallGraphNode* curFunNode = getTCG()->getCallGraphNode(svffun); + const CallGraphNode* svffun = curInst->getFun(); + PTACallGraphNode* curFunNode = + getTCG()->getPTACallGraphNode(svffun); for (PTACallGraphNode::const_iterator it = curFunNode->getInEdges().begin(), eit = curFunNode->getInEdges().end(); it != eit; ++it) { @@ -467,7 +473,8 @@ void LockAnalysis::handleRet(const CxtStmt& cts) { CallStrCxt newCxt = curCxt; const ICFGNode* inst = *cit; - if (matchCxt(newCxt, SVFUtil::cast(inst), curFunNode->getFunction())) + if (matchCxt(newCxt, SVFUtil::cast(inst), + curFunNode->getCallGraphNode())) { for(const ICFGEdge* outEdge : curInst->getOutEdges()) { @@ -484,7 +491,8 @@ void LockAnalysis::handleRet(const CxtStmt& cts) { CallStrCxt newCxt = curCxt; const ICFGNode* inst = *cit; - if (matchCxt(newCxt, SVFUtil::cast(inst), curFunNode->getFunction())) + if (matchCxt(newCxt, SVFUtil::cast(inst), + curFunNode->getCallGraphNode())) { for(const ICFGEdge* outEdge : curInst->getOutEdges()) { @@ -517,25 +525,27 @@ void LockAnalysis::handleIntra(const CxtStmt& cts) } -void LockAnalysis::pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee) +void LockAnalysis::pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const CallGraphNode* callee) { - const SVFFunction* svfcaller = call->getFun(); + const CallGraphNode* svfcaller = call->getFun(); CallSiteID csId = getTCG()->getCallSiteID(call, callee); // /// handle calling context for candidate functions only // if (isLockCandidateFun(caller) == false) // return; - if (tct->inSameCallGraphSCC(getTCG()->getCallGraphNode(svfcaller), getTCG()->getCallGraphNode(callee)) == false) + if (tct->inSameCallGraphSCC( + getTCG()->getPTACallGraphNode(svfcaller), + getTCG()->getPTACallGraphNode(callee)) == false) { tct->pushCxt(cxt,csId); DBOUT(DMTA, tct->dumpCxt(cxt)); } } -bool LockAnalysis::matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee) +bool LockAnalysis::matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const CallGraphNode* callee) { - const SVFFunction* svfcaller = call->getFun(); + const CallGraphNode* svfcaller = call->getFun(); CallSiteID csId = getTCG()->getCallSiteID(call, callee); // /// handle calling context for candidate functions only @@ -546,7 +556,9 @@ bool LockAnalysis::matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVF if (cxt.empty()) return true; - if (tct->inSameCallGraphSCC(getTCG()->getCallGraphNode(svfcaller), getTCG()->getCallGraphNode(callee)) == false) + if (tct->inSameCallGraphSCC( + getTCG()->getPTACallGraphNode(svfcaller), + getTCG()->getPTACallGraphNode(callee)) == false) { if (cxt.back() == csId) cxt.pop_back(); diff --git a/svf/lib/MTA/MHP.cpp b/svf/lib/MTA/MHP.cpp index b104a6d25a..3890854ed0 100644 --- a/svf/lib/MTA/MHP.cpp +++ b/svf/lib/MTA/MHP.cpp @@ -78,7 +78,7 @@ void MHP::analyzeInterleaving() { const CxtThread& ct = tpair.second->getCxtThread(); NodeID rootTid = tpair.first; - const SVFFunction* routine = tct->getStartRoutineOfCxtThread(ct); + const CallGraphNode* routine = tct->getStartRoutineOfCxtThread(ct); const ICFGNode* svfInst = routine->getEntryBlock()->front(); CxtThreadStmt rootcts(rootTid, ct.getContext(), svfInst); @@ -144,7 +144,7 @@ void MHP::analyzeInterleaving() void MHP::updateNonCandidateFunInterleaving() { SVFModule* module = tct->getSVFModule(); - for (const SVFFunction* fun : module->getFunctionSet()) + for (const CallGraphNode* fun : module->getFunctionSet()) { if (!tct->isCandidateFun(fun) && !isExtCall(fun)) { @@ -182,13 +182,14 @@ void MHP::updateNonCandidateFunInterleaving() void MHP::handleNonCandidateFun(const CxtThreadStmt& cts) { const ICFGNode* curInst = cts.getStmt(); - const SVFFunction* curfun = curInst->getFun(); + const CallGraphNode* curfun = curInst->getFun(); assert((curInst == curfun->getEntryBlock()->front()) && "curInst is not the entry of non candidate function."); const CallStrCxt& curCxt = cts.getContext(); - PTACallGraphNode* node = tcg->getCallGraphNode(curfun); + PTACallGraphNode* node = + tcg->getPTACallGraphNode(curfun); for (PTACallGraphNode::const_iterator nit = node->OutEdgeBegin(), neit = node->OutEdgeEnd(); nit != neit; nit++) { - const SVFFunction* callee = (*nit)->getDstNode()->getFunction(); + const CallGraphNode* callee = (*nit)->getDstNode()->getCallGraphNode(); if (!isExtCall(callee)) { const ICFGNode* calleeInst = callee->getEntryBlock()->front(); @@ -216,10 +217,11 @@ void MHP::handleFork(const CxtThreadStmt& cts, NodeID rootTid) ecgIt = tcg->getForkEdgeEnd(cbn); cgIt != ecgIt; ++cgIt) { - const SVFFunction* svfroutine = (*cgIt)->getDstNode()->getFunction(); + const CallGraphNode* cgn = + (*cgIt)->getDstNode()->getCallGraphNode(); CallStrCxt newCxt = curCxt; - pushCxt(newCxt, cbn, svfroutine); - const ICFGNode* stmt = svfroutine->getEntryBlock()->front(); + pushCxt(newCxt, cbn, cgn); + const ICFGNode* stmt = cgn->getEntryBlock()->front(); CxtThread ct(newCxt, call); CxtThreadStmt newcts(tct->getTCTNode(ct)->getId(), ct.getContext(), stmt); addInterleavingThread(newcts, cts); @@ -301,13 +303,14 @@ void MHP::handleCall(const CxtThreadStmt& cts, NodeID rootTid) cgIt != ecgIt; ++cgIt) { - const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction(); - if (isExtCall(svfcallee)) + const CallGraphNode* cgnCallee = + (*cgIt)->getDstNode()->getCallGraphNode(); + if (isExtCall(cgnCallee)) continue; CallStrCxt newCxt = curCxt; const CallICFGNode* callicfgnode = SVFUtil::cast(call); - pushCxt(newCxt, callicfgnode, svfcallee); - const ICFGNode* svfEntryInst = svfcallee->getEntryBlock()->front(); + pushCxt(newCxt, callicfgnode, cgnCallee); + const ICFGNode* svfEntryInst = cgnCallee->getEntryBlock()->front(); CxtThreadStmt newCts(cts.getTid(), newCxt, svfEntryInst); addInterleavingThread(newCts, cts); } @@ -319,7 +322,8 @@ void MHP::handleCall(const CxtThreadStmt& cts, NodeID rootTid) */ void MHP::handleRet(const CxtThreadStmt& cts) { - PTACallGraphNode* curFunNode = tcg->getCallGraphNode(cts.getStmt()->getFun()); + PTACallGraphNode* curFunNode = + tcg->getPTACallGraphNode(cts.getStmt()->getFun()); for (PTACallGraphEdge* edge : curFunNode->getInEdges()) { if (SVFUtil::isa(edge)) @@ -329,7 +333,7 @@ void MHP::handleRet(const CxtThreadStmt& cts) cit != ecit; ++cit) { CallStrCxt newCxt = cts.getContext(); - if (matchCxt(newCxt, *cit, curFunNode->getFunction())) + if (matchCxt(newCxt, *cit, curFunNode->getCallGraphNode())) { for(const ICFGEdge* outEdge : cts.getStmt()->getOutEdges()) { @@ -346,7 +350,7 @@ void MHP::handleRet(const CxtThreadStmt& cts) cit != ecit; ++cit) { CallStrCxt newCxt = cts.getContext(); - if (matchCxt(newCxt, *cit, curFunNode->getFunction())) + if (matchCxt(newCxt, *cit, curFunNode->getCallGraphNode())) { for(const ICFGEdge* outEdge : cts.getStmt()->getOutEdges()) { @@ -429,7 +433,7 @@ void MHP::updateSiblingThreads(NodeID curTid) continue; const CxtThread& ct = tct->getTCTNode(stid)->getCxtThread(); - const SVFFunction* routine = tct->getStartRoutineOfCxtThread(ct); + const CallGraphNode* routine = tct->getStartRoutineOfCxtThread(ct); const ICFGNode* stmt = routine->getEntryBlock()->front(); CxtThreadStmt cts(stid, ct.getContext(), stmt); addInterleavingThread(cts, curTid); @@ -519,9 +523,10 @@ bool MHP::isHBPair(NodeID tid1, NodeID tid2) return fja->isHBPair(tid1, tid2); } -bool MHP::isConnectedfromMain(const SVFFunction* fun) +bool MHP::isConnectedfromMain(const CallGraphNode* fun) { - PTACallGraphNode* cgnode = tcg->getCallGraphNode(fun); + PTACallGraphNode* cgnode = + tcg->getPTACallGraphNode(fun); FIFOWorkList worklist; TCT::PTACGNodeSet visited; worklist.push(cgnode); @@ -529,7 +534,7 @@ bool MHP::isConnectedfromMain(const SVFFunction* fun) while (!worklist.empty()) { const PTACallGraphNode* node = worklist.pop(); - if ("main" == node->getFunction()->getName()) + if ("main" == node->getCallGraphNode()->getName()) return true; for (PTACallGraphNode::const_iterator nit = node->InEdgeBegin(), neit = node->InEdgeEnd(); nit != neit; nit++) { @@ -668,7 +673,7 @@ void MHP::printInterleaving() void ForkJoinAnalysis::collectSCEVInfo() { // typedef Set CallInstSet; - // typedef Map FunToFJSites; + // typedef Map FunToFJSites; // FunToFJSites funToFJSites; // for (ThreadCallGraph::CallSiteSet::const_iterator it = tct->getThreadCallGraph()->forksitesBegin(), @@ -796,7 +801,8 @@ void ForkJoinAnalysis::handleFork(const CxtStmt& cts, NodeID rootTid) ecgIt = getTCG()->getForkEdgeEnd(cbn); cgIt != ecgIt; ++cgIt) { - const SVFFunction* callee = (*cgIt)->getDstNode()->getFunction(); + const CallGraphNode* callee = + (*cgIt)->getDstNode()->getCallGraphNode(); CallStrCxt newCxt = curCxt; pushCxt(newCxt, cbn, callee); CxtThread ct(newCxt, call); @@ -887,12 +893,13 @@ void ForkJoinAnalysis::handleCall(const CxtStmt& cts, NodeID rootTid) ecgIt = getTCG()->getCallEdgeEnd(cbn); cgIt != ecgIt; ++cgIt) { - const SVFFunction* svfcallee = (*cgIt)->getDstNode()->getFunction(); - if (isExtCall(svfcallee)) + const CallGraphNode* cgnCallee = + (*cgIt)->getDstNode()->getCallGraphNode(); + if (isExtCall(cgnCallee)) continue; CallStrCxt newCxt = curCxt; - pushCxt(newCxt, cbn, svfcallee); - const ICFGNode* svfEntryInst = svfcallee->getEntryBlock()->front(); + pushCxt(newCxt, cbn, cgnCallee); + const ICFGNode* svfEntryInst = cgnCallee->getEntryBlock()->front(); CxtStmt newCts(newCxt, svfEntryInst); markCxtStmtFlag(newCts, cts); } @@ -905,7 +912,8 @@ void ForkJoinAnalysis::handleRet(const CxtStmt& cts) const ICFGNode* curInst = cts.getStmt(); const CallStrCxt& curCxt = cts.getContext(); - PTACallGraphNode* curFunNode = getTCG()->getCallGraphNode(curInst->getFun()); + PTACallGraphNode* curFunNode = + getTCG()->getPTACallGraphNode(curInst->getFun()); for (PTACallGraphEdge* edge : curFunNode->getInEdges()) { if (SVFUtil::isa(edge)) @@ -916,7 +924,8 @@ void ForkJoinAnalysis::handleRet(const CxtStmt& cts) { CallStrCxt newCxt = curCxt; const ICFGNode* curNode = (*cit); - if (matchCxt(newCxt, SVFUtil::cast(curNode), curFunNode->getFunction())) + if (matchCxt(newCxt, SVFUtil::cast(curNode), + curFunNode->getCallGraphNode())) { for(const ICFGEdge* outEdge : curNode->getOutEdges()) { @@ -935,7 +944,8 @@ void ForkJoinAnalysis::handleRet(const CxtStmt& cts) CallStrCxt newCxt = curCxt; const ICFGNode* curNode = (*cit); - if (matchCxt(newCxt, SVFUtil::cast(curNode), curFunNode->getFunction())) + if (matchCxt(newCxt, SVFUtil::cast(curNode), + curFunNode->getCallGraphNode())) { for(const ICFGEdge* outEdge : curNode->getOutEdges()) { diff --git a/svf/lib/MTA/MTA.cpp b/svf/lib/MTA/MTA.cpp index 5b6e671c3f..dd193c8247 100644 --- a/svf/lib/MTA/MTA.cpp +++ b/svf/lib/MTA/MTA.cpp @@ -136,7 +136,7 @@ void MTA::detect(SVFModule* module) PointerAnalysis* pta = AndersenWaveDiff::createAndersenWaveDiff(pag); // Add symbols for all of the functions and the instructions in them. - for (const SVFFunction* F : module->getFunctionSet()) + for (const CallGraphNode* F : module->getFunctionSet()) { // collect and create symbols inside the function body for (auto it : *F) diff --git a/svf/lib/MTA/MTAStat.cpp b/svf/lib/MTA/MTAStat.cpp index a5c1b98491..811e705be3 100644 --- a/svf/lib/MTA/MTAStat.cpp +++ b/svf/lib/MTA/MTAStat.cpp @@ -118,13 +118,13 @@ void MTAStat::performMHPPairStat(MHP* mhp, LockAnalysis* lsa) Set instSet1; Set instSet2; SVFModule* mod = mhp->getTCT()->getSVFModule(); - for (const SVFFunction* fun : mod->getFunctionSet()) + for (const CallGraphNode* fun : mod->getFunctionSet()) { if(SVFUtil::isExtCall(fun)) continue; if(!mhp->isConnectedfromMain(fun)) continue; - for (SVFFunction::const_iterator bit = fun->begin(), ebit = fun->end(); bit != ebit; ++bit) + for (CallGraphNode::const_bb_iterator bit = fun->begin(), ebit = fun->end(); bit != ebit; ++bit) { const SVFBasicBlock* bb = bit->second; for (const auto& icfgNode : bb->getICFGNodeList()) diff --git a/svf/lib/MTA/TCT.cpp b/svf/lib/MTA/TCT.cpp index 752654176e..24876ae13f 100644 --- a/svf/lib/MTA/TCT.cpp +++ b/svf/lib/MTA/TCT.cpp @@ -55,7 +55,8 @@ bool TCT::isInLoopInstruction(const ICFGNode* inst) { const ICFGNode* inst = worklist.pop(); insts.insert(inst); - PTACallGraphNode* cgnode = tcg->getCallGraphNode(inst->getFun()); + PTACallGraphNode* cgnode = + tcg->getPTACallGraphNode(inst->getFun()); for(PTACallGraphNode::const_iterator nit = cgnode->InEdgeBegin(), neit = cgnode->InEdgeEnd(); nit!=neit; nit++) { for(PTACallGraphEdge::CallInstSet::const_iterator cit = (*nit)->directCallsBegin(), @@ -90,33 +91,35 @@ bool TCT::isInLoopInstruction(const ICFGNode* inst) */ bool TCT::isInRecursion(const ICFGNode* inst) const { - const SVFFunction* f = inst->getFun(); - FIFOWorkList worklist; - Set visits; + const CallGraphNode* f = inst->getFun(); + FIFOWorkList worklist; + Set visits; worklist.push(f); while(!worklist.empty()) { - const SVFFunction* svffun = worklist.pop(); + const CallGraphNode* svffun = worklist.pop(); visits.insert(svffun); - if(tcgSCC->isInCycle(tcg->getCallGraphNode(svffun)->getId())) + if(tcgSCC->isInCycle( + tcg->getPTACallGraphNode(svffun)->getId())) return true; - const PTACallGraphNode* cgnode = tcg->getCallGraphNode(svffun); + const PTACallGraphNode* cgnode = + tcg->getPTACallGraphNode(svffun); for(PTACallGraphNode::const_iterator nit = cgnode->InEdgeBegin(), neit = cgnode->InEdgeEnd(); nit!=neit; nit++) { for(PTACallGraphEdge::CallInstSet::const_iterator cit = (*nit)->directCallsBegin(), ecit = (*nit)->directCallsEnd(); cit!=ecit; ++cit) { - const SVFFunction* caller = (*cit)->getFun(); + const CallGraphNode* caller = (*cit)->getFun(); if(visits.find(caller)==visits.end()) worklist.push(caller); } for(PTACallGraphEdge::CallInstSet::const_iterator cit = (*nit)->indirectCallsBegin(), ecit = (*nit)->indirectCallsEnd(); cit!=ecit; ++cit) { - const SVFFunction* caller = (*cit)->getFun(); + const CallGraphNode* caller = (*cit)->getFun(); if(visits.find(caller)==visits.end()) worklist.push(caller); } @@ -134,20 +137,20 @@ void TCT::markRelProcs() { for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->forksitesBegin(), eit = tcg->forksitesEnd(); it != eit; ++it) { - const SVFFunction* svfun = (*it)->getParent()->getParent(); + const CallGraphNode* svfun = (*it)->getParent()->getParent(); markRelProcs(svfun); for(ThreadCallGraph::ForkEdgeSet::const_iterator nit = tcg->getForkEdgeBegin(*it), neit = tcg->getForkEdgeEnd(*it); nit!=neit; nit++) { const PTACallGraphNode* forkeeNode = (*nit)->getDstNode(); - candidateFuncSet.insert(forkeeNode->getFunction()); + candidateFuncSet.insert(forkeeNode->getCallGraphNode()); } } for (ThreadCallGraph::CallSiteSet::const_iterator it = tcg->joinsitesBegin(), eit = tcg->joinsitesEnd(); it != eit; ++it) { - const SVFFunction* svfun = (*it)->getParent()->getParent(); + const CallGraphNode* svfun = (*it)->getParent()->getParent(); markRelProcs(svfun); } @@ -158,9 +161,10 @@ void TCT::markRelProcs() /*! * */ -void TCT::markRelProcs(const SVFFunction* svffun) +void TCT::markRelProcs(const CallGraphNode* cgFun) { - PTACallGraphNode* cgnode = tcg->getCallGraphNode(svffun); + PTACallGraphNode* cgnode = + tcg->getPTACallGraphNode(cgFun); FIFOWorkList worklist; PTACGNodeSet visited; worklist.push(cgnode); @@ -168,7 +172,7 @@ void TCT::markRelProcs(const SVFFunction* svffun) while(!worklist.empty()) { const PTACallGraphNode* node = worklist.pop(); - candidateFuncSet.insert(node->getFunction()); + candidateFuncSet.insert(node->getCallGraphNode()); for(PTACallGraphNode::const_iterator nit = node->InEdgeBegin(), neit = node->InEdgeEnd(); nit!=neit; nit++) { const PTACallGraphNode* srcNode = (*nit)->getSrcNode(); @@ -189,10 +193,11 @@ void TCT::collectEntryFunInCallGraph() CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); for (const auto& item: *svfirCallGraph) { - const SVFFunction* fun = item.second->getFunction(); + const CallGraphNode* fun = item.second; if (SVFUtil::isExtCall(fun)) continue; - PTACallGraphNode* node = tcg->getCallGraphNode(fun); + PTACallGraphNode* node = + tcg->getPTACallGraphNode(fun); if (!node->hasIncomingEdge()) { entryFuncSet.insert(fun); @@ -244,7 +249,7 @@ void TCT::collectMultiForkedThreads() */ void TCT::handleCallRelation(CxtThreadProc& ctp, const PTACallGraphEdge* cgEdge, const CallICFGNode* cs) { - const SVFFunction* callee = cgEdge->getDstNode()->getFunction(); + const CallGraphNode* callee = cgEdge->getDstNode()->getCallGraphNode(); CallStrCxt cxt(ctp.getContext()); CallStrCxt oldCxt = cxt; @@ -291,7 +296,7 @@ void TCT::handleCallRelation(CxtThreadProc& ctp, const PTACallGraphEdge* cgEdge, bool TCT::isJoinMustExecutedInLoop(const LoopBBs& lp,const ICFGNode* join) { assert(!lp.empty() && "this is not a loop, empty basic block"); - const SVFFunction* svffun = join->getFun(); + const CallGraphNode* svffun = join->getFun(); const SVFBasicBlock* loopheadbb = svffun->getLoopHeader(lp); const SVFBasicBlock* joinbb = join->getBB(); assert(loopheadbb->getParent()==joinbb->getParent() && "should inside same function"); @@ -317,7 +322,7 @@ void TCT::collectLoopInfoForJoin() for(ThreadCallGraph::CallSiteSet::const_iterator it = tcg->joinsitesBegin(), eit = tcg->joinsitesEnd(); it!=eit; ++it) { const ICFGNode* join = *it; - const SVFFunction* svffun = join->getFun(); + const CallGraphNode* svffun = join->getFun(); const SVFBasicBlock* svfbb = join->getBB(); if(svffun->hasLoopInfo(svfbb)) @@ -374,7 +379,7 @@ bool TCT::isLoopExitOfJoinLoop(const SVFBasicBlock* bb) */ const TCT::LoopBBs& TCT::getLoop(const SVFBasicBlock* bb) { - const SVFFunction* fun = bb->getParent(); + const CallGraphNode* fun = bb->getParent(); return fun->getLoopInfo(bb); } @@ -406,8 +411,9 @@ void TCT::build() while(!ctpList.empty()) { CxtThreadProc ctp = popFromCTPWorkList(); - PTACallGraphNode* cgNode = tcg->getCallGraphNode(ctp.getProc()); - if(isCandidateFun(cgNode->getFunction()) == false) + PTACallGraphNode* cgNode = + tcg->getPTACallGraphNode(ctp.getProc()); + if(isCandidateFun(cgNode->getCallGraphNode()) == false) continue; for(PTACallGraphNode::const_iterator nit = cgNode->OutEdgeBegin(), neit = cgNode->OutEdgeEnd(); nit!=neit; nit++) @@ -442,17 +448,19 @@ void TCT::build() /*! * Push calling context */ -void TCT::pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee) +void TCT::pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const CallGraphNode* callee) { - const SVFFunction* caller = call->getFun(); + const CallGraphNode* caller = call->getFun(); CallSiteID csId = tcg->getCallSiteID(call, callee); /// handle calling context for candidate functions only if(isCandidateFun(caller) == false) return; - if(inSameCallGraphSCC(tcg->getCallGraphNode(caller),tcg->getCallGraphNode(callee))==false) + if(inSameCallGraphSCC( + tcg->getPTACallGraphNode(caller), + tcg->getPTACallGraphNode(callee))==false) { pushCxt(cxt,csId); DBOUT(DMTA,dumpCxt(cxt)); @@ -463,10 +471,10 @@ void TCT::pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* /*! * Match calling context */ -bool TCT::matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee) +bool TCT::matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const CallGraphNode* callee) { - const SVFFunction* caller = call->getFun(); + const CallGraphNode* caller = call->getFun(); CallSiteID csId = tcg->getCallSiteID(call, callee); /// handle calling context for candidate functions only @@ -477,7 +485,9 @@ bool TCT::matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* if(cxt.empty()) return true; - if(inSameCallGraphSCC(tcg->getCallGraphNode(caller),tcg->getCallGraphNode(callee))==false) + if(inSameCallGraphSCC( + tcg->getPTACallGraphNode(caller), + tcg->getPTACallGraphNode(callee))==false) { if(cxt.back() == csId) cxt.pop_back(); diff --git a/svf/lib/MemoryModel/PointerAnalysis.cpp b/svf/lib/MemoryModel/PointerAnalysis.cpp index 6aa63096f1..13efe6493d 100644 --- a/svf/lib/MemoryModel/PointerAnalysis.cpp +++ b/svf/lib/MemoryModel/PointerAnalysis.cpp @@ -137,9 +137,9 @@ bool PointerAnalysis::isLocalVarInRecursiveFun(NodeID id) const assert(baseObjVar && "base object not found!!"); if(SVFUtil::isa(baseObjVar)) { - if(const SVFFunction* svffun = pag->getGNode(id)->getFunction()) + if(const CallGraphNode* svffun = pag->getGNode(id)->getFunction()) { - return callGraphSCC->isInCycle(getCallGraph()->getCallGraphNode(svffun)->getId()); + return callGraphSCC->isInCycle(svffun->getId()); } } return false; @@ -323,7 +323,7 @@ void PointerAnalysis::printIndCSTargets(const CallICFGNode* cs, const FunctionSe FunctionSet::const_iterator feit = targets.end(); for (; fit != feit; ++fit) { - const SVFFunction* callee = *fit; + const CallGraphNode* callee = *fit; outs() << "\n\t" << callee->getName(); } } @@ -394,8 +394,8 @@ void PointerAnalysis::resolveIndCalls(const CallICFGNode* cs, const PointsTo& ta if(obj->isFunction()) { - const SVFFunction* calleefun = SVFUtil::cast(obj)->getFunction(); - const SVFFunction* callee = calleefun->getDefFunForMultipleModule(); + const CallGraphNode* calleefun = SVFUtil::cast(obj)->getFunction(); + const CallGraphNode* callee = calleefun->getDefFunForMultipleModule(); if(SVFUtil::matchArgs(cs, callee) == false) continue; @@ -469,7 +469,7 @@ void PointerAnalysis::connectVCallToVFns(const CallICFGNode* cs, const VFunSet & for (VFunSet::const_iterator fit = vfns.begin(), feit = vfns.end(); fit != feit; ++fit) { - const SVFFunction* callee = *fit; + const CallGraphNode* callee = *fit; callee = callee->getDefFunForMultipleModule(); if (getIndCallMap()[cs].count(callee) > 0) continue; @@ -504,7 +504,7 @@ void PointerAnalysis::resolveCPPIndCalls(const CallICFGNode* cs, const PointsTo& void PointerAnalysis::validateSuccessTests(std::string fun) { // check for must alias cases, whether our alias analysis produce the correct results - if (const SVFFunction* checkFun = svfMod->getSVFFunction(fun)) + if (const CallGraphNode* checkFun = pag->getCallGraph()->getCallGraphNode(fun)) { if(!checkFun->isUncalledFunction()) outs() << "[" << this->PTAName() << "] Checking " << fun << "\n"; @@ -569,7 +569,7 @@ void PointerAnalysis::validateSuccessTests(std::string fun) void PointerAnalysis::validateExpectedFailureTests(std::string fun) { - if (const SVFFunction* checkFun = svfMod->getSVFFunction(fun)) + if (const CallGraphNode* checkFun = pag->getCallGraph()->getCallGraphNode(fun)) { if(!checkFun->isUncalledFunction()) outs() << "[" << this->PTAName() << "] Checking " << fun << "\n"; diff --git a/svf/lib/MemoryModel/PointerAnalysisImpl.cpp b/svf/lib/MemoryModel/PointerAnalysisImpl.cpp index 0bb93092ea..bef6cddc2c 100644 --- a/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +++ b/svf/lib/MemoryModel/PointerAnalysisImpl.cpp @@ -541,9 +541,9 @@ void BVDataPTAImpl::onTheFlyThreadCallGraphSolve(const CallSiteToFunPtrMap& call const BaseObjVar* obj = pag->getBaseObject(objPN->getId()); if(obj->isFunction()) { - const SVFFunction *svfForkedFun = SVFUtil::cast(obj)->getFunction(); - if(tdCallGraph->addIndirectForkEdge(*it, svfForkedFun)) - newForkEdges[*it].insert(svfForkedFun); + const CallGraphNode *cgn = SVFUtil::cast(obj)->getCallGraphNode(); + if(tdCallGraph->addIndirectForkEdge(*it, cgn)) + newForkEdges[*it].insert(cgn); } } } diff --git a/svf/lib/SABER/DoubleFreeChecker.cpp b/svf/lib/SABER/DoubleFreeChecker.cpp index f14a0d8f58..cb30a0e3fe 100644 --- a/svf/lib/SABER/DoubleFreeChecker.cpp +++ b/svf/lib/SABER/DoubleFreeChecker.cpp @@ -30,6 +30,7 @@ #include "SABER/DoubleFreeChecker.h" #include "Util/SVFUtil.h" #include "Util/Options.h" +#include "Graphs/CallGraph.h" using namespace SVF; using namespace SVFUtil; @@ -55,14 +56,14 @@ void DoubleFreeChecker::testsValidation(ProgSlice *slice) { const SVFGNode* source = slice->getSource(); const CallICFGNode* cs = getSrcCSID(source); - const SVFFunction* fun = cs->getCalledFunction(); + const CallGraphNode* fun = cs->getCalledFunction(); if(fun==nullptr) return; validateSuccessTests(slice,fun); validateExpectedFailureTests(slice,fun); } -void DoubleFreeChecker::validateSuccessTests(ProgSlice *slice, const SVFFunction *fun) +void DoubleFreeChecker::validateSuccessTests(ProgSlice *slice, const CallGraphNode *fun) { const SVFGNode* source = slice->getSource(); const CallICFGNode* cs = getSrcCSID(source); @@ -108,7 +109,7 @@ void DoubleFreeChecker::validateSuccessTests(ProgSlice *slice, const SVFFunction } } -void DoubleFreeChecker::validateExpectedFailureTests(ProgSlice *slice, const SVFFunction *fun) +void DoubleFreeChecker::validateExpectedFailureTests(ProgSlice *slice, const CallGraphNode *fun) { const SVFGNode* source = slice->getSource(); const CallICFGNode* cs = getSrcCSID(source); diff --git a/svf/lib/SABER/LeakChecker.cpp b/svf/lib/SABER/LeakChecker.cpp index 7cfc96c679..1fcbad259f 100644 --- a/svf/lib/SABER/LeakChecker.cpp +++ b/svf/lib/SABER/LeakChecker.cpp @@ -29,6 +29,7 @@ #include "Util/Options.h" #include "SABER/LeakChecker.h" +#include "Graphs/CallGraph.h" using namespace SVF; using namespace SVFUtil; @@ -55,7 +56,7 @@ void LeakChecker::initSrcs() getCallgraph()->getCallees(cs->getCallICFGNode(),callees); for(PTACallGraph::FunctionSet::const_iterator cit = callees.begin(), ecit = callees.end(); cit!=ecit; cit++) { - const SVFFunction* fun = *cit; + const CallGraphNode* fun = *cit; if (isSourceLikeFun(fun)) { CSWorkList worklist; @@ -115,7 +116,7 @@ void LeakChecker::initSnks() getCallgraph()->getCallees(it->first,callees); for(PTACallGraph::FunctionSet::const_iterator cit = callees.begin(), ecit = callees.end(); cit!=ecit; cit++) { - const SVFFunction* fun = *cit; + const CallGraphNode* fun = *cit; if (isSinkLikeFun(fun)) { SVFIR::SVFVarList &arglist = it->second; @@ -179,7 +180,7 @@ void LeakChecker::testsValidation(const ProgSlice* slice) { const SVFGNode* source = slice->getSource(); const CallICFGNode* cs = getSrcCSID(source); - const SVFFunction* fun = cs->getCalledFunction(); + const CallGraphNode* fun = cs->getCalledFunction(); if(fun==nullptr) return; @@ -188,7 +189,7 @@ void LeakChecker::testsValidation(const ProgSlice* slice) } -void LeakChecker::validateSuccessTests(const SVFGNode* source, const SVFFunction* fun) +void LeakChecker::validateSuccessTests(const SVFGNode* source, const CallGraphNode* fun) { const CallICFGNode* cs = getSrcCSID(source); @@ -243,7 +244,7 @@ void LeakChecker::validateSuccessTests(const SVFGNode* source, const SVFFunction } } -void LeakChecker::validateExpectedFailureTests(const SVFGNode* source, const SVFFunction* fun) +void LeakChecker::validateExpectedFailureTests(const SVFGNode* source, const CallGraphNode* fun) { const CallICFGNode* cs = getSrcCSID(source); diff --git a/svf/lib/SABER/SaberCheckerAPI.cpp b/svf/lib/SABER/SaberCheckerAPI.cpp index 9baab29dc4..cb4c1a0315 100644 --- a/svf/lib/SABER/SaberCheckerAPI.cpp +++ b/svf/lib/SABER/SaberCheckerAPI.cpp @@ -28,6 +28,7 @@ */ #include "SABER/SaberCheckerAPI.h" #include +#include "Graphs/CallGraph.h" using namespace std; using namespace SVF; @@ -171,6 +172,17 @@ void SaberCheckerAPI::init() } } - +/// Get the function type of a function +SaberCheckerAPI::CHECKER_TYPE SaberCheckerAPI::getType( + const CallGraphNode* F) const +{ + if(F) + { + TDAPIMap::const_iterator it= tdAPIMap.find(F->getName()); + if(it != tdAPIMap.end()) + return it->second; + } + return CK_DUMMY; +} diff --git a/svf/lib/SABER/SaberCondAllocator.cpp b/svf/lib/SABER/SaberCondAllocator.cpp index 6a36a74ee2..0806dc52ca 100644 --- a/svf/lib/SABER/SaberCondAllocator.cpp +++ b/svf/lib/SABER/SaberCondAllocator.cpp @@ -63,11 +63,11 @@ void SaberCondAllocator::allocate(const SVFModule *M) CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); for (const auto& item: *svfirCallGraph) { - const SVFFunction *func = (item.second)->getFunction(); + const CallGraphNode *func = item.second; if (!SVFUtil::isExtCall(func)) { // Allocate conditions for a program. - for (SVFFunction::const_iterator bit = func->begin(), ebit = func->end(); + for (CallGraphNode::const_bb_iterator bit = func->begin(), ebit = func->end(); bit != ebit; ++bit) { const SVFBasicBlock* bb = bit->second; @@ -265,7 +265,7 @@ SaberCondAllocator::Condition SaberCondAllocator::evaluateProgExit(const BranchS */ SaberCondAllocator::Condition SaberCondAllocator::evaluateLoopExitBranch(const SVFBasicBlock* bb, const SVFBasicBlock* dst) { - const SVFFunction* svffun = bb->getParent(); + const CallGraphNode* svffun = bb->getParent(); assert(svffun == dst->getParent() && "two basic blocks should be in the same function"); if (svffun->isLoopHeader(bb)) @@ -436,7 +436,7 @@ void SaberCondAllocator::collectBBCallingProgExit(const SVFBasicBlock &bb) if (const CallICFGNode* cs = SVFUtil::dyn_cast(icfgNode)) if (SVFUtil::isProgExitCall(cs)) { - const SVFFunction* svfun = bb.getParent(); + const CallGraphNode* svfun = bb.getParent(); funToExitBBsMap[svfun].insert(&bb); } } @@ -447,7 +447,7 @@ void SaberCondAllocator::collectBBCallingProgExit(const SVFBasicBlock &bb) */ bool SaberCondAllocator::isBBCallsProgExit(const SVFBasicBlock* bb) { - const SVFFunction* svfun = bb->getParent(); + const CallGraphNode* svfun = bb->getParent(); FunToExitBBsMap::const_iterator it = funToExitBBsMap.find(svfun); if (it != funToExitBBsMap.end()) { @@ -506,7 +506,7 @@ SaberCondAllocator::ComputeInterCallVFGGuard(const SVFBasicBlock* srcBB, const S SaberCondAllocator::Condition SaberCondAllocator::ComputeInterRetVFGGuard(const SVFBasicBlock* srcBB, const SVFBasicBlock* dstBB, const SVFBasicBlock* retBB) { - const SVFFunction* parent = srcBB->getParent(); + const CallGraphNode* parent = srcBB->getParent(); const SVFBasicBlock* funExitBB = parent->getExitBB(); Condition c1 = ComputeIntraVFGGuard(srcBB, funExitBB); diff --git a/svf/lib/SABER/SaberSVFGBuilder.cpp b/svf/lib/SABER/SaberSVFGBuilder.cpp index 1b7bec223f..318f5214bf 100644 --- a/svf/lib/SABER/SaberSVFGBuilder.cpp +++ b/svf/lib/SABER/SaberSVFGBuilder.cpp @@ -303,7 +303,7 @@ void SaberSVFGBuilder::AddExtActualParmSVFGNodes(PTACallGraph* callgraph) ecit = callees.end(); cit != ecit; cit++) { - const SVFFunction* fun = *cit; + const CallGraphNode* fun = *cit; if (SaberCheckerAPI::getCheckerAPI()->isMemDealloc(fun) || SaberCheckerAPI::getCheckerAPI()->isFClose(fun)) { diff --git a/svf/lib/SVFIR/SVFModule.cpp b/svf/lib/SVFIR/SVFModule.cpp index 3fcd0a5739..b8168fdac9 100644 --- a/svf/lib/SVFIR/SVFModule.cpp +++ b/svf/lib/SVFIR/SVFModule.cpp @@ -34,8 +34,6 @@ SVFModule* SVFModule::svfModule = nullptr; SVFModule::~SVFModule() { - for (const SVFFunction* f : FunctionSet) - delete f; for (const SVFConstant* c : ConstantSet) delete c; for (const SVFValue* o : OtherValueSet) @@ -45,9 +43,9 @@ SVFModule::~SVFModule() ExtAPI::destory(); } -const SVFFunction* SVFModule::getSVFFunction(const std::string& name) +const CallGraphNode* SVFModule::getSVFFunction(const std::string& name) { - for (const SVFFunction* fun : getFunctionSet()) + for (const CallGraphNode* fun : getFunctionSet()) { if (fun->getName() == name) { diff --git a/svf/lib/SVFIR/SVFVariables.cpp b/svf/lib/SVFIR/SVFVariables.cpp index 219e771b66..e0ff784974 100644 --- a/svf/lib/SVFIR/SVFVariables.cpp +++ b/svf/lib/SVFIR/SVFVariables.cpp @@ -44,6 +44,19 @@ SVFVar::SVFVar(NodeID i, const SVFType* svfType, PNODEK k) : { } +/// Check if this pointer is in an uncalled function +bool SVFVar::ptrInUncalledFunction() const +{ + if (const CallGraphNode* fun = getFunction()) + { + return fun->isUncalledFunction(); + } + else + { + return false; + } +} + bool SVFVar::isIsolatedNode() const { if (getInEdges().empty() && getOutEdges().empty()) @@ -68,7 +81,7 @@ void SVFVar::dump() const outs() << this->toString() << "\n"; } -const SVFFunction* ValVar::getFunction() const +const CallGraphNode* ValVar::getFunction() const { if(icfgNode) return icfgNode->getFun(); @@ -109,19 +122,24 @@ ArgValVar::ArgValVar(NodeID i, u32_t argNo, const ICFGNode* icn, } -const SVFFunction* ArgValVar::getFunction() const +const CallGraphNode* ArgValVar::getFunction() const { return getParent(); } -const SVFFunction* ArgValVar::getParent() const +const CallGraphNode* ArgValVar::getParent() const +{ + return cgNode; +} + +bool ArgValVar::isArgOfUncalledFunction() const { - return cgNode->getFunction(); + return getFunction()->isUncalledFunction(); } bool ArgValVar::isPointer() const { - return cgNode->getFunction()->getArg(argNo)->getType()->isPointerTy(); + return cgNode->getArg(argNo)->getType()->isPointerTy(); } const std::string ArgValVar::toString() const @@ -162,9 +180,9 @@ RetValPN::RetValPN(NodeID i, const CallGraphNode* node, const SVFType* svfType, { } -const SVFFunction* RetValPN::getFunction() const +const CallGraphNode* RetValPN::getFunction() const { - return callGraphNode->getFunction(); + return callGraphNode; } bool RetValPN::isPointer() const @@ -202,7 +220,7 @@ bool BaseObjVar::isBlackHoleObj() const } -const SVFFunction* BaseObjVar::getFunction() const +const CallGraphNode* BaseObjVar::getFunction() const { if(icfgNode) return icfgNode->getFun(); @@ -433,12 +451,12 @@ bool FunObjVar::isPointer() const bool FunObjVar::isIsolatedNode() const { - return callGraphNode->getFunction()->isIntrinsic(); + return callGraphNode->isIntrinsic(); } -const SVFFunction* FunObjVar::getFunction() const +const CallGraphNode* FunObjVar::getFunction() const { - return callGraphNode->getFunction(); + return callGraphNode; } const std::string FunObjVar::toString() const @@ -462,9 +480,9 @@ const std::string RetValPN::toString() const return rawstr.str(); } -const SVFFunction* VarArgValPN::getFunction() const +const CallGraphNode* VarArgValPN::getFunction() const { - return callGraphNode->getFunction(); + return callGraphNode; } const std::string VarArgValPN::getValueName() const diff --git a/svf/lib/Util/CDGBuilder.cpp b/svf/lib/Util/CDGBuilder.cpp index 96c5b78b62..acbe0685ce 100644 --- a/svf/lib/Util/CDGBuilder.cpp +++ b/svf/lib/Util/CDGBuilder.cpp @@ -67,7 +67,7 @@ CDGBuilder::extractNodesBetweenPdomNodes(const SVFBasicBlock *succ, const SVFBas { if (succ == LCA) return; std::vector path; - SVFLoopAndDomInfo *ld = const_cast(LCA->getFunction())->getLoopAndDomInfo(); + SVFLoopAndDomInfo *ld = const_cast(LCA->getFunction())->getLoopAndDomInfo(); dfsNodesBetweenPdomNodes(LCA, succ, path, tgtNodes, ld); } @@ -126,11 +126,11 @@ void CDGBuilder::buildControlDependence(const SVFModule *svfgModule) CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); for (const auto& item: *svfirCallGraph) { - const SVFFunction *svfFun = (item.second)->getFunction(); - if (SVFUtil::isExtCall(svfFun)) continue; + CallGraphNode* cgn = item.second; + if (SVFUtil::isExtCall(cgn)) continue; // extract basic block edges to be processed Map> BBS; - extractBBS(svfFun, BBS); + extractBBS(cgn, BBS); for (const auto &item: BBS) { @@ -138,8 +138,7 @@ void CDGBuilder::buildControlDependence(const SVFModule *svfgModule) // for each bb pair for (const SVFBasicBlock *succ: item.second) { - const SVFBasicBlock *SVFLCA = const_cast(svfFun)-> - getLoopAndDomInfo()->findNearestCommonPDominator(pred, succ); + const SVFBasicBlock *SVFLCA = cgn->getLoopAndDomInfo()->findNearestCommonPDominator(pred, succ); std::vector tgtNodes; // no common ancestor, may be exit() if (SVFLCA == NULL) @@ -168,7 +167,7 @@ void CDGBuilder::buildControlDependence(const SVFModule *svfgModule) * @param func * @param res */ -void CDGBuilder::extractBBS(const SVF::SVFFunction *func, +void CDGBuilder::extractBBS(const SVF::CallGraphNode *func, Map> &res) { for (const auto &it: *func) diff --git a/svf/lib/Util/CallGraphBuilder.cpp b/svf/lib/Util/CallGraphBuilder.cpp index 5bda6882b8..9573c6a5ea 100644 --- a/svf/lib/Util/CallGraphBuilder.cpp +++ b/svf/lib/Util/CallGraphBuilder.cpp @@ -38,17 +38,15 @@ using namespace SVF; using namespace SVFUtil; -CallGraph* CallGraphBuilder::buildSVFIRCallGraph(SVFModule* svfModule) +CallGraph* CallGraphBuilder::createSVFIRCallGraph() { - CallGraph* callgraph = new CallGraph(); - for (const SVFFunction* svfFunc: svfModule->getFunctionSet()) - { - callgraph->addCallGraphNode(svfFunc); - } + return new CallGraph(); +} +void CallGraphBuilder::addSVFIRCallGraphEdges(SVF::CallGraph* callgraph){ for (const auto& item : *callgraph) { - for (auto it : *(item.second)->getFunction()) + for (auto it : *(item.second)) { const SVFBasicBlock* svfbb = it.second; for (const ICFGNode* inst : svfbb->getICFGNodeList()) @@ -56,17 +54,18 @@ CallGraph* CallGraphBuilder::buildSVFIRCallGraph(SVFModule* svfModule) if (SVFUtil::isNonInstricCallSite(inst)) { const CallICFGNode* callBlockNode = cast(inst); - if(const SVFFunction* callee = callBlockNode->getCalledFunction()) + if(const CallGraphNode* callee = callBlockNode->getCalledFunction()) { - callgraph->addDirectCallGraphEdge(callBlockNode,(item.second)->getFunction(),callee); + callgraph->addDirectCallGraphEdge(callBlockNode,item.second, + const_cast(callee)); } } } } } - return callgraph; } + PTACallGraph* CallGraphBuilder::buildPTACallGraph() { CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); @@ -81,7 +80,7 @@ ThreadCallGraph* CallGraphBuilder::buildThreadCallGraph() ThreadAPI* tdAPI = ThreadAPI::getThreadAPI(); for (const auto& item: *svfirCallGraph) { - for (auto it : *(item.second)->getFunction()) + for (auto it : *(item.second)) { const SVFBasicBlock* svfbb = it.second; for (const ICFGNode* inst : svfbb->getICFGNodeList()) @@ -107,7 +106,7 @@ ThreadCallGraph* CallGraphBuilder::buildThreadCallGraph() // record join sites for (const auto& item: *svfirCallGraph) { - for (auto it : *(item.second)->getFunction()) + for (auto it : *(item.second)) { const SVFBasicBlock* svfbb = it.second; for (const ICFGNode* node : svfbb->getICFGNodeList()) diff --git a/svf/lib/Util/ExtAPI.cpp b/svf/lib/Util/ExtAPI.cpp index 8bd009372c..8679377aeb 100644 --- a/svf/lib/Util/ExtAPI.cpp +++ b/svf/lib/Util/ExtAPI.cpp @@ -161,15 +161,15 @@ std::string ExtAPI::getExtBcPath() abort(); } -void ExtAPI::setExtFuncAnnotations(const SVFFunction* fun, const std::vector& funcAnnotations) +void ExtAPI::setExtFuncAnnotations(const CallGraphNode* fun, const std::vector& funcAnnotations) { - assert(fun && "Null SVFFunction* pointer"); + assert(fun && "Null CallGraphNode* pointer"); func2Annotations[fun] = funcAnnotations; } -bool ExtAPI::hasExtFuncAnnotation(const SVFFunction* fun, const std::string& funcAnnotation) +bool ExtAPI::hasExtFuncAnnotation(const CallGraphNode* fun, const std::string& funcAnnotation) { - assert(fun && "Null SVFFunction* pointer"); + assert(fun && "Null CallGraphNode* pointer"); auto it = func2Annotations.find(fun); if (it != func2Annotations.end()) { @@ -180,9 +180,9 @@ bool ExtAPI::hasExtFuncAnnotation(const SVFFunction* fun, const std::string& fun return false; } -std::string ExtAPI::getExtFuncAnnotation(const SVFFunction* fun, const std::string& funcAnnotation) +std::string ExtAPI::getExtFuncAnnotation(const CallGraphNode* fun, const std::string& funcAnnotation) { - assert(fun && "Null SVFFunction* pointer"); + assert(fun && "Null CallGraphNode* pointer"); auto it = func2Annotations.find(fun); if (it != func2Annotations.end()) { @@ -193,45 +193,45 @@ std::string ExtAPI::getExtFuncAnnotation(const SVFFunction* fun, const std::stri return ""; } -const std::vector& ExtAPI::getExtFuncAnnotations(const SVFFunction* fun) +const std::vector& ExtAPI::getExtFuncAnnotations(const CallGraphNode* fun) { - assert(fun && "Null SVFFunction* pointer"); + assert(fun && "Null CallGraphNode* pointer"); auto it = func2Annotations.find(fun); if (it != func2Annotations.end()) return it->second; return func2Annotations[fun]; } -bool ExtAPI::is_memcpy(const SVFFunction *F) +bool ExtAPI::is_memcpy(const CallGraphNode *F) { return F && (hasExtFuncAnnotation(F, "MEMCPY") || hasExtFuncAnnotation(F, "STRCPY") || hasExtFuncAnnotation(F, "STRCAT")); } -bool ExtAPI::is_memset(const SVFFunction *F) +bool ExtAPI::is_memset(const CallGraphNode *F) { return F && hasExtFuncAnnotation(F, "MEMSET"); } -bool ExtAPI::is_alloc(const SVFFunction* F) +bool ExtAPI::is_alloc(const CallGraphNode* F) { return F && hasExtFuncAnnotation(F, "ALLOC_HEAP_RET"); } // Does (F) allocate a new object and assign it to one of its arguments? -bool ExtAPI::is_arg_alloc(const SVFFunction* F) +bool ExtAPI::is_arg_alloc(const CallGraphNode* F) { return F && hasExtFuncAnnotation(F, "ALLOC_HEAP_ARG"); } -bool ExtAPI::is_alloc_stack_ret(const SVFFunction* F) +bool ExtAPI::is_alloc_stack_ret(const CallGraphNode* F) { return F && hasExtFuncAnnotation(F, "ALLOC_STACK_RET"); } // Get the position of argument which holds the new object -s32_t ExtAPI::get_alloc_arg_pos(const SVFFunction* F) +s32_t ExtAPI::get_alloc_arg_pos(const CallGraphNode* F) { std::string allocArg = getExtFuncAnnotation(F, "ALLOC_HEAP_ARG"); assert(!allocArg.empty() && "Not an alloc call via argument or incorrect extern function annotation!"); @@ -247,7 +247,7 @@ s32_t ExtAPI::get_alloc_arg_pos(const SVFFunction* F) } // Does (F) reallocate a new object? -bool ExtAPI::is_realloc(const SVFFunction* F) +bool ExtAPI::is_realloc(const CallGraphNode* F) { return F && hasExtFuncAnnotation(F, "REALLOC_HEAP_RET"); } @@ -255,9 +255,9 @@ bool ExtAPI::is_realloc(const SVFFunction* F) // Should (F) be considered "external" (either not defined in the program // or a user-defined version of a known alloc or no-op)? -bool ExtAPI::is_ext(const SVFFunction* F) +bool ExtAPI::is_ext(const CallGraphNode* F) { - assert(F && "Null SVFFunction* pointer"); + assert(F && "Null CallGraphNode* pointer"); if (F->isDeclaration() || F->isIntrinsic()) return true; else if (hasExtFuncAnnotation(F, "OVERWRITE") && getExtFuncAnnotations(F).size() == 1) diff --git a/svf/lib/Util/SVFBugReport.cpp b/svf/lib/Util/SVFBugReport.cpp index af6be8bb8e..180a2c12ed 100644 --- a/svf/lib/Util/SVFBugReport.cpp +++ b/svf/lib/Util/SVFBugReport.cpp @@ -31,6 +31,7 @@ #include "Util/SVFUtil.h" #include #include +#include "Graphs/CallGraph.h" using namespace std; using namespace SVF; @@ -304,7 +305,7 @@ const std::string SVFBugEvent::getEventDescription() const { std::string description("calls "); assert(SVFUtil::isa(eventInst) && "not a call ICFGNode?"); - const SVFFunction *callee = SVFUtil::cast(eventInst)->getCalledFunction(); + const CallGraphNode *callee = SVFUtil::cast(eventInst)->getCalledFunction(); if(callee == nullptr) { description += ""; diff --git a/svf/lib/Util/SVFStat.cpp b/svf/lib/Util/SVFStat.cpp index cc9aa3d128..dd6e2e071c 100644 --- a/svf/lib/Util/SVFStat.cpp +++ b/svf/lib/Util/SVFStat.cpp @@ -226,8 +226,8 @@ void SVFStat::branchStat() CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); for (const auto& item: *svfirCallGraph) { - const SVFFunction* func = item.second->getFunction(); - for (SVFFunction::const_iterator bbIt = func->begin(), bbEit = func->end(); + const CallGraphNode* func = item.second; + for (CallGraphNode::const_bb_iterator bbIt = func->begin(), bbEit = func->end(); bbIt != bbEit; ++bbIt) { const SVFBasicBlock* bb = bbIt->second; diff --git a/svf/lib/Util/SVFUtil.cpp b/svf/lib/Util/SVFUtil.cpp index 76d6c2ade8..007efc46b2 100644 --- a/svf/lib/Util/SVFUtil.cpp +++ b/svf/lib/Util/SVFUtil.cpp @@ -304,7 +304,7 @@ void SVFUtil::stopAnalysisLimitTimer(bool limitTimerSet) /// unless the callee is a variadic function (the first parameter of variadic function is its parameter number) /// e.g., void variadicFoo(int num, ...); variadicFoo(5, 1,2,3,4,5) /// for variadic function, callsite arg size must be greater than or equal to callee arg size -bool SVFUtil::matchArgs(const CallICFGNode* call, const SVFFunction* callee) +bool SVFUtil::matchArgs(const CallICFGNode* call, const CallGraphNode* callee) { if (callee->isVarArg() || ThreadAPI::getThreadAPI()->isTDFork(call)) return call->arg_size() >= callee->arg_size(); @@ -321,7 +321,7 @@ bool SVFUtil::isIntrinsicInst(const ICFGNode* inst) { if (const CallICFGNode* call = SVFUtil::dyn_cast(inst)) { - const SVFFunction* func = call->getCalledFunction(); + const CallGraphNode* func = call->getCalledFunction(); if (func && func->isIntrinsic()) { return true; @@ -337,7 +337,10 @@ bool SVFUtil::isExtCall(const CallICFGNode* cs) bool SVFUtil::isHeapAllocExtCallViaArg(const CallICFGNode* cs) { - return isHeapAllocExtFunViaArg(cs->getCalledFunction()); + if (cs->getCalledFunction()) + return isHeapAllocExtFunViaArg(cs->getCalledFunction()); + else + return false; } @@ -362,7 +365,8 @@ bool SVFUtil::isHeapAllocExtCall(const ICFGNode* cs) bool SVFUtil::isHeapAllocExtCallViaRet(const CallICFGNode* cs) { bool isPtrTy = cs->getType()->isPointerTy(); - return isPtrTy && isHeapAllocExtFunViaRet(cs->getCalledFunction()); + const CallGraphNode* fun = cs->getCalledFunction(); + return fun && isPtrTy && isHeapAllocExtFunViaRet(fun); } bool SVFUtil::isReallocExtCall(const CallICFGNode* cs) @@ -385,28 +389,34 @@ bool SVFUtil::isProgExitCall(const CallICFGNode* cs) return isProgExitFunction(cs->getCalledFunction()); } +/// Return true if this is a program entry function (e.g. main) +bool SVFUtil::isProgEntryFunction(const CallGraphNode* fun) +{ + return fun && fun->getName() == "main"; +} + /// Get program entry function from module. -const SVFFunction* SVFUtil::getProgFunction(const std::string& funName) +const CallGraphNode* SVFUtil::getProgFunction(const std::string& funName) { CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); for (const auto& item: *svfirCallGraph) { const CallGraphNode*fun = item.second; if (fun->getName()==funName) - return fun->getFunction(); + return fun; } return nullptr; } /// Get program entry function from module. -const SVFFunction* SVFUtil::getProgEntryFunction() +const CallGraphNode* SVFUtil::getProgEntryFunction() { CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); for (const auto& item: *svfirCallGraph) { const CallGraphNode*fun = item.second; - if (isProgEntryFunction(fun->getFunction())) - return (fun->getFunction()); + if (isProgEntryFunction(fun)) + return fun; } return nullptr; } @@ -425,3 +435,15 @@ const ObjVar* SVFUtil::getObjVarOfValVar(const SVF::ValVar* valVar) assert(valVar->getInEdges().size() == 1); return SVFUtil::dyn_cast((*valVar->getInEdges().begin())->getSrcNode()); } + +bool SVFUtil::isExtCall(const CallGraphNode* fun) +{ + return fun && ExtAPI::getExtAPI()->is_ext(fun); +} + +bool SVFUtil::isProgExitFunction (const CallGraphNode * fun) +{ + return fun && (fun->getName() == "exit" || + fun->getName() == "__assert_rtn" || + fun->getName() == "__assert_fail" ); +} \ No newline at end of file diff --git a/svf/lib/Util/ThreadAPI.cpp b/svf/lib/Util/ThreadAPI.cpp index a1fcae3c93..660ca0db23 100644 --- a/svf/lib/Util/ThreadAPI.cpp +++ b/svf/lib/Util/ThreadAPI.cpp @@ -130,6 +130,18 @@ void ThreadAPI::init() } } +/// Get the function type if it is a threadAPI function +ThreadAPI::TD_TYPE ThreadAPI::getType(const CallGraphNode* F) const +{ + if(F) + { + TDAPIMap::const_iterator it= tdAPIMap.find(F->getName()); + if(it != tdAPIMap.end()) + return it->second; + } + return TD_DUMMY; +} + bool ThreadAPI::isTDFork(const CallICFGNode *inst) const { return getType(inst->getCalledFunction()) == TD_FORK; @@ -181,10 +193,10 @@ const ValVar* ThreadAPI::getActualParmAtForkSite(const CallICFGNode *inst) const return inst->getArgument(3); } -const SVFVar* ThreadAPI::getFormalParmOfForkedFun(const SVFFunction* F) const +const SVFVar* ThreadAPI::getFormalParmOfForkedFun(const CallGraphNode* cgNode) const { - assert(PAG::getPAG()->hasFunArgsList(F) && "forked function has no args list!"); - const SVFIR::SVFVarList& funArgList = PAG::getPAG()->getFunArgsList(F); + assert(PAG::getPAG()->hasFunArgsList(cgNode) && "forked function has no args list!"); + const SVFIR::SVFVarList& funArgList = PAG::getPAG()->getFunArgsList(cgNode); // in pthread, forked functions are of type void *()(void *args) assert(funArgList.size() == 1 && "num of pthread forked function args is not 1!"); return funArgList[0]; @@ -273,7 +285,7 @@ void ThreadAPI::performAPIStat(SVFModule* module) CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); for (const auto& item: *svfirCallGraph) { - for (SVFFunction::const_iterator bit = (item.second)->getFunction()->begin(), ebit = (item.second)->getFunction()->end(); bit != ebit; ++bit) + for (CallGraphNode::const_bb_iterator bit = (item.second)->begin(), ebit = (item.second)->end(); bit != ebit; ++bit) { const SVFBasicBlock* bb = bit->second; for (const auto& svfInst: bb->getICFGNodeList()) @@ -281,7 +293,7 @@ void ThreadAPI::performAPIStat(SVFModule* module) if (!SVFUtil::isCallSite(svfInst)) continue; - const SVFFunction* fun = SVFUtil::cast(svfInst)->getCalledFunction(); + const CallGraphNode* fun = SVFUtil::cast(svfInst)->getCalledFunction(); TD_TYPE type = getType(fun); switch (type) { diff --git a/svf/lib/WPA/Andersen.cpp b/svf/lib/WPA/Andersen.cpp index e001178de1..71619e5401 100644 --- a/svf/lib/WPA/Andersen.cpp +++ b/svf/lib/WPA/Andersen.cpp @@ -33,6 +33,7 @@ #include "MemoryModel/PointsTo.h" #include "WPA/Andersen.h" #include "WPA/Steensgaard.h" +#include "Graphs/CallGraph.h" using namespace SVF; using namespace SVFUtil; @@ -241,19 +242,19 @@ bool AndersenBase::updateThreadCallGraph(const CallSiteToFunPtrMap& callsites, /*! * Connect formal and actual parameters for indirect forksites */ -void AndersenBase::connectCaller2ForkedFunParams(const CallICFGNode* cs, const SVFFunction* F, +void AndersenBase::connectCaller2ForkedFunParams(const CallICFGNode* cs, const CallGraphNode* cgNode, NodePairSet& cpySrcNodes) { - assert(F); + assert(cgNode); DBOUT(DAndersen, outs() << "connect parameters from indirect forksite " << cs->valueOnlyToString() << " to forked function " - << *F << "\n"); + << *cgNode << "\n"); ThreadCallGraph *tdCallGraph = SVFUtil::dyn_cast(callgraph); const PAGNode *cs_arg = tdCallGraph->getThreadAPI()->getActualParmAtForkSite(cs); - const PAGNode *fun_arg = tdCallGraph->getThreadAPI()->getFormalParmOfForkedFun(F); + const PAGNode *fun_arg = tdCallGraph->getThreadAPI()->getFormalParmOfForkedFun(cgNode); if(cs_arg->isPointer() && fun_arg->isPointer()) { @@ -272,7 +273,7 @@ void AndersenBase::connectCaller2ForkedFunParams(const CallICFGNode* cs, const S // * Connect formal and actual parameters for indirect callsites // */ void AndersenBase::connectCaller2CalleeParams(const CallICFGNode* cs, - const SVFFunction* F, NodePairSet &cpySrcNodes) + const CallGraphNode* F, NodePairSet &cpySrcNodes) { assert(F); diff --git a/svf/lib/WPA/FlowSensitive.cpp b/svf/lib/WPA/FlowSensitive.cpp index c15b85631a..255749268f 100644 --- a/svf/lib/WPA/FlowSensitive.cpp +++ b/svf/lib/WPA/FlowSensitive.cpp @@ -713,7 +713,7 @@ bool FlowSensitive::updateCallGraph(const CallSiteToFunPtrMap& callsites) for (FunctionSet::iterator potentialFunctionIt = potentialFunctionSet.begin(); potentialFunctionIt != potentialFunctionSet.end(); ) { - const SVFFunction *potentialFunction = *potentialFunctionIt; + const CallGraphNode *potentialFunction = *potentialFunctionIt; if (andersFunctionSet.find(potentialFunction) == andersFunctionSet.end()) { // potentialFunction is not in the Andersen's call graph -- remove it. @@ -750,7 +750,7 @@ void FlowSensitive::connectCallerAndCallee(const CallEdgeMap& newEdges, SVFGEdge const FunctionSet & functions = iter->second; for (FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++) { - const SVFFunction* func = *func_iter; + const CallGraphNode* func = *func_iter; svfg->connectCallerAndCallee(cs, func, edges); } } diff --git a/svf/lib/WPA/TypeAnalysis.cpp b/svf/lib/WPA/TypeAnalysis.cpp index 8da85d4241..d2a1500c1b 100644 --- a/svf/lib/WPA/TypeAnalysis.cpp +++ b/svf/lib/WPA/TypeAnalysis.cpp @@ -127,7 +127,7 @@ void TypeAnalysis::dumpCHAStats() vfunc_total = 0, vtbl_max = 0, pure_abstract = 0; - set allVirtualFunctions; + set allVirtualFunctions; for (CHGraph::const_iterator it = chgraph->begin(), eit = chgraph->end(); it != eit; ++it) { @@ -141,10 +141,10 @@ void TypeAnalysis::dumpCHAStats() veit = vecs.end(); vit != veit; ++vit) { vfuncs_size += (*vit).size(); - for (vector::const_iterator fit = (*vit).begin(), + for (vector::const_iterator fit = (*vit).begin(), feit = (*vit).end(); fit != feit; ++fit) { - const SVFFunction* func = *fit; + const CallGraphNode* func = *fit; allVirtualFunctions.insert(func); } } diff --git a/svf/lib/WPA/VersionedFlowSensitive.cpp b/svf/lib/WPA/VersionedFlowSensitive.cpp index 551bf000a2..cbd8608571 100644 --- a/svf/lib/WPA/VersionedFlowSensitive.cpp +++ b/svf/lib/WPA/VersionedFlowSensitive.cpp @@ -481,7 +481,7 @@ void VersionedFlowSensitive::buildDeltaMaps(void) // * Callsite returns: can get new incoming indirect edges if the callsite is indirect. // * Otherwise: static. bool isDelta = false; - if (const SVFFunction *fn = svfg->isFunEntrySVFGNode(s)) + if (const CallGraphNode *fn = svfg->isFunEntrySVFGNode(s)) { PTACallGraphEdge::CallInstSet callsites; /// use pre-analysis call graph to approximate all potential callsites diff --git a/svf/lib/WPA/WPAPass.cpp b/svf/lib/WPA/WPAPass.cpp index 4f3fac8d06..8f3f8078ec 100644 --- a/svf/lib/WPA/WPAPass.cpp +++ b/svf/lib/WPA/WPAPass.cpp @@ -142,8 +142,8 @@ void WPAPass::PrintAliasPairs(PointerAnalysis* pta) node2 = rit->second; if(node1==node2) continue; - const SVFFunction* fun1 = node1->getFunction(); - const SVFFunction* fun2 = node2->getFunction(); + const CallGraphNode* fun1 = node1->getFunction(); + const CallGraphNode* fun2 = node2->getFunction(); AliasResult result = pta->alias(node1->getId(), node2->getId()); SVFUtil::outs() << (result == AliasResult::NoAlias ? "NoAlias" : "MayAlias") << " var" << node1->getId() << "[" << node1->getName()