svf-tools 1.0.977 → 1.0.978
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 -30
- package/svf/include/Graphs/VFG.h +4 -4
- package/svf/include/MSSA/MemRegion.h +4 -4
- package/svf/include/MTA/LockAnalysis.h +42 -32
- package/svf/include/MTA/MHP.h +34 -54
- package/svf/include/MTA/MTAStat.h +1 -2
- package/svf/include/MTA/TCT.h +43 -25
- 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/include/Util/CxtStmt.h +13 -12
- package/svf/include/Util/Options.h +1 -20
- package/svf/include/Util/SVFUtil.h +8 -43
- package/svf/include/Util/ThreadAPI.h +42 -85
- 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 +12 -84
- package/svf/lib/Graphs/VFG.cpp +1 -1
- package/svf/lib/MSSA/MemRegion.cpp +7 -7
- package/svf/lib/MTA/LockAnalysis.cpp +100 -92
- package/svf/lib/MTA/MHP.cpp +159 -138
- package/svf/lib/MTA/MTA.cpp +3 -41
- package/svf/lib/MTA/MTAStat.cpp +7 -33
- package/svf/lib/MTA/TCT.cpp +52 -52
- 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 -17
- package/svf/lib/Util/Options.cpp +0 -62
- package/svf/lib/Util/PTAStat.cpp +7 -7
- package/svf/lib/Util/ThreadAPI.cpp +27 -6
- 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/lib/SVFIRExtAPI.cpp +0 -26
- package/svf-llvm/tools/AE/ae.cpp +1 -1
- package/svf-llvm/tools/Example/svf-ex.cpp +1 -1
- package/svf-llvm/tools/MTA/CMakeLists.txt +1 -1
- package/svf-llvm/tools/MTA/mta.cpp +0 -8
- package/svf/include/MTA/FSMPTA.h +0 -270
- package/svf/include/MTA/MTAResultValidator.h +0 -448
- package/svf/include/MTA/PCG.h +0 -229
- package/svf/lib/MTA/FSMPTA.cpp +0 -792
- package/svf/lib/MTA/PCG.cpp +0 -364
- package/svf-llvm/tools/MTA/LockResultValidator.cpp +0 -251
- package/svf-llvm/tools/MTA/LockResultValidator.h +0 -84
- package/svf-llvm/tools/MTA/MTAAnnotator.cpp +0 -293
- package/svf-llvm/tools/MTA/MTAAnnotator.h +0 -120
- package/svf-llvm/tools/MTA/MTAResultValidator.cpp +0 -716
- package/svf-llvm/tools/MTA/MTAResultValidator.h +0 -337
package/svf/lib/MTA/MTA.cpp
CHANGED
|
@@ -35,7 +35,6 @@
|
|
|
35
35
|
#include "MTA/LockAnalysis.h"
|
|
36
36
|
#include "MTA/MTAStat.h"
|
|
37
37
|
#include "WPA/Andersen.h"
|
|
38
|
-
#include "MTA/FSMPTA.h"
|
|
39
38
|
#include "Util/SVFUtil.h"
|
|
40
39
|
|
|
41
40
|
using namespace SVF;
|
|
@@ -66,43 +65,6 @@ bool MTA::runOnModule(SVFIR* pag)
|
|
|
66
65
|
|
|
67
66
|
if(Options::RaceCheck())
|
|
68
67
|
detect(pag->getModule());
|
|
69
|
-
/*
|
|
70
|
-
if (Options::AndersenAnno()) {
|
|
71
|
-
pta = mhp->getTCT()->getPTA();
|
|
72
|
-
if (pta->printStat())
|
|
73
|
-
stat->performMHPPairStat(mhp,lsa);
|
|
74
|
-
AndersenWaveDiff::releaseAndersenWaveDiff();
|
|
75
|
-
} else if (Options::FSAnno()) {
|
|
76
|
-
|
|
77
|
-
reportMemoryUsageKB("Mem before analysis");
|
|
78
|
-
DBOUT(DGENERAL, outs() << pasMsg("FSMPTA analysis\n"));
|
|
79
|
-
DBOUT(DMTA, outs() << pasMsg("FSMPTA analysis\n"));
|
|
80
|
-
|
|
81
|
-
DOTIMESTAT(double ptStart = stat->getClk());
|
|
82
|
-
pta = FSMPTA::createFSMPTA(module, mhp,lsa);
|
|
83
|
-
DOTIMESTAT(double ptEnd = stat->getClk());
|
|
84
|
-
DOTIMESTAT(stat->FSMPTATime += (ptEnd - ptStart) / TIMEINTERVAL);
|
|
85
|
-
|
|
86
|
-
reportMemoryUsageKB("Mem after analysis");
|
|
87
|
-
|
|
88
|
-
if (pta->printStat())
|
|
89
|
-
stat->performMHPPairStat(mhp,lsa);
|
|
90
|
-
|
|
91
|
-
FSMPTA::releaseFSMPTA();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (DoInstrumentation) {
|
|
95
|
-
DBOUT(DGENERAL, outs() << pasMsg("ThreadSanitizer Instrumentation\n"));
|
|
96
|
-
DBOUT(DMTA, outs() << pasMsg("ThreadSanitizer Instrumentation\n"));
|
|
97
|
-
TSan tsan;
|
|
98
|
-
tsan.doInitialization(*pta->getModule());
|
|
99
|
-
for (Module::iterator it = pta->getModule()->begin(), eit = pta->getModule()->end(); it != eit; ++it) {
|
|
100
|
-
tsan.runOnFunction(*it);
|
|
101
|
-
}
|
|
102
|
-
if (pta->printStat())
|
|
103
|
-
PrintStatistics();
|
|
104
|
-
}
|
|
105
|
-
*/
|
|
106
68
|
|
|
107
69
|
return false;
|
|
108
70
|
}
|
|
@@ -124,7 +86,7 @@ MHP* MTA::computeMHP(SVFModule* module)
|
|
|
124
86
|
DBOUT(DMTA, outs() << pasMsg("MTA analysis\n"));
|
|
125
87
|
SVFIR* pag = PAG::getPAG();
|
|
126
88
|
PointerAnalysis* pta = AndersenWaveDiff::createAndersenWaveDiff(pag);
|
|
127
|
-
pta->
|
|
89
|
+
pta->getCallGraph()->dump("ptacg");
|
|
128
90
|
|
|
129
91
|
DBOUT(DGENERAL, outs() << pasMsg("Build TCT\n"));
|
|
130
92
|
DBOUT(DMTA, outs() << pasMsg("Build TCT\n"));
|
|
@@ -205,8 +167,8 @@ void MTA::detect(SVFModule* module)
|
|
|
205
167
|
const StoreStmt* store = *sit;
|
|
206
168
|
if(load->getInst()==nullptr || store->getInst()==nullptr)
|
|
207
169
|
continue;
|
|
208
|
-
if(mhp->mayHappenInParallelInst(load->
|
|
209
|
-
if(lsa->isProtectedByCommonLock(load->
|
|
170
|
+
if(mhp->mayHappenInParallelInst(load->getICFGNode(),store->getICFGNode()) && pta->alias(load->getRHSVarID(),store->getLHSVarID()))
|
|
171
|
+
if(lsa->isProtectedByCommonLock(load->getICFGNode(),store->getICFGNode()) == false)
|
|
210
172
|
outs() << SVFUtil::bugMsg1("race pair(") << " store: " << store->toString() << ", load: " << load->toString() << SVFUtil::bugMsg1(")") << "\n";
|
|
211
173
|
}
|
|
212
174
|
}
|
package/svf/lib/MTA/MTAStat.cpp
CHANGED
|
@@ -32,7 +32,6 @@
|
|
|
32
32
|
#include "MTA/TCT.h"
|
|
33
33
|
#include "MTA/MHP.h"
|
|
34
34
|
#include "MTA/LockAnalysis.h"
|
|
35
|
-
#include "MTA/FSMPTA.h"
|
|
36
35
|
#include "Graphs/ThreadCallGraph.h"
|
|
37
36
|
|
|
38
37
|
using namespace SVF;
|
|
@@ -115,8 +114,8 @@ void MTAStat::performMHPPairStat(MHP* mhp, LockAnalysis* lsa)
|
|
|
115
114
|
SVFIR* pag = SVFIR::getPAG();
|
|
116
115
|
if(Options::AllPairMHP())
|
|
117
116
|
{
|
|
118
|
-
Set<const
|
|
119
|
-
Set<const
|
|
117
|
+
Set<const ICFGNode*> instSet1;
|
|
118
|
+
Set<const ICFGNode*> instSet2;
|
|
120
119
|
SVFModule* mod = mhp->getTCT()->getSVFModule();
|
|
121
120
|
for (const SVFFunction* fun : mod->getFunctionSet())
|
|
122
121
|
{
|
|
@@ -134,12 +133,12 @@ void MTAStat::performMHPPairStat(MHP* mhp, LockAnalysis* lsa)
|
|
|
134
133
|
{
|
|
135
134
|
if(SVFUtil::isa<LoadStmt>(stmt))
|
|
136
135
|
{
|
|
137
|
-
instSet1.insert(
|
|
136
|
+
instSet1.insert(stmt->getICFGNode());
|
|
138
137
|
}
|
|
139
138
|
else if(SVFUtil::isa<StoreStmt>(stmt))
|
|
140
139
|
{
|
|
141
|
-
instSet1.insert(
|
|
142
|
-
instSet2.insert(
|
|
140
|
+
instSet1.insert(stmt->getICFGNode());
|
|
141
|
+
instSet2.insert(stmt->getICFGNode());
|
|
143
142
|
}
|
|
144
143
|
}
|
|
145
144
|
|
|
@@ -148,9 +147,9 @@ void MTAStat::performMHPPairStat(MHP* mhp, LockAnalysis* lsa)
|
|
|
148
147
|
}
|
|
149
148
|
|
|
150
149
|
|
|
151
|
-
for(Set<const
|
|
150
|
+
for(Set<const ICFGNode*>::const_iterator it1 = instSet1.begin(), eit1 = instSet1.end(); it1!=eit1; ++it1)
|
|
152
151
|
{
|
|
153
|
-
for(Set<const
|
|
152
|
+
for(Set<const ICFGNode*>::const_iterator it2 = instSet2.begin(), eit2 = instSet2.end(); it2!=eit2; ++it2)
|
|
154
153
|
{
|
|
155
154
|
mhp->mayHappenInParallel(*it1,*it2);
|
|
156
155
|
}
|
|
@@ -166,38 +165,13 @@ void MTAStat::performMHPPairStat(MHP* mhp, LockAnalysis* lsa)
|
|
|
166
165
|
PTNumStatMap["TotalLockQueries"] = lsa->numOfTotalQueries;
|
|
167
166
|
PTNumStatMap["NumOfLockedPairs"] = lsa->numOfLockedQueries;
|
|
168
167
|
PTNumStatMap["NumOfCxtLocks"] = lsa->getNumOfCxtLocks();
|
|
169
|
-
PTNumStatMap["NumOfNewSVFGEdges"] = MTASVFGBuilder::numOfNewSVFGEdges;
|
|
170
|
-
PTNumStatMap["NumOfRemovedEdges"] = MTASVFGBuilder::numOfRemovedSVFGEdges;
|
|
171
|
-
PTNumStatMap["NumOfRemovedPTS"] = MTASVFGBuilder::numOfRemovedPTS;
|
|
172
168
|
timeStatMap["InterlevAnaTime"] = mhp->interleavingTime;
|
|
173
169
|
timeStatMap["LockAnaTime"] = lsa->lockTime;
|
|
174
170
|
timeStatMap["InterlevQueryTime"] = mhp->interleavingQueriesTime;
|
|
175
171
|
timeStatMap["LockQueryTime"] = lsa->lockQueriesTime;
|
|
176
172
|
timeStatMap["MHPAnalysisTime"] = MHPTime;
|
|
177
|
-
timeStatMap["MFSPTATime"] = FSMPTATime;
|
|
178
173
|
|
|
179
174
|
SVFUtil::outs() << "\n****MHP Stmt Pairs Statistics****\n";
|
|
180
175
|
PTAStat::printStat();
|
|
181
176
|
}
|
|
182
177
|
|
|
183
|
-
// void MTAStat::performAnnotationStat(MTAAnnotator* anno)
|
|
184
|
-
// {
|
|
185
|
-
|
|
186
|
-
// PTNumStatMap.clear();
|
|
187
|
-
// timeStatMap.clear();
|
|
188
|
-
// PTNumStatMap["TotalNumOfStore"] = anno->numOfAllSt;
|
|
189
|
-
// PTNumStatMap["TotalNumOfLoad"] = anno->numOfAllLd;
|
|
190
|
-
// PTNumStatMap["NumOfNonLocalStore"] = anno->numOfNonLocalSt;
|
|
191
|
-
// PTNumStatMap["NumOfNonLocalLoad"] = anno->numOfNonLocalLd;
|
|
192
|
-
// PTNumStatMap["NumOfAliasStore"] = anno->numOfAliasSt;
|
|
193
|
-
// PTNumStatMap["NumOfAliasLoad"] = anno->numOfAliasLd;
|
|
194
|
-
// PTNumStatMap["NumOfMHPStore"] = anno->numOfMHPSt;
|
|
195
|
-
// PTNumStatMap["NumOfMHPLoad"] = anno->numOfMHPLd;
|
|
196
|
-
// PTNumStatMap["NumOfAnnotatedStore"] = anno->numOfAnnotatedSt;
|
|
197
|
-
// PTNumStatMap["NumOfAnnotatedLoad"] = anno->numOfAnnotatedLd;
|
|
198
|
-
// timeStatMap["AnnotationTime"] = AnnotationTime;
|
|
199
|
-
|
|
200
|
-
// SVFUtil::outs() << "\n****Annotation Statistics****\n";
|
|
201
|
-
// PTAStat::printStat();
|
|
202
|
-
// }
|
|
203
|
-
|
package/svf/lib/MTA/TCT.cpp
CHANGED
|
@@ -42,40 +42,39 @@ using namespace SVFUtil;
|
|
|
42
42
|
* (1) the instruction i itself
|
|
43
43
|
* (2) all the callsites invoke the function where i resides in
|
|
44
44
|
*/
|
|
45
|
-
bool TCT::isInLoopInstruction(const
|
|
45
|
+
bool TCT::isInLoopInstruction(const ICFGNode* inst)
|
|
46
46
|
{
|
|
47
47
|
assert(inst && "null value instruction!!");
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
FIFOWorkList<const
|
|
49
|
+
Set<const ICFGNode*> insts;
|
|
50
|
+
FIFOWorkList<const ICFGNode*> worklist;
|
|
51
51
|
worklist.push(inst);
|
|
52
52
|
|
|
53
53
|
while(!worklist.empty())
|
|
54
54
|
{
|
|
55
|
-
const
|
|
55
|
+
const ICFGNode* inst = worklist.pop();
|
|
56
56
|
insts.insert(inst);
|
|
57
|
-
|
|
58
|
-
for(
|
|
57
|
+
CallGraphNode* cgnode = tcg->getCallGraphNode(inst->getFun());
|
|
58
|
+
for(CallGraphNode::const_iterator nit = cgnode->InEdgeBegin(), neit = cgnode->InEdgeEnd(); nit!=neit; nit++)
|
|
59
59
|
{
|
|
60
|
-
for(
|
|
60
|
+
for(CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->directCallsBegin(),
|
|
61
61
|
ecit = (*nit)->directCallsEnd(); cit!=ecit; ++cit)
|
|
62
62
|
{
|
|
63
|
-
if(insts.insert(
|
|
64
|
-
worklist.push(
|
|
63
|
+
if(insts.insert(*cit).second)
|
|
64
|
+
worklist.push(*cit);
|
|
65
65
|
}
|
|
66
|
-
for(
|
|
66
|
+
for(CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->indirectCallsBegin(),
|
|
67
67
|
ecit = (*nit)->indirectCallsEnd(); cit!=ecit; ++cit)
|
|
68
68
|
{
|
|
69
|
-
if(insts.insert(
|
|
70
|
-
worklist.push(
|
|
69
|
+
if(insts.insert(*cit).second)
|
|
70
|
+
worklist.push(*cit);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
for(
|
|
75
|
+
for(const ICFGNode* i : insts)
|
|
76
76
|
{
|
|
77
|
-
|
|
78
|
-
if(i->getFunction()->hasLoopInfo(i->getParent()))
|
|
77
|
+
if(i->getFun()->hasLoopInfo(i->getBB()))
|
|
79
78
|
return true;
|
|
80
79
|
}
|
|
81
80
|
|
|
@@ -88,9 +87,9 @@ bool TCT::isInLoopInstruction(const SVFInstruction* inst)
|
|
|
88
87
|
* (1) the function f where i resides in is in a recursion
|
|
89
88
|
* (2) any caller function starting from the function f in is in a recursion
|
|
90
89
|
*/
|
|
91
|
-
bool TCT::isInRecursion(const
|
|
90
|
+
bool TCT::isInRecursion(const ICFGNode* inst) const
|
|
92
91
|
{
|
|
93
|
-
const SVFFunction* f = inst->
|
|
92
|
+
const SVFFunction* f = inst->getFun();
|
|
94
93
|
FIFOWorkList<const SVFFunction*> worklist;
|
|
95
94
|
Set<const SVFFunction*> visits;
|
|
96
95
|
worklist.push(f);
|
|
@@ -102,18 +101,18 @@ bool TCT::isInRecursion(const SVFInstruction* inst) const
|
|
|
102
101
|
if(tcgSCC->isInCycle(tcg->getCallGraphNode(svffun)->getId()))
|
|
103
102
|
return true;
|
|
104
103
|
|
|
105
|
-
const
|
|
104
|
+
const CallGraphNode* cgnode = tcg->getCallGraphNode(svffun);
|
|
106
105
|
|
|
107
|
-
for(
|
|
106
|
+
for(CallGraphNode::const_iterator nit = cgnode->InEdgeBegin(), neit = cgnode->InEdgeEnd(); nit!=neit; nit++)
|
|
108
107
|
{
|
|
109
|
-
for(
|
|
108
|
+
for(CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->directCallsBegin(),
|
|
110
109
|
ecit = (*nit)->directCallsEnd(); cit!=ecit; ++cit)
|
|
111
110
|
{
|
|
112
111
|
const SVFFunction* caller = (*cit)->getCallSite()->getFunction();
|
|
113
112
|
if(visits.find(caller)==visits.end())
|
|
114
113
|
worklist.push(caller);
|
|
115
114
|
}
|
|
116
|
-
for(
|
|
115
|
+
for(CallGraphEdge::CallInstSet::const_iterator cit = (*nit)->indirectCallsBegin(),
|
|
117
116
|
ecit = (*nit)->indirectCallsEnd(); cit!=ecit; ++cit)
|
|
118
117
|
{
|
|
119
118
|
const SVFFunction* caller = (*cit)->getCallSite()->getFunction();
|
|
@@ -139,7 +138,7 @@ void TCT::markRelProcs()
|
|
|
139
138
|
|
|
140
139
|
for(ThreadCallGraph::ForkEdgeSet::const_iterator nit = tcg->getForkEdgeBegin(*it), neit = tcg->getForkEdgeEnd(*it); nit!=neit; nit++)
|
|
141
140
|
{
|
|
142
|
-
const
|
|
141
|
+
const CallGraphNode* forkeeNode = (*nit)->getDstNode();
|
|
143
142
|
candidateFuncSet.insert(forkeeNode->getFunction());
|
|
144
143
|
}
|
|
145
144
|
|
|
@@ -160,18 +159,18 @@ void TCT::markRelProcs()
|
|
|
160
159
|
*/
|
|
161
160
|
void TCT::markRelProcs(const SVFFunction* svffun)
|
|
162
161
|
{
|
|
163
|
-
|
|
164
|
-
FIFOWorkList<const
|
|
162
|
+
CallGraphNode* cgnode = tcg->getCallGraphNode(svffun);
|
|
163
|
+
FIFOWorkList<const CallGraphNode*> worklist;
|
|
165
164
|
PTACGNodeSet visited;
|
|
166
165
|
worklist.push(cgnode);
|
|
167
166
|
visited.insert(cgnode);
|
|
168
167
|
while(!worklist.empty())
|
|
169
168
|
{
|
|
170
|
-
const
|
|
169
|
+
const CallGraphNode* node = worklist.pop();
|
|
171
170
|
candidateFuncSet.insert(node->getFunction());
|
|
172
|
-
for(
|
|
171
|
+
for(CallGraphNode::const_iterator nit = node->InEdgeBegin(), neit = node->InEdgeEnd(); nit!=neit; nit++)
|
|
173
172
|
{
|
|
174
|
-
const
|
|
173
|
+
const CallGraphNode* srcNode = (*nit)->getSrcNode();
|
|
175
174
|
if(visited.find(srcNode)==visited.end())
|
|
176
175
|
{
|
|
177
176
|
visited.insert(srcNode);
|
|
@@ -189,9 +188,9 @@ void TCT::collectEntryFunInCallGraph()
|
|
|
189
188
|
for(SVFModule::const_iterator it = getSVFModule()->begin(), eit = getSVFModule()->end(); it!=eit; ++it)
|
|
190
189
|
{
|
|
191
190
|
const SVFFunction* fun = (*it);
|
|
192
|
-
if (isExtCall(fun))
|
|
191
|
+
if (SVFUtil::isExtCall(fun))
|
|
193
192
|
continue;
|
|
194
|
-
|
|
193
|
+
CallGraphNode* node = tcg->getCallGraphNode(fun);
|
|
195
194
|
if (!node->hasIncomingEdge())
|
|
196
195
|
{
|
|
197
196
|
entryFuncSet.insert(fun);
|
|
@@ -241,15 +240,16 @@ void TCT::collectMultiForkedThreads()
|
|
|
241
240
|
/*!
|
|
242
241
|
* Handle call relations
|
|
243
242
|
*/
|
|
244
|
-
void TCT::handleCallRelation(CxtThreadProc& ctp, const
|
|
243
|
+
void TCT::handleCallRelation(CxtThreadProc& ctp, const CallGraphEdge* cgEdge, CallSite cs)
|
|
245
244
|
{
|
|
246
245
|
const SVFFunction* callee = cgEdge->getDstNode()->getFunction();
|
|
247
246
|
|
|
248
247
|
CallStrCxt cxt(ctp.getContext());
|
|
249
248
|
CallStrCxt oldCxt = cxt;
|
|
250
|
-
|
|
249
|
+
const CallICFGNode* callNode = SVFUtil::cast<CallICFGNode>(getICFGNode(cs.getInstruction()));
|
|
250
|
+
pushCxt(cxt,callNode,callee);
|
|
251
251
|
|
|
252
|
-
if(cgEdge->getEdgeKind() ==
|
|
252
|
+
if(cgEdge->getEdgeKind() == CallGraphEdge::CallRetEdge)
|
|
253
253
|
{
|
|
254
254
|
CxtThreadProc newctp(ctp.getTid(),cxt,callee);
|
|
255
255
|
if(pushToCTPWorkList(newctp))
|
|
@@ -259,10 +259,10 @@ void TCT::handleCallRelation(CxtThreadProc& ctp, const PTACallGraphEdge* cgEdge,
|
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
261
|
|
|
262
|
-
else if(cgEdge->getEdgeKind() ==
|
|
262
|
+
else if(cgEdge->getEdgeKind() == CallGraphEdge::TDForkEdge)
|
|
263
263
|
{
|
|
264
264
|
/// Create spawnee TCT node
|
|
265
|
-
TCTNode* spawneeNode = getOrCreateTCTNode(cxt,
|
|
265
|
+
TCTNode* spawneeNode = getOrCreateTCTNode(cxt,callNode, oldCxt, callee);
|
|
266
266
|
CxtThreadProc newctp(spawneeNode->getId(),cxt,callee);
|
|
267
267
|
|
|
268
268
|
if(pushToCTPWorkList(newctp))
|
|
@@ -286,12 +286,12 @@ void TCT::handleCallRelation(CxtThreadProc& ctp, const PTACallGraphEdge* cgEdge,
|
|
|
286
286
|
* Return true if a join instruction must be executed inside a loop
|
|
287
287
|
* joinbb should post dominate the successive basic block of a loop header
|
|
288
288
|
*/
|
|
289
|
-
bool TCT::isJoinMustExecutedInLoop(const LoopBBs& lp,const
|
|
289
|
+
bool TCT::isJoinMustExecutedInLoop(const LoopBBs& lp,const ICFGNode* join)
|
|
290
290
|
{
|
|
291
291
|
assert(!lp.empty() && "this is not a loop, empty basic block");
|
|
292
|
-
const SVFFunction* svffun = join->
|
|
292
|
+
const SVFFunction* svffun = join->getFun();
|
|
293
293
|
const SVFBasicBlock* loopheadbb = svffun->getLoopHeader(lp);
|
|
294
|
-
const SVFBasicBlock* joinbb = join->
|
|
294
|
+
const SVFBasicBlock* joinbb = join->getBB();
|
|
295
295
|
assert(loopheadbb->getParent()==joinbb->getParent() && "should inside same function");
|
|
296
296
|
|
|
297
297
|
for (const SVFBasicBlock* svf_scc_bb : loopheadbb->getSuccessors())
|
|
@@ -314,9 +314,9 @@ void TCT::collectLoopInfoForJoin()
|
|
|
314
314
|
{
|
|
315
315
|
for(ThreadCallGraph::CallSiteSet::const_iterator it = tcg->joinsitesBegin(), eit = tcg->joinsitesEnd(); it!=eit; ++it)
|
|
316
316
|
{
|
|
317
|
-
const
|
|
318
|
-
const SVFFunction* svffun = join->
|
|
319
|
-
const SVFBasicBlock* svfbb = join->
|
|
317
|
+
const ICFGNode* join = *it;
|
|
318
|
+
const SVFFunction* svffun = join->getFun();
|
|
319
|
+
const SVFBasicBlock* svfbb = join->getBB();
|
|
320
320
|
|
|
321
321
|
if(svffun->hasLoopInfo(svfbb))
|
|
322
322
|
{
|
|
@@ -354,7 +354,7 @@ bool TCT::isLoopExitOfJoinLoop(const SVFBasicBlock* bb)
|
|
|
354
354
|
for(InstToLoopMap::const_iterator it = joinSiteToLoopMap.begin(), eit = joinSiteToLoopMap.end(); it!=eit; ++it)
|
|
355
355
|
{
|
|
356
356
|
std::vector<const SVFBasicBlock*> exitbbs;
|
|
357
|
-
it->first->
|
|
357
|
+
it->first->getFun()->getExitBlocksOfLoop(it->first->getBB(),exitbbs);
|
|
358
358
|
while(!exitbbs.empty())
|
|
359
359
|
{
|
|
360
360
|
const SVFBasicBlock* eb = exitbbs.back();
|
|
@@ -404,21 +404,21 @@ void TCT::build()
|
|
|
404
404
|
while(!ctpList.empty())
|
|
405
405
|
{
|
|
406
406
|
CxtThreadProc ctp = popFromCTPWorkList();
|
|
407
|
-
|
|
407
|
+
CallGraphNode* cgNode = tcg->getCallGraphNode(ctp.getProc());
|
|
408
408
|
if(isCandidateFun(cgNode->getFunction()) == false)
|
|
409
409
|
continue;
|
|
410
410
|
|
|
411
|
-
for(
|
|
411
|
+
for(CallGraphNode::const_iterator nit = cgNode->OutEdgeBegin(), neit = cgNode->OutEdgeEnd(); nit!=neit; nit++)
|
|
412
412
|
{
|
|
413
|
-
const
|
|
413
|
+
const CallGraphEdge* cgEdge = (*nit);
|
|
414
414
|
|
|
415
|
-
for(
|
|
415
|
+
for(CallGraphEdge::CallInstSet::const_iterator cit = cgEdge->directCallsBegin(),
|
|
416
416
|
ecit = cgEdge->directCallsEnd(); cit!=ecit; ++cit)
|
|
417
417
|
{
|
|
418
418
|
DBOUT(DMTA,outs() << "\nTCT handling direct call:" << **cit << "\t" << cgEdge->getSrcNode()->getFunction()->getName() << "-->" << cgEdge->getDstNode()->getFunction()->getName() << "\n");
|
|
419
419
|
handleCallRelation(ctp,cgEdge,getSVFCallSite((*cit)->getCallSite()));
|
|
420
420
|
}
|
|
421
|
-
for(
|
|
421
|
+
for(CallGraphEdge::CallInstSet::const_iterator ind = cgEdge->indirectCallsBegin(),
|
|
422
422
|
eind = cgEdge->indirectCallsEnd(); ind!=eind; ++ind)
|
|
423
423
|
{
|
|
424
424
|
DBOUT(DMTA,outs() << "\nTCT handling indirect call:" << **ind << "\t" << cgEdge->getSrcNode()->getFunction()->getName() << "-->" << cgEdge->getDstNode()->getFunction()->getName() << "\n");
|
|
@@ -440,11 +440,11 @@ void TCT::build()
|
|
|
440
440
|
/*!
|
|
441
441
|
* Push calling context
|
|
442
442
|
*/
|
|
443
|
-
void TCT::pushCxt(CallStrCxt& cxt, const
|
|
443
|
+
void TCT::pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee)
|
|
444
444
|
{
|
|
445
445
|
|
|
446
|
-
const SVFFunction* caller = call->
|
|
447
|
-
CallSiteID csId = tcg->getCallSiteID(
|
|
446
|
+
const SVFFunction* caller = call->getFun();
|
|
447
|
+
CallSiteID csId = tcg->getCallSiteID(call, callee);
|
|
448
448
|
|
|
449
449
|
/// handle calling context for candidate functions only
|
|
450
450
|
if(isCandidateFun(caller) == false)
|
|
@@ -461,11 +461,11 @@ void TCT::pushCxt(CallStrCxt& cxt, const SVFInstruction* call, const SVFFunction
|
|
|
461
461
|
/*!
|
|
462
462
|
* Match calling context
|
|
463
463
|
*/
|
|
464
|
-
bool TCT::matchCxt(CallStrCxt& cxt, const
|
|
464
|
+
bool TCT::matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const SVFFunction* callee)
|
|
465
465
|
{
|
|
466
466
|
|
|
467
|
-
const SVFFunction* caller = call->
|
|
468
|
-
CallSiteID csId = tcg->getCallSiteID(
|
|
467
|
+
const SVFFunction* caller = call->getFun();
|
|
468
|
+
CallSiteID csId = tcg->getCallSiteID(call, callee);
|
|
469
469
|
|
|
470
470
|
/// handle calling context for candidate functions only
|
|
471
471
|
if(isCandidateFun(caller) == false)
|
|
@@ -66,7 +66,7 @@ const std::string PointerAnalysis::aliasTestFailNoAliasMangled = "_Z20EXPECTEDF
|
|
|
66
66
|
* Constructor
|
|
67
67
|
*/
|
|
68
68
|
PointerAnalysis::PointerAnalysis(SVFIR* p, PTATY ty, bool alias_check) :
|
|
69
|
-
svfMod(nullptr),ptaTy(ty),stat(nullptr),
|
|
69
|
+
svfMod(nullptr),ptaTy(ty),stat(nullptr),callgraph(nullptr),callGraphSCC(nullptr),icfg(nullptr),chgraph(nullptr)
|
|
70
70
|
{
|
|
71
71
|
pag = p;
|
|
72
72
|
OnTheFlyIterBudgetForStat = Options::StatBudget();
|
|
@@ -88,8 +88,8 @@ PointerAnalysis::~PointerAnalysis()
|
|
|
88
88
|
|
|
89
89
|
void PointerAnalysis::destroy()
|
|
90
90
|
{
|
|
91
|
-
delete
|
|
92
|
-
|
|
91
|
+
delete callgraph;
|
|
92
|
+
callgraph = nullptr;
|
|
93
93
|
|
|
94
94
|
delete callGraphSCC;
|
|
95
95
|
callGraphSCC = nullptr;
|
|
@@ -113,19 +113,19 @@ void PointerAnalysis::initialize()
|
|
|
113
113
|
{
|
|
114
114
|
ThreadCallGraph* cg = new ThreadCallGraph();
|
|
115
115
|
ThreadCallGraphBuilder bd(cg, pag->getICFG());
|
|
116
|
-
|
|
116
|
+
callgraph = bd.buildThreadCallGraph(pag->getModule());
|
|
117
117
|
}
|
|
118
118
|
else
|
|
119
119
|
{
|
|
120
|
-
|
|
120
|
+
CallGraph* cg = new CallGraph();
|
|
121
121
|
CallGraphBuilder bd(cg,pag->getICFG());
|
|
122
|
-
|
|
122
|
+
callgraph = bd.buildCallGraph(pag->getModule());
|
|
123
123
|
}
|
|
124
124
|
callGraphSCCDetection();
|
|
125
125
|
|
|
126
126
|
// dump callgraph
|
|
127
127
|
if (Options::CallGraphDotGraph())
|
|
128
|
-
|
|
128
|
+
getCallGraph()->dump("callgraph_initial");
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
|
|
@@ -140,7 +140,7 @@ bool PointerAnalysis::isLocalVarInRecursiveFun(NodeID id) const
|
|
|
140
140
|
{
|
|
141
141
|
if(const SVFFunction* svffun = pag->getGNode(id)->getFunction())
|
|
142
142
|
{
|
|
143
|
-
return callGraphSCC->isInCycle(
|
|
143
|
+
return callGraphSCC->isInCycle(getCallGraph()->getCallGraphNode(svffun)->getId());
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
return false;
|
|
@@ -198,10 +198,10 @@ void PointerAnalysis::finalize()
|
|
|
198
198
|
if (Options::FuncPointerPrint())
|
|
199
199
|
printIndCSTargets();
|
|
200
200
|
|
|
201
|
-
|
|
201
|
+
getCallGraph()->verifyCallGraph();
|
|
202
202
|
|
|
203
203
|
if (Options::CallGraphDotGraph())
|
|
204
|
-
|
|
204
|
+
getCallGraph()->dump("callgraph_final");
|
|
205
205
|
|
|
206
206
|
if(!pag->isBuiltFromFile() && alias_validation)
|
|
207
207
|
validateTests();
|
|
@@ -412,7 +412,7 @@ void PointerAnalysis::resolveIndCalls(const CallICFGNode* cs, const PointsTo& ta
|
|
|
412
412
|
newEdges[cs].insert(callee);
|
|
413
413
|
getIndCallMap()[cs].insert(callee);
|
|
414
414
|
|
|
415
|
-
|
|
415
|
+
callgraph->addIndirectCallGraphEdge(cs, cs->getCaller(), callee);
|
|
416
416
|
// FIXME: do we need to update llvm call graph here?
|
|
417
417
|
// The indirect call is maintained by ourself, We may update llvm's when we need to
|
|
418
418
|
//CallGraphNode* callgraphNode = callgraph->getOrInsertFunction(cs.getCaller());
|
|
@@ -477,7 +477,7 @@ void PointerAnalysis::connectVCallToVFns(const CallICFGNode* cs, const VFunSet &
|
|
|
477
477
|
newEdges[cs].insert(callee);
|
|
478
478
|
getIndCallMap()[cs].insert(callee);
|
|
479
479
|
const CallICFGNode* callBlockNode = pag->getICFG()->getCallICFGNode(cs->getCallSite());
|
|
480
|
-
|
|
480
|
+
callgraph->addIndirectCallGraphEdge(callBlockNode, cs->getCaller(),callee);
|
|
481
481
|
}
|
|
482
482
|
}
|
|
483
483
|
}
|
|
@@ -52,9 +52,9 @@ void LeakChecker::initSrcs()
|
|
|
52
52
|
if(cs->getCallSite()->ptrInUncalledFunction() || !cs->getCallSite()->getType()->isPointerTy())
|
|
53
53
|
continue;
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
CallGraph::FunctionSet callees;
|
|
56
56
|
getCallgraph()->getCallees(cs->getCallICFGNode(),callees);
|
|
57
|
-
for(
|
|
57
|
+
for(CallGraph::FunctionSet::const_iterator cit = callees.begin(), ecit = callees.end(); cit!=ecit; cit++)
|
|
58
58
|
{
|
|
59
59
|
const SVFFunction* fun = *cit;
|
|
60
60
|
if (isSourceLikeFun(fun))
|
|
@@ -112,9 +112,9 @@ void LeakChecker::initSnks()
|
|
|
112
112
|
eit = pag->getCallSiteArgsMap().end(); it!=eit; ++it)
|
|
113
113
|
{
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
CallGraph::FunctionSet callees;
|
|
116
116
|
getCallgraph()->getCallees(it->first,callees);
|
|
117
|
-
for(
|
|
117
|
+
for(CallGraph::FunctionSet::const_iterator cit = callees.begin(), ecit = callees.end(); cit!=ecit; cit++)
|
|
118
118
|
{
|
|
119
119
|
const SVFFunction* fun = *cit;
|
|
120
120
|
if (isSinkLikeFun(fun))
|
|
@@ -57,7 +57,7 @@ void SaberSVFGBuilder::buildSVFG()
|
|
|
57
57
|
|
|
58
58
|
DBOUT(DGENERAL, outs() << pasMsg("\tAdd Sink SVFG Nodes\n"));
|
|
59
59
|
|
|
60
|
-
AddExtActualParmSVFGNodes(pta->
|
|
60
|
+
AddExtActualParmSVFGNodes(pta->getCallGraph());
|
|
61
61
|
|
|
62
62
|
if(pta->printStat())
|
|
63
63
|
svfg->performStat();
|
|
@@ -291,15 +291,15 @@ void SaberSVFGBuilder::rmIncomingEdgeForSUStore(BVDataPTAImpl* pta)
|
|
|
291
291
|
|
|
292
292
|
|
|
293
293
|
/// Add actual parameter SVFGNode for 1st argument of a deallocation like external function
|
|
294
|
-
void SaberSVFGBuilder::AddExtActualParmSVFGNodes(
|
|
294
|
+
void SaberSVFGBuilder::AddExtActualParmSVFGNodes(CallGraph* callgraph)
|
|
295
295
|
{
|
|
296
296
|
SVFIR* pag = SVFIR::getPAG();
|
|
297
297
|
for(SVFIR::CSToArgsListMap::iterator it = pag->getCallSiteArgsMap().begin(),
|
|
298
298
|
eit = pag->getCallSiteArgsMap().end(); it!=eit; ++it)
|
|
299
299
|
{
|
|
300
|
-
|
|
300
|
+
CallGraph::FunctionSet callees;
|
|
301
301
|
callgraph->getCallees(it->first, callees);
|
|
302
|
-
for (
|
|
302
|
+
for (CallGraph::FunctionSet::const_iterator cit = callees.begin(),
|
|
303
303
|
ecit = callees.end(); cit != ecit; cit++)
|
|
304
304
|
{
|
|
305
305
|
|
|
@@ -49,7 +49,7 @@ void SrcSnkDDA::initialize(SVFModule* module)
|
|
|
49
49
|
else
|
|
50
50
|
svfg = memSSA.buildPTROnlySVFG(ander);
|
|
51
51
|
setGraph(memSSA.getSVFG());
|
|
52
|
-
|
|
52
|
+
callgraph = ander->getCallGraph();
|
|
53
53
|
//AndersenWaveDiff::releaseAndersenWaveDiff();
|
|
54
54
|
/// allocate control-flow graph branch conditions
|
|
55
55
|
getSaberCondAllocator()->allocate(getPAG()->getModule());
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
using namespace SVF;
|
|
36
36
|
using namespace SVFUtil;
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
CallGraph* CallGraphBuilder::buildCallGraph(SVFModule* svfModule)
|
|
39
39
|
{
|
|
40
40
|
/// create nodes
|
|
41
41
|
for (SVFModule::const_iterator F = svfModule->begin(), E = svfModule->end(); F != E; ++F)
|
|
@@ -65,7 +65,7 @@ PTACallGraph* CallGraphBuilder::buildCallGraph(SVFModule* svfModule)
|
|
|
65
65
|
return callgraph;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
CallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule)
|
|
69
69
|
{
|
|
70
70
|
|
|
71
71
|
buildCallGraph(svfModule);
|
|
@@ -95,21 +95,6 @@ PTACallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule)
|
|
|
95
95
|
cg->addThreadForkEdgeSetMap(cs,nullptr);
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
|
-
else if (tdAPI->isHareParFor(inst))
|
|
99
|
-
{
|
|
100
|
-
const CallICFGNode* cs = icfg->getCallICFGNode(inst);
|
|
101
|
-
cg->addParForSite(cs);
|
|
102
|
-
const SVFFunction* taskFunc = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getTaskFuncAtHareParForSite(inst));
|
|
103
|
-
if (taskFunc)
|
|
104
|
-
{
|
|
105
|
-
cg->addDirectParForEdge(cs);
|
|
106
|
-
}
|
|
107
|
-
// indirect call to the start routine function
|
|
108
|
-
else
|
|
109
|
-
{
|
|
110
|
-
cg->addHareParForEdgeSetMap(cs,nullptr);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
98
|
}
|
|
114
99
|
}
|
|
115
100
|
}
|