svf-tools 1.0.1048 → 1.0.1050

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.1048",
3
+ "version": "1.0.1050",
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": {
@@ -169,7 +169,7 @@ const std::string GepValVar::toString() const
169
169
  if (Options::ShowSVFIRValue())
170
170
  {
171
171
  rawstr << "\n";
172
- rawstr << valueOnlyToString();
172
+ rawstr << getBaseNode()->valueOnlyToString();
173
173
  }
174
174
  return rawstr.str();
175
175
  }
@@ -203,7 +203,7 @@ const std::string GepObjVar::toString() const
203
203
  if (Options::ShowSVFIRValue())
204
204
  {
205
205
  rawstr << "\n";
206
- rawstr << valueOnlyToString();
206
+ rawstr << getBaseObj()->valueOnlyToString();
207
207
  }
208
208
  return rawstr.str();
209
209
  }
@@ -70,6 +70,8 @@ public:
70
70
  /// get or infer the type of the object pointed by the value
71
71
  const Type *inferObjType(const Value *var);
72
72
 
73
+ const Type *inferPointsToType(const Value *var);
74
+
73
75
  /// validate type inference
74
76
  void validateTypeCheck(const CallBase *cs);
75
77
 
@@ -767,33 +767,17 @@ const std::string SVFValue::valueOnlyToString() const
767
767
  {
768
768
  std::string str;
769
769
  llvm::raw_string_ostream rawstr(str);
770
- if (const SVF::CallGraphNode* fun = SVFUtil::dyn_cast<CallGraphNode>(this))
771
- {
772
- rawstr << "Function: " << fun->getFunction()->getName() << " ";
773
- }
770
+ assert(
771
+ !SVFUtil::isa<GepObjVar>(this) && !SVFUtil::isa<GepValVar>(this) &&
772
+ !SVFUtil::isa<DummyObjVar>(this) &&!SVFUtil::isa<DummyValVar>(this) &&
773
+ !SVFUtil::isa<BlackHoleValVar>(this) &&
774
+ "invalid value, refer to their toString method");
775
+ auto llvmVal =
776
+ LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(this);
777
+ if (llvmVal)
778
+ rawstr << " " << *llvmVal << " ";
774
779
  else
775
- {
776
- const SVFValue* baseNode = this;
777
- if (const GepValVar* valVar = SVFUtil::dyn_cast<GepValVar>(this))
778
- {
779
- baseNode = valVar->getBaseNode();
780
- }
781
- else if (const GepObjVar* objVar = SVFUtil::dyn_cast<GepObjVar>(this))
782
- {
783
- baseNode = objVar->getBaseObj();
784
- }
785
- if (SVFUtil::isa<DummyObjVar, DummyValVar, BlackHoleValVar>(baseNode))
786
- rawstr << "";
787
- else
788
- {
789
- auto llvmVal =
790
- LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(baseNode);
791
- if (llvmVal)
792
- rawstr << " " << *llvmVal << " ";
793
- else
794
- rawstr << "";
795
- }
796
- }
780
+ rawstr << "";
797
781
  rawstr << getSourceLoc();
798
782
  return rawstr.str();
799
783
  }
@@ -134,6 +134,45 @@ LLVMContext &ObjTypeInference::getLLVMCtx()
134
134
  * @param val
135
135
  */
136
136
  const Type *ObjTypeInference::inferObjType(const Value *var)
137
+ {
138
+ const Type* res = inferPointsToType(var);
139
+ // infer type by leveraging the type alignment of src and dst in memcpy
140
+ // for example,
141
+ //
142
+ // %tmp = alloca %struct.outer
143
+ // %inner_v = alloca %struct.inner
144
+ // %ptr = getelementptr inbounds %struct.outer, ptr %tmp, i32 0, i32 1, !dbg !38
145
+ // %0 = load ptr, ptr %ptr, align 8, !dbg !38
146
+ // call void @llvm.memcpy.p0.p0.i64(ptr %inner_v, ptr %0, i64 24, i1 false)
147
+ //
148
+ // It is difficult to infer the type of %0 without deep alias analysis,
149
+ // but we can infer the obj type of %0 based on that of %inner_v.
150
+ if (res == defaultType(var))
151
+ {
152
+ for (const auto& use: var->users())
153
+ {
154
+ if (const CallBase* cs = SVFUtil::dyn_cast<CallBase>(use))
155
+ {
156
+ if (const Function* calledFun = cs->getCalledFunction())
157
+ if (LLVMUtil::isMemcpyExtFun(LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(calledFun)))
158
+ {
159
+ assert(cs->getNumOperands() > 1 && "arguments should be greater than 1");
160
+ const Value* dst = cs->getArgOperand(0);
161
+ const Value* src = cs->getArgOperand(1);
162
+ if(calledFun->getName().find("iconv") != std::string::npos)
163
+ dst = cs->getArgOperand(3), src = cs->getArgOperand(1);
164
+
165
+ if (var == dst) return inferPointsToType(src);
166
+ else if (var == src) return inferPointsToType(dst);
167
+ else ABORT_MSG("invalid memcpy call");
168
+ }
169
+ }
170
+ }
171
+ }
172
+ return res;
173
+ }
174
+
175
+ const Type *ObjTypeInference::inferPointsToType(const Value *var)
137
176
  {
138
177
  if (isAlloc(var)) return fwInferObjType(var);
139
178
  Set<const Value *> &sources = bwfindAllocOfVar(var);
@@ -1384,6 +1384,27 @@ void SVFIRBuilder::handleDirectCall(CallBase* cs, const Function *F)
1384
1384
  }
