svf-tools 1.0.1026 → 1.0.1027

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.1026",
3
+ "version": "1.0.1027",
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": {
@@ -154,6 +154,7 @@ public:
154
154
  // ┌── SVFVar: Classes of top-level variables (ValVar) and address-taken variables (ObjVar)
155
155
  // │ └── ValVar: Classes of top-level variable nodes
156
156
  ValNode, // ├──Represents a standard value variable
157
+ ArgNode, // ├──Represents an argument value variable
157
158
  FunValNode, // ├──Represents a Function value variable
158
159
  GepValNode, // ├──Represents a GEP value variable
159
160
  RetNode, // ├──Represents a return value node
@@ -289,7 +290,7 @@ protected:
289
290
 
290
291
  static inline bool isSVFVarKind(GNodeK n)
291
292
  {
292
- static_assert(DummyObjNode - ValNode == 23,
293
+ static_assert(DummyObjNode - ValNode == 24,
293
294
  "The number of SVFVarKinds has changed, make sure the "
294
295
  "range is correct");
295
296
 
@@ -298,7 +299,7 @@ protected:
298
299
 
299
300
  static inline bool isValVarKinds(GNodeK n)
300
301
  {
301
- static_assert(DummyValNode - ValNode == 11,
302
+ static_assert(DummyValNode - ValNode == 12,
302
303
  "The number of ValVarKinds has changed, make sure the "
303
304
  "range is correct");
304
305
  return n <= DummyValNode && n >= ValNode;
@@ -578,6 +578,13 @@ private:
578
578
  return addValNode(nullptr, node, i);
579
579
  }
580
580
 
581
+ NodeID addArgValNode(NodeID i, u32_t argNo, const ICFGNode* icfgNode, const CallGraphNode* callGraphNode, bool isUncalled = false)
582
+ {
583
+ ArgValVar* node =
584
+ new ArgValVar(i, argNo, icfgNode, callGraphNode, isUncalled);
585
+ return addValNode(nullptr, node, i);
586
+ }
587
+
581
588
  inline NodeID addConstantFPValNode(const SVFValue* curInst, double dval, const NodeID i,
582
589
  const ICFGNode* icfgNode)
583
590
  {
@@ -133,11 +133,6 @@ public:
133
133
  {
134
134
  return inst->getParent()->getParent();
135
135
  }
136
- // For function arguments, return their parent function
137
- else if (auto arg = SVFUtil::dyn_cast<SVFArgument>(value))
138
- {
139
- return arg->getParent();
140
- }
141
136
  }
142
137
 
143
138
  // Return nullptr for globals/constants with no parent function
@@ -388,6 +383,83 @@ public:
388
383
  };
389
384
 
390
385
 
386
+ /**
387
+ * @brief Class representing a function argument variable in the SVFIR
388
+ *
389
+ * This class models function argument in the program analysis. It extends ValVar
390
+ * to specifically handle function argument.
391
+ */
392
+ class ArgValVar: public ValVar
393
+ {
394
+ friend class SVFIRWriter;
395
+ friend class SVFIRReader;
396
+
397
+ private:
398
+ const CallGraphNode* cgNode;
399
+ u32_t argNo;
400
+ bool uncalled;
401
+
402
+ protected:
403
+ /// Constructor to create function argument (for SVFIRReader/deserialization)
404
+ ArgValVar(NodeID i, PNODEK ty = ArgNode) : ValVar(i, ty) {}
405
+
406
+ public:
407
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
408
+ //@{
409
+ static inline bool classof(const ArgValVar*)
410
+ {
411
+ return true;
412
+ }
413
+ static inline bool classof(const ValVar* node)
414
+ {
415
+ return node->getNodeKind() == ArgNode;
416
+ }
417
+ static inline bool classof(const SVFVar* node)
418
+ {
419
+ return node->getNodeKind() == ArgNode;
420
+ }
421
+ static inline bool classof(const GenericPAGNodeTy* node)
422
+ {
423
+ return node->getNodeKind() == ArgNode;
424
+ }
425
+ static inline bool classof(const SVFBaseNode* node)
426
+ {
427
+ return node->getNodeKind() == ArgNode;
428
+ }
429
+ //@}
430
+
431
+ /// Constructor
432
+ ArgValVar(NodeID i, u32_t argNo, const ICFGNode* icn, const CallGraphNode* callGraphNode,
433
+ bool isUncalled = false, PNODEK ty = ArgNode);
434
+
435
+ /// Return name of a LLVM value
436
+ inline const std::string getValueName() const
437
+ {
438
+ if (value)
439
+ return value->getName() + " (argument valvar)";
440
+ return " (argument valvar)";
441
+ }
442
+
443
+ virtual const SVFFunction* getFunction() const;
444
+
445
+ const SVFFunction* getParent() const;
446
+
447
+ /// Return the index of this formal argument in its containing function.
448
+ /// For example in "void foo(int a, float b)" a is 0 and b is 1.
449
+ inline u32_t getArgNo() const
450
+ {
451
+ return argNo;
452
+ }
453
+
454
+ inline bool isArgOfUncalledFunction() const
455
+ {
456
+ return uncalled;
457
+ }
458
+
459
+ virtual const std::string toString() const;
460
+ };
461
+
462
+
391
463
  /*
392
464
  * Gep Value (Pointer) variable, this variable can be dynamic generated for field sensitive analysis
393
465
  * e.g. memcpy, temp gep value variable needs to be created
@@ -351,6 +351,8 @@ inline bool isArgOfUncalledFunction(const SVFValue* svfval)
351
351
  return false;
352
352
  }
353
353
 
354
+ bool isArgOfUncalledFunction(const SVFVar* svfvar);
355
+
354
356
  const ObjVar* getObjVarOfValVar(const ValVar* valVar);
355
357
 
356
358
  /// Return thread fork function
@@ -222,6 +222,7 @@ cJSON* SVFIRWriter::virtToJson(const SVFVar* var)
222
222
  CASE(DummyValNode, DummyValVar);
223
223
  CASE(DummyObjNode, DummyObjVar);
224
224
  CASE(FunObjNode, FunObjVar);
225
+ CASE(ArgNode, ArgValVar);
225
226
  CASE(FunValNode, FunValVar);
226
227
  CASE(HeapObjNode, HeapObjVar);
227
228
  CASE(StackObjNode, StackObjVar);
@@ -670,11 +670,10 @@ bool SVFIR::isValidPointer(NodeID nodeId) const
670
670
 
671
671
  if (node->hasValue() && node->isPointer())
672
672
  {
673
- if(const SVFArgument* arg = SVFUtil::dyn_cast<SVFArgument>(node->getValue()))
674
- {
675
- if (!(arg->getParent()->isDeclaration()))
676
- return true;
677
- }
673
+ if (const ValVar* pVar = pag->getBaseValVar(nodeId))
674
+ if (const ArgValVar* arg = SVFUtil::dyn_cast<ArgValVar>(pVar))
675
+ if (!(arg->getParent()->isDeclaration()))
676
+ return true;
678
677
  }
679
678
 
680
679
  if ((node->getInEdges().empty() && node->getOutEdges().empty()))
@@ -694,7 +693,7 @@ bool SVFIR::isValidTopLevelPtr(const SVFVar* node)
694
693
  return true;
695
694
  }
696
695
  else if(node->hasValue())
697
- return !SVFUtil::isArgOfUncalledFunction(node->getValue());
696
+ return !SVFUtil::isArgOfUncalledFunction(node);
698
697
  }
699
698
  }
700
699
  return false;
@@ -46,6 +46,7 @@ SVFVar::SVFVar(const SVFValue* val, NodeID i, PNODEK k) :
46
46
  switch (k)
47
47
  {
48
48
  case ValNode:
49
+ case ArgNode:
49
50
  case ConstantDataValNode:
50
51
  case GlobalValNode:
51
52
  case BlackHoleNode:
@@ -144,6 +145,39 @@ const std::string ObjVar::toString() const
144
145
  return rawstr.str();
145
146
  }
146
147
 
148
+ ArgValVar::ArgValVar(NodeID i, u32_t argNo, const ICFGNode* icn,
149
+ const SVF::CallGraphNode* callGraphNode, bool isUncalled,
150
+ SVF::SVFVar::PNODEK ty)
151
+ : ValVar(callGraphNode->getFunction()->getArg(argNo), i, ty, icn),
152
+ cgNode(callGraphNode), argNo(argNo), uncalled(isUncalled)
153
+ {
154
+ isPtr =
155
+ callGraphNode->getFunction()->getArg(argNo)->getType()->isPointerTy();
156
+ }
157
+
158
+ const SVFFunction* ArgValVar::getFunction() const
159
+ {
160
+ return getParent();
161
+ }
162
+
163
+ const SVFFunction* ArgValVar::getParent() const
164
+ {
165
+ return cgNode->getFunction();
166
+ }
167
+
168
+ const std::string ArgValVar::toString() const
169
+ {
170
+ std::string str;
171
+ std::stringstream rawstr(str);
172
+ rawstr << "ArgValVar ID: " << getId();
173
+ if (Options::ShowSVFIRValue())
174
+ {
175
+ rawstr << "\n";
176
+ rawstr << valueOnlyToString();
177
+ }
178
+ return rawstr.str();
179
+ }
180
+
147
181
  const std::string GepValVar::toString() const
148
182
  {
149
183
  std::string str;
@@ -468,4 +502,3 @@ bool SVFVar::isConstDataOrAggDataButNotNullPtr() const
468
502
  else
469
503
  return false;
470
504
  }
471
-
@@ -425,6 +425,14 @@ const SVFFunction* SVFUtil::getProgEntryFunction()
425
425
  return nullptr;
426
426
  }
427
427
 
428
+ bool SVFUtil::isArgOfUncalledFunction(const SVFVar* svfvar)
429
+ {
430
+ const ValVar* pVar = PAG::getPAG()->getBaseValVar(svfvar->getId());
431
+ if(const ArgValVar* arg = SVFUtil::dyn_cast<ArgValVar>(pVar))
432
+ return arg->isArgOfUncalledFunction();
433
+ else
434
+ return false;
435
+ }
428
436
 
429
437
  const ObjVar* SVFUtil::getObjVarOfValVar(const SVF::ValVar* valVar)
430
438
  {
@@ -207,13 +207,13 @@ const SVFVar* ThreadAPI::getLockVal(const ICFGNode *cs) const
207
207
  const SVFVar* ThreadAPI::getJoinedThread(const CallICFGNode *cs) const
208
208
  {
209
209
  assert(isTDJoin(cs) && "not a thread join function!");
210
- const SVFVar* join = cs->getArgument(0);
210
+ const ValVar* join = cs->getArgument(0);
211
211
  for(const SVFStmt* stmt : join->getInEdges())
212
212
  {
213
213
  if(SVFUtil::isa<LoadStmt>(stmt))
214
214
  return stmt->getSrcNode();
215
215
  }
216
- if(SVFUtil::isa<SVFArgument>(join->getValue()))
216
+ if(SVFUtil::isa<ArgValVar>(join))
217
217
  return join;
218
218
 
219
219
  assert(false && "the value of the first argument at join is not a load instruction?");
@@ -245,6 +245,15 @@ void SVFIRBuilder::initialiseNodes()
245
245
  // add value node representing the function
246
246
  pag->addFunValNode(cgn, iter->second, icfgNode);
247
247
  }
248
+ else if (auto argval = SVFUtil::dyn_cast<Argument>(llvmValue))
249
+ {
250
+ pag->addArgValNode(
251
+ iter->second, argval->getArgNo(), icfgNode,
252
+ llvmModuleSet()->getCallGraphNode(argval->getParent()),
253
+ LLVMUtil::isArgOfUncalledFunction(argval));
254
+ llvmModuleSet()->addToLLVMVal2SVFVarMap(
255
+ argval, pag->getGNode(iter->second));
256
+ }
248
257
  else if (auto fpValue = SVFUtil::dyn_cast<ConstantFP>(llvmValue))
249
258
  {
250
259
  pag->addConstantFPValNode(iter->first, LLVMUtil::getDoubleValue(fpValue), iter->second, icfgNode);