svf-tools 1.0.1258 → 1.0.1260
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1260",
|
|
4
4
|
"description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
#include "AE/Svfexe/AEStat.h"
|
|
38
38
|
#include "SVFIR/SVFIR.h"
|
|
39
39
|
#include "Util/SVFBugReport.h"
|
|
40
|
+
#include "Util/WorkList.h"
|
|
40
41
|
#include "Graphs/SCC.h"
|
|
41
42
|
#include "Graphs/CallGraph.h"
|
|
42
|
-
#include <deque>
|
|
43
43
|
|
|
44
44
|
namespace SVF
|
|
45
45
|
{
|
|
@@ -94,6 +94,12 @@ public:
|
|
|
94
94
|
WIDEN_NARROW
|
|
95
95
|
};
|
|
96
96
|
|
|
97
|
+
enum AEFunEntryMode
|
|
98
|
+
{
|
|
99
|
+
MAIN,
|
|
100
|
+
NO_MAIN
|
|
101
|
+
};
|
|
102
|
+
|
|
97
103
|
virtual void runOnModule();
|
|
98
104
|
|
|
99
105
|
/// Destructor
|
|
@@ -106,7 +112,7 @@ public:
|
|
|
106
112
|
void analyzeFromAllProgEntries();
|
|
107
113
|
|
|
108
114
|
/// Get all entry point functions (functions without callers)
|
|
109
|
-
|
|
115
|
+
FIFOWorkList<const FunObjVar*> collectProgEntryFuns();
|
|
110
116
|
|
|
111
117
|
/// Factory: returns the singleton instance. The concrete class is
|
|
112
118
|
/// chosen once, on first call, from `Options::AESparsity()`:
|
|
@@ -254,10 +260,10 @@ private:
|
|
|
254
260
|
virtual void handleCallSite(const ICFGNode* node);
|
|
255
261
|
|
|
256
262
|
/// Handle a WTO cycle (loop or recursive function) using widening/narrowing iteration
|
|
257
|
-
virtual void handleLoopOrRecursion(const ICFGCycleWTO* cycle, const CallICFGNode* caller
|
|
263
|
+
virtual void handleLoopOrRecursion(const ICFGCycleWTO* cycle, const CallICFGNode* caller);
|
|
258
264
|
|
|
259
265
|
/// Handle a function body via worklist-driven WTO traversal starting from funEntry
|
|
260
|
-
void handleFunction(const ICFGNode* funEntry, const CallICFGNode* caller
|
|
266
|
+
void handleFunction(const ICFGNode* funEntry, const CallICFGNode* caller);
|
|
261
267
|
|
|
262
268
|
/// Handle an ICFG node: execute statements; return true if state changed
|
|
263
269
|
bool handleICFGNode(const ICFGNode* node);
|
|
@@ -241,6 +241,7 @@ public:
|
|
|
241
241
|
|
|
242
242
|
// Abstract Execution
|
|
243
243
|
static const OptionMap<u32_t> AESparsity;
|
|
244
|
+
static const OptionMap<u32_t> AEFunEntry;
|
|
244
245
|
static const Option<u32_t> WidenDelay;
|
|
245
246
|
/// recursion handling mode, Default: TOP
|
|
246
247
|
static const OptionMap<u32_t> HandleRecur;
|
|
@@ -35,7 +35,6 @@
|
|
|
35
35
|
#include "Graphs/CallGraph.h"
|
|
36
36
|
#include "WPA/Andersen.h"
|
|
37
37
|
#include <cmath>
|
|
38
|
-
#include <deque>
|
|
39
38
|
#include <memory>
|
|
40
39
|
|
|
41
40
|
using namespace SVF;
|
|
@@ -118,11 +117,14 @@ AbstractInterpretation::~AbstractInterpretation()
|
|
|
118
117
|
}
|
|
119
118
|
|
|
120
119
|
/// Collect entry point functions for analysis.
|
|
121
|
-
///
|
|
122
|
-
///
|
|
123
|
-
|
|
120
|
+
/// In main mode, entry is main/svf.main. In no-main mode,
|
|
121
|
+
/// entries are SCCs with no external caller in the Andersen-resolved CallGraph.
|
|
122
|
+
FIFOWorkList<const FunObjVar*> AbstractInterpretation::collectProgEntryFuns()
|
|
124
123
|
{
|
|
125
|
-
|
|
124
|
+
FIFOWorkList<const FunObjVar*> entryFunctions;
|
|
125
|
+
const bool mainEntry = Options::AEFunEntry() == AEFunEntryMode::MAIN;
|
|
126
|
+
Set<NodeID> visitedEntrySCCs;
|
|
127
|
+
auto* callGraphSCC = preAnalysis->getCallGraphSCC();
|
|
126
128
|
|
|
127
129
|
for (auto it = callGraph->begin(); it != callGraph->end(); ++it)
|
|
128
130
|
{
|
|
@@ -133,39 +135,80 @@ std::deque<const FunObjVar*> AbstractInterpretation::collectProgEntryFuns()
|
|
|
133
135
|
if (fun->isDeclaration())
|
|
134
136
|
continue;
|
|
135
137
|
|
|
136
|
-
|
|
137
|
-
if (cgNode->getInEdges().empty())
|
|
138
|
+
if (mainEntry)
|
|
138
139
|
{
|
|
139
|
-
// If main exists, put it first for priority using deque's push_front
|
|
140
140
|
if (SVFUtil::isProgEntryFunction(fun))
|
|
141
141
|
{
|
|
142
|
-
entryFunctions.
|
|
142
|
+
entryFunctions.push(fun);
|
|
143
|
+
break;
|
|
143
144
|
}
|
|
144
|
-
|
|
145
|
+
}
|
|
146
|
+
else
|
|
147
|
+
{
|
|
148
|
+
NodeID repNodeId = callGraphSCC->repNode(cgNode->getId());
|
|
149
|
+
if (visitedEntrySCCs.count(repNodeId))
|
|
150
|
+
continue;
|
|
151
|
+
|
|
152
|
+
const NodeBS& cgSCCNodes = callGraphSCC->subNodes(repNodeId);
|
|
153
|
+
bool hasExternalCaller = false;
|
|
154
|
+
for (NodeID nodeId : cgSCCNodes)
|
|
155
|
+
{
|
|
156
|
+
const CallGraphNode* sccNode = callGraph->getGNode(nodeId);
|
|
157
|
+
for (auto inEdge : sccNode->getInEdges())
|
|
158
|
+
{
|
|
159
|
+
if (!cgSCCNodes.test(inEdge->getSrcID()))
|
|
160
|
+
{
|
|
161
|
+
hasExternalCaller = true;
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (hasExternalCaller)
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (hasExternalCaller)
|
|
170
|
+
continue;
|
|
171
|
+
|
|
172
|
+
visitedEntrySCCs.insert(repNodeId);
|
|
173
|
+
const FunObjVar* entryFun = fun;
|
|
174
|
+
for (NodeID nodeId : cgSCCNodes)
|
|
145
175
|
{
|
|
146
|
-
|
|
176
|
+
const FunObjVar* sccFun = callGraph->getGNode(nodeId)->getFunction();
|
|
177
|
+
if (SVFUtil::isProgEntryFunction(sccFun))
|
|
178
|
+
{
|
|
179
|
+
entryFun = sccFun;
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
147
182
|
}
|
|
183
|
+
entryFunctions.push(entryFun);
|
|
148
184
|
}
|
|
149
185
|
}
|
|
150
186
|
|
|
187
|
+
if (mainEntry && entryFunctions.empty())
|
|
188
|
+
{
|
|
189
|
+
SVFUtil::errs() << SVFUtil::errMsg(
|
|
190
|
+
"AE -ae-fun-entry=main requires a program entry function, but main/svf.main was not found.\n");
|
|
191
|
+
assert(false && "No program entry function found for -ae-fun-entry=main");
|
|
192
|
+
abort();
|
|
193
|
+
}
|
|
194
|
+
|
|
151
195
|
return entryFunctions;
|
|
152
196
|
}
|
|
153
197
|
|
|
154
198
|
|
|
155
|
-
/// Program entry -
|
|
199
|
+
/// Program entry - entry policy is selected by -ae-fun-entry.
|
|
156
200
|
void AbstractInterpretation::analyse()
|
|
157
201
|
{
|
|
158
|
-
// Always use multi-entry analysis from all entry points
|
|
159
202
|
analyzeFromAllProgEntries();
|
|
160
203
|
}
|
|
161
204
|
|
|
162
|
-
/// Analyze
|
|
205
|
+
/// Analyze the entry functions selected by collectProgEntryFuns().
|
|
163
206
|
/// Abstract state is shared across entry points so that functions analyzed from
|
|
164
207
|
/// earlier entries are not re-analyzed from scratch.
|
|
165
208
|
void AbstractInterpretation::analyzeFromAllProgEntries()
|
|
166
209
|
{
|
|
167
210
|
// Collect all entry point functions
|
|
168
|
-
|
|
211
|
+
FIFOWorkList<const FunObjVar*> entryFunctions = collectProgEntryFuns();
|
|
169
212
|
|
|
170
213
|
if (entryFunctions.empty())
|
|
171
214
|
{
|
|
@@ -174,10 +217,13 @@ void AbstractInterpretation::analyzeFromAllProgEntries()
|
|
|
174
217
|
}
|
|
175
218
|
// handle Global ICFGNode of SVFModule
|
|
176
219
|
handleGlobalNode();
|
|
177
|
-
|
|
220
|
+
const ICFGNode* globalNode = icfg->getGlobalICFGNode();
|
|
221
|
+
while (!entryFunctions.empty())
|
|
178
222
|
{
|
|
223
|
+
const FunObjVar* entryFun = entryFunctions.pop();
|
|
179
224
|
const ICFGNode* funEntry = icfg->getFunEntryICFGNode(entryFun);
|
|
180
|
-
|
|
225
|
+
updateAbsState(funEntry, getAbsState(globalNode));
|
|
226
|
+
handleFunction(funEntry, nullptr);
|
|
181
227
|
}
|
|
182
228
|
}
|
|
183
229
|
|
|
@@ -736,8 +782,7 @@ bool AbstractInterpretation::handleICFGNode(const ICFGNode* node)
|
|
|
736
782
|
void AbstractInterpretation::handleFunction(const ICFGNode* funEntry, const CallICFGNode* caller)
|
|
737
783
|
{
|
|
738
784
|
auto it = preAnalysis->getFuncToWTO().find(funEntry->getFun());
|
|
739
|
-
|
|
740
|
-
return;
|
|
785
|
+
assert(it != preAnalysis->getFuncToWTO().end() && "Missing WTO for function");
|
|
741
786
|
|
|
742
787
|
// Push all top-level WTO components into the worklist in WTO order
|
|
743
788
|
FIFOWorkList<const ICFGWTOComp*> worklist(it->second->getWTOComponents());
|
package/svf/lib/Util/Options.cpp
CHANGED
|
@@ -799,6 +799,20 @@ const OptionMap<u32_t> Options::AESparsity(
|
|
|
799
799
|
"Sparse abstract execution via SVFG."
|
|
800
800
|
}
|
|
801
801
|
});
|
|
802
|
+
const OptionMap<u32_t> Options::AEFunEntry(
|
|
803
|
+
"ae-fun-entry",
|
|
804
|
+
"Abstract execution function entry mode (Default: main)",
|
|
805
|
+
AbstractInterpretation::AEFunEntryMode::MAIN,
|
|
806
|
+
{
|
|
807
|
+
{
|
|
808
|
+
AbstractInterpretation::AEFunEntryMode::MAIN, "main",
|
|
809
|
+
"Analyze from the program entry function only."
|
|
810
|
+
},
|
|
811
|
+
{
|
|
812
|
+
AbstractInterpretation::AEFunEntryMode::NO_MAIN, "no-main",
|
|
813
|
+
"Analyze from every no-external-caller SCC after Andersen resolves the call graph."
|
|
814
|
+
}
|
|
815
|
+
});
|
|
802
816
|
const Option<u32_t> Options::WidenDelay(
|
|
803
817
|
"widen-delay", "Loop Widen Delay", 3);
|
|
804
818
|
const OptionMap<u32_t> Options::HandleRecur(
|