1385
1385
  }
1386
1386
 
1387
+ /*!
1388
+ * Example 1:
1389
+
1390
+ %0 = getelementptr inbounds %struct.outer, %struct.inner %base, i32 0, i32 0
1391
+ call void @llvm.memcpy(ptr %inner, ptr %0, i64 24, i1 false)
1392
+ The base value for %0 is %base.
1393
+ Note: the %base is recognized as the base value if the offset (field index) is 0
1394
+
1395
+ * Example 2:
1396
+ * https://github.com/SVF-tools/SVF/issues/1650
1397
+ https://github.com/SVF-tools/SVF/pull/1652
1398
+
1399
+ @i1 = dso_local global %struct.inner { i32 0, ptr @f1, ptr @f2 }
1400
+ @n1 = dso_local global %struct.outer { i32 0, ptr @i1 }
1401
+
1402
+ %inner = alloca %struct.inner
1403
+ %0 = load ptr, ptr getelementptr inbounds (%struct.outer, ptr @n1, i32 0, i32 1)
1404
+ call void @llvm.memcpy(ptr %inner, ptr %0, i64 24, i1 false)
1405
+
1406
+ The base value for %0 is @i1
1407
+ */
1387
1408
  const Value* SVFIRBuilder::getBaseValueForExtArg(const Value* V)
1388
1409
  {
1389
1410
  const Value* value = stripAllCasts(V);
@@ -1399,6 +1420,36 @@ const Value* SVFIRBuilder::getBaseValueForExtArg(const Value* V)
1399
1420
  if(totalidx == 0 && !SVFUtil::isa<StructType>(value->getType()))
1400
1421
  value = gep->getPointerOperand();
1401
1422
  }
1423
+ else if (const LoadInst* load = SVFUtil::dyn_cast<LoadInst>(value))
1424
+ {
1425
+ const Value* loadP = load->getPointerOperand();
1426
+ if (const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(loadP))
1427
+ {
1428
+ APOffset totalidx = 0;
1429
+ for (bridge_gep_iterator gi = bridge_gep_begin(gep), ge = bridge_gep_end(gep); gi != ge; ++gi)
1430
+ {
1431
+ if(const ConstantInt* op = SVFUtil::dyn_cast<ConstantInt>(gi.getOperand()))
1432
+ totalidx += LLVMUtil::getIntegerValue(op).first;
1433
+ }
1434
+ const Value * pointer_operand = gep->getPointerOperand();
1435
+ if (auto *glob = SVFUtil::dyn_cast<GlobalVariable>(pointer_operand))
1436
+ {
1437
+ if (glob->hasInitializer())
1438
+ {
1439
+ if (auto *initializer = SVFUtil::dyn_cast<
1440
+ ConstantStruct>(glob->getInitializer()))
1441
+ {
1442
+ auto *ptrField = initializer->getOperand(totalidx);
1443
+ if (auto *ptrValue = SVFUtil::dyn_cast<llvm::GlobalVariable>(ptrField))
1444
+ {
1445
+ return ptrValue;
1446
+ }
1447
+ }
1448
+ }
1449
+ }
1450
+ }
1451
+ }
1452
+
1402
1453
  return value;
1403
1454
  }
1404
1455
 
@@ -62,7 +62,7 @@ std::string printPts(PointerAnalysis* pta, const SVFVar* svfval)
62
62
  {
63
63
  rawstr << " " << *ii << " ";
64
64
  PAGNode* targetObj = pta->getPAG()->getGNode(*ii);
65
- rawstr << "(" << targetObj->valueOnlyToString() << ")\t ";
65
+ rawstr << "(" << targetObj->toString() << ")\t ";
66
66
  }
67
67
 
68
68
  return rawstr.str();