svf-tools 1.0.730 → 1.0.732
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/CFL/CFGNormalizer.h +1 -1
- package/svf/include/CFL/CFLAlias.h +2 -2
- package/svf/include/CFL/CFLBase.h +3 -0
- package/svf/include/CFL/CFLGramGraphChecker.h +10 -10
- package/svf/include/CFL/CFLGrammar.h +29 -29
- package/svf/include/CFL/CFLGraphBuilder.h +68 -44
- package/svf/include/CFL/CFLVF.h +3 -0
- package/svf/include/SVFIR/SVFValue.h +7 -0
- package/svf/include/Util/ExtAPI.h +209 -19
- package/svf/include/Util/ExtAPI.json +125 -22
- package/svf/include/Util/Options.h +1 -0
- package/svf/include/Util/SVFUtil.h +12 -5
- package/svf/lib/CFL/CFGNormalizer.cpp +26 -26
- package/svf/lib/CFL/CFLAlias.cpp +3 -0
- package/svf/lib/CFL/CFLBase.cpp +23 -2
- package/svf/lib/CFL/CFLGrammar.cpp +19 -19
- package/svf/lib/CFL/CFLGraphBuilder.cpp +153 -178
- package/svf/lib/CFL/CFLSolver.cpp +3 -3
- package/svf/lib/CFL/CFLVF.cpp +18 -0
- package/svf/lib/Util/ExtAPI.cpp +90 -18
- package/svf/lib/Util/Options.cpp +6 -0
- package/svf-llvm/include/SVF-LLVM/LLVMModule.h +1 -0
- package/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +10 -5
- package/svf-llvm/lib/LLVMUtil.cpp +21 -11
- package/svf-llvm/lib/SVFIRBuilder.cpp +1 -423
- package/svf-llvm/lib/SVFIRExtAPI.cpp +681 -0
- package/svf-llvm/tools/CFL/cfl.cpp +14 -0
|
@@ -848,8 +848,7 @@ void SVFIRBuilder::visitCallSite(CallBase* cs)
|
|
|
848
848
|
{
|
|
849
849
|
// There is no extpag for the function, use the old method.
|
|
850
850
|
preProcessExtCall(cs);
|
|
851
|
-
|
|
852
|
-
handleExtCall(svfinst, svfcallee);
|
|
851
|
+
handleExtCall(svfcall, svfcallee);
|
|
853
852
|
}
|
|
854
853
|
else
|
|
855
854
|
{
|
|
@@ -1115,184 +1114,6 @@ const Value* SVFIRBuilder::getBaseValueForExtArg(const Value* V)
|
|
|
1115
1114
|
return value;
|
|
1116
1115
|
}
|
|
1117
1116
|
|
|
1118
|
-
/*!
|
|
1119
|
-
* Find the base type and the max possible offset of an object pointed to by (V).
|
|
1120
|
-
*/
|
|
1121
|
-
const Type* SVFIRBuilder::getBaseTypeAndFlattenedFields(const Value* V, std::vector<LocationSet> &fields, const Value* szValue)
|
|
1122
|
-
{
|
|
1123
|
-
assert(V);
|
|
1124
|
-
const Value* value = getBaseValueForExtArg(V);
|
|
1125
|
-
const Type* T = value->getType();
|
|
1126
|
-
while (const PointerType *ptype = SVFUtil::dyn_cast<PointerType>(T))
|
|
1127
|
-
T = getPtrElementType(ptype);
|
|
1128
|
-
|
|
1129
|
-
u32_t numOfElems = pag->getSymbolInfo()->getNumOfFlattenElements(LLVMModuleSet::getLLVMModuleSet()->getSVFType(T));
|
|
1130
|
-
/// use user-specified size for this copy operation if the size is a constaint int
|
|
1131
|
-
if(szValue && SVFUtil::isa<ConstantInt>(szValue))
|
|
1132
|
-
{
|
|
1133
|
-
numOfElems = (numOfElems > SVFUtil::cast<ConstantInt>(szValue)->getSExtValue()) ? SVFUtil::cast<ConstantInt>(szValue)->getSExtValue() : numOfElems;
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
|
-
LLVMContext& context = LLVMModuleSet::getLLVMModuleSet()->getContext();
|
|
1137
|
-
for(u32_t ei = 0; ei < numOfElems; ei++)
|
|
1138
|
-
{
|
|
1139
|
-
LocationSet ls(ei);
|
|
1140
|
-
// make a ConstantInt and create char for the content type due to byte-wise copy
|
|
1141
|
-
const ConstantInt* offset = ConstantInt::get(context, llvm::APInt(32, ei));
|
|
1142
|
-
const SVFValue* svfOffset = LLVMModuleSet::getLLVMModuleSet()->getSVFValue(offset);
|
|
1143
|
-
if (!pag->getSymbolInfo()->hasValSym(svfOffset))
|
|
1144
|
-
{
|
|
1145
|
-
SymbolTableBuilder builder(pag->getSymbolInfo());
|
|
1146
|
-
builder.collectSym(offset);
|
|
1147
|
-
pag->addValNode(svfOffset, pag->getSymbolInfo()->getValSym(svfOffset));
|
|
1148
|
-
}
|
|
1149
|
-
ls.addOffsetVarAndGepTypePair(getPAG()->getGNode(getPAG()->getValueNode(svfOffset)), nullptr);
|
|
1150
|
-
fields.push_back(ls);
|
|
1151
|
-
}
|
|
1152
|
-
return T;
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
/*!
|
|
1156
|
-
* Add the load/store constraints and temp. nodes for the complex constraint
|
|
1157
|
-
* *D = *S (where D/S may point to structs).
|
|
1158
|
-
*/
|
|
1159
|
-
void SVFIRBuilder::addComplexConsForExt(const SVFValue* D, const SVFValue* S, const SVFValue* szValue)
|
|
1160
|
-
{
|
|
1161
|
-
assert(D && S);
|
|
1162
|
-
NodeID vnD= pag->getValueNode(D), vnS= pag->getValueNode(S);
|
|
1163
|
-
if(!vnD || !vnS)
|
|
1164
|
-
return;
|
|
1165
|
-
|
|
1166
|
-
std::vector<LocationSet> fields;
|
|
1167
|
-
|
|
1168
|
-
//Get the max possible size of the copy, unless it was provided.
|
|
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
|
-
|
|
1174
|
-
if(srcFields.size() > dstFields.size())
|
|
1175
|
-
fields = dstFields;
|
|
1176
|
-
else
|
|
1177
|
-
fields = srcFields;
|
|
1178
|
-
|
|
1179
|
-
/// If sz is 0, we will add edges for all fields.
|
|
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
|
-
}
|
|
1186
|
-
|
|
1187
|
-
if (fields.size() == 1 && (SVFUtil::isa<SVFConstantData>(D) || SVFUtil::isa<SVFConstantData>(S)))
|
|
1188
|
-
{
|
|
1189
|
-
NodeID dummy = pag->addDummyValNode();
|
|
1190
|
-
addLoadEdge(vnD,dummy);
|
|
1191
|
-
addStoreEdge(dummy,vnS);
|
|
1192
|
-
return;
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
|
-
//For each field (i), add (Ti = *S + i) and (*D + i = Ti).
|
|
1196
|
-
for (u32_t index = 0; index < sz; index++)
|
|
1197
|
-
{
|
|
1198
|
-
const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType(dtype,
|
|
1199
|
-
fields[index].getConstantFieldIdx());
|
|
1200
|
-
const SVFType* sElementType = pag->getSymbolInfo()->getFlatternedElemType(stype,
|
|
1201
|
-
fields[index].getConstantFieldIdx());
|
|
1202
|
-
NodeID dField = getGepValVar(D,fields[index],dElementType);
|
|
1203
|
-
NodeID sField = getGepValVar(S,fields[index],sElementType);
|
|
1204
|
-
NodeID dummy = pag->addDummyValNode();
|
|
1205
|
-
addLoadEdge(sField,dummy);
|
|
1206
|
-
addStoreEdge(dummy,dField);
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
void SVFIRBuilder::parseOperations(std::vector<ExtAPI::Operation> &operations, const SVFCallInst* svfcall)
|
|
1211
|
-
{
|
|
1212
|
-
// Record all dummy nodes
|
|
1213
|
-
std::map<std::string, NodeID> nodeIDMap;
|
|
1214
|
-
for (ExtAPI::Operation& operation : operations)
|
|
1215
|
-
{
|
|
1216
|
-
std::vector<NodeID>& operands = operation.getOperands();
|
|
1217
|
-
if (operation.getOperator() == "funptr_ops" || operation.getOperator() == "Rb_tree_ops")
|
|
1218
|
-
continue;
|
|
1219
|
-
for (const std::string& s : operation.getOperandStr())
|
|
1220
|
-
{
|
|
1221
|
-
// There is already a NodeID in nodeIDMap
|
|
1222
|
-
if (nodeIDMap.find(s) != nodeIDMap.end())
|
|
1223
|
-
operands.push_back(nodeIDMap[s]);
|
|
1224
|
-
else
|
|
1225
|
-
{
|
|
1226
|
-
s32_t nodeIDType = ExtAPI::getExtAPI()->getNodeIDType(s);
|
|
1227
|
-
// return value >= 0 is an argument node
|
|
1228
|
-
if (nodeIDType >= 0)
|
|
1229
|
-
{
|
|
1230
|
-
if( svfcall->arg_size() <= (u32_t) nodeIDType)
|
|
1231
|
-
assert(false && "Argument out of bounds!");
|
|
1232
|
-
else if (operation.getOperator() == "memcpy_like" || operation.getOperator() == "memset_like")
|
|
1233
|
-
{
|
|
1234
|
-
operands.push_back(nodeIDType);
|
|
1235
|
-
nodeIDMap[s] = nodeIDType;
|
|
1236
|
-
}
|
|
1237
|
-
else
|
|
1238
|
-
{
|
|
1239
|
-
operands.push_back(pag->getValueNode(svfcall->getArgOperand(nodeIDType)));
|
|
1240
|
-
nodeIDMap[s] = pag->getValueNode(svfcall->getArgOperand(nodeIDType));
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
// return value = -1 is an inst node
|
|
1244
|
-
else if (nodeIDType == -1)
|
|
1245
|
-
{
|
|
1246
|
-
operands.push_back(pag->getValueNode(svfcall));
|
|
1247
|
-
nodeIDMap[s] = pag->getValueNode(svfcall);
|
|
1248
|
-
}
|
|
1249
|
-
// return value = -2 is a Dummy node
|
|
1250
|
-
else if (nodeIDType == -2)
|
|
1251
|
-
{
|
|
1252
|
-
operands.push_back(pag->addDummyValNode());
|
|
1253
|
-
nodeIDMap[s] = operands[operands.size() - 1];
|
|
1254
|
-
}
|
|
1255
|
-
// return value = -3 is an object node
|
|
1256
|
-
else if (nodeIDType == -3)
|
|
1257
|
-
{
|
|
1258
|
-
if (svfcall->getType()->isPointerTy())
|
|
1259
|
-
{
|
|
1260
|
-
NodeID objId;
|
|
1261
|
-
// Indirect call
|
|
1262
|
-
if (getCallee(svfcall) == nullptr)
|
|
1263
|
-
objId = pag->addDummyObjNode(svfcall->getType());
|
|
1264
|
-
else // Direct call
|
|
1265
|
-
objId = pag->getObjectNode(svfcall);
|
|
1266
|
-
|
|
1267
|
-
operands.push_back(objId);
|
|
1268
|
-
nodeIDMap[s] = objId;
|
|
1269
|
-
}
|
|
1270
|
-
}
|
|
1271
|
-
// return value = -4 is a nullptr node
|
|
1272
|
-
else if (nodeIDType == -4)
|
|
1273
|
-
{
|
|
1274
|
-
operands.push_back(pag->getNullPtr());
|
|
1275
|
-
nodeIDMap[s] = operands[operands.size() - 1];
|
|
1276
|
-
}
|
|
1277
|
-
// return value = -5 is an offset
|
|
1278
|
-
else if (nodeIDType == -5)
|
|
1279
|
-
{
|
|
1280
|
-
for (char const &c : s)
|
|
1281
|
-
{
|
|
1282
|
-
if (std::isdigit(c) == 0)
|
|
1283
|
-
assert(false && "Invalid offset!");
|
|
1284
|
-
}
|
|
1285
|
-
operands.push_back(atoi(s.c_str()));
|
|
1286
|
-
nodeIDMap[s] = atoi(s.c_str());
|
|
1287
|
-
}
|
|
1288
|
-
// return value = -6 is an illegal operand format
|
|
1289
|
-
else
|
|
1290
|
-
assert(false && "The operand format of function operation is illegal!");
|
|
1291
|
-
}
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
1117
|
void SVFIRBuilder::preProcessExtCall(CallBase* cs)
|
|
1297
1118
|
{
|
|
1298
1119
|
const SVFInstruction* svfinst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(cs);
|
|
@@ -1360,249 +1181,6 @@ void SVFIRBuilder::preProcessExtCall(CallBase* cs)
|
|
|
1360
1181
|
}
|
|
1361
1182
|
}
|
|
1362
1183
|
|
|
1363
|
-
/*!
|
|
1364
|
-
* Handle external calls
|
|
1365
|
-
*/
|
|
1366
|
-
void SVFIRBuilder::handleExtCall(SVFInstruction* svfinst, const SVFFunction* svfcallee)
|
|
1367
|
-
{
|
|
1368
|
-
const SVFCallInst* svfcall = SVFUtil::cast<SVFCallInst>(svfinst);
|
|
1369
|
-
|
|
1370
|
-
if (isHeapAllocOrStaticExtCall(svfinst))
|
|
1371
|
-
{
|
|
1372
|
-
// case 1: ret = new obj
|
|
1373
|
-
if (isHeapAllocExtCallViaRet(svfinst) || isStaticExtCall(svfinst))
|
|
1374
|
-
{
|
|
1375
|
-
NodeID val = pag->getValueNode(svfinst);
|
|
1376
|
-
NodeID obj = pag->getObjectNode(svfinst);
|
|
1377
|
-
addAddrEdge(obj, val);
|
|
1378
|
-
}
|
|
1379
|
-
// case 2: *arg = new obj
|
|
1380
|
-
else
|
|
1381
|
-
{
|
|
1382
|
-
assert(isHeapAllocExtCallViaArg(svfinst) && "Must be heap alloc call via arg.");
|
|
1383
|
-
u32_t arg_pos = getHeapAllocHoldingArgPosition(svfcallee);
|
|
1384
|
-
const SVFValue* arg = svfcall->getArgOperand(arg_pos);
|
|
1385
|
-
if (arg->getType()->isPointerTy())
|
|
1386
|
-
{
|
|
1387
|
-
NodeID vnArg = pag->getValueNode(arg);
|
|
1388
|
-
NodeID dummy = pag->addDummyValNode();
|
|
1389
|
-
NodeID obj = pag->addDummyObjNode(arg->getType());
|
|
1390
|
-
if (vnArg && dummy && obj)
|
|
1391
|
-
{
|
|
1392
|
-
addAddrEdge(obj, dummy);
|
|
1393
|
-
addStoreEdge(dummy, vnArg);
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
else
|
|
1397
|
-
{
|
|
1398
|
-
writeWrnMsg("Arg receiving new object must be pointer type");
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
else
|
|
1403
|
-
{
|
|
1404
|
-
if (isExtCall(svfcallee))
|
|
1405
|
-
{
|
|
1406
|
-
std::string funName = ExtAPI::getExtAPI()->get_name(svfcallee);
|
|
1407
|
-
std::vector<ExtAPI::Operation> allOperations = ExtAPI::getExtAPI()->getAllOperations(funName);
|
|
1408
|
-
if (allOperations.size() == 0)
|
|
1409
|
-
{
|
|
1410
|
-
std::string str;
|
|
1411
|
-
std::stringstream rawstr(str);
|
|
1412
|
-
rawstr << "function " << funName << " not in the external function summary ExtAPI.json file";
|
|
1413
|
-
writeWrnMsg(rawstr.str());
|
|
1414
|
-
}
|
|
1415
|
-
else
|
|
1416
|
-
{
|
|
1417
|
-
parseOperations(allOperations, svfcall);
|
|
1418
|
-
for (ExtAPI::Operation op : allOperations)
|
|
1419
|
-
{
|
|
1420
|
-
if (op.getOperator() == "AddrStmt")
|
|
1421
|
-
{
|
|
1422
|
-
if (op.getOperands().size() == 2)
|
|
1423
|
-
addAddrEdge(op.getOperands()[0], op.getOperands()[1]);
|
|
1424
|
-
else
|
|
1425
|
-
writeWrnMsg("We need two valid NodeIDs to add an Addr edge");
|
|
1426
|
-
}
|
|
1427
|
-
else if (op.getOperator() == "CopyStmt")
|
|
1428
|
-
{
|
|
1429
|
-
if (op.getOperands().size() == 2)
|
|
1430
|
-
addCopyEdge(op.getOperands()[0], op.getOperands()[1]);
|
|
1431
|
-
else
|
|
1432
|
-
writeWrnMsg("We need two valid NodeIDs to add a Copy edge");
|
|
1433
|
-
}
|
|
1434
|
-
else if (op.getOperator() == "LoadStmt")
|
|
1435
|
-
{
|
|
1436
|
-
if (op.getOperands().size() == 2)
|
|
1437
|
-
addLoadEdge(op.getOperands()[0], op.getOperands()[1]);
|
|
1438
|
-
else
|
|
1439
|
-
writeWrnMsg("We need two valid NodeIDs to add a Load edge");
|
|
1440
|
-
}
|
|
1441
|
-
else if (op.getOperator() == "StoreStmt")
|
|
1442
|
-
{
|
|
1443
|
-
if (op.getOperands().size() == 2)
|
|
1444
|
-
addStoreEdge(op.getOperands()[0], op.getOperands()[1]);
|
|
1445
|
-
else
|
|
1446
|
-
writeWrnMsg("We need two valid NodeIDs to add a Store edge");
|
|
1447
|
-
}
|
|
1448
|
-
else if (op.getOperator() == "GepStmt")
|
|
1449
|
-
{
|
|
1450
|
-
if (op.getOperands().size() == 3)
|
|
1451
|
-
{
|
|
1452
|
-
LocationSet ls(op.getOperands()[2]);
|
|
1453
|
-
addNormalGepEdge(op.getOperands()[0], op.getOperands()[1], ls);
|
|
1454
|
-
}
|
|
1455
|
-
else
|
|
1456
|
-
writeWrnMsg("We need two valid NodeIDs and an offset to add a Gep edge");
|
|
1457
|
-
}
|
|
1458
|
-
else if (op.getOperator() == "BinaryOPStmt")
|
|
1459
|
-
{
|
|
1460
|
-
if (op.getOperands().size() == 4)
|
|
1461
|
-
addBinaryOPEdge(op.getOperands()[0], op.getOperands()[1], op.getOperands()[2], op.getOperands()[3]);
|
|
1462
|
-
else
|
|
1463
|
-
writeWrnMsg("We need four valid NodeIDs to add a BinaryOP edge");
|
|
1464
|
-
}
|
|
1465
|
-
else if (op.getOperator() == "UnaryOPStmt")
|
|
1466
|
-
{
|
|
1467
|
-
if (op.getOperands().size() == 3)
|
|
1468
|
-
addUnaryOPEdge(op.getOperands()[0], op.getOperands()[1], op.getOperands()[2]);
|
|
1469
|
-
else
|
|
1470
|
-
writeWrnMsg("We need three valid NodeIDs to add a UnaryOP edge");
|
|
1471
|
-
}
|
|
1472
|
-
else if (op.getOperator() == "CmpStmt")
|
|
1473
|
-
{
|
|
1474
|
-
if (op.getOperands().size() == 4)
|
|
1475
|
-
addCmpEdge(op.getOperands()[0], op.getOperands()[1], op.getOperands()[2], op.getOperands()[3]);
|
|
1476
|
-
else
|
|
1477
|
-
writeWrnMsg("We need four valid NodeIDs to add a CmpStmt edge");
|
|
1478
|
-
}
|
|
1479
|
-
else if (op.getOperator() == "memset_like")
|
|
1480
|
-
{
|
|
1481
|
-
// this is for memset(void *str, int c, size_t n)
|
|
1482
|
-
// which copies the character c (an unsigned char) to the first n characters of the string pointed to, by the argument str
|
|
1483
|
-
// const SVFConstantInt* arg2 = SVFUtil::dyn_cast<SVFConstantInt>(svfcall->getArgOperand(op.getOperands()[2]));
|
|
1484
|
-
NodeID argId = pag->getValueNode(svfcall->getArgOperand(op.getOperands()[0]));
|
|
1485
|
-
std::vector<LocationSet> dstFields = pag->getTypeLocSetsMap(argId).second;
|
|
1486
|
-
u32_t sz = dstFields.size();
|
|
1487
|
-
if (const SVFConstantInt* arg2 = SVFUtil::dyn_cast<SVFConstantInt>(svfcall->getArgOperand(op.getOperands()[2])))
|
|
1488
|
-
sz = (dstFields.size() > static_cast<u32_t>(arg2->getSExtValue())) ? arg2->getSExtValue() : dstFields.size();
|
|
1489
|
-
//For each field (i), add store edge *(arg0 + i) = arg1
|
|
1490
|
-
for (u32_t index = 0; index < sz; index++)
|
|
1491
|
-
{
|
|
1492
|
-
const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType(pag->getTypeLocSetsMap(argId).first, dstFields[index].getConstantFieldIdx());
|
|
1493
|
-
NodeID dField = getGepValVar(svfcall->getArgOperand(op.getOperands()[0]), dstFields[index], dElementType);
|
|
1494
|
-
addStoreEdge(pag->getValueNode(svfcall->getArgOperand(op.getOperands()[1])),dField);
|
|
1495
|
-
}
|
|
1496
|
-
if(svfcall->getType()->isPointerTy())
|
|
1497
|
-
addCopyEdge(pag->getValueNode(svfcall->getArgOperand(op.getOperands()[0])), pag->getValueNode(svfinst));
|
|
1498
|
-
}
|
|
1499
|
-
else if (op.getOperator() == "memcpy_like")
|
|
1500
|
-
{
|
|
1501
|
-
if(op.getOperands().size() == 3)
|
|
1502
|
-
addComplexConsForExt(svfcall->getArgOperand(op.getOperands()[0]), svfcall->getArgOperand(op.getOperands()[1]), svfcall->getArgOperand(op.getOperands()[2]));
|
|
1503
|
-
else
|
|
1504
|
-
addComplexConsForExt(svfcall->getArgOperand(op.getOperands()[0]), svfcall->getArgOperand(op.getOperands()[1]), nullptr);
|
|
1505
|
-
}
|
|
1506
|
-
else if (op.getOperator() == "Rb_tree_ops")
|
|
1507
|
-
{
|
|
1508
|
-
assert(svfcall->arg_size() == 4 && "_Rb_tree_insert_and_rebalance should have 4 arguments.\n");
|
|
1509
|
-
|
|
1510
|
-
// We have vArg3 points to the entry of _Rb_tree_node_base { color; parent; left; right; }.
|
|
1511
|
-
// Now we calculate the offset from base to vArg3
|
|
1512
|
-
NodeID vnArg3 = pag->getValueNode(svfcall->getArgOperand(3));
|
|
1513
|
-
s32_t offset = getLocationSetFromBaseNode(vnArg3).getConstantFieldIdx();
|
|
1514
|
-
|
|
1515
|
-
// We get all flattened fields of base
|
|
1516
|
-
vector<LocationSet> fields = pag->getTypeLocSetsMap(vnArg3).second;
|
|
1517
|
-
|
|
1518
|
-
// We summarize the side effects: arg3->parent = arg1, arg3->left = arg1, arg3->right = arg1
|
|
1519
|
-
// Note that arg0 is aligned with "offset".
|
|
1520
|
-
for (s32_t i = offset + 1; i <= offset + 3; ++i)
|
|
1521
|
-
{
|
|
1522
|
-
if((u32_t)i >= fields.size())
|
|
1523
|
-
break;
|
|
1524
|
-
const SVFType* elementType = pag->getSymbolInfo()->getFlatternedElemType(pag->getTypeLocSetsMap(vnArg3).first,
|
|
1525
|
-
fields[i].getConstantFieldIdx());
|
|
1526
|
-
NodeID vnD = getGepValVar(svfcall->getArgOperand(3), fields[i], elementType);
|
|
1527
|
-
NodeID vnS = pag->getValueNode(svfcall->getArgOperand(1));
|
|
1528
|
-
if(vnD && vnS)
|
|
1529
|
-
addStoreEdge(vnS,vnD);
|
|
1530
|
-
}
|
|
1531
|
-
}
|
|
1532
|
-
// default
|
|
1533
|
-
// illegal function operation of external function
|
|
1534
|
-
else
|
|
1535
|
-
{
|
|
1536
|
-
assert(false && "new type of SVFStmt for external calls?");
|
|
1537
|
-
}
|
|
1538
|
-
}
|
|
1539
|
-
}
|
|
1540
|
-
}
|
|
1541
|
-
|
|
1542
|
-
/// create inter-procedural SVFIR edges for thread forks
|
|
1543
|
-
if (isThreadForkCall(svfinst))
|
|
1544
|
-
{
|
|
1545
|
-
if (const SVFFunction* forkedFun = SVFUtil::dyn_cast<SVFFunction>(getForkedFun(svfinst)))
|
|
1546
|
-
{
|
|
1547
|
-
forkedFun = forkedFun->getDefFunForMultipleModule();
|
|
1548
|
-
const SVFValue* actualParm = getActualParmAtForkSite(svfinst);
|
|
1549
|
-
/// pthread_create has 1 arg.
|
|
1550
|
-
/// apr_thread_create has 2 arg.
|
|
1551
|
-
assert((forkedFun->arg_size() <= 2) && "Size of formal parameter of start routine should be one");
|
|
1552
|
-
if (forkedFun->arg_size() <= 2 && forkedFun->arg_size() >= 1)
|
|
1553
|
-
{
|
|
1554
|
-
const SVFArgument* formalParm = forkedFun->getArg(0);
|
|
1555
|
-
/// Connect actual parameter to formal parameter of the start routine
|
|
1556
|
-
if (actualParm->getType()->isPointerTy() && formalParm->getType()->isPointerTy())
|
|
1557
|
-
{
|
|
1558
|
-
CallICFGNode *icfgNode = pag->getICFG()->getCallICFGNode(svfinst);
|
|
1559
|
-
FunEntryICFGNode *entry = pag->getICFG()->getFunEntryICFGNode(forkedFun);
|
|
1560
|
-
addThreadForkEdge(pag->getValueNode(actualParm), pag->getValueNode(formalParm), icfgNode, entry);
|
|
1561
|
-
}
|
|
1562
|
-
}
|
|
1563
|
-
}
|
|
1564
|
-
else
|
|
1565
|
-
{
|
|
1566
|
-
/// handle indirect calls at pthread create APIs e.g., pthread_create(&t1, nullptr, fp, ...);
|
|
1567
|
-
/// const Value* fun = ThreadAPI::getThreadAPI()->getForkedFun(inst);
|
|
1568
|
-
/// if(!SVFUtil::isa<Function>(fun))
|
|
1569
|
-
/// pag->addIndirectCallsites(cs,pag->getValueNode(fun));
|
|
1570
|
-
}
|
|
1571
|
-
/// If forkedFun does not pass to spawnee as function type but as void pointer
|
|
1572
|
-
/// remember to update inter-procedural callgraph/SVFIR/SVFG etc. when indirect call targets are resolved
|
|
1573
|
-
/// We don't connect the callgraph here, further investigation is need to hanle mod-ref during SVFG construction.
|
|
1574
|
-
}
|
|
1575
|
-
|
|
1576
|
-
/// create inter-procedural SVFIR edges for hare_parallel_for calls
|
|
1577
|
-
else if (isHareParForCall(svfinst))
|
|
1578
|
-
{
|
|
1579
|
-
if (const SVFFunction* taskFunc = SVFUtil::dyn_cast<SVFFunction>(getTaskFuncAtHareParForSite(svfinst)))
|
|
1580
|
-
{
|
|
1581
|
-
/// The task function of hare_parallel_for has 3 args.
|
|
1582
|
-
assert((taskFunc->arg_size() == 3) && "Size of formal parameter of hare_parallel_for's task routine should be 3");
|
|
1583
|
-
const SVFValue* actualParm = getTaskDataAtHareParForSite(svfinst);
|
|
1584
|
-
const SVFArgument* formalParm = taskFunc->getArg(0);
|
|
1585
|
-
/// Connect actual parameter to formal parameter of the start routine
|
|
1586
|
-
if (actualParm->getType()->isPointerTy() && formalParm->getType()->isPointerTy())
|
|
1587
|
-
{
|
|
1588
|
-
CallICFGNode *icfgNode = pag->getICFG()->getCallICFGNode(svfinst);
|
|
1589
|
-
FunEntryICFGNode *entry = pag->getICFG()->getFunEntryICFGNode(taskFunc);
|
|
1590
|
-
addThreadForkEdge(pag->getValueNode(actualParm), pag->getValueNode(formalParm), icfgNode, entry);
|
|
1591
|
-
}
|
|
1592
|
-
}
|
|
1593
|
-
else
|
|
1594
|
-
{
|
|
1595
|
-
/// handle indirect calls at hare_parallel_for (e.g., hare_parallel_for(..., fp, ...);
|
|
1596
|
-
/// const Value* fun = ThreadAPI::getThreadAPI()->getForkedFun(inst);
|
|
1597
|
-
/// if(!SVFUtil::isa<Function>(fun))
|
|
1598
|
-
/// pag->addIndirectCallsites(cs,pag->getValueNode(fun));
|
|
1599
|
-
}
|
|
1600
|
-
}
|
|
1601
|
-
|
|
1602
|
-
/// TODO: inter-procedural SVFIR edges for thread joins
|
|
1603
|
-
}
|
|
1604
|
-
}
|
|
1605
|
-
|
|
1606
1184
|
/*!
|
|
1607
1185
|
* Indirect call is resolved on-the-fly during pointer analysis
|
|
1608
1186
|
*/
|