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.
@@ -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) && SVFUtil::isHeapAllocExtCallViaRet(LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(SVFUtil::cast<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) && SVFUtil::isHeapAllocExtCallViaRet(
119
- LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(SVFUtil::cast<Instruction>(val))))
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(SVFUtil::isHeapAllocExtCallViaRet(svfinst))
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(SVFUtil::isHeapAllocExtCallViaArg(svfinst))
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 : svfFunction->getAnnotations())
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
- LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(
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
@@ -728,7 +728,6 @@ void* _ZNSt5arrayIPK1ALm2EE4backEv(void *arg)
728
728
  }
729
729
 
730
730
  __attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0")))
731
- __attribute__((annotate("OVERWRITE")))
732
731
  void *SyGetmem(unsigned long size)
733
732
  {
734
733
  return NULL;