svf-tools 1.0.995 → 1.0.997
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/setup.sh +0 -1
- package/svf/include/Graphs/CDG.h +1 -1
- package/svf/include/Graphs/CHG.h +10 -8
- package/svf/include/Graphs/GenericGraph.h +22 -1
- package/svf/include/Graphs/ICFGNode.h +37 -62
- package/svf/include/MSSA/MSSAMuChi.h +2 -2
- package/svf/include/MTA/LockAnalysis.h +2 -2
- package/svf/include/MTA/MHP.h +3 -3
- package/svf/include/Util/SVFUtil.h +1 -8
- package/svf/include/Util/ThreadAPI.h +6 -6
- package/svf/lib/AE/Svfexe/AEDetector.cpp +14 -20
- package/svf/lib/AE/Svfexe/AbsExtAPI.cpp +49 -45
- package/svf/lib/CFL/CFLAlias.cpp +1 -1
- package/svf/lib/DDA/DDAClient.cpp +2 -2
- package/svf/lib/Graphs/CHG.cpp +17 -17
- package/svf/lib/Graphs/CallGraph.cpp +2 -1
- package/svf/lib/Graphs/ICFG.cpp +9 -9
- package/svf/lib/Graphs/SVFG.cpp +6 -6
- package/svf/lib/Graphs/ThreadCallGraph.cpp +8 -8
- package/svf/lib/Graphs/VFG.cpp +2 -2
- package/svf/lib/MTA/MTAStat.cpp +1 -1
- package/svf/lib/MTA/TCT.cpp +3 -3
- package/svf/lib/MemoryModel/PointerAnalysis.cpp +11 -11
- package/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +1 -1
- package/svf/lib/SABER/DoubleFreeChecker.cpp +8 -8
- package/svf/lib/SABER/LeakChecker.cpp +10 -10
- package/svf/lib/SVFIR/SVFFileSystem.cpp +8 -8
- package/svf/lib/Util/CallGraphBuilder.cpp +2 -1
- package/svf/lib/Util/SVFUtil.cpp +10 -3
- package/svf/lib/Util/ThreadAPI.cpp +14 -16
- package/svf/lib/WPA/Andersen.cpp +1 -1
- package/svf-llvm/include/SVF-LLVM/CHGBuilder.h +5 -0
- package/svf-llvm/include/SVF-LLVM/DCHG.h +2 -2
- package/svf-llvm/include/SVF-LLVM/LLVMModule.h +10 -0
- package/svf-llvm/lib/CHGBuilder.cpp +23 -17
- package/svf-llvm/lib/DCHG.cpp +18 -18
- package/svf-llvm/lib/ICFGBuilder.cpp +9 -2
- package/svf-llvm/lib/LLVMModule.cpp +6 -0
- package/svf-llvm/lib/LLVMUtil.cpp +25 -8
- package/svf-llvm/lib/SVFIRBuilder.cpp +2 -2
- package/svf-llvm/lib/SVFIRExtAPI.cpp +1 -1
- package/svf-llvm/lib/SymbolTableBuilder.cpp +2 -2
|
@@ -94,15 +94,15 @@ void DoubleFreeChecker::validateSuccessTests(ProgSlice *slice, const SVFFunction
|
|
|
94
94
|
if (success)
|
|
95
95
|
{
|
|
96
96
|
outs() << sucMsg("\t SUCCESS :") << funName << " check <src id:" << source->getId()
|
|
97
|
-
<< ", cs id:" << getSrcCSID(source)
|
|
98
|
-
<< cs->
|
|
97
|
+
<< ", cs id:" << (getSrcCSID(source))->toString() << "> at ("
|
|
98
|
+
<< cs->getSourceLoc() << ")\n";
|
|
99
99
|
outs() << "\t\t double free path: \n" << slice->evalFinalCond() << "\n";
|
|
100
100
|
}
|
|
101
101
|
else
|
|
102
102
|
{
|
|
103
103
|
SVFUtil::errs() << errMsg("\t FAILURE :") << funName << " check <src id:" << source->getId()
|
|
104
|
-
<< ", cs id:" <<getSrcCSID(source)
|
|
105
|
-
<< cs->
|
|
104
|
+
<< ", cs id:" << (getSrcCSID(source))->toString() << "> at ("
|
|
105
|
+
<< cs->getSourceLoc() << ")\n";
|
|
106
106
|
SVFUtil::errs() << "\t\t double free path: \n" << slice->evalFinalCond() << "\n";
|
|
107
107
|
assert(false && "test case failed!");
|
|
108
108
|
}
|
|
@@ -140,16 +140,16 @@ void DoubleFreeChecker::validateExpectedFailureTests(ProgSlice *slice, const SVF
|
|
|
140
140
|
if (expectedFailure)
|
|
141
141
|
{
|
|
142
142
|
outs() << sucMsg("\t EXPECTED-FAILURE :") << funName << " check <src id:" << source->getId()
|
|
143
|
-
<< ", cs id:" << getSrcCSID(source)
|
|
144
|
-
<< cs->
|
|
143
|
+
<< ", cs id:" << (getSrcCSID(source))->toString() << "> at ("
|
|
144
|
+
<< cs->getSourceLoc() << ")\n";
|
|
145
145
|
outs() << "\t\t double free path: \n" << slice->evalFinalCond() << "\n";
|
|
146
146
|
}
|
|
147
147
|
else
|
|
148
148
|
{
|
|
149
149
|
SVFUtil::errs() << errMsg("\t UNEXPECTED FAILURE :") << funName
|
|
150
150
|
<< " check <src id:" << source->getId()
|
|
151
|
-
<< ", cs id:" << getSrcCSID(source)
|
|
152
|
-
<< cs->
|
|
151
|
+
<< ", cs id:" << (getSrcCSID(source))->toString() << "> at ("
|
|
152
|
+
<< cs->getSourceLoc() << ")\n";
|
|
153
153
|
SVFUtil::errs() << "\t\t double free path: \n" << slice->evalFinalCond() << "\n";
|
|
154
154
|
assert(false && "test case failed!");
|
|
155
155
|
}
|
|
@@ -48,7 +48,7 @@ void LeakChecker::initSrcs()
|
|
|
48
48
|
/// if this callsite return reside in a dead function then we do not care about its leaks
|
|
49
49
|
/// for example instruction `int* p = malloc(size)` is in a dead function, then program won't allocate this memory
|
|
50
50
|
/// for example a customized malloc `int p = malloc()` returns an integer value, then program treat it as a system malloc
|
|
51
|
-
if(cs->
|
|
51
|
+
if(cs->getFun()->isUncalledFunction() || !cs->getType()->isPointerTy())
|
|
52
52
|
continue;
|
|
53
53
|
|
|
54
54
|
CallGraph::FunctionSet callees;
|
|
@@ -86,7 +86,7 @@ void LeakChecker::initSrcs()
|
|
|
86
86
|
else
|
|
87
87
|
{
|
|
88
88
|
// exclude sources in dead functions or sources in functions that have summary
|
|
89
|
-
if (!cs->
|
|
89
|
+
if (!cs->getFun()->isUncalledFunction() && !isExtCall(cs->getBB()->getParent()))
|
|
90
90
|
{
|
|
91
91
|
addToSources(node);
|
|
92
92
|
addSrcToCSID(node, cs);
|
|
@@ -231,14 +231,14 @@ void LeakChecker::validateSuccessTests(const SVFGNode* source, const SVFFunction
|
|
|
231
231
|
if (success)
|
|
232
232
|
{
|
|
233
233
|
outs() << sucMsg("\t SUCCESS :") << funName << " check <src id:" << source->getId()
|
|
234
|
-
<< ", cs id:" << getSrcCSID(source)
|
|
235
|
-
<< cs->
|
|
234
|
+
<< ", cs id:" << (getSrcCSID(source))->toString() << "> at ("
|
|
235
|
+
<< cs->getSourceLoc() << ")\n";
|
|
236
236
|
}
|
|
237
237
|
else
|
|
238
238
|
{
|
|
239
239
|
SVFUtil::errs() << errMsg("\t FAILURE :") << funName << " check <src id:" << source->getId()
|
|
240
|
-
<< ", cs id:" << getSrcCSID(source)
|
|
241
|
-
<< cs->
|
|
240
|
+
<< ", cs id:" << (getSrcCSID(source))->toString() << "> at ("
|
|
241
|
+
<< cs->getSourceLoc() << ")\n";
|
|
242
242
|
assert(false && "test case failed!");
|
|
243
243
|
}
|
|
244
244
|
}
|
|
@@ -281,15 +281,15 @@ void LeakChecker::validateExpectedFailureTests(const SVFGNode* source, const SVF
|
|
|
281
281
|
if (expectedFailure)
|
|
282
282
|
{
|
|
283
283
|
outs() << sucMsg("\t EXPECTED-FAILURE :") << funName << " check <src id:" << source->getId()
|
|
284
|
-
<< ", cs id:" << getSrcCSID(source)
|
|
285
|
-
<< cs->
|
|
284
|
+
<< ", cs id:" << (getSrcCSID(source))->toString() << "> at ("
|
|
285
|
+
<< cs->getSourceLoc() << ")\n";
|
|
286
286
|
}
|
|
287
287
|
else
|
|
288
288
|
{
|
|
289
289
|
SVFUtil::errs() << errMsg("\t UNEXPECTED FAILURE :") << funName
|
|
290
290
|
<< " check <src id:" << source->getId()
|
|
291
|
-
<< ", cs id:" << getSrcCSID(source)
|
|
292
|
-
<< cs->
|
|
291
|
+
<< ", cs id:" << (getSrcCSID(source))->toString() << "> at ("
|
|
292
|
+
<< cs->getSourceLoc() << ")\n";
|
|
293
293
|
assert(false && "test case failed!");
|
|
294
294
|
}
|
|
295
295
|
}
|
|
@@ -386,7 +386,7 @@ cJSON* SVFIRWriter::contentToJson(const GlobalICFGNode* node)
|
|
|
386
386
|
cJSON* SVFIRWriter::contentToJson(const IntraICFGNode* node)
|
|
387
387
|
{
|
|
388
388
|
cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
|
|
389
|
-
JSON_WRITE_FIELD(root, node,
|
|
389
|
+
JSON_WRITE_FIELD(root, node, isRet);
|
|
390
390
|
return root;
|
|
391
391
|
}
|
|
392
392
|
|
|
@@ -1153,10 +1153,10 @@ cJSON* SVFIRWriter::toJson(const CHGraph* graph)
|
|
|
1153
1153
|
F(classNameToAncestorsMap);
|
|
1154
1154
|
F(classNameToInstAndDescsMap);
|
|
1155
1155
|
F(templateNameToInstancesMap);
|
|
1156
|
-
F(
|
|
1156
|
+
F(callNodeToClassesMap);
|
|
1157
1157
|
F(virtualFunctionToIDMap);
|
|
1158
|
-
F(
|
|
1159
|
-
F(
|
|
1158
|
+
F(callNodeToCHAVtblsMap);
|
|
1159
|
+
F(callNodeToCHAVFnsMap);
|
|
1160
1160
|
#undef F
|
|
1161
1161
|
return root;
|
|
1162
1162
|
}
|
|
@@ -1755,10 +1755,10 @@ void SVFIRReader::readJson(CHGraph* graph)
|
|
|
1755
1755
|
F(classNameToAncestorsMap);
|
|
1756
1756
|
F(classNameToInstAndDescsMap);
|
|
1757
1757
|
F(templateNameToInstancesMap);
|
|
1758
|
-
F(
|
|
1758
|
+
F(callNodeToClassesMap);
|
|
1759
1759
|
F(virtualFunctionToIDMap);
|
|
1760
|
-
F(
|
|
1761
|
-
F(
|
|
1760
|
+
F(callNodeToCHAVtblsMap);
|
|
1761
|
+
F(callNodeToCHAVFnsMap);
|
|
1762
1762
|
#undef F
|
|
1763
1763
|
}
|
|
1764
1764
|
|
|
@@ -2182,7 +2182,7 @@ void SVFIRReader::fill(const cJSON*& fieldJson, GlobalICFGNode* node)
|
|
|
2182
2182
|
void SVFIRReader::fill(const cJSON*& fieldJson, IntraICFGNode* node)
|
|
2183
2183
|
{
|
|
2184
2184
|
fill(fieldJson, static_cast<ICFGNode*>(node));
|
|
2185
|
-
JSON_READ_FIELD_FWD(fieldJson, node,
|
|
2185
|
+
JSON_READ_FIELD_FWD(fieldJson, node, isRet);
|
|
2186
2186
|
}
|
|
2187
2187
|
|
|
2188
2188
|
void SVFIRReader::fill(const cJSON*& fieldJson, InterICFGNode* node)
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
#include "Util/SVFUtil.h"
|
|
32
32
|
#include "Util/CallGraphBuilder.h"
|
|
33
33
|
#include "Graphs/ICFG.h"
|
|
34
|
+
#include "SVFIR/SVFIR.h"
|
|
34
35
|
|
|
35
36
|
using namespace SVF;
|
|
36
37
|
using namespace SVFUtil;
|
|
@@ -84,7 +85,7 @@ CallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule)
|
|
|
84
85
|
{
|
|
85
86
|
const CallICFGNode* cs = cast<CallICFGNode>(inst);
|
|
86
87
|
cg->addForksite(cs);
|
|
87
|
-
const SVFFunction* forkee = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getForkedFun(cs));
|
|
88
|
+
const SVFFunction* forkee = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getForkedFun(cs)->getValue());
|
|
88
89
|
if (forkee)
|
|
89
90
|
{
|
|
90
91
|
cg->addDirectForkEdge(cs);
|
package/svf/lib/Util/SVFUtil.cpp
CHANGED
|
@@ -374,13 +374,13 @@ bool SVFUtil::isHeapAllocExtCall(const ICFGNode* cs)
|
|
|
374
374
|
|
|
375
375
|
bool SVFUtil::isHeapAllocExtCallViaRet(const CallICFGNode* cs)
|
|
376
376
|
{
|
|
377
|
-
bool isPtrTy = cs->
|
|
377
|
+
bool isPtrTy = cs->getType()->isPointerTy();
|
|
378
378
|
return isPtrTy && isHeapAllocExtFunViaRet(cs->getCalledFunction());
|
|
379
379
|
}
|
|
380
380
|
|
|
381
381
|
bool SVFUtil::isReallocExtCall(const CallICFGNode* cs)
|
|
382
382
|
{
|
|
383
|
-
bool isPtrTy = cs->
|
|
383
|
+
bool isPtrTy = cs->getType()->isPointerTy();
|
|
384
384
|
return isPtrTy && isReallocExtFun(cs->getCalledFunction());
|
|
385
385
|
}
|
|
386
386
|
|
|
@@ -388,7 +388,7 @@ bool SVFUtil::isReallocExtCall(const CallICFGNode* cs)
|
|
|
388
388
|
bool SVFUtil::isRetInstNode(const ICFGNode* node)
|
|
389
389
|
{
|
|
390
390
|
if (const auto& intraNode = dyn_cast<IntraICFGNode>(node))
|
|
391
|
-
return intraNode->
|
|
391
|
+
return intraNode->isRetInst();
|
|
392
392
|
else
|
|
393
393
|
return false;
|
|
394
394
|
}
|
|
@@ -396,4 +396,11 @@ bool SVFUtil::isRetInstNode(const ICFGNode* node)
|
|
|
396
396
|
bool SVFUtil::isProgExitCall(const CallICFGNode* cs)
|
|
397
397
|
{
|
|
398
398
|
return isProgExitFunction(cs->getCalledFunction());
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
__attribute__((weak))
|
|
402
|
+
const std::string SVFBaseNode::toString() const
|
|
403
|
+
{
|
|
404
|
+
assert("SVFBaseNode::toString should be implemented or supported by fronted" && false);
|
|
405
|
+
abort();
|
|
399
406
|
}
|
|
@@ -160,25 +160,24 @@ bool ThreadAPI::isTDBarWait(const CallICFGNode *inst) const
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
|
|
163
|
-
const
|
|
163
|
+
const SVFVar* ThreadAPI::getForkedThread(const CallICFGNode *inst) const
|
|
164
164
|
{
|
|
165
165
|
assert(isTDFork(inst) && "not a thread fork function!");
|
|
166
166
|
return inst->getArgument(0);
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
const
|
|
169
|
+
const SVFVar* ThreadAPI::getForkedFun(const CallICFGNode *inst) const
|
|
170
170
|
{
|
|
171
171
|
assert(isTDFork(inst) && "not a thread fork function!");
|
|
172
172
|
return inst->getArgument(2);
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
|
|
175
|
+
/// Return the forth argument of the call,
|
|
176
|
+
/// Note that, it is the sole argument of start routine ( a void* pointer )
|
|
177
|
+
const SVFVar* ThreadAPI::getActualParmAtForkSite(const CallICFGNode *inst) const
|
|
176
178
|
{
|
|
177
|
-
assert(
|
|
178
|
-
|
|
179
|
-
// pthread_create has 4 parameters
|
|
180
|
-
assert(csArgList.size() == 4 && "num of forksite args is not 4");
|
|
181
|
-
return csArgList[3];
|
|
179
|
+
assert(isTDFork(inst) && "not a thread fork function!");
|
|
180
|
+
return inst->getArgument(3);
|
|
182
181
|
}
|
|
183
182
|
|
|
184
183
|
const SVFVar* ThreadAPI::getFormalParmOfForkedFun(const SVFFunction* F) const
|
|
@@ -190,13 +189,13 @@ const SVFVar* ThreadAPI::getFormalParmOfForkedFun(const SVFFunction* F) const
|
|
|
190
189
|
return funArgList[0];
|
|
191
190
|
}
|
|
192
191
|
|
|
193
|
-
const
|
|
192
|
+
const SVFVar* ThreadAPI::getRetParmAtJoinedSite(const CallICFGNode *inst) const
|
|
194
193
|
{
|
|
195
194
|
assert(isTDJoin(inst) && "not a thread join function!");
|
|
196
195
|
return inst->getArgument(1);
|
|
197
196
|
}
|
|
198
197
|
|
|
199
|
-
const
|
|
198
|
+
const SVFVar* ThreadAPI::getLockVal(const ICFGNode *cs) const
|
|
200
199
|
{
|
|
201
200
|
const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(cs);
|
|
202
201
|
assert(call && "not a call ICFGNode?");
|
|
@@ -204,17 +203,16 @@ const SVFValue* ThreadAPI::getLockVal(const ICFGNode *cs) const
|
|
|
204
203
|
return call->getArgument(0);
|
|
205
204
|
}
|
|
206
205
|
|
|
207
|
-
const
|
|
206
|
+
const SVFVar* ThreadAPI::getJoinedThread(const CallICFGNode *cs) const
|
|
208
207
|
{
|
|
209
208
|
assert(isTDJoin(cs) && "not a thread join function!");
|
|
210
|
-
const
|
|
211
|
-
const
|
|
212
|
-
for(const SVFStmt* stmt : var->getInEdges())
|
|
209
|
+
const SVFVar* join = cs->getArgument(0);
|
|
210
|
+
for(const SVFStmt* stmt : join->getInEdges())
|
|
213
211
|
{
|
|
214
212
|
if(SVFUtil::isa<LoadStmt>(stmt))
|
|
215
|
-
return stmt->getSrcNode()
|
|
213
|
+
return stmt->getSrcNode();
|
|
216
214
|
}
|
|
217
|
-
if(SVFUtil::isa<SVFArgument>(join))
|
|
215
|
+
if(SVFUtil::isa<SVFArgument>(join->getValue()))
|
|
218
216
|
return join;
|
|
219
217
|
|
|
220
218
|
assert(false && "the value of the first argument at join is not a load instruction?");
|
package/svf/lib/WPA/Andersen.cpp
CHANGED
|
@@ -379,7 +379,7 @@ void AndersenBase::heapAllocatorViaIndCall(const CallICFGNode* cs, NodePairSet &
|
|
|
379
379
|
else
|
|
380
380
|
{
|
|
381
381
|
NodeID valNode = pag->addDummyValNode();
|
|
382
|
-
NodeID objNode = pag->addDummyObjNode(cs->
|
|
382
|
+
NodeID objNode = pag->addDummyObjNode(cs->getType());
|
|
383
383
|
addPts(valNode,objNode);
|
|
384
384
|
callsite2DummyValPN.insert(std::make_pair(cs,valNode));
|
|
385
385
|
consCG->addConstraintNode(new ConstraintNode(valNode),valNode);
|
|
@@ -33,6 +33,8 @@
|
|
|
33
33
|
namespace SVF
|
|
34
34
|
{
|
|
35
35
|
|
|
36
|
+
class LLVMModuleSet;
|
|
37
|
+
|
|
36
38
|
class CHGBuilder
|
|
37
39
|
{
|
|
38
40
|
|
|
@@ -67,6 +69,9 @@ public:
|
|
|
67
69
|
void buildCSToCHAVtblsAndVfnsMap();
|
|
68
70
|
const CHNodeSetTy& getCSClasses(const CallBase* cs);
|
|
69
71
|
void addFuncToFuncVector(CHNode::FuncVector &v, const Function *f);
|
|
72
|
+
|
|
73
|
+
private:
|
|
74
|
+
LLVMModuleSet* llvmModuleSet();
|
|
70
75
|
};
|
|
71
76
|
|
|
72
77
|
} // End namespace SVF
|
|
@@ -93,7 +93,7 @@ public:
|
|
|
93
93
|
|
|
94
94
|
~DCHNode() { }
|
|
95
95
|
|
|
96
|
-
const DIType *
|
|
96
|
+
const DIType * getDIType(void) const
|
|
97
97
|
{
|
|
98
98
|
return diType;
|
|
99
99
|
}
|
|
@@ -275,7 +275,7 @@ public:
|
|
|
275
275
|
}
|
|
276
276
|
|
|
277
277
|
virtual const VTableSet &getCSVtblsBasedonCHA(const CallICFGNode* cs) override;
|
|
278
|
-
virtual void getVFnsFromVtbls(const
|
|
278
|
+
virtual void getVFnsFromVtbls(const CallICFGNode* cs, const VTableSet &vtbls, VFunSet &virtualFunctions) override;
|
|
279
279
|
|
|
280
280
|
/// Returns true if a is a transitive base of b. firstField determines
|
|
281
281
|
/// whether to consider first-field edges.
|
|
@@ -60,6 +60,7 @@ public:
|
|
|
60
60
|
typedef Map<const Constant*, SVFConstant*> LLVMConst2SVFConstMap;
|
|
61
61
|
typedef Map<const Value*, SVFOtherValue*> LLVMValue2SVFOtherValueMap;
|
|
62
62
|
typedef Map<const SVFValue*, const Value*> SVFValue2LLVMValueMap;
|
|
63
|
+
typedef Map<const SVFBaseNode*, const Value*> SVFBaseNode2LLVMValueMap;
|
|
63
64
|
typedef Map<const Type*, SVFType*> LLVMType2SVFTypeMap;
|
|
64
65
|
typedef Map<const Type*, StInfo*> Type2TypeInfoMap;
|
|
65
66
|
typedef Map<std::string, std::vector<std::string>> Fun2AnnoMap;
|
|
@@ -97,6 +98,7 @@ private:
|
|
|
97
98
|
Type2TypeInfoMap Type2TypeInfo;
|
|
98
99
|
ObjTypeInference* typeInference;
|
|
99
100
|
|
|
101
|
+
SVFBaseNode2LLVMValueMap SVFBaseNode2LLVMValue;
|
|
100
102
|
CSToCallNodeMapTy CSToCallNodeMap; ///< map a callsite to its CallICFGNode
|
|
101
103
|
CSToRetNodeMapTy CSToRetNodeMap; ///< map a callsite to its RetICFGNode
|
|
102
104
|
InstToBlockNodeMapTy InstToBlockNodeMap; ///< map a basic block to its ICFGNode
|
|
@@ -216,6 +218,13 @@ public:
|
|
|
216
218
|
return it->second;
|
|
217
219
|
}
|
|
218
220
|
|
|
221
|
+
const Value* getLLVMValue(const SVFBaseNode* value) const
|
|
222
|
+
{
|
|
223
|
+
SVFBaseNode2LLVMValueMap ::const_iterator it = SVFBaseNode2LLVMValue.find(value);
|
|
224
|
+
assert(it!=SVFBaseNode2LLVMValue.end() && "can't find corresponding llvm value!");
|
|
225
|
+
return it->second;
|
|
226
|
+
}
|
|
227
|
+
|
|
219
228
|
inline SVFFunction* getSVFFunction(const Function* fun) const
|
|
220
229
|
{
|
|
221
230
|
LLVMFun2SVFFunMap::const_iterator it = LLVMFunc2SVFFunc.find(fun);
|
|
@@ -378,6 +387,7 @@ private:
|
|
|
378
387
|
void initSVFBasicBlock(const Function* func);
|
|
379
388
|
void initDomTree(SVFFunction* func, const Function* f);
|
|
380
389
|
void setValueAttr(const Value* val, SVFValue* value);
|
|
390
|
+
void setValueAttr(const Value* val, SVFBaseNode* svfBaseNode);
|
|
381
391
|
void buildFunToFunMap();
|
|
382
392
|
void buildGlobalDefToRepMap();
|
|
383
393
|
/// Invoke llvm passes to modify module
|
|
@@ -57,13 +57,17 @@ const string pureVirtualFunName = "__cxa_pure_virtual";
|
|
|
57
57
|
|
|
58
58
|
const string ztiLabel = "_ZTI";
|
|
59
59
|
|
|
60
|
+
LLVMModuleSet* CHGBuilder::llvmModuleSet()
|
|
61
|
+
{
|
|
62
|
+
return LLVMModuleSet::getLLVMModuleSet();
|
|
63
|
+
}
|
|
60
64
|
|
|
61
65
|
void CHGBuilder::buildCHG()
|
|
62
66
|
{
|
|
63
67
|
|
|
64
68
|
double timeStart, timeEnd;
|
|
65
69
|
timeStart = PTAStat::getClk(true);
|
|
66
|
-
for (Module &M :
|
|
70
|
+
for (Module &M : llvmModuleSet()->getLLVMModules())
|
|
67
71
|
{
|
|
68
72
|
DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("construct CHGraph From module "
|
|
69
73
|
+ M.getName().str() + "...\n"));
|
|
@@ -375,7 +379,7 @@ void CHGBuilder::analyzeVTables(const Module &M)
|
|
|
375
379
|
assert(node && "node not found?");
|
|
376
380
|
|
|
377
381
|
SVFGlobalValue* pValue =
|
|
378
|
-
|
|
382
|
+
llvmModuleSet()->getSVFGlobalValue(
|
|
379
383
|
globalvalue);
|
|
380
384
|
pValue->setName(vtblClassName);
|
|
381
385
|
node->setVTable(pValue);
|
|
@@ -655,7 +659,7 @@ void CHGBuilder::buildVirtualFunctionToIDMap()
|
|
|
655
659
|
void CHGBuilder::buildCSToCHAVtblsAndVfnsMap()
|
|
656
660
|
{
|
|
657
661
|
|
|
658
|
-
for (Module &M :
|
|
662
|
+
for (Module &M : llvmModuleSet()->getLLVMModules())
|
|
659
663
|
{
|
|
660
664
|
for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
|
|
661
665
|
{
|
|
@@ -679,12 +683,13 @@ void CHGBuilder::buildCSToCHAVtblsAndVfnsMap()
|
|
|
679
683
|
}
|
|
680
684
|
if (vtbls.size() > 0)
|
|
681
685
|
{
|
|
682
|
-
|
|
683
|
-
|
|
686
|
+
ICFGNode* icfgNode =
|
|
687
|
+
llvmModuleSet()->getICFGNode(callInst);
|
|
688
|
+
chg->callNodeToCHAVtblsMap[icfgNode] = vtbls;
|
|
684
689
|
VFunSet virtualFunctions;
|
|
685
|
-
chg->getVFnsFromVtbls(SVFUtil::cast<
|
|
690
|
+
chg->getVFnsFromVtbls(SVFUtil::cast<CallICFGNode>(icfgNode), vtbls, virtualFunctions);
|
|
686
691
|
if (virtualFunctions.size() > 0)
|
|
687
|
-
chg->
|
|
692
|
+
chg->callNodeToCHAVFnsMap[icfgNode] = virtualFunctions;
|
|
688
693
|
}
|
|
689
694
|
}
|
|
690
695
|
}
|
|
@@ -696,10 +701,11 @@ void CHGBuilder::buildCSToCHAVtblsAndVfnsMap()
|
|
|
696
701
|
const CHGraph::CHNodeSetTy& CHGBuilder::getCSClasses(const CallBase* cs)
|
|
697
702
|
{
|
|
698
703
|
assert(cppUtil::isVirtualCallSite(cs) && "not virtual callsite!");
|
|
699
|
-
const SVFInstruction* svfcall = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(cs);
|
|
700
704
|
|
|
701
|
-
|
|
702
|
-
|
|
705
|
+
ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(cs);
|
|
706
|
+
|
|
707
|
+
CHGraph::CallNodeToCHNodesMap::const_iterator it = chg->callNodeToClassesMap.find(icfgNode);
|
|
708
|
+
if (it != chg->callNodeToClassesMap.end())
|
|
703
709
|
{
|
|
704
710
|
return it->second;
|
|
705
711
|
}
|
|
@@ -712,9 +718,9 @@ const CHGraph::CHNodeSetTy& CHGBuilder::getCSClasses(const CallBase* cs)
|
|
|
712
718
|
// if we cannot infer classname, conservatively push all class nodes
|
|
713
719
|
for (const auto &node: *chg)
|
|
714
720
|
{
|
|
715
|
-
chg->
|
|
721
|
+
chg->callNodeToClassesMap[icfgNode].insert(node.second);
|
|
716
722
|
}
|
|
717
|
-
return chg->
|
|
723
|
+
return chg->callNodeToClassesMap[icfgNode];
|
|
718
724
|
}
|
|
719
725
|
|
|
720
726
|
for (const auto &thisPtrClassName: thisPtrClassNames)
|
|
@@ -722,12 +728,12 @@ const CHGraph::CHNodeSetTy& CHGBuilder::getCSClasses(const CallBase* cs)
|
|
|
722
728
|
if (const CHNode* thisNode = chg->getNode(thisPtrClassName))
|
|
723
729
|
{
|
|
724
730
|
const CHGraph::CHNodeSetTy& instAndDesces = getInstancesAndDescendants(thisPtrClassName);
|
|
725
|
-
chg->
|
|
731
|
+
chg->callNodeToClassesMap[icfgNode].insert(thisNode);
|
|
726
732
|
for (CHGraph::CHNodeSetTy::const_iterator it2 = instAndDesces.begin(), eit = instAndDesces.end(); it2 != eit; ++it2)
|
|
727
|
-
chg->
|
|
733
|
+
chg->callNodeToClassesMap[icfgNode].insert(*it2);
|
|
728
734
|
}
|
|
729
735
|
}
|
|
730
|
-
return chg->
|
|
736
|
+
return chg->callNodeToClassesMap[icfgNode];
|
|
731
737
|
}
|
|
732
738
|
}
|
|
733
739
|
|
|
@@ -738,14 +744,14 @@ void CHGBuilder::addFuncToFuncVector(CHNode::FuncVector &v, const Function *lf)
|
|
|
738
744
|
if (const auto* tf = cppUtil::getThunkTarget(lf))
|
|
739
745
|
{
|
|
740
746
|
SVFFunction* pFunction =
|
|
741
|
-
|
|
747
|
+
llvmModuleSet()->getSVFFunction(tf);
|
|
742
748
|
v.push_back(pFunction);
|
|
743
749
|
}
|
|
744
750
|
}
|
|
745
751
|
else
|
|
746
752
|
{
|
|
747
753
|
SVFFunction* pFunction =
|
|
748
|
-
|
|
754
|
+
llvmModuleSet()->getSVFFunction(lf);
|
|
749
755
|
v.push_back(pFunction);
|
|
750
756
|
}
|
|
751
757
|
}
|
package/svf-llvm/lib/DCHG.cpp
CHANGED
|
@@ -251,7 +251,7 @@ const NodeBS &DCHGraph::cha(const DIType *type, bool firstField)
|
|
|
251
251
|
continue;
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
-
const NodeBS &cchildren = cha(edge->getSrcNode()->
|
|
254
|
+
const NodeBS &cchildren = cha(edge->getSrcNode()->getDIType(), firstField);
|
|
255
255
|
// Children's children are my children.
|
|
256
256
|
for (NodeID cchild : cchildren)
|
|
257
257
|
{
|
|
@@ -530,10 +530,10 @@ void DCHGraph::buildCHG(bool extend)
|
|
|
530
530
|
for (iterator nodeI = begin(); nodeI != end(); ++nodeI)
|
|
531
531
|
{
|
|
532
532
|
// Everything without a parent gets char as a parent.
|
|
533
|
-
if (nodeI->second->
|
|
533
|
+
if (nodeI->second->getDIType() != nullptr
|
|
534
534
|
&& nodeI->second->getOutEdges().size() == 0)
|
|
535
535
|
{
|
|
536
|
-
addEdge(nodeI->second->
|
|
536
|
+
addEdge(nodeI->second->getDIType(), charType, DCHEdge::STD_DEF);
|
|
537
537
|
}
|
|
538
538
|
}
|
|
539
539
|
}
|
|
@@ -553,7 +553,7 @@ const VFunSet &DCHGraph::getCSVFsBasedonCHA(const CallICFGNode* cs)
|
|
|
553
553
|
|
|
554
554
|
VFunSet vfns;
|
|
555
555
|
const VTableSet &vtbls = getCSVtblsBasedonCHA(cs);
|
|
556
|
-
getVFnsFromVtbls(
|
|
556
|
+
getVFnsFromVtbls(cs, vtbls, vfns);
|
|
557
557
|
|
|
558
558
|
// Cache.
|
|
559
559
|
csCHAMap.insert({cs, vfns});
|
|
@@ -589,11 +589,10 @@ const VTableSet &DCHGraph::getCSVtblsBasedonCHA(const CallICFGNode* cs)
|
|
|
589
589
|
return vtblCHAMap[type];
|
|
590
590
|
}
|
|
591
591
|
|
|
592
|
-
void DCHGraph::getVFnsFromVtbls(const
|
|
592
|
+
void DCHGraph::getVFnsFromVtbls(const CallICFGNode* callsite, const VTableSet &vtbls, VFunSet &virtualFunctions)
|
|
593
593
|
{
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
std::string funName = cs->getFunNameOfVirtualCall();
|
|
594
|
+
size_t idx = callsite->getFunIdxInVtable();
|
|
595
|
+
std::string funName = callsite->getFunNameOfVirtualCall();
|
|
597
596
|
for (const SVFGlobalValue *vtbl : vtbls)
|
|
598
597
|
{
|
|
599
598
|
assert(vtblToTypeMap.find(vtbl) != vtblToTypeMap.end() && "floating vtbl");
|
|
@@ -611,7 +610,7 @@ void DCHGraph::getVFnsFromVtbls(const SVFCallInst* callsite, const VTableSet &vt
|
|
|
611
610
|
|
|
612
611
|
const Function* callee = vfnV[idx];
|
|
613
612
|
// Practically a copy of that in lib/MemoryModel/CHA.cpp
|
|
614
|
-
if (
|
|
613
|
+
if (callsite->arg_size() == callee->arg_size() || (callsite->isVarArg() && callee->isVarArg()))
|
|
615
614
|
{
|
|
616
615
|
cppUtil::DemangledName dname = cppUtil::demangle(callee->getName().str());
|
|
617
616
|
std::string calleeName = dname.funcName;
|
|
@@ -957,8 +956,8 @@ bool DCHGraph::isFirstField(const DIType *f, const DIType *b)
|
|
|
957
956
|
// Only care about first-field edges.
|
|
958
957
|
if (edge->getEdgeKind() == DCHEdge::FIRST_FIELD)
|
|
959
958
|
{
|
|
960
|
-
if (edge->getSrcNode()->
|
|
961
|
-
if (isFirstField(edge->getSrcNode()->
|
|
959
|
+
if (edge->getSrcNode()->getDIType() == b) return true;
|
|
960
|
+
if (isFirstField(edge->getSrcNode()->getDIType(), b)) return true;
|
|
962
961
|
}
|
|
963
962
|
}
|
|
964
963
|
|
|
@@ -1163,13 +1162,14 @@ void DCHGraph::print(void)
|
|
|
1163
1162
|
|
|
1164
1163
|
const DCHNode *node = getGNode(id);
|
|
1165
1164
|
|
|
1166
|
-
SVFUtil::outs() << indent(currIndent) << id << ": " << diTypeToStr(node->
|
|
1167
|
-
if (node->
|
|
1168
|
-
&& (node->
|
|
1169
|
-
||
|
|
1165
|
+
SVFUtil::outs() << indent(currIndent) << id << ": " << diTypeToStr(node->getDIType()) << " [" << node->getDIType() << "]" << "\n";
|
|
1166
|
+
if (node->getDIType() != nullptr
|
|
1167
|
+
&& (node->getDIType()->getTag() == dwarf::DW_TAG_class_type
|
|
1168
|
+
||
|
|
1169
|
+
node->getDIType()->getTag() == dwarf::DW_TAG_structure_type))
|
|
1170
1170
|
{
|
|
1171
1171
|
++numStructs;
|
|
1172
|
-
unsigned numFields = getFieldTypes(node->
|
|
1172
|
+
unsigned numFields = getFieldTypes(node->getDIType()).size();
|
|
1173
1173
|
largestStruct = numFields > largestStruct ? numFields : largestStruct;
|
|
1174
1174
|
}
|
|
1175
1175
|
|
|
@@ -1225,8 +1225,8 @@ void DCHGraph::print(void)
|
|
|
1225
1225
|
arrow = "----unknown---->";
|
|
1226
1226
|
}
|
|
1227
1227
|
|
|
1228
|
-
SVFUtil::outs() << indent(currIndent) << "[ " << diTypeToStr(node->
|
|
1229
|
-
<< arrow << " [ " << diTypeToStr(edge->getDstNode()->
|
|
1228
|
+
SVFUtil::outs() << indent(currIndent) << "[ " << diTypeToStr(node->getDIType()) << " ] "
|
|
1229
|
+
<< arrow << " [ " << diTypeToStr(edge->getDstNode()->getDIType()) << " ]\n";
|
|
1230
1230
|
}
|
|
1231
1231
|
|
|
1232
1232
|
if (node->getOutEdges().size() == 0)
|
|
@@ -239,15 +239,19 @@ InterICFGNode* ICFGBuilder::addInterBlockICFGNode(const Instruction* inst)
|
|
|
239
239
|
assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
|
|
240
240
|
assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
|
|
241
241
|
assert(llvmModuleSet()->getCallBlock(inst)==nullptr && "duplicate CallICFGNode");
|
|
242
|
-
CallICFGNode* callICFGNode =
|
|
242
|
+
CallICFGNode* callICFGNode =
|
|
243
|
+
new CallICFGNode(icfg->totalICFGNode++, svfInst,
|
|
244
|
+
llvmModuleSet()->getSVFType(inst->getType()));
|
|
243
245
|
icfg->addICFGNode(callICFGNode);
|
|
244
246
|
csToCallNodeMap()[inst] = callICFGNode;
|
|
247
|
+
llvmModuleSet()->setValueAttr(inst, callICFGNode);
|
|
245
248
|
|
|
246
249
|
assert(llvmModuleSet()->getRetBlock(inst)==nullptr && "duplicate RetICFGNode");
|
|
247
250
|
RetICFGNode* retICFGNode = new RetICFGNode(icfg->totalICFGNode++, svfInst, callICFGNode);
|
|
248
251
|
callICFGNode->setRetICFGNode(retICFGNode);
|
|
249
252
|
icfg->addICFGNode(retICFGNode);
|
|
250
253
|
csToRetNodeMap()[inst] = retICFGNode;
|
|
254
|
+
llvmModuleSet()->setValueAttr(inst, retICFGNode);
|
|
251
255
|
|
|
252
256
|
addICFGInterEdges(inst, LLVMUtil::getCallee(SVFUtil::cast<CallBase>(inst))); //creating interprocedural edges
|
|
253
257
|
return callICFGNode;
|
|
@@ -329,9 +333,12 @@ IntraICFGNode* ICFGBuilder::addIntraBlockICFGNode(const Instruction* inst)
|
|
|
329
333
|
llvmModuleSet()->getSVFInstruction(inst);
|
|
330
334
|
IntraICFGNode* node = llvmModuleSet()->getIntraBlock(inst);
|
|
331
335
|
assert (node==nullptr && "no IntraICFGNode for this instruction?");
|
|
332
|
-
IntraICFGNode* sNode =
|
|
336
|
+
IntraICFGNode* sNode =
|
|
337
|
+
new IntraICFGNode(icfg->totalICFGNode++, svfInst->getParent(),
|
|
338
|
+
SVFUtil::isa<ReturnInst>(inst));
|
|
333
339
|
icfg->addICFGNode(sNode);
|
|
334
340
|
instToBlockNodeMap()[inst] = sNode;
|
|
341
|
+
llvmModuleSet()->setValueAttr(inst, sNode);
|
|
335
342
|
return sNode;
|
|
336
343
|
}
|
|
337
344
|
|
|
@@ -1230,6 +1230,12 @@ void LLVMModuleSet::setValueAttr(const Value* val, SVFValue* svfvalue)
|
|
|
1230
1230
|
svfvalue->setSourceLoc(LLVMUtil::getSourceLoc(val));
|
|
1231
1231
|
}
|
|
1232
1232
|
|
|
1233
|
+
void LLVMModuleSet::setValueAttr(const SVF::Value* val, SVF::SVFBaseNode* svfBaseNode)
|
|
1234
|
+
{
|
|
1235
|
+
SVFBaseNode2LLVMValue[svfBaseNode] = val;
|
|
1236
|
+
svfBaseNode->setSourceLoc(LLVMUtil::getSourceLoc(val));
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1233
1239
|
SVFConstantData* LLVMModuleSet::getSVFConstantData(const ConstantData* cd)
|
|
1234
1240
|
{
|
|
1235
1241
|
LLVMConst2SVFConstMap::const_iterator it = LLVMConst2SVFConst.find(cd);
|