svf-lib 1.0.2682 → 1.0.2684
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/SVF-linux-x86_64/bin/mta +0 -0
- package/SVF-linux-x86_64/bin/saber +0 -0
- package/SVF-linux-x86_64/bin/wpa +0 -0
- package/SVF-linux-x86_64/include/AE/Core/NumericValue.h +1 -1
- package/SVF-linux-x86_64/include/Graphs/CDG.h +1 -1
- package/SVF-linux-x86_64/include/Graphs/CallGraph.h +34 -3
- package/SVF-linux-x86_64/include/Graphs/ICFG.h +6 -0
- package/SVF-linux-x86_64/include/Graphs/SVFG.h +6 -0
- package/SVF-linux-x86_64/include/Graphs/SlicedGraphs.h +119 -84
- package/SVF-linux-x86_64/include/Graphs/ThreadCallGraph.h +37 -0
- package/SVF-linux-x86_64/include/Graphs/VFG.h +1 -1
- package/SVF-linux-x86_64/include/MTA/FSMPTA.h +50 -34
- package/SVF-linux-x86_64/include/MTA/LockAnalysis.h +95 -55
- package/SVF-linux-x86_64/include/MTA/MHP.h +65 -24
- package/SVF-linux-x86_64/include/MTA/MTA.h +99 -51
- package/SVF-linux-x86_64/include/MTA/MTASVFGBuilder.h +115 -50
- package/SVF-linux-x86_64/include/MTA/MTASlicer.h +73 -79
- package/SVF-linux-x86_64/include/MTA/MTAStat.h +54 -6
- package/SVF-linux-x86_64/include/MTA/TCT.h +13 -22
- package/SVF-linux-x86_64/include/SVF-LLVM/GEPTypeBridgeIterator.h +2 -2
- package/SVF-linux-x86_64/include/SVF-LLVM/ObjTypeInference.h +1 -1
- package/SVF-linux-x86_64/include/Util/Options.h +2 -4
- package/SVF-linux-x86_64/include/Util/SparseBitVector.h +2 -2
- package/SVF-linux-x86_64/lib/libSvfCore.so.3.4 +0 -0
- package/SVF-linux-x86_64/lib/libSvfLLVM.so.3.4 +0 -0
- package/SVF-osx/bin/mta +0 -0
- package/SVF-osx/include/Graphs/CallGraph.h +34 -3
- package/SVF-osx/include/Graphs/ICFG.h +6 -0
- package/SVF-osx/include/Graphs/SVFG.h +6 -0
- package/SVF-osx/include/Graphs/SlicedGraphs.h +119 -84
- package/SVF-osx/include/Graphs/ThreadCallGraph.h +37 -0
- package/SVF-osx/include/MTA/FSMPTA.h +50 -34
- package/SVF-osx/include/MTA/LockAnalysis.h +95 -55
- package/SVF-osx/include/MTA/MHP.h +65 -24
- package/SVF-osx/include/MTA/MTA.h +99 -51
- package/SVF-osx/include/MTA/MTASVFGBuilder.h +115 -50
- package/SVF-osx/include/MTA/MTASlicer.h +73 -79
- package/SVF-osx/include/MTA/MTAStat.h +54 -6
- package/SVF-osx/include/MTA/TCT.h +13 -22
- package/SVF-osx/include/SVF-LLVM/ObjTypeInference.h +1 -1
- package/SVF-osx/include/Util/Options.h +2 -4
- package/SVF-osx/lib/libSvfCore.3.4.dylib +0 -0
- package/SVF-osx/lib/libSvfLLVM.3.4.dylib +0 -0
- package/package.json +1 -1
|
@@ -24,14 +24,6 @@
|
|
|
24
24
|
* MTASlicer.h
|
|
25
25
|
*
|
|
26
26
|
* Author: Jiawei Yang
|
|
27
|
-
*
|
|
28
|
-
* The program slicers of "Multi-Stage On-Demand Program Slicing for Modular
|
|
29
|
-
* Analysis of Multi-Threaded Programs" (ISSTA 2026): a shared MTASlicerBase plus
|
|
30
|
-
* three concrete slicers.
|
|
31
|
-
* - MultiStageSlicer : ILA (sync + dual + call) slice for the thread-aware analysis
|
|
32
|
-
* (its FSPTA stage: data-dependence slice over the thread-aware VFG_pre)
|
|
33
|
-
* - SingleSlicer: one unified slice combining all three dependence kinds, shared
|
|
34
|
-
* by both ILA and FSPTA (the single-pass baseline, MSli §3/§5.4)
|
|
35
27
|
*/
|
|
36
28
|
|
|
37
29
|
#ifndef MTA_MTASLICER_H
|
|
@@ -48,15 +40,11 @@
|
|
|
48
40
|
#include "Graphs/ThreadCallGraph.h"
|
|
49
41
|
#include "Graphs/ICFG.h"
|
|
50
42
|
#include "Graphs/ICFGNode.h"
|
|
51
|
-
#include <
|
|
43
|
+
#include <deque>
|
|
52
44
|
#include "Graphs/ICFGEdge.h"
|
|
53
45
|
#include "Graphs/CallGraph.h"
|
|
54
46
|
#include "Util/WorkList.h"
|
|
55
47
|
#include <memory>
|
|
56
|
-
#include <set>
|
|
57
|
-
#include <string>
|
|
58
|
-
#include <unordered_map>
|
|
59
|
-
#include <unordered_set>
|
|
60
48
|
#include <vector>
|
|
61
49
|
#include <utility>
|
|
62
50
|
|
|
@@ -68,6 +56,20 @@ class SVFG;
|
|
|
68
56
|
class VFGNode; // SVFGNode is a typedef for VFGNode
|
|
69
57
|
class PointerAnalysis;
|
|
70
58
|
|
|
59
|
+
struct ValueFlowSlice
|
|
60
|
+
{
|
|
61
|
+
OrderedSet<const SVFGNode*> svfgNodes;
|
|
62
|
+
OrderedSet<const ICFGNode*> icfgNodes;
|
|
63
|
+
|
|
64
|
+
NodeBS nodeIds() const
|
|
65
|
+
{
|
|
66
|
+
NodeBS ids;
|
|
67
|
+
for (const SVFGNode* node : svfgNodes)
|
|
68
|
+
ids.set(node->getId());
|
|
69
|
+
return ids;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
71
73
|
|
|
72
74
|
//===----------------------------------------------------------------------===//
|
|
73
75
|
// SlicedTCT - the Thread-Create-Tree rebuilt over a SlicedThreadCallGraphView.
|
|
@@ -80,16 +82,15 @@ class PointerAnalysis;
|
|
|
80
82
|
class SlicedTCT : public TCT
|
|
81
83
|
{
|
|
82
84
|
public:
|
|
83
|
-
/// @param
|
|
85
|
+
/// @param pointerAnalysis the shared Andersen pre-analysis
|
|
84
86
|
/// @param slicedView SlicedSVFIRView containing a SlicedThreadCallGraphView
|
|
85
|
-
/// @param
|
|
86
|
-
SlicedTCT(
|
|
87
|
+
/// @param contextLimit maximum context length for the main analysis
|
|
88
|
+
static std::unique_ptr<SlicedTCT> create(
|
|
89
|
+
PointerAnalysis& pointerAnalysis, const SlicedSVFIRView& slicedView,
|
|
90
|
+
u32_t contextLimit);
|
|
87
91
|
|
|
88
92
|
~SlicedTCT() override = default;
|
|
89
93
|
|
|
90
|
-
/// Override pushCxt to use the custom maxContextLen
|
|
91
|
-
void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const FunObjVar* callee) override;
|
|
92
|
-
|
|
93
94
|
protected:
|
|
94
95
|
void build() override;
|
|
95
96
|
void markRelProcs() override;
|
|
@@ -98,11 +99,12 @@ protected:
|
|
|
98
99
|
void handleCallRelation(CxtThreadProc& ctp, const CallGraphEdge* cgEdge, const CallICFGNode* cs) override;
|
|
99
100
|
|
|
100
101
|
private:
|
|
101
|
-
|
|
102
|
+
SlicedTCT(PointerAnalysis& pointerAnalysis,
|
|
103
|
+
const SlicedSVFIRView& slicedView, u32_t contextLimit);
|
|
102
104
|
|
|
103
|
-
|
|
104
|
-
u32_t maxContextLen; // 0 means use Options::MaxContextLen()
|
|
105
|
+
void collectEntryFunInCallGraph() override;
|
|
105
106
|
|
|
107
|
+
const SlicedThreadCallGraphView& tcgView;
|
|
106
108
|
bool isKeptNode(const CallGraphNode* node) const;
|
|
107
109
|
bool isKeptEdge(const CallGraphEdge* edge) const;
|
|
108
110
|
void getKeptForkSites(std::vector<const ICFGNode*>& out) const;
|
|
@@ -119,62 +121,61 @@ private:
|
|
|
119
121
|
class MTASlicerBase
|
|
120
122
|
{
|
|
121
123
|
public:
|
|
122
|
-
MTASlicerBase(SVFIR*
|
|
123
|
-
LockAnalysis* lockAnalysis, SVFG*
|
|
124
|
-
virtual ~MTASlicerBase();
|
|
124
|
+
MTASlicerBase(SVFIR* svfir, AndersenBase* pta, MHP* mhp,
|
|
125
|
+
LockAnalysis* lockAnalysis, SVFG* svfg = nullptr);
|
|
125
126
|
|
|
126
127
|
protected:
|
|
127
|
-
SVFIR*
|
|
128
|
+
SVFIR* svfir;
|
|
128
129
|
AndersenBase* pta;
|
|
129
130
|
MHP* mhp;
|
|
130
131
|
LockAnalysis* lockAnalysis;
|
|
131
132
|
CallGraph* callGraph;
|
|
132
|
-
SVFG*
|
|
133
|
+
SVFG* svfg; ///< thread-aware VFG_pre (PTA/Single slicers; null for MTA)
|
|
133
134
|
|
|
134
135
|
// === Data flow analysis helper ===
|
|
135
|
-
/**
|
|
136
|
-
* Paper-faithful (§4.3) data-dependence slice over the thread-aware SVFG
|
|
137
|
-
* (VFG_pre): seed from the value-flow nodes of the given statements and
|
|
138
|
-
* backward-traverse every value-flow edge -- direct (top-level def-use),
|
|
139
|
-
* indirect (address-taken / MemSSA def-use), and thread-aware interference.
|
|
140
|
-
* Returns the kept ICFG nodes. This is the single dependence model used
|
|
141
|
-
* by the FSPTA stage.
|
|
142
|
-
*/
|
|
143
|
-
OrderedSet<const ICFGNode*> sliceDataDependenceOverVFG(
|
|
144
|
-
const OrderedSet<const SVFStmt*>& seeds, SVFG* vfg);
|
|
145
|
-
|
|
146
136
|
/// The SVFG-node granularity of the data-dependence slice above: the set of
|
|
147
137
|
/// VFG nodes reachable backward from the seeds. ThreadVF(VFG'_pre) is exactly
|
|
148
138
|
/// the thread-aware edges whose *both* endpoints lie in this set, so ILA
|
|
149
139
|
/// slicing uses it to restrict the [THREAD-VF] sources to surviving edges.
|
|
150
140
|
OrderedSet<const VFGNode*> computeDataDependenceSVFGNodes(
|
|
151
|
-
const OrderedSet<const SVFStmt*>& seeds, SVFG*
|
|
141
|
+
const OrderedSet<const SVFStmt*>& seeds, SVFG* svfg);
|
|
142
|
+
|
|
143
|
+
static void enqueueSVFGNode(const SVFGNode* node,
|
|
144
|
+
OrderedSet<const SVFGNode*>& visited,
|
|
145
|
+
std::deque<const SVFGNode*>& worklist);
|
|
152
146
|
|
|
153
147
|
/// Project the retained VFG nodes (plus the seeds) onto their ICFG nodes.
|
|
154
148
|
OrderedSet<const ICFGNode*> svfgNodesToICFGNodes(
|
|
155
149
|
const OrderedSet<const VFGNode*>& nodes, const OrderedSet<const SVFStmt*>& seeds);
|
|
156
150
|
|
|
157
151
|
// === Thread analysis helpers ===
|
|
158
|
-
OrderedSet<const
|
|
152
|
+
OrderedSet<const CallICFGNode*> getDependentThreadCreate(const ICFGNode* node);
|
|
159
153
|
OrderedSet<const TCTNode*> getTCTNodeSetFromNode(const ICFGNode* node);
|
|
160
154
|
|
|
161
155
|
// === Lock analysis helpers ===
|
|
162
156
|
OrderedSet<const ICFGNode*> getLockSet(const ICFGNode* node);
|
|
163
|
-
OrderedSet<const CallICFGNode*> collectPthreadStatements(
|
|
164
|
-
|
|
157
|
+
OrderedSet<const CallICFGNode*> collectPthreadStatements(
|
|
158
|
+
const OrderedSet<const ICFGNode*>& sourceNodes);
|
|
159
|
+
OrderedSet<const CallICFGNode*> collectMutexStatements(
|
|
160
|
+
const OrderedSet<const ICFGNode*>& sourceNodes);
|
|
165
161
|
|
|
166
162
|
// === Common slicing helpers ===
|
|
167
163
|
/**
|
|
168
164
|
* Collect common pthread and mutex statements (shared by PTA and MTA slicing).
|
|
169
|
-
* @param
|
|
165
|
+
* @param sourceNodes Complete ILA source set ([INIT] union [THREAD-VF])
|
|
170
166
|
* @return Pair of (pthreadCallNodes, mutexCallNodes)
|
|
171
167
|
*/
|
|
172
168
|
std::pair<OrderedSet<const CallICFGNode*>, OrderedSet<const CallICFGNode*>>
|
|
173
|
-
collectCommonThreadStatements(const OrderedSet<const
|
|
169
|
+
collectCommonThreadStatements(const OrderedSet<const ICFGNode*>& sourceNodes);
|
|
174
170
|
|
|
175
|
-
|
|
176
|
-
|
|
171
|
+
/// Add synchronization primitives and the control-flow anchors required by
|
|
172
|
+
/// the sliced MHP/lock analyses.
|
|
173
|
+
void addSynchronizationDependencies(
|
|
174
|
+
const OrderedSet<const CallICFGNode*>& pthreadCallNodes,
|
|
175
|
+
const OrderedSet<const CallICFGNode*>& mutexCallNodes,
|
|
176
|
+
OrderedSet<const ICFGNode*>& retainedNodes);
|
|
177
177
|
|
|
178
|
+
// === ICFG analysis helpers ===
|
|
178
179
|
/**
|
|
179
180
|
* Call-dependence expansion (used by MultiStageSlicer): take the
|
|
180
181
|
* kept functions of the given nodes, close upward over the call graph
|
|
@@ -185,20 +186,13 @@ protected:
|
|
|
185
186
|
*/
|
|
186
187
|
OrderedSet<const ICFGNode*> expandCallDependence(const OrderedSet<const ICFGNode*>& nodes);
|
|
187
188
|
|
|
188
|
-
/**
|
|
189
|
-
* Perform dual slicing (temporal slicing): filter statements based on control flow and parallel execution.
|
|
190
|
-
* This is shared by both PTA and MTA slicing.
|
|
191
|
-
* @param slicedNodes Set of statements from statement-level slicing
|
|
192
|
-
* @return Set of ICFG nodes in the dual slice
|
|
193
|
-
*/
|
|
194
|
-
OrderedSet<const ICFGNode*> runDualSlicing(
|
|
195
|
-
const OrderedSet<const ICFGNode*>& slicedNodes);
|
|
196
189
|
};
|
|
197
190
|
|
|
198
191
|
/**
|
|
199
|
-
* MultiStageSlicer - the multi-stage (differential) slicer of MSli
|
|
200
|
-
*
|
|
201
|
-
*
|
|
192
|
+
* MultiStageSlicer - the multi-stage (differential) slicer of MSli. The
|
|
193
|
+
* pre-candidate closure scopes ILA queries and the Main-TVF overlay; the final
|
|
194
|
+
* closure is recomputed over that refined main graph.
|
|
195
|
+
* Stage 1 (ILA): runILASlicing -- synchronization slicing + function
|
|
202
196
|
* expansion, feeding the sliced MHP/lock.
|
|
203
197
|
* Stage 2 (FSPTA): runPTASlicing -- backward data-dependence slice feeding
|
|
204
198
|
* the sliced flow-sensitive solve.
|
|
@@ -207,11 +201,11 @@ protected:
|
|
|
207
201
|
class MultiStageSlicer : public MTASlicerBase
|
|
208
202
|
{
|
|
209
203
|
public:
|
|
210
|
-
MultiStageSlicer(SVFIR*
|
|
211
|
-
LockAnalysis* lockAnalysis, SVFG*
|
|
204
|
+
MultiStageSlicer(SVFIR* svfir, AndersenBase* pta, MHP* mhp,
|
|
205
|
+
LockAnalysis* lockAnalysis, SVFG* svfg = nullptr);
|
|
212
206
|
|
|
213
207
|
/**
|
|
214
|
-
* Stage 1: the ILA slice (
|
|
208
|
+
* Stage 1: the ILA slice (synchronization + function expansion for the IRView).
|
|
215
209
|
* @param vulnerableStatements Set of vulnerable statements to start slicing from
|
|
216
210
|
* (the [INIT] rule: pre-analysis race statements).
|
|
217
211
|
* @param threadVFSources Extra ILA slicing sources from the [THREAD-VF] rule
|
|
@@ -225,24 +219,24 @@ public:
|
|
|
225
219
|
const OrderedSet<const ICFGNode*>& threadVFSources = {});
|
|
226
220
|
|
|
227
221
|
/**
|
|
228
|
-
* Stage 2: the FSPTA slice (backward data dependence over the
|
|
229
|
-
*
|
|
222
|
+
* Stage 2: the FSPTA slice (backward data dependence over the refined main
|
|
223
|
+
* value-flow graph; node set only, no function expansion).
|
|
230
224
|
*/
|
|
231
|
-
|
|
232
|
-
const OrderedSet<const SVFStmt*>& vulnerableStatements
|
|
225
|
+
ValueFlowSlice runPTASlicing(
|
|
226
|
+
const OrderedSet<const SVFStmt*>& vulnerableStatements,
|
|
227
|
+
SVFG* refinedMainVFG);
|
|
233
228
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
* ThreadVF(VFG'_pre); runPTASlicing reuses the same set, so the backward
|
|
238
|
-
* closure over VFG_pre is computed once and shared across both stages.
|
|
239
|
-
*/
|
|
240
|
-
const OrderedSet<const VFGNode*>& getRetainedSVFGNodes(
|
|
229
|
+
/// Compute the pre-candidate slice used to restrict [THREAD-VF] sources and
|
|
230
|
+
/// scope construction of the refined main overlay.
|
|
231
|
+
void computePreCandidateSlice(
|
|
241
232
|
const OrderedSet<const SVFStmt*>& vulnerableStatements);
|
|
242
233
|
|
|
234
|
+
/// Return the pre-candidate slice after computePreCandidateSlice().
|
|
235
|
+
const ValueFlowSlice& getPreCandidateSlice() const;
|
|
236
|
+
|
|
243
237
|
private:
|
|
244
|
-
|
|
245
|
-
bool
|
|
238
|
+
ValueFlowSlice preCandidateSlice;
|
|
239
|
+
bool preCandidateComputed = false;
|
|
246
240
|
};
|
|
247
241
|
|
|
248
242
|
/**
|
|
@@ -252,21 +246,21 @@ private:
|
|
|
252
246
|
* graph). Both ILA and FSPTA run on this single slice, so V_ILA, V_PTA subset
|
|
253
247
|
* V_Single. Used by the differential-slicing ablation (-mta-slicing-single).
|
|
254
248
|
*
|
|
255
|
-
* Iteratively applies data dependence
|
|
256
|
-
*
|
|
249
|
+
* Iteratively applies synchronization, data, and call dependence over the
|
|
250
|
+
* thread-aware VFG_pre until convergence.
|
|
257
251
|
*/
|
|
258
252
|
class SingleSlicer : public MTASlicerBase
|
|
259
253
|
{
|
|
260
254
|
public:
|
|
261
|
-
SingleSlicer(SVFIR*
|
|
262
|
-
LockAnalysis* lockAnalysis, SVFG*
|
|
255
|
+
SingleSlicer(SVFIR* svfir, AndersenBase* pta, MHP* mhp,
|
|
256
|
+
LockAnalysis* lockAnalysis, SVFG* svfg = nullptr);
|
|
263
257
|
|
|
264
258
|
/**
|
|
265
259
|
* Perform unified slicing combining synchronization, data, and call dependence.
|
|
266
260
|
* @param vulnerableStatements Set of vulnerable statements to start slicing from
|
|
267
|
-
* @return
|
|
261
|
+
* @return Exact SVFG data slice plus its synchronization/call-complete ICFG view
|
|
268
262
|
*/
|
|
269
|
-
|
|
263
|
+
ValueFlowSlice runSlicing(
|
|
270
264
|
const OrderedSet<const SVFStmt*>& vulnerableStatements);
|
|
271
265
|
};
|
|
272
266
|
|
|
@@ -31,11 +31,63 @@
|
|
|
31
31
|
#define MTASTAT_H_
|
|
32
32
|
|
|
33
33
|
#include "Util/PTAStat.h"
|
|
34
|
+
#include "Util/Options.h"
|
|
35
|
+
#include "Util/SVFUtil.h"
|
|
36
|
+
|
|
37
|
+
#include <chrono>
|
|
38
|
+
#include <iomanip>
|
|
39
|
+
#include <sstream>
|
|
34
40
|
|
|
35
41
|
namespace SVF
|
|
36
42
|
{
|
|
37
43
|
|
|
38
|
-
|
|
44
|
+
/// MTA's phase and slice reports are opt-in. PStat itself defaults to true in
|
|
45
|
+
/// SVF, so its value alone does not indicate that the user requested -stat.
|
|
46
|
+
inline bool isMTAStatEnabled()
|
|
47
|
+
{
|
|
48
|
+
return Options::PStat.isSet() && Options::PStat();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
class ScopedPhaseTimer
|
|
52
|
+
{
|
|
53
|
+
public:
|
|
54
|
+
explicit ScopedPhaseTimer(const char* phaseName)
|
|
55
|
+
: name(phaseName), enabled(isMTAStatEnabled()),
|
|
56
|
+
start(enabled ? std::chrono::steady_clock::now()
|
|
57
|
+
: std::chrono::steady_clock::time_point())
|
|
58
|
+
{
|
|
59
|
+
if (enabled)
|
|
60
|
+
{
|
|
61
|
+
SVFUtil::outs() << "[TIMER] Phase: " << name << " - started\n";
|
|
62
|
+
SVFUtil::outs().flush();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
~ScopedPhaseTimer()
|
|
67
|
+
{
|
|
68
|
+
if (!enabled)
|
|
69
|
+
return;
|
|
70
|
+
|
|
71
|
+
const auto end = std::chrono::steady_clock::now();
|
|
72
|
+
const double milliseconds =
|
|
73
|
+
std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(
|
|
74
|
+
end - start).count();
|
|
75
|
+
std::ostringstream elapsed;
|
|
76
|
+
elapsed << std::fixed << std::setprecision(2) << milliseconds << " ms";
|
|
77
|
+
if (milliseconds >= 1000.0)
|
|
78
|
+
elapsed << " (" << std::fixed << std::setprecision(2)
|
|
79
|
+
<< (milliseconds / 1000.0) << " s)";
|
|
80
|
+
SVFUtil::outs() << "[TIMER] Phase: " << name << " - finished in "
|
|
81
|
+
<< elapsed.str() << "\n";
|
|
82
|
+
SVFUtil::outs().flush();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private:
|
|
86
|
+
const char* name;
|
|
87
|
+
const bool enabled;
|
|
88
|
+
std::chrono::steady_clock::time_point start;
|
|
89
|
+
};
|
|
90
|
+
|
|
39
91
|
class ThreadCallGraph;
|
|
40
92
|
class TCT;
|
|
41
93
|
class MHP;
|
|
@@ -48,18 +100,14 @@ class MTAStat : public PTAStat
|
|
|
48
100
|
{
|
|
49
101
|
|
|
50
102
|
public:
|
|
51
|
-
typedef Set<const Instruction*> InstSet;
|
|
52
|
-
|
|
53
103
|
/// Constructor
|
|
54
|
-
MTAStat():PTAStat(nullptr),TCTTime(0),MHPTime(0),AnnotationTime(0)
|
|
104
|
+
MTAStat() : PTAStat(nullptr), TCTTime(0), MHPTime(0), AnnotationTime(0)
|
|
55
105
|
{
|
|
56
106
|
}
|
|
57
107
|
/// Statistics for thread call graph
|
|
58
108
|
void performThreadCallGraphStat(ThreadCallGraph* tcg);
|
|
59
109
|
/// Statistics for thread creation tree
|
|
60
110
|
void performTCTStat(TCT* tct);
|
|
61
|
-
/// Statistics for annotation
|
|
62
|
-
//void performAnnotationStat(MTAAnnotator* anno);
|
|
63
111
|
|
|
64
112
|
double TCTTime;
|
|
65
113
|
double MHPTime;
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
#ifndef TCTNodeDetector_H_
|
|
31
31
|
#define TCTNodeDetector_H_
|
|
32
32
|
|
|
33
|
+
#include <memory>
|
|
33
34
|
#include <vector>
|
|
34
35
|
|
|
35
36
|
#include "MemoryModel/PointerAnalysis.h"
|
|
@@ -183,8 +184,13 @@ public:
|
|
|
183
184
|
typedef SCCDetection<CallGraph*> ThreadCallGraphSCC;
|
|
184
185
|
typedef Set<const ICFGNode*> DummyForkSiteSet;
|
|
185
186
|
|
|
186
|
-
///
|
|
187
|
-
TCT(PointerAnalysis* p);
|
|
187
|
+
/// Construct and build a TCT with the command-line context bound.
|
|
188
|
+
static std::unique_ptr<TCT> create(PointerAnalysis* p);
|
|
189
|
+
|
|
190
|
+
/// Construct and build a TCT with an explicit context bound. Analyses that
|
|
191
|
+
/// require a phase-specific bound must pass it here rather than mutating
|
|
192
|
+
/// the process-global option.
|
|
193
|
+
static std::unique_ptr<TCT> create(PointerAnalysis* p, u32_t contextLimit);
|
|
188
194
|
|
|
189
195
|
/// Destructor
|
|
190
196
|
virtual ~TCT();
|
|
@@ -444,8 +450,13 @@ public:
|
|
|
444
450
|
void print() const;
|
|
445
451
|
|
|
446
452
|
protected:
|
|
453
|
+
/// Initialize common TCT state. Factory functions invoke build() only after
|
|
454
|
+
/// the complete concrete object has been constructed.
|
|
455
|
+
TCT(PointerAnalysis* p, u32_t contextLimit);
|
|
456
|
+
|
|
447
457
|
ThreadCallGraph* tcg;
|
|
448
458
|
PointerAnalysis* pta;
|
|
459
|
+
const u32_t contextLimit;
|
|
449
460
|
u32_t TCTNodeNum;
|
|
450
461
|
u32_t TCTEdgeNum;
|
|
451
462
|
u32_t MaxCxtSize;
|
|
@@ -478,26 +489,6 @@ protected:
|
|
|
478
489
|
/// Build TCT
|
|
479
490
|
virtual void build();
|
|
480
491
|
|
|
481
|
-
/// Free the built graph and clear all bookkeeping so build() can run again from
|
|
482
|
-
/// a clean state (SlicedTCT rebuilds the tree over a sliced view).
|
|
483
|
-
void reset()
|
|
484
|
-
{
|
|
485
|
-
destroy();
|
|
486
|
-
IDToNodeMap.clear();
|
|
487
|
-
ctpToNodeMap.clear();
|
|
488
|
-
ctToForkCxtsMap.clear();
|
|
489
|
-
ctToRoutineFunMap.clear();
|
|
490
|
-
candidateFuncSet.clear();
|
|
491
|
-
entryFuncSet.clear();
|
|
492
|
-
joinSiteToLoopMap.clear();
|
|
493
|
-
inRecurJoinSites.clear();
|
|
494
|
-
ctpList.clear();
|
|
495
|
-
visitedCTPs.clear();
|
|
496
|
-
TCTNodeNum = 0;
|
|
497
|
-
TCTEdgeNum = 0;
|
|
498
|
-
MaxCxtSize = 0;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
492
|
/// Mark relevant procedures that are backward reachable from any fork/join site
|
|
502
493
|
//@{
|
|
503
494
|
virtual void markRelProcs();
|
|
@@ -92,8 +92,8 @@ public:
|
|
|
92
92
|
#endif
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
// non-standard operators, these may not need be bridged but seems it's
|
|
96
|
+
// prudent to do so...
|
|
97
97
|
Type* operator->() const
|
|
98
98
|
{
|
|
99
99
|
return operator*();
|
|
@@ -99,7 +99,7 @@ private:
|
|
|
99
99
|
const Type *fwInferObjType(const Value *var);
|
|
100
100
|
|
|
101
101
|
/// backward collect all possible allocation sites (stack, static, heap) of var
|
|
102
|
-
Set<const Value *>&
|
|
102
|
+
Set<const Value *>& bwFindAllocOfVar(const Value *var);
|
|
103
103
|
|
|
104
104
|
/// is allocation (stack, static, heap)
|
|
105
105
|
bool isAlloc(const SVF::Value *val);
|
|
@@ -258,11 +258,9 @@ public:
|
|
|
258
258
|
static const Option<bool> DumpMTAGraphs;
|
|
259
259
|
|
|
260
260
|
/// MTA slicing: slice before the FSAM main analysis (false = whole-program baseline), Default: true
|
|
261
|
-
static const Option<bool>
|
|
261
|
+
static const Option<bool> MTAEnableSlicing;
|
|
262
262
|
/// MTA slicing: one unified slice for ILA + FSPTA (single-pass baseline), Default: false
|
|
263
|
-
static const Option<bool>
|
|
264
|
-
/// MTA slicing: dump intermediate dot graphs (ICFG/TCG/SVFG/...), Default: false
|
|
265
|
-
static const Option<bool> SlicedDumpDot;
|
|
263
|
+
static const Option<bool> MTASingleStageSlicing;
|
|
266
264
|
/// if the access index of gepstmt is unknown, skip it, Default: false
|
|
267
265
|
static const Option<bool> GepUnknownIdx;
|
|
268
266
|
static const Option<bool> RunUncallFuncs;
|
|
@@ -1130,7 +1130,7 @@ public:
|
|
|
1130
1130
|
return (First.index() * ElementSize) + First.find_first();
|
|
1131
1131
|
}
|
|
1132
1132
|
|
|
1133
|
-
|
|
1133
|
+
// Return the last set bit in the bitmap. Return -1 if no bits are set.
|
|
1134
1134
|
int find_last() const
|
|
1135
1135
|
{
|
|
1136
1136
|
if (Elements.empty())
|
|
@@ -1139,7 +1139,7 @@ public:
|
|
|
1139
1139
|
return (Last.index() * ElementSize) + Last.find_last();
|
|
1140
1140
|
}
|
|
1141
1141
|
|
|
1142
|
-
|
|
1142
|
+
// Return true if the SparseBitVector is empty
|
|
1143
1143
|
bool empty() const
|
|
1144
1144
|
{
|
|
1145
1145
|
return Elements.empty();
|
|
Binary file
|
|
Binary file
|
package/SVF-osx/bin/mta
CHANGED
|
Binary file
|
|
@@ -503,6 +503,11 @@ template<> struct GenericGraphTraits<SVF::CallGraph*> : public GenericGraphTrait
|
|
|
503
503
|
{
|
|
504
504
|
typedef SVF::CallGraphNode*NodeRef;
|
|
505
505
|
|
|
506
|
+
static const SVF::CallGraphNode* getRawNode(const SVF::CallGraphNode* n)
|
|
507
|
+
{
|
|
508
|
+
return n;
|
|
509
|
+
}
|
|
510
|
+
|
|
506
511
|
// Graph-intrinsic queries shared with the sliced-view specialisation
|
|
507
512
|
// (GenericGraphTraits<const SlicedThreadCallGraphView*>).
|
|
508
513
|
//@{
|
|
@@ -514,10 +519,36 @@ template<> struct GenericGraphTraits<SVF::CallGraph*> : public GenericGraphTrait
|
|
|
514
519
|
for (SVF::CallGraphEdge* e : n->getInEdges())
|
|
515
520
|
out.push_back(e);
|
|
516
521
|
}
|
|
517
|
-
|
|
518
|
-
|
|
522
|
+
static void getOutEdges(const SVF::CallGraph*, const SVF::CallGraphNode* n,
|
|
523
|
+
std::vector<const SVF::CallGraphEdge*>& out)
|
|
524
|
+
{
|
|
525
|
+
out.clear();
|
|
526
|
+
for (SVF::CallGraphEdge* e : n->getOutEdges())
|
|
527
|
+
out.push_back(e);
|
|
528
|
+
}
|
|
529
|
+
static void getDirectCalls(const SVF::CallGraph*, const SVF::CallGraphEdge* e,
|
|
530
|
+
std::vector<const SVF::CallICFGNode*>& out)
|
|
531
|
+
{
|
|
532
|
+
out.assign(e->getDirectCalls().begin(), e->getDirectCalls().end());
|
|
533
|
+
}
|
|
534
|
+
static void getIndirectCalls(const SVF::CallGraph*, const SVF::CallGraphEdge* e,
|
|
535
|
+
std::vector<const SVF::CallICFGNode*>& out)
|
|
536
|
+
{
|
|
537
|
+
out.assign(e->getIndirectCalls().begin(), e->getIndirectCalls().end());
|
|
538
|
+
}
|
|
539
|
+
static bool containsCallSite(const SVF::CallGraph*,
|
|
540
|
+
const SVF::CallGraphEdge* e,
|
|
541
|
+
const SVF::CallICFGNode* callSite)
|
|
542
|
+
{
|
|
543
|
+
return e->getDirectCalls().count(callSite) ||
|
|
544
|
+
e->getIndirectCalls().count(callSite);
|
|
545
|
+
}
|
|
546
|
+
static void getCallees(SVF::CallGraph* g,
|
|
547
|
+
const SVF::CallICFGNode* callSite,
|
|
548
|
+
SVF::CallGraph::FunctionSet& callees)
|
|
519
549
|
{
|
|
520
|
-
|
|
550
|
+
callees.clear();
|
|
551
|
+
g->getCallees(callSite, callees);
|
|
521
552
|
}
|
|
522
553
|
//@}
|
|
523
554
|
};
|
|
@@ -309,6 +309,12 @@ template<> struct GenericGraphTraits<SVF::ICFG*> : public GenericGraphTraits<SVF
|
|
|
309
309
|
{
|
|
310
310
|
return fun->getEntryBlock()->front();
|
|
311
311
|
}
|
|
312
|
+
/// Exit node of fun under the whole ICFG.
|
|
313
|
+
static const SVF::ICFGNode* getFunExit(SVF::ICFG* graph,
|
|
314
|
+
const SVF::FunObjVar* fun)
|
|
315
|
+
{
|
|
316
|
+
return graph->getFunExitICFGNode(fun);
|
|
317
|
+
}
|
|
312
318
|
/// Nodes of fun contained in this graph (whole ICFG: all of them).
|
|
313
319
|
static void getFunICFGNodes(SVF::ICFG*, const SVF::FunObjVar* fun,
|
|
314
320
|
std::vector<const SVF::ICFGNode*>& out)
|
|
@@ -500,6 +500,7 @@ namespace SVF
|
|
|
500
500
|
template<> struct GenericGraphTraits<SVF::SVFG*> : public GenericGraphTraits<SVF::GenericGraph<SVF::SVFGNode,SVF::SVFGEdge>* >
|
|
501
501
|
{
|
|
502
502
|
typedef SVF::SVFGNode *NodeRef;
|
|
503
|
+
static constexpr bool isFilteredGraph = false;
|
|
503
504
|
|
|
504
505
|
/// Whether n belongs to this graph (the whole SVFG contains every node).
|
|
505
506
|
/// Mirrored by GenericGraphTraits<const SlicedSVFGView*>, so a solver
|
|
@@ -508,6 +509,11 @@ template<> struct GenericGraphTraits<SVF::SVFG*> : public GenericGraphTraits<SVF
|
|
|
508
509
|
{
|
|
509
510
|
return true;
|
|
510
511
|
}
|
|
512
|
+
|
|
513
|
+
static bool containsEdge(SVF::SVFG*, const SVF::SVFGEdge*)
|
|
514
|
+
{
|
|
515
|
+
return true;
|
|
516
|
+
}
|
|
511
517
|
};
|
|
512
518
|
|
|
513
519
|
} // End namespace llvm
|