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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-tools",
3
- "version": "1.0.985",
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::getCallee(cs);
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
- return getTCG()->getThreadAPI()->isTDFork(call);
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
- return getTCG()->getThreadAPI()->isTDAcquire(call);
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
- return getTCG()->getThreadAPI()->isTDRelease(call);
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)
@@ -227,12 +227,14 @@ private:
227
227
  /// Whether it is a fork site
228
228
  inline bool isTDFork(const ICFGNode* call)
229
229
  {
230
- return tcg->getThreadAPI()->isTDFork(call);
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
- return tcg->getThreadAPI()->isTDJoin(call);
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 ICFGNode* inst)
350
+ inline LoopBBs& getJoinLoop(const CallICFGNode* inst)
349
351
  {
350
352
  return tct->getJoinLoop(inst);
351
353
  }
352
- inline bool hasJoinLoop(const ICFGNode* inst)
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
- return getTCG()->getThreadAPI()->isTDFork(call);
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
- return getTCG()->getThreadAPI()->isTDJoin(call);
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)
@@ -364,7 +364,7 @@ public:
364
364
  }
365
365
 
366
366
  /// Get loop for join site
367
- inline LoopBBs& getJoinLoop(const ICFGNode* join)
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 ICFGNode* join) 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 ICFGNode* join) 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(SVFUtil::getCallee(cs->getCallSite()));
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(SVFUtil::getCallee(cs->getCallSite()));
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(SVFUtil::getCallee(cs->getCallSite()));
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(SVFUtil::getCallee(cs->getCallSite()));
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 int getHeapAllocHoldingArgPosition(const SVFFunction* fun)
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
- inline bool isExtCall(const CallICFGNode* cs)
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
- inline bool isHeapAllocExtCallViaArg(const CallICFGNode* cs)
415
- {
416
- return isHeapAllocExtFunViaArg(getCallee(cs));
417
- }
392
+ bool isHeapAllocExtCallViaArg(const CallICFGNode* cs);
418
393
 
419
- inline bool isHeapAllocExtCallViaArg(const SVFInstruction *inst)
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
- inline int getHeapAllocHoldingArgPosition(const CallICFGNode* cs)
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 ICFGNode *inst)
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 ICFGNode* cs)
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 ICFGNode* cs)
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 ICFGNode* cs)
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 ICFGNode* cs)
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 ICFGNode* cs)
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
- inline bool isProgExitCall(const CallICFGNode* cs)
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
- inline bool isTDJoin(const ICFGNode *inst) const
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
- inline bool isTDExit(const ICFGNode *inst) const
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
- inline bool isTDAcquire(const ICFGNode* inst) const
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
- inline bool isTDRelease(const ICFGNode *inst) const
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
- inline bool isTDBarWait(const ICFGNode *inst) const
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
- const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite());
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
- const SVFFunction *fun = SVFUtil::getCallee(call->getCallSite());
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 : fun->getAnnotations())
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(fun->getName()) == 0)
168
+ if (extAPIBufOverflowCheckRules.count(call->getCalledFunction()->getName()) == 0)
171
169
  {
172
- SVFUtil::errs() << "Warning: " << fun->getName() << " is not in the rules, please implement it\n";
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(fun->getName());
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(fun->getName()) == 0)
187
+ if (extAPIBufOverflowCheckRules.count(call->getCalledFunction()->getName()) == 0)
190
188
  {
191
- SVFUtil::errs() << "Warning: " << fun->getName() << " is not in the rules, please implement it\n";
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(fun->getName());
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(), fun->getName()) != 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(), fun->getName()) != 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
- const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite());
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
- const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite());
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
- const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite());
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[callfun];
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: callfun->getReachableBBs())
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 = SVFUtil::getCallee(call->getCallSite());
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 = SVFUtil::getCallee(call->getCallSite()))
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 = SVFUtil::getCallee(call);
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())
@@ -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(SVFUtil::getCallee(cs) == nullptr && "not an indirect callsite?");
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(SVFUtil::getCallee(call->getCallSite()) && "not a direct callsite??");
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 == SVFUtil::getCallee(call->getCallSite()) || nullptr == SVFUtil::dyn_cast<SVFFunction> (SVFUtil::getForkedFun(call))) && "not an indirect callsite??");
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
  }
@@ -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(call));
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
- assert(isTDJoin(joinsite) && "not a join site!");
483
- return !isMultiForkedThread(curTid) && !tct->isJoinSiteInRecursion(joinsite);
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(joinSite))
826
+ if (hasJoinLoop(SVFUtil::cast<CallICFGNode>(forkSite)))
825
827
  {
826
- LoopBBs& joinLoop = getJoinLoop(joinSite);
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(joinSite))
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 (SVFUtil::getCallee(callNode) == checkFun)
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 (SVFUtil::getCallee(callNode) == checkFun)
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 = getCallee(cs->getCallSite());
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 = getCallee(cs->getCallSite());
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
- if(const SVFFunction* callee = getCallee(inst))
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
- const SVFFunction *callee = SVFUtil::getCallee(eventInst);
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>";
@@ -343,24 +343,34 @@ bool SVFUtil::isIntrinsicInst(const ICFGNode* inst)
343
343
  return false;
344
344
  }
345
345
 
346
- const SVFFunction* SVFUtil::getCallee(const ICFGNode *inst)
346
+ bool SVFUtil::isExtCall(const CallICFGNode* cs)
347
347
  {
348
- if (!isCallSite(inst))
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
- const SVFFunction* SVFUtil::getCallee(const CallICFGNode *inst)
351
+ bool SVFUtil::isHeapAllocExtCallViaArg(const CallICFGNode* cs)
355
352
  {
356
- return inst->getCalledFunction();
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(getCallee(node));
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(getCallee(cs));
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(getCallee(cs));
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::getCallee(svfInst);
274
+ const SVFFunction* fun = SVFUtil::cast<CallICFGNode>(svfInst)->getCalledFunction();
255
275
  TD_TYPE type = getType(fun);
256
276
  switch (type)
257
277
  {
@@ -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(SVFUtil::getCallee(cs) == nullptr && "not an indirect callsite?");
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(SVFUtil::getCallee(cs) == nullptr && "not an indirect callsite?");
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, getCallee(inst)); //creating interprocedural edges
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
- int arg_pos = SVFUtil::getHeapAllocHoldingArgPosition(getCallee(svfinst));
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);