svf-tools 1.0.987 → 1.0.989
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/AE/Svfexe/AEDetector.h +15 -2
- package/svf/include/AE/Svfexe/AbsExtAPI.h +147 -0
- package/svf/include/AE/Svfexe/AbstractInterpretation.h +25 -92
- package/svf/include/SVFIR/SVFValue.h +0 -11
- package/svf/include/Util/ExtAPI.h +10 -0
- package/svf/include/Util/SVFUtil.h +1 -7
- package/svf/lib/AE/Svfexe/AEDetector.cpp +108 -28
- package/svf/lib/AE/Svfexe/AbsExtAPI.cpp +765 -0
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +24 -797
- package/svf/lib/SVFIR/SVFFileSystem.cpp +0 -2
- package/svf/lib/Util/ExtAPI.cpp +33 -10
- package/svf/lib/Util/SVFUtil.cpp +0 -15
- package/svf-llvm/include/SVF-LLVM/LLVMModule.h +1 -58
- package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +10 -19
- package/svf-llvm/lib/CHGBuilder.cpp +2 -2
- package/svf-llvm/lib/LLVMModule.cpp +216 -230
- package/svf-llvm/lib/LLVMUtil.cpp +32 -228
- package/svf-llvm/lib/ObjTypeInference.cpp +2 -2
- package/svf-llvm/lib/SVFIRBuilder.cpp +0 -1
- package/svf-llvm/lib/SymbolTableBuilder.cpp +5 -6
- package/svf-llvm/lib/extapi.c +0 -1
|
@@ -36,16 +36,6 @@
|
|
|
36
36
|
|
|
37
37
|
using namespace SVF;
|
|
38
38
|
|
|
39
|
-
const Function* LLVMUtil::getDefFunForMultipleModule(const Function* fun)
|
|
40
|
-
{
|
|
41
|
-
if (fun == nullptr)
|
|
42
|
-
return nullptr;
|
|
43
|
-
LLVMModuleSet* llvmModuleset = LLVMModuleSet::getLLVMModuleSet();
|
|
44
|
-
if (fun->isDeclaration() && llvmModuleset->hasDefinition(fun))
|
|
45
|
-
fun = LLVMModuleSet::getLLVMModuleSet()->getDefinition(fun);
|
|
46
|
-
return fun;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
39
|
const Function* LLVMUtil::getProgFunction(const std::string& funName)
|
|
50
40
|
{
|
|
51
41
|
for (const Module& M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
|
|
@@ -68,7 +58,7 @@ const Function* LLVMUtil::getProgFunction(const std::string& funName)
|
|
|
68
58
|
*/
|
|
69
59
|
bool LLVMUtil::isObject(const Value* ref)
|
|
70
60
|
{
|
|
71
|
-
if (SVFUtil::isa<Instruction>(ref) &&
|
|
61
|
+
if (SVFUtil::isa<Instruction>(ref) && isHeapAllocExtCallViaRet(SVFUtil::cast<Instruction>(ref)))
|
|
72
62
|
return true;
|
|
73
63
|
if (SVFUtil::isa<GlobalVariable>(ref))
|
|
74
64
|
return true;
|
|
@@ -177,22 +167,6 @@ bool LLVMUtil::isUncalledFunction (const Function* fun)
|
|
|
177
167
|
if (LLVMUtil::isCallSite(*i))
|
|
178
168
|
return false;
|
|
179
169
|
}
|
|
180
|
-
if (LLVMModuleSet::getLLVMModuleSet()->hasDeclaration(fun))
|
|
181
|
-
{
|
|
182
|
-
const LLVMModuleSet::FunctionSetType &decls = LLVMModuleSet::getLLVMModuleSet()->getDeclaration(fun);
|
|
183
|
-
for (LLVMModuleSet::FunctionSetType::const_iterator it = decls.begin(),
|
|
184
|
-
eit = decls.end(); it != eit; ++it)
|
|
185
|
-
{
|
|
186
|
-
const Function* decl = *it;
|
|
187
|
-
if(decl->hasAddressTaken())
|
|
188
|
-
return false;
|
|
189
|
-
for (Value::const_user_iterator i = decl->user_begin(), e = decl->user_end(); i != e; ++i)
|
|
190
|
-
{
|
|
191
|
-
if (LLVMUtil::isCallSite(*i))
|
|
192
|
-
return false;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
170
|
return true;
|
|
197
171
|
}
|
|
198
172
|
|
|
@@ -334,17 +308,6 @@ u32_t LLVMUtil::getNumOfElements(const Type* ety)
|
|
|
334
308
|
return numOfFields;
|
|
335
309
|
}
|
|
336
310
|
|
|
337
|
-
/*!
|
|
338
|
-
* Get the num of BB's predecessors
|
|
339
|
-
*/
|
|
340
|
-
u32_t LLVMUtil::getBBPredecessorNum(const BasicBlock* BB)
|
|
341
|
-
{
|
|
342
|
-
u32_t num = 0;
|
|
343
|
-
for (const_pred_iterator it = pred_begin(BB), et = pred_end(BB); it != et; ++it)
|
|
344
|
-
num++;
|
|
345
|
-
return num;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
311
|
/*
|
|
349
312
|
* Reference functions:
|
|
350
313
|
* llvm::parseIRFile (lib/IRReader/IRReader.cpp)
|
|
@@ -398,73 +361,6 @@ void LLVMUtil::processArguments(int argc, char **argv, int &arg_num, char **arg_
|
|
|
398
361
|
}
|
|
399
362
|
}
|
|
400
363
|
|
|
401
|
-
void LLVMUtil::removeFunAnnotations(Set<Function*>& removedFuncList)
|
|
402
|
-
{
|
|
403
|
-
if (removedFuncList.empty())
|
|
404
|
-
return; // No functions to remove annotations in extapi.bc module
|
|
405
|
-
|
|
406
|
-
Module* module = (*removedFuncList.begin())->getParent();
|
|
407
|
-
GlobalVariable* glob = module->getGlobalVariable("llvm.global.annotations");
|
|
408
|
-
if (glob == nullptr || !glob->hasInitializer())
|
|
409
|
-
return;
|
|
410
|
-
|
|
411
|
-
ConstantArray* ca = SVFUtil::dyn_cast<ConstantArray>(glob->getInitializer());
|
|
412
|
-
if (ca == nullptr)
|
|
413
|
-
return;
|
|
414
|
-
|
|
415
|
-
std::vector<Constant*> newAnnotations;
|
|
416
|
-
for (unsigned i = 0; i < ca->getNumOperands(); ++i)
|
|
417
|
-
{
|
|
418
|
-
ConstantStruct* structAn = SVFUtil::dyn_cast<ConstantStruct>(ca->getOperand(i));
|
|
419
|
-
if (structAn == nullptr)
|
|
420
|
-
continue;
|
|
421
|
-
|
|
422
|
-
Function* annotatedFunc = nullptr;
|
|
423
|
-
|
|
424
|
-
// Non-opague pointer, try to cast to ConstantExpr and check for BitCast
|
|
425
|
-
if (ConstantExpr* expr = SVFUtil::dyn_cast<ConstantExpr>(structAn->getOperand(0)))
|
|
426
|
-
{
|
|
427
|
-
if (expr->getOpcode() == Instruction::BitCast)
|
|
428
|
-
{
|
|
429
|
-
annotatedFunc = SVFUtil::dyn_cast<Function>(expr->getOperand(0));
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
// Opague pointer, If the above method didn't work, try casting directly to Function
|
|
434
|
-
if (!annotatedFunc)
|
|
435
|
-
{
|
|
436
|
-
annotatedFunc = SVFUtil::dyn_cast<Function>(structAn->getOperand(0));
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
// Process the annotated function if it's not in the removed list
|
|
440
|
-
if (annotatedFunc && std::find(removedFuncList.begin(), removedFuncList.end(), annotatedFunc) == removedFuncList.end())
|
|
441
|
-
{
|
|
442
|
-
newAnnotations.push_back(structAn);
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
if (newAnnotations.size() == ca->getNumOperands())
|
|
447
|
-
return; // No annotations to remove
|
|
448
|
-
|
|
449
|
-
ArrayType* annotationsType = ArrayType::get(ca->getType()->getElementType(), newAnnotations.size());
|
|
450
|
-
Constant* newCA = ConstantArray::get(annotationsType, newAnnotations);
|
|
451
|
-
|
|
452
|
-
glob->setName("llvm.global.annotations.old");
|
|
453
|
-
GlobalVariable *GV = new GlobalVariable(newCA->getType(), glob->isConstant(), glob->getLinkage(), newCA, "llvm.global.annotations");
|
|
454
|
-
GV->setSection(glob->getSection());
|
|
455
|
-
|
|
456
|
-
#if (LLVM_VERSION_MAJOR < 17)
|
|
457
|
-
module->getGlobalList().push_back(GV);
|
|
458
|
-
#elif (LLVM_VERSION_MAJOR >= 17)
|
|
459
|
-
module->insertGlobalVariable(GV);
|
|
460
|
-
#else
|
|
461
|
-
assert(false && "llvm version not supported!");
|
|
462
|
-
#endif
|
|
463
|
-
|
|
464
|
-
glob->replaceAllUsesWith(GV);
|
|
465
|
-
glob->eraseFromParent();
|
|
466
|
-
}
|
|
467
|
-
|
|
468
364
|
/// Get all called funcions in a parent function
|
|
469
365
|
std::vector<const Function *> LLVMUtil::getCalledFunctions(const Function *F)
|
|
470
366
|
{
|
|
@@ -485,84 +381,6 @@ std::vector<const Function *> LLVMUtil::getCalledFunctions(const Function *F)
|
|
|
485
381
|
return calledFunctions;
|
|
486
382
|
}
|
|
487
383
|
|
|
488
|
-
bool LLVMUtil::isUnusedGlobalVariable(const GlobalVariable& global)
|
|
489
|
-
{
|
|
490
|
-
// Check if it is an empty global annotations
|
|
491
|
-
if (global.getName() == "llvm.global.annotations" && SVFUtil::isa<ConstantArray>(global.getInitializer()))
|
|
492
|
-
return false;
|
|
493
|
-
else
|
|
494
|
-
{
|
|
495
|
-
// Check if any global strings has at least one effective user
|
|
496
|
-
for (auto& use : global.uses())
|
|
497
|
-
if (use.getUser()->getNumUses() != 0)
|
|
498
|
-
return false;
|
|
499
|
-
}
|
|
500
|
-
return true;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
void LLVMUtil::removeUnusedGlobalVariables(Module* module)
|
|
504
|
-
{
|
|
505
|
-
assert(module && "Null module pointer!");
|
|
506
|
-
std::vector<GlobalVariable*> unusedGlobals;
|
|
507
|
-
for (GlobalVariable& global : module->globals())
|
|
508
|
-
if (isUnusedGlobalVariable(global))
|
|
509
|
-
// Record unused global variables
|
|
510
|
-
unusedGlobals.push_back(&global);
|
|
511
|
-
|
|
512
|
-
// Delete unused global variables
|
|
513
|
-
for (GlobalVariable* global : unusedGlobals)
|
|
514
|
-
global->eraseFromParent();
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
/// Delete unused functions, annotations and global variables in extapi.bc
|
|
518
|
-
void LLVMUtil::removeUnusedFuncsAndAnnotationsAndGlobalVariables(Set<Function*> removedFuncList)
|
|
519
|
-
{
|
|
520
|
-
if (removedFuncList.empty())
|
|
521
|
-
return;
|
|
522
|
-
|
|
523
|
-
Module* mod = (*removedFuncList.begin())->getParent();
|
|
524
|
-
if (mod->getName().str() != ExtAPI::getExtAPI()->getExtBcPath())
|
|
525
|
-
return;
|
|
526
|
-
|
|
527
|
-
/// Delete unused function annotations
|
|
528
|
-
LLVMUtil::removeFunAnnotations(removedFuncList);
|
|
529
|
-
|
|
530
|
-
/// Delete unused functions
|
|
531
|
-
/// The functions to be deleted from extapi.bc can be categorized into two types.
|
|
532
|
-
/// The first type includes functions do not contain any invocation statements,
|
|
533
|
-
/// The second type includes functions whose contain invocation statements.
|
|
534
|
-
/// It is necessary to delete functions of the second type first before deleting those of the first type;
|
|
535
|
-
/// Otherwise, errors may occur when calling eraseFromParent().
|
|
536
|
-
std::vector<Function*> funcsToKeep;
|
|
537
|
-
/// Check whether a function is called by other functions
|
|
538
|
-
auto isCalledFunction = [](llvm::Function* F)
|
|
539
|
-
{
|
|
540
|
-
assert(F && "Null function pointer!");
|
|
541
|
-
for (auto& use : F->uses())
|
|
542
|
-
{
|
|
543
|
-
llvm::User* user = use.getUser();
|
|
544
|
-
if (llvm::isa<llvm::CallBase>(user))
|
|
545
|
-
return true;
|
|
546
|
-
}
|
|
547
|
-
return false;
|
|
548
|
-
};
|
|
549
|
-
|
|
550
|
-
for (Function* func : removedFuncList)
|
|
551
|
-
{
|
|
552
|
-
if (isCalledFunction(func))
|
|
553
|
-
// Record first kind function(which does not contain any invocation statements)
|
|
554
|
-
funcsToKeep.push_back(func);
|
|
555
|
-
else
|
|
556
|
-
// Delete second kind function(which contains invocation statements)
|
|
557
|
-
func->eraseFromParent();
|
|
558
|
-
}
|
|
559
|
-
// Delete first kind functions
|
|
560
|
-
for (Function* func : funcsToKeep)
|
|
561
|
-
func->eraseFromParent();
|
|
562
|
-
// Delete unused global variables
|
|
563
|
-
removeUnusedGlobalVariables(mod);
|
|
564
|
-
}
|
|
565
|
-
|
|
566
384
|
std::string LLVMUtil::restoreFuncName(std::string funcName)
|
|
567
385
|
{
|
|
568
386
|
assert(!funcName.empty() && "Empty function name");
|
|
@@ -606,26 +424,6 @@ const Value* LLVMUtil::getGlobalRep(const Value* val)
|
|
|
606
424
|
return val;
|
|
607
425
|
}
|
|
608
426
|
|
|
609
|
-
u32_t LLVMUtil::getTypeSizeInBytes(const Type* type)
|
|
610
|
-
{
|
|
611
|
-
// if the type has size then simply return it, otherwise just return 0
|
|
612
|
-
if(type->isSized())
|
|
613
|
-
return getDataLayout(LLVMModuleSet::getLLVMModuleSet()->getMainLLVMModule())->getTypeStoreSize(const_cast<Type*>(type));
|
|
614
|
-
else
|
|
615
|
-
return 0;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
u32_t LLVMUtil::getTypeSizeInBytes(const StructType *sty, u32_t field_idx)
|
|
619
|
-
{
|
|
620
|
-
|
|
621
|
-
const StructLayout *stTySL = getDataLayout(LLVMModuleSet::getLLVMModuleSet()->getMainLLVMModule())->getStructLayout( const_cast<StructType *>(sty) );
|
|
622
|
-
/// if this struct type does not have any element, i.e., opaque
|
|
623
|
-
if(sty->isOpaque())
|
|
624
|
-
return 0;
|
|
625
|
-
else
|
|
626
|
-
return stTySL->getElementOffset(field_idx);
|
|
627
|
-
}
|
|
628
|
-
|
|
629
427
|
/*!
|
|
630
428
|
* Get the meta data (line number and file name) info of a LLVM value
|
|
631
429
|
*/
|
|
@@ -776,31 +574,6 @@ void LLVMUtil::getNextInsts(const Instruction* curInst, std::vector<const Instru
|
|
|
776
574
|
}
|
|
777
575
|
|
|
778
576
|
|
|
779
|
-
/// Get the previous instructions following control flow
|
|
780
|
-
void LLVMUtil::getPrevInsts(const Instruction* curInst, std::vector<const Instruction*>& instList)
|
|
781
|
-
{
|
|
782
|
-
if (curInst != &(curInst->getParent()->front()))
|
|
783
|
-
{
|
|
784
|
-
const Instruction* prevInst = curInst->getPrevNode();
|
|
785
|
-
if (LLVMUtil::isIntrinsicInst(prevInst))
|
|
786
|
-
getPrevInsts(prevInst, instList);
|
|
787
|
-
else
|
|
788
|
-
instList.push_back(prevInst);
|
|
789
|
-
}
|
|
790
|
-
else
|
|
791
|
-
{
|
|
792
|
-
const BasicBlock *BB = curInst->getParent();
|
|
793
|
-
// Visit all successors of BB in the CFG
|
|
794
|
-
for (const_pred_iterator it = pred_begin(BB), ie = pred_end(BB); it != ie; ++it)
|
|
795
|
-
{
|
|
796
|
-
const Instruction* prevInst = &((*it)->back());
|
|
797
|
-
if (LLVMUtil::isIntrinsicInst(prevInst))
|
|
798
|
-
getPrevInsts(prevInst, instList);
|
|
799
|
-
else
|
|
800
|
-
instList.push_back(prevInst);
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
577
|
|
|
805
578
|
/// Check whether this value points-to a constant object
|
|
806
579
|
bool LLVMUtil::isConstantObjSym(const SVFValue* val)
|
|
@@ -842,6 +615,37 @@ std::string LLVMUtil::dumpValueAndDbgInfo(const Value *val)
|
|
|
842
615
|
return rawstr.str();
|
|
843
616
|
}
|
|
844
617
|
|
|
618
|
+
bool LLVMUtil::isHeapAllocExtCallViaRet(const Instruction* inst)
|
|
619
|
+
{
|
|
620
|
+
LLVMModuleSet* pSet = LLVMModuleSet::getLLVMModuleSet();
|
|
621
|
+
ExtAPI* extApi = ExtAPI::getExtAPI();
|
|
622
|
+
bool isPtrTy = inst->getType()->isPointerTy();
|
|
623
|
+
if (const CallBase* call = SVFUtil::dyn_cast<CallBase>(inst))
|
|
624
|
+
{
|
|
625
|
+
const Function* fun = call->getCalledFunction();
|
|
626
|
+
return fun && isPtrTy &&
|
|
627
|
+
(extApi->is_alloc(pSet->getSVFFunction(fun)) ||
|
|
628
|
+
extApi->is_realloc(pSet->getSVFFunction(fun)));
|
|
629
|
+
}
|
|
630
|
+
else
|
|
631
|
+
return false;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
bool LLVMUtil::isHeapAllocExtCallViaArg(const Instruction* inst)
|
|
635
|
+
{
|
|
636
|
+
if (const CallBase* call = SVFUtil::dyn_cast<CallBase>(inst))
|
|
637
|
+
{
|
|
638
|
+
const Function* fun = call->getCalledFunction();
|
|
639
|
+
return fun &&
|
|
640
|
+
ExtAPI::getExtAPI()->is_arg_alloc(
|
|
641
|
+
LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(fun));
|
|
642
|
+
}
|
|
643
|
+
else
|
|
644
|
+
{
|
|
645
|
+
return false;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
845
649
|
namespace SVF
|
|
846
650
|
{
|
|
847
651
|
|
|
@@ -115,8 +115,8 @@ const Type *ObjTypeInference::defaultType(const Value *val)
|
|
|
115
115
|
{
|
|
116
116
|
ABORT_IFNOT(val, "val cannot be null");
|
|
117
117
|
// heap has a default type of 8-bit integer type
|
|
118
|
-
if (SVFUtil::isa<Instruction>(val) &&
|
|
119
|
-
|
|
118
|
+
if (SVFUtil::isa<Instruction>(val) && LLVMUtil::isHeapAllocExtCallViaRet(
|
|
119
|
+
SVFUtil::cast<Instruction>(val)))
|
|
120
120
|
return int8Type();
|
|
121
121
|
// otherwise we return a pointer type in the default address space
|
|
122
122
|
return ptrType();
|
|
@@ -851,7 +851,6 @@ void SVFIRBuilder::visitCallSite(CallBase* cs)
|
|
|
851
851
|
|
|
852
852
|
if (const Function *callee = LLVMUtil::getCallee(cs))
|
|
853
853
|
{
|
|
854
|
-
callee = LLVMUtil::getDefFunForMultipleModule(callee);
|
|
855
854
|
const SVFFunction* svfcallee = LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(callee);
|
|
856
855
|
if (isExtCall(svfcallee))
|
|
857
856
|
{
|
|
@@ -594,7 +594,7 @@ const Type* SymbolTableBuilder::inferTypeOfHeapObjOrStaticObj(const Instruction
|
|
|
594
594
|
const Type* inferedType = nullptr;
|
|
595
595
|
assert(originalPType && "empty type?");
|
|
596
596
|
const SVFInstruction* svfinst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(inst);
|
|
597
|
-
if(
|
|
597
|
+
if(LLVMUtil::isHeapAllocExtCallViaRet(inst))
|
|
598
598
|
{
|
|
599
599
|
if(const Value* v = getFirstUseViaCastInst(inst))
|
|
600
600
|
{
|
|
@@ -605,7 +605,7 @@ const Type* SymbolTableBuilder::inferTypeOfHeapObjOrStaticObj(const Instruction
|
|
|
605
605
|
}
|
|
606
606
|
inferedType = inferObjType(startValue);
|
|
607
607
|
}
|
|
608
|
-
else if(
|
|
608
|
+
else if(LLVMUtil::isHeapAllocExtCallViaArg(inst))
|
|
609
609
|
{
|
|
610
610
|
const CallBase* cs = LLVMUtil::getLLVMCallSite(inst);
|
|
611
611
|
u32_t arg_pos = SVFUtil::getHeapAllocHoldingArgPosition(SVFUtil::cast<SVFCallInst>(svfinst)->getCalledFunction());
|
|
@@ -748,7 +748,7 @@ u32_t SymbolTableBuilder::analyzeHeapAllocByteSize(const Value* val)
|
|
|
748
748
|
calledFunction);
|
|
749
749
|
std::vector<const Value*> args;
|
|
750
750
|
// Heap alloc functions have annoation like "AllocSize:Arg1"
|
|
751
|
-
for (std::string annotation :
|
|
751
|
+
for (std::string annotation : ExtAPI::getExtAPI()->getExtFuncAnnotations(svfFunction))
|
|
752
752
|
{
|
|
753
753
|
if (annotation.find("AllocSize:") != std::string::npos)
|
|
754
754
|
{
|
|
@@ -894,9 +894,8 @@ void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val,
|
|
|
894
894
|
}
|
|
895
895
|
/// if val is heap alloc
|
|
896
896
|
else if (SVFUtil::isa<Instruction>(val) &&
|
|
897
|
-
isHeapAllocExtCall(
|
|
898
|
-
|
|
899
|
-
SVFUtil::cast<Instruction>(val))))
|
|
897
|
+
LLVMUtil::isHeapAllocExtCall(
|
|
898
|
+
SVFUtil::cast<Instruction>(val)))
|
|
900
899
|
{
|
|
901
900
|
elemNum = analyzeHeapObjType(typeinfo,val);
|
|
902
901
|
// analyze heap alloc like (malloc/calloc/...), the alloc functions have
|
package/svf-llvm/lib/extapi.c
CHANGED