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 +1 -1
- package/svf/lib/SVFIR/SVFVariables.cpp +2 -2
- package/svf-llvm/include/SVF-LLVM/ObjTypeInference.h +2 -0
- package/svf-llvm/lib/LLVMUtil.cpp +10 -26
- package/svf-llvm/lib/ObjTypeInference.cpp +39 -0
- package/svf-llvm/lib/SVFIRBuilder.cpp +51 -0
- package/svf-llvm/tools/Example/svf-ex.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.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
|
}
|
|
@@ -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
|
-
|
|
771
|
-
|
|
772
|
-
|
|
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->
|
|
65
|
+
rawstr << "(" << targetObj->toString() << ")\t ";
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
return rawstr.str();
|