svf-tools 1.0.983 → 1.0.985
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/AE/Svfexe/AbstractInterpretation.h +1 -1
- package/svf/include/CFL/CFLAlias.h +3 -3
- package/svf/include/Graphs/CHG.h +13 -31
- package/svf/include/Graphs/ICFG.h +2 -2
- package/svf/include/Graphs/ICFGEdge.h +4 -16
- package/svf/include/Graphs/ICFGNode.h +58 -0
- package/svf/include/Graphs/ThreadCallGraph.h +6 -6
- package/svf/include/MTA/MHP.h +3 -3
- package/svf/include/MTA/TCT.h +1 -1
- package/svf/include/SVFIR/SVFFileSystem.h +0 -2
- package/svf/include/SVFIR/SVFValue.h +0 -131
- package/svf/include/Util/SVFUtil.h +20 -37
- package/svf/include/Util/ThreadAPI.h +5 -26
- package/svf/include/WPA/Andersen.h +3 -3
- package/svf/include/WPA/Steensgaard.h +3 -3
- package/svf/include/WPA/WPAPass.h +3 -3
- package/svf/lib/AE/Svfexe/AEDetector.cpp +14 -18
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +66 -94
- package/svf/lib/CFL/CFLAlias.cpp +11 -12
- package/svf/lib/DDA/DDAClient.cpp +2 -2
- package/svf/lib/Graphs/CHG.cpp +33 -9
- package/svf/lib/Graphs/ICFG.cpp +13 -10
- package/svf/lib/MSSA/MemRegion.cpp +3 -3
- package/svf/lib/MTA/MHP.cpp +1 -1
- package/svf/lib/MemoryModel/PointerAnalysis.cpp +21 -23
- package/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +2 -2
- package/svf/lib/SABER/SaberCondAllocator.cpp +1 -1
- package/svf/lib/SABER/SaberSVFGBuilder.cpp +1 -1
- package/svf/lib/SVFIR/SVFFileSystem.cpp +2 -20
- package/svf/lib/Util/SVFUtil.cpp +34 -18
- package/svf/lib/Util/ThreadAPI.cpp +32 -15
- package/svf/lib/WPA/Andersen.cpp +8 -9
- package/svf/lib/WPA/AndersenSCD.cpp +1 -2
- package/svf/lib/WPA/Steensgaard.cpp +8 -12
- package/svf/lib/WPA/TypeAnalysis.cpp +2 -3
- package/svf/lib/WPA/WPAPass.cpp +6 -13
- package/svf-llvm/include/SVF-LLVM/DCHG.h +7 -7
- package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +0 -8
- package/svf-llvm/lib/CHGBuilder.cpp +4 -4
- package/svf-llvm/lib/DCHG.cpp +8 -7
- package/svf-llvm/lib/ICFGBuilder.cpp +2 -2
- package/svf-llvm/lib/LLVMModule.cpp +0 -2
- package/svf-llvm/lib/LLVMUtil.cpp +0 -58
- package/svf-llvm/lib/SVFIRExtAPI.cpp +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.985",
|
|
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": {
|
|
@@ -358,7 +358,7 @@ protected:
|
|
|
358
358
|
|
|
359
359
|
protected:
|
|
360
360
|
// there data should be shared with subclasses
|
|
361
|
-
Map<std::string, std::function<void(const
|
|
361
|
+
Map<std::string, std::function<void(const CallICFGNode*)>> func_map;
|
|
362
362
|
Set<const CallICFGNode*> checkpoints;
|
|
363
363
|
Set<std::string> checkpoint_names;
|
|
364
364
|
Map<const ICFGNode*, AbstractState>
|
|
@@ -42,7 +42,7 @@ class CFLAlias : public CFLBase
|
|
|
42
42
|
{
|
|
43
43
|
|
|
44
44
|
public:
|
|
45
|
-
typedef OrderedMap<
|
|
45
|
+
typedef OrderedMap<const CallICFGNode*, NodeID> CallSite2DummyValPN;
|
|
46
46
|
|
|
47
47
|
CFLAlias(SVFIR* ir) : CFLBase(ir, PointerAnalysis::CFLFICI_WPA)
|
|
48
48
|
{
|
|
@@ -143,9 +143,9 @@ public:
|
|
|
143
143
|
virtual void onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites, CallEdgeMap& newEdges);
|
|
144
144
|
|
|
145
145
|
/// Connect formal and actual parameters for indirect callsites
|
|
146
|
-
void connectCaller2CalleeParams(
|
|
146
|
+
void connectCaller2CalleeParams(const CallICFGNode* cs, const SVFFunction* F);
|
|
147
147
|
|
|
148
|
-
void heapAllocatorViaIndCall(
|
|
148
|
+
void heapAllocatorViaIndCall(const CallICFGNode* cs);
|
|
149
149
|
|
|
150
150
|
private:
|
|
151
151
|
CallSite2DummyValPN callsite2DummyValPN; ///< Map an instruction to a dummy obj which created at an indirect callsite, which invokes a heap allocator
|
package/svf/include/Graphs/CHG.h
CHANGED
|
@@ -57,11 +57,11 @@ public:
|
|
|
57
57
|
DI
|
|
58
58
|
};
|
|
59
59
|
|
|
60
|
-
virtual bool csHasVFnsBasedonCHA(
|
|
61
|
-
virtual const VFunSet &getCSVFsBasedonCHA(
|
|
62
|
-
virtual bool csHasVtblsBasedonCHA(
|
|
63
|
-
virtual const VTableSet &getCSVtblsBasedonCHA(
|
|
64
|
-
virtual void getVFnsFromVtbls(
|
|
60
|
+
virtual bool csHasVFnsBasedonCHA(const CallICFGNode* cs) = 0;
|
|
61
|
+
virtual const VFunSet &getCSVFsBasedonCHA(const CallICFGNode* cs) = 0;
|
|
62
|
+
virtual bool csHasVtblsBasedonCHA(const CallICFGNode* cs) = 0;
|
|
63
|
+
virtual const VTableSet &getCSVtblsBasedonCHA(const CallICFGNode* cs) = 0;
|
|
64
|
+
virtual void getVFnsFromVtbls(const SVFCallInst* cs, const VTableSet& vtbls,
|
|
65
65
|
VFunSet& virtualFunctions) = 0;
|
|
66
66
|
|
|
67
67
|
CHGKind getKind(void) const
|
|
@@ -222,9 +222,9 @@ public:
|
|
|
222
222
|
typedef Set<const CHNode*> CHNodeSetTy;
|
|
223
223
|
typedef FIFOWorkList<const CHNode*> WorkList;
|
|
224
224
|
typedef Map<std::string, CHNodeSetTy> NameToCHNodesMap;
|
|
225
|
-
typedef Map<
|
|
226
|
-
typedef Map<
|
|
227
|
-
typedef Map<
|
|
225
|
+
typedef Map<const SVFInstruction*, CHNodeSetTy> CallSiteToCHNodesMap;
|
|
226
|
+
typedef Map<const SVFInstruction*, VTableSet> CallSiteToVTableSetMap;
|
|
227
|
+
typedef Map<const SVFInstruction*, VFunSet> CallSiteToVFunSetMap;
|
|
228
228
|
|
|
229
229
|
typedef enum
|
|
230
230
|
{
|
|
@@ -242,7 +242,7 @@ public:
|
|
|
242
242
|
const std::string baseClassName,
|
|
243
243
|
CHEdge::CHEDGETYPE edgeType);
|
|
244
244
|
CHNode *getNode(const std::string name) const;
|
|
245
|
-
void getVFnsFromVtbls(
|
|
245
|
+
void getVFnsFromVtbls(const SVFCallInst* cs, const VTableSet &vtbls, VFunSet &virtualFunctions) override;
|
|
246
246
|
void dump(const std::string& filename);
|
|
247
247
|
void view();
|
|
248
248
|
void printCH();
|
|
@@ -286,28 +286,10 @@ public:
|
|
|
286
286
|
return templateNameToInstancesMap[className];
|
|
287
287
|
}
|
|
288
288
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
294
|
-
inline bool csHasVFnsBasedonCHA(CallSite cs) override
|
|
295
|
-
{
|
|
296
|
-
CallSiteToVFunSetMap::const_iterator it = csToCHAVFnsMap.find(cs);
|
|
297
|
-
return it != csToCHAVFnsMap.end();
|
|
298
|
-
}
|
|
299
|
-
inline const VTableSet &getCSVtblsBasedonCHA(CallSite cs) override
|
|
300
|
-
{
|
|
301
|
-
CallSiteToVTableSetMap::const_iterator it = csToCHAVtblsMap.find(cs);
|
|
302
|
-
assert(it != csToCHAVtblsMap.end() && "cs does not have vtabls based on CHA.");
|
|
303
|
-
return it->second;
|
|
304
|
-
}
|
|
305
|
-
inline const VFunSet &getCSVFsBasedonCHA(CallSite cs) override
|
|
306
|
-
{
|
|
307
|
-
CallSiteToVFunSetMap::const_iterator it = csToCHAVFnsMap.find(cs);
|
|
308
|
-
assert(it != csToCHAVFnsMap.end() && "cs does not have vfns based on CHA.");
|
|
309
|
-
return it->second;
|
|
310
|
-
}
|
|
289
|
+
bool csHasVtblsBasedonCHA(const CallICFGNode* cs) override;
|
|
290
|
+
bool csHasVFnsBasedonCHA(const CallICFGNode* cs) override;
|
|
291
|
+
const VTableSet &getCSVtblsBasedonCHA(const CallICFGNode* cs) override;
|
|
292
|
+
const VFunSet &getCSVFsBasedonCHA(const CallICFGNode* cs) override;
|
|
311
293
|
|
|
312
294
|
static inline bool classof(const CommonCHGraph *chg)
|
|
313
295
|
{
|
|
@@ -156,8 +156,8 @@ protected:
|
|
|
156
156
|
//@{
|
|
157
157
|
ICFGEdge* addIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode);
|
|
158
158
|
ICFGEdge* addConditionalIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFValue* condition, s32_t branchCondVal);
|
|
159
|
-
ICFGEdge* addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode
|
|
160
|
-
ICFGEdge* addRetEdge(ICFGNode* srcNode, ICFGNode* dstNode
|
|
159
|
+
ICFGEdge* addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode);
|
|
160
|
+
ICFGEdge* addRetEdge(ICFGNode* srcNode, ICFGNode* dstNode);
|
|
161
161
|
//@}
|
|
162
162
|
/// Remove a ICFG edge
|
|
163
163
|
inline void removeICFGEdge(ICFGEdge* edge)
|
|
@@ -179,20 +179,14 @@ class CallCFGEdge : public ICFGEdge
|
|
|
179
179
|
friend class SVFIRReader;
|
|
180
180
|
|
|
181
181
|
private:
|
|
182
|
-
const SVFInstruction* cs;
|
|
183
182
|
std::vector<const CallPE*> callPEs;
|
|
184
183
|
|
|
185
184
|
public:
|
|
186
185
|
/// Constructor
|
|
187
|
-
CallCFGEdge(ICFGNode* s, ICFGNode* d
|
|
188
|
-
: ICFGEdge(s, d, CallCF)
|
|
186
|
+
CallCFGEdge(ICFGNode* s, ICFGNode* d)
|
|
187
|
+
: ICFGEdge(s, d, CallCF)
|
|
189
188
|
{
|
|
190
189
|
}
|
|
191
|
-
/// Return callsite ID
|
|
192
|
-
inline const SVFInstruction* getCallSite() const
|
|
193
|
-
{
|
|
194
|
-
return cs;
|
|
195
|
-
}
|
|
196
190
|
/// Add call parameter edge to this CallCFGEdge
|
|
197
191
|
inline void addCallPE(const CallPE* callPE)
|
|
198
192
|
{
|
|
@@ -230,19 +224,13 @@ class RetCFGEdge : public ICFGEdge
|
|
|
230
224
|
friend class SVFIRReader;
|
|
231
225
|
|
|
232
226
|
private:
|
|
233
|
-
const SVFInstruction* cs;
|
|
234
227
|
const RetPE* retPE;
|
|
235
228
|
|
|
236
229
|
public:
|
|
237
230
|
/// Constructor
|
|
238
|
-
RetCFGEdge(ICFGNode* s, ICFGNode* d
|
|
239
|
-
: ICFGEdge(s, d, RetCF),
|
|
240
|
-
{
|
|
241
|
-
}
|
|
242
|
-
/// Return callsite ID
|
|
243
|
-
inline const SVFInstruction* getCallSite() const
|
|
231
|
+
RetCFGEdge(ICFGNode* s, ICFGNode* d)
|
|
232
|
+
: ICFGEdge(s, d, RetCF), retPE(nullptr)
|
|
244
233
|
{
|
|
245
|
-
return cs;
|
|
246
234
|
}
|
|
247
235
|
/// Add call parameter edge to this CallCFGEdge
|
|
248
236
|
inline void addRetPE(const RetPE* ret)
|
|
@@ -476,6 +476,64 @@ public:
|
|
|
476
476
|
{
|
|
477
477
|
APNodes.push_back(ap);
|
|
478
478
|
}
|
|
479
|
+
/// Parameter operations
|
|
480
|
+
//@{
|
|
481
|
+
const SVFValue* getArgument(u32_t ArgNo) const
|
|
482
|
+
{
|
|
483
|
+
return SVFUtil::cast<SVFCallInst>(cs)->getArgOperand(ArgNo);
|
|
484
|
+
}
|
|
485
|
+
const SVFType* getType() const
|
|
486
|
+
{
|
|
487
|
+
return SVFUtil::cast<SVFCallInst>(cs)->getType();
|
|
488
|
+
}
|
|
489
|
+
u32_t arg_size() const
|
|
490
|
+
{
|
|
491
|
+
return SVFUtil::cast<SVFCallInst>(cs)->arg_size();
|
|
492
|
+
}
|
|
493
|
+
bool arg_empty() const
|
|
494
|
+
{
|
|
495
|
+
return SVFUtil::cast<SVFCallInst>(cs)->arg_empty();
|
|
496
|
+
}
|
|
497
|
+
const SVFValue* getArgOperand(u32_t i) const
|
|
498
|
+
{
|
|
499
|
+
return SVFUtil::cast<SVFCallInst>(cs)->getArgOperand(i);
|
|
500
|
+
}
|
|
501
|
+
u32_t getNumArgOperands() const
|
|
502
|
+
{
|
|
503
|
+
return SVFUtil::cast<SVFCallInst>(cs)->arg_size();
|
|
504
|
+
}
|
|
505
|
+
const SVFFunction* getCalledFunction() const
|
|
506
|
+
{
|
|
507
|
+
return SVFUtil::cast<SVFCallInst>(cs)->getCalledFunction();
|
|
508
|
+
}
|
|
509
|
+
const SVFValue* getCalledValue() const
|
|
510
|
+
{
|
|
511
|
+
return SVFUtil::cast<SVFCallInst>(cs)->getCalledOperand();
|
|
512
|
+
}
|
|
513
|
+
bool isVarArg() const
|
|
514
|
+
{
|
|
515
|
+
return SVFUtil::cast<SVFCallInst>(cs)->isVarArg();
|
|
516
|
+
}
|
|
517
|
+
bool isVirtualCall() const
|
|
518
|
+
{
|
|
519
|
+
return SVFUtil::isa<SVFVirtualCallInst>(cs);
|
|
520
|
+
}
|
|
521
|
+
const SVFValue* getVtablePtr() const
|
|
522
|
+
{
|
|
523
|
+
assert(isVirtualCall() && "not a virtual call?");
|
|
524
|
+
return SVFUtil::cast<SVFVirtualCallInst>(cs)->getVtablePtr();
|
|
525
|
+
}
|
|
526
|
+
s32_t getFunIdxInVtable() const
|
|
527
|
+
{
|
|
528
|
+
assert(isVirtualCall() && "not a virtual call?");
|
|
529
|
+
return SVFUtil::cast<SVFVirtualCallInst>(cs)->getFunIdxInVtable();
|
|
530
|
+
}
|
|
531
|
+
const std::string& getFunNameOfVirtualCall() const
|
|
532
|
+
{
|
|
533
|
+
assert(isVirtualCall() && "not a virtual call?");
|
|
534
|
+
return SVFUtil::cast<SVFVirtualCallInst>(cs)->getFunNameOfVirtualCall();
|
|
535
|
+
}
|
|
536
|
+
//@}
|
|
479
537
|
|
|
480
538
|
///Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
481
539
|
//@{
|
|
@@ -72,9 +72,9 @@ public:
|
|
|
72
72
|
std::string str;
|
|
73
73
|
std::stringstream rawstr(str);
|
|
74
74
|
rawstr << "ThreadForkEdge ";
|
|
75
|
-
rawstr << "
|
|
76
|
-
rawstr << "
|
|
77
|
-
rawstr << "
|
|
75
|
+
rawstr << "CallSiteID: " << getCallSiteID();
|
|
76
|
+
rawstr << " srcNodeID " << getSrcID() << " (fun: " << getSrcNode()->getFunction()->getName() << ")";
|
|
77
|
+
rawstr << " dstNodeID " << getDstID() << " (fun: " << getDstNode()->getFunction()->getName() << ")";
|
|
78
78
|
return rawstr.str();
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -112,9 +112,9 @@ public:
|
|
|
112
112
|
std::string str;
|
|
113
113
|
std::stringstream rawstr(str);
|
|
114
114
|
rawstr << "ThreadJoinEdge ";
|
|
115
|
-
rawstr << "
|
|
116
|
-
rawstr << "
|
|
117
|
-
rawstr << "
|
|
115
|
+
rawstr << "CallSiteID: " << getCallSiteID();
|
|
116
|
+
rawstr << " srcNodeID " << getSrcID() << " (fun: " << getSrcNode()->getFunction()->getName() << ")";
|
|
117
|
+
rawstr << " dstNodeID " << getDstID() << " (fun: " << getDstNode()->getFunction()->getName() << ")";
|
|
118
118
|
return rawstr.str();
|
|
119
119
|
}
|
|
120
120
|
|
package/svf/include/MTA/MHP.h
CHANGED
|
@@ -377,7 +377,7 @@ private:
|
|
|
377
377
|
bool sameLoopTripCount(const ICFGNode* forkSite, const ICFGNode* joinSite);
|
|
378
378
|
|
|
379
379
|
/// Whether it is a matched fork join pair
|
|
380
|
-
bool isAliasedForkJoin(const
|
|
380
|
+
bool isAliasedForkJoin(const CallICFGNode* forkSite, const CallICFGNode* joinSite)
|
|
381
381
|
{
|
|
382
382
|
return tct->getPTA()->alias(getForkedThread(forkSite), getJoinedThread(joinSite)) && isSameSCEV(forkSite,joinSite);
|
|
383
383
|
}
|
|
@@ -469,12 +469,12 @@ private:
|
|
|
469
469
|
return getTCG()->getThreadAPI()->isTDJoin(call);
|
|
470
470
|
}
|
|
471
471
|
/// Get forked thread
|
|
472
|
-
inline const SVFValue* getForkedThread(const
|
|
472
|
+
inline const SVFValue* getForkedThread(const CallICFGNode* call)
|
|
473
473
|
{
|
|
474
474
|
return getTCG()->getThreadAPI()->getForkedThread(call);
|
|
475
475
|
}
|
|
476
476
|
/// Get joined thread
|
|
477
|
-
inline const SVFValue* getJoinedThread(const
|
|
477
|
+
inline const SVFValue* getJoinedThread(const CallICFGNode* call)
|
|
478
478
|
{
|
|
479
479
|
return getTCG()->getThreadAPI()->getJoinedThread(call);
|
|
480
480
|
}
|
package/svf/include/MTA/TCT.h
CHANGED
|
@@ -246,7 +246,7 @@ public:
|
|
|
246
246
|
inline bool isExtCall(const ICFGNode* inst)
|
|
247
247
|
{
|
|
248
248
|
if(const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(inst))
|
|
249
|
-
return SVFUtil::isExtCall(call
|
|
249
|
+
return SVFUtil::isExtCall(call);
|
|
250
250
|
return false;
|
|
251
251
|
}
|
|
252
252
|
/// Whether it is a callsite
|
|
@@ -421,7 +421,6 @@ private:
|
|
|
421
421
|
cJSON* toJson(const CHNode* node); // CHGraph Node
|
|
422
422
|
cJSON* toJson(const CHEdge* edge); // CHGraph Edge
|
|
423
423
|
|
|
424
|
-
cJSON* toJson(const CallSite& cs);
|
|
425
424
|
cJSON* toJson(const AccessPath& ap);
|
|
426
425
|
cJSON* toJson(const SVFLoop* loop);
|
|
427
426
|
cJSON* toJson(const MemObj* memObj);
|
|
@@ -1104,7 +1103,6 @@ private:
|
|
|
1104
1103
|
void readJson(const cJSON* obj, ICFGEdge*& edge); // ICFG Edge
|
|
1105
1104
|
void readJson(const cJSON* obj, CHNode*& node); // CHGraph Node
|
|
1106
1105
|
void readJson(const cJSON* obj, CHEdge*& edge); // CHGraph Edge
|
|
1107
|
-
void readJson(const cJSON* obj, CallSite& cs); // CHGraph's csToClassMap
|
|
1108
1106
|
|
|
1109
1107
|
void readJson(const cJSON* obj, AccessPath& ap);
|
|
1110
1108
|
void readJson(const cJSON* obj, SVFLoop*& loop);
|
|
@@ -637,15 +637,11 @@ class SVFInstruction : public SVFValue
|
|
|
637
637
|
{
|
|
638
638
|
friend class SVFIRWriter;
|
|
639
639
|
friend class SVFIRReader;
|
|
640
|
-
public:
|
|
641
|
-
typedef std::vector<const SVFInstruction*> InstVec;
|
|
642
640
|
|
|
643
641
|
private:
|
|
644
642
|
const SVFBasicBlock* bb; /// The BasicBlock where this Instruction resides
|
|
645
643
|
bool terminator; /// return true if this is a terminator instruction
|
|
646
644
|
bool ret; /// return true if this is an return instruction of a function
|
|
647
|
-
InstVec succInsts; /// successor Instructions
|
|
648
|
-
InstVec predInsts; /// predecessor Instructions
|
|
649
645
|
|
|
650
646
|
public:
|
|
651
647
|
/// Constructor without name, set name with setName()
|
|
@@ -665,36 +661,11 @@ public:
|
|
|
665
661
|
return bb;
|
|
666
662
|
}
|
|
667
663
|
|
|
668
|
-
inline InstVec& getSuccInstructions()
|
|
669
|
-
{
|
|
670
|
-
return succInsts;
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
inline InstVec& getPredInstructions()
|
|
674
|
-
{
|
|
675
|
-
return predInsts;
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
inline const InstVec& getSuccInstructions() const
|
|
679
|
-
{
|
|
680
|
-
return succInsts;
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
inline const InstVec& getPredInstructions() const
|
|
684
|
-
{
|
|
685
|
-
return predInsts;
|
|
686
|
-
}
|
|
687
|
-
|
|
688
664
|
inline const SVFFunction* getFunction() const
|
|
689
665
|
{
|
|
690
666
|
return bb->getParent();
|
|
691
667
|
}
|
|
692
668
|
|
|
693
|
-
inline bool isTerminator() const
|
|
694
|
-
{
|
|
695
|
-
return terminator;
|
|
696
|
-
}
|
|
697
|
-
|
|
698
669
|
inline bool isRetInst() const
|
|
699
670
|
{
|
|
700
671
|
return ret;
|
|
@@ -1115,98 +1086,6 @@ public:
|
|
|
1115
1086
|
};
|
|
1116
1087
|
|
|
1117
1088
|
|
|
1118
|
-
class CallSite
|
|
1119
|
-
{
|
|
1120
|
-
friend class SVFIRReader;
|
|
1121
|
-
|
|
1122
|
-
private:
|
|
1123
|
-
const SVFCallInst* CB;
|
|
1124
|
-
|
|
1125
|
-
/// Constructs empty CallSite (for SVFIRReader/deserialization)
|
|
1126
|
-
CallSite() : CB{} {}
|
|
1127
|
-
|
|
1128
|
-
public:
|
|
1129
|
-
CallSite(const SVFInstruction* I) : CB(SVFUtil::dyn_cast<SVFCallInst>(I))
|
|
1130
|
-
{
|
|
1131
|
-
assert(CB && "not a callsite?");
|
|
1132
|
-
}
|
|
1133
|
-
const SVFInstruction* getInstruction() const
|
|
1134
|
-
{
|
|
1135
|
-
return CB;
|
|
1136
|
-
}
|
|
1137
|
-
const SVFValue* getArgument(u32_t ArgNo) const
|
|
1138
|
-
{
|
|
1139
|
-
return CB->getArgOperand(ArgNo);
|
|
1140
|
-
}
|
|
1141
|
-
const SVFType* getType() const
|
|
1142
|
-
{
|
|
1143
|
-
return CB->getType();
|
|
1144
|
-
}
|
|
1145
|
-
u32_t arg_size() const
|
|
1146
|
-
{
|
|
1147
|
-
return CB->arg_size();
|
|
1148
|
-
}
|
|
1149
|
-
bool arg_empty() const
|
|
1150
|
-
{
|
|
1151
|
-
return CB->arg_empty();
|
|
1152
|
-
}
|
|
1153
|
-
const SVFValue* getArgOperand(u32_t i) const
|
|
1154
|
-
{
|
|
1155
|
-
return CB->getArgOperand(i);
|
|
1156
|
-
}
|
|
1157
|
-
u32_t getNumArgOperands() const
|
|
1158
|
-
{
|
|
1159
|
-
return CB->arg_size();
|
|
1160
|
-
}
|
|
1161
|
-
const SVFFunction* getCalledFunction() const
|
|
1162
|
-
{
|
|
1163
|
-
return CB->getCalledFunction();
|
|
1164
|
-
}
|
|
1165
|
-
const SVFValue* getCalledValue() const
|
|
1166
|
-
{
|
|
1167
|
-
return CB->getCalledOperand();
|
|
1168
|
-
}
|
|
1169
|
-
const SVFFunction* getCaller() const
|
|
1170
|
-
{
|
|
1171
|
-
return CB->getCaller();
|
|
1172
|
-
}
|
|
1173
|
-
bool isVarArg() const
|
|
1174
|
-
{
|
|
1175
|
-
return CB->isVarArg();
|
|
1176
|
-
}
|
|
1177
|
-
bool isVirtualCall() const
|
|
1178
|
-
{
|
|
1179
|
-
return SVFUtil::isa<SVFVirtualCallInst>(CB);
|
|
1180
|
-
}
|
|
1181
|
-
const SVFValue* getVtablePtr() const
|
|
1182
|
-
{
|
|
1183
|
-
assert(isVirtualCall() && "not a virtual call?");
|
|
1184
|
-
return SVFUtil::cast<SVFVirtualCallInst>(CB)->getVtablePtr();
|
|
1185
|
-
}
|
|
1186
|
-
s32_t getFunIdxInVtable() const
|
|
1187
|
-
{
|
|
1188
|
-
assert(isVirtualCall() && "not a virtual call?");
|
|
1189
|
-
return SVFUtil::cast<SVFVirtualCallInst>(CB)->getFunIdxInVtable();
|
|
1190
|
-
}
|
|
1191
|
-
const std::string& getFunNameOfVirtualCall() const
|
|
1192
|
-
{
|
|
1193
|
-
assert(isVirtualCall() && "not a virtual call?");
|
|
1194
|
-
return SVFUtil::cast<SVFVirtualCallInst>(CB)->getFunNameOfVirtualCall();
|
|
1195
|
-
}
|
|
1196
|
-
bool operator==(const CallSite& CS) const
|
|
1197
|
-
{
|
|
1198
|
-
return CB == CS.CB;
|
|
1199
|
-
}
|
|
1200
|
-
bool operator!=(const CallSite& CS) const
|
|
1201
|
-
{
|
|
1202
|
-
return CB != CS.CB;
|
|
1203
|
-
}
|
|
1204
|
-
bool operator<(const CallSite& CS) const
|
|
1205
|
-
{
|
|
1206
|
-
return getInstruction() < CS.getInstruction();
|
|
1207
|
-
}
|
|
1208
|
-
};
|
|
1209
|
-
|
|
1210
1089
|
/// [FOR DEBUG ONLY, DON'T USE IT UNSIDE `svf`!]
|
|
1211
1090
|
/// Converts an SVFValue to corresponding LLVM::Value, then get the string
|
|
1212
1091
|
/// representation of it. Use it only when you are debugging. Don't use
|
|
@@ -1222,14 +1101,4 @@ OutStream& operator<< (OutStream &o, const std::pair<F, S> &var)
|
|
|
1222
1101
|
|
|
1223
1102
|
} // End namespace SVF
|
|
1224
1103
|
|
|
1225
|
-
/// Specialise hash for CallSites.
|
|
1226
|
-
template <> struct std::hash<SVF::CallSite>
|
|
1227
|
-
{
|
|
1228
|
-
size_t operator()(const SVF::CallSite &cs) const
|
|
1229
|
-
{
|
|
1230
|
-
std::hash<const SVF::SVFInstruction *> h;
|
|
1231
|
-
return h(cs.getInstruction());
|
|
1232
|
-
}
|
|
1233
|
-
};
|
|
1234
|
-
|
|
1235
1104
|
#endif /* INCLUDE_SVFIR_SVFVALUE_H_ */
|
|
@@ -200,11 +200,6 @@ inline bool isNonInstricCallSite(const ICFGNode* inst)
|
|
|
200
200
|
return isCallSite(inst);
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
|
|
204
|
-
/// Return callsite given an instruction
|
|
205
|
-
CallSite getSVFCallSite(const ICFGNode* inst);
|
|
206
|
-
|
|
207
|
-
|
|
208
203
|
/// Match arguments for callsite at caller and callee
|
|
209
204
|
/// if the arg size does not match then we do not need to connect this parameter
|
|
210
205
|
/// unless the callee is a variadic function (the first parameter of variadic function is its parameter number)
|
|
@@ -235,19 +230,20 @@ inline std::vector<std::string> split(const std::string& s, char separator)
|
|
|
235
230
|
|
|
236
231
|
/// Return callee of a callsite. Return null if this is an indirect call
|
|
237
232
|
//@{
|
|
238
|
-
inline const SVFFunction* getCallee(const
|
|
233
|
+
inline const SVFFunction* getCallee(const SVFCallInst* cs)
|
|
239
234
|
{
|
|
240
|
-
return cs
|
|
235
|
+
return cs->getCalledFunction();
|
|
241
236
|
}
|
|
242
237
|
|
|
243
238
|
inline const SVFFunction* getCallee(const SVFInstruction *inst)
|
|
244
239
|
{
|
|
245
240
|
if (!isCallSite(inst))
|
|
246
241
|
return nullptr;
|
|
247
|
-
|
|
248
|
-
return getCallee(cs);
|
|
242
|
+
return getCallee(cast<SVFCallInst>(inst));
|
|
249
243
|
}
|
|
250
244
|
|
|
245
|
+
const SVFFunction* getCallee(const CallICFGNode *inst);
|
|
246
|
+
|
|
251
247
|
const SVFFunction* getCallee(const ICFGNode *inst);
|
|
252
248
|
//@}
|
|
253
249
|
|
|
@@ -401,47 +397,37 @@ inline bool isArgOfUncalledFunction(const SVFValue* svfval)
|
|
|
401
397
|
|
|
402
398
|
/// Return thread fork function
|
|
403
399
|
//@{
|
|
404
|
-
inline const SVFValue* getForkedFun(const
|
|
400
|
+
inline const SVFValue* getForkedFun(const CallICFGNode *inst)
|
|
405
401
|
{
|
|
406
402
|
return ThreadAPI::getThreadAPI()->getForkedFun(inst);
|
|
407
403
|
}
|
|
408
404
|
//@}
|
|
409
405
|
|
|
410
406
|
|
|
411
|
-
inline bool isExtCall(const
|
|
407
|
+
inline bool isExtCall(const CallICFGNode* cs)
|
|
412
408
|
{
|
|
413
409
|
return isExtCall(getCallee(cs));
|
|
414
410
|
}
|
|
415
411
|
|
|
416
412
|
bool isExtCall(const ICFGNode* node);
|
|
417
413
|
|
|
418
|
-
inline bool
|
|
419
|
-
{
|
|
420
|
-
return isExtCall(getCallee(inst));
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
inline bool isHeapAllocExtCallViaArg(const CallSite cs)
|
|
414
|
+
inline bool isHeapAllocExtCallViaArg(const CallICFGNode* cs)
|
|
424
415
|
{
|
|
425
416
|
return isHeapAllocExtFunViaArg(getCallee(cs));
|
|
426
417
|
}
|
|
427
418
|
|
|
428
419
|
inline bool isHeapAllocExtCallViaArg(const SVFInstruction *inst)
|
|
429
420
|
{
|
|
430
|
-
|
|
421
|
+
if(const SVFCallInst* call = SVFUtil::dyn_cast<SVFCallInst>(inst))
|
|
422
|
+
return isHeapAllocExtFunViaArg(call->getCalledFunction());
|
|
423
|
+
else
|
|
424
|
+
return false;
|
|
431
425
|
}
|
|
432
426
|
|
|
433
|
-
|
|
434
|
-
inline bool isHeapAllocExtCallViaRet(const CallSite cs)
|
|
435
|
-
{
|
|
436
|
-
bool isPtrTy = cs.getInstruction()->getType()->isPointerTy();
|
|
437
|
-
return isPtrTy && isHeapAllocExtFunViaRet(getCallee(cs));
|
|
438
|
-
}
|
|
427
|
+
bool isHeapAllocExtCallViaRet(const SVFInstruction *inst);
|
|
439
428
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
bool isPtrTy = inst->getType()->isPointerTy();
|
|
443
|
-
return isPtrTy && isHeapAllocExtFunViaRet(getCallee(inst));
|
|
444
|
-
}
|
|
429
|
+
/// interfaces to be used externally
|
|
430
|
+
bool isHeapAllocExtCallViaRet(const CallICFGNode* cs);
|
|
445
431
|
|
|
446
432
|
bool isHeapAllocExtCall(const ICFGNode* cs);
|
|
447
433
|
|
|
@@ -449,19 +435,16 @@ inline bool isHeapAllocExtCall(const SVFInstruction *inst)
|
|
|
449
435
|
{
|
|
450
436
|
return isHeapAllocExtCallViaRet(inst) || isHeapAllocExtCallViaArg(inst);
|
|
451
437
|
}
|
|
438
|
+
|
|
452
439
|
//@}
|
|
453
440
|
|
|
454
|
-
inline int getHeapAllocHoldingArgPosition(const
|
|
441
|
+
inline int getHeapAllocHoldingArgPosition(const CallICFGNode* cs)
|
|
455
442
|
{
|
|
456
443
|
return getHeapAllocHoldingArgPosition(getCallee(cs));
|
|
457
444
|
}
|
|
458
445
|
//@}
|
|
459
446
|
|
|
460
|
-
|
|
461
|
-
{
|
|
462
|
-
bool isPtrTy = cs.getInstruction()->getType()->isPointerTy();
|
|
463
|
-
return isPtrTy && isReallocExtFun(getCallee(cs));
|
|
464
|
-
}
|
|
447
|
+
bool isReallocExtCall(const CallICFGNode* cs);
|
|
465
448
|
//@}
|
|
466
449
|
|
|
467
450
|
/// Return true if this is a thread creation call
|
|
@@ -514,14 +497,14 @@ inline bool isBarrierWaitCall(const ICFGNode* cs)
|
|
|
514
497
|
|
|
515
498
|
/// Return sole argument of the thread routine
|
|
516
499
|
//@{
|
|
517
|
-
inline const SVFValue* getActualParmAtForkSite(const
|
|
500
|
+
inline const SVFValue* getActualParmAtForkSite(const CallICFGNode* cs)
|
|
518
501
|
{
|
|
519
502
|
return ThreadAPI::getThreadAPI()->getActualParmAtForkSite(cs);
|
|
520
503
|
}
|
|
521
504
|
//@}
|
|
522
505
|
|
|
523
506
|
|
|
524
|
-
inline bool isProgExitCall(const
|
|
507
|
+
inline bool isProgExitCall(const CallICFGNode* cs)
|
|
525
508
|
{
|
|
526
509
|
return isProgExitFunction(getCallee(cs));
|
|
527
510
|
}
|
|
@@ -122,7 +122,6 @@ public:
|
|
|
122
122
|
/// Return the callee/callsite/func
|
|
123
123
|
//@{
|
|
124
124
|
const SVFFunction* getCallee(const ICFGNode *inst) const;
|
|
125
|
-
const CallSite getSVFCallSite(const ICFGNode *inst) const;
|
|
126
125
|
//@}
|
|
127
126
|
|
|
128
127
|
/// Return true if this call create a new thread
|
|
@@ -137,29 +136,14 @@ public:
|
|
|
137
136
|
//@{
|
|
138
137
|
/// Return the first argument of the call,
|
|
139
138
|
/// Note that, it is the pthread_t pointer
|
|
140
|
-
|
|
141
|
-
{
|
|
142
|
-
assert(isTDFork(inst) && "not a thread fork function!");
|
|
143
|
-
CallSite cs = getSVFCallSite(inst);
|
|
144
|
-
return cs.getArgument(0);
|
|
145
|
-
}
|
|
139
|
+
const SVFValue* getForkedThread(const CallICFGNode *inst) const;
|
|
146
140
|
/// Return the third argument of the call,
|
|
147
141
|
/// Note that, it could be function type or a void* pointer
|
|
148
|
-
|
|
149
|
-
{
|
|
150
|
-
assert(isTDFork(inst) && "not a thread fork function!");
|
|
151
|
-
CallSite cs = getSVFCallSite(inst);
|
|
152
|
-
return cs.getArgument(2);
|
|
153
|
-
}
|
|
142
|
+
const SVFValue* getForkedFun(const CallICFGNode *inst) const;
|
|
154
143
|
|
|
155
144
|
/// Return the forth argument of the call,
|
|
156
145
|
/// Note that, it is the sole argument of start routine ( a void* pointer )
|
|
157
|
-
|
|
158
|
-
{
|
|
159
|
-
assert(isTDFork(inst) && "not a thread fork function!");
|
|
160
|
-
CallSite cs = getSVFCallSite(inst);
|
|
161
|
-
return cs.getArgument(3);
|
|
162
|
-
}
|
|
146
|
+
const SVFValue* getActualParmAtForkSite(const CallICFGNode *inst) const;
|
|
163
147
|
//@}
|
|
164
148
|
|
|
165
149
|
/// Return true if this call wait for a worker thread
|
|
@@ -174,15 +158,10 @@ public:
|
|
|
174
158
|
//@{
|
|
175
159
|
/// Return the first argument of the call,
|
|
176
160
|
/// Note that, it is the pthread_t pointer
|
|
177
|
-
const SVFValue* getJoinedThread(const
|
|
161
|
+
const SVFValue* getJoinedThread(const CallICFGNode *inst) const;
|
|
178
162
|
/// Return the send argument of the call,
|
|
179
163
|
/// Note that, it is the pthread_t pointer
|
|
180
|
-
|
|
181
|
-
{
|
|
182
|
-
assert(isTDJoin(inst) && "not a thread join function!");
|
|
183
|
-
CallSite cs = getSVFCallSite(inst);
|
|
184
|
-
return cs.getArgument(1);
|
|
185
|
-
}
|
|
164
|
+
const SVFValue* getRetParmAtJoinedSite(const CallICFGNode *inst) const;
|
|
186
165
|
//@}
|
|
187
166
|
|
|
188
167
|
|