svf-tools 1.0.1002 → 1.0.1003
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/svf/include/Graphs/CallGraph.h +9 -3
- package/svf/include/Graphs/ThreadCallGraph.h +4 -1
- package/svf/include/SVFIR/SVFIR.h +13 -0
- package/svf/include/SVFIR/SVFModule.h +0 -17
- package/svf/include/Util/CallGraphBuilder.h +5 -21
- package/svf/include/Util/SVFUtil.h +4 -22
- package/svf/lib/Graphs/CallGraph.cpp +37 -4
- package/svf/lib/Graphs/SVFG.cpp +1 -3
- package/svf/lib/Graphs/ThreadCallGraph.cpp +3 -2
- package/svf/lib/MSSA/MemRegion.cpp +3 -4
- package/svf/lib/MSSA/MemSSA.cpp +3 -3
- package/svf/lib/MSSA/SVFGBuilder.cpp +3 -4
- package/svf/lib/MTA/TCT.cpp +3 -2
- package/svf/lib/MemoryModel/PointerAnalysis.cpp +4 -6
- package/svf/lib/SABER/SaberCondAllocator.cpp +3 -1
- package/svf/lib/SVFIR/SVFIR.cpp +2 -0
- package/svf/lib/Util/CDGBuilder.cpp +4 -1
- package/svf/lib/Util/CallGraphBuilder.cpp +14 -23
- package/svf/lib/Util/SVFStat.cpp +3 -4
- package/svf/lib/Util/SVFUtil.cpp +26 -0
- package/svf/lib/Util/ThreadAPI.cpp +4 -2
- package/svf-llvm/include/SVF-LLVM/LLVMModule.h +1 -0
- package/svf-llvm/lib/LLVMModule.cpp +5 -0
- package/svf-llvm/lib/SVFIRBuilder.cpp +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1003",
|
|
4
4
|
"description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -189,6 +189,11 @@ public:
|
|
|
189
189
|
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
+
inline const std::string &getName() const
|
|
193
|
+
{
|
|
194
|
+
return fun->getName();
|
|
195
|
+
}
|
|
196
|
+
|
|
192
197
|
/// Get function of this call node
|
|
193
198
|
inline const SVFFunction* getFunction() const
|
|
194
199
|
{
|
|
@@ -254,8 +259,6 @@ public:
|
|
|
254
259
|
};
|
|
255
260
|
|
|
256
261
|
private:
|
|
257
|
-
CGEK kind;
|
|
258
|
-
|
|
259
262
|
/// Indirect call map
|
|
260
263
|
CallEdgeMap indirectCallMap;
|
|
261
264
|
|
|
@@ -270,6 +273,7 @@ protected:
|
|
|
270
273
|
|
|
271
274
|
NodeID callGraphNodeNum;
|
|
272
275
|
u32_t numOfResolvedIndCallEdge;
|
|
276
|
+
CGEK kind;
|
|
273
277
|
|
|
274
278
|
/// Clean up memory
|
|
275
279
|
void destroy();
|
|
@@ -278,7 +282,9 @@ public:
|
|
|
278
282
|
/// Constructor
|
|
279
283
|
CallGraph(CGEK k = NormCallGraph);
|
|
280
284
|
|
|
281
|
-
///
|
|
285
|
+
/// Copy constructor
|
|
286
|
+
CallGraph(const CallGraph& other);
|
|
287
|
+
|
|
282
288
|
void addCallGraphNode(const SVFFunction* fun);
|
|
283
289
|
|
|
284
290
|
/// Destructor
|
|
@@ -172,7 +172,10 @@ public:
|
|
|
172
172
|
typedef Map<const CallICFGNode*, ParForEdgeSet> CallInstToParForEdgesMap;
|
|
173
173
|
|
|
174
174
|
/// Constructor
|
|
175
|
-
ThreadCallGraph();
|
|
175
|
+
ThreadCallGraph(const CallGraph& cg);
|
|
176
|
+
|
|
177
|
+
ThreadCallGraph(ThreadCallGraph& cg) = delete;
|
|
178
|
+
|
|
176
179
|
/// Destructor
|
|
177
180
|
virtual ~ThreadCallGraph()
|
|
178
181
|
{
|
|
@@ -98,6 +98,7 @@ private:
|
|
|
98
98
|
ICFG* icfg; // ICFG
|
|
99
99
|
CommonCHGraph* chgraph; // class hierarchy graph
|
|
100
100
|
CallSiteSet callSiteSet; /// all the callsites of a program
|
|
101
|
+
CallGraph* callGraph; /// call graph
|
|
101
102
|
|
|
102
103
|
static std::unique_ptr<SVFIR> pag; ///< Singleton pattern here to enable instance of SVFIR can only be created once.
|
|
103
104
|
|
|
@@ -182,6 +183,18 @@ public:
|
|
|
182
183
|
assert(chgraph && "empty ICFG! Build SVF IR first!");
|
|
183
184
|
return chgraph;
|
|
184
185
|
}
|
|
186
|
+
|
|
187
|
+
/// Set/Get CG
|
|
188
|
+
inline void setCallGraph(CallGraph* c)
|
|
189
|
+
{
|
|
190
|
+
callGraph = c;
|
|
191
|
+
}
|
|
192
|
+
inline CallGraph* getCallGraph()
|
|
193
|
+
{
|
|
194
|
+
assert(callGraph && "empty CallGraph! Build SVF IR first!");
|
|
195
|
+
return callGraph;
|
|
196
|
+
}
|
|
197
|
+
|
|
185
198
|
/// Get/set methods to get SVFStmts based on their kinds and ICFGNodes
|
|
186
199
|
//@{
|
|
187
200
|
/// Get edges set according to its kind
|
|
@@ -130,23 +130,6 @@ public:
|
|
|
130
130
|
|
|
131
131
|
/// Iterators
|
|
132
132
|
///@{
|
|
133
|
-
iterator begin()
|
|
134
|
-
{
|
|
135
|
-
return FunctionSet.begin();
|
|
136
|
-
}
|
|
137
|
-
const_iterator begin() const
|
|
138
|
-
{
|
|
139
|
-
return FunctionSet.begin();
|
|
140
|
-
}
|
|
141
|
-
iterator end()
|
|
142
|
-
{
|
|
143
|
-
return FunctionSet.end();
|
|
144
|
-
}
|
|
145
|
-
const_iterator end() const
|
|
146
|
-
{
|
|
147
|
-
return FunctionSet.end();
|
|
148
|
-
}
|
|
149
|
-
|
|
150
133
|
global_iterator global_begin()
|
|
151
134
|
{
|
|
152
135
|
return GlobalSet.begin();
|
|
@@ -38,34 +38,18 @@ namespace SVF
|
|
|
38
38
|
{
|
|
39
39
|
|
|
40
40
|
class ICFG;
|
|
41
|
+
class SVFModule;
|
|
41
42
|
|
|
42
43
|
class CallGraphBuilder
|
|
43
44
|
{
|
|
44
|
-
|
|
45
|
-
protected:
|
|
46
|
-
CallGraph* callgraph;
|
|
47
|
-
ICFG* icfg;
|
|
48
45
|
public:
|
|
49
|
-
CallGraphBuilder(
|
|
50
|
-
{
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/// Build normal callgraph
|
|
54
|
-
CallGraph* buildCallGraph(SVFModule* svfModule);
|
|
55
|
-
|
|
56
|
-
};
|
|
46
|
+
CallGraphBuilder()=default;
|
|
57
47
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
public:
|
|
62
|
-
ThreadCallGraphBuilder(ThreadCallGraph* cg, ICFG* i): CallGraphBuilder(cg,i)
|
|
63
|
-
{
|
|
64
|
-
}
|
|
48
|
+
/// Buidl SVFIR callgraoh
|
|
49
|
+
CallGraph* buildSVFIRCallGraph(SVFModule* svfModule);
|
|
65
50
|
|
|
66
51
|
/// Build thread-aware callgraph
|
|
67
|
-
|
|
68
|
-
|
|
52
|
+
ThreadCallGraph* buildThreadCallGraph();
|
|
69
53
|
};
|
|
70
54
|
|
|
71
55
|
} // End namespace SVF
|
|
@@ -327,29 +327,11 @@ inline bool isProgEntryFunction(const SVFFunction* fun)
|
|
|
327
327
|
return fun && fun->getName() == "main";
|
|
328
328
|
}
|
|
329
329
|
|
|
330
|
-
/// Get program entry function from
|
|
331
|
-
|
|
332
|
-
{
|
|
333
|
-
for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it)
|
|
334
|
-
{
|
|
335
|
-
const SVFFunction *fun = *it;
|
|
336
|
-
if (fun->getName()==funName)
|
|
337
|
-
return fun;
|
|
338
|
-
}
|
|
339
|
-
return nullptr;
|
|
340
|
-
}
|
|
330
|
+
/// Get program entry function from function name.
|
|
331
|
+
const SVFFunction* getProgFunction(const std::string& funName);
|
|
341
332
|
|
|
342
|
-
/// Get program entry function
|
|
343
|
-
|
|
344
|
-
{
|
|
345
|
-
for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it)
|
|
346
|
-
{
|
|
347
|
-
const SVFFunction *fun = *it;
|
|
348
|
-
if (isProgEntryFunction(fun))
|
|
349
|
-
return (fun);
|
|
350
|
-
}
|
|
351
|
-
return nullptr;
|
|
352
|
-
}
|
|
333
|
+
/// Get program entry function.
|
|
334
|
+
const SVFFunction* getProgEntryFunction();
|
|
353
335
|
|
|
354
336
|
/// Return true if this is a program exit function call
|
|
355
337
|
//@{
|
|
@@ -112,6 +112,39 @@ CallGraph::CallGraph(CGEK k): kind(k)
|
|
|
112
112
|
numOfResolvedIndCallEdge = 0;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
/// Copy constructor
|
|
116
|
+
CallGraph::CallGraph(const CallGraph& other)
|
|
117
|
+
{
|
|
118
|
+
callGraphNodeNum = other.callGraphNodeNum;
|
|
119
|
+
numOfResolvedIndCallEdge = 0;
|
|
120
|
+
kind = other.kind;
|
|
121
|
+
|
|
122
|
+
/// copy call graph nodes
|
|
123
|
+
for (const auto& item : other)
|
|
124
|
+
{
|
|
125
|
+
const CallGraphNode* cgn = item.second;
|
|
126
|
+
CallGraphNode* callGraphNode = new CallGraphNode(cgn->getId(), cgn->getFunction());
|
|
127
|
+
addGNode(cgn->getId(),callGraphNode);
|
|
128
|
+
funToCallGraphNodeMap[cgn->getFunction()] = callGraphNode;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/// copy edges
|
|
132
|
+
for (const auto& item : other.callinstToCallGraphEdgesMap)
|
|
133
|
+
{
|
|
134
|
+
const CallICFGNode* cs = item.first;
|
|
135
|
+
for (const CallGraphEdge* edge : item.second)
|
|
136
|
+
{
|
|
137
|
+
CallGraphNode* src = getCallGraphNode(edge->getSrcID());
|
|
138
|
+
CallGraphNode* dst = getCallGraphNode(edge->getDstID());
|
|
139
|
+
CallGraphEdge* newEdge = new CallGraphEdge(src,dst,CallGraphEdge::CallRetEdge,edge->getCallSiteID());
|
|
140
|
+
newEdge->addDirectCallSite(cs);
|
|
141
|
+
addEdge(newEdge);
|
|
142
|
+
callinstToCallGraphEdgesMap[cs].insert(newEdge);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
}
|
|
147
|
+
|
|
115
148
|
/*!
|
|
116
149
|
* Memory has been cleaned up at GenericGraph
|
|
117
150
|
*/
|
|
@@ -124,10 +157,10 @@ void CallGraph::destroy()
|
|
|
124
157
|
*/
|
|
125
158
|
void CallGraph::addCallGraphNode(const SVFFunction* fun)
|
|
126
159
|
{
|
|
127
|
-
NodeID id
|
|
128
|
-
CallGraphNode*
|
|
129
|
-
addGNode(id,callGraphNode);
|
|
130
|
-
funToCallGraphNodeMap[
|
|
160
|
+
NodeID id = callGraphNodeNum;
|
|
161
|
+
CallGraphNode *callGraphNode = new CallGraphNode(id, fun);
|
|
162
|
+
addGNode(id, callGraphNode);
|
|
163
|
+
funToCallGraphNodeMap[callGraphNode->getFunction()] = callGraphNode;
|
|
131
164
|
callGraphNodeNum++;
|
|
132
165
|
}
|
|
133
166
|
|
package/svf/lib/Graphs/SVFG.cpp
CHANGED
|
@@ -427,9 +427,7 @@ void SVFG::connectIndirectSVFGEdges()
|
|
|
427
427
|
*/
|
|
428
428
|
void SVFG::connectFromGlobalToProgEntry()
|
|
429
429
|
{
|
|
430
|
-
|
|
431
|
-
const SVFFunction* mainFunc =
|
|
432
|
-
SVFUtil::getProgEntryFunction(svfModule);
|
|
430
|
+
const SVFFunction* mainFunc = SVFUtil::getProgEntryFunction();
|
|
433
431
|
FormalINSVFGNodeSet& formalIns = getFormalINSVFGNodes(mainFunc);
|
|
434
432
|
if (formalIns.empty())
|
|
435
433
|
return;
|
|
@@ -39,9 +39,10 @@ using namespace SVFUtil;
|
|
|
39
39
|
/*!
|
|
40
40
|
* Constructor
|
|
41
41
|
*/
|
|
42
|
-
ThreadCallGraph::ThreadCallGraph() :
|
|
43
|
-
CallGraph(
|
|
42
|
+
ThreadCallGraph::ThreadCallGraph(const CallGraph& cg) :
|
|
43
|
+
CallGraph(cg), tdAPI(ThreadAPI::getThreadAPI())
|
|
44
44
|
{
|
|
45
|
+
kind = ThdCallGraph;
|
|
45
46
|
DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("Building ThreadCallGraph\n"));
|
|
46
47
|
}
|
|
47
48
|
|
|
@@ -173,11 +173,10 @@ SVFIR::SVFStmtList& MRGenerator::getPAGEdgesFromInst(const ICFGNode* node)
|
|
|
173
173
|
void MRGenerator::collectModRefForLoadStore()
|
|
174
174
|
{
|
|
175
175
|
|
|
176
|
-
|
|
177
|
-
for (
|
|
178
|
-
++fi)
|
|
176
|
+
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
|
|
177
|
+
for (const auto& item: *svfirCallGraph)
|
|
179
178
|
{
|
|
180
|
-
const SVFFunction& fun =
|
|
179
|
+
const SVFFunction& fun = *item.second->getFunction();
|
|
181
180
|
|
|
182
181
|
/// if this function does not have any caller, then we do not care its MSSA
|
|
183
182
|
if (Options::IgnoreDeadFun() && fun.isUncalledFunction())
|
package/svf/lib/MSSA/MemSSA.cpp
CHANGED
|
@@ -575,10 +575,10 @@ u32_t MemSSA::getBBPhiNum() const
|
|
|
575
575
|
void MemSSA::dumpMSSA(OutStream& Out)
|
|
576
576
|
{
|
|
577
577
|
|
|
578
|
-
|
|
579
|
-
|
|
578
|
+
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
|
|
579
|
+
for (const auto& item: *svfirCallGraph)
|
|
580
580
|
{
|
|
581
|
-
const SVFFunction* fun =
|
|
581
|
+
const SVFFunction* fun = item.second->getFunction();
|
|
582
582
|
if(Options::MSSAFun()!="" && Options::MSSAFun()!=fun->getName())
|
|
583
583
|
continue;
|
|
584
584
|
|
|
@@ -101,12 +101,11 @@ std::unique_ptr<MemSSA> SVFGBuilder::buildMSSA(BVDataPTAImpl* pta, bool ptrOnlyM
|
|
|
101
101
|
|
|
102
102
|
auto mssa = std::make_unique<MemSSA>(pta, ptrOnlyMSSA);
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
for (
|
|
106
|
-
iter != eiter; ++iter)
|
|
104
|
+
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
|
|
105
|
+
for (const auto& item: *svfirCallGraph)
|
|
107
106
|
{
|
|
108
107
|
|
|
109
|
-
const SVFFunction *fun =
|
|
108
|
+
const SVFFunction *fun = item.second->getFunction();
|
|
110
109
|
if (isExtCall(fun))
|
|
111
110
|
continue;
|
|
112
111
|
|
package/svf/lib/MTA/TCT.cpp
CHANGED
|
@@ -185,9 +185,10 @@ void TCT::markRelProcs(const SVFFunction* svffun)
|
|
|
185
185
|
*/
|
|
186
186
|
void TCT::collectEntryFunInCallGraph()
|
|
187
187
|
{
|
|
188
|
-
|
|
188
|
+
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
|
|
189
|
+
for (const auto& item: *svfirCallGraph)
|
|
189
190
|
{
|
|
190
|
-
const SVFFunction* fun = (
|
|
191
|
+
const SVFFunction* fun = item.second->getFunction();
|
|
191
192
|
if (SVFUtil::isExtCall(fun))
|
|
192
193
|
continue;
|
|
193
194
|
CallGraphNode* node = tcg->getCallGraphNode(fun);
|
|
@@ -111,15 +111,13 @@ void PointerAnalysis::initialize()
|
|
|
111
111
|
/// initialise pta call graph for every pointer analysis instance
|
|
112
112
|
if(Options::EnableThreadCallGraph())
|
|
113
113
|
{
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
callgraph = bd.buildThreadCallGraph(pag->getModule());
|
|
114
|
+
CallGraphBuilder bd;
|
|
115
|
+
callgraph = bd.buildThreadCallGraph();
|
|
117
116
|
}
|
|
118
117
|
else
|
|
119
118
|
{
|
|
120
|
-
CallGraph* cg =
|
|
121
|
-
|
|
122
|
-
callgraph = bd.buildCallGraph(pag->getModule());
|
|
119
|
+
CallGraph* cg = pag->getCallGraph();
|
|
120
|
+
callgraph = new CallGraph(*cg);
|
|
123
121
|
}
|
|
124
122
|
callGraphSCCDetection();
|
|
125
123
|
|
|
@@ -59,8 +59,10 @@ void SaberCondAllocator::allocate(const SVFModule *M)
|
|
|
59
59
|
{
|
|
60
60
|
DBOUT(DGENERAL, outs() << pasMsg("path condition allocation starts\n"));
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
|
|
63
|
+
for (const auto& item: *svfirCallGraph)
|
|
63
64
|
{
|
|
65
|
+
const SVFFunction *func = (item.second)->getFunction();
|
|
64
66
|
if (!SVFUtil::isExtCall(func))
|
|
65
67
|
{
|
|
66
68
|
// Allocate conditions for a program.
|
package/svf/lib/SVFIR/SVFIR.cpp
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
* Author: Xiao Cheng
|
|
28
28
|
*/
|
|
29
29
|
#include "Util/CDGBuilder.h"
|
|
30
|
+
#include "Graphs/CallGraph.h"
|
|
30
31
|
|
|
31
32
|
using namespace SVF;
|
|
32
33
|
using namespace SVFUtil;
|
|
@@ -122,8 +123,10 @@ s64_t CDGBuilder::getBBSuccessorBranchID(const SVFBasicBlock *BB, const SVFBasic
|
|
|
122
123
|
*/
|
|
123
124
|
void CDGBuilder::buildControlDependence(const SVFModule *svfgModule)
|
|
124
125
|
{
|
|
125
|
-
|
|
126
|
+
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
|
|
127
|
+
for (const auto& item: *svfirCallGraph)
|
|
126
128
|
{
|
|
129
|
+
const SVFFunction *svfFun = (item.second)->getFunction();
|
|
127
130
|
if (SVFUtil::isExtCall(svfFun)) continue;
|
|
128
131
|
// extract basic block edges to be processed
|
|
129
132
|
Map<const SVFBasicBlock *, std::vector<const SVFBasicBlock *>> BBS;
|
|
@@ -36,18 +36,17 @@
|
|
|
36
36
|
using namespace SVF;
|
|
37
37
|
using namespace SVFUtil;
|
|
38
38
|
|
|
39
|
-
CallGraph* CallGraphBuilder::
|
|
39
|
+
CallGraph* CallGraphBuilder::buildSVFIRCallGraph(SVFModule* svfModule)
|
|
40
40
|
{
|
|
41
|
-
|
|
42
|
-
for (
|
|
41
|
+
CallGraph* callgraph = new CallGraph();
|
|
42
|
+
for (const SVFFunction* svfFunc: svfModule->getFunctionSet())
|
|
43
43
|
{
|
|
44
|
-
callgraph->addCallGraphNode(
|
|
44
|
+
callgraph->addCallGraphNode(svfFunc);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
for (SVFModule::const_iterator F = svfModule->begin(), E = svfModule->end(); F != E; ++F)
|
|
47
|
+
for (const auto& item : *callgraph)
|
|
49
48
|
{
|
|
50
|
-
for (const SVFBasicBlock* svfbb : (
|
|
49
|
+
for (const SVFBasicBlock* svfbb : (item.second)->getFunction()->getBasicBlockList())
|
|
51
50
|
{
|
|
52
51
|
for (const ICFGNode* inst : svfbb->getICFGNodeList())
|
|
53
52
|
{
|
|
@@ -56,28 +55,24 @@ CallGraph* CallGraphBuilder::buildCallGraph(SVFModule* svfModule)
|
|
|
56
55
|
const CallICFGNode* callBlockNode = cast<CallICFGNode>(inst);
|
|
57
56
|
if(const SVFFunction* callee = callBlockNode->getCalledFunction())
|
|
58
57
|
{
|
|
59
|
-
callgraph->addDirectCallGraphEdge(callBlockNode
|
|
58
|
+
callgraph->addDirectCallGraphEdge(callBlockNode,(item.second)->getFunction(),callee);
|
|
60
59
|
}
|
|
61
60
|
}
|
|
62
61
|
}
|
|
63
62
|
}
|
|
64
63
|
}
|
|
65
|
-
|
|
66
64
|
return callgraph;
|
|
67
65
|
}
|
|
68
66
|
|
|
69
|
-
|
|
67
|
+
ThreadCallGraph* CallGraphBuilder::buildThreadCallGraph()
|
|
70
68
|
{
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
ThreadCallGraph* cg = dyn_cast<ThreadCallGraph>(callgraph);
|
|
75
|
-
assert(cg && "not a thread callgraph?");
|
|
69
|
+
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
|
|
70
|
+
ThreadCallGraph* cg = new ThreadCallGraph(*svfirCallGraph);
|
|
76
71
|
|
|
77
72
|
ThreadAPI* tdAPI = ThreadAPI::getThreadAPI();
|
|
78
|
-
for (
|
|
73
|
+
for (const auto& item: *svfirCallGraph)
|
|
79
74
|
{
|
|
80
|
-
for (const SVFBasicBlock* svfbb : (
|
|
75
|
+
for (const SVFBasicBlock* svfbb : (item.second)->getFunction()->getBasicBlockList())
|
|
81
76
|
{
|
|
82
77
|
for (const ICFGNode* inst : svfbb->getICFGNodeList())
|
|
83
78
|
{
|
|
@@ -100,9 +95,9 @@ CallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule)
|
|
|
100
95
|
}
|
|
101
96
|
}
|
|
102
97
|
// record join sites
|
|
103
|
-
for (
|
|
98
|
+
for (const auto& item: *svfirCallGraph)
|
|
104
99
|
{
|
|
105
|
-
for (const SVFBasicBlock* svfbb : (
|
|
100
|
+
for (const SVFBasicBlock* svfbb : (item.second)->getFunction()->getBasicBlockList())
|
|
106
101
|
{
|
|
107
102
|
for (const ICFGNode* node : svfbb->getICFGNodeList())
|
|
108
103
|
{
|
|
@@ -117,7 +112,3 @@ CallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule)
|
|
|
117
112
|
|
|
118
113
|
return cg;
|
|
119
114
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
package/svf/lib/Util/SVFStat.cpp
CHANGED
|
@@ -214,13 +214,12 @@ void SVFStat::performStat()
|
|
|
214
214
|
|
|
215
215
|
void SVFStat::branchStat()
|
|
216
216
|
{
|
|
217
|
-
SVFModule* module = SVFIR::getPAG()->getModule();
|
|
218
217
|
u32_t numOfBB_2Succ = 0;
|
|
219
218
|
u32_t numOfBB_3Succ = 0;
|
|
220
|
-
|
|
221
|
-
|
|
219
|
+
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
|
|
220
|
+
for (const auto& item: *svfirCallGraph)
|
|
222
221
|
{
|
|
223
|
-
const SVFFunction* func =
|
|
222
|
+
const SVFFunction* func = item.second->getFunction();
|
|
224
223
|
for (SVFFunction::const_iterator bbIt = func->begin(), bbEit = func->end();
|
|
225
224
|
bbIt != bbEit; ++bbIt)
|
|
226
225
|
{
|
package/svf/lib/Util/SVFUtil.cpp
CHANGED
|
@@ -396,4 +396,30 @@ bool SVFUtil::isRetInstNode(const ICFGNode* node)
|
|
|
396
396
|
bool SVFUtil::isProgExitCall(const CallICFGNode* cs)
|
|
397
397
|
{
|
|
398
398
|
return isProgExitFunction(cs->getCalledFunction());
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/// Get program entry function from module.
|
|
402
|
+
const SVFFunction* SVFUtil::getProgFunction(const std::string& funName)
|
|
403
|
+
{
|
|
404
|
+
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
|
|
405
|
+
for (const auto& item: *svfirCallGraph)
|
|
406
|
+
{
|
|
407
|
+
const CallGraphNode*fun = item.second;
|
|
408
|
+
if (fun->getName()==funName)
|
|
409
|
+
return fun->getFunction();
|
|
410
|
+
}
|
|
411
|
+
return nullptr;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/// Get program entry function from module.
|
|
415
|
+
const SVFFunction* SVFUtil::getProgEntryFunction()
|
|
416
|
+
{
|
|
417
|
+
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
|
|
418
|
+
for (const auto& item: *svfirCallGraph)
|
|
419
|
+
{
|
|
420
|
+
const CallGraphNode*fun = item.second;
|
|
421
|
+
if (isProgEntryFunction(fun->getFunction()))
|
|
422
|
+
return (fun->getFunction());
|
|
423
|
+
}
|
|
424
|
+
return nullptr;
|
|
399
425
|
}
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
#include "Util/ThreadAPI.h"
|
|
34
34
|
#include "Util/SVFUtil.h"
|
|
35
35
|
#include "SVFIR/SVFIR.h"
|
|
36
|
+
#include "Graphs/CallGraph.h"
|
|
36
37
|
|
|
37
38
|
#include <iostream> /// std output
|
|
38
39
|
#include <stdio.h>
|
|
@@ -269,9 +270,10 @@ void ThreadAPI::performAPIStat(SVFModule* module)
|
|
|
269
270
|
|
|
270
271
|
statInit(tdAPIStatMap);
|
|
271
272
|
|
|
272
|
-
|
|
273
|
+
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
|
|
274
|
+
for (const auto& item: *svfirCallGraph)
|
|
273
275
|
{
|
|
274
|
-
for (SVFFunction::const_iterator bit = (
|
|
276
|
+
for (SVFFunction::const_iterator bit = (item.second)->getFunction()->begin(), ebit = (item.second)->getFunction()->end(); bit != ebit; ++bit)
|
|
275
277
|
{
|
|
276
278
|
const SVFBasicBlock* bb = *bit;
|
|
277
279
|
for (const auto& svfInst: bb->getICFGNodeList())
|
|
@@ -105,6 +105,7 @@ private:
|
|
|
105
105
|
InstToBlockNodeMapTy InstToBlockNodeMap; ///< map a basic block to its ICFGNode
|
|
106
106
|
FunToFunEntryNodeMapTy FunToFunEntryNodeMap; ///< map a function to its FunExitICFGNode
|
|
107
107
|
FunToFunExitNodeMapTy FunToFunExitNodeMap; ///< map a function to its FunEntryICFGNode
|
|
108
|
+
CallGraph* callgraph;
|
|
108
109
|
|
|
109
110
|
/// Constructor
|
|
110
111
|
LLVMModuleSet();
|
|
@@ -41,6 +41,8 @@
|
|
|
41
41
|
#include "SVF-LLVM/ObjTypeInference.h"
|
|
42
42
|
#include "llvm/Transforms/Utils/Cloning.h"
|
|
43
43
|
#include "SVF-LLVM/ICFGBuilder.h"
|
|
44
|
+
#include "Graphs/CallGraph.h"
|
|
45
|
+
#include "Util/CallGraphBuilder.h"
|
|
44
46
|
|
|
45
47
|
using namespace std;
|
|
46
48
|
using namespace SVF;
|
|
@@ -169,6 +171,9 @@ void LLVMModuleSet::build()
|
|
|
169
171
|
initSVFFunction();
|
|
170
172
|
ICFGBuilder icfgbuilder;
|
|
171
173
|
icfg = icfgbuilder.build();
|
|
174
|
+
|
|
175
|
+
CallGraphBuilder callGraphBuilder;
|
|
176
|
+
callgraph = callGraphBuilder.buildSVFIRCallGraph(svfModule);
|
|
172
177
|
}
|
|
173
178
|
|
|
174
179
|
void LLVMModuleSet::createSVFDataStructure()
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
#include "SVFIR/SVFFileSystem.h"
|
|
39
39
|
#include "SVFIR/SVFModule.h"
|
|
40
40
|
#include "SVFIR/SVFValue.h"
|
|
41
|
+
#include "Util/CallGraphBuilder.h"
|
|
41
42
|
#include "Util/Options.h"
|
|
42
43
|
#include "Util/SVFUtil.h"
|
|
43
44
|
|
|
@@ -62,6 +63,9 @@ SVFIR* SVFIRBuilder::build()
|
|
|
62
63
|
// Build ICFG
|
|
63
64
|
pag->setICFG(llvmModuleSet()->getICFG());
|
|
64
65
|
|
|
66
|
+
// Set callgraph
|
|
67
|
+
pag->setCallGraph(llvmModuleSet()->callgraph);
|
|
68
|
+
|
|
65
69
|
// Set icfgnode in memobj
|
|
66
70
|
for (auto& it : SymbolTableInfo::SymbolInfo()->idToObjMap())
|
|
67
71
|
{
|