svf-tools 1.0.1091 → 1.0.1093
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/Graphs/SVFGOPT.h +9 -0
- package/svf/include/Graphs/VFG.h +62 -0
- package/svf/include/MSSA/SVFGBuilder.h +7 -1
- package/svf/include/WPA/VersionedFlowSensitive.h +39 -38
- package/svf/lib/Graphs/SVFGOPT.cpp +20 -0
- package/svf/lib/MSSA/SVFGBuilder.cpp +19 -23
- package/svf-llvm/include/SVF-LLVM/LLVMModule.h +5 -0
- package/svf-llvm/lib/extapi.c +129 -31
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1093",
|
|
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": {
|
|
@@ -81,9 +81,18 @@ public:
|
|
|
81
81
|
keepContextSelfCycle = true;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
/// Optimised SVFG's aren't written in their optimised form; read full SVFG and optimise it
|
|
85
|
+
void readAndOptSVFG(const std::string &filename);
|
|
86
|
+
|
|
87
|
+
/// Optimised SVFG's shouldn't be written in their optimised form; writes the full SVFG to file before optimising
|
|
88
|
+
void buildAndWriteSVFG(const std::string &filename);
|
|
89
|
+
|
|
84
90
|
protected:
|
|
85
91
|
void buildSVFG() override;
|
|
86
92
|
|
|
93
|
+
/// Separate optimisation function to avoid duplicate code
|
|
94
|
+
void optimiseSVFG();
|
|
95
|
+
|
|
87
96
|
/// Connect SVFG nodes between caller and callee for indirect call sites
|
|
88
97
|
//@{
|
|
89
98
|
inline void connectAParamAndFParam(const PAGNode* cs_arg, const PAGNode* fun_arg, const CallICFGNode*, CallSiteID csId, SVFGEdgeSetTy& edges) override
|
package/svf/include/Graphs/VFG.h
CHANGED
|
@@ -191,9 +191,71 @@ public:
|
|
|
191
191
|
return getVFGNode(getDef(pagNode));
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
+
// Given an VFG node, return true if it has a left hand side top level pointer (PAGnode)
|
|
195
|
+
inline bool hasLHSTopLevPtr(const VFGNode* node) const
|
|
196
|
+
{
|
|
197
|
+
return node && SVFUtil::isa<AddrVFGNode,
|
|
198
|
+
CopyVFGNode,
|
|
199
|
+
GepVFGNode,
|
|
200
|
+
LoadVFGNode,
|
|
201
|
+
PHIVFGNode,
|
|
202
|
+
CmpVFGNode,
|
|
203
|
+
BinaryOPVFGNode,
|
|
204
|
+
UnaryOPVFGNode,
|
|
205
|
+
ActualParmVFGNode,
|
|
206
|
+
FormalParmVFGNode,
|
|
207
|
+
ActualRetVFGNode,
|
|
208
|
+
FormalRetVFGNode,
|
|
209
|
+
NullPtrVFGNode>(node);
|
|
210
|
+
}
|
|
211
|
+
|
|
194
212
|
// Given an VFG node, return its left hand side top level pointer (PAGnode)
|
|
195
213
|
const PAGNode* getLHSTopLevPtr(const VFGNode* node) const;
|
|
196
214
|
|
|
215
|
+
/// Existence checks for VFGNodes
|
|
216
|
+
//@{
|
|
217
|
+
inline bool hasStmtVFGNode(const PAGEdge* pagEdge) const
|
|
218
|
+
{
|
|
219
|
+
return PAGEdgeToStmtVFGNodeMap.find(pagEdge) != PAGEdgeToStmtVFGNodeMap.end();
|
|
220
|
+
}
|
|
221
|
+
inline bool hasIntraPHIVFGNode(const PAGNode* pagNode) const
|
|
222
|
+
{
|
|
223
|
+
return PAGNodeToIntraPHIVFGNodeMap.find(pagNode) != PAGNodeToIntraPHIVFGNodeMap.end();
|
|
224
|
+
}
|
|
225
|
+
inline bool hasBinaryOPVFGNode(const PAGNode* pagNode) const
|
|
226
|
+
{
|
|
227
|
+
return PAGNodeToBinaryOPVFGNodeMap.find(pagNode) != PAGNodeToBinaryOPVFGNodeMap.end();
|
|
228
|
+
}
|
|
229
|
+
inline bool hasUnaryOPVFGNode(const PAGNode* pagNode) const
|
|
230
|
+
{
|
|
231
|
+
return PAGNodeToUnaryOPVFGNodeMap.find(pagNode) != PAGNodeToUnaryOPVFGNodeMap.end();
|
|
232
|
+
}
|
|
233
|
+
inline bool hasBranchVFGNode(const PAGNode* pagNode) const
|
|
234
|
+
{
|
|
235
|
+
return PAGNodeToBranchVFGNodeMap.find(pagNode) != PAGNodeToBranchVFGNodeMap.end();
|
|
236
|
+
}
|
|
237
|
+
inline bool hasCmpVFGNode(const PAGNode* pagNode) const
|
|
238
|
+
{
|
|
239
|
+
return PAGNodeToCmpVFGNodeMap.find(pagNode) != PAGNodeToCmpVFGNodeMap.end();
|
|
240
|
+
}
|
|
241
|
+
inline bool hasActualParmVFGNode(const PAGNode* aparm,const CallICFGNode* cs) const
|
|
242
|
+
{
|
|
243
|
+
return PAGNodeToActualParmMap.find(std::make_pair(aparm->getId(),cs)) != PAGNodeToActualParmMap.end();
|
|
244
|
+
}
|
|
245
|
+
inline bool hasActualRetVFGNode(const PAGNode* aret) const
|
|
246
|
+
{
|
|
247
|
+
return PAGNodeToActualRetMap.find(aret) != PAGNodeToActualRetMap.end();
|
|
248
|
+
}
|
|
249
|
+
inline bool hasFormalParmVFGNode(const PAGNode* fparm) const
|
|
250
|
+
{
|
|
251
|
+
return PAGNodeToFormalParmMap.find(fparm) != PAGNodeToFormalParmMap.end();
|
|
252
|
+
}
|
|
253
|
+
inline bool hasFormalRetVFGNode(const PAGNode* fret) const
|
|
254
|
+
{
|
|
255
|
+
return PAGNodeToFormalRetMap.find(fret) != PAGNodeToFormalRetMap.end();
|
|
256
|
+
}
|
|
257
|
+
//@}
|
|
258
|
+
|
|
197
259
|
/// Get an VFGNode
|
|
198
260
|
//@{
|
|
199
261
|
inline StmtVFGNode* getStmtVFGNode(const PAGEdge* pagEdge) const
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
|
|
33
33
|
#include "MemoryModel/PointerAnalysis.h"
|
|
34
34
|
#include "Graphs/SVFGOPT.h"
|
|
35
|
+
#include "Util/Options.h"
|
|
35
36
|
|
|
36
37
|
namespace SVF
|
|
37
38
|
{
|
|
@@ -49,7 +50,10 @@ public:
|
|
|
49
50
|
typedef SVFG::SVFGEdgeSetTy SVFGEdgeSet;
|
|
50
51
|
|
|
51
52
|
/// Constructor
|
|
52
|
-
explicit SVFGBuilder(bool _SVFGWithIndCall =
|
|
53
|
+
explicit SVFGBuilder(bool _SVFGWithIndCall = Options::SVFGWithIndirectCall(), bool _SVFGWithPostOpts = Options::OPTSVFG())
|
|
54
|
+
: svfg(nullptr), SVFGWithIndCall(_SVFGWithIndCall), SVFGWithPostOpts(_SVFGWithPostOpts)
|
|
55
|
+
{
|
|
56
|
+
}
|
|
53
57
|
|
|
54
58
|
/// Destructor
|
|
55
59
|
virtual ~SVFGBuilder() = default;
|
|
@@ -91,6 +95,8 @@ protected:
|
|
|
91
95
|
std::unique_ptr<SVFG> svfg;
|
|
92
96
|
/// SVFG with precomputed indirect call edges
|
|
93
97
|
bool SVFGWithIndCall;
|
|
98
|
+
/// Build optimised version of SVFG
|
|
99
|
+
bool SVFGWithPostOpts;
|
|
94
100
|
};
|
|
95
101
|
|
|
96
102
|
} // End namespace SVF
|
|
@@ -110,6 +110,45 @@ protected:
|
|
|
110
110
|
/// Override since we want to assign different weights based on versioning.
|
|
111
111
|
virtual void cluster(void) override;
|
|
112
112
|
|
|
113
|
+
public:
|
|
114
|
+
/// Returns true if l is a store node.
|
|
115
|
+
virtual bool isStore(const NodeID l) const;
|
|
116
|
+
|
|
117
|
+
/// Returns true if l is a load node.
|
|
118
|
+
virtual bool isLoad(const NodeID l) const;
|
|
119
|
+
|
|
120
|
+
/// Shared code for getConsume and getYield. They wrap this function.
|
|
121
|
+
Version getVersion(const NodeID l, const NodeID o, const LocVersionMap &lvm) const;
|
|
122
|
+
|
|
123
|
+
/// Returns the consumed version of o at l. If no such version exists, returns invalidVersion.
|
|
124
|
+
Version getConsume(const NodeID l, const NodeID o) const;
|
|
125
|
+
|
|
126
|
+
/// Returns the yielded version of o at l. If no such version exists, returns invalidVersion.
|
|
127
|
+
Version getYield(const NodeID l, const NodeID o) const;
|
|
128
|
+
|
|
129
|
+
/// Returns the versions of o which rely on o:v.
|
|
130
|
+
std::vector<Version> &getReliantVersions(const NodeID o, const Version v);
|
|
131
|
+
|
|
132
|
+
/// Returns the statements which rely on o:v.
|
|
133
|
+
NodeBS &getStmtReliance(const NodeID o, const Version v);
|
|
134
|
+
|
|
135
|
+
/// Dumps versionReliance and stmtReliance.
|
|
136
|
+
void dumpReliances(void) const;
|
|
137
|
+
|
|
138
|
+
/// Dumps maps consume and yield.
|
|
139
|
+
void dumpLocVersionMaps(void) const;
|
|
140
|
+
|
|
141
|
+
void solveAndwritePtsToFile(const std::string& filename) override;
|
|
142
|
+
|
|
143
|
+
void writeVersionedAnalysisResultToFile(const std::string& filename);
|
|
144
|
+
|
|
145
|
+
void readVersionedAnalysisResultFromFile(std::ifstream& F);
|
|
146
|
+
|
|
147
|
+
void readPtsFromFile(const std::string& filename) override;
|
|
148
|
+
|
|
149
|
+
/// Dumps a MeldVersion to stdout.
|
|
150
|
+
static void dumpMeldVersion(MeldVersion &v);
|
|
151
|
+
|
|
113
152
|
private:
|
|
114
153
|
/// Prelabel the SVFG: set y(o) for stores and c(o) for delta nodes to a new version.
|
|
115
154
|
void prelabel(void);
|
|
@@ -133,12 +172,6 @@ private:
|
|
|
133
172
|
/// Fills in isStoreMap and isLoadMap.
|
|
134
173
|
virtual void buildIsStoreLoadMaps(void);
|
|
135
174
|
|
|
136
|
-
/// Returns true if l is a store node.
|
|
137
|
-
virtual bool isStore(const NodeID l) const;
|
|
138
|
-
|
|
139
|
-
/// Returns true if l is a load node.
|
|
140
|
-
virtual bool isLoad(const NodeID l) const;
|
|
141
|
-
|
|
142
175
|
/// Fills in deltaMap and deltaSourceMap for the SVFG.
|
|
143
176
|
virtual void buildDeltaMaps(void);
|
|
144
177
|
|
|
@@ -150,15 +183,6 @@ private:
|
|
|
150
183
|
/// edge to a delta node due to on-the-fly callgraph construction.
|
|
151
184
|
virtual bool deltaSource(const NodeID l) const;
|
|
152
185
|
|
|
153
|
-
/// Shared code for getConsume and getYield. They wrap this function.
|
|
154
|
-
Version getVersion(const NodeID l, const NodeID o, const LocVersionMap &lvm) const;
|
|
155
|
-
|
|
156
|
-
/// Returns the consumed version of o at l. If no such version exists, returns invalidVersion.
|
|
157
|
-
Version getConsume(const NodeID l, const NodeID o) const;
|
|
158
|
-
|
|
159
|
-
/// Returns the yielded version of o at l. If no such version exists, returns invalidVersion.
|
|
160
|
-
Version getYield(const NodeID l, const NodeID o) const;
|
|
161
|
-
|
|
162
186
|
/// Shared code for setConsume and setYield. They wrap this function.
|
|
163
187
|
void setVersion(const NodeID l, const NodeID o, const Version v, LocVersionMap &lvm);
|
|
164
188
|
|
|
@@ -168,29 +192,6 @@ private:
|
|
|
168
192
|
/// Sets the yielded version of o at l to v.
|
|
169
193
|
void setYield(const NodeID l, const NodeID o, const Version v);
|
|
170
194
|
|
|
171
|
-
/// Returns the versions of o which rely on o:v.
|
|
172
|
-
std::vector<Version> &getReliantVersions(const NodeID o, const Version v);
|
|
173
|
-
|
|
174
|
-
/// Returns the statements which rely on o:v.
|
|
175
|
-
NodeBS &getStmtReliance(const NodeID o, const Version v);
|
|
176
|
-
|
|
177
|
-
/// Dumps versionReliance and stmtReliance.
|
|
178
|
-
void dumpReliances(void) const;
|
|
179
|
-
|
|
180
|
-
/// Dumps maps consume and yield.
|
|
181
|
-
void dumpLocVersionMaps(void) const;
|
|
182
|
-
|
|
183
|
-
void solveAndwritePtsToFile(const std::string& filename) override;
|
|
184
|
-
|
|
185
|
-
void writeVersionedAnalysisResultToFile(const std::string& filename);
|
|
186
|
-
|
|
187
|
-
void readVersionedAnalysisResultFromFile(std::ifstream& F);
|
|
188
|
-
|
|
189
|
-
void readPtsFromFile(const std::string& filename) override;
|
|
190
|
-
|
|
191
|
-
/// Dumps a MeldVersion to stdout.
|
|
192
|
-
static void dumpMeldVersion(MeldVersion &v);
|
|
193
|
-
|
|
194
195
|
/// Maps locations to objects to a version. The object version is what is
|
|
195
196
|
/// consumed at that location.
|
|
196
197
|
LocVersionMap consume;
|
|
@@ -43,11 +43,30 @@ static std::string KeepAllSelfCycle = "all";
|
|
|
43
43
|
static std::string KeepContextSelfCycle = "context";
|
|
44
44
|
static std::string KeepNoneSelfCycle = "none";
|
|
45
45
|
|
|
46
|
+
/// Optimised SVFGs aren't written to file; reads the full SVFG and optimises it
|
|
47
|
+
void SVFGOPT::readAndOptSVFG(const std::string &filename)
|
|
48
|
+
{
|
|
49
|
+
SVFG::readFile(filename);
|
|
50
|
+
optimiseSVFG();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/// Shouldn't write optimised SVFG to file; writes the built SVFG to file before optimisation
|
|
54
|
+
void SVFGOPT::buildAndWriteSVFG(const std::string &filename)
|
|
55
|
+
{
|
|
56
|
+
SVFG::buildSVFG();
|
|
57
|
+
SVFG::writeToFile(filename);
|
|
58
|
+
optimiseSVFG();
|
|
59
|
+
}
|
|
46
60
|
|
|
47
61
|
void SVFGOPT::buildSVFG()
|
|
48
62
|
{
|
|
49
63
|
SVFG::buildSVFG();
|
|
64
|
+
optimiseSVFG();
|
|
65
|
+
}
|
|
50
66
|
|
|
67
|
+
/// Separate function to optimise the SVFG to avoid duplicate code
|
|
68
|
+
void SVFGOPT::optimiseSVFG()
|
|
69
|
+
{
|
|
51
70
|
if(Options::DumpVFG())
|
|
52
71
|
dump("SVFG_before_opt");
|
|
53
72
|
|
|
@@ -62,6 +81,7 @@ void SVFGOPT::buildSVFG()
|
|
|
62
81
|
stat->sfvgOptEnd();
|
|
63
82
|
|
|
64
83
|
}
|
|
84
|
+
|
|
65
85
|
/*!
|
|
66
86
|
*
|
|
67
87
|
*/
|
|
@@ -26,33 +26,29 @@
|
|
|
26
26
|
* Created on: Apr 15, 2014
|
|
27
27
|
* Author: Yulei Sui
|
|
28
28
|
*/
|
|
29
|
+
#include "MSSA/SVFGBuilder.h"
|
|
30
|
+
#include "Graphs/CallGraph.h"
|
|
31
|
+
#include "Graphs/SVFG.h"
|
|
32
|
+
#include "MSSA/MemSSA.h"
|
|
29
33
|
#include "Util/Options.h"
|
|
30
34
|
#include "Util/SVFUtil.h"
|
|
31
|
-
#include "MSSA/MemSSA.h"
|
|
32
|
-
#include "Graphs/SVFG.h"
|
|
33
|
-
#include "MSSA/SVFGBuilder.h"
|
|
34
35
|
#include "WPA/Andersen.h"
|
|
35
|
-
#include "Graphs/CallGraph.h"
|
|
36
|
-
|
|
37
36
|
|
|
38
37
|
using namespace SVF;
|
|
39
38
|
using namespace SVFUtil;
|
|
40
39
|
|
|
41
|
-
|
|
42
40
|
SVFG* SVFGBuilder::buildPTROnlySVFG(BVDataPTAImpl* pta)
|
|
43
41
|
{
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
else
|
|
47
|
-
return build(pta, VFG::PTRONLYSVFG);
|
|
42
|
+
return this->SVFGWithPostOpts ? build(pta, VFG::PTRONLYSVFG_OPT)
|
|
43
|
+
: build(pta, VFG::PTRONLYSVFG);
|
|
48
44
|
}
|
|
49
45
|
|
|
50
46
|
SVFG* SVFGBuilder::buildFullSVFG(BVDataPTAImpl* pta)
|
|
51
47
|
{
|
|
52
|
-
return build(pta, VFG::
|
|
48
|
+
return this->SVFGWithPostOpts ? build(pta, VFG::FULLSVFG_OPT)
|
|
49
|
+
: build(pta, VFG::FULLSVFG);
|
|
53
50
|
}
|
|
54
51
|
|
|
55
|
-
|
|
56
52
|
/*!
|
|
57
53
|
* Create SVFG
|
|
58
54
|
*/
|
|
@@ -65,23 +61,24 @@ void SVFGBuilder::buildSVFG()
|
|
|
65
61
|
SVFG* SVFGBuilder::build(BVDataPTAImpl* pta, VFG::VFGK kind)
|
|
66
62
|
{
|
|
67
63
|
|
|
68
|
-
auto mssa = buildMSSA(
|
|
64
|
+
auto mssa = buildMSSA(
|
|
65
|
+
pta, (VFG::PTRONLYSVFG == kind || VFG::PTRONLYSVFG_OPT == kind));
|
|
69
66
|
|
|
70
67
|
DBOUT(DGENERAL, outs() << pasMsg("Build Sparse Value-Flow Graph \n"));
|
|
71
|
-
if(kind == VFG::FULLSVFG_OPT || kind == VFG::PTRONLYSVFG_OPT)
|
|
68
|
+
if (kind == VFG::FULLSVFG_OPT || kind == VFG::PTRONLYSVFG_OPT)
|
|
72
69
|
svfg = std::make_unique<SVFGOPT>(std::move(mssa), kind);
|
|
73
70
|
else
|
|
74
|
-
svfg = std::unique_ptr<SVFG>(new SVFG(std::move(mssa),kind));
|
|
71
|
+
svfg = std::unique_ptr<SVFG>(new SVFG(std::move(mssa), kind));
|
|
75
72
|
buildSVFG();
|
|
76
73
|
|
|
77
74
|
/// Update call graph using pre-analysis results
|
|
78
|
-
if(
|
|
75
|
+
if (SVFGWithIndCall)
|
|
79
76
|
svfg->updateCallGraph(pta);
|
|
80
77
|
|
|
81
|
-
if(svfg->getMSSA()->getPTA()->printStat())
|
|
78
|
+
if (svfg->getMSSA()->getPTA()->printStat())
|
|
82
79
|
svfg->performStat();
|
|
83
80
|
|
|
84
|
-
if(Options::DumpVFG())
|
|
81
|
+
if (Options::DumpVFG())
|
|
85
82
|
svfg->dump("svfg_final");
|
|
86
83
|
|
|
87
84
|
return svfg.get();
|
|
@@ -95,7 +92,8 @@ void SVFGBuilder::releaseMemory()
|
|
|
95
92
|
svfg->clearMSSA();
|
|
96
93
|
}
|
|
97
94
|
|
|
98
|
-
std::unique_ptr<MemSSA> SVFGBuilder::buildMSSA(BVDataPTAImpl* pta,
|
|
95
|
+
std::unique_ptr<MemSSA> SVFGBuilder::buildMSSA(BVDataPTAImpl* pta,
|
|
96
|
+
bool ptrOnlyMSSA)
|
|
99
97
|
{
|
|
100
98
|
|
|
101
99
|
DBOUT(DGENERAL, outs() << pasMsg("Build Memory SSA \n"));
|
|
@@ -103,10 +101,10 @@ std::unique_ptr<MemSSA> SVFGBuilder::buildMSSA(BVDataPTAImpl* pta, bool ptrOnlyM
|
|
|
103
101
|
auto mssa = std::make_unique<MemSSA>(pta, ptrOnlyMSSA);
|
|
104
102
|
|
|
105
103
|
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
|
|
106
|
-
for (const auto& item: *svfirCallGraph)
|
|
104
|
+
for (const auto& item : *svfirCallGraph)
|
|
107
105
|
{
|
|
108
106
|
|
|
109
|
-
const FunObjVar
|
|
107
|
+
const FunObjVar* fun = item.second->getFunction();
|
|
110
108
|
if (isExtCall(fun))
|
|
111
109
|
continue;
|
|
112
110
|
|
|
@@ -121,5 +119,3 @@ std::unique_ptr<MemSSA> SVFGBuilder::buildMSSA(BVDataPTAImpl* pta, bool ptrOnlyM
|
|
|
121
119
|
|
|
122
120
|
return mssa;
|
|
123
121
|
}
|
|
124
|
-
|
|
125
|
-
|
|
@@ -250,6 +250,11 @@ public:
|
|
|
250
250
|
addToSVFVar2LLVMValueMap(inst, svfInst);
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
+
inline bool hasLLVMValue(const SVFValue* value) const
|
|
254
|
+
{
|
|
255
|
+
return SVFBaseNode2LLVMValue.find(value) != SVFBaseNode2LLVMValue.end();
|
|
256
|
+
}
|
|
257
|
+
|
|
253
258
|
const Value* getLLVMValue(const SVFValue* value) const
|
|
254
259
|
{
|
|
255
260
|
SVFBaseNode2LLVMValueMap ::const_iterator it = SVFBaseNode2LLVMValue.find(value);
|
package/svf-llvm/lib/extapi.c
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
#include <stddef.h>
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
// Ensure NULL is always defined (but don't redefine)
|
|
4
|
+
#ifndef NULL
|
|
5
|
+
# define NULL ((void *)0)
|
|
6
|
+
#endif
|
|
3
7
|
|
|
4
8
|
/*
|
|
5
9
|
Functions with __attribute__((annotate("XXX"))) will be handle by SVF specifcially.
|
|
@@ -189,24 +193,6 @@ void* xmalloc(unsigned long size)
|
|
|
189
193
|
return NULL;
|
|
190
194
|
}
|
|
191
195
|
|
|
192
|
-
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
193
|
-
void *_Znam(unsigned long size)
|
|
194
|
-
{
|
|
195
|
-
return NULL;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
199
|
-
void *_Znaj(unsigned long size)
|
|
200
|
-
{
|
|
201
|
-
return NULL;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
205
|
-
void *_Znwj(unsigned long size)
|
|
206
|
-
{
|
|
207
|
-
return NULL;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
196
|
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
211
197
|
void *__cxa_allocate_exception(unsigned long size)
|
|
212
198
|
{
|
|
@@ -231,6 +217,12 @@ void *valloc(unsigned long size)
|
|
|
231
217
|
return NULL;
|
|
232
218
|
}
|
|
233
219
|
|
|
220
|
+
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
221
|
+
void *pvalloc(unsigned long size)
|
|
222
|
+
{
|
|
223
|
+
return NULL;
|
|
224
|
+
}
|
|
225
|
+
|
|
234
226
|
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg1")))
|
|
235
227
|
void *mmap64(void *addr, unsigned long len, int prot, int flags, int fildes, long off)
|
|
236
228
|
{
|
|
@@ -369,6 +361,12 @@ char *strdup(const char *s)
|
|
|
369
361
|
return NULL;
|
|
370
362
|
}
|
|
371
363
|
|
|
364
|
+
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:UNKNOWN")))
|
|
365
|
+
char *strndup(const char *s, unsigned long n)
|
|
366
|
+
{
|
|
367
|
+
return NULL;
|
|
368
|
+
}
|
|
369
|
+
|
|
372
370
|
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:UNKNOWN")))
|
|
373
371
|
char *strerror(int errnum)
|
|
374
372
|
{
|
|
@@ -429,6 +427,12 @@ char *realloc(void *ptr, unsigned long size)
|
|
|
429
427
|
return NULL;
|
|
430
428
|
}
|
|
431
429
|
|
|
430
|
+
__attribute__((annotate("REALLOC_HEAP_RET"), annotate("AllocSize:Arg1*Arg2")))
|
|
431
|
+
char *reallocarray(void *ptr, unsigned long elems, unsigned long size)
|
|
432
|
+
{
|
|
433
|
+
return NULL;
|
|
434
|
+
}
|
|
435
|
+
|
|
432
436
|
__attribute__((annotate("REALLOC_HEAP_RET"), annotate("AllocSize:Arg1")))
|
|
433
437
|
void* safe_realloc(void *p, unsigned long n)
|
|
434
438
|
{
|
|
@@ -469,26 +473,120 @@ void *xrealloc(void *ptr, unsigned long bytes)
|
|
|
469
473
|
return NULL;
|
|
470
474
|
}
|
|
471
475
|
|
|
476
|
+
// ::operator new (size (unsigned int))
|
|
477
|
+
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
478
|
+
void *_Znwj(unsigned int size)
|
|
479
|
+
{
|
|
480
|
+
return NULL;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// ::operator new (size (unsigned int), nothrow)
|
|
484
|
+
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
485
|
+
void *_ZnwjRKSt9nothrow_t(unsigned int size, void *)
|
|
486
|
+
{
|
|
487
|
+
return NULL;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// ::operator new (size (unsigned int), aligned)
|
|
491
|
+
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
492
|
+
void *_ZnwjSt11align_val_t(unsigned int size, unsigned long)
|
|
493
|
+
{
|
|
494
|
+
return NULL;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// ::operator new (size (unsigned int), aligned, nothrow)
|
|
498
|
+
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
499
|
+
void *_ZnwjSt11align_val_tRKSt9nothrow_t(unsigned int size, unsigned long, void *)
|
|
500
|
+
{
|
|
501
|
+
return NULL;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// ::operator new[] (size (unsigned int))
|
|
505
|
+
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
506
|
+
void *_Znaj(unsigned int size)
|
|
507
|
+
{
|
|
508
|
+
return NULL;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// ::operator new[] (size (unsigned int), nothrow)
|
|
512
|
+
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
513
|
+
void *_ZnajRKSt9nothrow_t(unsigned int size, void *)
|
|
514
|
+
{
|
|
515
|
+
return NULL;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// ::operator new[] (size (unsigned int), aligned)
|
|
519
|
+
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
520
|
+
void *_ZnajSt11align_val_t(unsigned int size, unsigned long)
|
|
521
|
+
{
|
|
522
|
+
return NULL;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// ::operator new[] (size (unsigned int), aligned, nothrow)
|
|
526
|
+
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
527
|
+
void *_ZnajSt11align_val_tRKSt9nothrow_t(unsigned int size, unsigned long, void *)
|
|
528
|
+
{
|
|
529
|
+
return NULL;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// ::operator new (size (size_t))
|
|
472
533
|
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
473
534
|
void *_Znwm(unsigned long size)
|
|
474
535
|
{
|
|
475
536
|
return NULL;
|
|
476
537
|
}
|
|
477
538
|
|
|
539
|
+
// ::operator new (size (size_t), nothrow)
|
|
478
540
|
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
479
541
|
void *_ZnwmRKSt9nothrow_t(unsigned long size, void *)
|
|
480
542
|
{
|
|
481
543
|
return NULL;
|
|
482
544
|
}
|
|
483
545
|
|
|
546
|
+
// ::operator new (size (size_t), aligned)
|
|
547
|
+
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
548
|
+
void *_ZnwmSt11align_val_t(unsigned long size, unsigned long)
|
|
549
|
+
{
|
|
550
|
+
return NULL;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// ::operator new (size (size_t), aligned, nothrow)
|
|
554
|
+
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
555
|
+
void *_ZnwmSt11align_val_tRKSt9nothrow_t(unsigned long size, unsigned long, void *)
|
|
556
|
+
{
|
|
557
|
+
return NULL;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// ::operator new[]
|
|
561
|
+
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
562
|
+
void *_Znam(unsigned long size)
|
|
563
|
+
{
|
|
564
|
+
return NULL;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// ::operator new[] (nothrow)
|
|
484
568
|
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
485
569
|
void *_ZnamRKSt9nothrow_t(unsigned long size, void *)
|
|
486
570
|
{
|
|
487
571
|
return NULL;
|
|
488
572
|
}
|
|
489
573
|
|
|
574
|
+
// ::operator new[] (aligned)
|
|
575
|
+
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
576
|
+
void *_ZnamSt11align_val_t(unsigned long size, unsigned long)
|
|
577
|
+
{
|
|
578
|
+
return NULL;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// ::operator new[] (aligned, nothrow)
|
|
582
|
+
__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0")))
|
|
583
|
+
void *_ZnamSt11align_val_tRKSt9nothrow_t(unsigned long size, unsigned long, void *)
|
|
584
|
+
{
|
|
585
|
+
return NULL;
|
|
586
|
+
}
|
|
587
|
+
|
|
490
588
|
__attribute__((annotate("ALLOC_HEAP_ARG0"), annotate("AllocSize:UNKNOWN")))
|
|
491
|
-
int asprintf(char **
|
|
589
|
+
int asprintf(char **__restrict strp, const char *__restrict fmt, ...)
|
|
492
590
|
{
|
|
493
591
|
return 0;
|
|
494
592
|
}
|
|
@@ -536,7 +634,7 @@ int posix_memalign(void **a, unsigned long b, unsigned long c)
|
|
|
536
634
|
}
|
|
537
635
|
|
|
538
636
|
__attribute__((annotate("ALLOC_HEAP_ARG1"), annotate("AllocSize:UNKNOWN")))
|
|
539
|
-
int scandir(const char *
|
|
637
|
+
int scandir(const char *__restrict dirp, struct dirent ***__restrict namelist, int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **))
|
|
540
638
|
{
|
|
541
639
|
return 0;
|
|
542
640
|
}
|
|
@@ -590,7 +688,7 @@ __attribute__((annotate("MEMCPY")))
|
|
|
590
688
|
void bcopy(const void *s1, void *s2, unsigned long n){}
|
|
591
689
|
|
|
592
690
|
__attribute__((annotate("MEMCPY")))
|
|
593
|
-
void *memccpy( void *
|
|
691
|
+
void *memccpy( void *__restrict dest, const void *__restrict src, int c, unsigned long count)
|
|
594
692
|
{
|
|
595
693
|
return NULL;
|
|
596
694
|
}
|
|
@@ -644,7 +742,7 @@ wchar_t* __wcscat_chk(wchar_t * dest, const wchar_t * src)
|
|
|
644
742
|
}
|
|
645
743
|
|
|
646
744
|
__attribute__((annotate("STRCPY")))
|
|
647
|
-
char *stpcpy(char *
|
|
745
|
+
char *stpcpy(char *__restrict dst, const char *__restrict src)
|
|
648
746
|
{
|
|
649
747
|
return NULL;
|
|
650
748
|
}
|
|
@@ -702,7 +800,7 @@ char *wcscpy(wchar_t* dest, const wchar_t* src) {
|
|
|
702
800
|
}
|
|
703
801
|
|
|
704
802
|
__attribute__((annotate("MEMCPY")))
|
|
705
|
-
unsigned long iconv(void* cd, char **
|
|
803
|
+
unsigned long iconv(void* cd, char **__restrict inbuf, unsigned long *__restrict inbytesleft, char **__restrict outbuf, unsigned long *__restrict outbytesleft)
|
|
706
804
|
{
|
|
707
805
|
return 0;
|
|
708
806
|
}
|
|
@@ -906,7 +1004,7 @@ struct tm *localtime_r(const void *timep, struct tm *result)
|
|
|
906
1004
|
return result;
|
|
907
1005
|
}
|
|
908
1006
|
|
|
909
|
-
char *realpath(const char *
|
|
1007
|
+
char *realpath(const char *__restrict path, char *__restrict resolved_path)
|
|
910
1008
|
{
|
|
911
1009
|
return resolved_path;
|
|
912
1010
|
}
|
|
@@ -921,7 +1019,7 @@ void* freopen(const char* voidname, const char* mode, void* fp)
|
|
|
921
1019
|
return fp;
|
|
922
1020
|
}
|
|
923
1021
|
|
|
924
|
-
const char *inet_ntop(int af, const void *
|
|
1022
|
+
const char *inet_ntop(int af, const void *__restrict src, char *__restrict dst, unsigned int size)
|
|
925
1023
|
{
|
|
926
1024
|
return dst;
|
|
927
1025
|
}
|
|
@@ -995,9 +1093,9 @@ char* ctime_r(const char *timer, char *buf)
|
|
|
995
1093
|
return buf;
|
|
996
1094
|
}
|
|
997
1095
|
|
|
998
|
-
int readdir_r(void *
|
|
1096
|
+
int readdir_r(void *__restrict dir, void *__restrict entry, void **__restrict result)
|
|
999
1097
|
{
|
|
1000
|
-
|
|
1098
|
+
entry = *result;
|
|
1001
1099
|
return 0;
|
|
1002
1100
|
}
|
|
1003
1101
|
|
|
@@ -1048,13 +1146,13 @@ const unsigned short **__ctype_b_loc(void)
|
|
|
1048
1146
|
int ctype_tolower_loc_global[10];
|
|
1049
1147
|
int **__ctype_tolower_loc(void)
|
|
1050
1148
|
{
|
|
1051
|
-
return &ctype_tolower_loc_global;
|
|
1149
|
+
return (int **)&ctype_tolower_loc_global;
|
|
1052
1150
|
}
|
|
1053
1151
|
|
|
1054
1152
|
int ctype_toupper_loc_global[10];
|
|
1055
1153
|
int **__ctype_toupper_loc(void)
|
|
1056
1154
|
{
|
|
1057
|
-
return &ctype_toupper_loc_global;
|
|
1155
|
+
return (int **)&ctype_toupper_loc_global;
|
|
1058
1156
|
}
|
|
1059
1157
|
|
|
1060
1158
|
int error_global[10];
|
|
@@ -1075,7 +1173,7 @@ void* __res_state(void)
|
|
|
1075
1173
|
return res_state_global;
|
|
1076
1174
|
}
|
|
1077
1175
|
|
|
1078
|
-
|
|
1176
|
+
char time_global[10];
|
|
1079
1177
|
char *asctime(const void *timeptr)
|
|
1080
1178
|
{
|
|
1081
1179
|
return time_global;
|