svf-tools 1.0.549 → 1.0.550

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.
Files changed (65) hide show
  1. package/SVF-doxygen/html/html/ExtAPI_8cpp_source.html +38 -41
  2. package/SVF-doxygen/html/html/ExtAPI_8h_source.html +70 -81
  3. package/SVF-doxygen/html/html/SVFIRBuilder_8cpp_source.html +2 -4
  4. package/SVF-doxygen/html/html/SVFIRBuilder_8h_source.html +9 -10
  5. package/SVF-doxygen/html/html/SVFUtil_8h_source.html +7 -7
  6. package/SVF-doxygen/html/html/classSVF_1_1ExtAPI-members.html +24 -36
  7. package/SVF-doxygen/html/html/classSVF_1_1ExtAPI.html +141 -224
  8. package/SVF-doxygen/html/html/classSVF_1_1ExtAPI_1_1Operation-members.html +8 -7
  9. package/SVF-doxygen/html/html/classSVF_1_1ExtAPI_1_1Operation.html +81 -56
  10. package/SVF-doxygen/html/html/classSVF_1_1SVFIRBuilder-members.html +1 -1
  11. package/SVF-doxygen/html/html/classSVF_1_1SVFIRBuilder.html +60 -76
  12. package/SVF-doxygen/html/html/functions_a.html +6 -9
  13. package/SVF-doxygen/html/html/functions_c.html +2 -2
  14. package/SVF-doxygen/html/html/functions_e.html +2 -35
  15. package/SVF-doxygen/html/html/functions_enum.html +0 -3
  16. package/SVF-doxygen/html/html/functions_eval_e.html +0 -30
  17. package/SVF-doxygen/html/html/functions_f.html +3 -3
  18. package/SVF-doxygen/html/html/functions_func_g.html +20 -17
  19. package/SVF-doxygen/html/html/functions_func_o.html +1 -1
  20. package/SVF-doxygen/html/html/functions_func_p.html +3 -3
  21. package/SVF-doxygen/html/html/functions_func_s.html +10 -13
  22. package/SVF-doxygen/html/html/functions_g.html +21 -18
  23. package/SVF-doxygen/html/html/functions_i.html +6 -6
  24. package/SVF-doxygen/html/html/functions_l.html +3 -3
  25. package/SVF-doxygen/html/html/functions_o.html +20 -17
  26. package/SVF-doxygen/html/html/functions_p.html +12 -14
  27. package/SVF-doxygen/html/html/functions_r.html +7 -5
  28. package/SVF-doxygen/html/html/functions_s.html +22 -23
  29. package/SVF-doxygen/html/html/functions_t.html +7 -5
  30. package/SVF-doxygen/html/html/functions_v.html +6 -6
  31. package/SVF-doxygen/html/html/functions_vars_a.html +0 -3
  32. package/SVF-doxygen/html/html/functions_vars_o.html +7 -4
  33. package/SVF-doxygen/html/html/search/all_1.js +0 -1
  34. package/SVF-doxygen/html/html/search/all_10.js +10 -10
  35. package/SVF-doxygen/html/html/search/all_11.js +2 -2
  36. package/SVF-doxygen/html/html/search/all_12.js +7 -8
  37. package/SVF-doxygen/html/html/search/all_13.js +2 -2
  38. package/SVF-doxygen/html/html/search/all_14.js +1 -1
  39. package/SVF-doxygen/html/html/search/all_15.js +3 -3
  40. package/SVF-doxygen/html/html/search/all_16.js +1 -1
  41. package/SVF-doxygen/html/html/search/all_3.js +1 -1
  42. package/SVF-doxygen/html/html/search/all_5.js +0 -11
  43. package/SVF-doxygen/html/html/search/all_6.js +1 -1
  44. package/SVF-doxygen/html/html/search/all_7.js +5 -4
  45. package/SVF-doxygen/html/html/search/all_9.js +2 -2
  46. package/SVF-doxygen/html/html/search/all_c.js +3 -3
  47. package/SVF-doxygen/html/html/search/all_e.js +4 -4
  48. package/SVF-doxygen/html/html/search/all_f.js +6 -4
  49. package/SVF-doxygen/html/html/search/enums_3.js +0 -1
  50. package/SVF-doxygen/html/html/search/enumvalues_4.js +1 -11
  51. package/SVF-doxygen/html/html/search/functions_11.js +1 -2
  52. package/SVF-doxygen/html/html/search/functions_6.js +5 -4
  53. package/SVF-doxygen/html/html/search/functions_e.js +1 -1
  54. package/SVF-doxygen/html/html/search/functions_f.js +2 -2
  55. package/SVF-doxygen/html/html/search/variables_1.js +0 -1
  56. package/SVF-doxygen/html/html/search/variables_13.js +1 -1
  57. package/SVF-doxygen/html/html/search/variables_14.js +1 -1
  58. package/SVF-doxygen/html/html/search/variables_e.js +3 -3
  59. package/SVF-doxygen/html/html/search/variables_f.js +3 -2
  60. package/include/SVF-FE/SVFIRBuilder.h +1 -1
  61. package/include/Util/ExtAPI.h +17 -42
  62. package/include/Util/ExtAPI.json +1013 -989
  63. package/lib/SVF-FE/SVFIRBuilder.cpp +122 -222
  64. package/lib/Util/ExtAPI.cpp +53 -68
  65. package/package.json +1 -1
