svf-tools 1.0.985 → 1.0.986
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/Graphs/ICFGNode.h +1 -1
- package/svf/include/MTA/LockAnalysis.h +9 -3
- package/svf/include/MTA/MHP.h +10 -6
- package/svf/include/MTA/TCT.h +3 -3
- package/svf/include/SABER/SaberCheckerAPI.h +4 -4
- package/svf/include/Util/SVFUtil.h +12 -49
- package/svf/include/Util/ThreadAPI.h +10 -33
- package/svf/lib/AE/Svfexe/AEDetector.cpp +11 -14
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +8 -13
- package/svf/lib/CFL/CFLAlias.cpp +1 -1
- package/svf/lib/Graphs/CallGraph.cpp +2 -2
- package/svf/lib/MTA/LockAnalysis.cpp +2 -2
- package/svf/lib/MTA/MHP.cpp +9 -7
- package/svf/lib/MemoryModel/PointerAnalysis.cpp +2 -2
- package/svf/lib/SABER/DoubleFreeChecker.cpp +1 -1
- package/svf/lib/SABER/LeakChecker.cpp +1 -1
- package/svf/lib/Util/CallGraphBuilder.cpp +4 -4
- package/svf/lib/Util/SVFBugReport.cpp +2 -1
- package/svf/lib/Util/SVFUtil.cpp +25 -10
- package/svf/lib/Util/ThreadAPI.cpp +32 -12
- package/svf/lib/WPA/Andersen.cpp +1 -1
- package/svf/lib/WPA/Steensgaard.cpp +1 -1
- package/svf-llvm/lib/ICFGBuilder.cpp +1 -1
- package/svf-llvm/lib/SymbolTableBuilder.cpp +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.986",
|
|
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": {
|
|
@@ -462,7 +462,7 @@ public:
|
|
|
462
462
|
/// Return true if this is an indirect call
|
|
463
463
|
inline bool isIndirectCall() const
|
|
464
464
|
{
|
|
465
|
-
return nullptr == SVFUtil::
|
|
465
|
+
return nullptr == SVFUtil::cast<SVFCallInst>(cs)->getCalledFunction();
|
|
466
466
|
}
|
|
467
467
|
|
|
468
468
|
/// Return the set of actual parameters
|
|
@@ -437,17 +437,23 @@ private:
|
|
|
437
437
|
/// Whether it is a lock site
|
|
438
438
|
inline bool isTDFork(const ICFGNode* call)
|
|
439
439
|
{
|
|
440
|
-
|
|
440
|
+
if(SVFUtil::isa<CallICFGNode>(call) == false)
|
|
441
|
+
return false;
|
|
442
|
+
return getTCG()->getThreadAPI()->isTDFork(SVFUtil::cast<CallICFGNode>(call));
|
|
441
443
|
}
|
|
442
444
|
/// Whether it is a lock site
|
|
443
445
|
inline bool isTDAcquire(const ICFGNode* call)
|
|
444
446
|
{
|
|
445
|
-
|
|
447
|
+
if(SVFUtil::isa<CallICFGNode>(call) == false)
|
|
448
|
+
return false;
|
|
449
|
+
return getTCG()->getThreadAPI()->isTDAcquire(SVFUtil::cast<CallICFGNode>(call));
|
|
446
450
|
}
|
|
447
451
|
/// Whether it is a unlock site
|
|
448
452
|
inline bool isTDRelease(const ICFGNode* call)
|
|
449
453
|
{
|
|
450
|
-
|
|
454
|
+
if(SVFUtil::isa<CallICFGNode>(call) == false)
|
|
455
|
+
return false;
|
|
456
|
+
return getTCG()->getThreadAPI()->isTDRelease(SVFUtil::cast<CallICFGNode>(call));
|
|
451
457
|
}
|
|
452
458
|
/// Whether it is a callsite
|
|
453
459
|
inline bool isCallSite(const ICFGNode* inst)
|
package/svf/include/MTA/MHP.h
CHANGED
|
@@ -227,12 +227,14 @@ private:
|
|
|
227
227
|
/// Whether it is a fork site
|
|
228
228
|
inline bool isTDFork(const ICFGNode* call)
|
|
229
229
|
{
|
|
230
|
-
|
|
230
|
+
const CallICFGNode* fork = SVFUtil::dyn_cast<CallICFGNode>(call);
|
|
231
|
+
return fork && tcg->getThreadAPI()->isTDFork(fork);
|
|
231
232
|
}
|
|
232
233
|
/// Whether it is a join site
|
|
233
234
|
inline bool isTDJoin(const ICFGNode* call)
|
|
234
235
|
{
|
|
235
|
-
|
|
236
|
+
const CallICFGNode* join = SVFUtil::dyn_cast<CallICFGNode>(call);
|
|
237
|
+
return join && tcg->getThreadAPI()->isTDJoin(join);
|
|
236
238
|
}
|
|
237
239
|
|
|
238
240
|
/// Return thread id(s) which are directly or indirectly joined at this join site
|
|
@@ -345,11 +347,11 @@ public:
|
|
|
345
347
|
}
|
|
346
348
|
|
|
347
349
|
/// Get loop for join site
|
|
348
|
-
inline LoopBBs& getJoinLoop(const
|
|
350
|
+
inline LoopBBs& getJoinLoop(const CallICFGNode* inst)
|
|
349
351
|
{
|
|
350
352
|
return tct->getJoinLoop(inst);
|
|
351
353
|
}
|
|
352
|
-
inline bool hasJoinLoop(const
|
|
354
|
+
inline bool hasJoinLoop(const CallICFGNode* inst)
|
|
353
355
|
{
|
|
354
356
|
return tct->hasJoinLoop(inst);
|
|
355
357
|
}
|
|
@@ -461,12 +463,14 @@ private:
|
|
|
461
463
|
/// Whether it is a fork site
|
|
462
464
|
inline bool isTDFork(const ICFGNode* call)
|
|
463
465
|
{
|
|
464
|
-
|
|
466
|
+
const CallICFGNode* fork = SVFUtil::dyn_cast<CallICFGNode>(call);
|
|
467
|
+
return fork && getTCG()->getThreadAPI()->isTDFork(fork);
|
|
465
468
|
}
|
|
466
469
|
/// Whether it is a join site
|
|
467
470
|
inline bool isTDJoin(const ICFGNode* call)
|
|
468
471
|
{
|
|
469
|
-
|
|
472
|
+
const CallICFGNode* join = SVFUtil::dyn_cast<CallICFGNode>(call);
|
|
473
|
+
return join && getTCG()->getThreadAPI()->isTDJoin(join);
|
|
470
474
|
}
|
|
471
475
|
/// Get forked thread
|
|
472
476
|
inline const SVFValue* getForkedThread(const CallICFGNode* call)
|
package/svf/include/MTA/TCT.h
CHANGED
|
@@ -364,7 +364,7 @@ public:
|
|
|
364
364
|
}
|
|
365
365
|
|
|
366
366
|
/// Get loop for join site
|
|
367
|
-
inline LoopBBs& getJoinLoop(const
|
|
367
|
+
inline LoopBBs& getJoinLoop(const CallICFGNode* join)
|
|
368
368
|
{
|
|
369
369
|
assert(tcg->getThreadAPI()->isTDJoin(join) && "not a join site");
|
|
370
370
|
InstToLoopMap::iterator it = joinSiteToLoopMap.find(join);
|
|
@@ -372,7 +372,7 @@ public:
|
|
|
372
372
|
return it->second;
|
|
373
373
|
}
|
|
374
374
|
|
|
375
|
-
inline bool hasJoinLoop(const
|
|
375
|
+
inline bool hasJoinLoop(const CallICFGNode* join) const
|
|
376
376
|
{
|
|
377
377
|
assert(tcg->getThreadAPI()->isTDJoin(join) && "not a join site");
|
|
378
378
|
InstToLoopMap::const_iterator it = joinSiteToLoopMap.find(join);
|
|
@@ -407,7 +407,7 @@ public:
|
|
|
407
407
|
MaxCxtSize = cxt.size();
|
|
408
408
|
}
|
|
409
409
|
/// Whether a join site is in recursion
|
|
410
|
-
inline bool isJoinSiteInRecursion(const
|
|
410
|
+
inline bool isJoinSiteInRecursion(const CallICFGNode* join) const
|
|
411
411
|
{
|
|
412
412
|
assert(tcg->getThreadAPI()->isTDJoin(join) && "not a join site");
|
|
413
413
|
return inRecurJoinSites.find(join)!=inRecurJoinSites.end();
|
|
@@ -103,7 +103,7 @@ public:
|
|
|
103
103
|
}
|
|
104
104
|
inline bool isMemAlloc(const CallICFGNode* cs) const
|
|
105
105
|
{
|
|
106
|
-
return isMemAlloc(
|
|
106
|
+
return isMemAlloc(cs->getCalledFunction());
|
|
107
107
|
}
|
|
108
108
|
//@}
|
|
109
109
|
|
|
@@ -115,7 +115,7 @@ public:
|
|
|
115
115
|
}
|
|
116
116
|
inline bool isMemDealloc(const CallICFGNode* cs) const
|
|
117
117
|
{
|
|
118
|
-
return isMemDealloc(
|
|
118
|
+
return isMemDealloc(cs->getCalledFunction());
|
|
119
119
|
}
|
|
120
120
|
//@}
|
|
121
121
|
|
|
@@ -127,7 +127,7 @@ public:
|
|
|
127
127
|
}
|
|
128
128
|
inline bool isFOpen(const CallICFGNode* cs) const
|
|
129
129
|
{
|
|
130
|
-
return isFOpen(
|
|
130
|
+
return isFOpen(cs->getCalledFunction());
|
|
131
131
|
}
|
|
132
132
|
//@}
|
|
133
133
|
|
|
@@ -139,7 +139,7 @@ public:
|
|
|
139
139
|
}
|
|
140
140
|
inline bool isFClose(const CallICFGNode* cs) const
|
|
141
141
|
{
|
|
142
|
-
return isFClose(
|
|
142
|
+
return isFClose(cs->getCalledFunction());
|
|
143
143
|
}
|
|
144
144
|
//@}
|
|
145
145
|
|
|
@@ -228,25 +228,6 @@ inline std::vector<std::string> split(const std::string& s, char separator)
|
|
|
228
228
|
return output;
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
-
/// Return callee of a callsite. Return null if this is an indirect call
|
|
232
|
-
//@{
|
|
233
|
-
inline const SVFFunction* getCallee(const SVFCallInst* cs)
|
|
234
|
-
{
|
|
235
|
-
return cs->getCalledFunction();
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
inline const SVFFunction* getCallee(const SVFInstruction *inst)
|
|
239
|
-
{
|
|
240
|
-
if (!isCallSite(inst))
|
|
241
|
-
return nullptr;
|
|
242
|
-
return getCallee(cast<SVFCallInst>(inst));
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
const SVFFunction* getCallee(const CallICFGNode *inst);
|
|
246
|
-
|
|
247
|
-
const SVFFunction* getCallee(const ICFGNode *inst);
|
|
248
|
-
//@}
|
|
249
|
-
|
|
250
231
|
/// Given a map mapping points-to sets to a count, adds from into to.
|
|
251
232
|
template <typename Data>
|
|
252
233
|
void mergePtsOccMaps(Map<Data, unsigned> &to, const Map<Data, unsigned> from)
|
|
@@ -332,7 +313,7 @@ inline bool isHeapAllocExtFunViaArg(const SVFFunction* fun)
|
|
|
332
313
|
|
|
333
314
|
/// Get the position of argument that holds an allocated heap object.
|
|
334
315
|
//@{
|
|
335
|
-
inline
|
|
316
|
+
inline u32_t getHeapAllocHoldingArgPosition(const SVFFunction* fun)
|
|
336
317
|
{
|
|
337
318
|
return ExtAPI::getExtAPI()->get_alloc_arg_pos(fun);
|
|
338
319
|
}
|
|
@@ -404,25 +385,13 @@ inline const SVFValue* getForkedFun(const CallICFGNode *inst)
|
|
|
404
385
|
//@}
|
|
405
386
|
|
|
406
387
|
|
|
407
|
-
|
|
408
|
-
{
|
|
409
|
-
return isExtCall(getCallee(cs));
|
|
410
|
-
}
|
|
388
|
+
bool isExtCall(const CallICFGNode* cs);
|
|
411
389
|
|
|
412
390
|
bool isExtCall(const ICFGNode* node);
|
|
413
391
|
|
|
414
|
-
|
|
415
|
-
{
|
|
416
|
-
return isHeapAllocExtFunViaArg(getCallee(cs));
|
|
417
|
-
}
|
|
392
|
+
bool isHeapAllocExtCallViaArg(const CallICFGNode* cs);
|
|
418
393
|
|
|
419
|
-
|
|
420
|
-
{
|
|
421
|
-
if(const SVFCallInst* call = SVFUtil::dyn_cast<SVFCallInst>(inst))
|
|
422
|
-
return isHeapAllocExtFunViaArg(call->getCalledFunction());
|
|
423
|
-
else
|
|
424
|
-
return false;
|
|
425
|
-
}
|
|
394
|
+
bool isHeapAllocExtCallViaArg(const SVFInstruction *inst);
|
|
426
395
|
|
|
427
396
|
bool isHeapAllocExtCallViaRet(const SVFInstruction *inst);
|
|
428
397
|
|
|
@@ -438,10 +407,7 @@ inline bool isHeapAllocExtCall(const SVFInstruction *inst)
|
|
|
438
407
|
|
|
439
408
|
//@}
|
|
440
409
|
|
|
441
|
-
|
|
442
|
-
{
|
|
443
|
-
return getHeapAllocHoldingArgPosition(getCallee(cs));
|
|
444
|
-
}
|
|
410
|
+
u32_t getHeapAllocHoldingArgPosition(const CallICFGNode* cs);
|
|
445
411
|
//@}
|
|
446
412
|
|
|
447
413
|
bool isReallocExtCall(const CallICFGNode* cs);
|
|
@@ -449,7 +415,7 @@ bool isReallocExtCall(const CallICFGNode* cs);
|
|
|
449
415
|
|
|
450
416
|
/// Return true if this is a thread creation call
|
|
451
417
|
///@{
|
|
452
|
-
inline bool isThreadForkCall(const
|
|
418
|
+
inline bool isThreadForkCall(const CallICFGNode *inst)
|
|
453
419
|
{
|
|
454
420
|
return ThreadAPI::getThreadAPI()->isTDFork(inst);
|
|
455
421
|
}
|
|
@@ -457,7 +423,7 @@ inline bool isThreadForkCall(const ICFGNode *inst)
|
|
|
457
423
|
|
|
458
424
|
/// Return true if this is a thread join call
|
|
459
425
|
///@{
|
|
460
|
-
inline bool isThreadJoinCall(const
|
|
426
|
+
inline bool isThreadJoinCall(const CallICFGNode* cs)
|
|
461
427
|
{
|
|
462
428
|
return ThreadAPI::getThreadAPI()->isTDJoin(cs);
|
|
463
429
|
}
|
|
@@ -465,7 +431,7 @@ inline bool isThreadJoinCall(const ICFGNode* cs)
|
|
|
465
431
|
|
|
466
432
|
/// Return true if this is a thread exit call
|
|
467
433
|
///@{
|
|
468
|
-
inline bool isThreadExitCall(const
|
|
434
|
+
inline bool isThreadExitCall(const CallICFGNode* cs)
|
|
469
435
|
{
|
|
470
436
|
return ThreadAPI::getThreadAPI()->isTDExit(cs);
|
|
471
437
|
}
|
|
@@ -473,7 +439,7 @@ inline bool isThreadExitCall(const ICFGNode* cs)
|
|
|
473
439
|
|
|
474
440
|
/// Return true if this is a lock acquire call
|
|
475
441
|
///@{
|
|
476
|
-
inline bool isLockAquireCall(const
|
|
442
|
+
inline bool isLockAquireCall(const CallICFGNode* cs)
|
|
477
443
|
{
|
|
478
444
|
return ThreadAPI::getThreadAPI()->isTDAcquire(cs);
|
|
479
445
|
}
|
|
@@ -481,7 +447,7 @@ inline bool isLockAquireCall(const ICFGNode* cs)
|
|
|
481
447
|
|
|
482
448
|
/// Return true if this is a lock acquire call
|
|
483
449
|
///@{
|
|
484
|
-
inline bool isLockReleaseCall(const
|
|
450
|
+
inline bool isLockReleaseCall(const CallICFGNode* cs)
|
|
485
451
|
{
|
|
486
452
|
return ThreadAPI::getThreadAPI()->isTDRelease(cs);
|
|
487
453
|
}
|
|
@@ -489,7 +455,7 @@ inline bool isLockReleaseCall(const ICFGNode* cs)
|
|
|
489
455
|
|
|
490
456
|
/// Return true if this is a barrier wait call
|
|
491
457
|
//@{
|
|
492
|
-
inline bool isBarrierWaitCall(const
|
|
458
|
+
inline bool isBarrierWaitCall(const CallICFGNode* cs)
|
|
493
459
|
{
|
|
494
460
|
return ThreadAPI::getThreadAPI()->isTDBarWait(cs);
|
|
495
461
|
}
|
|
@@ -504,10 +470,7 @@ inline const SVFValue* getActualParmAtForkSite(const CallICFGNode* cs)
|
|
|
504
470
|
//@}
|
|
505
471
|
|
|
506
472
|
|
|
507
|
-
|
|
508
|
-
{
|
|
509
|
-
return isProgExitFunction(getCallee(cs));
|
|
510
|
-
}
|
|
473
|
+
bool isProgExitCall(const CallICFGNode* cs);
|
|
511
474
|
|
|
512
475
|
|
|
513
476
|
template<typename T>
|
|
@@ -119,19 +119,6 @@ public:
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
/// Return the callee/callsite/func
|
|
123
|
-
//@{
|
|
124
|
-
const SVFFunction* getCallee(const ICFGNode *inst) const;
|
|
125
|
-
//@}
|
|
126
|
-
|
|
127
|
-
/// Return true if this call create a new thread
|
|
128
|
-
//@{
|
|
129
|
-
inline bool isTDFork(const ICFGNode *inst) const
|
|
130
|
-
{
|
|
131
|
-
return getType(getCallee(inst)) == TD_FORK;
|
|
132
|
-
}
|
|
133
|
-
//@}
|
|
134
|
-
|
|
135
122
|
/// Return arguments/attributes of pthread_create / hare_parallel_for
|
|
136
123
|
//@{
|
|
137
124
|
/// Return the first argument of the call,
|
|
@@ -146,12 +133,14 @@ public:
|
|
|
146
133
|
const SVFValue* getActualParmAtForkSite(const CallICFGNode *inst) const;
|
|
147
134
|
//@}
|
|
148
135
|
|
|
136
|
+
/// Return true if this call create a new thread
|
|
137
|
+
//@{
|
|
138
|
+
bool isTDFork(const CallICFGNode *inst) const;
|
|
139
|
+
//@}
|
|
140
|
+
|
|
149
141
|
/// Return true if this call wait for a worker thread
|
|
150
142
|
//@{
|
|
151
|
-
|
|
152
|
-
{
|
|
153
|
-
return getType(getCallee(inst)) == TD_JOIN;
|
|
154
|
-
}
|
|
143
|
+
bool isTDJoin(const CallICFGNode *inst) const;
|
|
155
144
|
//@}
|
|
156
145
|
|
|
157
146
|
/// Return arguments/attributes of pthread_join
|
|
@@ -167,26 +156,17 @@ public:
|
|
|
167
156
|
|
|
168
157
|
/// Return true if this call exits/terminate a thread
|
|
169
158
|
//@{
|
|
170
|
-
|
|
171
|
-
{
|
|
172
|
-
return getType(getCallee(inst)) == TD_EXIT;
|
|
173
|
-
}
|
|
159
|
+
bool isTDExit(const CallICFGNode *inst) const;
|
|
174
160
|
//@}
|
|
175
161
|
|
|
176
162
|
/// Return true if this call acquire a lock
|
|
177
163
|
//@{
|
|
178
|
-
|
|
179
|
-
{
|
|
180
|
-
return getType(getCallee(inst)) == TD_ACQUIRE;
|
|
181
|
-
}
|
|
164
|
+
bool isTDAcquire(const CallICFGNode* inst) const;
|
|
182
165
|
//@}
|
|
183
166
|
|
|
184
167
|
/// Return true if this call release a lock
|
|
185
168
|
//@{
|
|
186
|
-
|
|
187
|
-
{
|
|
188
|
-
return getType(getCallee(inst)) == TD_RELEASE;
|
|
189
|
-
}
|
|
169
|
+
bool isTDRelease(const CallICFGNode *inst) const;
|
|
190
170
|
//@}
|
|
191
171
|
|
|
192
172
|
/// Return lock value
|
|
@@ -197,10 +177,7 @@ public:
|
|
|
197
177
|
|
|
198
178
|
/// Return true if this call waits for a barrier
|
|
199
179
|
//@{
|
|
200
|
-
|
|
201
|
-
{
|
|
202
|
-
return getType(getCallee(inst)) == TD_BAR_WAIT;
|
|
203
|
-
}
|
|
180
|
+
bool isTDBarWait(const CallICFGNode *inst) const;
|
|
204
181
|
//@}
|
|
205
182
|
|
|
206
183
|
void performAPIStat(SVFModule* m);
|
|
@@ -94,8 +94,7 @@ void BufOverflowDetector::detect(AbstractState& as, const ICFGNode* node)
|
|
|
94
94
|
{
|
|
95
95
|
// Handle call nodes by checking for external API calls
|
|
96
96
|
const CallICFGNode* callNode = SVFUtil::cast<CallICFGNode>(node);
|
|
97
|
-
|
|
98
|
-
if (SVFUtil::isExtCall(callfun))
|
|
97
|
+
if (SVFUtil::isExtCall(callNode->getCalledFunction()))
|
|
99
98
|
{
|
|
100
99
|
detectExtAPI(as, callNode);
|
|
101
100
|
}
|
|
@@ -146,13 +145,12 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
|
|
|
146
145
|
const CallICFGNode* call)
|
|
147
146
|
{
|
|
148
147
|
SVFIR* svfir = PAG::getPAG();
|
|
149
|
-
|
|
150
|
-
assert(fun && "SVFFunction* is nullptr");
|
|
148
|
+
assert(call->getCalledFunction() && "SVFFunction* is nullptr");
|
|
151
149
|
|
|
152
150
|
AbstractInterpretation::ExtAPIType extType = AbstractInterpretation::UNCLASSIFIED;
|
|
153
151
|
|
|
154
152
|
// Determine the type of external memory API
|
|
155
|
-
for (const std::string &annotation :
|
|
153
|
+
for (const std::string &annotation : call->getCalledFunction()->getAnnotations())
|
|
156
154
|
{
|
|
157
155
|
if (annotation.find("MEMCPY") != std::string::npos)
|
|
158
156
|
extType = AbstractInterpretation::MEMCPY;
|
|
@@ -167,13 +165,13 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
|
|
|
167
165
|
// Apply buffer overflow checks based on the determined API type
|
|
168
166
|
if (extType == AbstractInterpretation::MEMCPY)
|
|
169
167
|
{
|
|
170
|
-
if (extAPIBufOverflowCheckRules.count(
|
|
168
|
+
if (extAPIBufOverflowCheckRules.count(call->getCalledFunction()->getName()) == 0)
|
|
171
169
|
{
|
|
172
|
-
SVFUtil::errs() << "Warning: " <<
|
|
170
|
+
SVFUtil::errs() << "Warning: " << call->getCalledFunction()->getName() << " is not in the rules, please implement it\n";
|
|
173
171
|
return;
|
|
174
172
|
}
|
|
175
173
|
std::vector<std::pair<u32_t, u32_t>> args =
|
|
176
|
-
extAPIBufOverflowCheckRules.at(
|
|
174
|
+
extAPIBufOverflowCheckRules.at(call->getCalledFunction()->getName());
|
|
177
175
|
for (auto arg : args)
|
|
178
176
|
{
|
|
179
177
|
IntervalValue offset = as[svfir->getValueNode(call->getArgument(arg.second))].getInterval() - IntervalValue(1);
|
|
@@ -186,13 +184,13 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
|
|
|
186
184
|
}
|
|
187
185
|
else if (extType == AbstractInterpretation::MEMSET)
|
|
188
186
|
{
|
|
189
|
-
if (extAPIBufOverflowCheckRules.count(
|
|
187
|
+
if (extAPIBufOverflowCheckRules.count(call->getCalledFunction()->getName()) == 0)
|
|
190
188
|
{
|
|
191
|
-
SVFUtil::errs() << "Warning: " <<
|
|
189
|
+
SVFUtil::errs() << "Warning: " << call->getCalledFunction()->getName() << " is not in the rules, please implement it\n";
|
|
192
190
|
return;
|
|
193
191
|
}
|
|
194
192
|
std::vector<std::pair<u32_t, u32_t>> args =
|
|
195
|
-
extAPIBufOverflowCheckRules.at(
|
|
193
|
+
extAPIBufOverflowCheckRules.at(call->getCalledFunction()->getName());
|
|
196
194
|
for (auto arg : args)
|
|
197
195
|
{
|
|
198
196
|
IntervalValue offset = as[svfir->getValueNode(call->getArgument(arg.second))].getInterval() - IntervalValue(1);
|
|
@@ -340,12 +338,11 @@ bool BufOverflowDetector::detectStrcpy(AbstractState& as, const CallICFGNode *ca
|
|
|
340
338
|
bool BufOverflowDetector::detectStrcat(AbstractState& as, const CallICFGNode *call)
|
|
341
339
|
{
|
|
342
340
|
SVFIR* svfir = PAG::getPAG();
|
|
343
|
-
const SVFFunction *fun = SVFUtil::getCallee(call->getCallSite());
|
|
344
341
|
|
|
345
342
|
const std::vector<std::string> strcatGroup = {"__strcat_chk", "strcat", "__wcscat_chk", "wcscat"};
|
|
346
343
|
const std::vector<std::string> strncatGroup = {"__strncat_chk", "strncat", "__wcsncat_chk", "wcsncat"};
|
|
347
344
|
|
|
348
|
-
if (std::find(strcatGroup.begin(), strcatGroup.end(),
|
|
345
|
+
if (std::find(strcatGroup.begin(), strcatGroup.end(), call->getCalledFunction()->getName()) != strcatGroup.end())
|
|
349
346
|
{
|
|
350
347
|
const SVFValue* arg0Val = call->getArgument(0);
|
|
351
348
|
const SVFValue* arg1Val = call->getArgument(1);
|
|
@@ -354,7 +351,7 @@ bool BufOverflowDetector::detectStrcat(AbstractState& as, const CallICFGNode *ca
|
|
|
354
351
|
IntervalValue totalLen = strLen0 + strLen1;
|
|
355
352
|
return canSafelyAccessMemory(as, arg0Val, totalLen);
|
|
356
353
|
}
|
|
357
|
-
else if (std::find(strncatGroup.begin(), strncatGroup.end(),
|
|
354
|
+
else if (std::find(strncatGroup.begin(), strncatGroup.end(), call->getCalledFunction()->getName()) != strncatGroup.end())
|
|
358
355
|
{
|
|
359
356
|
const SVFValue* arg0Val = call->getArgument(0);
|
|
360
357
|
const SVFValue* arg2Val = call->getArgument(2);
|
|
@@ -616,8 +616,7 @@ void AbstractInterpretation::handleCallSite(const ICFGNode* node)
|
|
|
616
616
|
|
|
617
617
|
bool AbstractInterpretation::isExtCall(const SVF::CallICFGNode *callNode)
|
|
618
618
|
{
|
|
619
|
-
|
|
620
|
-
return SVFUtil::isExtCall(callfun);
|
|
619
|
+
return SVFUtil::isExtCall(callNode->getCalledFunction());
|
|
621
620
|
}
|
|
622
621
|
|
|
623
622
|
void AbstractInterpretation::extCallPass(const SVF::CallICFGNode *callNode)
|
|
@@ -629,8 +628,7 @@ void AbstractInterpretation::extCallPass(const SVF::CallICFGNode *callNode)
|
|
|
629
628
|
|
|
630
629
|
bool AbstractInterpretation::isRecursiveCall(const SVF::CallICFGNode *callNode)
|
|
631
630
|
{
|
|
632
|
-
|
|
633
|
-
return recursiveFuns.find(callfun) != recursiveFuns.end();
|
|
631
|
+
return recursiveFuns.find(callNode->getCalledFunction()) != recursiveFuns.end();
|
|
634
632
|
}
|
|
635
633
|
|
|
636
634
|
void AbstractInterpretation::recursiveCallPass(const SVF::CallICFGNode *callNode)
|
|
@@ -654,18 +652,16 @@ void AbstractInterpretation::recursiveCallPass(const SVF::CallICFGNode *callNode
|
|
|
654
652
|
|
|
655
653
|
bool AbstractInterpretation::isDirectCall(const SVF::CallICFGNode *callNode)
|
|
656
654
|
{
|
|
657
|
-
|
|
658
|
-
return funcToWTO.find(callfun) != funcToWTO.end();
|
|
655
|
+
return funcToWTO.find(callNode->getCalledFunction()) != funcToWTO.end();
|
|
659
656
|
}
|
|
660
657
|
void AbstractInterpretation::directCallFunPass(const SVF::CallICFGNode *callNode)
|
|
661
658
|
{
|
|
662
659
|
AbstractState& as = getAbsStateFromTrace(callNode);
|
|
663
|
-
const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite());
|
|
664
660
|
callSiteStack.push_back(callNode);
|
|
665
661
|
|
|
666
662
|
abstractTrace[callNode] = as;
|
|
667
663
|
|
|
668
|
-
ICFGWTO* wto = funcToWTO[
|
|
664
|
+
ICFGWTO* wto = funcToWTO[callNode->getCalledFunction()];
|
|
669
665
|
handleWTOComponents(wto->getWTOComponents());
|
|
670
666
|
|
|
671
667
|
callSiteStack.pop_back();
|
|
@@ -819,7 +815,6 @@ void AbstractInterpretation::handleSVFStatement(const SVFStmt *stmt)
|
|
|
819
815
|
void AbstractInterpretation::SkipRecursiveCall(const CallICFGNode *callNode)
|
|
820
816
|
{
|
|
821
817
|
AbstractState& as = getAbsStateFromTrace(callNode);
|
|
822
|
-
const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite());
|
|
823
818
|
const RetICFGNode *retNode = callNode->getRetICFGNode();
|
|
824
819
|
if (retNode->getSVFStmts().size() > 0)
|
|
825
820
|
{
|
|
@@ -843,7 +838,7 @@ void AbstractInterpretation::SkipRecursiveCall(const CallICFGNode *callNode)
|
|
|
843
838
|
}
|
|
844
839
|
FIFOWorkList<const SVFBasicBlock *> blkWorkList;
|
|
845
840
|
FIFOWorkList<const ICFGNode *> instWorklist;
|
|
846
|
-
for (const SVFBasicBlock * bb:
|
|
841
|
+
for (const SVFBasicBlock * bb: callNode->getCalledFunction()->getReachableBBs())
|
|
847
842
|
{
|
|
848
843
|
for (const ICFGNode* node: bb->getICFGNodeList())
|
|
849
844
|
{
|
|
@@ -1333,7 +1328,7 @@ std::string AbstractInterpretation::strRead(AbstractState& as, const SVFValue* r
|
|
|
1333
1328
|
void AbstractInterpretation::handleExtAPI(const CallICFGNode *call)
|
|
1334
1329
|
{
|
|
1335
1330
|
AbstractState& as = getAbsStateFromTrace(call);
|
|
1336
|
-
const SVFFunction *fun =
|
|
1331
|
+
const SVFFunction *fun = call->getCalledFunction();
|
|
1337
1332
|
assert(fun && "SVFFunction* is nullptr");
|
|
1338
1333
|
ExtAPIType extType = UNCLASSIFIED;
|
|
1339
1334
|
// get type of mem api
|
|
@@ -1404,7 +1399,7 @@ void AbstractInterpretation::collectCheckPoint()
|
|
|
1404
1399
|
const ICFGNode* node = it->second;
|
|
1405
1400
|
if (const CallICFGNode *call = SVFUtil::dyn_cast<CallICFGNode>(node))
|
|
1406
1401
|
{
|
|
1407
|
-
if (const SVFFunction *fun =
|
|
1402
|
+
if (const SVFFunction *fun = call->getCalledFunction())
|
|
1408
1403
|
{
|
|
1409
1404
|
if (checkpoint_names.find(fun->getName()) !=
|
|
1410
1405
|
checkpoint_names.end())
|
|
@@ -1527,7 +1522,7 @@ void AbstractInterpretation::handleStrcat(const SVF::CallICFGNode *call)
|
|
|
1527
1522
|
// __strcat_chk, strcat, __wcscat_chk, wcscat, __strncat_chk, strncat, __wcsncat_chk, wcsncat
|
|
1528
1523
|
// to check it is strcat group or strncat group
|
|
1529
1524
|
AbstractState& as = getAbsStateFromTrace(call);
|
|
1530
|
-
const SVFFunction *fun =
|
|
1525
|
+
const SVFFunction *fun = call->getCalledFunction();
|
|
1531
1526
|
const std::vector<std::string> strcatGroup = {"__strcat_chk", "strcat", "__wcscat_chk", "wcscat"};
|
|
1532
1527
|
const std::vector<std::string> strncatGroup = {"__strncat_chk", "strncat", "__wcsncat_chk", "wcsncat"};
|
|
1533
1528
|
if (std::find(strcatGroup.begin(), strcatGroup.end(), fun->getName()) != strcatGroup.end())
|
package/svf/lib/CFL/CFLAlias.cpp
CHANGED
|
@@ -143,7 +143,7 @@ void CFLAlias::connectCaller2CalleeParams(const CallICFGNode* cs, const SVFFunct
|
|
|
143
143
|
|
|
144
144
|
void CFLAlias::heapAllocatorViaIndCall(const CallICFGNode* cs)
|
|
145
145
|
{
|
|
146
|
-
assert(
|
|
146
|
+
assert(cs->getCalledFunction() == nullptr && "not an indirect callsite?");
|
|
147
147
|
const RetICFGNode* retBlockNode = cs->getRetICFGNode();
|
|
148
148
|
const PAGNode* cs_return = svfir->getCallSiteRet(retBlockNode);
|
|
149
149
|
NodeID srcret;
|
|
@@ -45,13 +45,13 @@ CallSiteID CallGraph::totalCallSiteNum = 1;
|
|
|
45
45
|
//@{
|
|
46
46
|
void CallGraphEdge::addDirectCallSite(const CallICFGNode* call)
|
|
47
47
|
{
|
|
48
|
-
assert(
|
|
48
|
+
assert(call->getCalledFunction() && "not a direct callsite??");
|
|
49
49
|
directCalls.insert(call);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
void CallGraphEdge::addInDirectCallSite(const CallICFGNode* call)
|
|
53
53
|
{
|
|
54
|
-
assert((nullptr ==
|
|
54
|
+
assert((nullptr == call->getCalledFunction() || nullptr == SVFUtil::dyn_cast<SVFFunction> (SVFUtil::getForkedFun(call))) && "not an indirect callsite??");
|
|
55
55
|
indirectCalls.insert(call);
|
|
56
56
|
}
|
|
57
57
|
//@}
|
|
@@ -76,11 +76,11 @@ void LockAnalysis::collectLockUnlocksites()
|
|
|
76
76
|
{
|
|
77
77
|
for (const ICFGNode* icfgNode : bb->getICFGNodeList())
|
|
78
78
|
{
|
|
79
|
-
if (tcg->getThreadAPI()->isTDRelease(icfgNode))
|
|
79
|
+
if (isa<CallICFGNode>(icfgNode) && tcg->getThreadAPI()->isTDRelease(cast<CallICFGNode>(icfgNode)))
|
|
80
80
|
{
|
|
81
81
|
unlocksites.insert(icfgNode);
|
|
82
82
|
}
|
|
83
|
-
if (tcg->getThreadAPI()->isTDAcquire(icfgNode))
|
|
83
|
+
if (isa<CallICFGNode>(icfgNode) && tcg->getThreadAPI()->isTDAcquire(cast<CallICFGNode>(icfgNode)))
|
|
84
84
|
{
|
|
85
85
|
locksites.insert(icfgNode);
|
|
86
86
|
}
|
package/svf/lib/MTA/MHP.cpp
CHANGED
|
@@ -233,10 +233,11 @@ void MHP::handleFork(const CxtThreadStmt& cts, NodeID rootTid)
|
|
|
233
233
|
void MHP::handleJoin(const CxtThreadStmt& cts, NodeID rootTid)
|
|
234
234
|
{
|
|
235
235
|
|
|
236
|
-
const ICFGNode* call = cts.getStmt();
|
|
237
236
|
const CallStrCxt& curCxt = cts.getContext();
|
|
238
237
|
|
|
239
|
-
assert(isTDJoin(
|
|
238
|
+
assert(isTDJoin(cts.getStmt()));
|
|
239
|
+
|
|
240
|
+
const CallICFGNode* call = SVFUtil::cast<CallICFGNode>(cts.getStmt());
|
|
240
241
|
|
|
241
242
|
NodeBS joinedTids = getDirAndIndJoinedTid(curCxt, call);
|
|
242
243
|
if (!joinedTids.empty())
|
|
@@ -479,8 +480,9 @@ bool MHP::isRecurFullJoin(NodeID parentTid, NodeID curTid)
|
|
|
479
480
|
*/
|
|
480
481
|
bool MHP::isMustJoin(NodeID curTid, const ICFGNode* joinsite)
|
|
481
482
|
{
|
|
482
|
-
|
|
483
|
-
|
|
483
|
+
const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(joinsite);
|
|
484
|
+
assert(call && isTDJoin(call) && "not a join site!");
|
|
485
|
+
return !isMultiForkedThread(curTid) && !tct->isJoinSiteInRecursion(call);
|
|
484
486
|
}
|
|
485
487
|
|
|
486
488
|
/*!
|
|
@@ -821,9 +823,9 @@ void ForkJoinAnalysis::handleJoin(const CxtStmt& cts, NodeID rootTid)
|
|
|
821
823
|
|
|
822
824
|
if (isAliasedForkJoin(SVFUtil::cast<CallICFGNode>(forkSite), SVFUtil::cast<CallICFGNode>(joinSite)))
|
|
823
825
|
{
|
|
824
|
-
if (hasJoinLoop(
|
|
826
|
+
if (hasJoinLoop(SVFUtil::cast<CallICFGNode>(forkSite)))
|
|
825
827
|
{
|
|
826
|
-
LoopBBs& joinLoop = getJoinLoop(
|
|
828
|
+
LoopBBs& joinLoop = getJoinLoop(SVFUtil::cast<CallICFGNode>(forkSite));
|
|
827
829
|
std::vector<const SVFBasicBlock *> exitbbs;
|
|
828
830
|
joinSite->getFun()->getExitBlocksOfLoop(joinSite->getBB(), exitbbs);
|
|
829
831
|
while (!exitbbs.empty())
|
|
@@ -853,7 +855,7 @@ void ForkJoinAnalysis::handleJoin(const CxtStmt& cts, NodeID rootTid)
|
|
|
853
855
|
/// we process the loop exit
|
|
854
856
|
else
|
|
855
857
|
{
|
|
856
|
-
if (hasJoinLoop(
|
|
858
|
+
if (hasJoinLoop(SVFUtil::cast<CallICFGNode>(forkSite)))
|
|
857
859
|
{
|
|
858
860
|
std::vector<const SVFBasicBlock*> exitbbs;
|
|
859
861
|
joinSite->getFun()->getExitBlocksOfLoop(joinSite->getBB(), exitbbs);
|
|
@@ -509,7 +509,7 @@ void PointerAnalysis::validateSuccessTests(std::string fun)
|
|
|
509
509
|
|
|
510
510
|
for(const CallICFGNode* callNode : pag->getCallSiteSet())
|
|
511
511
|
{
|
|
512
|
-
if (
|
|
512
|
+
if (callNode->getCalledFunction() == checkFun)
|
|
513
513
|
{
|
|
514
514
|
assert(callNode->getNumArgOperands() == 2
|
|
515
515
|
&& "arguments should be two pointers!!");
|
|
@@ -574,7 +574,7 @@ void PointerAnalysis::validateExpectedFailureTests(std::string fun)
|
|
|
574
574
|
|
|
575
575
|
for(const CallICFGNode* callNode : pag->getCallSiteSet())
|
|
576
576
|
{
|
|
577
|
-
if (
|
|
577
|
+
if (callNode->getCalledFunction() == checkFun)
|
|
578
578
|
{
|
|
579
579
|
assert(callNode->arg_size() == 2
|
|
580
580
|
&& "arguments should be two pointers!!");
|
|
@@ -55,7 +55,7 @@ void DoubleFreeChecker::testsValidation(ProgSlice *slice)
|
|
|
55
55
|
{
|
|
56
56
|
const SVFGNode* source = slice->getSource();
|
|
57
57
|
const CallICFGNode* cs = getSrcCSID(source);
|
|
58
|
-
const SVFFunction* fun =
|
|
58
|
+
const SVFFunction* fun = cs->getCalledFunction();
|
|
59
59
|
if(fun==nullptr)
|
|
60
60
|
return;
|
|
61
61
|
validateSuccessTests(slice,fun);
|
|
@@ -180,7 +180,7 @@ void LeakChecker::testsValidation(const ProgSlice* slice)
|
|
|
180
180
|
{
|
|
181
181
|
const SVFGNode* source = slice->getSource();
|
|
182
182
|
const CallICFGNode* cs = getSrcCSID(source);
|
|
183
|
-
const SVFFunction* fun =
|
|
183
|
+
const SVFFunction* fun = cs->getCalledFunction();
|
|
184
184
|
if(fun==nullptr)
|
|
185
185
|
return;
|
|
186
186
|
|
|
@@ -52,9 +52,9 @@ CallGraph* CallGraphBuilder::buildCallGraph(SVFModule* svfModule)
|
|
|
52
52
|
{
|
|
53
53
|
if (SVFUtil::isNonInstricCallSite(inst))
|
|
54
54
|
{
|
|
55
|
-
|
|
55
|
+
const CallICFGNode* callBlockNode = cast<CallICFGNode>(inst);
|
|
56
|
+
if(const SVFFunction* callee = callBlockNode->getCalledFunction())
|
|
56
57
|
{
|
|
57
|
-
const CallICFGNode* callBlockNode = cast<CallICFGNode>(inst);
|
|
58
58
|
callgraph->addDirectCallGraphEdge(callBlockNode,*F,callee);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -80,7 +80,7 @@ CallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule)
|
|
|
80
80
|
{
|
|
81
81
|
for (const ICFGNode* inst : svfbb->getICFGNodeList())
|
|
82
82
|
{
|
|
83
|
-
if (tdAPI->isTDFork(inst))
|
|
83
|
+
if (SVFUtil::isa<CallICFGNode>(inst) && tdAPI->isTDFork(SVFUtil::cast<CallICFGNode>(inst)))
|
|
84
84
|
{
|
|
85
85
|
const CallICFGNode* cs = cast<CallICFGNode>(inst);
|
|
86
86
|
cg->addForksite(cs);
|
|
@@ -105,7 +105,7 @@ CallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule)
|
|
|
105
105
|
{
|
|
106
106
|
for (const ICFGNode* node : svfbb->getICFGNodeList())
|
|
107
107
|
{
|
|
108
|
-
if (tdAPI->isTDJoin(node))
|
|
108
|
+
if (SVFUtil::isa<CallICFGNode>(node) && tdAPI->isTDJoin(SVFUtil::cast<CallICFGNode>(node)))
|
|
109
109
|
{
|
|
110
110
|
const CallICFGNode* cs = SVFUtil::cast<CallICFGNode>(node);
|
|
111
111
|
cg->addJoinsite(cs);
|
|
@@ -303,7 +303,8 @@ const std::string SVFBugEvent::getEventDescription() const
|
|
|
303
303
|
case SVFBugEvent::CallSite:
|
|
304
304
|
{
|
|
305
305
|
std::string description("calls ");
|
|
306
|
-
|
|
306
|
+
assert(SVFUtil::isa<CallICFGNode>(eventInst) && "not a call ICFGNode?");
|
|
307
|
+
const SVFFunction *callee = SVFUtil::cast<CallICFGNode>(eventInst)->getCalledFunction();
|
|
307
308
|
if(callee == nullptr)
|
|
308
309
|
{
|
|
309
310
|
description += "<unknown>";
|
package/svf/lib/Util/SVFUtil.cpp
CHANGED
|
@@ -343,24 +343,34 @@ bool SVFUtil::isIntrinsicInst(const ICFGNode* inst)
|
|
|
343
343
|
return false;
|
|
344
344
|
}
|
|
345
345
|
|
|
346
|
-
|
|
346
|
+
bool SVFUtil::isExtCall(const CallICFGNode* cs)
|
|
347
347
|
{
|
|
348
|
-
|
|
349
|
-
return nullptr;
|
|
350
|
-
const CallICFGNode* call = SVFUtil::cast<CallICFGNode>(inst);
|
|
351
|
-
return call->getCalledFunction();
|
|
348
|
+
return isExtCall(cs->getCalledFunction());
|
|
352
349
|
}
|
|
353
350
|
|
|
354
|
-
|
|
351
|
+
bool SVFUtil::isHeapAllocExtCallViaArg(const CallICFGNode* cs)
|
|
355
352
|
{
|
|
356
|
-
return
|
|
353
|
+
return isHeapAllocExtFunViaArg(cs->getCalledFunction());
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
bool SVFUtil::isHeapAllocExtCallViaArg(const SVFInstruction *inst)
|
|
357
|
+
{
|
|
358
|
+
if(const SVFCallInst* call = SVFUtil::dyn_cast<SVFCallInst>(inst))
|
|
359
|
+
return isHeapAllocExtFunViaArg(call->getCalledFunction());
|
|
360
|
+
else
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
u32_t SVFUtil::getHeapAllocHoldingArgPosition(const CallICFGNode* cs)
|
|
365
|
+
{
|
|
366
|
+
return getHeapAllocHoldingArgPosition(cs->getCalledFunction());
|
|
357
367
|
}
|
|
358
368
|
|
|
359
369
|
|
|
360
370
|
bool SVFUtil::isExtCall(const ICFGNode* node)
|
|
361
371
|
{
|
|
362
372
|
if(!isCallSite(node)) return false;
|
|
363
|
-
return isExtCall(
|
|
373
|
+
return isExtCall(cast<CallICFGNode>(node)->getCalledFunction());
|
|
364
374
|
}
|
|
365
375
|
|
|
366
376
|
bool SVFUtil::isHeapAllocExtCall(const ICFGNode* cs)
|
|
@@ -372,13 +382,13 @@ bool SVFUtil::isHeapAllocExtCall(const ICFGNode* cs)
|
|
|
372
382
|
bool SVFUtil::isHeapAllocExtCallViaRet(const CallICFGNode* cs)
|
|
373
383
|
{
|
|
374
384
|
bool isPtrTy = cs->getCallSite()->getType()->isPointerTy();
|
|
375
|
-
return isPtrTy && isHeapAllocExtFunViaRet(
|
|
385
|
+
return isPtrTy && isHeapAllocExtFunViaRet(cs->getCalledFunction());
|
|
376
386
|
}
|
|
377
387
|
|
|
378
388
|
bool SVFUtil::isReallocExtCall(const CallICFGNode* cs)
|
|
379
389
|
{
|
|
380
390
|
bool isPtrTy = cs->getCallSite()->getType()->isPointerTy();
|
|
381
|
-
return isPtrTy && isReallocExtFun(
|
|
391
|
+
return isPtrTy && isReallocExtFun(cs->getCalledFunction());
|
|
382
392
|
}
|
|
383
393
|
|
|
384
394
|
bool SVFUtil::isHeapAllocExtCallViaRet(const SVFInstruction *inst)
|
|
@@ -396,4 +406,9 @@ bool SVFUtil::isRetInstNode(const ICFGNode* node)
|
|
|
396
406
|
return intraNode->getInst()->isRetInst();
|
|
397
407
|
else
|
|
398
408
|
return false;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
bool SVFUtil::isProgExitCall(const CallICFGNode* cs)
|
|
412
|
+
{
|
|
413
|
+
return isProgExitFunction(cs->getCalledFunction());
|
|
399
414
|
}
|
|
@@ -129,6 +129,37 @@ void ThreadAPI::init()
|
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
bool ThreadAPI::isTDFork(const CallICFGNode *inst) const
|
|
133
|
+
{
|
|
134
|
+
return getType(inst->getCalledFunction()) == TD_FORK;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
bool ThreadAPI::isTDJoin(const CallICFGNode *inst) const
|
|
138
|
+
{
|
|
139
|
+
return getType(inst->getCalledFunction()) == TD_JOIN;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
bool ThreadAPI::isTDExit(const CallICFGNode *inst) const
|
|
143
|
+
{
|
|
144
|
+
return getType(inst->getCalledFunction()) == TD_EXIT;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
bool ThreadAPI::isTDAcquire(const CallICFGNode* inst) const
|
|
148
|
+
{
|
|
149
|
+
return getType(inst->getCalledFunction()) == TD_ACQUIRE;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
bool ThreadAPI::isTDRelease(const CallICFGNode *inst) const
|
|
153
|
+
{
|
|
154
|
+
return getType(inst->getCalledFunction()) == TD_RELEASE;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
bool ThreadAPI::isTDBarWait(const CallICFGNode *inst) const
|
|
158
|
+
{
|
|
159
|
+
return getType(inst->getCalledFunction()) == TD_BAR_WAIT;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
|
|
132
163
|
const SVFValue* ThreadAPI::getForkedThread(const CallICFGNode *inst) const
|
|
133
164
|
{
|
|
134
165
|
assert(isTDFork(inst) && "not a thread fork function!");
|
|
@@ -155,17 +186,6 @@ const SVFValue* ThreadAPI::getRetParmAtJoinedSite(const CallICFGNode *inst) cons
|
|
|
155
186
|
return inst->getArgument(1);
|
|
156
187
|
}
|
|
157
188
|
|
|
158
|
-
/*!
|
|
159
|
-
*
|
|
160
|
-
*/
|
|
161
|
-
const SVFFunction* ThreadAPI::getCallee(const ICFGNode *inst) const
|
|
162
|
-
{
|
|
163
|
-
if(const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(inst))
|
|
164
|
-
return SVFUtil::getCallee(call->getCallSite());
|
|
165
|
-
else
|
|
166
|
-
return nullptr;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
189
|
const SVFValue* ThreadAPI::getLockVal(const ICFGNode *cs) const
|
|
170
190
|
{
|
|
171
191
|
const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(cs);
|
|
@@ -251,7 +271,7 @@ void ThreadAPI::performAPIStat(SVFModule* module)
|
|
|
251
271
|
if (!SVFUtil::isCallSite(svfInst))
|
|
252
272
|
continue;
|
|
253
273
|
|
|
254
|
-
const SVFFunction* fun = SVFUtil::
|
|
274
|
+
const SVFFunction* fun = SVFUtil::cast<CallICFGNode>(svfInst)->getCalledFunction();
|
|
255
275
|
TD_TYPE type = getType(fun);
|
|
256
276
|
switch (type)
|
|
257
277
|
{
|
package/svf/lib/WPA/Andersen.cpp
CHANGED
|
@@ -679,7 +679,7 @@ bool Andersen::updateCallGraph(const CallSiteToFunPtrMap& callsites)
|
|
|
679
679
|
|
|
680
680
|
void Andersen::heapAllocatorViaIndCall(const CallICFGNode* cs, NodePairSet &cpySrcNodes)
|
|
681
681
|
{
|
|
682
|
-
assert(
|
|
682
|
+
assert(cs->getCalledFunction() == nullptr && "not an indirect callsite?");
|
|
683
683
|
const RetICFGNode* retBlockNode = cs->getRetICFGNode();
|
|
684
684
|
const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode);
|
|
685
685
|
NodeID srcret;
|
|
@@ -157,7 +157,7 @@ bool Steensgaard::updateCallGraph(const CallSiteToFunPtrMap& callsites)
|
|
|
157
157
|
|
|
158
158
|
void Steensgaard::heapAllocatorViaIndCall(const CallICFGNode* cs, NodePairSet& cpySrcNodes)
|
|
159
159
|
{
|
|
160
|
-
assert(
|
|
160
|
+
assert(cs->getCalledFunction() == nullptr && "not an indirect callsite?");
|
|
161
161
|
const RetICFGNode* retBlockNode = cs->getRetICFGNode();
|
|
162
162
|
const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode);
|
|
163
163
|
NodeID srcret;
|
|
@@ -233,7 +233,7 @@ InterICFGNode* ICFGBuilder::addInterBlockICFGNode(const SVFInstruction* inst)
|
|
|
233
233
|
assert(SVFUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
|
|
234
234
|
CallICFGNode* callICFGNode = icfg->addCallICFGNode(inst);
|
|
235
235
|
(void) icfg->addRetICFGNode(inst);
|
|
236
|
-
addICFGInterEdges(inst,
|
|
236
|
+
addICFGInterEdges(inst, callICFGNode->getCalledFunction()); //creating interprocedural edges
|
|
237
237
|
return callICFGNode;
|
|
238
238
|
}
|
|
239
239
|
|
|
@@ -608,7 +608,7 @@ const Type* SymbolTableBuilder::inferTypeOfHeapObjOrStaticObj(const Instruction
|
|
|
608
608
|
else if(SVFUtil::isHeapAllocExtCallViaArg(svfinst))
|
|
609
609
|
{
|
|
610
610
|
const CallBase* cs = LLVMUtil::getLLVMCallSite(inst);
|
|
611
|
-
|
|
611
|
+
u32_t arg_pos = SVFUtil::getHeapAllocHoldingArgPosition(SVFUtil::cast<SVFCallInst>(svfinst)->getCalledFunction());
|
|
612
612
|
const Value* arg = cs->getArgOperand(arg_pos);
|
|
613
613
|
originalPType = SVFUtil::dyn_cast<PointerType>(arg->getType());
|
|
614
614
|
inferedType = inferObjType(startValue = arg);
|