svf-tools 1.0.975 → 1.0.976
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/AE/Svfexe/AbstractInterpretation.h +1 -1
- package/svf/include/DDA/ContextDDA.h +2 -2
- package/svf/include/DDA/DDAVFSolver.h +5 -5
- package/svf/include/DDA/FlowDDA.h +1 -1
- package/svf/include/Graphs/{PTACallGraph.h → CallGraph.h} +41 -41
- package/svf/include/Graphs/ICFG.h +2 -2
- package/svf/include/Graphs/ThreadCallGraph.h +24 -24
- package/svf/include/Graphs/VFG.h +4 -4
- package/svf/include/MSSA/MemRegion.h +4 -4
- package/svf/include/MTA/LockAnalysis.h +1 -1
- package/svf/include/MTA/MHP.h +2 -2
- package/svf/include/MTA/PCG.h +3 -3
- package/svf/include/MTA/TCT.h +7 -7
- package/svf/include/MemoryModel/PointerAnalysis.h +13 -13
- package/svf/include/SABER/SaberSVFGBuilder.h +1 -1
- package/svf/include/SABER/SrcSnkDDA.h +7 -7
- package/svf/include/Util/CallGraphBuilder.h +5 -5
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +1 -1
- package/svf/lib/CFL/CFLSVFGBuilder.cpp +1 -1
- package/svf/lib/DDA/ContextDDA.cpp +9 -9
- package/svf/lib/DDA/DDAClient.cpp +3 -3
- package/svf/lib/DDA/DDAPass.cpp +4 -4
- package/svf/lib/DDA/FlowDDA.cpp +2 -2
- package/svf/lib/Graphs/{PTACallGraph.cpp → CallGraph.cpp} +66 -66
- package/svf/lib/Graphs/ICFG.cpp +6 -6
- package/svf/lib/Graphs/SVFG.cpp +7 -7
- package/svf/lib/Graphs/SVFGReadWrite.cpp +6 -6
- package/svf/lib/Graphs/SVFGStat.cpp +1 -1
- package/svf/lib/Graphs/ThreadCallGraph.cpp +17 -17
- package/svf/lib/Graphs/VFG.cpp +1 -1
- package/svf/lib/MSSA/MemRegion.cpp +7 -7
- package/svf/lib/MTA/LockAnalysis.cpp +18 -18
- package/svf/lib/MTA/MHP.cpp +19 -19
- package/svf/lib/MTA/MTA.cpp +1 -1
- package/svf/lib/MTA/PCG.cpp +12 -12
- package/svf/lib/MTA/TCT.cpp +23 -23
- package/svf/lib/MemoryModel/PointerAnalysis.cpp +12 -12
- package/svf/lib/SABER/LeakChecker.cpp +4 -4
- package/svf/lib/SABER/SaberSVFGBuilder.cpp +4 -4
- package/svf/lib/SABER/SrcSnkDDA.cpp +1 -1
- package/svf/lib/Util/CallGraphBuilder.cpp +2 -2
- package/svf/lib/Util/PTAStat.cpp +7 -7
- package/svf/lib/WPA/VersionedFlowSensitive.cpp +2 -2
- package/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +1 -1
- package/svf-llvm/lib/SVFIRBuilder.cpp +5 -5
- package/svf-llvm/tools/AE/ae.cpp +1 -1
- package/svf-llvm/tools/Example/svf-ex.cpp +1 -1
- package/svf-llvm/tools/MTA/LockResultValidator.cpp +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//===-
|
|
1
|
+
//===- CallGraph.cpp -- Call graph used internally in SVF------------------//
|
|
2
2
|
//
|
|
3
3
|
// SVF: Static Value-Flow Analysis
|
|
4
4
|
//
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
/*
|
|
25
|
-
*
|
|
25
|
+
* CallGraph.cpp
|
|
26
26
|
*
|
|
27
27
|
* Created on: Nov 7, 2013
|
|
28
28
|
* Author: Yulei Sui
|
|
@@ -31,32 +31,32 @@
|
|
|
31
31
|
#include <sstream>
|
|
32
32
|
#include "SVFIR/SVFModule.h"
|
|
33
33
|
#include "Util/SVFUtil.h"
|
|
34
|
-
#include "Graphs/
|
|
34
|
+
#include "Graphs/CallGraph.h"
|
|
35
35
|
|
|
36
36
|
using namespace SVF;
|
|
37
37
|
using namespace SVFUtil;
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
CallSiteID
|
|
39
|
+
CallGraph::CallSiteToIdMap CallGraph::csToIdMap;
|
|
40
|
+
CallGraph::IdToCallSiteMap CallGraph::idToCSMap;
|
|
41
|
+
CallSiteID CallGraph::totalCallSiteNum = 1;
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
/// Add direct and indirect callsite
|
|
45
45
|
//@{
|
|
46
|
-
void
|
|
46
|
+
void CallGraphEdge::addDirectCallSite(const CallICFGNode* call)
|
|
47
47
|
{
|
|
48
48
|
assert(SVFUtil::getCallee(call->getCallSite()) && "not a direct callsite??");
|
|
49
49
|
directCalls.insert(call);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
void
|
|
52
|
+
void CallGraphEdge::addInDirectCallSite(const CallICFGNode* call)
|
|
53
53
|
{
|
|
54
54
|
assert((nullptr == SVFUtil::getCallee(call->getCallSite()) || nullptr == SVFUtil::dyn_cast<SVFFunction> (SVFUtil::getForkedFun(call->getCallSite()))) && "not an indirect callsite??");
|
|
55
55
|
indirectCalls.insert(call);
|
|
56
56
|
}
|
|
57
57
|
//@}
|
|
58
58
|
|
|
59
|
-
const std::string
|
|
59
|
+
const std::string CallGraphEdge::toString() const
|
|
60
60
|
{
|
|
61
61
|
std::string str;
|
|
62
62
|
std::stringstream rawstr(str);
|
|
@@ -69,7 +69,7 @@ const std::string PTACallGraphEdge::toString() const
|
|
|
69
69
|
return rawstr.str();
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
const std::string
|
|
72
|
+
const std::string CallGraphNode::toString() const
|
|
73
73
|
{
|
|
74
74
|
std::string str;
|
|
75
75
|
std::stringstream rawstr(str);
|
|
@@ -77,16 +77,16 @@ const std::string PTACallGraphNode::toString() const
|
|
|
77
77
|
return rawstr.str();
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
bool
|
|
80
|
+
bool CallGraphNode::isReachableFromProgEntry() const
|
|
81
81
|
{
|
|
82
|
-
std::stack<const
|
|
82
|
+
std::stack<const CallGraphNode*> nodeStack;
|
|
83
83
|
NodeBS visitedNodes;
|
|
84
84
|
nodeStack.push(this);
|
|
85
85
|
visitedNodes.set(getId());
|
|
86
86
|
|
|
87
87
|
while (nodeStack.empty() == false)
|
|
88
88
|
{
|
|
89
|
-
|
|
89
|
+
CallGraphNode* node = const_cast<CallGraphNode*>(nodeStack.top());
|
|
90
90
|
nodeStack.pop();
|
|
91
91
|
|
|
92
92
|
if (SVFUtil::isProgEntryFunction(node->getFunction()))
|
|
@@ -94,7 +94,7 @@ bool PTACallGraphNode::isReachableFromProgEntry() const
|
|
|
94
94
|
|
|
95
95
|
for (const_iterator it = node->InEdgeBegin(), eit = node->InEdgeEnd(); it != eit; ++it)
|
|
96
96
|
{
|
|
97
|
-
|
|
97
|
+
CallGraphEdge* edge = *it;
|
|
98
98
|
if (visitedNodes.test_and_set(edge->getSrcID()))
|
|
99
99
|
nodeStack.push(edge->getSrcNode());
|
|
100
100
|
}
|
|
@@ -105,7 +105,7 @@ bool PTACallGraphNode::isReachableFromProgEntry() const
|
|
|
105
105
|
|
|
106
106
|
|
|
107
107
|
/// Constructor
|
|
108
|
-
|
|
108
|
+
CallGraph::CallGraph(CGEK k): kind(k)
|
|
109
109
|
{
|
|
110
110
|
callGraphNodeNum = 0;
|
|
111
111
|
numOfResolvedIndCallEdge = 0;
|
|
@@ -114,17 +114,17 @@ PTACallGraph::PTACallGraph(CGEK k): kind(k)
|
|
|
114
114
|
/*!
|
|
115
115
|
* Memory has been cleaned up at GenericGraph
|
|
116
116
|
*/
|
|
117
|
-
void
|
|
117
|
+
void CallGraph::destroy()
|
|
118
118
|
{
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
/*!
|
|
122
122
|
* Add call graph node
|
|
123
123
|
*/
|
|
124
|
-
void
|
|
124
|
+
void CallGraph::addCallGraphNode(const SVFFunction* fun)
|
|
125
125
|
{
|
|
126
126
|
NodeID id = callGraphNodeNum;
|
|
127
|
-
|
|
127
|
+
CallGraphNode* callGraphNode = new CallGraphNode(id, fun);
|
|
128
128
|
addGNode(id,callGraphNode);
|
|
129
129
|
funToCallGraphNodeMap[fun] = callGraphNode;
|
|
130
130
|
callGraphNodeNum++;
|
|
@@ -133,11 +133,11 @@ void PTACallGraph::addCallGraphNode(const SVFFunction* fun)
|
|
|
133
133
|
/*!
|
|
134
134
|
* Whether we have already created this call graph edge
|
|
135
135
|
*/
|
|
136
|
-
|
|
136
|
+
CallGraphEdge* CallGraph::hasGraphEdge(CallGraphNode* src, CallGraphNode* dst,CallGraphEdge::CEDGEK kind, CallSiteID csId) const
|
|
137
137
|
{
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
CallGraphEdge edge(src,dst,kind,csId);
|
|
139
|
+
CallGraphEdge* outEdge = src->hasOutgoingEdge(&edge);
|
|
140
|
+
CallGraphEdge* inEdge = dst->hasIncomingEdge(&edge);
|
|
141
141
|
if (outEdge && inEdge)
|
|
142
142
|
{
|
|
143
143
|
assert(outEdge == inEdge && "edges not match");
|
|
@@ -150,12 +150,12 @@ PTACallGraphEdge* PTACallGraph::hasGraphEdge(PTACallGraphNode* src, PTACallGraph
|
|
|
150
150
|
/*!
|
|
151
151
|
* get CallGraph edge via nodes
|
|
152
152
|
*/
|
|
153
|
-
|
|
153
|
+
CallGraphEdge* CallGraph::getGraphEdge(CallGraphNode* src, CallGraphNode* dst,CallGraphEdge::CEDGEK kind, CallSiteID)
|
|
154
154
|
{
|
|
155
|
-
for (
|
|
155
|
+
for (CallGraphEdge::CallGraphEdgeSet::iterator iter = src->OutEdgeBegin();
|
|
156
156
|
iter != src->OutEdgeEnd(); ++iter)
|
|
157
157
|
{
|
|
158
|
-
|
|
158
|
+
CallGraphEdge* edge = (*iter);
|
|
159
159
|
if (edge->getEdgeKind() == kind && edge->getDstID() == dst->getId())
|
|
160
160
|
return edge;
|
|
161
161
|
}
|
|
@@ -165,17 +165,17 @@ PTACallGraphEdge* PTACallGraph::getGraphEdge(PTACallGraphNode* src, PTACallGraph
|
|
|
165
165
|
/*!
|
|
166
166
|
* Add direct call edges
|
|
167
167
|
*/
|
|
168
|
-
void
|
|
168
|
+
void CallGraph::addDirectCallGraphEdge(const CallICFGNode* cs,const SVFFunction* callerFun, const SVFFunction* calleeFun)
|
|
169
169
|
{
|
|
170
170
|
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
CallGraphNode* caller = getCallGraphNode(callerFun);
|
|
172
|
+
CallGraphNode* callee = getCallGraphNode(calleeFun);
|
|
173
173
|
|
|
174
174
|
CallSiteID csId = addCallSite(cs, callee->getFunction());
|
|
175
175
|
|
|
176
|
-
if(!hasGraphEdge(caller,callee,
|
|
176
|
+
if(!hasGraphEdge(caller,callee, CallGraphEdge::CallRetEdge,csId))
|
|
177
177
|
{
|
|
178
|
-
|
|
178
|
+
CallGraphEdge* edge = new CallGraphEdge(caller,callee,CallGraphEdge::CallRetEdge,csId);
|
|
179
179
|
edge->addDirectCallSite(cs);
|
|
180
180
|
addEdge(edge);
|
|
181
181
|
callinstToCallGraphEdgesMap[cs].insert(edge);
|
|
@@ -185,19 +185,19 @@ void PTACallGraph::addDirectCallGraphEdge(const CallICFGNode* cs,const SVFFuncti
|
|
|
185
185
|
/*!
|
|
186
186
|
* Add indirect call edge to update call graph
|
|
187
187
|
*/
|
|
188
|
-
void
|
|
188
|
+
void CallGraph::addIndirectCallGraphEdge(const CallICFGNode* cs,const SVFFunction* callerFun, const SVFFunction* calleeFun)
|
|
189
189
|
{
|
|
190
190
|
|
|
191
|
-
|
|
192
|
-
|
|
191
|
+
CallGraphNode* caller = getCallGraphNode(callerFun);
|
|
192
|
+
CallGraphNode* callee = getCallGraphNode(calleeFun);
|
|
193
193
|
|
|
194
194
|
numOfResolvedIndCallEdge++;
|
|
195
195
|
|
|
196
196
|
CallSiteID csId = addCallSite(cs, callee->getFunction());
|
|
197
197
|
|
|
198
|
-
if(!hasGraphEdge(caller,callee,
|
|
198
|
+
if(!hasGraphEdge(caller,callee, CallGraphEdge::CallRetEdge,csId))
|
|
199
199
|
{
|
|
200
|
-
|
|
200
|
+
CallGraphEdge* edge = new CallGraphEdge(caller,callee,CallGraphEdge::CallRetEdge, csId);
|
|
201
201
|
edge->addInDirectCallSite(cs);
|
|
202
202
|
addEdge(edge);
|
|
203
203
|
callinstToCallGraphEdgesMap[cs].insert(edge);
|
|
@@ -207,18 +207,18 @@ void PTACallGraph::addIndirectCallGraphEdge(const CallICFGNode* cs,const SVFFunc
|
|
|
207
207
|
/*!
|
|
208
208
|
* Get all callsite invoking this callee
|
|
209
209
|
*/
|
|
210
|
-
void
|
|
210
|
+
void CallGraph::getAllCallSitesInvokingCallee(const SVFFunction* callee, CallGraphEdge::CallInstSet& csSet)
|
|
211
211
|
{
|
|
212
|
-
|
|
213
|
-
for(
|
|
212
|
+
CallGraphNode* callGraphNode = getCallGraphNode(callee);
|
|
213
|
+
for(CallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd();
|
|
214
214
|
it!=eit; ++it)
|
|
215
215
|
{
|
|
216
|
-
for(
|
|
216
|
+
for(CallGraphEdge::CallInstSet::const_iterator cit = (*it)->directCallsBegin(),
|
|
217
217
|
ecit = (*it)->directCallsEnd(); cit!=ecit; ++cit)
|
|
218
218
|
{
|
|
219
219
|
csSet.insert((*cit));
|
|
220
220
|
}
|
|
221
|
-
for(
|
|
221
|
+
for(CallGraphEdge::CallInstSet::const_iterator cit = (*it)->indirectCallsBegin(),
|
|
222
222
|
ecit = (*it)->indirectCallsEnd(); cit!=ecit; ++cit)
|
|
223
223
|
{
|
|
224
224
|
csSet.insert((*cit));
|
|
@@ -229,13 +229,13 @@ void PTACallGraph::getAllCallSitesInvokingCallee(const SVFFunction* callee, PTAC
|
|
|
229
229
|
/*!
|
|
230
230
|
* Get direct callsite invoking this callee
|
|
231
231
|
*/
|
|
232
|
-
void
|
|
232
|
+
void CallGraph::getDirCallSitesInvokingCallee(const SVFFunction* callee, CallGraphEdge::CallInstSet& csSet)
|
|
233
233
|
{
|
|
234
|
-
|
|
235
|
-
for(
|
|
234
|
+
CallGraphNode* callGraphNode = getCallGraphNode(callee);
|
|
235
|
+
for(CallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd();
|
|
236
236
|
it!=eit; ++it)
|
|
237
237
|
{
|
|
238
|
-
for(
|
|
238
|
+
for(CallGraphEdge::CallInstSet::const_iterator cit = (*it)->directCallsBegin(),
|
|
239
239
|
ecit = (*it)->directCallsEnd(); cit!=ecit; ++cit)
|
|
240
240
|
{
|
|
241
241
|
csSet.insert((*cit));
|
|
@@ -246,13 +246,13 @@ void PTACallGraph::getDirCallSitesInvokingCallee(const SVFFunction* callee, PTAC
|
|
|
246
246
|
/*!
|
|
247
247
|
* Get indirect callsite invoking this callee
|
|
248
248
|
*/
|
|
249
|
-
void
|
|
249
|
+
void CallGraph::getIndCallSitesInvokingCallee(const SVFFunction* callee, CallGraphEdge::CallInstSet& csSet)
|
|
250
250
|
{
|
|
251
|
-
|
|
252
|
-
for(
|
|
251
|
+
CallGraphNode* callGraphNode = getCallGraphNode(callee);
|
|
252
|
+
for(CallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd();
|
|
253
253
|
it!=eit; ++it)
|
|
254
254
|
{
|
|
255
|
-
for(
|
|
255
|
+
for(CallGraphEdge::CallInstSet::const_iterator cit = (*it)->indirectCallsBegin(),
|
|
256
256
|
ecit = (*it)->indirectCallsEnd(); cit!=ecit; ++cit)
|
|
257
257
|
{
|
|
258
258
|
csSet.insert((*cit));
|
|
@@ -263,7 +263,7 @@ void PTACallGraph::getIndCallSitesInvokingCallee(const SVFFunction* callee, PTAC
|
|
|
263
263
|
/*!
|
|
264
264
|
* Issue a warning if the function which has indirect call sites can not be reached from program entry.
|
|
265
265
|
*/
|
|
266
|
-
void
|
|
266
|
+
void CallGraph::verifyCallGraph()
|
|
267
267
|
{
|
|
268
268
|
CallEdgeMap::const_iterator it = indirectCallMap.begin();
|
|
269
269
|
CallEdgeMap::const_iterator eit = indirectCallMap.end();
|
|
@@ -283,18 +283,18 @@ void PTACallGraph::verifyCallGraph()
|
|
|
283
283
|
/*!
|
|
284
284
|
* Whether its reachable between two functions
|
|
285
285
|
*/
|
|
286
|
-
bool
|
|
286
|
+
bool CallGraph::isReachableBetweenFunctions(const SVFFunction* srcFn, const SVFFunction* dstFn) const
|
|
287
287
|
{
|
|
288
|
-
|
|
288
|
+
CallGraphNode* dstNode = getCallGraphNode(dstFn);
|
|
289
289
|
|
|
290
|
-
std::stack<const
|
|
290
|
+
std::stack<const CallGraphNode*> nodeStack;
|
|
291
291
|
NodeBS visitedNodes;
|
|
292
292
|
nodeStack.push(dstNode);
|
|
293
293
|
visitedNodes.set(dstNode->getId());
|
|
294
294
|
|
|
295
295
|
while (nodeStack.empty() == false)
|
|
296
296
|
{
|
|
297
|
-
|
|
297
|
+
CallGraphNode* node = const_cast<CallGraphNode*>(nodeStack.top());
|
|
298
298
|
nodeStack.pop();
|
|
299
299
|
|
|
300
300
|
if (node->getFunction() == srcFn)
|
|
@@ -302,7 +302,7 @@ bool PTACallGraph::isReachableBetweenFunctions(const SVFFunction* srcFn, const S
|
|
|
302
302
|
|
|
303
303
|
for (CallGraphEdgeConstIter it = node->InEdgeBegin(), eit = node->InEdgeEnd(); it != eit; ++it)
|
|
304
304
|
{
|
|
305
|
-
|
|
305
|
+
CallGraphEdge* edge = *it;
|
|
306
306
|
if (visitedNodes.test_and_set(edge->getSrcID()))
|
|
307
307
|
nodeStack.push(edge->getSrcNode());
|
|
308
308
|
}
|
|
@@ -314,12 +314,12 @@ bool PTACallGraph::isReachableBetweenFunctions(const SVFFunction* srcFn, const S
|
|
|
314
314
|
/*!
|
|
315
315
|
* Dump call graph into dot file
|
|
316
316
|
*/
|
|
317
|
-
void
|
|
317
|
+
void CallGraph::dump(const std::string& filename)
|
|
318
318
|
{
|
|
319
319
|
GraphPrinter::WriteGraphToFile(outs(), filename, this);
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
-
void
|
|
322
|
+
void CallGraph::view()
|
|
323
323
|
{
|
|
324
324
|
SVF::ViewGraph(this, "Call Graph");
|
|
325
325
|
}
|
|
@@ -331,10 +331,10 @@ namespace SVF
|
|
|
331
331
|
* Write value flow graph into dot file for debugging
|
|
332
332
|
*/
|
|
333
333
|
template<>
|
|
334
|
-
struct DOTGraphTraits<
|
|
334
|
+
struct DOTGraphTraits<CallGraph*> : public DefaultDOTGraphTraits
|
|
335
335
|
{
|
|
336
336
|
|
|
337
|
-
typedef
|
|
337
|
+
typedef CallGraphNode NodeType;
|
|
338
338
|
typedef NodeType::iterator ChildIteratorType;
|
|
339
339
|
DOTGraphTraits(bool isSimple = false) :
|
|
340
340
|
DefaultDOTGraphTraits(isSimple)
|
|
@@ -342,17 +342,17 @@ struct DOTGraphTraits<PTACallGraph*> : public DefaultDOTGraphTraits
|
|
|
342
342
|
}
|
|
343
343
|
|
|
344
344
|
/// Return name of the graph
|
|
345
|
-
static std::string getGraphName(
|
|
345
|
+
static std::string getGraphName(CallGraph*)
|
|
346
346
|
{
|
|
347
347
|
return "Call Graph";
|
|
348
348
|
}
|
|
349
349
|
/// Return function name;
|
|
350
|
-
static std::string getNodeLabel(
|
|
350
|
+
static std::string getNodeLabel(CallGraphNode *node, CallGraph*)
|
|
351
351
|
{
|
|
352
352
|
return node->toString();
|
|
353
353
|
}
|
|
354
354
|
|
|
355
|
-
static std::string getNodeAttributes(
|
|
355
|
+
static std::string getNodeAttributes(CallGraphNode *node, CallGraph*)
|
|
356
356
|
{
|
|
357
357
|
const SVFFunction* fun = node->getFunction();
|
|
358
358
|
if (!SVFUtil::isExtCall(fun))
|
|
@@ -364,20 +364,20 @@ struct DOTGraphTraits<PTACallGraph*> : public DefaultDOTGraphTraits
|
|
|
364
364
|
}
|
|
365
365
|
|
|
366
366
|
template<class EdgeIter>
|
|
367
|
-
static std::string getEdgeAttributes(
|
|
367
|
+
static std::string getEdgeAttributes(CallGraphNode*, EdgeIter EI, CallGraph*)
|
|
368
368
|
{
|
|
369
369
|
|
|
370
370
|
//TODO: mark indirect call of Fork with different color
|
|
371
|
-
|
|
371
|
+
CallGraphEdge* edge = *(EI.getCurrent());
|
|
372
372
|
assert(edge && "No edge found!!");
|
|
373
373
|
|
|
374
374
|
std::string color;
|
|
375
375
|
|
|
376
|
-
if (edge->getEdgeKind() ==
|
|
376
|
+
if (edge->getEdgeKind() == CallGraphEdge::TDJoinEdge)
|
|
377
377
|
{
|
|
378
378
|
color = "color=green";
|
|
379
379
|
}
|
|
380
|
-
else if (edge->getEdgeKind() ==
|
|
380
|
+
else if (edge->getEdgeKind() == CallGraphEdge::TDForkEdge)
|
|
381
381
|
{
|
|
382
382
|
color = "color=blue";
|
|
383
383
|
}
|
|
@@ -395,7 +395,7 @@ struct DOTGraphTraits<PTACallGraph*> : public DefaultDOTGraphTraits
|
|
|
395
395
|
template<class EdgeIter>
|
|
396
396
|
static std::string getEdgeSourceLabel(NodeType*, EdgeIter EI)
|
|
397
397
|
{
|
|
398
|
-
|
|
398
|
+
CallGraphEdge* edge = *(EI.getCurrent());
|
|
399
399
|
assert(edge && "No edge found!!");
|
|
400
400
|
|
|
401
401
|
std::string str;
|
package/svf/lib/Graphs/ICFG.cpp
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
#include "SVFIR/SVFModule.h"
|
|
32
32
|
#include "Graphs/ICFG.h"
|
|
33
33
|
#include "SVFIR/SVFIR.h"
|
|
34
|
-
#include "Graphs/
|
|
34
|
+
#include "Graphs/CallGraph.h"
|
|
35
35
|
|
|
36
36
|
using namespace SVF;
|
|
37
37
|
using namespace SVFUtil;
|
|
@@ -460,17 +460,17 @@ void ICFG::view()
|
|
|
460
460
|
/*!
|
|
461
461
|
* Update ICFG for indirect calls
|
|
462
462
|
*/
|
|
463
|
-
void ICFG::updateCallGraph(
|
|
463
|
+
void ICFG::updateCallGraph(CallGraph* callgraph)
|
|
464
464
|
{
|
|
465
|
-
|
|
466
|
-
|
|
465
|
+
CallGraph::CallEdgeMap::const_iterator iter = callgraph->getIndCallMap().begin();
|
|
466
|
+
CallGraph::CallEdgeMap::const_iterator eiter = callgraph->getIndCallMap().end();
|
|
467
467
|
for (; iter != eiter; iter++)
|
|
468
468
|
{
|
|
469
469
|
const CallICFGNode* callBlock = iter->first;
|
|
470
470
|
const SVFInstruction* cs = callBlock->getCallSite();
|
|
471
471
|
assert(callBlock->isIndirectCall() && "this is not an indirect call?");
|
|
472
|
-
const
|
|
473
|
-
for (
|
|
472
|
+
const CallGraph::FunctionSet & functions = iter->second;
|
|
473
|
+
for (CallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
|
|
474
474
|
{
|
|
475
475
|
const SVFFunction* callee = *func_iter;
|
|
476
476
|
CallICFGNode* callBlockNode = getCallICFGNode(cs);
|
package/svf/lib/Graphs/SVFG.cpp
CHANGED
|
@@ -197,7 +197,7 @@ FormalOUTSVFGNode::FormalOUTSVFGNode(NodeID id, const MRVer* mrVer, const FunExi
|
|
|
197
197
|
/*!
|
|
198
198
|
* Constructor
|
|
199
199
|
*/
|
|
200
|
-
SVFG::SVFG(std::unique_ptr<MemSSA> mssa, VFGK k): VFG(mssa->getPTA()->
|
|
200
|
+
SVFG::SVFG(std::unique_ptr<MemSSA> mssa, VFGK k): VFG(mssa->getPTA()->getCallGraph(),k),mssa(std::move(mssa)), pta(this->mssa->getPTA())
|
|
201
201
|
{
|
|
202
202
|
stat = new SVFGStat(this);
|
|
203
203
|
}
|
|
@@ -356,9 +356,9 @@ void SVFG::connectIndirectSVFGEdges()
|
|
|
356
356
|
}
|
|
357
357
|
else if(const FormalINSVFGNode* formalIn = SVFUtil::dyn_cast<FormalINSVFGNode>(node))
|
|
358
358
|
{
|
|
359
|
-
|
|
360
|
-
mssa->getPTA()->
|
|
361
|
-
for(
|
|
359
|
+
CallGraphEdge::CallInstSet callInstSet;
|
|
360
|
+
mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalIn->getFun(),callInstSet);
|
|
361
|
+
for(CallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it!=eit; ++it)
|
|
362
362
|
{
|
|
363
363
|
const CallICFGNode* cs = *it;
|
|
364
364
|
if(!mssa->hasMU(cs))
|
|
@@ -373,10 +373,10 @@ void SVFG::connectIndirectSVFGEdges()
|
|
|
373
373
|
}
|
|
374
374
|
else if(const FormalOUTSVFGNode* formalOut = SVFUtil::dyn_cast<FormalOUTSVFGNode>(node))
|
|
375
375
|
{
|
|
376
|
-
|
|
376
|
+
CallGraphEdge::CallInstSet callInstSet;
|
|
377
377
|
// const MemSSA::RETMU* retMu = formalOut->getRetMU();
|
|
378
|
-
mssa->getPTA()->
|
|
379
|
-
for(
|
|
378
|
+
mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalOut->getFun(),callInstSet);
|
|
379
|
+
for(CallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it!=eit; ++it)
|
|
380
380
|
{
|
|
381
381
|
const CallICFGNode* cs = *it;
|
|
382
382
|
if(!mssa->hasCHI(cs))
|
|
@@ -144,9 +144,9 @@ void SVFG::writeToFile(const string& filename)
|
|
|
144
144
|
}
|
|
145
145
|
else if(const FormalINSVFGNode* formalIn = SVFUtil::dyn_cast<FormalINSVFGNode>(node))
|
|
146
146
|
{
|
|
147
|
-
|
|
148
|
-
mssa->getPTA()->
|
|
149
|
-
for(
|
|
147
|
+
CallGraphEdge::CallInstSet callInstSet;
|
|
148
|
+
mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalIn->getFun(),callInstSet);
|
|
149
|
+
for(CallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it!=eit; ++it)
|
|
150
150
|
{
|
|
151
151
|
const CallICFGNode* cs = *it;
|
|
152
152
|
if(!mssa->hasMU(cs))
|
|
@@ -161,9 +161,9 @@ void SVFG::writeToFile(const string& filename)
|
|
|
161
161
|
}
|
|
162
162
|
else if(const FormalOUTSVFGNode* formalOut = SVFUtil::dyn_cast<FormalOUTSVFGNode>(node))
|
|
163
163
|
{
|
|
164
|
-
|
|
165
|
-
mssa->getPTA()->
|
|
166
|
-
for(
|
|
164
|
+
CallGraphEdge::CallInstSet callInstSet;
|
|
165
|
+
mssa->getPTA()->getCallGraph()->getDirCallSitesInvokingCallee(formalOut->getFun(),callInstSet);
|
|
166
|
+
for(CallGraphEdge::CallInstSet::iterator it = callInstSet.begin(), eit = callInstSet.end(); it!=eit; ++it)
|
|
167
167
|
{
|
|
168
168
|
const CallICFGNode* cs = *it;
|
|
169
169
|
if(!mssa->hasCHI(cs))
|
|
@@ -38,7 +38,7 @@ using namespace SVFUtil;
|
|
|
38
38
|
* Constructor
|
|
39
39
|
*/
|
|
40
40
|
ThreadCallGraph::ThreadCallGraph() :
|
|
41
|
-
|
|
41
|
+
CallGraph(ThdCallGraph), tdAPI(ThreadAPI::getThreadAPI())
|
|
42
42
|
{
|
|
43
43
|
DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("Building ThreadCallGraph\n"));
|
|
44
44
|
}
|
|
@@ -58,8 +58,8 @@ void ThreadCallGraph::updateCallGraph(PointerAnalysis* pta)
|
|
|
58
58
|
for (; iter != eiter; iter++)
|
|
59
59
|
{
|
|
60
60
|
const CallICFGNode* cs = iter->first;
|
|
61
|
-
const
|
|
62
|
-
for (
|
|
61
|
+
const CallGraph::FunctionSet &functions = iter->second;
|
|
62
|
+
for (CallGraph::FunctionSet::const_iterator func_iter =
|
|
63
63
|
functions.begin(); func_iter != functions.end(); func_iter++)
|
|
64
64
|
{
|
|
65
65
|
const SVFFunction* callee = *func_iter;
|
|
@@ -145,13 +145,13 @@ void ThreadCallGraph::updateJoinEdge(PointerAnalysis* pta)
|
|
|
145
145
|
void ThreadCallGraph::addDirectForkEdge(const CallICFGNode* cs)
|
|
146
146
|
{
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
CallGraphNode* caller = getCallGraphNode(cs->getCaller());
|
|
149
149
|
const SVFFunction* forkee = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getForkedFun(cs->getCallSite()));
|
|
150
150
|
assert(forkee && "callee does not exist");
|
|
151
|
-
|
|
151
|
+
CallGraphNode* callee = getCallGraphNode(forkee->getDefFunForMultipleModule());
|
|
152
152
|
CallSiteID csId = addCallSite(cs, callee->getFunction());
|
|
153
153
|
|
|
154
|
-
if (!hasGraphEdge(caller, callee,
|
|
154
|
+
if (!hasGraphEdge(caller, callee, CallGraphEdge::TDForkEdge, csId))
|
|
155
155
|
{
|
|
156
156
|
assert(cs->getCaller() == caller->getFunction() && "callee instruction not inside caller??");
|
|
157
157
|
|
|
@@ -168,12 +168,12 @@ void ThreadCallGraph::addDirectForkEdge(const CallICFGNode* cs)
|
|
|
168
168
|
*/
|
|
169
169
|
void ThreadCallGraph::addIndirectForkEdge(const CallICFGNode* cs, const SVFFunction* calleefun)
|
|
170
170
|
{
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
CallGraphNode* caller = getCallGraphNode(cs->getCaller());
|
|
172
|
+
CallGraphNode* callee = getCallGraphNode(calleefun);
|
|
173
173
|
|
|
174
174
|
CallSiteID csId = addCallSite(cs, callee->getFunction());
|
|
175
175
|
|
|
176
|
-
if (!hasGraphEdge(caller, callee,
|
|
176
|
+
if (!hasGraphEdge(caller, callee, CallGraphEdge::TDForkEdge, csId))
|
|
177
177
|
{
|
|
178
178
|
assert(cs->getCaller() == caller->getFunction() && "callee instruction not inside caller??");
|
|
179
179
|
|
|
@@ -194,14 +194,14 @@ void ThreadCallGraph::addIndirectForkEdge(const CallICFGNode* cs, const SVFFunct
|
|
|
194
194
|
void ThreadCallGraph::addDirectJoinEdge(const CallICFGNode* cs,const CallSiteSet& forkset)
|
|
195
195
|
{
|
|
196
196
|
|
|
197
|
-
|
|
197
|
+
CallGraphNode* joinFunNode = getCallGraphNode(cs->getCaller());
|
|
198
198
|
|
|
199
199
|
for (CallSiteSet::const_iterator it = forkset.begin(), eit = forkset.end(); it != eit; ++it)
|
|
200
200
|
{
|
|
201
201
|
|
|
202
202
|
const SVFFunction* threadRoutineFun = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getForkedFun((*it)->getCallSite()));
|
|
203
203
|
assert(threadRoutineFun && "thread routine function does not exist");
|
|
204
|
-
|
|
204
|
+
CallGraphNode* threadRoutineFunNode = getCallGraphNode(threadRoutineFun);
|
|
205
205
|
CallSiteID csId = addCallSite(cs, threadRoutineFun);
|
|
206
206
|
|
|
207
207
|
if (!hasThreadJoinEdge(cs,joinFunNode,threadRoutineFunNode, csId))
|
|
@@ -221,15 +221,15 @@ void ThreadCallGraph::addDirectJoinEdge(const CallICFGNode* cs,const CallSiteSet
|
|
|
221
221
|
void ThreadCallGraph::addDirectParForEdge(const CallICFGNode* cs)
|
|
222
222
|
{
|
|
223
223
|
|
|
224
|
-
|
|
224
|
+
CallGraphNode* caller = getCallGraphNode(cs->getCaller());
|
|
225
225
|
const SVFFunction* taskFunc = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getTaskFuncAtHareParForSite(cs->getCallSite()));
|
|
226
226
|
assert(taskFunc && "callee does not exist");
|
|
227
227
|
|
|
228
|
-
|
|
228
|
+
CallGraphNode* callee = getCallGraphNode(taskFunc);
|
|
229
229
|
|
|
230
230
|
CallSiteID csId = addCallSite(cs, callee->getFunction());
|
|
231
231
|
|
|
232
|
-
if (!hasGraphEdge(caller, callee,
|
|
232
|
+
if (!hasGraphEdge(caller, callee, CallGraphEdge::TDForkEdge, csId))
|
|
233
233
|
{
|
|
234
234
|
assert(cs->getCaller() == caller->getFunction() && "callee instruction not inside caller??");
|
|
235
235
|
|
|
@@ -247,12 +247,12 @@ void ThreadCallGraph::addDirectParForEdge(const CallICFGNode* cs)
|
|
|
247
247
|
void ThreadCallGraph::addIndirectParForEdge(const CallICFGNode* cs, const SVFFunction* calleefun)
|
|
248
248
|
{
|
|
249
249
|
|
|
250
|
-
|
|
251
|
-
|
|
250
|
+
CallGraphNode* caller = getCallGraphNode(cs->getCaller());
|
|
251
|
+
CallGraphNode* callee = getCallGraphNode(calleefun);
|
|
252
252
|
|
|
253
253
|
CallSiteID csId = addCallSite(cs, callee->getFunction());
|
|
254
254
|
|
|
255
|
-
if (!hasGraphEdge(caller, callee,
|
|
255
|
+
if (!hasGraphEdge(caller, callee, CallGraphEdge::HareParForEdge,csId))
|
|
256
256
|
{
|
|
257
257
|
assert(cs->getCaller() == caller->getFunction() && "callee instruction not inside caller??");
|
|
258
258
|
|
package/svf/lib/Graphs/VFG.cpp
CHANGED
|
@@ -438,7 +438,7 @@ PHIVFGNode::PHIVFGNode(NodeID id, const PAGNode* r,VFGNodeK k): VFGNode(id, k),
|
|
|
438
438
|
* 2) connect VFG edges
|
|
439
439
|
* between two statements (PAGEdges)
|
|
440
440
|
*/
|
|
441
|
-
VFG::VFG(
|
|
441
|
+
VFG::VFG(CallGraph* cg, VFGK k): totalVFGNode(0), callgraph(cg), pag(SVFIR::getPAG()), kind(k)
|
|
442
442
|
{
|
|
443
443
|
|
|
444
444
|
DBOUT(DGENERAL, outs() << pasMsg("\tCreate VFG Top Level Node\n"));
|
|
@@ -41,7 +41,7 @@ u32_t MRVer::totalVERNum = 0;
|
|
|
41
41
|
MRGenerator::MRGenerator(BVDataPTAImpl* p, bool ptrOnly) :
|
|
42
42
|
pta(p), ptrOnlyMSSA(ptrOnly)
|
|
43
43
|
{
|
|
44
|
-
callGraph = pta->
|
|
44
|
+
callGraph = pta->getCallGraph();
|
|
45
45
|
callGraphSCC = new SCC(callGraph);
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -248,7 +248,7 @@ void MRGenerator::collectModRefForCall()
|
|
|
248
248
|
const NodeBS& subNodes = callGraphSCC->subNodes(callGraphNodeID);
|
|
249
249
|
for(NodeBS::iterator it = subNodes.begin(), eit = subNodes.end(); it!=eit; ++it)
|
|
250
250
|
{
|
|
251
|
-
|
|
251
|
+
CallGraphNode* subCallGraphNode = callGraph->getCallGraphNode(*it);
|
|
252
252
|
/// Get mod-ref of all callsites calling callGraphNode
|
|
253
253
|
modRefAnalysis(subCallGraphNode,worklist);
|
|
254
254
|
}
|
|
@@ -630,17 +630,17 @@ bool MRGenerator::handleCallsiteModRef(NodeBS& mod, NodeBS& ref, const CallICFGN
|
|
|
630
630
|
* Call site mod-ref analysis
|
|
631
631
|
* Compute mod-ref of all callsites invoking this call graph node
|
|
632
632
|
*/
|
|
633
|
-
void MRGenerator::modRefAnalysis(
|
|
633
|
+
void MRGenerator::modRefAnalysis(CallGraphNode* callGraphNode, WorkList& worklist)
|
|
634
634
|
{
|
|
635
635
|
|
|
636
636
|
/// add ref/mod set of callee to its invocation callsites at caller
|
|
637
|
-
for(
|
|
637
|
+
for(CallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd();
|
|
638
638
|
it!=eit; ++it)
|
|
639
639
|
{
|
|
640
|
-
|
|
640
|
+
CallGraphEdge* edge = *it;
|
|
641
641
|
|
|
642
642
|
/// handle direct callsites
|
|
643
|
-
for(
|
|
643
|
+
for(CallGraphEdge::CallInstSet::iterator cit = edge->getDirectCalls().begin(),
|
|
644
644
|
ecit = edge->getDirectCalls().end(); cit!=ecit; ++cit)
|
|
645
645
|
{
|
|
646
646
|
NodeBS mod, ref;
|
|
@@ -650,7 +650,7 @@ void MRGenerator::modRefAnalysis(PTACallGraphNode* callGraphNode, WorkList& work
|
|
|
650
650
|
worklist.push(edge->getSrcID());
|
|
651
651
|
}
|
|
652
652
|
/// handle indirect callsites
|
|
653
|
-
for(
|
|
653
|
+
for(CallGraphEdge::CallInstSet::iterator cit = edge->getIndirectCalls().begin(),
|
|
654
654
|
ecit = edge->getIndirectCalls().end(); cit!=ecit; ++cit)
|
|
655
655
|
{
|
|
656
656
|
NodeBS mod, ref;
|