svf-tools 1.0.688 → 1.0.690
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/WPA/Steensgaard.h +30 -15
- package/svf/lib/Util/ExtAPI.cpp +2 -1
- package/svf/lib/WPA/Steensgaard.cpp +182 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.690",
|
|
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": {
|
|
@@ -17,24 +17,21 @@ namespace SVF
|
|
|
17
17
|
*/
|
|
18
18
|
typedef WPASolver<ConstraintGraph*> WPAConstraintSolver;
|
|
19
19
|
|
|
20
|
-
class Steensgaard:
|
|
20
|
+
class Steensgaard : public AndersenBase
|
|
21
21
|
{
|
|
22
22
|
|
|
23
23
|
public:
|
|
24
|
-
|
|
25
24
|
typedef Map<NodeID, NodeID> NodeToEquivClassMap;
|
|
26
25
|
typedef Map<NodeID, Set<NodeID>> NodeToSubsMap;
|
|
26
|
+
typedef OrderedMap<CallSite, NodeID> CallSite2DummyValPN;
|
|
27
27
|
|
|
28
28
|
/// Constructor
|
|
29
|
-
Steensgaard(SVFIR* _pag)
|
|
30
|
-
: AndersenBase(_pag, Steensgaard_WPA, true)
|
|
31
|
-
{
|
|
32
|
-
}
|
|
29
|
+
Steensgaard(SVFIR* _pag) : AndersenBase(_pag, Steensgaard_WPA, true) {}
|
|
33
30
|
|
|
34
31
|
/// Create an singleton instance
|
|
35
32
|
static Steensgaard* createSteensgaard(SVFIR* _pag)
|
|
36
33
|
{
|
|
37
|
-
if(steens==nullptr)
|
|
34
|
+
if (steens == nullptr)
|
|
38
35
|
{
|
|
39
36
|
steens = new Steensgaard(_pag);
|
|
40
37
|
steens->analyze();
|
|
@@ -57,15 +54,15 @@ public:
|
|
|
57
54
|
|
|
58
55
|
/// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
59
56
|
//@{
|
|
60
|
-
static inline bool classof(const Steensgaard
|
|
57
|
+
static inline bool classof(const Steensgaard*)
|
|
61
58
|
{
|
|
62
59
|
return true;
|
|
63
60
|
}
|
|
64
|
-
static inline bool classof(const AndersenBase
|
|
61
|
+
static inline bool classof(const AndersenBase* pta)
|
|
65
62
|
{
|
|
66
63
|
return (pta->getAnalysisTy() == Steensgaard_WPA);
|
|
67
64
|
}
|
|
68
|
-
static inline bool classof(const PointerAnalysis
|
|
65
|
+
static inline bool classof(const PointerAnalysis* pta)
|
|
69
66
|
{
|
|
70
67
|
return (pta->getAnalysisTy() == Steensgaard_WPA);
|
|
71
68
|
}
|
|
@@ -87,7 +84,7 @@ public:
|
|
|
87
84
|
{
|
|
88
85
|
id = getEC(id);
|
|
89
86
|
ptd = getEC(ptd);
|
|
90
|
-
return getPTDataTy()->unionPts(id,ptd);
|
|
87
|
+
return getPTDataTy()->unionPts(id, ptd);
|
|
91
88
|
}
|
|
92
89
|
|
|
93
90
|
/// API for equivalence class operations
|
|
@@ -96,7 +93,7 @@ public:
|
|
|
96
93
|
inline NodeID getEC(NodeID id) const
|
|
97
94
|
{
|
|
98
95
|
NodeToEquivClassMap::const_iterator it = nodeToECMap.find(id);
|
|
99
|
-
if(it==nodeToECMap.end())
|
|
96
|
+
if (it == nodeToECMap.end())
|
|
100
97
|
return id;
|
|
101
98
|
else
|
|
102
99
|
return it->second;
|
|
@@ -113,14 +110,32 @@ public:
|
|
|
113
110
|
nodeToSubsMap[node].insert(sub);
|
|
114
111
|
}
|
|
115
112
|
|
|
116
|
-
|
|
113
|
+
/// Add copy edge on constraint graph
|
|
114
|
+
virtual inline bool addCopyEdge(NodeID src, NodeID dst)
|
|
115
|
+
{
|
|
116
|
+
return consCG->addCopyCGEdge(src, dst);
|
|
117
|
+
}
|
|
117
118
|
|
|
119
|
+
protected:
|
|
120
|
+
CallSite2DummyValPN
|
|
121
|
+
callsite2DummyValPN; ///< Map an instruction to a dummy obj which
|
|
122
|
+
///< created at an indirect callsite, which invokes
|
|
123
|
+
///< a heap allocator
|
|
124
|
+
void heapAllocatorViaIndCall(CallSite cs, NodePairSet& cpySrcNodes);
|
|
125
|
+
|
|
126
|
+
/// Update call graph for the input indirect callsites
|
|
127
|
+
virtual bool updateCallGraph(const CallSiteToFunPtrMap& callsites);
|
|
128
|
+
|
|
129
|
+
/// Connect formal and actual parameters for indirect callsites
|
|
130
|
+
void connectCaller2CalleeParams(CallSite cs, const SVFFunction* F,
|
|
131
|
+
NodePairSet& cpySrcNodes);
|
|
132
|
+
|
|
133
|
+
private:
|
|
118
134
|
static Steensgaard* steens; // static instance
|
|
119
135
|
NodeToEquivClassMap nodeToECMap;
|
|
120
136
|
NodeToSubsMap nodeToSubsMap;
|
|
121
137
|
};
|
|
122
138
|
|
|
123
|
-
}
|
|
124
|
-
|
|
139
|
+
} // namespace SVF
|
|
125
140
|
|
|
126
141
|
#endif /* INCLUDE_WPA_STEENSGAARD_H_ */
|
package/svf/lib/Util/ExtAPI.cpp
CHANGED
|
@@ -84,6 +84,7 @@ static std::string getJsonFile(const std::string& path)
|
|
|
84
84
|
jsonFilePath.append("/svf-lib/SVF-osx");
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
+
if (jsonFilePath.back() != '/') jsonFilePath.push_back('/');
|
|
87
88
|
jsonFilePath.append(EXTAPI_JSON_PATH);
|
|
88
89
|
return jsonFilePath;
|
|
89
90
|
}
|
|
@@ -164,7 +165,7 @@ ExtAPI* ExtAPI::getExtAPI(const std::string& path)
|
|
|
164
165
|
root = parseJson(jsonFilePath, statbuf.st_size);
|
|
165
166
|
return extOp;
|
|
166
167
|
}
|
|
167
|
-
SVFUtil::errs() << "No JsonFile found at " << jsonFilePath << " for getExtAPI()
|
|
168
|
+
SVFUtil::errs() << "No JsonFile found at " << jsonFilePath << " for getExtAPI(); set $SVF_DIR first!\n";
|
|
168
169
|
abort();
|
|
169
170
|
}
|
|
170
171
|
return extOp;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
//===- Steensgaard.cpp -- Steensgaard's field-insensitive
|
|
1
|
+
//===- Steensgaard.cpp -- Steensgaard's field-insensitive
|
|
2
|
+
// analysis--------------//
|
|
2
3
|
//
|
|
3
4
|
// SVF: Static Value-Flow Analysis
|
|
4
5
|
//
|
|
@@ -32,7 +33,7 @@
|
|
|
32
33
|
using namespace SVF;
|
|
33
34
|
using namespace SVFUtil;
|
|
34
35
|
|
|
35
|
-
Steensgaard
|
|
36
|
+
Steensgaard* Steensgaard::steens = nullptr;
|
|
36
37
|
|
|
37
38
|
/*!
|
|
38
39
|
* Steensgaard analysis
|
|
@@ -50,7 +51,7 @@ void Steensgaard::solveWorklist()
|
|
|
50
51
|
ConstraintNode* node = consCG->getConstraintNode(nodeId);
|
|
51
52
|
|
|
52
53
|
/// foreach o \in pts(p)
|
|
53
|
-
for(NodeID o : getPts(nodeId))
|
|
54
|
+
for (NodeID o : getPts(nodeId))
|
|
54
55
|
{
|
|
55
56
|
|
|
56
57
|
/// *p = q : EC(o) == EC(q)
|
|
@@ -68,36 +69,34 @@ void Steensgaard::solveWorklist()
|
|
|
68
69
|
/// q = p : EC(q) == EC(p)
|
|
69
70
|
for (ConstraintEdge* edge : node->getCopyOutEdges())
|
|
70
71
|
{
|
|
71
|
-
ecUnion(edge->getSrcID(),edge->getDstID());
|
|
72
|
+
ecUnion(edge->getSrcID(), edge->getDstID());
|
|
72
73
|
}
|
|
73
74
|
/// q = &p->f : EC(q) == EC(p)
|
|
74
75
|
for (ConstraintEdge* edge : node->getGepOutEdges())
|
|
75
76
|
{
|
|
76
|
-
ecUnion(edge->getSrcID(),edge->getDstID());
|
|
77
|
+
ecUnion(edge->getSrcID(), edge->getDstID());
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
81
|
|
|
81
|
-
|
|
82
82
|
void Steensgaard::setEC(NodeID node, NodeID rep)
|
|
83
83
|
{
|
|
84
84
|
rep = getEC(rep);
|
|
85
85
|
Set<NodeID>& subNodes = getSubNodes(node);
|
|
86
|
-
for(NodeID sub : subNodes)
|
|
86
|
+
for (NodeID sub : subNodes)
|
|
87
87
|
{
|
|
88
88
|
nodeToECMap[sub] = rep;
|
|
89
|
-
addSubNode(rep,sub);
|
|
89
|
+
addSubNode(rep, sub);
|
|
90
90
|
}
|
|
91
91
|
subNodes.clear();
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
|
|
95
94
|
/// merge node into equiv class and merge node's pts into ec's pts
|
|
96
95
|
void Steensgaard::ecUnion(NodeID node, NodeID ec)
|
|
97
96
|
{
|
|
98
|
-
if(unionPts(ec, node))
|
|
97
|
+
if (unionPts(ec, node))
|
|
99
98
|
pushIntoWorklist(ec);
|
|
100
|
-
setEC(node,ec);
|
|
99
|
+
setEC(node, ec);
|
|
101
100
|
}
|
|
102
101
|
|
|
103
102
|
/*!
|
|
@@ -105,10 +104,13 @@ void Steensgaard::ecUnion(NodeID node, NodeID ec)
|
|
|
105
104
|
*/
|
|
106
105
|
void Steensgaard::processAllAddr()
|
|
107
106
|
{
|
|
108
|
-
for (ConstraintGraph::const_iterator nodeIt = consCG->begin(),
|
|
107
|
+
for (ConstraintGraph::const_iterator nodeIt = consCG->begin(),
|
|
108
|
+
nodeEit = consCG->end();
|
|
109
|
+
nodeIt != nodeEit; nodeIt++)
|
|
109
110
|
{
|
|
110
|
-
ConstraintNode
|
|
111
|
-
for (ConstraintNode::const_iterator it = cgNode->incomingAddrsBegin(),
|
|
111
|
+
ConstraintNode* cgNode = nodeIt->second;
|
|
112
|
+
for (ConstraintNode::const_iterator it = cgNode->incomingAddrsBegin(),
|
|
113
|
+
eit = cgNode->incomingAddrsEnd();
|
|
112
114
|
it != eit; ++it)
|
|
113
115
|
{
|
|
114
116
|
numOfProcessedAddr++;
|
|
@@ -116,9 +118,174 @@ void Steensgaard::processAllAddr()
|
|
|
116
118
|
const AddrCGEdge* addr = cast<AddrCGEdge>(*it);
|
|
117
119
|
NodeID dst = addr->getDstID();
|
|
118
120
|
NodeID src = addr->getSrcID();
|
|
119
|
-
if(addPts(dst,src))
|
|
121
|
+
if (addPts(dst, src))
|
|
120
122
|
pushIntoWorklist(dst);
|
|
121
123
|
}
|
|
122
124
|
}
|
|
123
125
|
}
|
|
124
126
|
|
|
127
|
+
bool Steensgaard::updateCallGraph(const CallSiteToFunPtrMap& callsites)
|
|
128
|
+
{
|
|
129
|
+
|
|
130
|
+
double cgUpdateStart = stat->getClk();
|
|
131
|
+
|
|
132
|
+
CallEdgeMap newEdges;
|
|
133
|
+
onTheFlyCallGraphSolve(callsites, newEdges);
|
|
134
|
+
NodePairSet cpySrcNodes; /// nodes as a src of a generated new copy edge
|
|
135
|
+
for (CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end();
|
|
136
|
+
it != eit; ++it)
|
|
137
|
+
{
|
|
138
|
+
CallSite cs = SVFUtil::getSVFCallSite(it->first->getCallSite());
|
|
139
|
+
for (FunctionSet::iterator cit = it->second.begin(),
|
|
140
|
+
ecit = it->second.end();
|
|
141
|
+
cit != ecit; ++cit)
|
|
142
|
+
{
|
|
143
|
+
connectCaller2CalleeParams(cs, *cit, cpySrcNodes);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
for (NodePairSet::iterator it = cpySrcNodes.begin(),
|
|
147
|
+
eit = cpySrcNodes.end();
|
|
148
|
+
it != eit; ++it)
|
|
149
|
+
{
|
|
150
|
+
pushIntoWorklist(it->first);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
double cgUpdateEnd = stat->getClk();
|
|
154
|
+
timeOfUpdateCallGraph += (cgUpdateEnd - cgUpdateStart) / TIMEINTERVAL;
|
|
155
|
+
|
|
156
|
+
return (!newEdges.empty());
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
void Steensgaard::heapAllocatorViaIndCall(CallSite cs, NodePairSet& cpySrcNodes)
|
|
160
|
+
{
|
|
161
|
+
assert(SVFUtil::getCallee(cs) == nullptr && "not an indirect callsite?");
|
|
162
|
+
RetICFGNode* retBlockNode =
|
|
163
|
+
pag->getICFG()->getRetICFGNode(cs.getInstruction());
|
|
164
|
+
const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode);
|
|
165
|
+
NodeID srcret;
|
|
166
|
+
CallSite2DummyValPN::const_iterator it = callsite2DummyValPN.find(cs);
|
|
167
|
+
if (it != callsite2DummyValPN.end())
|
|
168
|
+
{
|
|
169
|
+
srcret = getEC(it->second);
|
|
170
|
+
}
|
|
171
|
+
else
|
|
172
|
+
{
|
|
173
|
+
NodeID valNode = pag->addDummyValNode();
|
|
174
|
+
NodeID objNode = pag->addDummyObjNode(cs.getType());
|
|
175
|
+
addPts(valNode, objNode);
|
|
176
|
+
callsite2DummyValPN.insert(std::make_pair(cs, valNode));
|
|
177
|
+
consCG->addConstraintNode(new ConstraintNode(valNode), valNode);
|
|
178
|
+
consCG->addConstraintNode(new ConstraintNode(objNode), objNode);
|
|
179
|
+
srcret = valNode;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
NodeID dstrec = getEC(cs_return->getId());
|
|
183
|
+
if (addCopyEdge(srcret, dstrec))
|
|
184
|
+
cpySrcNodes.insert(std::make_pair(srcret, dstrec));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/*!
|
|
188
|
+
* Connect formal and actual parameters for indirect callsites
|
|
189
|
+
*/
|
|
190
|
+
void Steensgaard::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F,
|
|
191
|
+
NodePairSet& cpySrcNodes)
|
|
192
|
+
{
|
|
193
|
+
assert(F);
|
|
194
|
+
|
|
195
|
+
DBOUT(DAndersen, outs() << "connect parameters from indirect callsite "
|
|
196
|
+
<< cs.getInstruction()->toString() << " to callee "
|
|
197
|
+
<< *F << "\n");
|
|
198
|
+
|
|
199
|
+
CallICFGNode* callBlockNode =
|
|
200
|
+
pag->getICFG()->getCallICFGNode(cs.getInstruction());
|
|
201
|
+
RetICFGNode* retBlockNode =
|
|
202
|
+
pag->getICFG()->getRetICFGNode(cs.getInstruction());
|
|
203
|
+
|
|
204
|
+
if (SVFUtil::isHeapAllocExtFunViaRet(F) &&
|
|
205
|
+
pag->callsiteHasRet(retBlockNode))
|
|
206
|
+
{
|
|
207
|
+
heapAllocatorViaIndCall(cs, cpySrcNodes);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (pag->funHasRet(F) && pag->callsiteHasRet(retBlockNode))
|
|
211
|
+
{
|
|
212
|
+
const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode);
|
|
213
|
+
const PAGNode* fun_return = pag->getFunRet(F);
|
|
214
|
+
if (cs_return->isPointer() && fun_return->isPointer())
|
|
215
|
+
{
|
|
216
|
+
NodeID dstrec = getEC(cs_return->getId());
|
|
217
|
+
NodeID srcret = getEC(fun_return->getId());
|
|
218
|
+
if (addCopyEdge(srcret, dstrec))
|
|
219
|
+
{
|
|
220
|
+
cpySrcNodes.insert(std::make_pair(srcret, dstrec));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else
|
|
224
|
+
{
|
|
225
|
+
DBOUT(DAndersen, outs() << "not a pointer ignored\n");
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (pag->hasCallSiteArgsMap(callBlockNode) && pag->hasFunArgsList(F))
|
|
230
|
+
{
|
|
231
|
+
|
|
232
|
+
// connect actual and formal param
|
|
233
|
+
const SVFIR::SVFVarList& csArgList =
|
|
234
|
+
pag->getCallSiteArgsList(callBlockNode);
|
|
235
|
+
const SVFIR::SVFVarList& funArgList = pag->getFunArgsList(F);
|
|
236
|
+
// Go through the fixed parameters.
|
|
237
|
+
DBOUT(DPAGBuild, outs() << " args:");
|
|
238
|
+
SVFIR::SVFVarList::const_iterator funArgIt = funArgList.begin(),
|
|
239
|
+
funArgEit = funArgList.end();
|
|
240
|
+
SVFIR::SVFVarList::const_iterator csArgIt = csArgList.begin(),
|
|
241
|
+
csArgEit = csArgList.end();
|
|
242
|
+
for (; funArgIt != funArgEit; ++csArgIt, ++funArgIt)
|
|
243
|
+
{
|
|
244
|
+
// Some programs (e.g. Linux kernel) leave unneeded parameters
|
|
245
|
+
// empty.
|
|
246
|
+
if (csArgIt == csArgEit)
|
|
247
|
+
{
|
|
248
|
+
DBOUT(DAndersen, outs() << " !! not enough args\n");
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
const PAGNode* cs_arg = *csArgIt;
|
|
252
|
+
const PAGNode* fun_arg = *funArgIt;
|
|
253
|
+
|
|
254
|
+
if (cs_arg->isPointer() && fun_arg->isPointer())
|
|
255
|
+
{
|
|
256
|
+
DBOUT(DAndersen, outs() << "process actual parm "
|
|
257
|
+
<< cs_arg->toString() << " \n");
|
|
258
|
+
NodeID srcAA = getEC(cs_arg->getId());
|
|
259
|
+
NodeID dstFA = getEC(fun_arg->getId());
|
|
260
|
+
if (addCopyEdge(srcAA, dstFA))
|
|
261
|
+
{
|
|
262
|
+
cpySrcNodes.insert(std::make_pair(srcAA, dstFA));
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Any remaining actual args must be varargs.
|
|
268
|
+
if (F->isVarArg())
|
|
269
|
+
{
|
|
270
|
+
NodeID vaF = getEC(pag->getVarargNode(F));
|
|
271
|
+
DBOUT(DPAGBuild, outs() << "\n varargs:");
|
|
272
|
+
for (; csArgIt != csArgEit; ++csArgIt)
|
|
273
|
+
{
|
|
274
|
+
const PAGNode* cs_arg = *csArgIt;
|
|
275
|
+
if (cs_arg->isPointer())
|
|
276
|
+
{
|
|
277
|
+
NodeID vnAA = getEC(cs_arg->getId());
|
|
278
|
+
if (addCopyEdge(vnAA, vaF))
|
|
279
|
+
{
|
|
280
|
+
cpySrcNodes.insert(std::make_pair(vnAA, vaF));
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
if (csArgIt != csArgEit)
|
|
286
|
+
{
|
|
287
|
+
writeWrnMsg("too many args to non-vararg func.");
|
|
288
|
+
writeWrnMsg("(" + cs.getInstruction()->getSourceLoc() + ")");
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|