svf-tools 1.0.702 → 1.0.703
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/include/SVFIR/SVFIR.h +13 -0
- package/svf/include/Util/ExtAPI.h +3 -0
- package/svf/include/Util/ExtAPI.json +0 -7
- package/svf/include/Util/SVFUtil.h +6 -0
- package/svf/lib/Util/ExtAPI.cpp +7 -0
- package/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +5 -4
- package/svf-llvm/lib/SVFIRBuilder.cpp +128 -83
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.703",
|
|
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": {
|
|
@@ -69,6 +69,8 @@ public:
|
|
|
69
69
|
typedef Map<NodeOffset,NodeID> NodeOffsetMap;
|
|
70
70
|
typedef Map<NodeLocationSet,NodeID> NodeLocationSetMap;
|
|
71
71
|
typedef Map<const SVFValue*, NodeLocationSetMap> GepValueVarMap;
|
|
72
|
+
typedef std::pair<const SVFType*, std::vector<LocationSet>> SVFTypeLocSetsPair;
|
|
73
|
+
typedef Map<NodeID, SVFTypeLocSetsPair> TypeLocSetsMap;
|
|
72
74
|
typedef Map<NodePair,NodeID> NodePairSetMap;
|
|
73
75
|
|
|
74
76
|
private:
|
|
@@ -77,6 +79,7 @@ private:
|
|
|
77
79
|
ICFGNode2SVFStmtsMap icfgNode2SVFStmtsMap; ///< Map an ICFGNode to its SVFStmts
|
|
78
80
|
ICFGNode2SVFStmtsMap icfgNode2PTASVFStmtsMap; ///< Map an ICFGNode to its PointerAnalysis related SVFStmts
|
|
79
81
|
GepValueVarMap GepValObjMap; ///< Map a pair<base,off> to a gep value node id
|
|
82
|
+
TypeLocSetsMap typeLocSetsMap; ///< Map an arg to its base SVFType* and all its field location sets
|
|
80
83
|
NodeLocationSetMap GepObjVarMap; ///< Map a pair<base,off> to a gep obj node id
|
|
81
84
|
MemObjToFieldsMap memToFieldsMap; ///< Map a mem object id to all its fields
|
|
82
85
|
SVFStmtSet globSVFStmtSet; ///< Global PAGEdges without control flow information
|
|
@@ -218,6 +221,16 @@ public:
|
|
|
218
221
|
if (edge->isPTAEdge())
|
|
219
222
|
icfgNode2PTASVFStmtsMap[inst].push_back(edge);
|
|
220
223
|
}
|
|
224
|
+
/// Add a base SVFType* and all its field location sets to an arg NodeId
|
|
225
|
+
inline void addToTypeLocSetsMap(NodeID argId, SVFTypeLocSetsPair& locSets)
|
|
226
|
+
{
|
|
227
|
+
typeLocSetsMap[argId]=locSets;
|
|
228
|
+
}
|
|
229
|
+
/// Given an arg NodeId, get its base SVFType* and all its field location sets
|
|
230
|
+
inline SVFTypeLocSetsPair& getTypeLocSetsMap(NodeID argId)
|
|
231
|
+
{
|
|
232
|
+
return typeLocSetsMap[argId];
|
|
233
|
+
}
|
|
221
234
|
/// Get global PAGEdges (not in a procedure)
|
|
222
235
|
inline SVFStmtSet& getGlobalSVFStmtSet()
|
|
223
236
|
{
|
|
@@ -306,6 +306,9 @@ public:
|
|
|
306
306
|
// Assuming hasStatic(F), does (F) have a second static Y where X -> Y?
|
|
307
307
|
bool has_static2(const SVFFunction *F);
|
|
308
308
|
|
|
309
|
+
// Does (F) have a memset_like or memcpy_like operation?
|
|
310
|
+
bool is_memset_or_memcpy(const SVFFunction *F);
|
|
311
|
+
|
|
309
312
|
// Does (F) allocate a new object and return it?
|
|
310
313
|
bool is_alloc(const SVFFunction *F);
|
|
311
314
|
|
|
@@ -5096,13 +5096,6 @@
|
|
|
5096
5096
|
"dst": "Ret"
|
|
5097
5097
|
}
|
|
5098
5098
|
},
|
|
5099
|
-
"dlsym": {
|
|
5100
|
-
"return": "void *",
|
|
5101
|
-
"arguments": "(void *, const char *)",
|
|
5102
|
-
"type": "EFT_L_A1__FunPtr",
|
|
5103
|
-
"overwrite_app_function": 0,
|
|
5104
|
-
"funptr_ops": ["Arg1"]
|
|
5105
|
-
},
|
|
5106
5099
|
"bcopy": {
|
|
5107
5100
|
"return": "void",
|
|
5108
5101
|
"arguments": "(const void *, void *, size_t)",
|
|
@@ -299,6 +299,12 @@ inline bool isExtCall(const SVFFunction* fun)
|
|
|
299
299
|
return fun && ExtAPI::getExtAPI()->is_ext(fun);
|
|
300
300
|
}
|
|
301
301
|
|
|
302
|
+
// Return true if extern function contains memset_like or memcpy_like operations
|
|
303
|
+
inline bool isMemSetOrCpyExtFun(const SVFFunction* fun)
|
|
304
|
+
{
|
|
305
|
+
return fun && ExtAPI::getExtAPI()->is_memset_or_memcpy(fun);
|
|
306
|
+
}
|
|
307
|
+
|
|
302
308
|
/// Return true if the call is a heap allocator/reallocator
|
|
303
309
|
//@{
|
|
304
310
|
/// note that these two functions are not suppose to be used externally
|
package/svf/lib/Util/ExtAPI.cpp
CHANGED
|
@@ -443,6 +443,13 @@ bool ExtAPI::has_static2(const SVFFunction* F)
|
|
|
443
443
|
return t == EFT_STAT2;
|
|
444
444
|
}
|
|
445
445
|
|
|
446
|
+
bool ExtAPI::is_memset_or_memcpy(const SVFFunction* F)
|
|
447
|
+
{
|
|
448
|
+
ExtAPI::extType t = get_type(F);
|
|
449
|
+
return t == EFT_L_A0__A0R_A1 || t == EFT_L_A0__A0R_A1R || t == EFT_A1R_A0R || t == EFT_A3R_A1R_NS
|
|
450
|
+
|| t == EFT_STD_RB_TREE_INSERT_AND_REBALANCE || t == EFT_L_A0__A1_A0;
|
|
451
|
+
}
|
|
452
|
+
|
|
446
453
|
bool ExtAPI::is_alloc(const SVFFunction* F)
|
|
447
454
|
{
|
|
448
455
|
ExtAPI::extType t = get_type(F);
|
|
@@ -235,9 +235,10 @@ protected:
|
|
|
235
235
|
|
|
236
236
|
/// Handle external call
|
|
237
237
|
//@{
|
|
238
|
-
virtual void parseOperations(std::vector<ExtAPI::Operation> &operations,
|
|
239
|
-
virtual void
|
|
240
|
-
void
|
|
238
|
+
virtual void parseOperations(std::vector<ExtAPI::Operation> &operations, const SVFCallInst* svfcall);
|
|
239
|
+
virtual void preProcessExtCall(CallBase* cs);
|
|
240
|
+
virtual void handleExtCall(SVFInstruction* svfinst, const SVFFunction* svfcallee);
|
|
241
|
+
void addComplexConsForExt(const SVFValue* D, const SVFValue* S, const SVFValue* sz);
|
|
241
242
|
//@}
|
|
242
243
|
|
|
243
244
|
/// Set current basic block in order to keep track of control flow information
|
|
@@ -281,7 +282,7 @@ protected:
|
|
|
281
282
|
return nullPtr;
|
|
282
283
|
}
|
|
283
284
|
|
|
284
|
-
NodeID getGepValVar(const
|
|
285
|
+
NodeID getGepValVar(const SVFValue* val, const LocationSet& ls, const SVFType* baseType);
|
|
285
286
|
|
|
286
287
|
void setCurrentBBAndValueForPAGEdge(PAGEdge* edge);
|
|
287
288
|
|
|
@@ -470,7 +470,7 @@ NodeID SVFIRBuilder::getGlobalVarField(const GlobalVariable *gvar, u32_t offset,
|
|
|
470
470
|
/// then we need to create a gep node for this field
|
|
471
471
|
else
|
|
472
472
|
{
|
|
473
|
-
return getGepValVar(gvar, LocationSet(offset), tpy);
|
|
473
|
+
return getGepValVar(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(gvar), LocationSet(offset), tpy);
|
|
474
474
|
}
|
|
475
475
|
}
|
|
476
476
|
|
|
@@ -847,7 +847,9 @@ void SVFIRBuilder::visitCallSite(CallBase* cs)
|
|
|
847
847
|
if (isExtCall(svfcallee))
|
|
848
848
|
{
|
|
849
849
|
// There is no extpag for the function, use the old method.
|
|
850
|
-
|
|
850
|
+
preProcessExtCall(cs);
|
|
851
|
+
SVFInstruction* svfinst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(cs);
|
|
852
|
+
handleExtCall(svfinst, svfcallee);
|
|
851
853
|
}
|
|
852
854
|
else
|
|
853
855
|
{
|
|
@@ -1154,20 +1156,21 @@ const Type* SVFIRBuilder::getBaseTypeAndFlattenedFields(const Value* V, std::vec
|
|
|
1154
1156
|
* Add the load/store constraints and temp. nodes for the complex constraint
|
|
1155
1157
|
* *D = *S (where D/S may point to structs).
|
|
1156
1158
|
*/
|
|
1157
|
-
void SVFIRBuilder::addComplexConsForExt(const
|
|
1159
|
+
void SVFIRBuilder::addComplexConsForExt(const SVFValue* D, const SVFValue* S, const SVFValue* szValue)
|
|
1158
1160
|
{
|
|
1159
1161
|
assert(D && S);
|
|
1160
|
-
NodeID vnD= getValueNode(D), vnS= getValueNode(S);
|
|
1162
|
+
NodeID vnD= pag->getValueNode(D), vnS= pag->getValueNode(S);
|
|
1161
1163
|
if(!vnD || !vnS)
|
|
1162
1164
|
return;
|
|
1163
1165
|
|
|
1164
1166
|
std::vector<LocationSet> fields;
|
|
1165
1167
|
|
|
1166
1168
|
//Get the max possible size of the copy, unless it was provided.
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1169
|
+
const SVFType* stype = pag->getTypeLocSetsMap(vnS).first;
|
|
1170
|
+
const SVFType* dtype = pag->getTypeLocSetsMap(vnD).first;
|
|
1171
|
+
std::vector<LocationSet> srcFields = pag->getTypeLocSetsMap(vnS).second;
|
|
1172
|
+
std::vector<LocationSet> dstFields = pag->getTypeLocSetsMap(vnD).second;
|
|
1173
|
+
|
|
1171
1174
|
if(srcFields.size() > dstFields.size())
|
|
1172
1175
|
fields = dstFields;
|
|
1173
1176
|
else
|
|
@@ -1175,8 +1178,13 @@ void SVFIRBuilder::addComplexConsForExt(const Value* D, const Value* S, const Va
|
|
|
1175
1178
|
|
|
1176
1179
|
/// If sz is 0, we will add edges for all fields.
|
|
1177
1180
|
u32_t sz = fields.size();
|
|
1181
|
+
if (szValue && SVFUtil::dyn_cast<SVFConstantInt>(szValue))
|
|
1182
|
+
{
|
|
1183
|
+
const SVFConstantInt* arg2 = SVFUtil::dyn_cast<SVFConstantInt>(szValue);
|
|
1184
|
+
sz = (fields.size() > static_cast<u32_t>(arg2->getSExtValue())) ? arg2->getSExtValue() : fields.size();
|
|
1185
|
+
}
|
|
1178
1186
|
|
|
1179
|
-
if (fields.size() == 1 && (
|
|
1187
|
+
if (fields.size() == 1 && (SVFUtil::isa<SVFConstantData>(D) || SVFUtil::isa<SVFConstantData>(S)))
|
|
1180
1188
|
{
|
|
1181
1189
|
NodeID dummy = pag->addDummyValNode();
|
|
1182
1190
|
addLoadEdge(vnD,dummy);
|
|
@@ -1187,10 +1195,9 @@ void SVFIRBuilder::addComplexConsForExt(const Value* D, const Value* S, const Va
|
|
|
1187
1195
|
//For each field (i), add (Ti = *S + i) and (*D + i = Ti).
|
|
1188
1196
|
for (u32_t index = 0; index < sz; index++)
|
|
1189
1197
|
{
|
|
1190
|
-
|
|
1191
|
-
const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType(llvmmodule->getSVFType(dtype),
|
|
1198
|
+
const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType(dtype,
|
|
1192
1199
|
fields[index].getConstantFieldIdx());
|
|
1193
|
-
const SVFType* sElementType = pag->getSymbolInfo()->getFlatternedElemType(
|
|
1200
|
+
const SVFType* sElementType = pag->getSymbolInfo()->getFlatternedElemType(stype,
|
|
1194
1201
|
fields[index].getConstantFieldIdx());
|
|
1195
1202
|
NodeID dField = getGepValVar(D,fields[index],dElementType);
|
|
1196
1203
|
NodeID sField = getGepValVar(S,fields[index],sElementType);
|
|
@@ -1200,7 +1207,7 @@ void SVFIRBuilder::addComplexConsForExt(const Value* D, const Value* S, const Va
|
|
|
1200
1207
|
}
|
|
1201
1208
|
}
|
|
1202
1209
|
|
|
1203
|
-
void SVFIRBuilder::parseOperations(std::vector<ExtAPI::Operation> &operations,
|
|
1210
|
+
void SVFIRBuilder::parseOperations(std::vector<ExtAPI::Operation> &operations, const SVFCallInst* svfcall)
|
|
1204
1211
|
{
|
|
1205
1212
|
// Record all dummy nodes
|
|
1206
1213
|
std::map<std::string, NodeID> nodeIDMap;
|
|
@@ -1219,7 +1226,7 @@ void SVFIRBuilder::parseOperations(std::vector<ExtAPI::Operation> &operations,
|
|
|
1219
1226
|
s32_t nodeIDType = ExtAPI::getExtAPI()->getNodeIDType(s);
|
|
1220
1227
|
if (nodeIDType >= 0)
|
|
1221
1228
|
{
|
|
1222
|
-
if(
|
|
1229
|
+
if( svfcall->arg_size() <= (u32_t) nodeIDType)
|
|
1223
1230
|
assert(false && "Argument out of bounds!");
|
|
1224
1231
|
else if (operation.getOperator() == "memcpy_like" || operation.getOperator() == "memset_like")
|
|
1225
1232
|
{
|
|
@@ -1228,14 +1235,14 @@ void SVFIRBuilder::parseOperations(std::vector<ExtAPI::Operation> &operations,
|
|
|
1228
1235
|
}
|
|
1229
1236
|
else
|
|
1230
1237
|
{
|
|
1231
|
-
operands.push_back(getValueNode(
|
|
1232
|
-
nodeIDMap[s] = getValueNode(
|
|
1238
|
+
operands.push_back(pag->getValueNode(svfcall->getArgOperand(nodeIDType)));
|
|
1239
|
+
nodeIDMap[s] = pag->getValueNode(svfcall->getArgOperand(nodeIDType));
|
|
1233
1240
|
}
|
|
1234
1241
|
}
|
|
1235
1242
|
else if (nodeIDType == -1)
|
|
1236
1243
|
{
|
|
1237
|
-
operands.push_back(getValueNode(
|
|
1238
|
-
nodeIDMap[s] = getValueNode(
|
|
1244
|
+
operands.push_back(pag->getValueNode(svfcall));
|
|
1245
|
+
nodeIDMap[s] = pag->getValueNode(svfcall);
|
|
1239
1246
|
}
|
|
1240
1247
|
else if (nodeIDType == -2)
|
|
1241
1248
|
{
|
|
@@ -1244,10 +1251,10 @@ void SVFIRBuilder::parseOperations(std::vector<ExtAPI::Operation> &operations,
|
|
|
1244
1251
|
}
|
|
1245
1252
|
else if (nodeIDType == -3)
|
|
1246
1253
|
{
|
|
1247
|
-
if (
|
|
1254
|
+
if (svfcall->getType()->isPointerTy())
|
|
1248
1255
|
{
|
|
1249
|
-
operands.push_back(getObjectNode(
|
|
1250
|
-
nodeIDMap[s] = getObjectNode(
|
|
1256
|
+
operands.push_back(pag->getObjectNode(svfcall));
|
|
1257
|
+
nodeIDMap[s] = pag->getObjectNode(svfcall);
|
|
1251
1258
|
}
|
|
1252
1259
|
}
|
|
1253
1260
|
else if (nodeIDType == -4)
|
|
@@ -1272,21 +1279,87 @@ void SVFIRBuilder::parseOperations(std::vector<ExtAPI::Operation> &operations,
|
|
|
1272
1279
|
}
|
|
1273
1280
|
}
|
|
1274
1281
|
|
|
1282
|
+
void SVFIRBuilder::preProcessExtCall(CallBase* cs)
|
|
1283
|
+
{
|
|
1284
|
+
const SVFInstruction* svfinst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(cs);
|
|
1285
|
+
const SVFCallInst* svfcall = SVFUtil::cast<SVFCallInst>(svfinst);
|
|
1286
|
+
/// Currently focusing on providing specialized treatment for the extern function void *dlsym(void *handle, const char *funname)
|
|
1287
|
+
/// and generalization will be done later.
|
|
1288
|
+
if (svfcall->getCalledFunction()->getName() == "dlsym")
|
|
1289
|
+
{
|
|
1290
|
+
const Value* src = cs->getArgOperand(1);
|
|
1291
|
+
if(const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(src))
|
|
1292
|
+
src = stripConstantCasts(gep->getPointerOperand());
|
|
1293
|
+
|
|
1294
|
+
auto getHookFn = [](const Value* src)->const Function*
|
|
1295
|
+
{
|
|
1296
|
+
if (!SVFUtil::isa<GlobalVariable>(src))
|
|
1297
|
+
return nullptr;
|
|
1298
|
+
|
|
1299
|
+
auto *glob = SVFUtil::cast<GlobalVariable>(src);
|
|
1300
|
+
if (!glob->hasInitializer() || !SVFUtil::isa<ConstantDataArray>(glob->getInitializer()))
|
|
1301
|
+
return nullptr;
|
|
1302
|
+
|
|
1303
|
+
auto *constarray = SVFUtil::cast<ConstantDataArray>(glob->getInitializer());
|
|
1304
|
+
return LLVMUtil::getProgFunction(constarray->getAsCString().str());
|
|
1305
|
+
};
|
|
1306
|
+
|
|
1307
|
+
if (const Function *fn = getHookFn(src))
|
|
1308
|
+
{
|
|
1309
|
+
NodeID srcNode = getValueNode(fn);
|
|
1310
|
+
addCopyEdge(srcNode, getValueNode(cs));
|
|
1311
|
+
}
|
|
1312
|
+
return;
|
|
1313
|
+
}
|
|
1314
|
+
/// Preprocess the arguments of functions such as memset() and memcpy() that involve arrays or structures,
|
|
1315
|
+
/// and identify the original data types of these arguments, flattening each subfield.
|
|
1316
|
+
if (isMemSetOrCpyExtFun(svfcall->getCalledFunction()))
|
|
1317
|
+
{
|
|
1318
|
+
for (u32_t i = 0; i < cs->arg_size(); i++)
|
|
1319
|
+
{
|
|
1320
|
+
const Type* T = getBaseValueForExtArg(cs->getArgOperand(i))->getType();
|
|
1321
|
+
while (const PointerType *ptype = SVFUtil::dyn_cast<PointerType>(T))
|
|
1322
|
+
T = getPtrElementType(ptype);
|
|
1323
|
+
const SVFType *st = LLVMModuleSet::getLLVMModuleSet()->getSVFType(T);
|
|
1324
|
+
std::vector<LocationSet> fields;
|
|
1325
|
+
u32_t numOfElems = pag->getSymbolInfo()->getNumOfFlattenElements(st);
|
|
1326
|
+
LLVMContext& context = LLVMModuleSet::getLLVMModuleSet()->getContext();
|
|
1327
|
+
for(u32_t ei = 0; ei < numOfElems; ei++)
|
|
1328
|
+
{
|
|
1329
|
+
LocationSet ls(ei);
|
|
1330
|
+
// make a ConstantInt and create char for the content type due to byte-wise copy
|
|
1331
|
+
const ConstantInt* offset = ConstantInt::get(context, llvm::APInt(32, ei));
|
|
1332
|
+
const SVFValue* svfOffset = LLVMModuleSet::getLLVMModuleSet()->getSVFValue(offset);
|
|
1333
|
+
if (!pag->getSymbolInfo()->hasValSym(svfOffset))
|
|
1334
|
+
{
|
|
1335
|
+
SymbolTableBuilder builder(pag->getSymbolInfo());
|
|
1336
|
+
builder.collectSym(offset);
|
|
1337
|
+
pag->addValNode(svfOffset, pag->getSymbolInfo()->getValSym(svfOffset));
|
|
1338
|
+
}
|
|
1339
|
+
ls.addOffsetVarAndGepTypePair(getPAG()->getGNode(getPAG()->getValueNode(svfOffset)), nullptr);
|
|
1340
|
+
fields.push_back(ls);
|
|
1341
|
+
}
|
|
1342
|
+
NodeID argId = pag->getValueNode(svfcall->getArgOperand(i));
|
|
1343
|
+
std::pair<const SVFType*, std::vector<LocationSet>> pairToInsert = std::make_pair(st, fields);
|
|
1344
|
+
pag->addToTypeLocSetsMap(argId, pairToInsert);
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1275
1349
|
/*!
|
|
1276
1350
|
* Handle external calls
|
|
1277
1351
|
*/
|
|
1278
|
-
void SVFIRBuilder::handleExtCall(
|
|
1352
|
+
void SVFIRBuilder::handleExtCall(SVFInstruction* svfinst, const SVFFunction* svfcallee)
|
|
1279
1353
|
{
|
|
1280
|
-
const
|
|
1281
|
-
const SVFFunction* svfcallee = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(callee);
|
|
1354
|
+
const SVFCallInst* svfcall = SVFUtil::cast<SVFCallInst>(svfinst);
|
|
1282
1355
|
|
|
1283
1356
|
if (isHeapAllocOrStaticExtCall(svfinst))
|
|
1284
1357
|
{
|
|
1285
1358
|
// case 1: ret = new obj
|
|
1286
1359
|
if (isHeapAllocExtCallViaRet(svfinst) || isStaticExtCall(svfinst))
|
|
1287
1360
|
{
|
|
1288
|
-
NodeID val = getValueNode(
|
|
1289
|
-
NodeID obj = getObjectNode(
|
|
1361
|
+
NodeID val = pag->getValueNode(svfinst);
|
|
1362
|
+
NodeID obj = pag->getObjectNode(svfinst);
|
|
1290
1363
|
addAddrEdge(obj, val);
|
|
1291
1364
|
}
|
|
1292
1365
|
// case 2: *arg = new obj
|
|
@@ -1294,12 +1367,12 @@ void SVFIRBuilder::handleExtCall(CallBase* cs, const Function *callee)
|
|
|
1294
1367
|
{
|
|
1295
1368
|
assert(isHeapAllocExtCallViaArg(svfinst) && "Must be heap alloc call via arg.");
|
|
1296
1369
|
u32_t arg_pos = getHeapAllocHoldingArgPosition(svfcallee);
|
|
1297
|
-
const
|
|
1370
|
+
const SVFValue* arg = svfcall->getArgOperand(arg_pos);
|
|
1298
1371
|
if (arg->getType()->isPointerTy())
|
|
1299
1372
|
{
|
|
1300
|
-
NodeID vnArg = getValueNode(arg);
|
|
1373
|
+
NodeID vnArg = pag->getValueNode(arg);
|
|
1301
1374
|
NodeID dummy = pag->addDummyValNode();
|
|
1302
|
-
NodeID obj = pag->addDummyObjNode(
|
|
1375
|
+
NodeID obj = pag->addDummyObjNode(arg->getType());
|
|
1303
1376
|
if (vnArg && dummy && obj)
|
|
1304
1377
|
{
|
|
1305
1378
|
addAddrEdge(obj, dummy);
|
|
@@ -1322,12 +1395,12 @@ void SVFIRBuilder::handleExtCall(CallBase* cs, const Function *callee)
|
|
|
1322
1395
|
{
|
|
1323
1396
|
std::string str;
|
|
1324
1397
|
std::stringstream rawstr(str);
|
|
1325
|
-
rawstr << "function " <<
|
|
1398
|
+
rawstr << "function " << funName << " not in the external function summary ExtAPI.json file";
|
|
1326
1399
|
writeWrnMsg(rawstr.str());
|
|
1327
1400
|
}
|
|
1328
1401
|
else
|
|
1329
1402
|
{
|
|
1330
|
-
parseOperations(allOperations,
|
|
1403
|
+
parseOperations(allOperations, svfcall);
|
|
1331
1404
|
for (ExtAPI::Operation op : allOperations)
|
|
1332
1405
|
{
|
|
1333
1406
|
if (op.getOperator() == "AddrStmt")
|
|
@@ -1393,69 +1466,40 @@ void SVFIRBuilder::handleExtCall(CallBase* cs, const Function *callee)
|
|
|
1393
1466
|
{
|
|
1394
1467
|
// this is for memset(void *str, int c, size_t n)
|
|
1395
1468
|
// which copies the character c (an unsigned char) to the first n characters of the string pointed to, by the argument str
|
|
1396
|
-
|
|
1397
|
-
|
|
1469
|
+
// const SVFConstantInt* arg2 = SVFUtil::dyn_cast<SVFConstantInt>(svfcall->getArgOperand(op.getOperands()[2]));
|
|
1470
|
+
NodeID argId = pag->getValueNode(svfcall->getArgOperand(op.getOperands()[0]));
|
|
1471
|
+
std::vector<LocationSet> dstFields = pag->getTypeLocSetsMap(argId).second;
|
|
1398
1472
|
u32_t sz = dstFields.size();
|
|
1473
|
+
if (const SVFConstantInt* arg2 = SVFUtil::dyn_cast<SVFConstantInt>(svfcall->getArgOperand(op.getOperands()[2])))
|
|
1474
|
+
sz = (dstFields.size() > static_cast<u32_t>(arg2->getSExtValue())) ? arg2->getSExtValue() : dstFields.size();
|
|
1399
1475
|
//For each field (i), add store edge *(arg0 + i) = arg1
|
|
1400
1476
|
for (u32_t index = 0; index < sz; index++)
|
|
1401
1477
|
{
|
|
1402
|
-
const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType(
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
addStoreEdge(getValueNode(cs->getArgOperand(op.getOperands()[1])),dField);
|
|
1478
|
+
const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType(pag->getTypeLocSetsMap(argId).first, dstFields[index].getConstantFieldIdx());
|
|
1479
|
+
NodeID dField = getGepValVar(svfcall->getArgOperand(op.getOperands()[0]), dstFields[index], dElementType);
|
|
1480
|
+
addStoreEdge(pag->getValueNode(svfcall->getArgOperand(op.getOperands()[1])),dField);
|
|
1406
1481
|
}
|
|
1407
|
-
if(
|
|
1408
|
-
addCopyEdge(getValueNode(
|
|
1482
|
+
if(svfcall->getType()->isPointerTy())
|
|
1483
|
+
addCopyEdge(pag->getValueNode(svfcall->getArgOperand(op.getOperands()[0])), pag->getValueNode(svfinst));
|
|
1409
1484
|
}
|
|
1410
1485
|
else if (op.getOperator() == "memcpy_like")
|
|
1411
1486
|
{
|
|
1412
|
-
/// handle strcpy
|
|
1413
1487
|
if(op.getOperands().size() == 3)
|
|
1414
|
-
addComplexConsForExt(
|
|
1488
|
+
addComplexConsForExt(svfcall->getArgOperand(op.getOperands()[0]), svfcall->getArgOperand(op.getOperands()[1]), svfcall->getArgOperand(op.getOperands()[2]));
|
|
1415
1489
|
else
|
|
1416
|
-
addComplexConsForExt(
|
|
1417
|
-
}
|
|
1418
|
-
else if (op.getOperator() == "funptr_ops")
|
|
1419
|
-
{
|
|
1420
|
-
/// handling external function e.g., void *dlsym(void *handle, const char *funname);
|
|
1421
|
-
const Value* src = cs->getArgOperand(1);
|
|
1422
|
-
if(const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(src))
|
|
1423
|
-
src = stripConstantCasts(gep->getPointerOperand());
|
|
1424
|
-
|
|
1425
|
-
auto getHookFn = [](const Value* src)->const Function*
|
|
1426
|
-
{
|
|
1427
|
-
if (!SVFUtil::isa<GlobalVariable>(src))
|
|
1428
|
-
return nullptr;
|
|
1429
|
-
|
|
1430
|
-
auto *glob = SVFUtil::cast<GlobalVariable>(src);
|
|
1431
|
-
if (!glob->hasInitializer() || !SVFUtil::isa<ConstantDataArray>(glob->getInitializer()))
|
|
1432
|
-
return nullptr;
|
|
1433
|
-
|
|
1434
|
-
auto *constarray = SVFUtil::cast<ConstantDataArray>(glob->getInitializer());
|
|
1435
|
-
return LLVMUtil::getProgFunction(constarray->getAsCString().str());
|
|
1436
|
-
};
|
|
1437
|
-
|
|
1438
|
-
if (const Function *fn = getHookFn(src))
|
|
1439
|
-
{
|
|
1440
|
-
NodeID srcNode = getValueNode(fn);
|
|
1441
|
-
addCopyEdge(srcNode, getValueNode(cs));
|
|
1442
|
-
}
|
|
1490
|
+
addComplexConsForExt(svfcall->getArgOperand(op.getOperands()[0]), svfcall->getArgOperand(op.getOperands()[1]), nullptr);
|
|
1443
1491
|
}
|
|
1444
1492
|
else if (op.getOperator() == "Rb_tree_ops")
|
|
1445
1493
|
{
|
|
1446
|
-
assert(
|
|
1447
|
-
|
|
1448
|
-
const Value* vArg1 = cs->getArgOperand(1);
|
|
1449
|
-
const Value* vArg3 = cs->getArgOperand(3);
|
|
1494
|
+
assert(svfcall->arg_size() == 4 && "_Rb_tree_insert_and_rebalance should have 4 arguments.\n");
|
|
1450
1495
|
|
|
1451
1496
|
// We have vArg3 points to the entry of _Rb_tree_node_base { color; parent; left; right; }.
|
|
1452
1497
|
// Now we calculate the offset from base to vArg3
|
|
1453
|
-
NodeID vnArg3 = pag->getValueNode(
|
|
1498
|
+
NodeID vnArg3 = pag->getValueNode(svfcall->getArgOperand(3));
|
|
1454
1499
|
s32_t offset = getLocationSetFromBaseNode(vnArg3).getConstantFieldIdx();
|
|
1455
1500
|
|
|
1456
1501
|
// We get all flattened fields of base
|
|
1457
|
-
vector<LocationSet> fields;
|
|
1458
|
-
const Type* type = getBaseTypeAndFlattenedFields(vArg3, fields, nullptr);
|
|
1502
|
+
vector<LocationSet> fields = pag->getTypeLocSetsMap(vnArg3).second;
|
|
1459
1503
|
|
|
1460
1504
|
// We summarize the side effects: arg3->parent = arg1, arg3->left = arg1, arg3->right = arg1
|
|
1461
1505
|
// Note that arg0 is aligned with "offset".
|
|
@@ -1463,10 +1507,10 @@ void SVFIRBuilder::handleExtCall(CallBase* cs, const Function *callee)
|
|
|
1463
1507
|
{
|
|
1464
1508
|
if((u32_t)i >= fields.size())
|
|
1465
1509
|
break;
|
|
1466
|
-
const SVFType* elementType = pag->getSymbolInfo()->getFlatternedElemType(
|
|
1510
|
+
const SVFType* elementType = pag->getSymbolInfo()->getFlatternedElemType(pag->getTypeLocSetsMap(vnArg3).first,
|
|
1467
1511
|
fields[i].getConstantFieldIdx());
|
|
1468
|
-
NodeID vnD = getGepValVar(
|
|
1469
|
-
NodeID vnS = getValueNode(
|
|
1512
|
+
NodeID vnD = getGepValVar(svfcall->getArgOperand(3), fields[i], elementType);
|
|
1513
|
+
NodeID vnS = pag->getValueNode(svfcall->getArgOperand(1));
|
|
1470
1514
|
if(vnD && vnS)
|
|
1471
1515
|
addStoreEdge(vnS,vnD);
|
|
1472
1516
|
}
|
|
@@ -1574,7 +1618,9 @@ void SVFIRBuilder::updateCallGraph(PTACallGraph* callgraph)
|
|
|
1574
1618
|
if (isExtCall(*func_iter))
|
|
1575
1619
|
{
|
|
1576
1620
|
setCurrentLocation(callee, callee->empty() ? nullptr : &callee->getEntryBlock());
|
|
1577
|
-
|
|
1621
|
+
SVFInstruction* svfinst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(callbase);
|
|
1622
|
+
const SVFFunction* svfcallee = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(callee);
|
|
1623
|
+
handleExtCall(svfinst, svfcallee);
|
|
1578
1624
|
}
|
|
1579
1625
|
else
|
|
1580
1626
|
{
|
|
@@ -1618,9 +1664,9 @@ void SVFIRBuilder::sanityCheck()
|
|
|
1618
1664
|
* Add a temp field value node according to base value and offset
|
|
1619
1665
|
* this node is after the initial node method, it is out of scope of symInfo table
|
|
1620
1666
|
*/
|
|
1621
|
-
NodeID SVFIRBuilder::getGepValVar(const
|
|
1667
|
+
NodeID SVFIRBuilder::getGepValVar(const SVFValue* val, const LocationSet& ls, const SVFType* elementType)
|
|
1622
1668
|
{
|
|
1623
|
-
NodeID base = pag->getBaseValVar(getValueNode(val));
|
|
1669
|
+
NodeID base = pag->getBaseValVar(pag->getValueNode(val));
|
|
1624
1670
|
NodeID gepval = pag->getGepValVar(curVal, base, ls);
|
|
1625
1671
|
if (gepval==UINT_MAX)
|
|
1626
1672
|
{
|
|
@@ -1640,8 +1686,7 @@ NodeID SVFIRBuilder::getGepValVar(const Value* val, const LocationSet& ls, const
|
|
|
1640
1686
|
const SVFValue* cval = getCurrentValue();
|
|
1641
1687
|
const SVFBasicBlock* cbb = getCurrentBB();
|
|
1642
1688
|
setCurrentLocation(curVal, nullptr);
|
|
1643
|
-
|
|
1644
|
-
NodeID gepNode= pag->addGepValNode(curVal, llvmmodule->getSVFValue(val),ls, NodeIDAllocator::get()->allocateValueId(),elementType->getPointerTo());
|
|
1689
|
+
NodeID gepNode= pag->addGepValNode(curVal, val,ls, NodeIDAllocator::get()->allocateValueId(),elementType->getPointerTo());
|
|
1645
1690
|
addGepEdge(base, gepNode, ls, true);
|
|
1646
1691
|
setCurrentLocation(cval, cbb);
|
|
1647
1692
|
return gepNode;
|