svf-lib 1.0.1276 → 1.0.1278
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/SVF-linux/Release-build/lib/libSvf.a +0 -0
- package/SVF-linux/include/Graphs/ConsGNode.h +48 -24
- package/SVF-linux/include/Graphs/GenericGraph.h +4 -2
- package/SVF-linux/include/Graphs/ICFG.h +3 -2
- package/SVF-linux/include/Graphs/SVFGOPT.h +7 -7
- package/SVF-linux/include/Graphs/VFG.h +3 -2
- package/SVF-linux/include/MSSA/MemSSA.h +6 -6
- package/SVF-linux/include/MemoryModel/PersistentPointsToDS.h +1 -1
- package/SVF-linux/include/MemoryModel/SVFIR.h +3 -1
- package/SVF-linux/include/SABER/SaberCondAllocator.h +7 -2
- package/SVF-linux/include/SVF-FE/IRAnnotator.h +3 -1
- package/SVF-linux/include/Util/SparseBitVector.h +2 -0
- package/SVF-osx/Release-build/lib/libSvf.a +0 -0
- package/SVF-osx/include/DDA/DDAVFSolver.h +1 -2
- package/SVF-osx/include/Graphs/ICFG.h +16 -16
- package/SVF-osx/include/Graphs/ICFGEdge.h +6 -6
- package/SVF-osx/include/Graphs/ICFGNode.h +16 -16
- package/SVF-osx/include/Graphs/IRGraph.h +6 -6
- package/SVF-osx/include/Graphs/ThreadCallGraph.h +2 -2
- package/SVF-osx/include/Graphs/VFGNode.h +1 -1
- package/SVF-osx/include/MSSA/MSSAMuChi.h +11 -11
- package/SVF-osx/include/MSSA/MemRegion.h +2 -2
- package/SVF-osx/include/MSSA/MemSSA.h +13 -13
- package/SVF-osx/include/MTA/FSMPTA.h +1 -1
- package/SVF-osx/include/MTA/LockAnalysis.h +33 -33
- package/SVF-osx/include/MTA/LockResultValidator.h +7 -6
- package/SVF-osx/include/MTA/MHP.h +46 -46
- package/SVF-osx/include/MTA/MTA.h +4 -4
- package/SVF-osx/include/MTA/MTAAnnotator.h +6 -4
- package/SVF-osx/include/MTA/MTAResultValidator.h +51 -44
- package/SVF-osx/include/MTA/PCG.h +22 -27
- package/SVF-osx/include/MTA/TCT.h +28 -37
- package/SVF-osx/include/MemoryModel/SVFStatements.h +11 -6
- package/SVF-osx/include/MemoryModel/SVFVariables.h +4 -4
- package/SVF-osx/include/MemoryModel/SymbolTableInfo.h +13 -19
- package/SVF-osx/include/SABER/ProgSlice.h +5 -5
- package/SVF-osx/include/SABER/SaberCheckerAPI.h +4 -4
- package/SVF-osx/include/SABER/SaberCondAllocator.h +32 -35
- package/SVF-osx/include/SVF-FE/BasicTypes.h +10 -0
- package/SVF-osx/include/SVF-FE/CPPUtil.h +9 -8
- package/SVF-osx/include/SVF-FE/DCHG.h +4 -4
- package/SVF-osx/include/SVF-FE/DataFlowUtil.h +1 -1
- package/SVF-osx/include/SVF-FE/GEPTypeBridgeIterator.h +1 -1
- package/SVF-osx/include/SVF-FE/ICFGBuilder.h +9 -9
- package/SVF-osx/include/SVF-FE/IRAnnotator.h +9 -9
- package/SVF-osx/include/SVF-FE/LLVMModule.h +119 -22
- package/SVF-osx/include/SVF-FE/LLVMUtil.h +31 -52
- package/SVF-osx/include/SVF-FE/SVFIRBuilder.h +14 -20
- package/SVF-osx/include/SVF-FE/SymbolTableBuilder.h +8 -8
- package/SVF-osx/include/Util/Annotator.h +22 -22
- package/SVF-osx/include/Util/BasicTypes.h +476 -72
- package/SVF-osx/include/Util/Casting.h +1 -1
- package/SVF-osx/include/Util/CxtStmt.h +13 -12
- package/SVF-osx/include/Util/SVFBasicTypes.h +0 -78
- package/SVF-osx/include/Util/SVFInstruction.h +40 -0
- package/SVF-osx/include/Util/SVFModule.h +58 -124
- package/SVF-osx/include/Util/SVFUtil.h +48 -39
- package/SVF-osx/include/Util/ThreadAPI.h +17 -28
- package/SVF-osx/include/WPA/WPAPass.h +4 -4
- package/package.json +1 -1
|
@@ -47,17 +47,17 @@ class MHP
|
|
|
47
47
|
{
|
|
48
48
|
|
|
49
49
|
public:
|
|
50
|
-
typedef Set<const
|
|
51
|
-
typedef Set<const
|
|
50
|
+
typedef Set<const SVFFunction*> FunSet;
|
|
51
|
+
typedef Set<const SVFInstruction*> InstSet;
|
|
52
52
|
typedef TCT::InstVec InstVec;
|
|
53
53
|
typedef FIFOWorkList<CxtThreadStmt> CxtThreadStmtWorkList;
|
|
54
54
|
typedef Set<CxtThreadStmt> CxtThreadStmtSet;
|
|
55
55
|
typedef Map<CxtThreadStmt,NodeBS> ThreadStmtToThreadInterleav;
|
|
56
|
-
typedef Map<const
|
|
56
|
+
typedef Map<const SVFInstruction*,CxtThreadStmtSet> InstToThreadStmtSetMap;
|
|
57
57
|
|
|
58
58
|
typedef Set<CxtStmt> LockSpan;
|
|
59
59
|
|
|
60
|
-
typedef std::pair<const
|
|
60
|
+
typedef std::pair<const SVFFunction*,const SVFFunction*> FuncPair;
|
|
61
61
|
typedef Map<FuncPair, bool> FuncPairToBool;
|
|
62
62
|
|
|
63
63
|
/// Constructor
|
|
@@ -85,29 +85,29 @@ public:
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
// Get CallICFGNode
|
|
88
|
-
inline CallICFGNode* getCBN(const
|
|
88
|
+
inline CallICFGNode* getCBN(const SVFInstruction* inst)
|
|
89
89
|
{
|
|
90
90
|
return tct->getCallICFGNode(inst);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
/// Whether the function is connected from main function in thread call graph
|
|
94
|
-
bool isConnectedfromMain(const
|
|
94
|
+
bool isConnectedfromMain(const SVFFunction* fun);
|
|
95
95
|
|
|
96
96
|
// /// Interface to query whether two instructions are protected by common locks
|
|
97
|
-
// virtual bool isProtectedByACommonLock(const
|
|
98
|
-
// virtual bool isAllCxtInSameLockSpan(const
|
|
99
|
-
// virtual bool isOneCxtInSameLockSpan(const
|
|
97
|
+
// virtual bool isProtectedByACommonLock(const SVFInstruction* i1, const SVFInstruction* i2);
|
|
98
|
+
// virtual bool isAllCxtInSameLockSpan(const SVFInstruction *I1, const SVFInstruction *I2);
|
|
99
|
+
// virtual bool isOneCxtInSameLockSpan(const SVFInstruction *I1, const SVFInstruction *I2);
|
|
100
100
|
//
|
|
101
|
-
// bool hasOneCxtInLockSpan(const
|
|
102
|
-
// bool hasAllCxtInLockSpan(const
|
|
101
|
+
// bool hasOneCxtInLockSpan(const SVFInstruction *I, LockSpan lspan);
|
|
102
|
+
// bool hasAllCxtInLockSpan(const SVFInstruction *I, LockSpan lspan);
|
|
103
103
|
//
|
|
104
104
|
//
|
|
105
105
|
// LockSpan getSpanfromCxtLock(NodeID l);
|
|
106
106
|
/// Interface to query whether two instructions may happen-in-parallel
|
|
107
|
-
virtual bool mayHappenInParallel(const
|
|
108
|
-
virtual bool mayHappenInParallelCache(const
|
|
109
|
-
virtual bool mayHappenInParallelInst(const
|
|
110
|
-
virtual bool executedByTheSameThread(const
|
|
107
|
+
virtual bool mayHappenInParallel(const SVFInstruction* i1, const SVFInstruction* i2);
|
|
108
|
+
virtual bool mayHappenInParallelCache(const SVFInstruction* i1, const SVFInstruction* i2);
|
|
109
|
+
virtual bool mayHappenInParallelInst(const SVFInstruction* i1, const SVFInstruction* i2);
|
|
110
|
+
virtual bool executedByTheSameThread(const SVFInstruction* i1, const SVFInstruction* i2);
|
|
111
111
|
|
|
112
112
|
/// Get interleaving thread for statement inst
|
|
113
113
|
//@{
|
|
@@ -123,13 +123,13 @@ public:
|
|
|
123
123
|
|
|
124
124
|
/// Get/has ThreadStmt
|
|
125
125
|
//@{
|
|
126
|
-
inline const CxtThreadStmtSet& getThreadStmtSet(const
|
|
126
|
+
inline const CxtThreadStmtSet& getThreadStmtSet(const SVFInstruction* inst) const
|
|
127
127
|
{
|
|
128
128
|
InstToThreadStmtSetMap::const_iterator it = instToTSMap.find(inst);
|
|
129
129
|
assert(it!=instToTSMap.end() && "no thread access the instruction?");
|
|
130
130
|
return it->second;
|
|
131
131
|
}
|
|
132
|
-
inline bool hasThreadStmtSet(const
|
|
132
|
+
inline bool hasThreadStmtSet(const SVFInstruction* inst) const
|
|
133
133
|
{
|
|
134
134
|
return instToTSMap.find(inst)!=instToTSMap.end();
|
|
135
135
|
}
|
|
@@ -140,7 +140,7 @@ public:
|
|
|
140
140
|
|
|
141
141
|
private:
|
|
142
142
|
|
|
143
|
-
inline const PTACallGraph::FunctionSet& getCallee(const
|
|
143
|
+
inline const PTACallGraph::FunctionSet& getCallee(const SVFInstruction* inst, PTACallGraph::FunctionSet& callees)
|
|
144
144
|
{
|
|
145
145
|
tcg->getCallees(getCBN(inst), callees);
|
|
146
146
|
return callees;
|
|
@@ -189,7 +189,7 @@ private:
|
|
|
189
189
|
pushToCTSWorkList(tgr);
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
|
-
inline void rmInterleavingThread(const CxtThreadStmt& tgr, const NodeBS& tids, const
|
|
192
|
+
inline void rmInterleavingThread(const CxtThreadStmt& tgr, const NodeBS& tids, const SVFInstruction* joinsite)
|
|
193
193
|
{
|
|
194
194
|
NodeBS joinedTids;
|
|
195
195
|
for(NodeBS::iterator it = tids.begin(), eit = tids.end(); it!=eit; ++it)
|
|
@@ -214,7 +214,7 @@ private:
|
|
|
214
214
|
bool isRecurFullJoin(NodeID parentTid, NodeID curTid);
|
|
215
215
|
|
|
216
216
|
/// Whether a join site must join a thread t
|
|
217
|
-
bool isMustJoin(const NodeID curTid, const
|
|
217
|
+
bool isMustJoin(const NodeID curTid, const SVFInstruction* joinsite);
|
|
218
218
|
|
|
219
219
|
/// A thread is a multiForked thread if it is in a loop or recursion
|
|
220
220
|
inline bool isMultiForkedThread(NodeID curTid)
|
|
@@ -223,17 +223,17 @@ private:
|
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
/// Get the next instructions following control flow
|
|
226
|
-
inline void getNextInsts(const
|
|
226
|
+
inline void getNextInsts(const SVFInstruction* inst, InstVec& instVec)
|
|
227
227
|
{
|
|
228
228
|
tct->getNextInsts(inst,instVec);
|
|
229
229
|
}
|
|
230
230
|
/// Push calling context
|
|
231
|
-
inline void pushCxt(CallStrCxt& cxt, const
|
|
231
|
+
inline void pushCxt(CallStrCxt& cxt, const SVFInstruction* call, const SVFFunction* callee)
|
|
232
232
|
{
|
|
233
233
|
tct->pushCxt(cxt,call,callee);
|
|
234
234
|
}
|
|
235
235
|
/// Match context
|
|
236
|
-
inline bool matchCxt(CallStrCxt& cxt, const
|
|
236
|
+
inline bool matchCxt(CallStrCxt& cxt, const SVFInstruction* call, const SVFFunction* callee)
|
|
237
237
|
{
|
|
238
238
|
return tct->matchCxt(cxt,call,callee);
|
|
239
239
|
}
|
|
@@ -251,21 +251,21 @@ private:
|
|
|
251
251
|
}
|
|
252
252
|
|
|
253
253
|
/// Whether it is a fork site
|
|
254
|
-
inline bool isTDFork(const
|
|
254
|
+
inline bool isTDFork(const SVFInstruction* call)
|
|
255
255
|
{
|
|
256
256
|
return tcg->getThreadAPI()->isTDFork(call);
|
|
257
257
|
}
|
|
258
258
|
/// Whether it is a join site
|
|
259
|
-
inline bool isTDJoin(const
|
|
259
|
+
inline bool isTDJoin(const SVFInstruction* call)
|
|
260
260
|
{
|
|
261
261
|
return tcg->getThreadAPI()->isTDJoin(call);
|
|
262
262
|
}
|
|
263
263
|
|
|
264
264
|
/// Return thread id(s) which are directly or indirectly joined at this join site
|
|
265
|
-
NodeBS getDirAndIndJoinedTid(const CallStrCxt& cxt, const
|
|
265
|
+
NodeBS getDirAndIndJoinedTid(const CallStrCxt& cxt, const SVFInstruction* call);
|
|
266
266
|
|
|
267
267
|
/// Whether a context-sensitive join satisfies symmetric loop pattern
|
|
268
|
-
const Loop* isJoinInSymmetricLoop(const CallStrCxt& cxt, const
|
|
268
|
+
const Loop* isJoinInSymmetricLoop(const CallStrCxt& cxt, const SVFInstruction* call) const;
|
|
269
269
|
|
|
270
270
|
/// Whether thread t1 happens before t2 based on ForkJoin Analysis
|
|
271
271
|
bool isHBPair(NodeID tid1, NodeID tid2);
|
|
@@ -309,7 +309,7 @@ public:
|
|
|
309
309
|
typedef Set<NodePair> ThreadPairSet;
|
|
310
310
|
typedef Map<CxtStmt, const Loop*> CxtStmtToLoopMap;
|
|
311
311
|
typedef FIFOWorkList<CxtStmt> CxtStmtWorkList;
|
|
312
|
-
typedef Map<const
|
|
312
|
+
typedef Map<const SVFInstruction*, PTASCEV> forkjoinToPTASCEVMap;
|
|
313
313
|
ForkJoinAnalysis(TCT* t) : tct(t)
|
|
314
314
|
{
|
|
315
315
|
collectSCEVInfo();
|
|
@@ -358,22 +358,22 @@ public:
|
|
|
358
358
|
}
|
|
359
359
|
|
|
360
360
|
/// Get exit instruction of the start routine function of tid's parent thread
|
|
361
|
-
inline const
|
|
361
|
+
inline const SVFInstruction* getExitInstOfParentRoutineFun(NodeID tid) const
|
|
362
362
|
{
|
|
363
363
|
NodeID parentTid = tct->getParentThread(tid);
|
|
364
364
|
const CxtThread& parentct = tct->getTCTNode(parentTid)->getCxtThread();
|
|
365
|
-
const
|
|
366
|
-
const
|
|
367
|
-
return
|
|
365
|
+
const SVFFunction* parentRoutine = tct->getStartRoutineOfCxtThread(parentct);
|
|
366
|
+
const SVFInstruction* inst = parentRoutine->getExitBB()->back();
|
|
367
|
+
return inst;
|
|
368
368
|
}
|
|
369
369
|
|
|
370
370
|
/// Get loop for join site
|
|
371
|
-
inline const Loop* getJoinLoop(const
|
|
371
|
+
inline const Loop* getJoinLoop(const SVFInstruction* inst)
|
|
372
372
|
{
|
|
373
373
|
return tct->getJoinLoop(inst);
|
|
374
374
|
}
|
|
375
375
|
/// Get SE for function
|
|
376
|
-
inline ScalarEvolution* getSE(const
|
|
376
|
+
inline ScalarEvolution* getSE(const SVFInstruction* inst)
|
|
377
377
|
{
|
|
378
378
|
return tct->getSE(inst);
|
|
379
379
|
}
|
|
@@ -395,18 +395,18 @@ private:
|
|
|
395
395
|
void handleIntra(const CxtStmt& cts);
|
|
396
396
|
|
|
397
397
|
/// Return true if the fork and join have the same SCEV
|
|
398
|
-
bool isSameSCEV(const
|
|
398
|
+
bool isSameSCEV(const SVFInstruction* forkSite, const SVFInstruction* joinSite);
|
|
399
399
|
|
|
400
400
|
/// Same loop trip count
|
|
401
|
-
bool sameLoopTripCount(const
|
|
401
|
+
bool sameLoopTripCount(const SVFInstruction* forkSite, const SVFInstruction* joinSite);
|
|
402
402
|
|
|
403
403
|
/// Whether it is a matched fork join pair
|
|
404
|
-
bool isAliasedForkJoin(const
|
|
404
|
+
bool isAliasedForkJoin(const SVFInstruction* forkSite, const SVFInstruction* joinSite)
|
|
405
405
|
{
|
|
406
406
|
return tct->getPTA()->alias(getForkedThread(forkSite), getJoinedThread(joinSite)) && isSameSCEV(forkSite,joinSite);
|
|
407
407
|
}
|
|
408
408
|
// Get CallICFGNode
|
|
409
|
-
inline CallICFGNode* getCBN(const
|
|
409
|
+
inline CallICFGNode* getCBN(const SVFInstruction* inst)
|
|
410
410
|
{
|
|
411
411
|
return tct->getCallICFGNode(inst);
|
|
412
412
|
}
|
|
@@ -477,42 +477,42 @@ private:
|
|
|
477
477
|
//@}
|
|
478
478
|
|
|
479
479
|
/// Get the next instructions following control flow
|
|
480
|
-
inline void getNextInsts(const
|
|
480
|
+
inline void getNextInsts(const SVFInstruction* inst, InstVec& instSet)
|
|
481
481
|
{
|
|
482
482
|
tct->getNextInsts(inst,instSet);
|
|
483
483
|
}
|
|
484
484
|
/// Push calling context
|
|
485
|
-
inline void pushCxt(CallStrCxt& cxt, const
|
|
485
|
+
inline void pushCxt(CallStrCxt& cxt, const SVFInstruction* call, const SVFFunction* callee)
|
|
486
486
|
{
|
|
487
487
|
tct->pushCxt(cxt,call,callee);
|
|
488
488
|
}
|
|
489
489
|
/// Match context
|
|
490
|
-
inline bool matchCxt(CallStrCxt& cxt, const
|
|
490
|
+
inline bool matchCxt(CallStrCxt& cxt, const SVFInstruction* call, const SVFFunction* callee)
|
|
491
491
|
{
|
|
492
492
|
return tct->matchCxt(cxt,call,callee);
|
|
493
493
|
}
|
|
494
494
|
|
|
495
495
|
/// Whether it is a fork site
|
|
496
|
-
inline bool isTDFork(const
|
|
496
|
+
inline bool isTDFork(const SVFInstruction* call)
|
|
497
497
|
{
|
|
498
498
|
return getTCG()->getThreadAPI()->isTDFork(call);
|
|
499
499
|
}
|
|
500
500
|
/// Whether it is a join site
|
|
501
|
-
inline bool isTDJoin(const
|
|
501
|
+
inline bool isTDJoin(const SVFInstruction* call)
|
|
502
502
|
{
|
|
503
503
|
return getTCG()->getThreadAPI()->isTDJoin(call);
|
|
504
504
|
}
|
|
505
505
|
/// Get forked thread
|
|
506
|
-
inline const Value* getForkedThread(const
|
|
506
|
+
inline const Value* getForkedThread(const SVFInstruction* call)
|
|
507
507
|
{
|
|
508
508
|
return getTCG()->getThreadAPI()->getForkedThread(call);
|
|
509
509
|
}
|
|
510
510
|
/// Get joined thread
|
|
511
|
-
inline const Value* getJoinedThread(const
|
|
511
|
+
inline const Value* getJoinedThread(const SVFInstruction* call)
|
|
512
512
|
{
|
|
513
513
|
return getTCG()->getThreadAPI()->getJoinedThread(call);
|
|
514
514
|
}
|
|
515
|
-
inline const PTACallGraph::FunctionSet& getCallee(const
|
|
515
|
+
inline const PTACallGraph::FunctionSet& getCallee(const SVFInstruction* inst, PTACallGraph::FunctionSet& callees)
|
|
516
516
|
{
|
|
517
517
|
getTCG()->getCallees(getCBN(inst), callees);
|
|
518
518
|
return callees;
|
|
@@ -60,8 +60,8 @@ class MTA: public ModulePass
|
|
|
60
60
|
public:
|
|
61
61
|
typedef Set<const LoadInst*> LoadSet;
|
|
62
62
|
typedef Set<const StoreInst*> StoreSet;
|
|
63
|
-
typedef Map<const
|
|
64
|
-
typedef Map<const
|
|
63
|
+
typedef Map<const SVFFunction*, ScalarEvolution*> FunToSEMap;
|
|
64
|
+
typedef Map<const SVFFunction*, LoopInfo*> FunToLoopInfoMap;
|
|
65
65
|
|
|
66
66
|
/// Pass ID
|
|
67
67
|
static char ID;
|
|
@@ -96,12 +96,12 @@ public:
|
|
|
96
96
|
void dump(Module &module, MHP *mhp, LockAnalysis *lsa);
|
|
97
97
|
|
|
98
98
|
// Get ScalarEvolution for Function F.
|
|
99
|
-
static inline ScalarEvolution* getSE(const
|
|
99
|
+
static inline ScalarEvolution* getSE(const SVFFunction* F)
|
|
100
100
|
{
|
|
101
101
|
FunToSEMap::iterator it = func2ScevMap.find(F);
|
|
102
102
|
if (it != func2ScevMap.end())
|
|
103
103
|
return it->second;
|
|
104
|
-
ScalarEvolutionWrapperPass *scev = &modulePass->getAnalysis<ScalarEvolutionWrapperPass>(*const_cast<Function*>(F));
|
|
104
|
+
ScalarEvolutionWrapperPass *scev = &modulePass->getAnalysis<ScalarEvolutionWrapperPass>(*const_cast<Function*>(F->getLLVMFun()));
|
|
105
105
|
func2ScevMap[F] = &scev->getSE();
|
|
106
106
|
return &scev->getSE();
|
|
107
107
|
}
|
|
@@ -68,16 +68,18 @@ public:
|
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
/// Check if Function "F" is memset
|
|
71
|
-
inline bool isMemset(const Instruction
|
|
71
|
+
inline bool isMemset(const Instruction* I)
|
|
72
72
|
{
|
|
73
|
-
const
|
|
73
|
+
const SVFInstruction* svfInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(I);
|
|
74
|
+
const Function* F =SVFUtil::getCallee(svfInst)->getLLVMFun();
|
|
74
75
|
return F && F->getName().find("llvm.memset") != std::string::npos;
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
/// Check if Function "F" is memcpy
|
|
78
|
-
inline bool isMemcpy(const Instruction
|
|
79
|
+
inline bool isMemcpy(const Instruction* I)
|
|
79
80
|
{
|
|
80
|
-
const
|
|
81
|
+
const SVFInstruction* svfInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(I);
|
|
82
|
+
const SVFFunction* F = SVFUtil::getCallee(svfInst);
|
|
81
83
|
return F && F->getName().find("llvm.memcpy") != std::string::npos;
|
|
82
84
|
}
|
|
83
85
|
|
|
@@ -52,15 +52,15 @@ protected:
|
|
|
52
52
|
std::vector<std::string> split(const std::string &s, char delim);
|
|
53
53
|
|
|
54
54
|
// Get special arguments of given call sites
|
|
55
|
-
NodeID getIntArg(const
|
|
56
|
-
std::vector<std::string> getStringArg(const
|
|
57
|
-
CallStrCxt getCxtArg(const
|
|
55
|
+
NodeID getIntArg(const SVFInstruction* inst, unsigned int arg_num);
|
|
56
|
+
std::vector<std::string> getStringArg(const SVFInstruction* inst, unsigned int arg_num);
|
|
57
|
+
CallStrCxt getCxtArg(const SVFInstruction* inst, unsigned int arg_num);
|
|
58
58
|
|
|
59
59
|
/*
|
|
60
60
|
* Get the previous LoadInst or StoreInst from Instruction "I" in the
|
|
61
61
|
* same BasicBlock. Return nullptr if none exists.
|
|
62
62
|
*/
|
|
63
|
-
const Instruction
|
|
63
|
+
const Instruction* getPreviousMemoryAccessInst(const Instruction* I);
|
|
64
64
|
|
|
65
65
|
// Compare two cxts
|
|
66
66
|
bool matchCxt(const CallStrCxt cxt1, const CallStrCxt cxt2) const;
|
|
@@ -77,7 +77,7 @@ protected:
|
|
|
77
77
|
/*
|
|
78
78
|
* Collect the callsite targets for validations.
|
|
79
79
|
* The targets are labeled by "cs1:", "cs2:"... that are the names of its basic blocks.
|
|
80
|
-
* The collected targets are stored in csnumToInstMap that maps label "cs1" to
|
|
80
|
+
* The collected targets are stored in csnumToInstMap that maps label "cs1" to its Callsite.
|
|
81
81
|
*/
|
|
82
82
|
bool collectCallsiteTargets();
|
|
83
83
|
|
|
@@ -117,7 +117,7 @@ protected:
|
|
|
117
117
|
|
|
118
118
|
private:
|
|
119
119
|
|
|
120
|
-
typedef Map<NodeID, const
|
|
120
|
+
typedef Map<NodeID, const SVFInstruction*> csnumToInst;
|
|
121
121
|
typedef Map<NodeID, CallStrCxt> vthdToCxtMap;
|
|
122
122
|
typedef Map<NodeID, NodeID> vthdTorthdMap;
|
|
123
123
|
typedef Map<NodeID, NodeID> rthdTovthdMap;
|
|
@@ -177,7 +177,7 @@ public:
|
|
|
177
177
|
{
|
|
178
178
|
public:
|
|
179
179
|
/// Constructor
|
|
180
|
-
AccessPair(const Instruction
|
|
180
|
+
AccessPair(const Instruction* I1, const Instruction* I2,
|
|
181
181
|
const RC_FLAG flags) :
|
|
182
182
|
I1(I1), I2(I2), flags(flags)
|
|
183
183
|
{
|
|
@@ -189,19 +189,19 @@ public:
|
|
|
189
189
|
{
|
|
190
190
|
return flags & flag;
|
|
191
191
|
}
|
|
192
|
-
inline const Instruction
|
|
192
|
+
inline const Instruction* getInstruction1() const
|
|
193
193
|
{
|
|
194
194
|
return I1;
|
|
195
195
|
}
|
|
196
|
-
inline const Instruction
|
|
196
|
+
inline const Instruction* getInstruction2() const
|
|
197
197
|
{
|
|
198
198
|
return I2;
|
|
199
199
|
}
|
|
200
200
|
//@}
|
|
201
201
|
|
|
202
202
|
private:
|
|
203
|
-
const Instruction
|
|
204
|
-
const Instruction
|
|
203
|
+
const Instruction* I1;
|
|
204
|
+
const Instruction* I2;
|
|
205
205
|
RC_FLAG flags;
|
|
206
206
|
};
|
|
207
207
|
|
|
@@ -240,26 +240,26 @@ protected:
|
|
|
240
240
|
/// Interface to the specific validation properties.
|
|
241
241
|
/// Override one or more to implement your own analysis.
|
|
242
242
|
//@{
|
|
243
|
-
virtual bool mayAccessAliases(const Instruction
|
|
244
|
-
const Instruction
|
|
243
|
+
virtual bool mayAccessAliases(const Instruction* I1,
|
|
244
|
+
const Instruction* I2)
|
|
245
245
|
{
|
|
246
246
|
selectedValidationScenarios &= ~RC_ALIASES;
|
|
247
247
|
return true;
|
|
248
248
|
}
|
|
249
|
-
virtual bool mayHappenInParallel(const Instruction
|
|
250
|
-
const Instruction
|
|
249
|
+
virtual bool mayHappenInParallel(const Instruction* I1,
|
|
250
|
+
const Instruction* I2)
|
|
251
251
|
{
|
|
252
252
|
selectedValidationScenarios &= ~RC_MHP;
|
|
253
253
|
return true;
|
|
254
254
|
}
|
|
255
|
-
virtual bool protectedByCommonLocks(const Instruction
|
|
256
|
-
const Instruction
|
|
255
|
+
virtual bool protectedByCommonLocks(const Instruction* I1,
|
|
256
|
+
const Instruction* I2)
|
|
257
257
|
{
|
|
258
258
|
selectedValidationScenarios &= ~RC_PROTECTED;
|
|
259
259
|
return true;
|
|
260
260
|
}
|
|
261
|
-
virtual bool mayHaveDataRace(const Instruction
|
|
262
|
-
const Instruction
|
|
261
|
+
virtual bool mayHaveDataRace(const Instruction* I1,
|
|
262
|
+
const Instruction* I2)
|
|
263
263
|
{
|
|
264
264
|
selectedValidationScenarios &= ~RC_RACE;
|
|
265
265
|
return true;
|
|
@@ -274,15 +274,18 @@ protected:
|
|
|
274
274
|
void collectValidationTargets()
|
|
275
275
|
{
|
|
276
276
|
// Collect call sites of all RC_ACCESS function calls.
|
|
277
|
-
std::vector<
|
|
278
|
-
const Function
|
|
279
|
-
for(
|
|
277
|
+
std::vector<CallSite> csInsts;
|
|
278
|
+
const Function* F = nullptr;
|
|
279
|
+
for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
|
|
280
280
|
{
|
|
281
|
-
|
|
282
|
-
if(fName.find(RC_ACCESS) != std::string::npos)
|
|
281
|
+
for(auto it = M.begin(); it != M.end(); it++)
|
|
283
282
|
{
|
|
284
|
-
|
|
285
|
-
|
|
283
|
+
const std::string fName = (*it).getName().str();
|
|
284
|
+
if(fName.find(RC_ACCESS) != std::string::npos)
|
|
285
|
+
{
|
|
286
|
+
F = &(*it);
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
286
289
|
}
|
|
287
290
|
}
|
|
288
291
|
if (!F) return;
|
|
@@ -292,9 +295,11 @@ protected:
|
|
|
292
295
|
{
|
|
293
296
|
const Use *u = &*it;
|
|
294
297
|
const Value *user = u->getUser();
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
+
if(SVFUtil::isCallSite(user))
|
|
299
|
+
{
|
|
300
|
+
CallSite csInst = SVFUtil::getLLVMCallSite(user);
|
|
301
|
+
csInsts.push_back(csInst);
|
|
302
|
+
}
|
|
298
303
|
}
|
|
299
304
|
assert(csInsts.size() % 2 == 0 && "We should have RC_ACCESS called in pairs.");
|
|
300
305
|
|
|
@@ -304,12 +309,12 @@ protected:
|
|
|
304
309
|
// Generate access pairs.
|
|
305
310
|
for (int i = 0, e = csInsts.size(); i != e;)
|
|
306
311
|
{
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
const ConstantInt
|
|
312
|
+
CallSite CI1 = csInsts[i++];
|
|
313
|
+
CallSite CI2 = csInsts[i++];
|
|
314
|
+
const ConstantInt* C = SVFUtil::dyn_cast<ConstantInt>(CI1.getArgOperand(1));
|
|
310
315
|
assert(C);
|
|
311
|
-
const Instruction
|
|
312
|
-
const Instruction
|
|
316
|
+
const Instruction* I1 = getPreviousMemoryAccessInst(CI1.getInstruction()->getLLVMInstruction());
|
|
317
|
+
const Instruction* I2 = getPreviousMemoryAccessInst(CI2.getInstruction()->getLLVMInstruction());
|
|
313
318
|
assert(I1 && I2 && "RC_ACCESS should be placed immediately after the target memory access.");
|
|
314
319
|
RC_FLAG flags = C->getZExtValue();
|
|
315
320
|
accessPairs.push_back(AccessPair(I1, I2, flags));
|
|
@@ -325,8 +330,8 @@ protected:
|
|
|
325
330
|
for (int i = 0, e = accessPairs.size(); i != e; ++i)
|
|
326
331
|
{
|
|
327
332
|
const AccessPair &ap = accessPairs[i];
|
|
328
|
-
const Instruction
|
|
329
|
-
const Instruction
|
|
333
|
+
const Instruction* I1 = ap.getInstruction1();
|
|
334
|
+
const Instruction* I2 = ap.getInstruction2();
|
|
330
335
|
|
|
331
336
|
bool mhp = mayHappenInParallel(I1, I2);
|
|
332
337
|
bool alias = mayAccessAliases(I1, I2);
|
|
@@ -390,12 +395,12 @@ private:
|
|
|
390
395
|
* Comparison function to sort the validation targets in ascending order of
|
|
391
396
|
* the validation id (i.e., the 1st argument of RC_ACCESS function call).
|
|
392
397
|
*/
|
|
393
|
-
static bool compare(
|
|
398
|
+
static bool compare(CallSite CI1, CallSite CI2)
|
|
394
399
|
{
|
|
395
|
-
const Value *V1 = CI1
|
|
396
|
-
const Value *V2 = CI2
|
|
397
|
-
const ConstantInt
|
|
398
|
-
const ConstantInt
|
|
400
|
+
const Value *V1 = CI1.getArgOperand(0);
|
|
401
|
+
const Value *V2 = CI2.getArgOperand(0);
|
|
402
|
+
const ConstantInt* C1 = SVFUtil::dyn_cast<ConstantInt>(V1);
|
|
403
|
+
const ConstantInt* C2 = SVFUtil::dyn_cast<ConstantInt>(V2);
|
|
399
404
|
assert(0 != C1 && 0 != C2);
|
|
400
405
|
return C1->getZExtValue() < C2->getZExtValue();
|
|
401
406
|
}
|
|
@@ -405,8 +410,8 @@ private:
|
|
|
405
410
|
* same BasicBlock.
|
|
406
411
|
* Return nullptr if none exists.
|
|
407
412
|
*/
|
|
408
|
-
const Instruction
|
|
409
|
-
const Instruction
|
|
413
|
+
const Instruction* getPreviousMemoryAccessInst(
|
|
414
|
+
const Instruction* I)
|
|
410
415
|
{
|
|
411
416
|
I = I->getPrevNode();
|
|
412
417
|
while (I)
|
|
@@ -414,7 +419,9 @@ private:
|
|
|
414
419
|
if (SVFUtil::isa<LoadInst>(I) || SVFUtil::isa<StoreInst>(I))
|
|
415
420
|
return I;
|
|
416
421
|
|
|
417
|
-
|
|
422
|
+
const SVFInstruction* inst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(I);
|
|
423
|
+
|
|
424
|
+
if (const SVFFunction *callee = SVFUtil::getCallee(inst))
|
|
418
425
|
{
|
|
419
426
|
if (callee->getName().find("llvm.memset") != std::string::npos)
|
|
420
427
|
return I;
|
|
@@ -51,11 +51,11 @@ class PCG
|
|
|
51
51
|
{
|
|
52
52
|
|
|
53
53
|
public:
|
|
54
|
-
typedef Set<const
|
|
55
|
-
typedef std::vector<const
|
|
56
|
-
typedef Set<const
|
|
57
|
-
typedef FIFOWorkList<const
|
|
58
|
-
typedef FIFOWorkList<const
|
|
54
|
+
typedef Set<const SVFFunction*> FunSet;
|
|
55
|
+
typedef std::vector<const SVFFunction*> FunVec;
|
|
56
|
+
typedef Set<const SVFInstruction*> CallInstSet;
|
|
57
|
+
typedef FIFOWorkList<const SVFFunction*> FunWorkList;
|
|
58
|
+
typedef FIFOWorkList<const SVFBasicBlock*> BBWorkList;
|
|
59
59
|
|
|
60
60
|
private:
|
|
61
61
|
FunSet spawners;
|
|
@@ -72,31 +72,31 @@ private:
|
|
|
72
72
|
|
|
73
73
|
/// Add/Get methods for thread properties of a procedure
|
|
74
74
|
//@{
|
|
75
|
-
inline bool isSpawnerFun(const
|
|
75
|
+
inline bool isSpawnerFun(const SVFFunction* fun) const
|
|
76
76
|
{
|
|
77
77
|
return spawners.find(fun) != spawners.end();
|
|
78
78
|
}
|
|
79
|
-
inline bool isSpawneeFun(const
|
|
79
|
+
inline bool isSpawneeFun(const SVFFunction* fun) const
|
|
80
80
|
{
|
|
81
81
|
return spawnees.find(fun) != spawnees.end();
|
|
82
82
|
}
|
|
83
|
-
inline bool isFollowerFun(const
|
|
83
|
+
inline bool isFollowerFun(const SVFFunction* fun) const
|
|
84
84
|
{
|
|
85
85
|
return followers.find(fun) != followers.end();
|
|
86
86
|
}
|
|
87
|
-
inline bool addSpawnerFun(const
|
|
87
|
+
inline bool addSpawnerFun(const SVFFunction* fun)
|
|
88
88
|
{
|
|
89
89
|
if (fun->isDeclaration())
|
|
90
90
|
return false;
|
|
91
91
|
return spawners.insert(fun).second;
|
|
92
92
|
}
|
|
93
|
-
inline bool addSpawneeFun(const
|
|
93
|
+
inline bool addSpawneeFun(const SVFFunction* fun)
|
|
94
94
|
{
|
|
95
95
|
if (fun->isDeclaration())
|
|
96
96
|
return false;
|
|
97
97
|
return spawnees.insert(fun).second;
|
|
98
98
|
}
|
|
99
|
-
inline bool addFollowerFun(const
|
|
99
|
+
inline bool addFollowerFun(const SVFFunction* fun)
|
|
100
100
|
{
|
|
101
101
|
if (fun->isDeclaration())
|
|
102
102
|
return false;
|
|
@@ -106,11 +106,11 @@ private:
|
|
|
106
106
|
|
|
107
107
|
/// Add/search spawn sites which directly or indirectly create a thread
|
|
108
108
|
//@{
|
|
109
|
-
inline bool addSpawnsite(const
|
|
109
|
+
inline bool addSpawnsite(const SVFInstruction* callInst)
|
|
110
110
|
{
|
|
111
111
|
return spawnCallSites.insert(callInst).second;
|
|
112
112
|
}
|
|
113
|
-
inline bool isSpawnsite(const
|
|
113
|
+
inline bool isSpawnsite(const SVFInstruction* callInst)
|
|
114
114
|
{
|
|
115
115
|
return spawnCallSites.find(callInst) != spawnCallSites.end();
|
|
116
116
|
}
|
|
@@ -145,18 +145,13 @@ public:
|
|
|
145
145
|
{
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
CallICFGNode* getCallICFGNode(const
|
|
148
|
+
CallICFGNode* getCallICFGNode(const SVFInstruction* inst)
|
|
149
149
|
{
|
|
150
150
|
return pta->getICFG()->getCallICFGNode(inst);
|
|
151
151
|
}
|
|
152
|
-
const SVFFunction* getSVFFun(const Function* fun) const
|
|
153
|
-
{
|
|
154
|
-
return LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(fun);
|
|
155
|
-
}
|
|
156
152
|
/// Interface to query whether two function may happen-in-parallel
|
|
157
|
-
virtual bool mayHappenInParallel(const
|
|
158
|
-
bool mayHappenInParallelBetweenFunctions(const
|
|
159
|
-
//bool mayHappenInParallel(const Function* fun1, const Function* fun2) const;
|
|
153
|
+
virtual bool mayHappenInParallel(const SVFInstruction* i1, const SVFInstruction* i2) const;
|
|
154
|
+
bool mayHappenInParallelBetweenFunctions(const SVFFunction* fun1, const SVFFunction* fun2) const;
|
|
160
155
|
inline const FunSet& getMHPFunctions() const
|
|
161
156
|
{
|
|
162
157
|
return mhpfuns;
|
|
@@ -192,27 +187,27 @@ public:
|
|
|
192
187
|
|
|
193
188
|
/// Iterators for thread properties of a procedure
|
|
194
189
|
//@{
|
|
195
|
-
inline FunSet::const_iterator spawnersBegin(const
|
|
190
|
+
inline FunSet::const_iterator spawnersBegin(const SVFFunction* fun) const
|
|
196
191
|
{
|
|
197
192
|
return spawners.begin();
|
|
198
193
|
}
|
|
199
|
-
inline FunSet::const_iterator spawnersEnd(const
|
|
194
|
+
inline FunSet::const_iterator spawnersEnd(const SVFFunction* fun) const
|
|
200
195
|
{
|
|
201
196
|
return spawners.end();
|
|
202
197
|
}
|
|
203
|
-
inline FunSet::const_iterator spawneesBegin(const
|
|
198
|
+
inline FunSet::const_iterator spawneesBegin(const SVFFunction* fun) const
|
|
204
199
|
{
|
|
205
200
|
return spawnees.begin();
|
|
206
201
|
}
|
|
207
|
-
inline FunSet::const_iterator spawneesEnd(const
|
|
202
|
+
inline FunSet::const_iterator spawneesEnd(const SVFFunction* fun) const
|
|
208
203
|
{
|
|
209
204
|
return spawnees.end();
|
|
210
205
|
}
|
|
211
|
-
inline FunSet::const_iterator followersBegin(const
|
|
206
|
+
inline FunSet::const_iterator followersBegin(const SVFFunction* fun) const
|
|
212
207
|
{
|
|
213
208
|
return followers.begin();
|
|
214
209
|
}
|
|
215
|
-
inline FunSet::const_iterator followersEnd(const
|
|
210
|
+
inline FunSet::const_iterator followersEnd(const SVFFunction* fun) const
|
|
216
211
|
{
|
|
217
212
|
return followers.end();
|
|
218
213
|
}
|