Static Value-Flow Analysis
CallGraphBuilder.cpp
Go to the documentation of this file.
1 //===- CallGraphBuilder.cpp ----------------------------------------------------------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-> <Yulei Sui>
6 //
7 
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
17 
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 
24 /*
25  * CallGraphBuilder.cpp
26  *
27  * Created on:
28  * Author: Yulei
29  */
30 
31 #include "Util/SVFUtil.h"
32 #include "Util/CallGraphBuilder.h"
33 #include "Graphs/ICFG.h"
34 #include "SVFIR/SVFIR.h"
35 
36 using namespace SVF;
37 using namespace SVFUtil;
38 
40 {
41  PTACallGraph* callgraph = new PTACallGraph();
42  for (const SVFFunction* svfFunc: svfModule->getFunctionSet())
43  {
44  callgraph->addCallGraphNode(svfFunc);
45  }
46 
47  for (const auto& item : *callgraph)
48  {
49  for (const SVFBasicBlock* svfbb : (item.second)->getFunction()->getBasicBlockList())
50  {
51  for (const ICFGNode* inst : svfbb->getICFGNodeList())
52  {
54  {
55  const CallICFGNode* callBlockNode = cast<CallICFGNode>(inst);
56  if(const SVFFunction* callee = callBlockNode->getCalledFunction())
57  {
58  callgraph->addDirectCallGraphEdge(callBlockNode,(item.second)->getFunction(),callee);
59  }
60  }
61  }
62  }
63  }
64  return callgraph;
65 }
66 
68 {
69  PTACallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
70  ThreadCallGraph* cg = new ThreadCallGraph(*svfirCallGraph);
71 
73  for (const auto& item: *svfirCallGraph)
74  {
75  for (const SVFBasicBlock* svfbb : (item.second)->getFunction()->getBasicBlockList())
76  {
77  for (const ICFGNode* inst : svfbb->getICFGNodeList())
78  {
79  if (SVFUtil::isa<CallICFGNode>(inst) && tdAPI->isTDFork(SVFUtil::cast<CallICFGNode>(inst)))
80  {
81  const CallICFGNode* cs = cast<CallICFGNode>(inst);
82  cg->addForksite(cs);
83  const SVFFunction* forkee = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getForkedFun(cs)->getValue());
84  if (forkee)
85  {
86  cg->addDirectForkEdge(cs);
87  }
88  // indirect call to the start routine function
89  else
90  {
91  cg->addThreadForkEdgeSetMap(cs,nullptr);
92  }
93  }
94  }
95  }
96  }
97  // record join sites
98  for (const auto& item: *svfirCallGraph)
99  {
100  for (const SVFBasicBlock* svfbb : (item.second)->getFunction()->getBasicBlockList())
101  {
102  for (const ICFGNode* node : svfbb->getICFGNodeList())
103  {
104  if (SVFUtil::isa<CallICFGNode>(node) && tdAPI->isTDJoin(SVFUtil::cast<CallICFGNode>(node)))
105  {
106  const CallICFGNode* cs = SVFUtil::cast<CallICFGNode>(node);
107  cg->addJoinsite(cs);
108  }
109  }
110  }
111  }
112 
113  return cg;
114 }
cJSON * item
Definition: cJSON.h:222
ThreadCallGraph * buildThreadCallGraph()
Build thread-aware callgraph.
PTACallGraph * buildSVFIRCallGraph(SVFModule *svfModule)
Buidl SVFIR callgraoh.
const SVFFunction * getCalledFunction() const
Definition: ICFGNode.h:518
void addDirectCallGraphEdge(const CallICFGNode *call, const SVFFunction *callerFun, const SVFFunction *calleeFun)
Add direct/indirect call edges.
void addCallGraphNode(const SVFFunction *fun)
const SVFFunction * getFunction() const
Definition: SVFValue.h:589
const std::vector< const SVFBasicBlock * > & getBasicBlockList() const
Definition: SVFValue.h:445
PTACallGraph * getCallGraph()
Definition: SVFIR.h:192
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115
const FunctionSetType & getFunctionSet() const
Definition: SVFModule.h:199
const SVFValue * getValue() const
Get/has methods of the components.
Definition: SVFVariables.h:83
bool isTDFork(const CallICFGNode *inst) const
Return true if this call create a new thread.
Definition: ThreadAPI.cpp:133
bool isTDJoin(const CallICFGNode *inst) const
Return true if this call wait for a worker thread.
Definition: ThreadAPI.cpp:138
static ThreadAPI * getThreadAPI()
Return a static reference.
Definition: ThreadAPI.h:105
const SVFVar * getForkedFun(const CallICFGNode *inst) const
Definition: ThreadAPI.cpp:170
bool addDirectForkEdge(const CallICFGNode *cs)
Add direct/indirect thread fork edges.
bool addForksite(const CallICFGNode *cs)
Add fork sites which directly or indirectly create a thread.
bool addJoinsite(const CallICFGNode *cs)
void addThreadForkEdgeSetMap(const CallICFGNode *cs, ThreadForkEdge *edge)
map call instruction to its PTACallGraphEdge map
bool isNonInstricCallSite(const ICFGNode *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
Definition: SVFUtil.h:189
for isBitcode
Definition: BasicTypes.h:68