svf-tools 1.0.985 → 1.0.987

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.987",
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);