@@ -1125,20 +1125,43 @@ void SVFIRBuilder::addComplexConsForExt(Value *D, Value *S, const Value* szValue
1125
1125
  }
1126
1126
  }
1127
1127
 
1128
- /*!
1129
- * Get NodeId of s
1130
- */
1131
- NodeID SVFIRBuilder::parseNode(std::string s, CallSite cs, const Instruction *inst)
1128
+ void SVFIRBuilder::parseOperations(std::vector<ExtAPI::Operation> &operations, CallSite cs)
1132
1129
  {
1133
- int nodeIDType = ExtAPI::getExtAPI()->getNodeIDType(s);
1134
- if (nodeIDType >=0)
1135
- return getValueNode(cs.getArgument(nodeIDType));
1136
- if (nodeIDType == -1)
1137
- return getValueNode(inst);
1138
- if (nodeIDType == -2)
1139
- return pag->addDummyValNode();
1140
- assert(false && "The operand format of function operation is illegal!");
1141
- return -1;
1130
+ // Record all dummy nodes
1131
+ std::map<std::string, NodeID> nodeIDMap;
1132
+ for (ExtAPI::Operation& operation : operations)
1133
+ {
1134
+ std::string op = operation.getOperator();
1135
+ std::vector<NodeID> operands;
1136
+ if (op == "funptr_ops" || op == "Rb_tree_ops")
1137
+ continue;
1138
+ for (auto s: operation.getOperandStr())
1139
+ {
1140
+ NodeID operandID;
1141
+ // There is already a NodeID in nodeIDMap
1142
+ if (nodeIDMap.find(s) != nodeIDMap.end())
1143
+ operandID = nodeIDMap[s];
1144
+ else
1145
+ {
1146
+ int nodeIDType = ExtAPI::getExtAPI()->getNodeIDType(s);
1147
+ if (nodeIDType >= 0)
1148
+ operandID = getValueNode(cs.getArgument(nodeIDType));
1149
+ else if (nodeIDType == -1)
1150
+ operandID = getValueNode(cs.getInstruction());
1151
+ else if (nodeIDType == -2)
1152
+ operandID = pag->addDummyValNode();
1153
+ else if (nodeIDType == -3)
1154
+ operandID = getObjectNode(cs.getInstruction());
1155
+ else if (nodeIDType == -4)
1156
+ operandID = atoi(s.c_str());
1157
+ else
1158
+ assert(false && "The operand format of function operation is illegal!");
1159
+ nodeIDMap.insert(std::pair<std::string, NodeID>(s, operandID));
1160
+ }
1161
+ operands.push_back(operandID);
1162
+ }
1163
+ operation.setOperands(operands);
1164
+ }
1142
1165
  }
1143
1166
 
