svf-lib 1.0.2436 → 1.0.2438
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-aarch64/include/MTA/LockAnalysis.h +12 -9
- package/SVF-linux-aarch64/include/MTA/MHP.h +56 -20
- package/SVF-linux-aarch64/include/MTA/MTA.h +1 -1
- package/SVF-linux-aarch64/include/MTA/TCT.h +47 -46
- package/SVF-linux-aarch64/lib/libSvfCore.so.3.2 +0 -0
- package/SVF-osx/include/SVFIR/SVFIR.h +24 -24
- package/SVF-osx/include/SVFIR/SVFStatements.h +5 -1
- package/SVF-osx/include/SVFIR/SVFVariables.h +21 -29
- package/SVF-osx/lib/libSvfCore.3.2.dylib +0 -0
- package/SVF-osx/lib/libSvfLLVM.3.2.dylib +0 -0
- package/package.json +1 -1
|
@@ -72,13 +72,11 @@ public:
|
|
|
72
72
|
typedef Map<CxtLock, LockSpan> CxtLockToSpan;
|
|
73
73
|
typedef Map<CxtLock, NodeBS> CxtLockToLockSet;
|
|
74
74
|
typedef Map<const ICFGNode*, NodeBS> LockSiteToLockSet;
|
|
75
|
-
typedef Map<const ICFGNode*,
|
|
75
|
+
typedef Map<const ICFGNode*, CxtStmtSet> InstToCxtStmtSet;
|
|
76
76
|
typedef Map<CxtStmt, CxtLockSet> CxtStmtToCxtLockSet;
|
|
77
77
|
typedef FIFOWorkList<CxtLockProc> CxtLockProcVec;
|
|
78
78
|
typedef Set<CxtLockProc> CxtLockProcSet;
|
|
79
79
|
|
|
80
|
-
typedef Map<const ICFGNode*, CxtStmtSet> InstToCxtStmt;
|
|
81
|
-
|
|
82
80
|
LockAnalysis(TCT* t) : tct(t), lockTime(0),numOfTotalQueries(0), numOfLockedQueries(0), lockQueriesTime(0)
|
|
83
81
|
{
|
|
84
82
|
}
|
|
@@ -200,12 +198,12 @@ public:
|
|
|
200
198
|
/// Context-sensitive statement and lock spans
|
|
201
199
|
//@{
|
|
202
200
|
/// Get LockSet and LockSpan
|
|
203
|
-
inline bool
|
|
201
|
+
inline bool hasCxtStmtFromInst(const ICFGNode* inst) const
|
|
204
202
|
{
|
|
205
203
|
InstToCxtStmtSet::const_iterator it = instToCxtStmtSet.find(inst);
|
|
206
204
|
return (it != instToCxtStmtSet.end());
|
|
207
205
|
}
|
|
208
|
-
inline const CxtStmtSet&
|
|
206
|
+
inline const CxtStmtSet& getCxtStmtsFromInst(const ICFGNode* inst) const
|
|
209
207
|
{
|
|
210
208
|
InstToCxtStmtSet::const_iterator it = instToCxtStmtSet.find(inst);
|
|
211
209
|
assert(it != instToCxtStmtSet.end());
|
|
@@ -271,9 +269,9 @@ public:
|
|
|
271
269
|
/// Check if one instruction's context stmt is in a lock span
|
|
272
270
|
inline bool hasOneCxtInLockSpan(const ICFGNode *I, LockSpan lspan) const
|
|
273
271
|
{
|
|
274
|
-
if(!
|
|
272
|
+
if(!hasCxtStmtFromInst(I))
|
|
275
273
|
return false;
|
|
276
|
-
const LockSpan ctsset =
|
|
274
|
+
const LockSpan ctsset = getCxtStmtsFromInst(I);
|
|
277
275
|
for (LockSpan::const_iterator cts = ctsset.begin(), ects = ctsset.end(); cts != ects; cts++)
|
|
278
276
|
{
|
|
279
277
|
if(lspan.find(*cts) != lspan.end())
|
|
@@ -286,9 +284,9 @@ public:
|
|
|
286
284
|
|
|
287
285
|
inline bool hasAllCxtInLockSpan(const ICFGNode *I, LockSpan lspan) const
|
|
288
286
|
{
|
|
289
|
-
if(!
|
|
287
|
+
if(!hasCxtStmtFromInst(I))
|
|
290
288
|
return false;
|
|
291
|
-
const LockSpan ctsset =
|
|
289
|
+
const LockSpan ctsset = getCxtStmtsFromInst(I);
|
|
292
290
|
for (LockSpan::const_iterator cts = ctsset.begin(), ects = ctsset.end(); cts != ects; cts++)
|
|
293
291
|
{
|
|
294
292
|
if (lspan.find(*cts) == lspan.end())
|
|
@@ -429,10 +427,15 @@ private:
|
|
|
429
427
|
}
|
|
430
428
|
//@}
|
|
431
429
|
|
|
430
|
+
/// Context helper functions
|
|
431
|
+
//@{
|
|
432
432
|
/// Push calling context
|
|
433
433
|
void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const FunObjVar* callee);
|
|
434
434
|
/// Match context
|
|
435
435
|
bool matchCxt(CallStrCxt& cxt, const CallICFGNode* call, const FunObjVar* callee);
|
|
436
|
+
/// If lhs is a suffix of rhs, including equal
|
|
437
|
+
bool isContextSuffix(const CallStrCxt& lhs, const CallStrCxt& call);
|
|
438
|
+
//@}
|
|
436
439
|
|
|
437
440
|
/// Whether it is a lock site
|
|
438
441
|
inline bool isTDFork(const ICFGNode* call)
|
|
@@ -96,11 +96,11 @@ public:
|
|
|
96
96
|
//@{
|
|
97
97
|
inline const NodeBS& getInterleavingThreads(const CxtThreadStmt& cts)
|
|
98
98
|
{
|
|
99
|
-
return
|
|
99
|
+
return threadStmtToThreadInterLeav[cts];
|
|
100
100
|
}
|
|
101
101
|
inline bool hasInterleavingThreads(const CxtThreadStmt& cts) const
|
|
102
102
|
{
|
|
103
|
-
return
|
|
103
|
+
return threadStmtToThreadInterLeav.find(cts)!=threadStmtToThreadInterLeav.end();
|
|
104
104
|
}
|
|
105
105
|
//@}
|
|
106
106
|
|
|
@@ -154,7 +154,7 @@ private:
|
|
|
154
154
|
//@{
|
|
155
155
|
inline void addInterleavingThread(const CxtThreadStmt& tgr, NodeID tid)
|
|
156
156
|
{
|
|
157
|
-
if(
|
|
157
|
+
if(threadStmtToThreadInterLeav[tgr].test_and_set(tid))
|
|
158
158
|
{
|
|
159
159
|
instToTSMap[tgr.getStmt()].insert(tgr);
|
|
160
160
|
pushToCTSWorkList(tgr);
|
|
@@ -162,7 +162,7 @@ private:
|
|
|
162
162
|
}
|
|
163
163
|
inline void addInterleavingThread(const CxtThreadStmt& tgr, const CxtThreadStmt& src)
|
|
164
164
|
{
|
|
165
|
-
bool changed =
|
|
165
|
+
bool changed = threadStmtToThreadInterLeav[tgr] |= threadStmtToThreadInterLeav[src];
|
|
166
166
|
if(changed)
|
|
167
167
|
{
|
|
168
168
|
instToTSMap[tgr.getStmt()].insert(tgr);
|
|
@@ -177,7 +177,7 @@ private:
|
|
|
177
177
|
if(isMustJoin(tgr.getTid(),joinsite))
|
|
178
178
|
joinedTids.set(*it);
|
|
179
179
|
}
|
|
180
|
-
if(
|
|
180
|
+
if(threadStmtToThreadInterLeav[tgr].intersectWithComplement(joinedTids))
|
|
181
181
|
{
|
|
182
182
|
pushToCTSWorkList(tgr);
|
|
183
183
|
}
|
|
@@ -201,16 +201,28 @@ private:
|
|
|
201
201
|
{
|
|
202
202
|
return tct->getTCTNode(curTid)->isMultiforked();
|
|
203
203
|
}
|
|
204
|
+
|
|
205
|
+
/// Context helper functions
|
|
206
|
+
//@{
|
|
204
207
|
/// Push calling context
|
|
205
208
|
inline void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const FunObjVar* callee)
|
|
206
209
|
{
|
|
210
|
+
/// handle calling context for candidate functions only
|
|
211
|
+
if(tct->isCandidateFun(call->getFun()) == false)
|
|
212
|
+
return;
|
|
207
213
|
tct->pushCxt(cxt,call,callee);
|
|
208
214
|
}
|
|
209
215
|
/// Match context
|
|
210
|
-
inline bool
|
|
216
|
+
inline bool matchAndPopCxt(CallStrCxt& cxt, const CallICFGNode* call, const FunObjVar* callee)
|
|
217
|
+
{
|
|
218
|
+
return tct->matchAndPopCxt(cxt,call,callee);
|
|
219
|
+
}
|
|
220
|
+
/// If lhs is a suffix of rhs, including equal
|
|
221
|
+
inline bool isContextSuffix(const CallStrCxt& lhs, const CallStrCxt call)
|
|
211
222
|
{
|
|
212
|
-
return tct->
|
|
223
|
+
return tct->isContextSuffix(lhs,call);
|
|
213
224
|
}
|
|
225
|
+
//@}
|
|
214
226
|
|
|
215
227
|
/// WorkList helper functions
|
|
216
228
|
//@{
|
|
@@ -253,7 +265,7 @@ private:
|
|
|
253
265
|
TCT* tct; ///< TCT
|
|
254
266
|
ForkJoinAnalysis* fja; ///< ForJoin Analysis
|
|
255
267
|
CxtThreadStmtWorkList cxtStmtList; ///< CxtThreadStmt worklist
|
|
256
|
-
ThreadStmtToThreadInterleav
|
|
268
|
+
ThreadStmtToThreadInterleav threadStmtToThreadInterLeav; /// Map a statement to its thread interleavings
|
|
257
269
|
InstToThreadStmtSetMap instToTSMap; ///< Map an instruction to its ThreadStmtSet
|
|
258
270
|
FuncPairToBool nonCandidateFuncMHPRelMap;
|
|
259
271
|
|
|
@@ -290,6 +302,10 @@ public:
|
|
|
290
302
|
typedef Map<CxtStmt, LoopBBs> CxtStmtToLoopMap;
|
|
291
303
|
typedef FIFOWorkList<CxtStmt> CxtStmtWorkList;
|
|
292
304
|
|
|
305
|
+
typedef Set<CxtStmt> CxtStmtSet;
|
|
306
|
+
typedef Map<const ICFGNode*, CxtStmtSet> InstToCxtStmt;
|
|
307
|
+
|
|
308
|
+
|
|
293
309
|
ForkJoinAnalysis(TCT* t) : tct(t)
|
|
294
310
|
{
|
|
295
311
|
collectSCEVInfo();
|
|
@@ -337,15 +353,6 @@ public:
|
|
|
337
353
|
return full && !partial;
|
|
338
354
|
}
|
|
339
355
|
|
|
340
|
-
/// Get exit instruction of the start routine function of tid's parent thread
|
|
341
|
-
inline const ICFGNode* getExitInstOfParentRoutineFun(NodeID tid) const
|
|
342
|
-
{
|
|
343
|
-
NodeID parentTid = tct->getParentThread(tid);
|
|
344
|
-
const CxtThread& parentct = tct->getTCTNode(parentTid)->getCxtThread();
|
|
345
|
-
const FunObjVar* parentRoutine = tct->getStartRoutineOfCxtThread(parentct);
|
|
346
|
-
return parentRoutine->getExitBB()->back();
|
|
347
|
-
}
|
|
348
|
-
|
|
349
356
|
/// Get loop for join site
|
|
350
357
|
inline LoopBBs& getJoinLoop(const CallICFGNode* inst)
|
|
351
358
|
{
|
|
@@ -381,7 +388,7 @@ private:
|
|
|
381
388
|
/// Whether it is a matched fork join pair
|
|
382
389
|
bool isAliasedForkJoin(const CallICFGNode* forkSite, const CallICFGNode* joinSite)
|
|
383
390
|
{
|
|
384
|
-
return tct->getPTA()->alias(getForkedThread(forkSite)->getId(), getJoinedThread(joinSite)->getId())
|
|
391
|
+
return tct->getPTA()->alias(getForkedThread(forkSite)->getId(), getJoinedThread(joinSite)->getId());
|
|
385
392
|
}
|
|
386
393
|
/// Mark thread flags for cxtStmt
|
|
387
394
|
//@{
|
|
@@ -403,7 +410,11 @@ private:
|
|
|
403
410
|
ValDomain flag_tgr = getMarkedFlag(tgr);
|
|
404
411
|
cxtStmtToAliveFlagMap[tgr] = flag;
|
|
405
412
|
if(flag_tgr!=getMarkedFlag(tgr))
|
|
413
|
+
{
|
|
414
|
+
instToCxtStmt[tgr.getStmt()].insert(tgr);
|
|
406
415
|
pushToCTSWorkList(tgr);
|
|
416
|
+
}
|
|
417
|
+
|
|
407
418
|
}
|
|
408
419
|
/// Transfer function for marking context-sensitive statement
|
|
409
420
|
void markCxtStmtFlag(const CxtStmt& tgr, const CxtStmt& src)
|
|
@@ -425,6 +436,7 @@ private:
|
|
|
425
436
|
}
|
|
426
437
|
if(flag_tgr!=getMarkedFlag(tgr))
|
|
427
438
|
{
|
|
439
|
+
instToCxtStmt[tgr.getStmt()].insert(tgr);
|
|
428
440
|
pushToCTSWorkList(tgr);
|
|
429
441
|
}
|
|
430
442
|
}
|
|
@@ -449,16 +461,27 @@ private:
|
|
|
449
461
|
}
|
|
450
462
|
//@}
|
|
451
463
|
|
|
464
|
+
/// Context helper functions
|
|
465
|
+
//@{
|
|
452
466
|
/// Push calling context
|
|
453
467
|
inline void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const FunObjVar* callee)
|
|
454
468
|
{
|
|
469
|
+
/// handle calling context for candidate functions only
|
|
470
|
+
if(tct->isCandidateFun(call->getFun()) == false)
|
|
471
|
+
return;
|
|
455
472
|
tct->pushCxt(cxt,call,callee);
|
|
456
473
|
}
|
|
457
474
|
/// Match context
|
|
458
|
-
inline bool
|
|
475
|
+
inline bool matchAndPopCxt(CallStrCxt& cxt, const CallICFGNode* call, const FunObjVar* callee)
|
|
476
|
+
{
|
|
477
|
+
return tct->matchAndPopCxt(cxt,call,callee);
|
|
478
|
+
}
|
|
479
|
+
/// If lhs is a suffix of rhs, including equal
|
|
480
|
+
inline bool isContextSuffix(const CallStrCxt& lhs, const CallStrCxt call)
|
|
459
481
|
{
|
|
460
|
-
return tct->
|
|
482
|
+
return tct->isContextSuffix(lhs,call);
|
|
461
483
|
}
|
|
484
|
+
//@}
|
|
462
485
|
|
|
463
486
|
/// Whether it is a fork site
|
|
464
487
|
inline bool isTDFork(const ICFGNode* call)
|
|
@@ -524,6 +547,18 @@ private:
|
|
|
524
547
|
}
|
|
525
548
|
//@}
|
|
526
549
|
|
|
550
|
+
/// Get CxtStmtSet for an instruction
|
|
551
|
+
inline const CxtStmtSet& getCxtStmtsFromInst(const ICFGNode* inst) const
|
|
552
|
+
{
|
|
553
|
+
InstToCxtStmt::const_iterator it = instToCxtStmt.find(inst);
|
|
554
|
+
assert(it!=instToCxtStmt.end() && "no CxtStmt for the instruction?");
|
|
555
|
+
return it->second;
|
|
556
|
+
}
|
|
557
|
+
inline bool hasCxtStmtsFromInst(const ICFGNode* inst) const
|
|
558
|
+
{
|
|
559
|
+
return instToCxtStmt.find(inst)!=instToCxtStmt.end();
|
|
560
|
+
}
|
|
561
|
+
|
|
527
562
|
/// Add inloop join
|
|
528
563
|
inline void addSymmetricLoopJoin(const CxtStmt& cs, LoopBBs& lp)
|
|
529
564
|
{
|
|
@@ -539,6 +574,7 @@ private:
|
|
|
539
574
|
ThreadPairSet HPPair; ///< threads happen-in-parallel
|
|
540
575
|
ThreadPairSet fullJoin; ///< t1 fully joins t2 along all program path
|
|
541
576
|
ThreadPairSet partialJoin; ///< t1 partially joins t2 along some program path(s)
|
|
577
|
+
InstToCxtStmt instToCxtStmt; ///<Map a statement to all its context-sensitive statements
|
|
542
578
|
};
|
|
543
579
|
|
|
544
580
|
} // End namespace SVF
|
|
@@ -66,7 +66,7 @@ public:
|
|
|
66
66
|
/// We start the pass here
|
|
67
67
|
virtual bool runOnModule(SVFIR* module);
|
|
68
68
|
/// Compute MHP
|
|
69
|
-
virtual MHP* computeMHP();
|
|
69
|
+
virtual MHP* computeMHP(TCT* tct);
|
|
70
70
|
/// Compute locksets
|
|
71
71
|
virtual LockAnalysis* computeLocksets(TCT* tct);
|
|
72
72
|
/// Perform detection
|
|
@@ -97,7 +97,7 @@ public:
|
|
|
97
97
|
SVFUtil::outs() << "---\ntid: " << this->getId() << " inloop:" << ctx.isInloop() << " incycle:" << ctx.isIncycle() << " multiforked:"<< isMultiforked();
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
/// Get
|
|
100
|
+
/// Get thread creation context, <fork site, call string context>
|
|
101
101
|
inline const CxtThread& getCxtThread() const
|
|
102
102
|
{
|
|
103
103
|
return ctx;
|
|
@@ -142,7 +142,7 @@ public:
|
|
|
142
142
|
|
|
143
143
|
|
|
144
144
|
private:
|
|
145
|
-
const CxtThread ctx;
|
|
145
|
+
const CxtThread ctx; /// Thread creation context, <fork site, call string context>
|
|
146
146
|
bool multiforked;
|
|
147
147
|
};
|
|
148
148
|
|
|
@@ -162,7 +162,8 @@ public:
|
|
|
162
162
|
typedef Set<const ICFGNode*> InstSet;
|
|
163
163
|
typedef Set<const CallGraphNode*> PTACGNodeSet;
|
|
164
164
|
typedef Map<CxtThread,TCTNode*> CxtThreadToNodeMap;
|
|
165
|
-
typedef
|
|
165
|
+
typedef Set<std::pair<NodeID, CallStrCxt>> CallStrCxtSet;
|
|
166
|
+
typedef Map<CxtThread,CallStrCxtSet> CxtThreadToForkCxtSet;
|
|
166
167
|
typedef Map<CxtThread,const FunObjVar*> CxtThreadToFun;
|
|
167
168
|
typedef Map<const ICFGNode*, LoopBBs> InstToLoopMap;
|
|
168
169
|
typedef FIFOWorkList<CxtThreadProc> CxtThreadProcVec;
|
|
@@ -172,7 +173,8 @@ public:
|
|
|
172
173
|
/// Constructor
|
|
173
174
|
TCT(PointerAnalysis* p) :pta(p),TCTNodeNum(0),TCTEdgeNum(0),MaxCxtSize(0)
|
|
174
175
|
{
|
|
175
|
-
tcg = SVFUtil::
|
|
176
|
+
tcg = SVFUtil::dyn_cast<ThreadCallGraph>(pta->getCallGraph());
|
|
177
|
+
assert(tcg != nullptr && "TCT::TCT: call graph is not a ThreadCallGraph!");
|
|
176
178
|
tcg->updateCallGraph(pta);
|
|
177
179
|
//tcg->updateJoinEdge(pta);
|
|
178
180
|
tcgSCC = pta->getCallGraphSCC();
|
|
@@ -182,9 +184,7 @@ public:
|
|
|
182
184
|
|
|
183
185
|
/// Destructor
|
|
184
186
|
virtual ~TCT()
|
|
185
|
-
{
|
|
186
|
-
destroy();
|
|
187
|
-
}
|
|
187
|
+
{ }
|
|
188
188
|
|
|
189
189
|
/// Get TCG
|
|
190
190
|
inline ThreadCallGraph* getThreadCallGraph() const
|
|
@@ -310,24 +310,29 @@ public:
|
|
|
310
310
|
const TCTNode* node = getTCTNode(tid);
|
|
311
311
|
return node->getInEdges().size()==1;
|
|
312
312
|
}
|
|
313
|
-
/// Get parent
|
|
314
|
-
inline
|
|
313
|
+
/// Get parent threads
|
|
314
|
+
inline NodeBS getParentThreads(NodeID tid) const
|
|
315
315
|
{
|
|
316
|
+
NodeBS parentTds;
|
|
316
317
|
const TCTNode* node = getTCTNode(tid);
|
|
317
|
-
assert(node->getInEdges().size()
|
|
318
|
-
|
|
319
|
-
const TCTEdge* edge
|
|
320
|
-
|
|
318
|
+
assert(node->getInEdges().size()>=1 && "does not have a parent thread");
|
|
319
|
+
|
|
320
|
+
for (const TCTEdge* edge : node->getInEdges())
|
|
321
|
+
{
|
|
322
|
+
parentTds.set(edge->getSrcID());
|
|
323
|
+
}
|
|
324
|
+
return parentTds;
|
|
321
325
|
}
|
|
322
326
|
/// Get all ancestor threads
|
|
323
|
-
const NodeBS
|
|
327
|
+
const NodeBS getAncestorThreads(NodeID tid) const
|
|
324
328
|
{
|
|
325
329
|
NodeBS tds;
|
|
326
330
|
if(hasParentThread(tid) == false)
|
|
327
331
|
return tds;
|
|
328
332
|
|
|
329
333
|
FIFOWorkList<NodeID> worklist;
|
|
330
|
-
|
|
334
|
+
for(NodeID parentTid : getParentThreads(tid))
|
|
335
|
+
worklist.push(parentTid);
|
|
331
336
|
|
|
332
337
|
while(!worklist.empty())
|
|
333
338
|
{
|
|
@@ -335,7 +340,8 @@ public:
|
|
|
335
340
|
if(tds.test_and_set(t))
|
|
336
341
|
{
|
|
337
342
|
if(hasParentThread(t))
|
|
338
|
-
|
|
343
|
+
for(NodeID parentTid : getParentThreads(t))
|
|
344
|
+
worklist.push(parentTid);
|
|
339
345
|
}
|
|
340
346
|
}
|
|
341
347
|
return tds;
|
|
@@ -346,24 +352,26 @@ public:
|
|
|
346
352
|
NodeBS tds;
|
|
347
353
|
if(hasParentThread(tid) == false)
|
|
348
354
|
return tds;
|
|
349
|
-
|
|
350
|
-
const TCTNode* node = getTCTNode(getParentThread(tid));
|
|
351
|
-
for(ThreadCreateEdgeSet::const_iterator it = getChildrenBegin(node), eit = getChildrenEnd(node); it!=eit; ++it)
|
|
355
|
+
for (NodeID parentTid : getParentThreads(tid))
|
|
352
356
|
{
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
357
|
+
const TCTNode* parentNode = getTCTNode(parentTid);
|
|
358
|
+
for(ThreadCreateEdgeSet::const_iterator it = getChildrenBegin(parentNode),
|
|
359
|
+
eit = getChildrenEnd(parentNode); it!=eit; ++it)
|
|
360
|
+
{
|
|
361
|
+
NodeID child = (*it)->getDstNode()->getId();
|
|
362
|
+
if(child!=tid)
|
|
363
|
+
tds.set(child);
|
|
364
|
+
}
|
|
356
365
|
}
|
|
357
|
-
|
|
358
366
|
return tds;
|
|
359
367
|
}
|
|
360
368
|
//@}
|
|
361
369
|
|
|
362
|
-
/// get the
|
|
363
|
-
const
|
|
370
|
+
/// get the contexts of a thread at its spawning sites (fork sites)
|
|
371
|
+
const CallStrCxtSet& getCxtOfCxtThread(const CxtThread& ct) const
|
|
364
372
|
{
|
|
365
|
-
|
|
366
|
-
assert(it!=
|
|
373
|
+
CxtThreadToForkCxtSet::const_iterator it = ctToForkCxtsMap.find(ct);
|
|
374
|
+
assert(it!=ctToForkCxtsMap.end() && "Cxt Thread not found!!");
|
|
367
375
|
return it->second;
|
|
368
376
|
}
|
|
369
377
|
|
|
@@ -407,17 +415,16 @@ public:
|
|
|
407
415
|
/// Get loop for fork/join site
|
|
408
416
|
const LoopBBs& getLoop(const SVFBasicBlock* bb);
|
|
409
417
|
|
|
418
|
+
/// Context helper functions
|
|
419
|
+
//@{
|
|
410
420
|
/// Push calling context
|
|
411
421
|
void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const FunObjVar* callee);
|
|
412
422
|
/// Match context
|
|
413
|
-
bool
|
|
423
|
+
bool matchAndPopCxt(CallStrCxt& cxt, const CallICFGNode* call, const FunObjVar* callee);
|
|
424
|
+
/// If lhs is a suffix of rhs, including equal
|
|
425
|
+
bool isContextSuffix(const CallStrCxt& lhs, const CallStrCxt& call);
|
|
426
|
+
//@}
|
|
414
427
|
|
|
415
|
-
inline void pushCxt(CallStrCxt& cxt, CallSiteID csId)
|
|
416
|
-
{
|
|
417
|
-
cxt.push_back(csId);
|
|
418
|
-
if (cxt.size() > MaxCxtSize)
|
|
419
|
-
MaxCxtSize = cxt.size();
|
|
420
|
-
}
|
|
421
428
|
/// Whether a join site is in recursion
|
|
422
429
|
inline bool isJoinSiteInRecursion(const CallICFGNode* join) const
|
|
423
430
|
{
|
|
@@ -504,7 +511,7 @@ private:
|
|
|
504
511
|
|
|
505
512
|
/// Get or create a tct node based on CxtThread
|
|
506
513
|
//@{
|
|
507
|
-
inline TCTNode* getOrCreateTCTNode(const CallStrCxt& cxt, const ICFGNode* fork,const
|
|
514
|
+
inline TCTNode* getOrCreateTCTNode(const CallStrCxt& cxt, const ICFGNode* fork, const CxtThreadProc& forkSiteCtp, const FunObjVar* routine)
|
|
508
515
|
{
|
|
509
516
|
CxtThread ct(cxt,fork);
|
|
510
517
|
CxtThreadToNodeMap::const_iterator it = ctpToNodeMap.find(ct);
|
|
@@ -513,7 +520,7 @@ private:
|
|
|
513
520
|
return it->second;
|
|
514
521
|
}
|
|
515
522
|
|
|
516
|
-
addCxtOfCxtThread(
|
|
523
|
+
addCxtOfCxtThread(forkSiteCtp.getTid(), forkSiteCtp.getContext(), ct);
|
|
517
524
|
addStartRoutineOfCxtThread(routine,ct);
|
|
518
525
|
|
|
519
526
|
setMultiForkedAttrs(ct);
|
|
@@ -540,10 +547,11 @@ private:
|
|
|
540
547
|
}
|
|
541
548
|
|
|
542
549
|
/// Add context for a thread at its spawning site (fork site)
|
|
543
|
-
void addCxtOfCxtThread(const CallStrCxt& cxt, const CxtThread& ct)
|
|
550
|
+
void addCxtOfCxtThread(NodeID pTid, const CallStrCxt& cxt, const CxtThread& ct)
|
|
544
551
|
{
|
|
545
|
-
|
|
552
|
+
ctToForkCxtsMap[ct].insert(std::make_pair(pTid, cxt));
|
|
546
553
|
}
|
|
554
|
+
|
|
547
555
|
/// Add start routine function of a cxt thread
|
|
548
556
|
void addStartRoutineOfCxtThread(const FunObjVar* fun, const CxtThread& ct)
|
|
549
557
|
{
|
|
@@ -571,13 +579,6 @@ private:
|
|
|
571
579
|
return visitedCTPs.find(ctp)!=visitedCTPs.end();
|
|
572
580
|
}
|
|
573
581
|
//@}
|
|
574
|
-
/// Clean up memory
|
|
575
|
-
inline void destroy()
|
|
576
|
-
{
|
|
577
|
-
if(tcgSCC)
|
|
578
|
-
delete tcgSCC;
|
|
579
|
-
tcgSCC=nullptr;
|
|
580
|
-
}
|
|
581
582
|
|
|
582
583
|
FunSet entryFuncSet; /// Procedures that are neither called by other functions nor extern functions
|
|
583
584
|
FunSet candidateFuncSet; /// Procedures we care about during call graph traversing when creating TCT
|
|
@@ -585,7 +586,7 @@ private:
|
|
|
585
586
|
CxtThreadProcVec ctpList; /// CxtThreadProc List
|
|
586
587
|
CxtThreadProcSet visitedCTPs; /// Record all visited ctps
|
|
587
588
|
CxtThreadToNodeMap ctpToNodeMap; /// Map a ctp to its graph node
|
|
588
|
-
|
|
589
|
+
CxtThreadToForkCxtSet ctToForkCxtsMap; /// Map a CxtThread to the context at its spawning site (fork site).
|
|
589
590
|
CxtThreadToFun ctToRoutineFunMap; /// Map a CxtThread to its start routine function.
|
|
590
591
|
InstToLoopMap joinSiteToLoopMap; ///< map an inloop join to its loop class
|
|
591
592
|
Set<const ICFGNode*> inRecurJoinSites; ///< Fork or Join sites in recursions
|
|
Binary file
|
|
@@ -614,79 +614,79 @@ private:
|
|
|
614
614
|
|
|
615
615
|
|
|
616
616
|
/// Add a memory obj node
|
|
617
|
-
inline NodeID addObjNode(NodeID i, ObjTypeInfo* ti, const
|
|
617
|
+
inline NodeID addObjNode(NodeID i, ObjTypeInfo* ti, const ICFGNode* node)
|
|
618
618
|
{
|
|
619
|
-
return addFIObjNode( i, ti,
|
|
619
|
+
return addFIObjNode( i, ti, node);
|
|
620
620
|
}
|
|
621
621
|
|
|
622
622
|
/**
|
|
623
623
|
* Creates and adds a heap object node to the SVFIR
|
|
624
624
|
*/
|
|
625
|
-
inline NodeID addHeapObjNode(NodeID i, ObjTypeInfo* ti, const
|
|
625
|
+
inline NodeID addHeapObjNode(NodeID i, ObjTypeInfo* ti, const ICFGNode* node)
|
|
626
626
|
{
|
|
627
627
|
memToFieldsMap[i].set(i);
|
|
628
|
-
HeapObjVar *heapObj = new HeapObjVar(i, ti,
|
|
628
|
+
HeapObjVar *heapObj = new HeapObjVar(i, ti, node);
|
|
629
629
|
return addObjNode(heapObj);
|
|
630
630
|
}
|
|
631
631
|
|
|
632
632
|
/**
|
|
633
633
|
* Creates and adds a stack object node to the SVFIR
|
|
634
634
|
*/
|
|
635
|
-
inline NodeID addStackObjNode(NodeID i, ObjTypeInfo* ti, const
|
|
635
|
+
inline NodeID addStackObjNode(NodeID i, ObjTypeInfo* ti, const ICFGNode* node)
|
|
636
636
|
{
|
|
637
637
|
memToFieldsMap[i].set(i);
|
|
638
|
-
StackObjVar *stackObj = new StackObjVar(i, ti,
|
|
638
|
+
StackObjVar *stackObj = new StackObjVar(i, ti, node);
|
|
639
639
|
return addObjNode(stackObj);
|
|
640
640
|
}
|
|
641
641
|
|
|
642
|
-
NodeID addFunObjNode(NodeID id, ObjTypeInfo* ti, const
|
|
642
|
+
NodeID addFunObjNode(NodeID id, ObjTypeInfo* ti, const ICFGNode* node)
|
|
643
643
|
{
|
|
644
644
|
memToFieldsMap[id].set(id);
|
|
645
|
-
FunObjVar* funObj = new FunObjVar(id, ti,
|
|
645
|
+
FunObjVar* funObj = new FunObjVar(id, ti, node);
|
|
646
646
|
return addObjNode(funObj);
|
|
647
647
|
}
|
|
648
648
|
|
|
649
649
|
|
|
650
|
-
inline NodeID addConstantFPObjNode(NodeID i, ObjTypeInfo* ti, double dval, const
|
|
650
|
+
inline NodeID addConstantFPObjNode(NodeID i, ObjTypeInfo* ti, double dval, const ICFGNode* node)
|
|
651
651
|
{
|
|
652
652
|
memToFieldsMap[i].set(i);
|
|
653
|
-
ConstFPObjVar* conObj = new ConstFPObjVar(i, dval, ti,
|
|
653
|
+
ConstFPObjVar* conObj = new ConstFPObjVar(i, dval, ti, node);
|
|
654
654
|
return addObjNode(conObj);
|
|
655
655
|
}
|
|
656
656
|
|
|
657
657
|
|
|
658
|
-
inline NodeID addConstantIntObjNode(NodeID i, ObjTypeInfo* ti, const std::pair<s64_t, u64_t>& intValue, const
|
|
658
|
+
inline NodeID addConstantIntObjNode(NodeID i, ObjTypeInfo* ti, const std::pair<s64_t, u64_t>& intValue, const ICFGNode* node)
|
|
659
659
|
{
|
|
660
660
|
memToFieldsMap[i].set(i);
|
|
661
661
|
ConstIntObjVar* conObj =
|
|
662
|
-
new ConstIntObjVar(i, intValue.first, intValue.second, ti,
|
|
662
|
+
new ConstIntObjVar(i, intValue.first, intValue.second, ti, node);
|
|
663
663
|
return addObjNode(conObj);
|
|
664
664
|
}
|
|
665
665
|
|
|
666
666
|
|
|
667
|
-
inline NodeID addConstantNullPtrObjNode(const NodeID i, ObjTypeInfo* ti, const
|
|
667
|
+
inline NodeID addConstantNullPtrObjNode(const NodeID i, ObjTypeInfo* ti, const ICFGNode* node)
|
|
668
668
|
{
|
|
669
669
|
memToFieldsMap[i].set(i);
|
|
670
|
-
ConstNullPtrObjVar* conObj = new ConstNullPtrObjVar(i, ti,
|
|
670
|
+
ConstNullPtrObjVar* conObj = new ConstNullPtrObjVar(i, ti, node);
|
|
671
671
|
return addObjNode(conObj);
|
|
672
672
|
}
|
|
673
673
|
|
|
674
|
-
inline NodeID addGlobalObjNode(const NodeID i, ObjTypeInfo* ti, const
|
|
674
|
+
inline NodeID addGlobalObjNode(const NodeID i, ObjTypeInfo* ti, const ICFGNode* node)
|
|
675
675
|
{
|
|
676
676
|
memToFieldsMap[i].set(i);
|
|
677
|
-
GlobalObjVar* gObj = new GlobalObjVar(i, ti,
|
|
677
|
+
GlobalObjVar* gObj = new GlobalObjVar(i, ti, node);
|
|
678
678
|
return addObjNode(gObj);
|
|
679
679
|
}
|
|
680
|
-
inline NodeID addConstantAggObjNode(const NodeID i, ObjTypeInfo* ti, const
|
|
680
|
+
inline NodeID addConstantAggObjNode(const NodeID i, ObjTypeInfo* ti, const ICFGNode* node)
|
|
681
681
|
{
|
|
682
682
|
memToFieldsMap[i].set(i);
|
|
683
|
-
ConstAggObjVar* conObj = new ConstAggObjVar(i, ti,
|
|
683
|
+
ConstAggObjVar* conObj = new ConstAggObjVar(i, ti, node);
|
|
684
684
|
return addObjNode(conObj);
|
|
685
685
|
}
|
|
686
|
-
inline NodeID addConstantDataObjNode(const NodeID i, ObjTypeInfo* ti, const
|
|
686
|
+
inline NodeID addConstantDataObjNode(const NodeID i, ObjTypeInfo* ti, const ICFGNode* node)
|
|
687
687
|
{
|
|
688
688
|
memToFieldsMap[i].set(i);
|
|
689
|
-
ConstDataObjVar* conObj = new ConstDataObjVar(i, ti,
|
|
689
|
+
ConstDataObjVar* conObj = new ConstDataObjVar(i, ti, node);
|
|
690
690
|
return addObjNode(conObj);
|
|
691
691
|
}
|
|
692
692
|
|
|
@@ -708,10 +708,10 @@ private:
|
|
|
708
708
|
/// Add a field obj node, this method can only invoked by getGepObjVar
|
|
709
709
|
NodeID addGepObjNode(const BaseObjVar* baseObj, const APOffset& apOffset, const NodeID gepId);
|
|
710
710
|
/// Add a field-insensitive node, this method can only invoked by getFIGepObjNode
|
|
711
|
-
NodeID addFIObjNode(NodeID i, ObjTypeInfo* ti, const
|
|
711
|
+
NodeID addFIObjNode(NodeID i, ObjTypeInfo* ti, const ICFGNode* node)
|
|
712
712
|
{
|
|
713
713
|
memToFieldsMap[i].set(i);
|
|
714
|
-
BaseObjVar* baseObj = new BaseObjVar(i, ti,
|
|
714
|
+
BaseObjVar* baseObj = new BaseObjVar(i, ti, node);
|
|
715
715
|
return addObjNode(baseObj);
|
|
716
716
|
}
|
|
717
717
|
|
|
@@ -730,11 +730,11 @@ private:
|
|
|
730
730
|
{
|
|
731
731
|
ObjTypeInfo* ti = createObjTypeInfo(type);
|
|
732
732
|
idToObjTypeInfoMap()[i] = ti;
|
|
733
|
-
return addObjNode(new DummyObjVar(i, ti, nullptr
|
|
733
|
+
return addObjNode(new DummyObjVar(i, ti, nullptr));
|
|
734
734
|
}
|
|
735
735
|
else
|
|
736
736
|
{
|
|
737
|
-
return addObjNode(new DummyObjVar(i, getObjTypeInfo(i), nullptr
|
|
737
|
+
return addObjNode(new DummyObjVar(i, getObjTypeInfo(i), nullptr));
|
|
738
738
|
}
|
|
739
739
|
}
|
|
740
740
|
|
|
@@ -129,7 +129,7 @@ public:
|
|
|
129
129
|
return edgeId;
|
|
130
130
|
}
|
|
131
131
|
/// Whether src and dst nodes are both of pointer type
|
|
132
|
-
bool isPTAEdge() const;
|
|
132
|
+
virtual bool isPTAEdge() const;
|
|
133
133
|
|
|
134
134
|
/// Get/set methods for llvm instruction
|
|
135
135
|
//@{
|
|
@@ -343,6 +343,10 @@ public:
|
|
|
343
343
|
return arrSize;
|
|
344
344
|
}
|
|
345
345
|
|
|
346
|
+
virtual bool isPTAEdge() const override
|
|
347
|
+
{
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
346
350
|
};
|
|
347
351
|
|
|
348
352
|
/*!
|
|
@@ -533,9 +533,8 @@ public:
|
|
|
533
533
|
//@}
|
|
534
534
|
|
|
535
535
|
/// Constructor
|
|
536
|
-
BaseObjVar(NodeID i, ObjTypeInfo* ti,
|
|
537
|
-
|
|
538
|
-
: ObjVar(i, svfType, ty), typeInfo(ti), icfgNode(node)
|
|
536
|
+
BaseObjVar(NodeID i, ObjTypeInfo* ti, const ICFGNode* node, PNODEK ty = BaseObjNode)
|
|
537
|
+
: ObjVar(i, ti->getType(), ty), typeInfo(ti), icfgNode(node)
|
|
539
538
|
{
|
|
540
539
|
}
|
|
541
540
|
|
|
@@ -564,12 +563,6 @@ public:
|
|
|
564
563
|
return id;
|
|
565
564
|
}
|
|
566
565
|
|
|
567
|
-
/// Get obj type
|
|
568
|
-
const SVFType* getType() const
|
|
569
|
-
{
|
|
570
|
-
return typeInfo->getType();
|
|
571
|
-
}
|
|
572
|
-
|
|
573
566
|
/// Get the number of elements of this object
|
|
574
567
|
u32_t getNumOfElements() const
|
|
575
568
|
{
|
|
@@ -832,8 +825,8 @@ public:
|
|
|
832
825
|
//@}
|
|
833
826
|
|
|
834
827
|
/// Constructor
|
|
835
|
-
HeapObjVar(NodeID i, ObjTypeInfo* ti, const
|
|
836
|
-
BaseObjVar(i, ti,
|
|
828
|
+
HeapObjVar(NodeID i, ObjTypeInfo* ti, const ICFGNode* node):
|
|
829
|
+
BaseObjVar(i, ti, node, HeapObjNode)
|
|
837
830
|
{
|
|
838
831
|
}
|
|
839
832
|
|
|
@@ -888,8 +881,8 @@ public:
|
|
|
888
881
|
//@}
|
|
889
882
|
|
|
890
883
|
/// Constructor
|
|
891
|
-
StackObjVar(NodeID i, ObjTypeInfo* ti, const
|
|
892
|
-
BaseObjVar(i, ti,
|
|
884
|
+
StackObjVar(NodeID i, ObjTypeInfo* ti, const ICFGNode* node):
|
|
885
|
+
BaseObjVar(i, ti, node, StackObjNode)
|
|
893
886
|
{
|
|
894
887
|
}
|
|
895
888
|
|
|
@@ -962,7 +955,7 @@ public:
|
|
|
962
955
|
//@}
|
|
963
956
|
|
|
964
957
|
/// Constructor
|
|
965
|
-
FunObjVar(NodeID i, ObjTypeInfo* ti, const
|
|
958
|
+
FunObjVar(NodeID i, ObjTypeInfo* ti, const ICFGNode* node);
|
|
966
959
|
|
|
967
960
|
|
|
968
961
|
virtual ~FunObjVar()
|
|
@@ -1599,8 +1592,8 @@ public:
|
|
|
1599
1592
|
//@}
|
|
1600
1593
|
|
|
1601
1594
|
/// Constructor
|
|
1602
|
-
GlobalObjVar(NodeID i, ObjTypeInfo* ti, const
|
|
1603
|
-
PNODEK ty = GlobalObjNode): BaseObjVar(i, ti,
|
|
1595
|
+
GlobalObjVar(NodeID i, ObjTypeInfo* ti, const ICFGNode* node,
|
|
1596
|
+
PNODEK ty = GlobalObjNode): BaseObjVar(i, ti, node, ty)
|
|
1604
1597
|
{
|
|
1605
1598
|
|
|
1606
1599
|
}
|
|
@@ -1643,8 +1636,8 @@ public:
|
|
|
1643
1636
|
//@}
|
|
1644
1637
|
|
|
1645
1638
|
/// Constructor
|
|
1646
|
-
ConstAggObjVar(NodeID i, ObjTypeInfo* ti, const
|
|
1647
|
-
: BaseObjVar(i, ti,
|
|
1639
|
+
ConstAggObjVar(NodeID i, ObjTypeInfo* ti, const ICFGNode* node)
|
|
1640
|
+
: BaseObjVar(i, ti, node, ConstAggObjNode)
|
|
1648
1641
|
{
|
|
1649
1642
|
|
|
1650
1643
|
}
|
|
@@ -1695,8 +1688,8 @@ public:
|
|
|
1695
1688
|
//@}
|
|
1696
1689
|
|
|
1697
1690
|
/// Constructor
|
|
1698
|
-
ConstDataObjVar(NodeID i, ObjTypeInfo* ti, const
|
|
1699
|
-
: BaseObjVar(i, ti,
|
|
1691
|
+
ConstDataObjVar(NodeID i, ObjTypeInfo* ti, const ICFGNode* node, PNODEK ty = ConstDataObjNode)
|
|
1692
|
+
: BaseObjVar(i, ti, node, ty)
|
|
1700
1693
|
{
|
|
1701
1694
|
}
|
|
1702
1695
|
|
|
@@ -1756,8 +1749,8 @@ public:
|
|
|
1756
1749
|
//@}
|
|
1757
1750
|
|
|
1758
1751
|
/// Constructor
|
|
1759
|
-
ConstFPObjVar(NodeID i, double dv, ObjTypeInfo* ti, const
|
|
1760
|
-
: ConstDataObjVar(i, ti,
|
|
1752
|
+
ConstFPObjVar(NodeID i, double dv, ObjTypeInfo* ti, const ICFGNode* node)
|
|
1753
|
+
: ConstDataObjVar(i, ti, node, ConstFPObjNode), dval(dv)
|
|
1761
1754
|
{
|
|
1762
1755
|
}
|
|
1763
1756
|
|
|
@@ -1825,12 +1818,11 @@ public:
|
|
|
1825
1818
|
//@}
|
|
1826
1819
|
|
|
1827
1820
|
/// Constructor
|
|
1828
|
-
ConstIntObjVar(NodeID i, s64_t sv, u64_t zv, ObjTypeInfo* ti, const
|
|
1829
|
-
: ConstDataObjVar(i, ti,
|
|
1821
|
+
ConstIntObjVar(NodeID i, s64_t sv, u64_t zv, ObjTypeInfo* ti, const ICFGNode* node)
|
|
1822
|
+
: ConstDataObjVar(i, ti, node, ConstIntObjNode), zval(zv), sval(sv)
|
|
1830
1823
|
{
|
|
1831
1824
|
}
|
|
1832
1825
|
|
|
1833
|
-
|
|
1834
1826
|
virtual const std::string toString() const;
|
|
1835
1827
|
};
|
|
1836
1828
|
|
|
@@ -1874,8 +1866,8 @@ public:
|
|
|
1874
1866
|
//@}
|
|
1875
1867
|
|
|
1876
1868
|
/// Constructor
|
|
1877
|
-
ConstNullPtrObjVar(NodeID i, ObjTypeInfo* ti, const
|
|
1878
|
-
: ConstDataObjVar(i, ti,
|
|
1869
|
+
ConstNullPtrObjVar(NodeID i, ObjTypeInfo* ti, const ICFGNode* node)
|
|
1870
|
+
: ConstDataObjVar(i, ti, node, ConstNullptrObjNode)
|
|
1879
1871
|
{
|
|
1880
1872
|
}
|
|
1881
1873
|
virtual bool isConstDataOrAggDataButNotNullPtr() const
|
|
@@ -2073,8 +2065,8 @@ public:
|
|
|
2073
2065
|
//@}
|
|
2074
2066
|
|
|
2075
2067
|
/// Constructor
|
|
2076
|
-
DummyObjVar(NodeID i, ObjTypeInfo* ti, const ICFGNode* node
|
|
2077
|
-
: BaseObjVar(i, ti,
|
|
2068
|
+
DummyObjVar(NodeID i, ObjTypeInfo* ti, const ICFGNode* node)
|
|
2069
|
+
: BaseObjVar(i, ti, node, DummyObjNode)
|
|
2078
2070
|
{
|
|
2079
2071
|
}
|
|
2080
2072
|
|
|
Binary file
|
|
Binary file
|