svf-tools 1.0.729 → 1.0.731
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/SVFValue.h +7 -0
- package/svf/include/Util/ExtAPI.h +209 -19
- package/svf/include/Util/ExtAPI.json +125 -22
- package/svf/lib/Util/ExtAPI.cpp +90 -18
- package/svf-llvm/include/SVF-LLVM/LLVMModule.h +1 -0
- package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +23 -0
- package/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +10 -5
- package/svf-llvm/lib/CHGBuilder.cpp +2 -5
- package/svf-llvm/lib/DCHG.cpp +1 -2
- package/svf-llvm/lib/LLVMUtil.cpp +34 -11
- package/svf-llvm/lib/SVFIRBuilder.cpp +1 -423
- package/svf-llvm/lib/SVFIRExtAPI.cpp +681 -0
package/svf/lib/Util/ExtAPI.cpp
CHANGED
|
@@ -348,44 +348,116 @@ cJSON* ExtAPI::get_FunJson(const std::string& funName)
|
|
|
348
348
|
return cJSON_GetObjectItemCaseSensitive(root, funName.c_str());
|
|
349
349
|
}
|
|
350
350
|
|
|
351
|
+
ExtAPI::Operand ExtAPI::getBasicOperation(cJSON* obj)
|
|
352
|
+
{
|
|
353
|
+
Operand basicOp;
|
|
354
|
+
if (strstr(obj->string, "AddrStmt") != NULL)
|
|
355
|
+
basicOp.setType(ExtAPI::OperationType::Addr);
|
|
356
|
+
else if (strstr(obj->string, "CopyStmt") != NULL)
|
|
357
|
+
basicOp.setType(ExtAPI::OperationType::Copy);
|
|
358
|
+
else if (strstr(obj->string, "LoadStmt") != NULL)
|
|
359
|
+
basicOp.setType(ExtAPI::OperationType::Load);
|
|
360
|
+
else if (strstr(obj->string, "StoreStmt") != NULL)
|
|
361
|
+
basicOp.setType(ExtAPI::OperationType::Store);
|
|
362
|
+
else if (strstr(obj->string, "GepStmt") != NULL)
|
|
363
|
+
basicOp.setType(ExtAPI::OperationType::Gep);
|
|
364
|
+
else if (strstr(obj->string, "ReturnStmt") != NULL)
|
|
365
|
+
basicOp.setType(ExtAPI::OperationType::Return);
|
|
366
|
+
else if (strstr(obj->string, "Rb_tree_ops") != NULL)
|
|
367
|
+
basicOp.setType(ExtAPI::OperationType::Rb_tree_ops);
|
|
368
|
+
else if (strstr(obj->string, "memcpy_like") != NULL)
|
|
369
|
+
basicOp.setType(ExtAPI::OperationType::Memcpy_like);
|
|
370
|
+
else if (strstr(obj->string, "memset_like") != NULL)
|
|
371
|
+
basicOp.setType(ExtAPI::OperationType::Memset_like);
|
|
372
|
+
else
|
|
373
|
+
assert(false && "Unknown operation type");
|
|
374
|
+
|
|
375
|
+
cJSON* value = obj->child;
|
|
376
|
+
while (value)
|
|
377
|
+
{
|
|
378
|
+
if (strcmp(value->string, "src") == 0)
|
|
379
|
+
basicOp.setSrcValue(value->valuestring);
|
|
380
|
+
else if (strcmp(value->string, "dst") == 0)
|
|
381
|
+
basicOp.setDstValue(value->valuestring);
|
|
382
|
+
else if (strcmp(value->string, "offset") == 0 || strcmp(value->string, "size") == 0)
|
|
383
|
+
basicOp.setOffsetOrSizeStr(value->valuestring);
|
|
384
|
+
else
|
|
385
|
+
assert(false && "Unknown operation value");
|
|
386
|
+
value = value->next;
|
|
387
|
+
}
|
|
388
|
+
return basicOp;
|
|
389
|
+
}
|
|
390
|
+
|
|
351
391
|
// Get all operations of an extern function
|
|
352
|
-
|
|
392
|
+
ExtAPI::ExtFunctionOps ExtAPI::getExtFunctionOps(std::string funName)
|
|
353
393
|
{
|
|
354
|
-
|
|
394
|
+
auto it = extFunToOps.find(funName);
|
|
395
|
+
if (it != extFunToOps.end())
|
|
396
|
+
return it->second;
|
|
397
|
+
|
|
398
|
+
ExtAPI::ExtFunctionOps extFunctionOps;
|
|
399
|
+
extFunctionOps.setExtFunName(funName);
|
|
355
400
|
cJSON* item = get_FunJson(funName);
|
|
356
401
|
if (item != nullptr)
|
|
357
402
|
{
|
|
358
403
|
cJSON* obj = item->child;
|
|
359
404
|
// Get the first operation of the function
|
|
360
405
|
obj = obj->next->next->next->next;
|
|
361
|
-
std::vector<ExtAPI::Operation*> operations;
|
|
362
406
|
while (obj)
|
|
363
407
|
{
|
|
364
|
-
|
|
365
|
-
std::vector<std::string> operandsStr;
|
|
366
|
-
std::map<std::string, NodeID> opMap;
|
|
408
|
+
ExtOperation operation;
|
|
367
409
|
if (obj->type == cJSON_Object || obj->type == cJSON_Array)
|
|
368
410
|
{
|
|
369
|
-
|
|
370
|
-
cJSON* value = obj->child;
|
|
371
|
-
std::vector<std::string> args;
|
|
372
|
-
while (value)
|
|
411
|
+
if (strstr(obj->string, "CallStmt") != NULL)
|
|
373
412
|
{
|
|
374
|
-
|
|
413
|
+
extFunctionOps.setCallStmtNum(extFunctionOps.getCallStmtNum() + 1);
|
|
414
|
+
operation.setCallOp(true);
|
|
415
|
+
cJSON* value = obj->child;
|
|
416
|
+
while (value)
|
|
375
417
|
{
|
|
376
|
-
|
|
418
|
+
if (strcmp(value->string, "callee_name") == 0)
|
|
419
|
+
operation.setCalleeName(value->valuestring);
|
|
420
|
+
else if (strcmp(value->string, "callee_return") == 0)
|
|
421
|
+
operation.setCalleeReturn(value->valuestring);
|
|
422
|
+
else if (strcmp(value->string, "callee_arguments") == 0)
|
|
423
|
+
operation.setCalleeArguments(value->valuestring);
|
|
424
|
+
else
|
|
425
|
+
operation.getCalleeOperands().push_back(getBasicOperation(value));
|
|
426
|
+
value = value->next;
|
|
377
427
|
}
|
|
378
|
-
value = value->next;
|
|
379
428
|
}
|
|
429
|
+
else if (strstr(obj->string, "CondStmt") != NULL)
|
|
430
|
+
{
|
|
431
|
+
operation.setConOp(true);
|
|
432
|
+
obj = obj->child;
|
|
433
|
+
assert(strcmp(obj->string, "Condition") == 0 && "Unknown operation type");
|
|
434
|
+
operation.setConOp(obj->valuestring);
|
|
435
|
+
obj = obj->next;
|
|
436
|
+
assert(strcmp(obj->string, "TrueBranch") == 0 && "Unknown operation type");
|
|
437
|
+
cJSON* value = obj->child;
|
|
438
|
+
while (value)
|
|
439
|
+
{
|
|
440
|
+
operation.getTrueBranchOperands().push_back(getBasicOperation(value));
|
|
441
|
+
value = value->next;
|
|
442
|
+
}
|
|
443
|
+
obj = obj->next;
|
|
444
|
+
assert(strcmp(obj->string, "FalseBranch") == 0&& "Unknown operation type");
|
|
445
|
+
value = obj->child;
|
|
446
|
+
while (value)
|
|
447
|
+
{
|
|
448
|
+
operation.getFalseBranchOperands().push_back(getBasicOperation(value));
|
|
449
|
+
value = value->next;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
else
|
|
453
|
+
operation.setBasicOp(getBasicOperation(obj));
|
|
380
454
|
}
|
|
381
|
-
ExtAPI::Operation operation(op, operandsStr);
|
|
382
|
-
allOperations.push_back(operation);
|
|
383
|
-
operations.clear();
|
|
384
|
-
|
|
385
455
|
obj = obj->next;
|
|
456
|
+
extFunctionOps.getOperations().push_back(operation);
|
|
386
457
|
}
|
|
387
458
|
}
|
|
388
|
-
|
|
459
|
+
extFunToOps[funName] = extFunctionOps;
|
|
460
|
+
return extFunctionOps;
|
|
389
461
|
}
|
|
390
462
|
|
|
391
463
|
// Get arguments of the operation, e.g. ["A1R", "A0", "A2"]
|
|
@@ -409,6 +409,29 @@ void viewCFG(const Function* fun);
|
|
|
409
409
|
// Dump Control Flow Graph of llvm function, without instructions
|
|
410
410
|
void viewCFGOnly(const Function* fun);
|
|
411
411
|
|
|
412
|
+
/*
|
|
413
|
+
* Get the vtable struct of a class.
|
|
414
|
+
*
|
|
415
|
+
* Given the class:
|
|
416
|
+
*
|
|
417
|
+
* class A {
|
|
418
|
+
* virtual ~A();
|
|
419
|
+
* };
|
|
420
|
+
* A::~A() = default;
|
|
421
|
+
*
|
|
422
|
+
* The corresponding vtable @_ZTV1A is of type:
|
|
423
|
+
*
|
|
424
|
+
* { [4 x i8*] }
|
|
425
|
+
*
|
|
426
|
+
* If the program has been compiled with AddressSanitizer,
|
|
427
|
+
* the vtable will have redzones and appear as:
|
|
428
|
+
*
|
|
429
|
+
* { { [4 x i8*] }, [32 x i8] }
|
|
430
|
+
*
|
|
431
|
+
* See https://github.com/SVF-tools/SVF/issues/1114 for more.
|
|
432
|
+
*/
|
|
433
|
+
const ConstantStruct *getVtblStruct(const GlobalValue *vtbl);
|
|
434
|
+
|
|
412
435
|
bool isValVtbl(const Value* val);
|
|
413
436
|
bool isLoadVtblInst(const LoadInst* loadInst);
|
|
414
437
|
bool isVirtualCallSite(const CallBase* cs);
|
|
@@ -224,9 +224,6 @@ protected:
|
|
|
224
224
|
/// Get the base value of (i8* src and i8* dst) for external argument (e.g. memcpy(i8* dst, i8* src, int size))
|
|
225
225
|
const Value* getBaseValueForExtArg(const Value* V);
|
|
226
226
|
|
|
227
|
-
/// Get the base type and max offset
|
|
228
|
-
const Type* getBaseTypeAndFlattenedFields(const Value* V, std::vector<LocationSet> &fields, const Value* sz);
|
|
229
|
-
|
|
230
227
|
/// Handle direct call
|
|
231
228
|
void handleDirectCall(CallBase* cs, const Function *F);
|
|
232
229
|
|
|
@@ -235,9 +232,17 @@ protected:
|
|
|
235
232
|
|
|
236
233
|
/// Handle external call
|
|
237
234
|
//@{
|
|
238
|
-
virtual
|
|
235
|
+
virtual SVFCallInst* addSVFExtCallInst(const SVFCallInst* svfInst, SVFBasicBlock* svfBB, const SVFFunction* svfCaller, const SVFFunction* svfCallee);
|
|
236
|
+
virtual void addSVFExtRetInst(SVFCallInst* svfCall, SVFBasicBlock* svfBB, SVFFunction* svfCaller);
|
|
237
|
+
virtual SVFInstruction* addSVFExtInst(const std::string& instName, const SVFCallInst* svfInst, SVFBasicBlock* svfBB, SVF::ExtAPI::OperationType opType, const SVFType* svfType);
|
|
238
|
+
virtual void extFuncAtomaticOperation(ExtAPI::Operand& atomicOp, const SVFCallInst* svfInst);
|
|
239
|
+
virtual SVFBasicBlock* extFuncInitialization(const SVFCallInst* svfInst, SVFFunction* svfCaller);
|
|
240
|
+
virtual void handleExtCallStat(ExtAPI::ExtFunctionOps &extFunctionOps, const SVFCallInst* svfInst);
|
|
241
|
+
virtual NodeID getExtID(ExtAPI::OperationType operationType, const std::string &s, const SVFCallInst* svfCall);
|
|
242
|
+
virtual void parseAtomaticOp(SVF::ExtAPI::Operand &atomaticOp, const SVFCallInst* svfCall, std::map<std::string, NodeID> &nodeIDMap);
|
|
243
|
+
virtual void parseExtFunctionOps(ExtAPI::ExtFunctionOps &extFunctionOps, const SVFCallInst* svfCall);
|
|
239
244
|
virtual void preProcessExtCall(CallBase* cs);
|
|
240
|
-
virtual void handleExtCall(SVFInstruction*
|
|
245
|
+
virtual void handleExtCall(const SVFInstruction* svfInst, const SVFFunction* svfCallee);
|
|
241
246
|
void addComplexConsForExt(const SVFValue* D, const SVFValue* S, const SVFValue* sz);
|
|
242
247
|
//@}
|
|
243
248
|
|
|
@@ -90,8 +90,7 @@ void CHGBuilder::buildCHGNodes(const GlobalValue *globalvalue)
|
|
|
90
90
|
{
|
|
91
91
|
if (LLVMUtil::isValVtbl(globalvalue) && globalvalue->getNumOperands() > 0)
|
|
92
92
|
{
|
|
93
|
-
const ConstantStruct *vtblStruct =
|
|
94
|
-
assert(vtblStruct && "Initializer of a vtable not a struct?");
|
|
93
|
+
const ConstantStruct *vtblStruct = LLVMUtil::getVtblStruct(globalvalue);
|
|
95
94
|
string className = getClassNameFromVtblObj(globalvalue->getName().str());
|
|
96
95
|
if (!chg->getNode(className))
|
|
97
96
|
createNode(className);
|
|
@@ -367,9 +366,7 @@ void CHGBuilder::analyzeVTables(const Module &M)
|
|
|
367
366
|
const GlobalValue *globalvalue = SVFUtil::dyn_cast<const GlobalValue>(&(*I));
|
|
368
367
|
if (LLVMUtil::isValVtbl(globalvalue) && globalvalue->getNumOperands() > 0)
|
|
369
368
|
{
|
|
370
|
-
const ConstantStruct *vtblStruct =
|
|
371
|
-
SVFUtil::dyn_cast<ConstantStruct>(globalvalue->getOperand(0));
|
|
372
|
-
assert(vtblStruct && "Initializer of a vtable not a struct?");
|
|
369
|
+
const ConstantStruct *vtblStruct = LLVMUtil::getVtblStruct(globalvalue);
|
|
373
370
|
|
|
374
371
|
string vtblClassName = getClassNameFromVtblObj(globalvalue->getName().str());
|
|
375
372
|
CHNode *node = chg->getNode(vtblClassName);
|
package/svf-llvm/lib/DCHG.cpp
CHANGED
|
@@ -180,8 +180,7 @@ void DCHGraph::buildVTables(const SVFModule &module)
|
|
|
180
180
|
node->setVTable(svfgv);
|
|
181
181
|
vtblToTypeMap[svfgv] = getCanonicalType(type);
|
|
182
182
|
|
|
183
|
-
const ConstantStruct *vtbls =
|
|
184
|
-
assert(vtbls && "unexpected vtable type");
|
|
183
|
+
const ConstantStruct *vtbls = LLVMUtil::getVtblStruct(gv);
|
|
185
184
|
for (unsigned nthVtbl = 0; nthVtbl < vtbls->getNumOperands(); ++nthVtbl)
|
|
186
185
|
{
|
|
187
186
|
const ConstantArray *vtbl = SVFUtil::dyn_cast<ConstantArray>(vtbls->getOperand(nthVtbl));
|
|
@@ -682,6 +682,19 @@ bool LLVMUtil::isConstantObjSym(const Value* val)
|
|
|
682
682
|
return LLVMUtil::isConstDataOrAggData(val);
|
|
683
683
|
}
|
|
684
684
|
|
|
685
|
+
const ConstantStruct *LLVMUtil::getVtblStruct(const GlobalValue *vtbl)
|
|
686
|
+
{
|
|
687
|
+
const ConstantStruct *vtblStruct = SVFUtil::dyn_cast<ConstantStruct>(vtbl->getOperand(0));
|
|
688
|
+
assert(vtblStruct && "Initializer of a vtable not a struct?");
|
|
689
|
+
|
|
690
|
+
if (vtblStruct->getNumOperands() == 2 &&
|
|
691
|
+
SVFUtil::isa<ConstantStruct>(vtblStruct->getOperand(0)) &&
|
|
692
|
+
vtblStruct->getOperand(1)->getType()->isArrayTy())
|
|
693
|
+
return SVFUtil::cast<ConstantStruct>(vtblStruct->getOperand(0));
|
|
694
|
+
|
|
695
|
+
return vtblStruct;
|
|
696
|
+
}
|
|
697
|
+
|
|
685
698
|
bool LLVMUtil::isValVtbl(const Value* val)
|
|
686
699
|
{
|
|
687
700
|
if (!SVFUtil::isa<GlobalVariable>(val))
|
|
@@ -1036,22 +1049,32 @@ std::string dumpLLVMValue(const SVFValue* svfValue)
|
|
|
1036
1049
|
{
|
|
1037
1050
|
std::string str;
|
|
1038
1051
|
llvm::raw_string_ostream rawstr(str);
|
|
1039
|
-
if (
|
|
1040
|
-
{
|
|
1041
|
-
rawstr << "Function: " << fun->getName() << " ";
|
|
1042
|
-
}
|
|
1043
|
-
else if (const SVFBasicBlock* bb = SVFUtil::dyn_cast<SVFBasicBlock>(svfValue))
|
|
1052
|
+
if (LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(svfValue) == nullptr)
|
|
1044
1053
|
{
|
|
1045
|
-
|
|
1054
|
+
assert((SVFUtil::isa<SVFInstruction>(svfValue) ||
|
|
1055
|
+
SVFUtil::isa<SVFBasicBlock>(svfValue)) && "Manually created SVF call inst, actual parameter and BasicBlock by ExtAPI do not have LLVM value!");
|
|
1056
|
+
rawstr << svfValue->getName();
|
|
1057
|
+
return rawstr.str();
|
|
1046
1058
|
}
|
|
1047
1059
|
else
|
|
1048
1060
|
{
|
|
1049
|
-
const
|
|
1050
|
-
|
|
1051
|
-
|
|
1061
|
+
if (const SVF::SVFFunction* fun = SVFUtil::dyn_cast<SVFFunction>(svfValue))
|
|
1062
|
+
{
|
|
1063
|
+
rawstr << "Function: " << fun->getName() << " ";
|
|
1064
|
+
}
|
|
1065
|
+
else if (const SVFBasicBlock* bb = SVFUtil::dyn_cast<SVFBasicBlock>(svfValue))
|
|
1066
|
+
{
|
|
1067
|
+
rawstr << "BasicBlock: " << bb->getName() << " ";
|
|
1068
|
+
}
|
|
1069
|
+
else
|
|
1070
|
+
{
|
|
1071
|
+
const Value* val =
|
|
1072
|
+
LLVMModuleSet::getLLVMModuleSet()->getLLVMValue(svfValue);
|
|
1073
|
+
rawstr << " " << *val << " ";
|
|
1074
|
+
}
|
|
1075
|
+
rawstr << svfValue->getSourceLoc();
|
|
1076
|
+
return rawstr.str();
|
|
1052
1077
|
}
|
|
1053
|
-
rawstr << svfValue->getSourceLoc();
|
|
1054
|
-
return rawstr.str();
|
|
1055
1078
|
}
|
|
1056
1079
|
|
|
1057
1080
|
std::string dumpLLVMType(const SVFType* svfType)
|