svf-lib 1.0.2549 → 1.0.2551
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-aarch64/bin/ae +0 -0
- package/SVF-linux-aarch64/include/AE/Core/AbstractState.h +5 -1
- package/SVF-linux-aarch64/include/AE/Svfexe/AEDetector.h +0 -1
- package/SVF-linux-aarch64/include/AE/Svfexe/{PreAnalysis.h → AEWTO.h} +11 -11
- package/SVF-linux-aarch64/include/AE/Svfexe/AbsExtAPI.h +3 -4
- package/SVF-linux-aarch64/include/AE/Svfexe/AbstractInterpretation.h +107 -74
- package/SVF-linux-aarch64/include/AE/Svfexe/SparseAbstractInterpretation.h +115 -0
- package/SVF-linux-aarch64/lib/cmake/SVF/SVFTargets.cmake +1 -1
- package/SVF-linux-aarch64/lib/libSvfCore.so.3.3 +0 -0
- package/SVF-osx/bin/ae +0 -0
- package/SVF-osx/include/AE/Core/AbstractState.h +5 -1
- package/SVF-osx/include/AE/Svfexe/AEDetector.h +0 -1
- package/SVF-osx/include/AE/Svfexe/{PreAnalysis.h → AEWTO.h} +11 -11
- package/SVF-osx/include/AE/Svfexe/AbsExtAPI.h +3 -4
- package/SVF-osx/include/AE/Svfexe/AbstractInterpretation.h +107 -74
- package/SVF-osx/include/AE/Svfexe/SparseAbstractInterpretation.h +115 -0
- package/SVF-osx/lib/cmake/SVF/SVFTargets.cmake +1 -1
- package/SVF-osx/lib/libSvfCore.3.3.dylib +0 -0
- package/package.json +1 -1
- package/SVF-linux-aarch64/include/AE/Svfexe/AbstractStateManager.h +0 -185
- package/SVF-osx/include/AE/Svfexe/AbstractStateManager.h +0 -185
package/SVF-linux-aarch64/bin/ae
CHANGED
|
Binary file
|
|
@@ -261,7 +261,6 @@ public:
|
|
|
261
261
|
/// domain join with other, important! other widen this.
|
|
262
262
|
void joinWith(const AbstractState&other);
|
|
263
263
|
|
|
264
|
-
|
|
265
264
|
/// Replace address-taken (ObjVar) state with other's, preserving ValVar state.
|
|
266
265
|
void updateAddrStateOnly(const AbstractState& other)
|
|
267
266
|
{
|
|
@@ -277,6 +276,11 @@ public:
|
|
|
277
276
|
_freedAddrs.insert(addr);
|
|
278
277
|
}
|
|
279
278
|
|
|
279
|
+
const Set<NodeID>& getFreedAddrs() const
|
|
280
|
+
{
|
|
281
|
+
return _freedAddrs;
|
|
282
|
+
}
|
|
283
|
+
|
|
280
284
|
bool isFreedMem(u32_t addr) const
|
|
281
285
|
{
|
|
282
286
|
return _freedAddrs.find(addr) != _freedAddrs.end();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//===-
|
|
1
|
+
//===- AEWTO.h -- WTO + pointer-analysis prep for Abstract Interpretation ---//
|
|
2
2
|
//
|
|
3
3
|
// SVF: Static Value-Flow Analysis
|
|
4
4
|
//
|
|
@@ -21,18 +21,18 @@
|
|
|
21
21
|
//===----------------------------------------------------------------------===//
|
|
22
22
|
|
|
23
23
|
/*
|
|
24
|
-
*
|
|
24
|
+
* AEWTO.h
|
|
25
25
|
*
|
|
26
26
|
* Created on: Feb 25, 2026
|
|
27
27
|
* Author: Jiawei Wang
|
|
28
28
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
29
|
+
* Runs Andersen's pointer analysis and builds the per-function WTO
|
|
30
|
+
* (Weak Topological Order) consumed by Abstract Interpretation. Also
|
|
31
|
+
* caches per-cycle ValVar sets for the semi-sparse loop helpers.
|
|
32
32
|
*/
|
|
33
33
|
|
|
34
|
-
#ifndef
|
|
35
|
-
#define
|
|
34
|
+
#ifndef INCLUDE_AE_SVFEXE_AEWTO_H_
|
|
35
|
+
#define INCLUDE_AE_SVFEXE_AEWTO_H_
|
|
36
36
|
|
|
37
37
|
#include "SVFIR/SVFIR.h"
|
|
38
38
|
#include "Graphs/ICFG.h"
|
|
@@ -44,13 +44,13 @@
|
|
|
44
44
|
namespace SVF
|
|
45
45
|
{
|
|
46
46
|
|
|
47
|
-
class
|
|
47
|
+
class AEWTO
|
|
48
48
|
{
|
|
49
49
|
public:
|
|
50
50
|
typedef SCCDetection<CallGraph*> CallGraphSCC;
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
virtual ~
|
|
52
|
+
AEWTO(SVFIR* pag, ICFG* icfg);
|
|
53
|
+
virtual ~AEWTO();
|
|
54
54
|
|
|
55
55
|
/// Accessors for Andersen's results
|
|
56
56
|
AndersenWaveDiff* getPointerAnalysis() const
|
|
@@ -103,4 +103,4 @@ private:
|
|
|
103
103
|
|
|
104
104
|
} // End namespace SVF
|
|
105
105
|
|
|
106
|
-
#endif /*
|
|
106
|
+
#endif /* INCLUDE_AE_SVFEXE_AEWTO_H_ */
|
|
@@ -34,7 +34,6 @@ namespace SVF
|
|
|
34
34
|
{
|
|
35
35
|
|
|
36
36
|
class AbstractInterpretation;
|
|
37
|
-
class AbstractStateManager;
|
|
38
37
|
|
|
39
38
|
/**
|
|
40
39
|
* @class AbsExtAPI
|
|
@@ -53,7 +52,7 @@ public:
|
|
|
53
52
|
* @brief Constructor for AbsExtAPI.
|
|
54
53
|
* @param ae Reference to the AbstractInterpretation instance.
|
|
55
54
|
*/
|
|
56
|
-
AbsExtAPI(
|
|
55
|
+
AbsExtAPI(AbstractInterpretation* ae);
|
|
57
56
|
|
|
58
57
|
/**
|
|
59
58
|
* @brief Initializes the external function map.
|
|
@@ -106,7 +105,7 @@ public:
|
|
|
106
105
|
* @return Reference to the abstract state.
|
|
107
106
|
* @throws Assertion if no trace exists for the node.
|
|
108
107
|
*/
|
|
109
|
-
AbstractState&
|
|
108
|
+
AbstractState& getAbsState(const ICFGNode* node);
|
|
110
109
|
|
|
111
110
|
void collectCheckPoint();
|
|
112
111
|
void checkPointAllSet();
|
|
@@ -114,7 +113,7 @@ public:
|
|
|
114
113
|
Set<const CallICFGNode*> checkpoints; // for CI check
|
|
115
114
|
|
|
116
115
|
protected:
|
|
117
|
-
|
|
116
|
+
AbstractInterpretation* ae; ///< Owning AbstractInterpretation; provides state access.
|
|
118
117
|
SVFIR* svfir; ///< Pointer to the SVF intermediate representation.
|
|
119
118
|
ICFG* icfg; ///< Pointer to the interprocedural control flow graph.
|
|
120
119
|
Map<std::string, std::function<void(const CallICFGNode*)>> func_map; ///< Map of function names to handlers.
|
|
@@ -31,11 +31,11 @@
|
|
|
31
31
|
#pragma once
|
|
32
32
|
#include "AE/Core/AbstractState.h"
|
|
33
33
|
#include "AE/Core/ICFGWTO.h"
|
|
34
|
-
#include "AE/Svfexe/AbstractStateManager.h"
|
|
35
34
|
#include "AE/Svfexe/AEDetector.h"
|
|
36
|
-
#include "AE/Svfexe/
|
|
35
|
+
#include "AE/Svfexe/AEWTO.h"
|
|
37
36
|
#include "AE/Svfexe/AbsExtAPI.h"
|
|
38
37
|
#include "AE/Svfexe/AEStat.h"
|
|
38
|
+
#include "SVFIR/SVFIR.h"
|
|
39
39
|
#include "Util/SVFBugReport.h"
|
|
40
40
|
#include "Graphs/SCC.h"
|
|
41
41
|
#include "Graphs/CallGraph.h"
|
|
@@ -47,10 +47,16 @@ class AbstractInterpretation;
|
|
|
47
47
|
class AbsExtAPI;
|
|
48
48
|
class AEStat;
|
|
49
49
|
class AEAPI;
|
|
50
|
+
class AndersenWaveDiff;
|
|
50
51
|
|
|
51
52
|
template<typename T> class FILOWorkList;
|
|
52
53
|
|
|
53
|
-
/// AbstractInterpretation is same as Abstract Execution
|
|
54
|
+
/// AbstractInterpretation is same as Abstract Execution.
|
|
55
|
+
///
|
|
56
|
+
/// Owns the per-node abstract trace and exposes the read/write API
|
|
57
|
+
/// directly (no separate state-manager indirection). Sparse modes are
|
|
58
|
+
/// implemented as subclasses that override the virtual hooks below
|
|
59
|
+
/// (cycle helpers, ValVar accessors, joinStates, def/use queries).
|
|
54
60
|
class AbstractInterpretation
|
|
55
61
|
{
|
|
56
62
|
friend class AEStat;
|
|
@@ -88,10 +94,7 @@ public:
|
|
|
88
94
|
WIDEN_NARROW
|
|
89
95
|
};
|
|
90
96
|
|
|
91
|
-
|
|
92
|
-
AbstractInterpretation();
|
|
93
|
-
|
|
94
|
-
virtual void runOnModule(ICFG* icfg);
|
|
97
|
+
virtual void runOnModule();
|
|
95
98
|
|
|
96
99
|
/// Destructor
|
|
97
100
|
virtual ~AbstractInterpretation();
|
|
@@ -105,12 +108,12 @@ public:
|
|
|
105
108
|
/// Get all entry point functions (functions without callers)
|
|
106
109
|
std::deque<const FunObjVar*> collectProgEntryFuns();
|
|
107
110
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
111
|
+
/// Factory: returns the singleton instance. The concrete class is
|
|
112
|
+
/// chosen once, on first call, from `Options::AESparsity()`:
|
|
113
|
+
/// `SemiSparseAbstractInterpretation` for SemiSparse,
|
|
114
|
+
/// `FullSparseAbstractInterpretation` for Sparse, otherwise the
|
|
115
|
+
/// dense base. Must be called only after the option parser has run.
|
|
116
|
+
static AbstractInterpretation& getAEInstance();
|
|
114
117
|
|
|
115
118
|
void addDetector(std::unique_ptr<AEDetector> detector)
|
|
116
119
|
{
|
|
@@ -123,50 +126,104 @@ public:
|
|
|
123
126
|
return svfir->getSVFVar(varId);
|
|
124
127
|
}
|
|
125
128
|
|
|
126
|
-
|
|
127
|
-
AbstractStateManager* getStateMgr()
|
|
128
|
-
{
|
|
129
|
-
return svfStateMgr;
|
|
130
|
-
}
|
|
129
|
+
// ---- Abstract Value Access ----------------------------------------
|
|
131
130
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
///
|
|
136
|
-
///
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
131
|
+
/// Read a top-level variable's abstract value. Dense base does a
|
|
132
|
+
/// direct trace lookup; sparse subclasses override with their own
|
|
133
|
+
/// resolution chain (def-site walk, call-result fallback, etc.).
|
|
134
|
+
/// All three overloads are virtual so full-sparse can route ObjVar
|
|
135
|
+
/// reads through the SVFG.
|
|
136
|
+
virtual const AbstractValue& getAbsValue(const ValVar* var, const ICFGNode* node);
|
|
137
|
+
virtual const AbstractValue& getAbsValue(const ObjVar* var, const ICFGNode* node);
|
|
138
|
+
virtual const AbstractValue& getAbsValue(const SVFVar* var, const ICFGNode* node);
|
|
141
139
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
140
|
+
/// Side-effect-free existence check.
|
|
141
|
+
virtual bool hasAbsValue(const ValVar* var, const ICFGNode* node) const;
|
|
142
|
+
virtual bool hasAbsValue(const ObjVar* var, const ICFGNode* node) const;
|
|
143
|
+
virtual bool hasAbsValue(const SVFVar* var, const ICFGNode* node) const;
|
|
146
144
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
145
|
+
/// Write a variable's abstract value. Sparse subclasses re-route
|
|
146
|
+
/// ValVar writes to the def-site.
|
|
147
|
+
virtual void updateAbsValue(const ValVar* var, const AbstractValue& val, const ICFGNode* node);
|
|
148
|
+
virtual void updateAbsValue(const ObjVar* var, const AbstractValue& val, const ICFGNode* node);
|
|
149
|
+
virtual void updateAbsValue(const SVFVar* var, const AbstractValue& val, const ICFGNode* node);
|
|
151
150
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
151
|
+
// ---- State Access -------------------------------------------------
|
|
152
|
+
|
|
153
|
+
AbstractState& getAbsState(const ICFGNode* node);
|
|
154
|
+
|
|
155
|
+
/// Replace the state at `node`. Sparse subclasses replace only the
|
|
156
|
+
/// ObjVar map (ValVars live at def-sites).
|
|
157
|
+
virtual void updateAbsState(const ICFGNode* node, const AbstractState& state);
|
|
158
|
+
|
|
159
|
+
/// Join `src` into `dst` with sparsity-aware semantics. Dense merges
|
|
160
|
+
/// everything; semi-sparse skips ValVars.
|
|
161
|
+
virtual void joinStates(AbstractState& dst, const AbstractState& src);
|
|
162
|
+
|
|
163
|
+
bool hasAbsState(const ICFGNode* node);
|
|
156
164
|
|
|
157
|
-
|
|
165
|
+
void getAbsState(const Set<const ValVar*>& vars, AbstractState& result, const ICFGNode* node);
|
|
166
|
+
void getAbsState(const Set<const ObjVar*>& vars, AbstractState& result, const ICFGNode* node);
|
|
167
|
+
void getAbsState(const Set<const SVFVar*>& vars, AbstractState& result, const ICFGNode* node);
|
|
168
|
+
|
|
169
|
+
// ---- GEP / Load-Store / Type Helpers ------------------------------
|
|
170
|
+
|
|
171
|
+
IntervalValue getGepElementIndex(const GepStmt* gep);
|
|
172
|
+
IntervalValue getGepByteOffset(const GepStmt* gep);
|
|
173
|
+
AddressValue getGepObjAddrs(const ValVar* pointer, IntervalValue offset);
|
|
174
|
+
|
|
175
|
+
AbstractValue loadValue(const ValVar* pointer, const ICFGNode* node);
|
|
176
|
+
void storeValue(const ValVar* pointer, const AbstractValue& val, const ICFGNode* node);
|
|
177
|
+
|
|
178
|
+
const SVFType* getPointeeElement(const ObjVar* var, const ICFGNode* node);
|
|
179
|
+
u32_t getAllocaInstByteSize(const AddrStmt* addr);
|
|
180
|
+
|
|
181
|
+
// ---- Direct Trace Access ------------------------------------------
|
|
182
|
+
|
|
183
|
+
Map<const ICFGNode*, AbstractState>& getTrace()
|
|
158
184
|
{
|
|
159
|
-
return
|
|
185
|
+
return abstractTrace;
|
|
160
186
|
}
|
|
161
|
-
|
|
162
|
-
inline void updateAbsValue(const SVFVar* var, const AbstractValue& val, const ICFGNode* node)
|
|
187
|
+
AbstractState& operator[](const ICFGNode* node)
|
|
163
188
|
{
|
|
164
|
-
|
|
189
|
+
return abstractTrace[node];
|
|
165
190
|
}
|
|
166
191
|
|
|
192
|
+
// ---- Def/Use site queries (sparsity-aware) ------------------------
|
|
193
|
+
|
|
194
|
+
virtual Set<const ICFGNode*> getUseSitesOfObjVar(const ObjVar* obj, const ICFGNode* node) const;
|
|
195
|
+
virtual Set<const ICFGNode*> getUseSitesOfValVar(const ValVar* var) const;
|
|
196
|
+
virtual const ICFGNode* getDefSiteOfValVar(const ValVar* var) const;
|
|
197
|
+
virtual const ICFGNode* getDefSiteOfObjVar(const ObjVar* obj, const ICFGNode* node) const;
|
|
198
|
+
|
|
167
199
|
/// Propagate an ObjVar's abstract value from defSite to all its use-sites.
|
|
168
200
|
void propagateObjVarAbsVal(const ObjVar* var, const ICFGNode* defSite);
|
|
169
201
|
|
|
202
|
+
protected:
|
|
203
|
+
/// Factory-only construction. External callers must use getAEInstance();
|
|
204
|
+
/// `SparseAbstractInterpretation` reaches this via its own ctor.
|
|
205
|
+
AbstractInterpretation();
|
|
206
|
+
|
|
207
|
+
// ---- Cycle helpers overridden by SparseAbstractInterpretation ----
|
|
208
|
+
// The dense versions write only to trace[cycle_head]. The semi-sparse
|
|
209
|
+
// subclass adds def-site scatter on top for body ValVars.
|
|
210
|
+
|
|
211
|
+
/// Build a full cycle-head AbstractState. Dense default: trace[cycle_head]
|
|
212
|
+
/// as-is. Semi-sparse subclass: also pull cycle ValVars from def-sites.
|
|
213
|
+
virtual AbstractState getFullCycleHeadState(const ICFGCycleWTO* cycle);
|
|
214
|
+
|
|
215
|
+
/// Widen prev with cur; write the widened state to trace[cycle_head].
|
|
216
|
+
/// Returns true when next == prev (fixpoint). Semi-sparse subclass
|
|
217
|
+
/// additionally scatters ValVars to their def-sites.
|
|
218
|
+
virtual bool widenCycleState(const AbstractState& prev, const AbstractState& cur,
|
|
219
|
+
const ICFGCycleWTO* cycle);
|
|
220
|
+
|
|
221
|
+
/// Narrow prev with cur; write the narrowed state back. Returns true
|
|
222
|
+
/// when narrowing is disabled or the narrowed state equals prev.
|
|
223
|
+
/// Semi-sparse subclass scatters the narrowed ValVars on non-fixpoint.
|
|
224
|
+
virtual bool narrowCycleState(const AbstractState& prev, const AbstractState& cur,
|
|
225
|
+
const ICFGCycleWTO* cycle);
|
|
226
|
+
|
|
170
227
|
private:
|
|
171
228
|
/// Initialize abstract state for the global ICFG node and process global statements
|
|
172
229
|
virtual void handleGlobalNode();
|
|
@@ -185,30 +242,6 @@ private:
|
|
|
185
242
|
/// Handle a WTO cycle (loop or recursive function) using widening/narrowing iteration
|
|
186
243
|
virtual void handleLoopOrRecursion(const ICFGCycleWTO* cycle, const CallICFGNode* caller = nullptr);
|
|
187
244
|
|
|
188
|
-
// ---- Semi-sparse cycle helpers ----
|
|
189
|
-
// ValVars whose def-site is inside the cycle but NOT cycle_head do not
|
|
190
|
-
// flow through cycle_head's merge in semi-sparse mode, so the around-merge
|
|
191
|
-
// widening cannot observe them. getFullCycleHeadState pulls these ValVars
|
|
192
|
-
// into a single AbstractState snapshot so widen/narrow can treat ValVars
|
|
193
|
-
// and ObjVars uniformly; after widen/narrow we scatter the ValVars back
|
|
194
|
-
// to their def-sites.
|
|
195
|
-
|
|
196
|
-
/// Build a full cycle-head AbstractState: the ObjVars currently at
|
|
197
|
-
/// cycle_head combined with every cycle ValVar pulled from its
|
|
198
|
-
/// def-site. Skips ValVars without a stored value to avoid the
|
|
199
|
-
/// top-fallback contamination. In dense mode this is equivalent to
|
|
200
|
-
/// trace[cycle_head] since ValVars already live there.
|
|
201
|
-
AbstractState getFullCycleHeadState(const ICFGCycleWTO* cycle);
|
|
202
|
-
|
|
203
|
-
/// Widen prev with cur; write the widened state to trace[cycle_head]
|
|
204
|
-
/// and scatter its ValVars back to their def-sites. Returns true
|
|
205
|
-
/// when the widened result equals prev (fixpoint).
|
|
206
|
-
bool widenCycleState(const AbstractState& prev, const AbstractState& cur,
|
|
207
|
-
const ICFGCycleWTO* cycle);
|
|
208
|
-
/// Narrow prev with cur; write the narrowed state back and scatter.
|
|
209
|
-
bool narrowCycleState(const AbstractState& prev, const AbstractState& cur,
|
|
210
|
-
const ICFGCycleWTO* cycle);
|
|
211
|
-
|
|
212
245
|
/// Handle a function body via worklist-driven WTO traversal starting from funEntry
|
|
213
246
|
void handleFunction(const ICFGNode* funEntry, const CallICFGNode* caller = nullptr);
|
|
214
247
|
|
|
@@ -246,8 +279,6 @@ private:
|
|
|
246
279
|
|
|
247
280
|
void updateStateOnPhi(const PhiStmt *phi);
|
|
248
281
|
|
|
249
|
-
/// protected data members, also used in subclasses
|
|
250
|
-
SVFIR* svfir;
|
|
251
282
|
/// Execution State, used to store the Interval Value of every SVF variable
|
|
252
283
|
AEAPI* api{nullptr};
|
|
253
284
|
|
|
@@ -255,8 +286,6 @@ private:
|
|
|
255
286
|
CallGraph* callGraph;
|
|
256
287
|
AEStat* stat;
|
|
257
288
|
|
|
258
|
-
PreAnalysis* preAnalysis{nullptr};
|
|
259
|
-
|
|
260
289
|
AbsExtAPI* getUtils()
|
|
261
290
|
{
|
|
262
291
|
return utils;
|
|
@@ -272,18 +301,22 @@ private:
|
|
|
272
301
|
|
|
273
302
|
bool skipRecursiveCall(const CallICFGNode* callNode);
|
|
274
303
|
const FunObjVar* getCallee(const CallICFGNode* callNode);
|
|
275
|
-
bool shouldApplyNarrowing(const FunObjVar* fun);
|
|
276
304
|
|
|
277
305
|
// there data should be shared with subclasses
|
|
278
306
|
Map<std::string, std::function<void(const CallICFGNode*)>> func_map;
|
|
279
307
|
|
|
280
|
-
AbstractStateManager* svfStateMgr{nullptr}; // state management (owns abstractTrace)
|
|
281
308
|
Set<const ICFGNode*> allAnalyzedNodes; // All nodes ever analyzed (across all entry points)
|
|
282
309
|
std::string moduleName;
|
|
283
310
|
|
|
284
311
|
std::vector<std::unique_ptr<AEDetector>> detectors;
|
|
285
312
|
AbsExtAPI* utils;
|
|
286
313
|
|
|
314
|
+
protected:
|
|
315
|
+
/// Data and helpers reachable from SparseAbstractInterpretation.
|
|
316
|
+
SVFIR* svfir{nullptr};
|
|
317
|
+
AEWTO* preAnalysis{nullptr};
|
|
318
|
+
Map<const ICFGNode*, AbstractState> abstractTrace; ///< per-node trace; owned here
|
|
287
319
|
|
|
320
|
+
bool shouldApplyNarrowing(const FunObjVar* fun);
|
|
288
321
|
};
|
|
289
322
|
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
//===- SparseAbstractInterpretation.h -- Sparse Abstract Execution------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-> <Yulei Sui>
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
// This program is free software: you can redistribute it and/or modify
|
|
9
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
10
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
// (at your option) any later version.
|
|
12
|
+
|
|
13
|
+
// This program is distributed in the hope that it will be useful,
|
|
14
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
// GNU Affero General Public License for more details.
|
|
17
|
+
|
|
18
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
19
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
//
|
|
21
|
+
//===---------------------------------------------------------------------===//
|
|
22
|
+
|
|
23
|
+
#ifndef INCLUDE_AE_SVFEXE_SPARSEABSTRACTINTERPRETATION_H_
|
|
24
|
+
#define INCLUDE_AE_SVFEXE_SPARSEABSTRACTINTERPRETATION_H_
|
|
25
|
+
|
|
26
|
+
#include "AE/Svfexe/AbstractInterpretation.h"
|
|
27
|
+
|
|
28
|
+
namespace SVF
|
|
29
|
+
{
|
|
30
|
+
|
|
31
|
+
class SVFG;
|
|
32
|
+
|
|
33
|
+
/// Abstract Interpretation for `Options::AESparsity::SemiSparse`.
|
|
34
|
+
///
|
|
35
|
+
/// ValVars live at their SVFG-style def-sites: reads pull from there,
|
|
36
|
+
/// writes go there, state merges replace only the ObjVar map and skip
|
|
37
|
+
/// the ValVar map, and the cycle helpers gather/scatter cycle ValVars
|
|
38
|
+
/// around each widening iteration.
|
|
39
|
+
class SemiSparseAbstractInterpretation : public AbstractInterpretation
|
|
40
|
+
{
|
|
41
|
+
public:
|
|
42
|
+
SemiSparseAbstractInterpretation()
|
|
43
|
+
{
|
|
44
|
+
preAnalysis->initCycleValVars();
|
|
45
|
+
}
|
|
46
|
+
~SemiSparseAbstractInterpretation() override = default;
|
|
47
|
+
|
|
48
|
+
protected:
|
|
49
|
+
AbstractState getFullCycleHeadState(const ICFGCycleWTO* cycle) override;
|
|
50
|
+
|
|
51
|
+
bool widenCycleState(const AbstractState& prev,
|
|
52
|
+
const AbstractState& cur,
|
|
53
|
+
const ICFGCycleWTO* cycle) override;
|
|
54
|
+
|
|
55
|
+
bool narrowCycleState(const AbstractState& prev,
|
|
56
|
+
const AbstractState& cur,
|
|
57
|
+
const ICFGCycleWTO* cycle) override;
|
|
58
|
+
|
|
59
|
+
const AbstractValue& getAbsValue(const ValVar* var, const ICFGNode* node) override;
|
|
60
|
+
using AbstractInterpretation::getAbsValue;
|
|
61
|
+
|
|
62
|
+
bool hasAbsValue(const ValVar* var, const ICFGNode* node) const override;
|
|
63
|
+
using AbstractInterpretation::hasAbsValue;
|
|
64
|
+
|
|
65
|
+
void updateAbsValue(const ValVar* var, const AbstractValue& val, const ICFGNode* node) override;
|
|
66
|
+
using AbstractInterpretation::updateAbsValue;
|
|
67
|
+
|
|
68
|
+
void updateAbsState(const ICFGNode* node, const AbstractState& state) override;
|
|
69
|
+
|
|
70
|
+
void joinStates(AbstractState& dst, const AbstractState& src) override;
|
|
71
|
+
|
|
72
|
+
const ICFGNode* getICFGNode(const ValVar* var) const;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/// Abstract Interpretation for `Options::AESparsity::Sparse` (full-sparse).
|
|
76
|
+
///
|
|
77
|
+
/// In full-sparse mode both ValVars and ObjVars live at their SVFG
|
|
78
|
+
/// def-sites; reads query the SVFG for the reaching-def site, writes
|
|
79
|
+
/// happen at def-sites. ValVar reads currently assert(false) until the
|
|
80
|
+
/// SVFG-backed resolution lands (see `doc/plan-full-sparse.md`); cycle
|
|
81
|
+
/// helpers are inherited from the semi-sparse parent and will also need
|
|
82
|
+
/// extension for ObjVars.
|
|
83
|
+
class FullSparseAbstractInterpretation : public SemiSparseAbstractInterpretation
|
|
84
|
+
{
|
|
85
|
+
public:
|
|
86
|
+
FullSparseAbstractInterpretation()
|
|
87
|
+
{
|
|
88
|
+
buildSVFG();
|
|
89
|
+
}
|
|
90
|
+
~FullSparseAbstractInterpretation() override;
|
|
91
|
+
|
|
92
|
+
// Full-sparse ValVar resolution will route through the SVFG once
|
|
93
|
+
// implemented; fail loudly until then rather than silently inherit
|
|
94
|
+
// semi-sparse semantics.
|
|
95
|
+
const AbstractValue& getAbsValue(const ValVar* var, const ICFGNode* node) override;
|
|
96
|
+
using SemiSparseAbstractInterpretation::getAbsValue;
|
|
97
|
+
|
|
98
|
+
bool hasAbsValue(const ValVar* var, const ICFGNode* node) const override;
|
|
99
|
+
using SemiSparseAbstractInterpretation::hasAbsValue;
|
|
100
|
+
|
|
101
|
+
Set<const ICFGNode*> getUseSitesOfObjVar(const ObjVar* obj, const ICFGNode* node) const override;
|
|
102
|
+
Set<const ICFGNode*> getUseSitesOfValVar(const ValVar* var) const override;
|
|
103
|
+
const ICFGNode* getDefSiteOfValVar(const ValVar* var) const override;
|
|
104
|
+
const ICFGNode* getDefSiteOfObjVar(const ObjVar* obj, const ICFGNode* node) const override;
|
|
105
|
+
|
|
106
|
+
protected:
|
|
107
|
+
/// Build the SVFG on top of the semi-sparse precompute.
|
|
108
|
+
void buildSVFG();
|
|
109
|
+
|
|
110
|
+
SVFG* svfg{nullptr};
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
} // namespace SVF
|
|
114
|
+
|
|
115
|
+
#endif /* INCLUDE_AE_SVFEXE_SPARSEABSTRACTINTERPRETATION_H_ */
|
|
@@ -81,7 +81,7 @@ if(NOT CMAKE_VERSION VERSION_LESS "3.23.0")
|
|
|
81
81
|
FILE_SET "HEADERS"
|
|
82
82
|
TYPE "HEADERS"
|
|
83
83
|
BASE_DIRS "${_IMPORT_PREFIX}/include"
|
|
84
|
-
FILES "${_IMPORT_PREFIX}/include/AE/Core/AbstractState.h" "${_IMPORT_PREFIX}/include/AE/Core/AbstractValue.h" "${_IMPORT_PREFIX}/include/AE/Core/AddressValue.h" "${_IMPORT_PREFIX}/include/AE/Core/ICFGWTO.h" "${_IMPORT_PREFIX}/include/AE/Core/IntervalValue.h" "${_IMPORT_PREFIX}/include/AE/Core/NumericValue.h" "${_IMPORT_PREFIX}/include/AE/Core/RelExeState.h" "${_IMPORT_PREFIX}/include/AE/Core/RelationSolver.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AEDetector.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AEStat.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/
|
|
84
|
+
FILES "${_IMPORT_PREFIX}/include/AE/Core/AbstractState.h" "${_IMPORT_PREFIX}/include/AE/Core/AbstractValue.h" "${_IMPORT_PREFIX}/include/AE/Core/AddressValue.h" "${_IMPORT_PREFIX}/include/AE/Core/ICFGWTO.h" "${_IMPORT_PREFIX}/include/AE/Core/IntervalValue.h" "${_IMPORT_PREFIX}/include/AE/Core/NumericValue.h" "${_IMPORT_PREFIX}/include/AE/Core/RelExeState.h" "${_IMPORT_PREFIX}/include/AE/Core/RelationSolver.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AEDetector.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AEStat.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AEWTO.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AbsExtAPI.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AbstractInterpretation.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/SparseAbstractInterpretation.h" "${_IMPORT_PREFIX}/include/CFL/CFGNormalizer.h" "${_IMPORT_PREFIX}/include/CFL/CFGrammar.h" "${_IMPORT_PREFIX}/include/CFL/CFLAlias.h" "${_IMPORT_PREFIX}/include/CFL/CFLBase.h" "${_IMPORT_PREFIX}/include/CFL/CFLGramGraphChecker.h" "${_IMPORT_PREFIX}/include/CFL/CFLGraphBuilder.h" "${_IMPORT_PREFIX}/include/CFL/CFLSVFGBuilder.h" "${_IMPORT_PREFIX}/include/CFL/CFLSolver.h" "${_IMPORT_PREFIX}/include/CFL/CFLStat.h" "${_IMPORT_PREFIX}/include/CFL/CFLVF.h" "${_IMPORT_PREFIX}/include/CFL/GrammarBuilder.h" "${_IMPORT_PREFIX}/include/DDA/ContextDDA.h" "${_IMPORT_PREFIX}/include/DDA/DDAClient.h" "${_IMPORT_PREFIX}/include/DDA/DDAPass.h" "${_IMPORT_PREFIX}/include/DDA/DDAStat.h" "${_IMPORT_PREFIX}/include/DDA/DDAVFSolver.h" "${_IMPORT_PREFIX}/include/DDA/FlowDDA.h" "${_IMPORT_PREFIX}/include/FastCluster/fastcluster.h" "${_IMPORT_PREFIX}/include/Graphs/BasicBlockG.h" "${_IMPORT_PREFIX}/include/Graphs/CDG.h" "${_IMPORT_PREFIX}/include/Graphs/CFLGraph.h" "${_IMPORT_PREFIX}/include/Graphs/CHG.h" "${_IMPORT_PREFIX}/include/Graphs/CallGraph.h" "${_IMPORT_PREFIX}/include/Graphs/ConsG.h" "${_IMPORT_PREFIX}/include/Graphs/ConsGEdge.h" "${_IMPORT_PREFIX}/include/Graphs/ConsGNode.h" "${_IMPORT_PREFIX}/include/Graphs/DOTGraphTraits.h" "${_IMPORT_PREFIX}/include/Graphs/GenericGraph.h" "${_IMPORT_PREFIX}/include/Graphs/GraphPrinter.h" "${_IMPORT_PREFIX}/include/Graphs/GraphTraits.h" "${_IMPORT_PREFIX}/include/Graphs/GraphWriter.h" "${_IMPORT_PREFIX}/include/Graphs/ICFG.h" "${_IMPORT_PREFIX}/include/Graphs/ICFGEdge.h" "${_IMPORT_PREFIX}/include/Graphs/ICFGNode.h" "${_IMPORT_PREFIX}/include/Graphs/ICFGStat.h" "${_IMPORT_PREFIX}/include/Graphs/IRGraph.h" "${_IMPORT_PREFIX}/include/Graphs/SCC.h" "${_IMPORT_PREFIX}/include/Graphs/SVFG.h" "${_IMPORT_PREFIX}/include/Graphs/SVFGEdge.h" "${_IMPORT_PREFIX}/include/Graphs/SVFGNode.h" "${_IMPORT_PREFIX}/include/Graphs/SVFGOPT.h" "${_IMPORT_PREFIX}/include/Graphs/SVFGStat.h" "${_IMPORT_PREFIX}/include/Graphs/ThreadCallGraph.h" "${_IMPORT_PREFIX}/include/Graphs/VFG.h" "${_IMPORT_PREFIX}/include/Graphs/VFGEdge.h" "${_IMPORT_PREFIX}/include/Graphs/VFGNode.h" "${_IMPORT_PREFIX}/include/Graphs/WTO.h" "${_IMPORT_PREFIX}/include/MSSA/MSSAMuChi.h" "${_IMPORT_PREFIX}/include/MSSA/MemPartition.h" "${_IMPORT_PREFIX}/include/MSSA/MemRegion.h" "${_IMPORT_PREFIX}/include/MSSA/MemSSA.h" "${_IMPORT_PREFIX}/include/MSSA/SVFGBuilder.h" "${_IMPORT_PREFIX}/include/MTA/LockAnalysis.h" "${_IMPORT_PREFIX}/include/MTA/MHP.h" "${_IMPORT_PREFIX}/include/MTA/MTA.h" "${_IMPORT_PREFIX}/include/MTA/MTAStat.h" "${_IMPORT_PREFIX}/include/MTA/TCT.h" "${_IMPORT_PREFIX}/include/MemoryModel/AbstractPointsToDS.h" "${_IMPORT_PREFIX}/include/MemoryModel/AccessPath.h" "${_IMPORT_PREFIX}/include/MemoryModel/ConditionalPT.h" "${_IMPORT_PREFIX}/include/MemoryModel/MutablePointsToDS.h" "${_IMPORT_PREFIX}/include/MemoryModel/PersistentPointsToCache.h" "${_IMPORT_PREFIX}/include/MemoryModel/PersistentPointsToDS.h" "${_IMPORT_PREFIX}/include/MemoryModel/PointerAnalysis.h" "${_IMPORT_PREFIX}/include/MemoryModel/PointerAnalysisImpl.h" "${_IMPORT_PREFIX}/include/MemoryModel/PointsTo.h" "${_IMPORT_PREFIX}/include/MemoryModel/SVFLoop.h" "${_IMPORT_PREFIX}/include/SABER/DoubleFreeChecker.h" "${_IMPORT_PREFIX}/include/SABER/FileChecker.h" "${_IMPORT_PREFIX}/include/SABER/LeakChecker.h" "${_IMPORT_PREFIX}/include/SABER/ProgSlice.h" "${_IMPORT_PREFIX}/include/SABER/SaberCheckerAPI.h" "${_IMPORT_PREFIX}/include/SABER/SaberCondAllocator.h" "${_IMPORT_PREFIX}/include/SABER/SaberSVFGBuilder.h" "${_IMPORT_PREFIX}/include/SABER/SrcSnkDDA.h" "${_IMPORT_PREFIX}/include/SABER/SrcSnkSolver.h" "${_IMPORT_PREFIX}/include/SVFIR/ObjTypeInfo.h" "${_IMPORT_PREFIX}/include/SVFIR/PAGBuilderFromFile.h" "${_IMPORT_PREFIX}/include/SVFIR/SVFIR.h" "${_IMPORT_PREFIX}/include/SVFIR/SVFStatements.h" "${_IMPORT_PREFIX}/include/SVFIR/SVFType.h" "${_IMPORT_PREFIX}/include/SVFIR/SVFValue.h" "${_IMPORT_PREFIX}/include/SVFIR/SVFVariables.h" "${_IMPORT_PREFIX}/include/Util/Annotator.h" "${_IMPORT_PREFIX}/include/Util/BitVector.h" "${_IMPORT_PREFIX}/include/Util/CDGBuilder.h" "${_IMPORT_PREFIX}/include/Util/CallGraphBuilder.h" "${_IMPORT_PREFIX}/include/Util/Casting.h" "${_IMPORT_PREFIX}/include/Util/CommandLine.h" "${_IMPORT_PREFIX}/include/Util/CoreBitVector.h" "${_IMPORT_PREFIX}/include/Util/CxtStmt.h" "${_IMPORT_PREFIX}/include/Util/DPItem.h" "${_IMPORT_PREFIX}/include/Util/ExtAPI.h" "${_IMPORT_PREFIX}/include/Util/GeneralType.h" "${_IMPORT_PREFIX}/include/Util/GraphReachSolver.h" "${_IMPORT_PREFIX}/include/Util/NodeIDAllocator.h" "${_IMPORT_PREFIX}/include/Util/Options.h" "${_IMPORT_PREFIX}/include/Util/PTAStat.h" "${_IMPORT_PREFIX}/include/Util/SVFBugReport.h" "${_IMPORT_PREFIX}/include/Util/SVFLoopAndDomInfo.h" "${_IMPORT_PREFIX}/include/Util/SVFStat.h" "${_IMPORT_PREFIX}/include/Util/SVFUtil.h" "${_IMPORT_PREFIX}/include/Util/SparseBitVector.h" "${_IMPORT_PREFIX}/include/Util/ThreadAPI.h" "${_IMPORT_PREFIX}/include/Util/WorkList.h" "${_IMPORT_PREFIX}/include/Util/Z3Expr.h" "${_IMPORT_PREFIX}/include/Util/cJSON.h" "${_IMPORT_PREFIX}/include/Util/iterator.h" "${_IMPORT_PREFIX}/include/Util/iterator_range.h" "${_IMPORT_PREFIX}/include/WPA/Andersen.h" "${_IMPORT_PREFIX}/include/WPA/AndersenPWC.h" "${_IMPORT_PREFIX}/include/WPA/CSC.h" "${_IMPORT_PREFIX}/include/WPA/FlowSensitive.h" "${_IMPORT_PREFIX}/include/WPA/Steensgaard.h" "${_IMPORT_PREFIX}/include/WPA/TypeAnalysis.h" "${_IMPORT_PREFIX}/include/WPA/VersionedFlowSensitive.h" "${_IMPORT_PREFIX}/include/WPA/WPAFSSolver.h" "${_IMPORT_PREFIX}/include/WPA/WPAPass.h" "${_IMPORT_PREFIX}/include/WPA/WPASolver.h" "${_IMPORT_PREFIX}/include/WPA/WPAStat.h"
|
|
85
85
|
)
|
|
86
86
|
else()
|
|
87
87
|
set_property(TARGET SVF::SvfCore
|
|
Binary file
|
package/SVF-osx/bin/ae
CHANGED
|
Binary file
|
|
@@ -261,7 +261,6 @@ public:
|
|
|
261
261
|
/// domain join with other, important! other widen this.
|
|
262
262
|
void joinWith(const AbstractState&other);
|
|
263
263
|
|
|
264
|
-
|
|
265
264
|
/// Replace address-taken (ObjVar) state with other's, preserving ValVar state.
|
|
266
265
|
void updateAddrStateOnly(const AbstractState& other)
|
|
267
266
|
{
|
|
@@ -277,6 +276,11 @@ public:
|
|
|
277
276
|
_freedAddrs.insert(addr);
|
|
278
277
|
}
|
|
279
278
|
|
|
279
|
+
const Set<NodeID>& getFreedAddrs() const
|
|
280
|
+
{
|
|
281
|
+
return _freedAddrs;
|
|
282
|
+
}
|
|
283
|
+
|
|
280
284
|
bool isFreedMem(u32_t addr) const
|
|
281
285
|
{
|
|
282
286
|
return _freedAddrs.find(addr) != _freedAddrs.end();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//===-
|
|
1
|
+
//===- AEWTO.h -- WTO + pointer-analysis prep for Abstract Interpretation ---//
|
|
2
2
|
//
|
|
3
3
|
// SVF: Static Value-Flow Analysis
|
|
4
4
|
//
|
|
@@ -21,18 +21,18 @@
|
|
|
21
21
|
//===----------------------------------------------------------------------===//
|
|
22
22
|
|
|
23
23
|
/*
|
|
24
|
-
*
|
|
24
|
+
* AEWTO.h
|
|
25
25
|
*
|
|
26
26
|
* Created on: Feb 25, 2026
|
|
27
27
|
* Author: Jiawei Wang
|
|
28
28
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
29
|
+
* Runs Andersen's pointer analysis and builds the per-function WTO
|
|
30
|
+
* (Weak Topological Order) consumed by Abstract Interpretation. Also
|
|
31
|
+
* caches per-cycle ValVar sets for the semi-sparse loop helpers.
|
|
32
32
|
*/
|
|
33
33
|
|
|
34
|
-
#ifndef
|
|
35
|
-
#define
|
|
34
|
+
#ifndef INCLUDE_AE_SVFEXE_AEWTO_H_
|
|
35
|
+
#define INCLUDE_AE_SVFEXE_AEWTO_H_
|
|
36
36
|
|
|
37
37
|
#include "SVFIR/SVFIR.h"
|
|
38
38
|
#include "Graphs/ICFG.h"
|
|
@@ -44,13 +44,13 @@
|
|
|
44
44
|
namespace SVF
|
|
45
45
|
{
|
|
46
46
|
|
|
47
|
-
class
|
|
47
|
+
class AEWTO
|
|
48
48
|
{
|
|
49
49
|
public:
|
|
50
50
|
typedef SCCDetection<CallGraph*> CallGraphSCC;
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
virtual ~
|
|
52
|
+
AEWTO(SVFIR* pag, ICFG* icfg);
|
|
53
|
+
virtual ~AEWTO();
|
|
54
54
|
|
|
55
55
|
/// Accessors for Andersen's results
|
|
56
56
|
AndersenWaveDiff* getPointerAnalysis() const
|
|
@@ -103,4 +103,4 @@ private:
|
|
|
103
103
|
|
|
104
104
|
} // End namespace SVF
|
|
105
105
|
|
|
106
|
-
#endif /*
|
|
106
|
+
#endif /* INCLUDE_AE_SVFEXE_AEWTO_H_ */
|