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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-tools",
3
- "version": "1.0.702",
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
@@ -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, CallBase* cs);
239
- virtual void handleExtCall(CallBase* cs, const Function *F);
240
- void addComplexConsForExt(const Value* D, const Value* S, const Value* sz);
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 Value* val, const LocationSet& ls, const SVFType* baseType);
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
- handleExtCall(cs, callee);
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 Value* D, const Value* S, const Value* szValue)
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
- std::vector<LocationSet> srcFields;
1168
- std::vector<LocationSet> dstFields;
1169
- const Type* stype = getBaseTypeAndFlattenedFields(S, srcFields, szValue);
1170
- const Type* dtype = getBaseTypeAndFlattenedFields(D, dstFields, szValue);
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 && (LLVMUtil::isConstDataOrAggData(D) || LLVMUtil::isConstDataOrAggData(S)))
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
- LLVMModuleSet* llvmmodule = LLVMModuleSet::getLLVMModuleSet();
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(llvmmodule->getSVFType(stype),
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, CallBase* cs)
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( cs->arg_size() <= (u32_t) nodeIDType)
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(cs->getArgOperand(nodeIDType)));
1232
- nodeIDMap[s] = getValueNode(cs->getArgOperand(nodeIDType));
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(cs));
1238
- nodeIDMap[s] = getValueNode(cs);
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 (SVFUtil::isa<PointerType>(cs->getType()))
1254
+ if (svfcall->getType()->isPointerTy())
1248
1255
  {
1249
- operands.push_back(getObjectNode(cs));
1250
- nodeIDMap[s] = getObjectNode(cs);
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(CallBase* cs, const Function *callee)
1352
+ void SVFIRBuilder::handleExtCall(SVFInstruction* svfinst, const SVFFunction* svfcallee)
1279
1353
  {
1280
- const SVFInstruction* svfinst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(cs);
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(cs);
1289
- NodeID obj = getObjectNode(cs);
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 Value* arg = cs->getArgOperand(arg_pos);
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(LLVMModuleSet::getLLVMModuleSet()->getSVFType(arg->getType()));
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 " << callee->getName().str() << " not in the external function summary ExtAPI.json file";
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, cs);
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
- std::vector<LocationSet> dstFields;
1397
- const Type* dtype = getBaseTypeAndFlattenedFields(cs->getArgOperand(op.getOperands()[0]), dstFields, cs->getArgOperand(op.getOperands()[2]));
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(LLVMModuleSet::getLLVMModuleSet()->getSVFType(dtype),
1403
- dstFields[index].getConstantFieldIdx());
1404
- NodeID dField = getGepValVar(cs->getArgOperand(op.getOperands()[0]), dstFields[index], dElementType);
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(SVFUtil::isa<PointerType>(cs->getType()))
1408
- addCopyEdge(getValueNode(cs->getArgOperand(op.getOperands()[0])), getValueNode(cs));
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(cs->getArgOperand(op.getOperands()[0]), cs->getArgOperand(op.getOperands()[1]), cs->getArgOperand(op.getOperands()[2]));
1488
+ addComplexConsForExt(svfcall->getArgOperand(op.getOperands()[0]), svfcall->getArgOperand(op.getOperands()[1]), svfcall->getArgOperand(op.getOperands()[2]));
1415
1489
  else
1416
- addComplexConsForExt(cs->getArgOperand(op.getOperands()[0]), cs->getArgOperand(op.getOperands()[1]), nullptr);
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(cs->arg_size() == 4 && "_Rb_tree_insert_and_rebalance should have 4 arguments.\n");
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(LLVMModuleSet::getLLVMModuleSet()->getSVFValue(vArg3));
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(LLVMModuleSet::getLLVMModuleSet()->getSVFType(type),
1510
+ const SVFType* elementType = pag->getSymbolInfo()->getFlatternedElemType(pag->getTypeLocSetsMap(vnArg3).first,
1467
1511
  fields[i].getConstantFieldIdx());
1468
- NodeID vnD = getGepValVar(vArg3, fields[i], elementType);
1469
- NodeID vnS = getValueNode(vArg1);
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
- handleExtCall(const_cast<CallBase*>(callbase), callee);
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 Value* val, const LocationSet& ls, const SVFType* elementType)
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
- LLVMModuleSet* llvmmodule = LLVMModuleSet::getLLVMModuleSet();
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;