1144
1167
  /*!
@@ -1184,7 +1207,7 @@ void SVFIRBuilder::handleExtCall(CallSite cs, const SVFFunction *callee)
1184
1207
  if (isExtCall(callee))
1185
1208
  {
1186
1209
  std::string funName = ExtAPI::getExtAPI()->get_name(callee);
1187
- std::vector<std::vector<ExtAPI::Operation *>> allOperations = ExtAPI::getExtAPI()->getAllOperations(funName);
1210
+ std::vector<ExtAPI::Operation> allOperations = ExtAPI::getExtAPI()->getAllOperations(funName);
1188
1211
  if (allOperations.size() == 0)
1189
1212
  {
1190
1213
  std::string str;
@@ -1194,233 +1217,110 @@ void SVFIRBuilder::handleExtCall(CallSite cs, const SVFFunction *callee)
1194
1217
  }
1195
1218
  else
1196
1219
  {
1197
- for (auto operations: allOperations)
1220
+ parseOperations(allOperations, cs);
1221
+ for (auto op : allOperations)
1198
1222
  {
1199
- NodeID tempNode = -1;
1200
- // Record the previous operation
1201
- ExtAPI::Operation *preOp = nullptr;
1202
- for (auto op : operations)
1223
+ if (op.getOperator() == "AddrStmt")
1203
1224
  {
1204
- ExtAPI::extf_t opName = ExtAPI::getExtAPI()->get_opName(op->getOperation());
1205
- std::vector<std::string> args = op->getArgs();
1206
-
1207
- switch (opName)
1208
- {
1209
- case ExtAPI::EXT_ADDR:
1210
- {
1211
- if (args.size() == 1)
1212
- {
1213
- if (!SVFUtil::isa<PointerType>(inst->getType()))
1214
- break;
1215
- // e.g. void *realloc(void *ptr, size_t size)
1216
- // if ptr is null then we will treat it as a malloc
1217
- // if ptr is not null, then we assume a new data memory will be attached to
1218
- // the tail of old allocated memory block.
1219
- if (SVFUtil::isa<ConstantPointerNull>(cs.getArgument(0)))
1220
- {
1221
- NodeID val = parseNode(args[0], cs, inst);
1222
- NodeID obj = getObjectNode(inst);
1223
- if (val && obj)
1224
- addAddrEdge(obj, val);
1225
- }
1226
- }
1227
- break;
1228
- }
1229
- case ExtAPI::EXT_COPY:
1230
- {
1231
- if(operations.size() == 1)
1232
- {
1233
- NodeID vnS = parseNode(args[0], cs, inst);
1234
- NodeID vnD = parseNode(args[1], cs, inst);
1235
- if (vnS && vnD)
1236
- addCopyEdge(vnS, vnD);
1237
- }
1238
- break;
1239
- }
1240
- case ExtAPI::EXT_LOAD:
1241
- {
1242
- NodeID vnS = parseNode(args[0], cs, inst);
1243
- NodeID vnD = parseNode(args[1], cs, inst);
1244
- if (vnS && vnD)
1245
- {
1246
- addLoadEdge(vnS, vnD);
1247
- if (operations.size() > 1 && !preOp)
1248
- {
1249
- preOp = op;
1250
- tempNode = vnD;
1251
- }
1252
- }
1253
- break;
1254
- }
1255
- case ExtAPI::EXT_STORE:
1256
- {
1257
- if (operations.size() == 1)
1258
- {
1259
- NodeID vnS = parseNode(args[0], cs, inst);
1260
- NodeID vnD = parseNode(args[1], cs, inst);
1261
- if (vnS && vnD)
1262
- addStoreEdge(vnS, vnD);
1263
- }
1264
- else
1265
- {
1266
- if(preOp && preOp->getArgs()[1] == op->getArgs()[0])
1267
- {
1268
- NodeID vnD = parseNode(args[1], cs, inst);
1269
- addStoreEdge(tempNode, vnD);
1270
- }
1271
- }
1272
- break;
1273
- }
1274
- case ExtAPI::EXT_GEP:
1275
- {
1276
- // "compound"
1277
- if(operations.size() > 1)
1278
- {
1279
- // multiple GEP operations
1280
- if (!preOp)
1281
- {
1282
- NodeID vnS = parseNode(args[0], cs, inst);
1283
- NodeID vnD = parseNode(args[1], cs, inst);
1284
- u32_t offset = stoul(args[2]);
1285
- if (vnD && vnS)
1286
- {
1287
- LocationSet ls(offset);
1288
- addNormalGepEdge(vnS, vnD, ls);
1289
- tempNode = vnD;
1290
- }
1291
- }
1292
- else
1293
- {
1294
- if(op->getArgs()[0] == preOp->getArgs()[1])
1295
- {
1296
- NodeID vnD = parseNode(args[1], cs, inst);
1297
- u32_t offset = stoul(args[2]);
1298
- if (vnD)
1299
- {
1300
- LocationSet ls(offset);
1301
- addNormalGepEdge(tempNode, vnD, ls);
1302
- }
1303
- }
1304
- }
1305
-
1306
- if (operations.back() == op)
1307
- preOp = nullptr;
1308
- preOp = op;
1309
- }
1310
- // General GEP operation
1311
- else
1312
- {
1313
- NodeID vnS = parseNode(args[0], cs, inst);
1314
- NodeID vnD = parseNode(args[1], cs, inst);
1315
- u32_t offset = stoul(args[2]);
1316
- if (vnD && vnS)
1317
- {
1318
- LocationSet ls(offset);
1319
- addNormalGepEdge(vnS, vnD, ls);
1320
- }
1321
- }
1322
- break;
1323
- }
1324
- case ExtAPI::EXT_COPY_N:
1325
- {
1326
- // void *memset(void *str, int c, size_t n)
1327
- // this is for memset(void *str, int c, size_t n)
1328
- // which copies the character c (an unsigned char) to the first n characters of the string pointed to, by the argument str
1329
- u32_t arg_posA = ExtAPI::getExtAPI()->getArgPos(args[0]);
1330
- u32_t arg_posB = ExtAPI::getExtAPI()->getArgPos(args[1]);
1331
- u32_t arg_posC = ExtAPI::getExtAPI()->getArgPos(args[2]);
1332
- std::vector<LocationSet> dstFields;
1333
- const Type *dtype = getBaseTypeAndFlattenedFields(cs.getArgument(arg_posA), dstFields, cs.getArgument(arg_posC));
1334
- u32_t sz = dstFields.size();
1335
- // For each field (i), add store edge *(arg0 + i) = arg1
1336
- for (u32_t index = 0; index < sz; index++)
1337
- {
1338
- const Type *dElementType = SymbolTableInfo::SymbolInfo()->getFlatternedElemType(dtype, dstFields[index].accumulateConstantFieldIdx());
1339
- NodeID dField = getGepValVar(cs.getArgument(arg_posA), dstFields[index], dElementType);
1340
- addStoreEdge(pag->getValueNode(cs.getArgument(arg_posB)), dField);
1341
- }
1342
- if (SVFUtil::isa<PointerType>(inst->getType()))
1343
- addCopyEdge(getValueNode(cs.getArgument(arg_posA)), getValueNode(inst));
1344
- break;
1345
- }
1346
- case ExtAPI::EXT_COPY_MN:
1225
+ addAddrEdge(op.getOperands()[0], op.getOperands()[1]);
1226
+ }
1227
+ else if (op.getOperator() == "CopyStmt")
1228
+ {
1229
+ addCopyEdge(op.getOperands()[0], op.getOperands()[1]);
1230
+ }
1231
+ else if (op.getOperator() == "LoadStmt")
1232
+ {
1233
+ addLoadEdge(op.getOperands()[0], op.getOperands()[1]);
1234
+ }
1235
+ else if (op.getOperator() == "StoreStmt")
1236
+ {
1237
+ addStoreEdge(op.getOperands()[0], op.getOperands()[1]);
1238
+ }
1239
+ else if (op.getOperator() == "GepStmt")
1240
+ {
1241
+ LocationSet ls(op.getOperands()[2]);
1242
+ addNormalGepEdge(op.getOperands()[0], op.getOperands()[1], ls);
1243
+ }
1244
+ else if (op.getOperator() == "memset_like")
1245
+ {
1246
+ // this is for memset(void *str, int c, size_t n)
1247
+ // which copies the character c (an unsigned char) to the first n characters of the string pointed to, by the argument str
1248
+ std::vector<LocationSet> dstFields;
1249
+ const Type *dtype = getBaseTypeAndFlattenedFields(cs.getArgument(0), dstFields, cs.getArgument(2));
1250
+ u32_t sz = dstFields.size();
1251
+ //For each field (i), add store edge *(arg0 + i) = arg1
1252
+ for (u32_t index = 0; index < sz; index++)
1347
1253
  {
1348
- u32_t arg_posA = ExtAPI::getExtAPI()->getArgPos(args[0]);
1349
- u32_t arg_posB = ExtAPI::getExtAPI()->getArgPos(args[1]);
1350
- if (args.size() >= 3)
1351
- {
1352
- u32_t arg_posC = ExtAPI::getExtAPI()->getArgPos(args[2]);
1353
- addComplexConsForExt(cs.getArgument(arg_posA), cs.getArgument(arg_posB), cs.getArgument(arg_posC));
1354
- }
1355
- else
1356
- addComplexConsForExt(cs.getArgument(arg_posA), cs.getArgument(arg_posB), nullptr);
1357
- break;
1254
+ const Type* dElementType = SymbolTableInfo::SymbolInfo()->getFlatternedElemType(dtype, dstFields[index].accumulateConstantFieldIdx());
1255
+ NodeID dField = getGepValVar(cs.getArgument(0), dstFields[index], dElementType);
1256
+ addStoreEdge(pag->getValueNode(cs.getArgument(1)),dField);
1358
1257
  }
1359
- case ExtAPI::EXT_FUNPTR:
1258
+ if(SVFUtil::isa<PointerType>(inst->getType()))
1259
+ addCopyEdge(getValueNode(cs.getArgument(0)), getValueNode(inst));
1260
+ }
1261
+ else if (op.getOperator() == "memcpy_like")
1262
+ {
1263
+ /// handle strcpy
1264
+ if(cs.arg_size()>=3)
1265
+ addComplexConsForExt(cs.getArgument(op.getOperands()[0]), cs.getArgument(op.getOperands()[1]), cs.getArgument(op.getOperands()[2]));
1266
+ else
1267
+ addComplexConsForExt(cs.getArgument(op.getOperands()[0]), cs.getArgument(op.getOperands()[1]), nullptr);
1268
+ }
1269
+ else if (op.getOperator() == "funptr_ops")
1270
+ {
1271
+ /// handling external function e.g., void *dlsym(void *handle, const char *funname);
1272
+ const Value *src = cs.getArgument(1);
1273
+ if(const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(src))
1274
+ src = stripConstantCasts(gep->getPointerOperand());
1275
+ if(const GlobalVariable* glob = SVFUtil::dyn_cast<GlobalVariable>(src))
1360
1276
  {
1361
- /// handling external function e.g., void *dlsym(void *handle, const char *funname);
1362
- u32_t arg_posA = ExtAPI::getExtAPI()->getArgPos(args[0]);
1363
- const Value *src = cs.getArgument(arg_posA);
1364
- if (const GetElementPtrInst *gep = SVFUtil::dyn_cast<GetElementPtrInst>(src))
1365
- src = stripConstantCasts(gep->getPointerOperand());
1366
- if (const GlobalVariable *glob = SVFUtil::dyn_cast<GlobalVariable>(src))
1277
+ if(const ConstantDataArray* constarray = SVFUtil::dyn_cast<ConstantDataArray>(glob->getInitializer()))
1367
1278
  {
1368
- if (const ConstantDataArray *constarray = SVFUtil::dyn_cast<ConstantDataArray>(glob->getInitializer()))
1279
+ if(const SVFFunction* fun = getProgFunction(svfMod,constarray->getAsCString().str()))
1369
1280
  {
1370
- if (const SVFFunction *fun = getProgFunction(svfMod, constarray->getAsCString().str()))
1371
- {
1372
- NodeID srcNode = getValueNode(fun->getLLVMFun());
1373
- addCopyEdge(srcNode, getValueNode(inst));
1374
- }
1281
+ NodeID srcNode = getValueNode(fun->getLLVMFun());
1282
+ addCopyEdge(srcNode, getValueNode(inst));
1375
1283
  }
1376
1284
  }
1377
- break;
1378
1285
  }
1379
- case ExtAPI::EXT_COMPLEX:
1380
- {
1381
- assert(cs.arg_size() == 4 && "_Rb_tree_insert_and_rebalance should have 4 arguments.\n");
1286
+ }
1287
+ else if (op.getOperator() == "Rb_tree_ops")
1288
+ {
1289
+ assert(cs.arg_size() == 4 && "_Rb_tree_insert_and_rebalance should have 4 arguments.\n");
1382
1290
 
1383
- Value *argA = cs.getArgument(ExtAPI::getExtAPI()->getArgPos(args[0]));
1384
- Value *argB = cs.getArgument(ExtAPI::getExtAPI()->getArgPos(args[1]));
1291
+ Value *vArg1 = cs.getArgument(1);
1292
+ Value *vArg3 = cs.getArgument(3);
1385
1293
 
1386
- // We have vArg3 points to the entry of _Rb_tree_node_base { color; parent; left; right; }.
1387
- // Now we calculate the offset from base to vArg3
1388
- NodeID vnB = pag->getValueNode(argB);
1389
- s32_t offset = getLocationSetFromBaseNode(vnB).accumulateConstantFieldIdx();
1294
+ // We have vArg3 points to the entry of _Rb_tree_node_base { color; parent; left; right; }.
1295
+ // Now we calculate the offset from base to vArg3
1296
+ NodeID vnArg3 = pag->getValueNode(vArg3);
1297
+ s32_t offset = getLocationSetFromBaseNode(vnArg3).accumulateConstantFieldIdx();
1390
1298
 
1391
- // We get all flattened fields of base
1392
- vector<LocationSet> fields;
1393
- const Type *type = getBaseTypeAndFlattenedFields(argB, fields, nullptr);
1299
+ // We get all flattened fields of base
1300
+ vector<LocationSet> fields;
1301
+ const Type *type = getBaseTypeAndFlattenedFields(vArg3, fields, nullptr);
1394
1302
 
1395
- // We summarize the side effects: arg3->parent = arg1, arg3->left = arg1, arg3->right = arg1
1396
- // Note that arg0 is aligned with "offset".
1397
- for (s32_t i = offset + 1; i <= offset + 3; ++i)
1398
- {
1399
- if ((u32_t)i >= fields.size())
1400
- break;
1401
- const Type *elementType = SymbolTableInfo::SymbolInfo()->getFlatternedElemType(type, fields[i].accumulateConstantFieldIdx());
1402
- NodeID vnD = getGepValVar(argB, fields[i], elementType);
1403
- NodeID vnS = getValueNode(argA);
1404
- if (vnD && vnS)
1405
- addStoreEdge(vnS, vnD);
1406
- }
1407
- break;
1408
- }
1409
- // default
1410
- // illegal function operation of external function
1411
- case ExtAPI::EXT_OTHER:
1412
- default:
1303
+ // We summarize the side effects: arg3->parent = arg1, arg3->left = arg1, arg3->right = arg1
1304
+ // Note that arg0 is aligned with "offset".
1305
+ for (s32_t i = offset + 1; i <= offset + 3; ++i)
1413
1306
  {
1414
- assert(false && "new type of SVFStmt for external calls?");
1415
- }
1307
+ if((u32_t)i >= fields.size())
1308
+ break;
1309
+ const Type* elementType = SymbolTableInfo::SymbolInfo()->getFlatternedElemType(type, fields[i].accumulateConstantFieldIdx());
1310
+ NodeID vnD = getGepValVar(vArg3, fields[i], elementType);
1311
+ NodeID vnS = getValueNode(vArg1);
1312
+ if(vnD && vnS)
1313
+ addStoreEdge(vnS,vnD);
1416
1314
  }
1417
1315
  }
1418
- for(u32_t it = 0; it != operations.size(); ++it)
1419
- delete operations[it];
1420
- operations.clear();
1316
+ // default
1317
+ // illegal function operation of external function
1318
+ else
1319
+ {
1320
+ assert(false && "new type of SVFStmt for external calls?");
1321
+ }
1421
1322
  }
1422
1323
  }
1423
- allOperations.clear();
1424
1324
  }
1425
1325
 
1426
1326
  /// create inter-procedural SVFIR edges for thread forks
@@ -201,17 +201,12 @@ void ExtAPI::add_entry(const char* funName, extType type, bool overwrite_app_fun
201
201
  }
202
202
 
203
203
  // Get the corresponding name in ext_t, e.g. "EXT_ADDR" in {"addr", EXT_ADDR},
204
- ExtAPI::extf_t ExtAPI::get_opName(const std::string& s)
204
+ std::string ExtAPI::get_opName(const std::string& s)
205
205
  {
206
- std::map<std::string, extf_t>::iterator pos = op_pair.find(s);
207
- if (pos != op_pair.end())
208
- {
209
- return pos->second;
210
- }
211
- else
212
- {
213
- return EXT_OTHER;
214
- }
206
+ u32_t end = 0;
207
+ while(end < s.size() && !isdigit(s[end]))
208
+ end++;
209
+ return s.substr(0, end);
215
210
  }
216
211
 
217
212
  const std::string& ExtAPI::extType_toString(extType type)
@@ -227,13 +222,15 @@ const std::string& ExtAPI::extType_toString(extType type)
227
222
  // Get numeric index of the argument in external function
228
223
  u32_t ExtAPI::getArgPos(std::string s)
229
224
  {
230
- if(s[0] != 'A')
231
- assert(false && "the argument of extern function in ExtAPI.json should start with 'A' !");
232
- u32_t i = 1;
233
- u32_t start = i;
234
- while(i < s.size() && isdigit(s[i]))
235
- i++;
236
- std::string digitStr = s.substr(start, i-start);
225
+ u32_t start = 0;
226
+ while (start < s.size() && isalpha(s[start]))
227
+ start++;
228
+ if (s.substr(0, start) != "Arg")
229
+ assert(false && "the argument of extern function in ExtAPI.json should start with 'Arg' !");
230
+ u32_t end = start + 1;
231
+ while (end < s.size() && isdigit(s[end]))
232
+ end++;
233
+ std::string digitStr = s.substr(start, end - start);
237
234
  u32_t argNum = atoi(digitStr.c_str());
238
235
  return argNum;
239
236
  }
@@ -241,29 +238,43 @@ u32_t ExtAPI::getArgPos(std::string s)
241
238
  // return value >= 0 is an argument node
242
239
  // return value = -1 is an inst node
243
240
  // return value = -2 is a Dummy node
244
- // return value = -2 is an illegal operand format
241
+ // return value = -3 is an object node
242
+ // return value = -4 is an offset
243
+ // return value = -5 is an illegal operand format
245
244
  int ExtAPI::getNodeIDType(std::string s)
246
245
  {
247
- size_t argPos = -1;
246
+ u32_t argPos = -1;
248
247
  // 'A' represents an argument
249
248
  if (s.size() == 0)
250
- return -3;
251
- if (s[0] == 'A')
249
+ return -5;
250
+ u32_t start = 0;
251
+ while (start < s.size() && isalpha(s[start]))
252
+ start++;
253
+ std::string argStr = s.substr(0, start);
254
+ if (argStr == "Arg")
252
255
  {
253
- size_t start = 1;
254
- size_t end = 1;
256
+ u32_t end = start + 1;
255
257
  while(end < s.size() && isdigit(s[end]))
256
258
  end++;
257
259
  std::string digitStr = s.substr(start, end - start);
258
260
  argPos = atoi(digitStr.c_str());
259
261
  return argPos;
260
262
  }
261
- if(s[0] == 'L')
263
+ else if(argStr == "Ret")
262
264
  return -1;
263
- if(s[0] == 'D')
265
+ else if(argStr == "Dummy")
264
266
  return -2;
267
+ else if(argStr == "Obj")
268
+ return -3;
269
+ else // offset
270
+ {
271
+ u32_t i=0;
272
+ while(i < s.size() && isdigit(s[i])) i++;
273
+ if (i == s.size())
274
+ return -4;
275
+ }
265
276
 
266
- return -3;
277
+ return -5;
267
278
  }
268
279
 
269
280
  // Get external function name, e.g "memcpy"
@@ -288,9 +299,9 @@ cJSON *ExtAPI::get_FunJson(const std::string &funName)
288
299
  }
289
300
 
290
301
  // Get all operations of an extern function
291
- std::vector<std::vector<ExtAPI::Operation *>> ExtAPI::getAllOperations(std::string funName)
302
+ std::vector<ExtAPI::Operation> ExtAPI::getAllOperations(std::string funName)
292
303
  {
293
- std::vector<std::vector<ExtAPI::Operation *>> allOperations;
304
+ std::vector<ExtAPI::Operation> allOperations;
294
305
  cJSON *item = get_FunJson(funName);
295
306
  if (item != nullptr)
296
307
  {
@@ -300,52 +311,25 @@ std::vector<std::vector<ExtAPI::Operation *>> ExtAPI::getAllOperations(std::stri
300
311
  std::vector<ExtAPI::Operation *> operations;
301
312
  while (obj)
302
313
  {
303
- std::string operationName;
304
- std::vector<std::string> arguments;
305
- Operation operation;
306
- // All operations in "compound" are related to each other.
307
- // For example, the first parameter of the second operation
308
- // depends on the second parameter of the first operation.
309
- // Therefore, all operations in "compound" need to be processed uniformly
310
- if (strstr(obj->string, "compound") != NULL)
314
+ std::string op;
315
+ std::vector<std::string> operandsStr;
316
+ std::map<std::string, NodeID> opMap;
317
+ if (obj->type == cJSON_Object || obj->type == cJSON_Array)
311
318
  {
312
- if (obj->type == cJSON_Object)
319
+ op = get_opName(obj -> string);
320
+ cJSON *value = obj->child;
321
+ std::vector<std::string> args;
322
+ while (value)
313
323
  {
314
- cJSON *value = obj->child;
315
- while (value)
324
+ if (value->type == cJSON_String)
316
325
  {
317
- operationName = value -> string;
318
- if (value->type == cJSON_Object)
319
- {
320
- cJSON *edge = value->child;
321
- arguments = ExtAPI::getExtAPI()->get_opArgs(edge);
322
- }
323
- else
324
- {
325
- if (value->type == cJSON_String)
326
- arguments.push_back(value->valuestring);
327
- else
328
- assert(false && "The function operation format is illegal!");
329
- }
330
- operations.push_back(new ExtAPI::Operation(operationName, arguments));
331
- arguments.clear();
332
- value = value->next;
326
+ operandsStr.push_back(value->valuestring);
333
327
  }
328
+ value = value->next;
334
329
  }
335
330
  }
336
- // General operation(Independent operation, the operation does not need to dependent other operations' arguments)
337
- else
338
- {
339
- if (obj->type == cJSON_Object || obj->type == cJSON_Array)
340
- {
341
- operationName = obj -> string;
342
- cJSON *edge = obj->child;
343
- arguments = ExtAPI::getExtAPI()->get_opArgs(edge);
344
- operations.push_back(new ExtAPI::Operation(operationName, arguments));
345
- arguments.clear();
346
- }
347
- }
348
- allOperations.push_back(operations);
331
+ ExtAPI::Operation operation(op, operandsStr);
332
+ allOperations.push_back(operation);
349
333
  operations.clear();
350
334
 
351
335
  obj = obj -> next;
@@ -519,3 +503,4 @@ bool ExtAPI::is_ext(const SVFFunction *F)
519
503
  }
520
504
  return res;
521
505
  }
506
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-tools",
3
- "version": "1.0.549",
3
+ "version": "1.0.550",
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": {