diff --git a/svf-llvm/include/SVF-LLVM/LLVMModule.h b/svf-llvm/include/SVF-LLVM/LLVMModule.h index 3d9bf0f52..7b5a81e38 100644 --- a/svf-llvm/include/SVF-LLVM/LLVMModule.h +++ b/svf-llvm/include/SVF-LLVM/LLVMModule.h @@ -105,6 +105,7 @@ class LLVMModuleSet InstToBlockNodeMapTy InstToBlockNodeMap; ///< map a basic block to its ICFGNode FunToFunEntryNodeMapTy FunToFunEntryNodeMap; ///< map a function to its FunExitICFGNode FunToFunExitNodeMapTy FunToFunExitNodeMap; ///< map a function to its FunEntryICFGNode + CallGraph* callgraph; /// Constructor LLVMModuleSet(); diff --git a/svf-llvm/lib/LLVMModule.cpp b/svf-llvm/lib/LLVMModule.cpp index d520dc514..a2ac9076d 100644 --- a/svf-llvm/lib/LLVMModule.cpp +++ b/svf-llvm/lib/LLVMModule.cpp @@ -41,6 +41,8 @@ #include "SVF-LLVM/ObjTypeInference.h" #include "llvm/Transforms/Utils/Cloning.h" #include "SVF-LLVM/ICFGBuilder.h" +#include "Graphs/CallGraph.h" +#include "Util/CallGraphBuilder.h" using namespace std; using namespace SVF; @@ -169,6 +171,9 @@ void LLVMModuleSet::build() initSVFFunction(); ICFGBuilder icfgbuilder; icfg = icfgbuilder.build(); + + CallGraphBuilder callGraphBuilder; + callgraph = callGraphBuilder.buildSVFIRCallGraph(svfModule); } void LLVMModuleSet::createSVFDataStructure() diff --git a/svf-llvm/lib/SVFIRBuilder.cpp b/svf-llvm/lib/SVFIRBuilder.cpp index 66221980f..7c5e1b544 100644 --- a/svf-llvm/lib/SVFIRBuilder.cpp +++ b/svf-llvm/lib/SVFIRBuilder.cpp @@ -38,6 +38,7 @@ #include "SVFIR/SVFFileSystem.h" #include "SVFIR/SVFModule.h" #include "SVFIR/SVFValue.h" +#include "Util/CallGraphBuilder.h" #include "Util/Options.h" #include "Util/SVFUtil.h" @@ -62,6 +63,9 @@ SVFIR* SVFIRBuilder::build() // Build ICFG pag->setICFG(llvmModuleSet()->getICFG()); + // Set callgraph + pag->setCallGraph(llvmModuleSet()->callgraph); + // Set icfgnode in memobj for (auto& it : SymbolTableInfo::SymbolInfo()->idToObjMap()) { diff --git a/svf/include/Graphs/CallGraph.h b/svf/include/Graphs/CallGraph.h index bbe2dd7cf..7b08b8e3f 100644 --- a/svf/include/Graphs/CallGraph.h +++ b/svf/include/Graphs/CallGraph.h @@ -189,6 +189,11 @@ class CallGraphNode : public GenericCallGraphNodeTy } + inline const std::string &getName() const + { + return fun->getName(); + } + /// Get function of this call node inline const SVFFunction* getFunction() const { @@ -254,8 +259,6 @@ class CallGraph : public GenericCallGraphTy }; private: - CGEK kind; - /// Indirect call map CallEdgeMap indirectCallMap; @@ -270,6 +273,7 @@ class CallGraph : public GenericCallGraphTy NodeID callGraphNodeNum; u32_t numOfResolvedIndCallEdge; + CGEK kind; /// Clean up memory void destroy(); @@ -278,7 +282,9 @@ class CallGraph : public GenericCallGraphTy /// Constructor CallGraph(CGEK k = NormCallGraph); - /// Add callgraph Node + /// Copy constructor + CallGraph(const CallGraph& other); + void addCallGraphNode(const SVFFunction* fun); /// Destructor diff --git a/svf/include/Graphs/ThreadCallGraph.h b/svf/include/Graphs/ThreadCallGraph.h index ace02fb44..8bc2578cf 100644 --- a/svf/include/Graphs/ThreadCallGraph.h +++ b/svf/include/Graphs/ThreadCallGraph.h @@ -172,7 +172,10 @@ class ThreadCallGraph: public CallGraph typedef Map CallInstToParForEdgesMap; /// Constructor - ThreadCallGraph(); + ThreadCallGraph(const CallGraph& cg); + + ThreadCallGraph(ThreadCallGraph& cg) = delete; + /// Destructor virtual ~ThreadCallGraph() { diff --git a/svf/include/SVFIR/SVFIR.h b/svf/include/SVFIR/SVFIR.h index 09e7de131..0cf19c22a 100644 --- a/svf/include/SVFIR/SVFIR.h +++ b/svf/include/SVFIR/SVFIR.h @@ -98,6 +98,7 @@ class SVFIR : public IRGraph ICFG* icfg; // ICFG CommonCHGraph* chgraph; // class hierarchy graph CallSiteSet callSiteSet; /// all the callsites of a program + CallGraph* callGraph; /// call graph static std::unique_ptr pag; ///< Singleton pattern here to enable instance of SVFIR can only be created once. @@ -182,6 +183,18 @@ class SVFIR : public IRGraph assert(chgraph && "empty ICFG! Build SVF IR first!"); return chgraph; } + + /// Set/Get CG + inline void setCallGraph(CallGraph* c) + { + callGraph = c; + } + inline CallGraph* getCallGraph() + { + assert(callGraph && "empty CallGraph! Build SVF IR first!"); + return callGraph; + } + /// Get/set methods to get SVFStmts based on their kinds and ICFGNodes //@{ /// Get edges set according to its kind diff --git a/svf/include/SVFIR/SVFModule.h b/svf/include/SVFIR/SVFModule.h index 60827032f..c4735cb19 100644 --- a/svf/include/SVFIR/SVFModule.h +++ b/svf/include/SVFIR/SVFModule.h @@ -130,23 +130,6 @@ class SVFModule /// Iterators ///@{ - iterator begin() - { - return FunctionSet.begin(); - } - const_iterator begin() const - { - return FunctionSet.begin(); - } - iterator end() - { - return FunctionSet.end(); - } - const_iterator end() const - { - return FunctionSet.end(); - } - global_iterator global_begin() { return GlobalSet.begin(); diff --git a/svf/include/Util/CallGraphBuilder.h b/svf/include/Util/CallGraphBuilder.h index 39afafd65..d2f20880b 100644 --- a/svf/include/Util/CallGraphBuilder.h +++ b/svf/include/Util/CallGraphBuilder.h @@ -38,34 +38,18 @@ namespace SVF { class ICFG; +class SVFModule; class CallGraphBuilder { - -protected: - CallGraph* callgraph; - ICFG* icfg; public: - CallGraphBuilder(CallGraph* cg, ICFG* i): callgraph(cg),icfg(i) - { - } - - /// Build normal callgraph - CallGraph* buildCallGraph(SVFModule* svfModule); - -}; + CallGraphBuilder()=default; -class ThreadCallGraphBuilder : public CallGraphBuilder -{ - -public: - ThreadCallGraphBuilder(ThreadCallGraph* cg, ICFG* i): CallGraphBuilder(cg,i) - { - } + /// Buidl SVFIR callgraoh + CallGraph* buildSVFIRCallGraph(SVFModule* svfModule); /// Build thread-aware callgraph - CallGraph* buildThreadCallGraph(SVFModule* svfModule); - + ThreadCallGraph* buildThreadCallGraph(); }; } // End namespace SVF diff --git a/svf/include/Util/SVFUtil.h b/svf/include/Util/SVFUtil.h index 4193d3038..a48387692 100644 --- a/svf/include/Util/SVFUtil.h +++ b/svf/include/Util/SVFUtil.h @@ -327,29 +327,11 @@ inline bool isProgEntryFunction(const SVFFunction* fun) return fun && fun->getName() == "main"; } -/// Get program entry function from module. -inline const SVFFunction* getProgFunction(SVFModule* svfModule, const std::string& funName) -{ - for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it) - { - const SVFFunction *fun = *it; - if (fun->getName()==funName) - return fun; - } - return nullptr; -} +/// Get program entry function from function name. +const SVFFunction* getProgFunction(const std::string& funName); -/// Get program entry function from module. -inline const SVFFunction* getProgEntryFunction(SVFModule* svfModule) -{ - for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it) - { - const SVFFunction *fun = *it; - if (isProgEntryFunction(fun)) - return (fun); - } - return nullptr; -} +/// Get program entry function. +const SVFFunction* getProgEntryFunction(); /// Return true if this is a program exit function call //@{ diff --git a/svf/lib/Graphs/CallGraph.cpp b/svf/lib/Graphs/CallGraph.cpp index 78dc39937..35c8d5d24 100644 --- a/svf/lib/Graphs/CallGraph.cpp +++ b/svf/lib/Graphs/CallGraph.cpp @@ -112,6 +112,38 @@ CallGraph::CallGraph(CGEK k): kind(k) numOfResolvedIndCallEdge = 0; } +/// Copy constructor +CallGraph::CallGraph(const CallGraph& other) { + callGraphNodeNum = other.callGraphNodeNum; + numOfResolvedIndCallEdge = 0; + kind = other.kind; + + /// copy call graph nodes + for (const auto& item : other) + { + const CallGraphNode* cgn = item.second; + CallGraphNode* callGraphNode = new CallGraphNode(cgn->getId(), cgn->getFunction()); + addGNode(cgn->getId(),callGraphNode); + funToCallGraphNodeMap[cgn->getFunction()] = callGraphNode; + } + + /// copy edges + for (const auto& item : other.callinstToCallGraphEdgesMap) + { + const CallICFGNode* cs = item.first; + for (const CallGraphEdge* edge : item.second) + { + CallGraphNode* src = getCallGraphNode(edge->getSrcID()); + CallGraphNode* dst = getCallGraphNode(edge->getDstID()); + CallGraphEdge* newEdge = new CallGraphEdge(src,dst,CallGraphEdge::CallRetEdge,edge->getCallSiteID()); + newEdge->addDirectCallSite(cs); + addEdge(newEdge); + callinstToCallGraphEdgesMap[cs].insert(newEdge); + } + } + +} + /*! * Memory has been cleaned up at GenericGraph */ @@ -122,12 +154,11 @@ void CallGraph::destroy() /*! * Add call graph node */ -void CallGraph::addCallGraphNode(const SVFFunction* fun) -{ - NodeID id = callGraphNodeNum; - CallGraphNode* callGraphNode = new CallGraphNode(id, fun); - addGNode(id,callGraphNode); - funToCallGraphNodeMap[fun] = callGraphNode; +void CallGraph::addCallGraphNode(const SVFFunction* fun) { + NodeID id = callGraphNodeNum; + CallGraphNode *callGraphNode = new CallGraphNode(id, fun); + addGNode(id, callGraphNode); + funToCallGraphNodeMap[callGraphNode->getFunction()] = callGraphNode; callGraphNodeNum++; } diff --git a/svf/lib/Graphs/SVFG.cpp b/svf/lib/Graphs/SVFG.cpp index b7189de2a..380cfa34d 100644 --- a/svf/lib/Graphs/SVFG.cpp +++ b/svf/lib/Graphs/SVFG.cpp @@ -427,9 +427,7 @@ void SVFG::connectIndirectSVFGEdges() */ void SVFG::connectFromGlobalToProgEntry() { - SVFModule* svfModule = mssa->getPTA()->getModule(); - const SVFFunction* mainFunc = - SVFUtil::getProgEntryFunction(svfModule); + const SVFFunction* mainFunc = SVFUtil::getProgEntryFunction(); FormalINSVFGNodeSet& formalIns = getFormalINSVFGNodes(mainFunc); if (formalIns.empty()) return; diff --git a/svf/lib/Graphs/ThreadCallGraph.cpp b/svf/lib/Graphs/ThreadCallGraph.cpp index 1a53def30..bb3528f77 100644 --- a/svf/lib/Graphs/ThreadCallGraph.cpp +++ b/svf/lib/Graphs/ThreadCallGraph.cpp @@ -39,9 +39,10 @@ using namespace SVFUtil; /*! * Constructor */ -ThreadCallGraph::ThreadCallGraph() : - CallGraph(ThdCallGraph), tdAPI(ThreadAPI::getThreadAPI()) +ThreadCallGraph::ThreadCallGraph(const CallGraph& cg) : + CallGraph(cg), tdAPI(ThreadAPI::getThreadAPI()) { + kind = ThdCallGraph; DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("Building ThreadCallGraph\n")); } diff --git a/svf/lib/MSSA/MemRegion.cpp b/svf/lib/MSSA/MemRegion.cpp index 57d7c4a79..14d65ae84 100644 --- a/svf/lib/MSSA/MemRegion.cpp +++ b/svf/lib/MSSA/MemRegion.cpp @@ -173,11 +173,10 @@ SVFIR::SVFStmtList& MRGenerator::getPAGEdgesFromInst(const ICFGNode* node) void MRGenerator::collectModRefForLoadStore() { - SVFModule* svfModule = pta->getModule(); - for (SVFModule::const_iterator fi = svfModule->begin(), efi = svfModule->end(); fi != efi; - ++fi) + CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); + for (const auto& item: *svfirCallGraph) { - const SVFFunction& fun = **fi; + const SVFFunction& fun = *item.second->getFunction(); /// if this function does not have any caller, then we do not care its MSSA if (Options::IgnoreDeadFun() && fun.isUncalledFunction()) diff --git a/svf/lib/MSSA/MemSSA.cpp b/svf/lib/MSSA/MemSSA.cpp index f5043be2e..d13477682 100644 --- a/svf/lib/MSSA/MemSSA.cpp +++ b/svf/lib/MSSA/MemSSA.cpp @@ -575,10 +575,10 @@ u32_t MemSSA::getBBPhiNum() const void MemSSA::dumpMSSA(OutStream& Out) { - for (SVFModule::iterator fit = pta->getModule()->begin(), efit = pta->getModule()->end(); - fit != efit; ++fit) + CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); + for (const auto& item: *svfirCallGraph) { - const SVFFunction* fun = *fit; + const SVFFunction* fun = item.second->getFunction(); if(Options::MSSAFun()!="" && Options::MSSAFun()!=fun->getName()) continue; diff --git a/svf/lib/MSSA/SVFGBuilder.cpp b/svf/lib/MSSA/SVFGBuilder.cpp index 33974d24a..43383c303 100644 --- a/svf/lib/MSSA/SVFGBuilder.cpp +++ b/svf/lib/MSSA/SVFGBuilder.cpp @@ -101,12 +101,11 @@ std::unique_ptr SVFGBuilder::buildMSSA(BVDataPTAImpl* pta, bool ptrOnlyM auto mssa = std::make_unique(pta, ptrOnlyMSSA); - SVFModule* svfModule = mssa->getPTA()->getModule(); - for (SVFModule::const_iterator iter = svfModule->begin(), eiter = svfModule->end(); - iter != eiter; ++iter) + CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); + for (const auto& item: *svfirCallGraph) { - const SVFFunction *fun = *iter; + const SVFFunction *fun = item.second->getFunction(); if (isExtCall(fun)) continue; diff --git a/svf/lib/MTA/TCT.cpp b/svf/lib/MTA/TCT.cpp index 399b7ffa8..323c24ecd 100644 --- a/svf/lib/MTA/TCT.cpp +++ b/svf/lib/MTA/TCT.cpp @@ -185,9 +185,10 @@ void TCT::markRelProcs(const SVFFunction* svffun) */ void TCT::collectEntryFunInCallGraph() { - for(SVFModule::const_iterator it = getSVFModule()->begin(), eit = getSVFModule()->end(); it!=eit; ++it) + CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); + for (const auto& item: *svfirCallGraph) { - const SVFFunction* fun = (*it); + const SVFFunction* fun = item.second->getFunction(); if (SVFUtil::isExtCall(fun)) continue; CallGraphNode* node = tcg->getCallGraphNode(fun); diff --git a/svf/lib/MemoryModel/PointerAnalysis.cpp b/svf/lib/MemoryModel/PointerAnalysis.cpp index 2103802ff..b2ba50e05 100644 --- a/svf/lib/MemoryModel/PointerAnalysis.cpp +++ b/svf/lib/MemoryModel/PointerAnalysis.cpp @@ -111,15 +111,13 @@ void PointerAnalysis::initialize() /// initialise pta call graph for every pointer analysis instance if(Options::EnableThreadCallGraph()) { - ThreadCallGraph* cg = new ThreadCallGraph(); - ThreadCallGraphBuilder bd(cg, pag->getICFG()); - callgraph = bd.buildThreadCallGraph(pag->getModule()); + CallGraphBuilder bd; + callgraph = bd.buildThreadCallGraph(); } else { - CallGraph* cg = new CallGraph(); - CallGraphBuilder bd(cg,pag->getICFG()); - callgraph = bd.buildCallGraph(pag->getModule()); + CallGraph* cg = pag->getCallGraph(); + callgraph = new CallGraph(*cg); } callGraphSCCDetection(); diff --git a/svf/lib/SABER/SaberCondAllocator.cpp b/svf/lib/SABER/SaberCondAllocator.cpp index c3d8d1dae..872227c58 100644 --- a/svf/lib/SABER/SaberCondAllocator.cpp +++ b/svf/lib/SABER/SaberCondAllocator.cpp @@ -59,8 +59,10 @@ void SaberCondAllocator::allocate(const SVFModule *M) { DBOUT(DGENERAL, outs() << pasMsg("path condition allocation starts\n")); - for (const auto &func: *M) + CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); + for (const auto& item: *svfirCallGraph) { + const SVFFunction *func = (item.second)->getFunction(); if (!SVFUtil::isExtCall(func)) { // Allocate conditions for a program. diff --git a/svf/lib/SVFIR/SVFIR.cpp b/svf/lib/SVFIR/SVFIR.cpp index 674351997..311dd8249 100644 --- a/svf/lib/SVFIR/SVFIR.cpp +++ b/svf/lib/SVFIR/SVFIR.cpp @@ -544,6 +544,8 @@ void SVFIR::destroy() chgraph = nullptr; SVFModule::releaseSVFModule(); svfModule = nullptr; + delete callGraph; + callGraph = nullptr; } /*! diff --git a/svf/lib/Util/CDGBuilder.cpp b/svf/lib/Util/CDGBuilder.cpp index f67e9c450..12739ad65 100644 --- a/svf/lib/Util/CDGBuilder.cpp +++ b/svf/lib/Util/CDGBuilder.cpp @@ -27,6 +27,7 @@ * Author: Xiao Cheng */ #include "Util/CDGBuilder.h" +#include "Graphs/CallGraph.h" using namespace SVF; using namespace SVFUtil; @@ -122,8 +123,10 @@ s64_t CDGBuilder::getBBSuccessorBranchID(const SVFBasicBlock *BB, const SVFBasic */ void CDGBuilder::buildControlDependence(const SVFModule *svfgModule) { - for (const auto &svfFun: *svfgModule) + CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); + for (const auto& item: *svfirCallGraph) { + const SVFFunction *svfFun = (item.second)->getFunction(); if (SVFUtil::isExtCall(svfFun)) continue; // extract basic block edges to be processed Map> BBS; diff --git a/svf/lib/Util/CallGraphBuilder.cpp b/svf/lib/Util/CallGraphBuilder.cpp index a8ab807f3..c7b7a0418 100644 --- a/svf/lib/Util/CallGraphBuilder.cpp +++ b/svf/lib/Util/CallGraphBuilder.cpp @@ -36,18 +36,16 @@ using namespace SVF; using namespace SVFUtil; -CallGraph* CallGraphBuilder::buildCallGraph(SVFModule* svfModule) +CallGraph* CallGraphBuilder::buildSVFIRCallGraph(SVFModule* svfModule) { - /// create nodes - for (SVFModule::const_iterator F = svfModule->begin(), E = svfModule->end(); F != E; ++F) - { - callgraph->addCallGraphNode(*F); + CallGraph* callgraph = new CallGraph(); + for (const SVFFunction* svfFunc: svfModule->getFunctionSet()){ + callgraph->addCallGraphNode(svfFunc); } - /// create edges - for (SVFModule::const_iterator F = svfModule->begin(), E = svfModule->end(); F != E; ++F) + for (const auto& item : *callgraph) { - for (const SVFBasicBlock* svfbb : (*F)->getBasicBlockList()) + for (const SVFBasicBlock* svfbb : (item.second)->getFunction()->getBasicBlockList()) { for (const ICFGNode* inst : svfbb->getICFGNodeList()) { @@ -56,28 +54,24 @@ CallGraph* CallGraphBuilder::buildCallGraph(SVFModule* svfModule) const CallICFGNode* callBlockNode = cast(inst); if(const SVFFunction* callee = callBlockNode->getCalledFunction()) { - callgraph->addDirectCallGraphEdge(callBlockNode,*F,callee); + callgraph->addDirectCallGraphEdge(callBlockNode,(item.second)->getFunction(),callee); } } } } } - return callgraph; } -CallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule) +ThreadCallGraph* CallGraphBuilder::buildThreadCallGraph() { - - buildCallGraph(svfModule); - - ThreadCallGraph* cg = dyn_cast(callgraph); - assert(cg && "not a thread callgraph?"); + CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); + ThreadCallGraph* cg = new ThreadCallGraph(*svfirCallGraph); ThreadAPI* tdAPI = ThreadAPI::getThreadAPI(); - for (SVFModule::const_iterator F = svfModule->begin(), E = svfModule->end(); F != E; ++F) + for (const auto& item: *svfirCallGraph) { - for (const SVFBasicBlock* svfbb : (*F)->getBasicBlockList()) + for (const SVFBasicBlock* svfbb : (item.second)->getFunction()->getBasicBlockList()) { for (const ICFGNode* inst : svfbb->getICFGNodeList()) { @@ -100,9 +94,9 @@ CallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule) } } // record join sites - for (SVFModule::const_iterator F = svfModule->begin(), E = svfModule->end(); F != E; ++F) + for (const auto& item: *svfirCallGraph) { - for (const SVFBasicBlock* svfbb : (*F)->getBasicBlockList()) + for (const SVFBasicBlock* svfbb : (item.second)->getFunction()->getBasicBlockList()) { for (const ICFGNode* node : svfbb->getICFGNodeList()) { @@ -117,7 +111,3 @@ CallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule) return cg; } - - - - diff --git a/svf/lib/Util/SVFStat.cpp b/svf/lib/Util/SVFStat.cpp index 7cab07720..ed2c8743f 100644 --- a/svf/lib/Util/SVFStat.cpp +++ b/svf/lib/Util/SVFStat.cpp @@ -214,13 +214,12 @@ void SVFStat::performStat() void SVFStat::branchStat() { - SVFModule* module = SVFIR::getPAG()->getModule(); u32_t numOfBB_2Succ = 0; u32_t numOfBB_3Succ = 0; - for (SVFModule::const_iterator funIter = module->begin(), funEiter = module->end(); - funIter != funEiter; ++funIter) + CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); + for (const auto& item: *svfirCallGraph) { - const SVFFunction* func = *funIter; + const SVFFunction* func = item.second->getFunction(); for (SVFFunction::const_iterator bbIt = func->begin(), bbEit = func->end(); bbIt != bbEit; ++bbIt) { diff --git a/svf/lib/Util/SVFUtil.cpp b/svf/lib/Util/SVFUtil.cpp index f9cb3afd8..98aa8d22f 100644 --- a/svf/lib/Util/SVFUtil.cpp +++ b/svf/lib/Util/SVFUtil.cpp @@ -396,4 +396,30 @@ bool SVFUtil::isRetInstNode(const ICFGNode* node) bool SVFUtil::isProgExitCall(const CallICFGNode* cs) { return isProgExitFunction(cs->getCalledFunction()); +} + +/// Get program entry function from module. +const SVFFunction* 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 nullptr; +} + +/// Get program entry function from module. +const SVFFunction* SVFUtil::getProgEntryFunction() +{ + CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); + for (const auto& item: *svfirCallGraph) + { + const CallGraphNode*fun = item.second; + if (isProgEntryFunction(fun->getFunction())) + return (fun->getFunction()); + } + return nullptr; } \ No newline at end of file diff --git a/svf/lib/Util/ThreadAPI.cpp b/svf/lib/Util/ThreadAPI.cpp index 7b305b7e6..ff7237e31 100644 --- a/svf/lib/Util/ThreadAPI.cpp +++ b/svf/lib/Util/ThreadAPI.cpp @@ -33,6 +33,7 @@ #include "Util/ThreadAPI.h" #include "Util/SVFUtil.h" #include "SVFIR/SVFIR.h" +#include "Graphs/CallGraph.h" #include /// std output #include @@ -269,9 +270,10 @@ void ThreadAPI::performAPIStat(SVFModule* module) statInit(tdAPIStatMap); - for (SVFModule::const_iterator it = module->begin(), eit = module->end(); it != eit; ++it) + CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph(); + for (const auto& item: *svfirCallGraph) { - for (SVFFunction::const_iterator bit = (*it)->begin(), ebit = (*it)->end(); bit != ebit; ++bit) + for (SVFFunction::const_iterator bit = (item.second)->getFunction()->begin(), ebit = (item.second)->getFunction()->end(); bit != ebit; ++bit) { const SVFBasicBlock* bb = *bit; for (const auto& svfInst: bb->getICFGNodeList())