Static Value-Flow Analysis
Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | Friends | List of all members
SVF::LLVMModuleSet Class Reference

#include <LLVMModule.h>

Public Types

typedef std::vector< const Function * > FunctionSetType
 
typedef Map< const Function *, const Function * > FunDeclToDefMapTy
 
typedef Map< const Function *, FunctionSetTypeFunDefToDeclsMapTy
 
typedef Map< const GlobalVariable *, GlobalVariable * > GlobalDefToRepMapTy
 
typedef Map< const Function *, SVFFunction * > LLVMFun2SVFFunMap
 
typedef Map< const BasicBlock *, SVFBasicBlock * > LLVMBB2SVFBBMap
 
typedef Map< const Instruction *, SVFInstruction * > LLVMInst2SVFInstMap
 
typedef Map< const Argument *, SVFArgument * > LLVMArgument2SVFArgumentMap
 
typedef Map< const Constant *, SVFConstant * > LLVMConst2SVFConstMap
 
typedef Map< const Value *, SVFOtherValue * > LLVMValue2SVFOtherValueMap
 
typedef Map< const SVFValue *, const Value * > SVFValue2LLVMValueMap
 
typedef Map< const SVFBaseNode *, const Value * > SVFBaseNode2LLVMValueMap
 
typedef Map< const Type *, SVFType * > LLVMType2SVFTypeMap
 
typedef Map< const Type *, StInfo * > Type2TypeInfoMap
 
typedef Map< std::string, std::vector< std::string > > Fun2AnnoMap
 
typedef Map< const Instruction *, CallICFGNode * > CSToCallNodeMapTy
 
typedef Map< const Instruction *, RetICFGNode * > CSToRetNodeMapTy
 
typedef Map< const Instruction *, IntraICFGNode * > InstToBlockNodeMapTy
 
typedef Map< const Function *, FunEntryICFGNode * > FunToFunEntryNodeMapTy
 
typedef Map< const Function *, FunExitICFGNode * > FunToFunExitNodeMapTy
 

Public Member Functions

 ~LLVMModuleSet ()
 
SVFModulegetSVFModule ()
 
u32_t getModuleNum () const
 
const std::vector< std::reference_wrapper< Module > > & getLLVMModules () const
 
ModulegetModule (u32_t idx) const
 
ModulegetModuleRef (u32_t idx) const
 
void dumpModulesToFile (const std::string &suffix)
 
void addFunctionMap (const Function *func, SVFFunction *svfFunc)
 
void addBasicBlockMap (const BasicBlock *bb, SVFBasicBlock *svfBB)
 
void addInstructionMap (const Instruction *inst, SVFInstruction *svfInst)
 
void addArgumentMap (const Argument *arg, SVFArgument *svfArg)
 
void addGlobalValueMap (const GlobalValue *glob, SVFGlobalValue *svfglob)
 
void addConstantDataMap (const ConstantData *cd, SVFConstantData *svfcd)
 
void addOtherConstantMap (const Constant *cons, SVFConstant *svfcons)
 
void addOtherValueMap (const Value *ov, SVFOtherValue *svfov)
 
SVFValuegetSVFValue (const Value *value)
 
const ValuegetLLVMValue (const SVFValue *value) const
 
const ValuegetLLVMValue (const SVFBaseNode *value) const
 
SVFFunctiongetSVFFunction (const Function *fun) const
 
SVFBasicBlockgetSVFBasicBlock (const BasicBlock *bb) const
 
SVFInstructiongetSVFInstruction (const Instruction *inst) const
 
SVFArgumentgetSVFArgument (const Argument *arg) const
 
SVFGlobalValuegetSVFGlobalValue (const GlobalValue *g) const
 
SVFConstantDatagetSVFConstantData (const ConstantData *cd)
 
SVFConstantgetOtherSVFConstant (const Constant *oc)
 
SVFOtherValuegetSVFOtherValue (const Value *ov)
 
const SVFFunctiongetSVFFunction (const std::string &name)
 Get the corresponding Function based on its name. More...
 
ICFGNodegetICFGNode (const Instruction *inst)
 Get a basic block ICFGNode. More...
 
bool hasICFGNode (const Instruction *inst)
 
CallICFGNodegetCallICFGNode (const Instruction *cs)
 get a call node More...
 
RetICFGNodegetRetICFGNode (const Instruction *cs)
 get a return node More...
 
IntraICFGNodegetIntraICFGNode (const Instruction *inst)
 get a intra node More...
 
FunEntryICFGNodegetFunEntryICFGNode (const Function *fun)
 Add a function entry node. More...
 
FunExitICFGNodegetFunExitICFGNode (const Function *fun)
 Add a function exit node. More...
 
bool hasGlobalRep (const GlobalVariable *val) const
 Global to rep. More...
 
GlobalVariablegetGlobalRep (const GlobalVariable *val) const
 
ModulegetMainLLVMModule () const
 
LLVMContextgetContext () const
 
bool empty () const
 
SVFTypegetSVFType (const Type *T)
 Get or create SVFType and typeinfo. More...
 
const TypegetLLVMType (const SVFType *T) const
 Get LLVM Type. More...
 
ObjTypeInferencegetTypeInference ()
 
ICFGgetICFG ()
 

Static Public Member Functions

static LLVMModuleSetgetLLVMModuleSet ()
 
static void releaseLLVMModuleSet ()
 
static SVFModulebuildSVFModule (Module &mod)
 
static SVFModulebuildSVFModule (const std::vector< std::string > &moduleNameVec)
 
static void preProcessBCs (std::vector< std::string > &moduleNameVec)
 

Private Member Functions

 LLVMModuleSet ()
 Constructor. More...
 
void build ()
 
SVFTypeaddSVFTypeInfo (const Type *t)
 Create SVFTypes. More...
 
StInfocollectTypeInfo (const Type *ty)
 Collect a type info. More...
 
StInfocollectStructInfo (const StructType *structTy, u32_t &numFields)
 Collect the struct info and set the number of fields after flattening. More...
 
StInfocollectArrayInfo (const ArrayType *T)
 Collect the array info. More...
 
StInfocollectSimpleTypeInfo (const Type *T)
 Collect simple type (non-aggregate) info. More...
 
std::vector< const Function * > getLLVMGlobalFunctions (const GlobalVariable *global)
 
void loadModules (const std::vector< std::string > &moduleNameVec)
 
void loadExtAPIModules ()
 
void addSVFMain ()
 
void createSVFDataStructure ()
 
void createSVFFunction (const Function *func)
 
void initSVFFunction ()
 
void initSVFBasicBlock (const Function *func)
 
void initDomTree (SVFFunction *func, const Function *f)
 
void setValueAttr (const Value *val, SVFValue *value)
 
void setValueAttr (const Value *val, SVFBaseNode *svfBaseNode)
 
void buildFunToFunMap ()
 
void buildGlobalDefToRepMap ()
 
void prePassSchedule ()
 Invoke llvm passes to modify module. More...
 
void buildSymbolTable () const
 
void collectExtFunAnnotations (const Module *mod)
 
CallICFGNodegetCallBlock (const Instruction *cs)
 Get/Add a call node. More...
 
RetICFGNodegetRetBlock (const Instruction *cs)
 Get/Add a return node. More...
 
IntraICFGNodegetIntraBlock (const Instruction *inst)
 
FunEntryICFGNodegetFunEntryBlock (const Function *fun)
 Get/Add a function entry node. More...
 
FunExitICFGNodegetFunExitBlock (const Function *fun)
 Get/Add a function exit node. More...
 

Private Attributes

SymbolTableInfosymInfo
 
SVFModulesvfModule
 Borrowed from singleton SVFModule::svfModule. More...
 
ICFGicfg
 
std::unique_ptr< LLVMContextowned_ctx
 
std::vector< std::unique_ptr< Module > > owned_modules
 
std::vector< std::reference_wrapper< Module > > modules
 
FunctionSetType ExtFuncsVec
 Record some "sse_" function declarations used in other ext function definition, e.g., svf_ext_foo(), and svf_ext_foo() used in app functions. More...
 
Fun2AnnoMap ExtFun2Annotations
 Record annotations of function in extapi.bc. More...
 
GlobalDefToRepMapTy GlobalDefToRepMap
 Global definition to a rep definition map. More...
 
LLVMFun2SVFFunMap LLVMFunc2SVFFunc
 Map an LLVM Function to an SVF Function. More...
 
LLVMBB2SVFBBMap LLVMBB2SVFBB
 
LLVMInst2SVFInstMap LLVMInst2SVFInst
 
LLVMArgument2SVFArgumentMap LLVMArgument2SVFArgument
 
LLVMConst2SVFConstMap LLVMConst2SVFConst
 
LLVMValue2SVFOtherValueMap LLVMValue2SVFOtherValue
 
SVFValue2LLVMValueMap SVFValue2LLVMValue
 
LLVMType2SVFTypeMap LLVMType2SVFType
 
Type2TypeInfoMap Type2TypeInfo
 
ObjTypeInferencetypeInference
 
SVFBaseNode2LLVMValueMap SVFBaseNode2LLVMValue
 
CSToCallNodeMapTy CSToCallNodeMap
 map a callsite to its CallICFGNode More...
 
CSToRetNodeMapTy CSToRetNodeMap
 map a callsite to its RetICFGNode More...
 
InstToBlockNodeMapTy InstToBlockNodeMap
 map a basic block to its ICFGNode More...
 
FunToFunEntryNodeMapTy FunToFunEntryNodeMap
 map a function to its FunExitICFGNode More...
 
FunToFunExitNodeMapTy FunToFunExitNodeMap
 map a function to its FunEntryICFGNode More...
 
PTACallGraphcallgraph
 

Static Private Attributes

static LLVMModuleSetllvmModuleSet = nullptr
 
static bool preProcessed = false
 

Friends

class SVFIRBuilder
 
class ICFGBuilder
 

Detailed Description

Definition at line 44 of file LLVMModule.h.

Member Typedef Documentation

◆ CSToCallNodeMapTy

Definition at line 68 of file LLVMModule.h.

◆ CSToRetNodeMapTy

Definition at line 69 of file LLVMModule.h.

◆ Fun2AnnoMap

Definition at line 66 of file LLVMModule.h.

◆ FunctionSetType

typedef std::vector<const Function*> SVF::LLVMModuleSet::FunctionSetType

Definition at line 51 of file LLVMModule.h.

◆ FunDeclToDefMapTy

Definition at line 52 of file LLVMModule.h.

◆ FunDefToDeclsMapTy

Definition at line 53 of file LLVMModule.h.

◆ FunToFunEntryNodeMapTy

Definition at line 71 of file LLVMModule.h.

◆ FunToFunExitNodeMapTy

Definition at line 72 of file LLVMModule.h.

◆ GlobalDefToRepMapTy

Definition at line 54 of file LLVMModule.h.

◆ InstToBlockNodeMapTy

Definition at line 70 of file LLVMModule.h.

◆ LLVMArgument2SVFArgumentMap

Definition at line 59 of file LLVMModule.h.

◆ LLVMBB2SVFBBMap

Definition at line 57 of file LLVMModule.h.

◆ LLVMConst2SVFConstMap

Definition at line 60 of file LLVMModule.h.

◆ LLVMFun2SVFFunMap

Definition at line 56 of file LLVMModule.h.

◆ LLVMInst2SVFInstMap

Definition at line 58 of file LLVMModule.h.

◆ LLVMType2SVFTypeMap

Definition at line 64 of file LLVMModule.h.

◆ LLVMValue2SVFOtherValueMap

Definition at line 61 of file LLVMModule.h.

◆ SVFBaseNode2LLVMValueMap

Definition at line 63 of file LLVMModule.h.

◆ SVFValue2LLVMValueMap

Definition at line 62 of file LLVMModule.h.

◆ Type2TypeInfoMap

Definition at line 65 of file LLVMModule.h.

Constructor & Destructor Documentation

◆ LLVMModuleSet()

LLVMModuleSet::LLVMModuleSet ( )
private

Constructor.

Definition at line 80 of file LLVMModule.cpp.

83 {
84 }
ObjTypeInference * typeInference
Definition: LLVMModule.h:100
SVFModule * svfModule
Borrowed from singleton SVFModule::svfModule.
Definition: LLVMModule.h:78
SymbolTableInfo * symInfo
Definition: LLVMModule.h:77
static SVFModule * getSVFModule()
Definition: SVFModule.cpp:60
static SymbolTableInfo * SymbolInfo()
Singleton design here to make sure we only have one instance during any analysis.

◆ ~LLVMModuleSet()

LLVMModuleSet::~LLVMModuleSet ( )

Definition at line 86 of file LLVMModule.cpp.

87 {
88  for (auto& item : LLVMInst2SVFInst)
89  {
90  delete item.second;
91  item.second = nullptr;
92  }
93  delete typeInference;
94  typeInference = nullptr;
95 }
cJSON * item
Definition: cJSON.h:222
LLVMInst2SVFInstMap LLVMInst2SVFInst
Definition: LLVMModule.h:93

Member Function Documentation

◆ addArgumentMap()

void SVF::LLVMModuleSet::addArgumentMap ( const Argument arg,
SVFArgument svfArg 
)
inline

Definition at line 183 of file LLVMModule.h.

184  {
185  LLVMArgument2SVFArgument[arg] = svfArg;
186  setValueAttr(arg,svfArg);
187  }
void setValueAttr(const Value *val, SVFValue *value)
LLVMArgument2SVFArgumentMap LLVMArgument2SVFArgument
Definition: LLVMModule.h:94

◆ addBasicBlockMap()

void SVF::LLVMModuleSet::addBasicBlockMap ( const BasicBlock bb,
SVFBasicBlock svfBB 
)
inline

Definition at line 173 of file LLVMModule.h.

174  {
175  LLVMBB2SVFBB[bb] = svfBB;
176  setValueAttr(bb,svfBB);
177  }
LLVMBB2SVFBBMap LLVMBB2SVFBB
Definition: LLVMModule.h:92

◆ addConstantDataMap()

void SVF::LLVMModuleSet::addConstantDataMap ( const ConstantData cd,
SVFConstantData svfcd 
)
inline

Definition at line 198 of file LLVMModule.h.

199  {
200  LLVMConst2SVFConst[cd] = svfcd;
201  setValueAttr(cd,svfcd);
202  }
LLVMConst2SVFConstMap LLVMConst2SVFConst
Definition: LLVMModule.h:95

◆ addFunctionMap()

void SVF::LLVMModuleSet::addFunctionMap ( const Function func,
SVFFunction svfFunc 
)
inline

Definition at line 168 of file LLVMModule.h.

169  {
170  LLVMFunc2SVFFunc[func] = svfFunc;
171  setValueAttr(func,svfFunc);
172  }
LLVMFun2SVFFunMap LLVMFunc2SVFFunc
Map an LLVM Function to an SVF Function.
Definition: LLVMModule.h:91

◆ addGlobalValueMap()

void SVF::LLVMModuleSet::addGlobalValueMap ( const GlobalValue glob,
SVFGlobalValue svfglob 
)
inline

Definition at line 188 of file LLVMModule.h.

189  {
190  if (auto glob_var = llvm::dyn_cast<llvm::GlobalVariable>(glob);
191  hasGlobalRep(glob_var))
192  {
193  glob = getGlobalRep(glob_var);
194  }
195  LLVMConst2SVFConst[glob] = svfglob;
196  setValueAttr(glob,svfglob);
197  }
bool hasGlobalRep(const GlobalVariable *val) const
Global to rep.
Definition: LLVMModule.h:321
GlobalVariable * getGlobalRep(const GlobalVariable *val) const
Definition: LLVMModule.h:327

◆ addInstructionMap()

void SVF::LLVMModuleSet::addInstructionMap ( const Instruction inst,
SVFInstruction svfInst 
)
inline

Definition at line 178 of file LLVMModule.h.

179  {
180  LLVMInst2SVFInst[inst] = svfInst;
181  setValueAttr(inst,svfInst);
182  }

◆ addOtherConstantMap()

void SVF::LLVMModuleSet::addOtherConstantMap ( const Constant cons,
SVFConstant svfcons 
)
inline

Definition at line 203 of file LLVMModule.h.

204  {
205  LLVMConst2SVFConst[cons] = svfcons;
206  setValueAttr(cons,svfcons);
207  }

◆ addOtherValueMap()

void SVF::LLVMModuleSet::addOtherValueMap ( const Value ov,
SVFOtherValue svfov 
)
inline

Definition at line 208 of file LLVMModule.h.

209  {
210  LLVMValue2SVFOtherValue[ov] = svfov;
211  setValueAttr(ov,svfov);
212  }
LLVMValue2SVFOtherValueMap LLVMValue2SVFOtherValue
Definition: LLVMModule.h:96

◆ addSVFMain()

void LLVMModuleSet::addSVFMain ( )
private

Definition at line 714 of file LLVMModule.cpp.

715 {
716  std::vector<const Function*> ctor_funcs;
717  std::vector<const Function*> dtor_funcs;
718  Function* orgMain = 0;
719  Module* mainMod = nullptr;
720 
721  for (Module &mod : modules)
722  {
723  // Collect ctor and dtor functions
724  for (const GlobalVariable& global : mod.globals())
725  {
726  if (global.getName().equals(SVF_GLOBAL_CTORS) && global.hasInitializer())
727  {
728  ctor_funcs = getLLVMGlobalFunctions(&global);
729  }
730  else if (global.getName().equals(SVF_GLOBAL_DTORS) && global.hasInitializer())
731  {
732  dtor_funcs = getLLVMGlobalFunctions(&global);
733  }
734  }
735 
736  // Find main function
737  for (auto &func : mod)
738  {
739  auto funName = func.getName();
740 
741  assert(!funName.equals(SVF_MAIN_FUNC_NAME) && SVF_MAIN_FUNC_NAME " already defined");
742 
743  if (funName.equals("main"))
744  {
745  orgMain = &func;
746  mainMod = &mod;
747  }
748  }
749  }
750 
751  // Only create svf.main when the original main function is found, and also
752  // there are global constructor or destructor functions.
753  if (orgMain && getModuleNum() > 0 &&
754  (ctor_funcs.size() > 0 || dtor_funcs.size() > 0))
755  {
756  assert(mainMod && "Module with main function not found.");
757  Module& M = *mainMod;
758  // char **
759  Type* ptr = PointerType::getUnqual(M.getContext());
760  Type* i32 = IntegerType::getInt32Ty(M.getContext());
761  // define void @svf.main(i32, i8**, i8**)
762 #if (LLVM_VERSION_MAJOR >= 9)
763  FunctionCallee svfmainFn = M.getOrInsertFunction(
765  Type::getVoidTy(M.getContext()),
766  i32,ptr,ptr
767  );
768  Function* svfmain = SVFUtil::dyn_cast<Function>(svfmainFn.getCallee());
769 #else
770  Function* svfmain = SVFUtil::dyn_cast<Function>(M.getOrInsertFunction(
772  Type::getVoidTy(M.getContext()),
773  i32,i8ptr2,i8ptr2
774  ));
775 #endif
776  svfmain->setCallingConv(llvm::CallingConv::C);
777  BasicBlock* block = BasicBlock::Create(M.getContext(), "entry", svfmain);
778  IRBuilder Builder(block);
779  // emit "call void @ctor()". ctor_funcs is sorted so the functions are
780  // emitted in the order of priority
781  for (auto& ctor : ctor_funcs)
782  {
783  auto target = M.getOrInsertFunction(
784  ctor->getName(),
785  Type::getVoidTy(M.getContext())
786  );
787  Builder.CreateCall(target);
788  }
789  // main() should be called after all ctor functions and before dtor
790  // functions.
791  Function::arg_iterator arg_it = svfmain->arg_begin();
792  Value* args[] = {arg_it, arg_it + 1, arg_it + 2};
793  size_t cnt = orgMain->arg_size();
794  assert(cnt <= 3 && "Too many arguments for main()");
795  Builder.CreateCall(orgMain, llvm::ArrayRef<Value*>(args, args + cnt));
796  // emit "call void @dtor()". dtor_funcs is sorted so the functions are
797  // emitted in the order of priority
798  for (auto& dtor : dtor_funcs)
799  {
800  auto target = M.getOrInsertFunction(dtor->getName(), Type::getVoidTy(M.getContext()));
801  Builder.CreateCall(target);
802  }
803  // return;
804  Builder.CreateRetVoid();
805  }
806 }
#define SVF_MAIN_FUNC_NAME
Definition: LLVMModule.cpp:73
#define SVF_GLOBAL_DTORS
Definition: LLVMModule.cpp:75
#define SVF_GLOBAL_CTORS
Definition: LLVMModule.cpp:74
std::vector< const Function * > getLLVMGlobalFunctions(const GlobalVariable *global)
Definition: LLVMModule.cpp:625
std::vector< std::reference_wrapper< Module > > modules
Definition: LLVMModule.h:82
u32_t getModuleNum() const
Definition: LLVMModule.h:144
llvm::GlobalVariable GlobalVariable
Definition: BasicTypes.h:130
llvm::Type Type
Definition: BasicTypes.h:83
llvm::BasicBlock BasicBlock
Definition: BasicTypes.h:86
llvm::Function Function
Definition: BasicTypes.h:85
llvm::Value Value
LLVM Basic classes.
Definition: BasicTypes.h:82
llvm::IRBuilder IRBuilder
Definition: BasicTypes.h:74
llvm::Module Module
Definition: BasicTypes.h:84

◆ addSVFTypeInfo()

SVFType * LLVMModuleSet::addSVFTypeInfo ( const Type t)
private

Create SVFTypes.

Definition at line 1483 of file LLVMModule.cpp.

1484 {
1485  assert(LLVMType2SVFType.find(T) == LLVMType2SVFType.end() &&
1486  "SVFType has been added before");
1487 
1488  // add SVFType's LLVM byte size iff T isSized(), otherwise byteSize is 1 (default value)
1489  u32_t byteSize = 1;
1490  if (T->isSized())
1491  {
1493  getMainLLVMModule()->getDataLayout();
1494  Type *mut_T = const_cast<Type *>(T);
1495  byteSize = DL.getTypeAllocSize(mut_T);
1496  }
1497 
1498  SVFType* svftype;
1499  if (SVFUtil::isa<PointerType>(T))
1500  {
1501  svftype = new SVFPointerType(byteSize);
1502  }
1503  else if (const IntegerType* intT = SVFUtil::dyn_cast<IntegerType>(T))
1504  {
1505  auto svfIntT = new SVFIntegerType(byteSize);
1506  unsigned signWidth = intT->getBitWidth();
1507  assert(signWidth < INT16_MAX && "Integer width too big");
1508  svfIntT->setSignAndWidth(intT->getSignBit() ? -signWidth : signWidth);
1509  svftype = svfIntT;
1510  }
1511  else if (const FunctionType* ft = SVFUtil::dyn_cast<FunctionType>(T))
1512  svftype = new SVFFunctionType(getSVFType(ft->getReturnType()));
1513  else if (const StructType* st = SVFUtil::dyn_cast<StructType>(T))
1514  {
1515  auto svfst = new SVFStructType(byteSize);
1516  if (st->hasName())
1517  svfst->setName(st->getName().str());
1518  svftype = svfst;
1519  }
1520  else if (const auto at = SVFUtil::dyn_cast<ArrayType>(T))
1521  {
1522  auto svfat = new SVFArrayType(byteSize);
1523  svfat->setNumOfElement(at->getNumElements());
1524  svfat->setTypeOfElement(getSVFType(at->getElementType()));
1525  svftype = svfat;
1526  }
1527  else
1528  {
1530  auto ot = new SVFOtherType(T->isSingleValueType(), byteSize);
1531  llvm::raw_string_ostream(buffer) << *T;
1532  ot->setRepr(std::move(buffer));
1533  svftype = ot;
1534  }
1535 
1536  symInfo->addTypeInfo(svftype);
1537  LLVMType2SVFType[T] = svftype;
1538 
1539  return svftype;
1540 }
unsigned u32_t
Definition: CommandLine.h:18
char * buffer
Definition: cJSON.h:163
const char *const string
Definition: cJSON.h:172
LLVMType2SVFTypeMap LLVMType2SVFType
Definition: LLVMModule.h:98
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
Module * getMainLLVMModule() const
Definition: LLVMModule.h:334
static LLVMModuleSet * getLLVMModuleSet()
Definition: LLVMModule.h:118
void addTypeInfo(const SVFType *ty)
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
Definition: SVFUtil.h:447
llvm::DataLayout DataLayout
Definition: BasicTypes.h:108
llvm::StructType StructType
LLVM types.
Definition: BasicTypes.h:94
llvm::IntegerType IntegerType
Definition: BasicTypes.h:97
llvm::FunctionType FunctionType
Definition: BasicTypes.h:98

◆ build()

void LLVMModuleSet::build ( )
private

Definition at line 159 of file LLVMModule.cpp.

160 {
161  if(preProcessed==false)
162  prePassSchedule();
163 
166 
167  if (Options::SVFMain())
168  addSVFMain();
169 
171  initSVFFunction();
172  ICFGBuilder icfgbuilder;
173  icfg = icfgbuilder.build();
174 
175  CallGraphBuilder callGraphBuilder;
176  callgraph = callGraphBuilder.buildSVFIRCallGraph(svfModule);
177 }
PTACallGraph * buildSVFIRCallGraph(SVFModule *svfModule)
Buidl SVFIR callgraoh.
static bool preProcessed
Definition: LLVMModule.h:76
void createSVFDataStructure()
Definition: LLVMModule.cpp:179
void prePassSchedule()
Invoke llvm passes to modify module.
Definition: LLVMModule.cpp:476
PTACallGraph * callgraph
Definition: LLVMModule.h:108
void buildGlobalDefToRepMap()
static const Option< bool > SVFMain
Definition: Options.h:183

◆ buildFunToFunMap()

void LLVMModuleSet::buildFunToFunMap ( )
private

Keep svf_main() function and all the functions called in svf_main()

app functions

App Func decl -> SVF extern Func def

Overwrite App Func def -> SVF extern Func def

Definition at line 876 of file LLVMModule.cpp.

877 {
878  Set<const Function*> appFunDecls, appFunDefs, extFuncs, clonedFuncs;
879  OrderedSet<string> appFuncDeclNames, appFuncDefNames, extFunDefNames, intersectNames;
880  Map<const Function*, const Function*> extFuncs2ClonedFuncs;
881  Module* appModule = nullptr;
882  Module* extModule = nullptr;
883 
884  for (Module& mod : modules)
885  {
886  // extapi.bc functions
887  if (mod.getName().str() == ExtAPI::getExtAPI()->getExtBcPath())
888  {
890  extModule = &mod;
891  for (const Function& fun : mod.functions())
892  {
893  // there is main declaration in ext bc, it should be mapped to
894  // main definition in app bc.
895  if (fun.getName().str() == "main")
896  {
897  appFunDecls.insert(&fun);
898  appFuncDeclNames.insert(fun.getName().str());
899  }
901  else if (fun.getName().str() == "svf__main")
902  {
903  ExtFuncsVec.push_back(&fun);
904  }
905  else
906  {
907  extFuncs.insert(&fun);
908  extFunDefNames.insert(fun.getName().str());
909  }
910  }
911  }
912  else
913  {
914  appModule = &mod;
916  for (const Function& fun : mod.functions())
917  {
918  if (fun.isDeclaration())
919  {
920  appFunDecls.insert(&fun);
921  appFuncDeclNames.insert(fun.getName().str());
922  }
923  else
924  {
925  appFunDefs.insert(&fun);
926  appFuncDefNames.insert(fun.getName().str());
927  }
928  }
929  }
930  }
931 
932  // Find the intersectNames between appFuncDefNames and externalFunDefNames
933  std::set_intersection(
934  appFuncDefNames.begin(), appFuncDefNames.end(), extFunDefNames.begin(), extFunDefNames.end(),
935  std::inserter(intersectNames, intersectNames.end()));
936 
937  auto cloneAndReplaceFunction = [&](const Function* extFunToClone, Function* appFunToReplace, Module* appModule, bool cloneBody) -> Function*
938  {
939  assert(!(appFunToReplace == NULL && appModule == NULL) && "appFunToReplace and appModule cannot both be NULL");
940 
941  if (appFunToReplace)
942  {
943  appModule = appFunToReplace->getParent();
944  }
945  // Create a new function with the same signature as extFunToClone
946  Function *clonedFunction = Function::Create(extFunToClone->getFunctionType(), Function::ExternalLinkage, extFunToClone->getName(), appModule);
947  // Map the arguments of the new function to the arguments of extFunToClone
948  llvm::ValueToValueMapTy valueMap;
949  Function::arg_iterator destArg = clonedFunction->arg_begin();
950  for (Function::const_arg_iterator srcArg = extFunToClone->arg_begin(); srcArg != extFunToClone->arg_end(); ++srcArg)
951  {
952  destArg->setName(srcArg->getName()); // Copy the name of the original argument
953  valueMap[&*srcArg] = &*destArg++; // Add a mapping from the old arg to the new arg
954  }
955  if (cloneBody)
956  {
957  // Clone the body of extFunToClone into clonedFunction
958  llvm::SmallVector<ReturnInst*, 8> ignoredReturns;
959  CloneFunctionInto(clonedFunction, extFunToClone, valueMap, llvm::CloneFunctionChangeType::LocalChangesOnly, ignoredReturns, "", nullptr);
960  }
961  if (appFunToReplace)
962  {
963  // Replace all uses of appFunToReplace with clonedFunction
964  appFunToReplace->replaceAllUsesWith(clonedFunction);
965  std::string oldFunctionName = appFunToReplace->getName().str();
966  // Delete the old function
967  appFunToReplace->eraseFromParent();
968  clonedFunction->setName(oldFunctionName);
969  }
970  return clonedFunction;
971  };
972 
974  for (const Function* appFunDecl : appFunDecls)
975  {
976  std::string appFunDeclName = LLVMUtil::restoreFuncName(appFunDecl->getName().str());
977  for (const Function* extFun : extFuncs)
978  {
979  if (extFun->getName().str().compare(appFunDeclName) == 0)
980  {
981  auto it = ExtFun2Annotations.find(extFun->getName().str());
982  // Without annotations, this function is normal function with useful function body
983  if (it == ExtFun2Annotations.end())
984  {
985  Function* clonedFunction = cloneAndReplaceFunction(const_cast<Function*>(extFun), const_cast<Function*>(appFunDecl), nullptr, true);
986  extFuncs2ClonedFuncs[extFun] = clonedFunction;
987  clonedFuncs.insert(clonedFunction);
988  }
989  else
990  {
991  ExtFuncsVec.push_back(appFunDecl);
992  }
993  break;
994  }
995  }
996  }
997 
1000  for (string sameFuncDef: intersectNames)
1001  {
1002  Function* appFuncDef = appModule->getFunction(sameFuncDef);
1003  Function* extFuncDef = extModule->getFunction(sameFuncDef);
1004  if (appFuncDef == nullptr || extFuncDef == nullptr)
1005  continue;
1006 
1007  FunctionType *appFuncDefType = appFuncDef->getFunctionType();
1008  FunctionType *extFuncDefType = extFuncDef->getFunctionType();
1009  if (appFuncDefType != extFuncDefType)
1010  continue;
1011 
1012  auto it = ExtFun2Annotations.find(sameFuncDef);
1013  if (it != ExtFun2Annotations.end())
1014  {
1015  std::vector<std::string> annotations = it->second;
1016  if (annotations.size() == 1 && annotations[0].find("OVERWRITE") != std::string::npos)
1017  {
1018  Function* clonedFunction = cloneAndReplaceFunction(const_cast<Function*>(extFuncDef), const_cast<Function*>(appFuncDef), nullptr, true);
1019  extFuncs2ClonedFuncs[extFuncDef] = clonedFunction;
1020  clonedFuncs.insert(clonedFunction);
1021  }
1022  else
1023  {
1024  if (annotations.size() >= 2)
1025  {
1026  for (const auto& annotation : annotations)
1027  {
1028  if(annotation.find("OVERWRITE") != std::string::npos)
1029  {
1030  assert(false && "overwrite and other annotations cannot co-exist");
1031  }
1032  }
1033  }
1034  }
1035  }
1036  }
1037 
1038  auto linkFunctions = [&](Function* caller, Function* callee)
1039  {
1040  for (inst_iterator I = inst_begin(caller), E = inst_end(caller); I != E; ++I)
1041  {
1042  Instruction *inst = &*I;
1043 
1044  if (CallInst *callInst = SVFUtil::dyn_cast<CallInst>(inst))
1045  {
1046  Function *calledFunc = callInst->getCalledFunction();
1047 
1048  if (calledFunc && calledFunc->getName() == callee->getName())
1049  {
1050  callInst->setCalledFunction(callee);
1051  }
1052  }
1053  }
1054  };
1055 
1056  std::function<void(const Function*, Function*)> cloneAndLinkFunction;
1057  cloneAndLinkFunction = [&](const Function* extFunToClone, Function* appClonedFun)
1058  {
1059  if (clonedFuncs.find(extFunToClone) != clonedFuncs.end())
1060  return;
1061 
1062  Module* appModule = appClonedFun->getParent();
1063  // Check if the function already exists in the parent module
1064  if (appModule->getFunction(extFunToClone->getName()))
1065  {
1066  // The function already exists, no need to clone, but need to link it with the caller
1067  Function* func = appModule->getFunction(extFunToClone->getName());
1068  linkFunctions(appClonedFun, func);
1069  return;
1070  }
1071  // Decide whether to clone the function body based on ExtFun2Annotations
1072  bool cloneBody = true;
1073  auto it = ExtFun2Annotations.find(extFunToClone->getName().str());
1074  if (it != ExtFun2Annotations.end())
1075  {
1076  std::vector<std::string> annotations = it->second;
1077  if (!(annotations.size() == 1 && annotations[0].find("OVERWRITE") != std::string::npos))
1078  {
1079  cloneBody = false;
1080  }
1081  }
1082 
1083  Function* clonedFunction = cloneAndReplaceFunction(extFunToClone, nullptr, appModule, cloneBody);
1084 
1085  clonedFuncs.insert(clonedFunction);
1086  // Add the cloned function to ExtFuncsVec for further processing
1087  ExtFuncsVec.push_back(clonedFunction);
1088 
1089  linkFunctions(appClonedFun, clonedFunction);
1090 
1091  std::vector<const Function*> calledFunctions = LLVMUtil::getCalledFunctions(extFunToClone);
1092 
1093  for (const auto& calledFunction : calledFunctions)
1094  {
1095  cloneAndLinkFunction(calledFunction, clonedFunction);
1096  }
1097  };
1098 
1099  // Recursive clone called functions
1100  for (const auto& pair : extFuncs2ClonedFuncs)
1101  {
1102  Function* extFun = const_cast<Function*>(pair.first);
1103  Function* clonedExtFun = const_cast<Function*>(pair.second);
1104  std::vector<const Function*> extCalledFuns = LLVMUtil::getCalledFunctions(extFun);
1105 
1106  for (const auto& extCalledFun : extCalledFuns)
1107  {
1108  cloneAndLinkFunction(extCalledFun, clonedExtFun);
1109  }
1110  }
1111 
1112  // Remove unused annotations in ExtFun2Annotations according to the functions in ExtFuncsVec
1113  Fun2AnnoMap newFun2AnnoMap;
1114  for (const Function* extFun : ExtFuncsVec)
1115  {
1116  std::string name = LLVMUtil::restoreFuncName(extFun->getName().str());
1117  auto it = ExtFun2Annotations.find(name);
1118  if (it != ExtFun2Annotations.end())
1119  {
1120  std::string newKey = name;
1121  if (name != extFun->getName().str())
1122  {
1123  newKey = extFun->getName().str();
1124  }
1125  newFun2AnnoMap.insert({newKey, it->second});
1126  }
1127  }
1128  ExtFun2Annotations.swap(newFun2AnnoMap);
1129 
1130  // Remove ExtAPI module from modules
1131  auto it = std::find_if(modules.begin(), modules.end(),
1132  [&extModule](const std::reference_wrapper<llvm::Module>& moduleRef)
1133  {
1134  return &moduleRef.get() == extModule;
1135  });
1136 
1137  if (it != modules.end())
1138  {
1139  size_t index = std::distance(modules.begin(), it);
1140  modules.erase(it);
1141  owned_modules.erase(owned_modules.begin() + index);
1142  }
1143 }
return NULL
Definition: cJSON.cpp:1173
const char *const name
Definition: cJSON.h:264
int index
Definition: cJSON.h:170
std::string getExtBcPath()
Definition: ExtAPI.cpp:119
static ExtAPI * getExtAPI()
Definition: ExtAPI.cpp:42
Fun2AnnoMap ExtFun2Annotations
Record annotations of function in extapi.bc.
Definition: LLVMModule.h:87
FunctionSetType ExtFuncsVec
Record some "sse_" function declarations used in other ext function definition, e....
Definition: LLVMModule.h:85
Map< std::string, std::vector< std::string > > Fun2AnnoMap
Definition: LLVMModule.h:66
std::vector< std::unique_ptr< Module > > owned_modules
Definition: LLVMModule.h:81
void collectExtFunAnnotations(const Module *mod)
Definition: LLVMModule.cpp:808
std::vector< const Function * > getCalledFunctions(const Function *F)
Get all called funcions in a parent function.
Definition: LLVMUtil.cpp:365
std::string restoreFuncName(std::string funcName)
Definition: LLVMUtil.cpp:384
llvm::inst_iterator inst_iterator
Definition: BasicTypes.h:249
std::set< Key, Compare, Allocator > OrderedSet
Definition: GeneralType.h:105
llvm::Instruction Instruction
Definition: BasicTypes.h:87
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition: GeneralType.h:101
llvm::CallInst CallInst
Definition: BasicTypes.h:147
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96

◆ buildGlobalDefToRepMap()

void LLVMModuleSet::buildGlobalDefToRepMap ( )
private

Definition at line 1145 of file LLVMModule.cpp.

1146 {
1147  typedef Map<string, Set<GlobalVariable*>> NameToGlobalsMapTy;
1148  NameToGlobalsMapTy nameToGlobalsMap;
1149  for (Module &mod : modules)
1150  {
1151  // Collect ctor and dtor functions
1152  for (GlobalVariable& global : mod.globals())
1153  {
1154  if (global.hasPrivateLinkage())
1155  continue;
1156  string name = global.getName().str();
1157  if (name.empty())
1158  continue;
1159  nameToGlobalsMap[std::move(name)].insert(&global);
1160  }
1161  }
1162 
1163  for (const auto& pair : nameToGlobalsMap)
1164  {
1165  const Set<GlobalVariable*> &globals = pair.second;
1166 
1167  const auto repIt =
1168  std::find_if(globals.begin(), globals.end(),
1169  [](GlobalVariable* g)
1170  {
1171  return g->hasInitializer();
1172  });
1173  GlobalVariable* rep =
1174  repIt != globals.end()
1175  ? *repIt
1176  // When there is no initializer, just pick the first one.
1177  : (assert(!globals.empty() && "Empty global set"),
1178  *globals.begin());
1179 
1180  for (const GlobalVariable* cur : globals)
1181  {
1182  GlobalDefToRepMap[cur] = rep;
1183  }
1184  }
1185 }
GlobalDefToRepMapTy GlobalDefToRepMap
Global definition to a rep definition map.
Definition: LLVMModule.h:89

◆ buildSVFModule() [1/2]

SVFModule * LLVMModuleSet::buildSVFModule ( const std::vector< std::string > &  moduleNameVec)
static

Definition at line 119 of file LLVMModule.cpp.

120 {
121  double startSVFModuleTime = SVFStat::getClk(true);
122 
124 
125  mset->loadModules(moduleNameVec); // Populates `modules`; can get context via `this->getContext()`
126  mset->loadExtAPIModules(); // Uses context from first module through `this->getContext()`
127 
128  if (!moduleNameVec.empty())
129  {
130  SVFModule::getSVFModule()->setModuleIdentifier(moduleNameVec.front());
131  }
132 
133  mset->build();
134 
135  double endSVFModuleTime = SVFStat::getClk(true);
137  (endSVFModuleTime - startSVFModuleTime) / TIMEINTERVAL;
138 
139  mset->buildSymbolTable();
140  // Don't releaseLLVMModuleSet() here, as IRBuilder might still need LLVMMoudleSet
141  return SVFModule::getSVFModule();
142 }
#define TIMEINTERVAL
Definition: SVFType.h:512
void buildSymbolTable() const
Definition: LLVMModule.cpp:144
void loadModules(const std::vector< std::string > &moduleNameVec)
Definition: LLVMModule.cpp:521
void setModuleIdentifier(const std::string &moduleIdentifier)
Definition: SVFModule.h:88
static double timeOfBuildingLLVMModule
Definition: SVFStat.h:93
static double getClk(bool mark=false)
Definition: SVFStat.cpp:47

◆ buildSVFModule() [2/2]

SVFModule * LLVMModuleSet::buildSVFModule ( Module mod)
static

Definition at line 102 of file LLVMModule.cpp.

103 {
105 
106  double startSVFModuleTime = SVFStat::getClk(true);
107  SVFModule::getSVFModule()->setModuleIdentifier(mod.getModuleIdentifier());
108  mset->modules.emplace_back(mod); // Populates `modules`; can get context via `this->getContext()`
109  mset->loadExtAPIModules(); // Uses context from module through `this->getContext()`
110  mset->build();
111  double endSVFModuleTime = SVFStat::getClk(true);
112  SVFStat::timeOfBuildingLLVMModule = (endSVFModuleTime - startSVFModuleTime)/TIMEINTERVAL;
113 
114  mset->buildSymbolTable();
115  // Don't releaseLLVMModuleSet() here, as IRBuilder might still need LLVMMoudleSet
116  return SVFModule::getSVFModule();
117 }

◆ buildSymbolTable()

void LLVMModuleSet::buildSymbolTable ( ) const
private

building symbol table

Definition at line 144 of file LLVMModule.cpp.

145 {
146  double startSymInfoTime = SVFStat::getClk(true);
148  {
150  DBOUT(DGENERAL, SVFUtil::outs() << SVFUtil::pasMsg("Building Symbol table ...\n"));
151  SymbolTableBuilder builder(symInfo);
152  builder.buildMemModel(svfModule);
153  }
154  double endSymInfoTime = SVFStat::getClk(true);
156  (endSymInfoTime - startSymInfoTime) / TIMEINTERVAL;
157 }
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition: SVFType.h:484
#define DGENERAL
Definition: SVFType.h:490
static bool pagReadFromTXT()
Definition: SVFModule.h:98
static double timeOfBuildingSymbolTable
Definition: SVFStat.h:94
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition: SVFUtil.cpp:99
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50

◆ collectArrayInfo()

StInfo * LLVMModuleSet::collectArrayInfo ( const ArrayType ty)
private

Collect the array info.

Fill in StInfo for an array type.

array without any element (this is not true in C/C++ arrays) we assume there is an empty dummy element

Array's flatten field infor is the same as its element's flatten infor.

Flatten arrays, map each array element index i to flattened index (i * nfE * totalElemNum)/outArrayElemNum nfE>1 if the array element is a struct with more than one field.

Definition at line 1545 of file LLVMModule.cpp.

1546 {
1547  u64_t totalElemNum = ty->getNumElements();
1548  const Type* elemTy = ty->getElementType();
1549  while (const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(elemTy))
1550  {
1551  totalElemNum *= aty->getNumElements();
1552  elemTy = aty->getElementType();
1553  }
1554 
1555  StInfo* stInfo = new StInfo(totalElemNum);
1556  const SVFType* elemSvfType = getSVFType(elemTy);
1557 
1559  if (totalElemNum == 0)
1560  {
1561  stInfo->addFldWithType(0, elemSvfType, 0);
1562  stInfo->setNumOfFieldsAndElems(1, 1);
1563  stInfo->getFlattenFieldTypes().push_back(elemSvfType);
1564  stInfo->getFlattenElementTypes().push_back(elemSvfType);
1565  return stInfo;
1566  }
1567 
1570  StInfo* elemStInfo = collectTypeInfo(elemTy);
1571  u32_t nfF = elemStInfo->getNumOfFlattenFields();
1572  u32_t nfE = elemStInfo->getNumOfFlattenElements();
1573  for (u32_t j = 0; j < nfF; j++)
1574  {
1575  const SVFType* fieldTy = elemStInfo->getFlattenFieldTypes()[j];
1576  stInfo->getFlattenFieldTypes().push_back(fieldTy);
1577  }
1578 
1581  u32_t outArrayElemNum = ty->getNumElements();
1582  for (u32_t i = 0; i < outArrayElemNum; ++i)
1583  {
1584  auto idx = (i * nfE * totalElemNum) / outArrayElemNum;
1585  stInfo->addFldWithType(0, elemSvfType, idx);
1586  }
1587 
1588  for (u32_t i = 0; i < totalElemNum; ++i)
1589  {
1590  for (u32_t j = 0; j < nfE; ++j)
1591  {
1592  const SVFType* et = elemStInfo->getFlattenElementTypes()[j];
1593  stInfo->getFlattenElementTypes().push_back(et);
1594  }
1595  }
1596 
1597  assert(stInfo->getFlattenElementTypes().size() == nfE * totalElemNum &&
1598  "typeForArray size incorrect!!!");
1599  stInfo->setNumOfFieldsAndElems(nfF, nfE * totalElemNum);
1600 
1601  return stInfo;
1602 }
StInfo * collectTypeInfo(const Type *ty)
Collect a type info.
std::vector< const SVFType * > & getFlattenElementTypes()
Definition: SVFType.h:102
void setNumOfFieldsAndElems(u32_t nf, u32_t ne)
Set number of fields and elements of an aggregate.
Definition: SVFType.h:132
u32_t getNumOfFlattenElements() const
Return number of elements after flattening (including array elements)
Definition: SVFType.h:139
void addFldWithType(u32_t fldIdx, const SVFType *type, u32_t elemIdx)
Add field index and element index and their corresponding type.
Definition: SVFValue.cpp:9
std::vector< const SVFType * > & getFlattenFieldTypes()
Definition: SVFType.h:106
u32_t getNumOfFlattenFields() const
Return the number of fields after flattening (ignoring array elements)
Definition: SVFType.h:145
llvm::ArrayType ArrayType
Definition: BasicTypes.h:95
unsigned long long u64_t
Definition: GeneralType.h:48

◆ collectExtFunAnnotations()

void LLVMModuleSet::collectExtFunAnnotations ( const Module mod)
private

Non-opaque pointer

Opaque pointer

Definition at line 808 of file LLVMModule.cpp.

809 {
810  GlobalVariable *glob = mod->getGlobalVariable("llvm.global.annotations");
811  if (glob == nullptr || !glob->hasInitializer())
812  return;
813 
814  ConstantArray *ca = SVFUtil::dyn_cast<ConstantArray>(glob->getInitializer());
815  if (ca == nullptr)
816  return;
817 
818  for (unsigned i = 0; i < ca->getNumOperands(); ++i)
819  {
820  ConstantStruct *structAn = SVFUtil::dyn_cast<ConstantStruct>(ca->getOperand(i));
821  if (structAn == nullptr || structAn->getNumOperands() == 0)
822  continue;
823 
824  // Check if the annotation is for a function
825  Function* fun = nullptr;
826  GlobalVariable *annotateStr = nullptr;
828  if (ConstantExpr *expr = SVFUtil::dyn_cast<ConstantExpr>(structAn->getOperand(0)))
829  {
830  if (expr->getOpcode() == Instruction::BitCast && SVFUtil::isa<Function>(expr->getOperand(0)))
831  fun = SVFUtil::cast<Function>(expr->getOperand(0));
832 
833  ConstantExpr *note = SVFUtil::cast<ConstantExpr>(structAn->getOperand(1));
834  if (note->getOpcode() != Instruction::GetElementPtr)
835  continue;
836 
837  annotateStr = SVFUtil::dyn_cast<GlobalVariable>(note->getOperand(0));
838  }
840  else
841  {
842  fun = SVFUtil::dyn_cast<Function>(structAn->getOperand(0));
843  annotateStr = SVFUtil::dyn_cast<GlobalVariable>(structAn->getOperand(1));
844  }
845 
846  if (!fun || annotateStr == nullptr || !annotateStr->hasInitializer())
847  continue;;
848 
849  ConstantDataSequential *data = SVFUtil::dyn_cast<ConstantDataSequential>(annotateStr->getInitializer());
850  if (data && data->isString())
851  {
852  std::string annotation = data->getAsString().str();
853  if (!annotation.empty())
854  ExtFun2Annotations[fun->getName().str()].push_back(annotation);
855  }
856  }
857 }
llvm::ConstantStruct ConstantStruct
Definition: BasicTypes.h:106
llvm::ConstantArray ConstantArray
Definition: BasicTypes.h:123
llvm::ConstantDataSequential ConstantDataSequential
Definition: BasicTypes.h:119
llvm::ConstantExpr ConstantExpr
Definition: BasicTypes.h:120

◆ collectSimpleTypeInfo()

StInfo * LLVMModuleSet::collectSimpleTypeInfo ( const Type ty)
private

Collect simple type (non-aggregate) info.

Collect simple type (non-aggregate) info

Only one field

Definition at line 1665 of file LLVMModule.cpp.

1666 {
1668  StInfo* stInfo = new StInfo(1);
1669  SVFType* svfType = getSVFType(ty);
1670  stInfo->addFldWithType(0, svfType, 0);
1671 
1672  stInfo->getFlattenFieldTypes().push_back(svfType);
1673  stInfo->getFlattenElementTypes().push_back(svfType);
1674  stInfo->setNumOfFieldsAndElems(1,1);
1675 
1676  return stInfo;
1677 }

◆ collectStructInfo()

StInfo * LLVMModuleSet::collectStructInfo ( const StructType structTy,
u32_t numFields 
)
private

Collect the struct info and set the number of fields after flattening.

Fill in struct_info for T. Given a Struct type, we recursively extend and record its fields and types.

The struct info should not be processed before

Definition at line 1608 of file LLVMModule.cpp.

1610 {
1612  StInfo* stInfo = new StInfo(1);
1613 
1614  // Number of fields after flattening the struct
1615  numFields = 0;
1616  // The offset when considering array stride info
1617  u32_t strideOffset = 0;
1618  for (const Type* elemTy : structTy->elements())
1619  {
1620  const SVFType* elemSvfTy = getSVFType(elemTy);
1621  // offset with int_32 (s32_t) is large enough and won't overflow
1622  stInfo->addFldWithType(numFields, elemSvfTy, strideOffset);
1623 
1624  if (SVFUtil::isa<StructType, ArrayType>(elemTy))
1625  {
1626  StInfo* subStInfo = collectTypeInfo(elemTy);
1627  u32_t nfF = subStInfo->getNumOfFlattenFields();
1628  u32_t nfE = subStInfo->getNumOfFlattenElements();
1629  // Copy ST's info, whose element 0 is the size of ST itself.
1630  for (u32_t j = 0; j < nfF; ++j)
1631  {
1632  const SVFType* elemTy = subStInfo->getFlattenFieldTypes()[j];
1633  stInfo->getFlattenFieldTypes().push_back(elemTy);
1634  }
1635  numFields += nfF;
1636  strideOffset += nfE;
1637  for (u32_t tpj = 0; tpj < nfE; ++tpj)
1638  {
1639  const SVFType* ty = subStInfo->getFlattenElementTypes()[tpj];
1640  stInfo->getFlattenElementTypes().push_back(ty);
1641  }
1642 
1643  }
1644  else
1645  {
1646  // Simple type
1647  numFields += 1;
1648  strideOffset += 1;
1649  stInfo->getFlattenFieldTypes().push_back(elemSvfTy);
1650  stInfo->getFlattenElementTypes().push_back(elemSvfTy);
1651  }
1652  }
1653 
1654  assert(stInfo->getFlattenElementTypes().size() == strideOffset &&
1655  "typeForStruct size incorrect!");
1656  stInfo->setNumOfFieldsAndElems(numFields,strideOffset);
1657 
1658  return stInfo;
1659 }

◆ collectTypeInfo()

StInfo * LLVMModuleSet::collectTypeInfo ( const Type ty)
private

Collect a type info.

Definition at line 1451 of file LLVMModule.cpp.

1452 {
1453  Type2TypeInfoMap::iterator tit = Type2TypeInfo.find(T);
1454  if (tit != Type2TypeInfo.end())
1455  {
1456  return tit->second;
1457  }
1458  // No such StInfo for T, create it now.
1459  StInfo* stInfo;
1460  if (const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(T))
1461  {
1462  stInfo = collectArrayInfo(aty);
1463  }
1464  else if (const StructType* sty = SVFUtil::dyn_cast<StructType>(T))
1465  {
1466  u32_t nf;
1467  stInfo = collectStructInfo(sty, nf);
1468  if (nf > symInfo->maxStSize)
1469  {
1470  symInfo->maxStruct = getSVFType(sty);
1471  symInfo->maxStSize = nf;
1472  }
1473  }
1474  else
1475  {
1476  stInfo = collectSimpleTypeInfo(T);
1477  }
1478  Type2TypeInfo.emplace(T, stInfo);
1479  symInfo->addStInfo(stInfo);
1480  return stInfo;
1481 }
StInfo * collectSimpleTypeInfo(const Type *T)
Collect simple type (non-aggregate) info.
StInfo * collectStructInfo(const StructType *structTy, u32_t &numFields)
Collect the struct info and set the number of fields after flattening.
StInfo * collectArrayInfo(const ArrayType *T)
Collect the array info.
Type2TypeInfoMap Type2TypeInfo
Definition: LLVMModule.h:99
const SVFType * maxStruct
The struct type with the most fields.
void addStInfo(StInfo *stInfo)
u32_t maxStSize
The number of fields in max_struct.

◆ createSVFDataStructure()

void LLVMModuleSet::createSVFDataStructure ( )
private

Function

then traverse candidate sets

GlobalVariable

GlobalAlias

GlobalIFunc

Definition at line 179 of file LLVMModule.cpp.

180 {
183  // Functions need to be retrieved in the order of insertion
184  // candidateDefs is the vector for all used defined functions
185  // candidateDecls is the vector for all used declared functions
186  std::vector<const Function*> candidateDefs, candidateDecls;
187 
188  for (Module& mod : modules)
189  {
191  for (Function& func : mod.functions())
192  {
193  if (func.isDeclaration())
194  {
195  candidateDecls.push_back(&func);
196  }
197  else
198  {
199  candidateDefs.push_back(&func);
200  }
201  }
202  }
203 
204  for (const Function* func: candidateDefs)
205  {
206  createSVFFunction(func);
207  }
208  for (const Function* func: candidateDecls)
209  {
210  createSVFFunction(func);
211  }
212 
213  // Store annotations of functions in extapi.bc
214  for (const auto& pair : ExtFun2Annotations)
215  {
216  const SVFFunction* svffun = getSVFFunction(pair.first);
217  ExtAPI::getExtAPI()->setExtFuncAnnotations(svffun, pair.second);
218  }
219 
221  for (const Module& mod : modules)
222  {
224  for (const GlobalVariable& global : mod.globals())
225  {
226  SVFGlobalValue* svfglobal = new SVFGlobalValue(
227  global.getName().str(), getSVFType(global.getType()));
228  svfModule->addGlobalSet(svfglobal);
229  addGlobalValueMap(&global, svfglobal);
230  }
231 
233  for (const GlobalAlias& alias : mod.aliases())
234  {
235  SVFGlobalValue* svfalias = new SVFGlobalValue(
236  alias.getName().str(), getSVFType(alias.getType()));
237  svfModule->addAliasSet(svfalias);
238  addGlobalValueMap(&alias, svfalias);
239  }
240 
242  for (const GlobalIFunc& ifunc : mod.ifuncs())
243  {
244  SVFGlobalValue* svfifunc = new SVFGlobalValue(
245  ifunc.getName().str(), getSVFType(ifunc.getType()));
246  svfModule->addAliasSet(svfifunc);
247  addGlobalValueMap(&ifunc, svfifunc);
248  }
249  }
250 }
void setExtFuncAnnotations(const SVFFunction *fun, const std::vector< std::string > &funcAnnotations)
Definition: ExtAPI.cpp:164
void createSVFFunction(const Function *func)
Definition: LLVMModule.cpp:252
SVFFunction * getSVFFunction(const Function *fun) const
Definition: LLVMModule.h:230
void addGlobalValueMap(const GlobalValue *glob, SVFGlobalValue *svfglob)
Definition: LLVMModule.h:188
ObjTypeInference * getTypeInference()
Definition: LLVMModule.cpp:97
void addGlobalSet(SVFGlobalValue *glob)
Definition: SVFModule.h:110
void addAliasSet(SVFGlobalValue *alias)
Definition: SVFModule.h:115
static SVFType * svfPtrTy
ptr type
Definition: SVFType.h:192
static SVFType * svfI8Ty
8-bit int type
Definition: SVFType.h:193
llvm::GlobalAlias GlobalAlias
Definition: BasicTypes.h:128
llvm::GlobalIFunc GlobalIFunc
Definition: BasicTypes.h:129

◆ createSVFFunction()

void LLVMModuleSet::createSVFFunction ( const Function func)
private

Definition at line 252 of file LLVMModule.cpp.

253 {
254  SVFFunction* svfFunc = new SVFFunction(
255  getSVFType(func->getType()),
256  SVFUtil::cast<SVFFunctionType>(
257  getSVFType(func->getFunctionType())),
258  func->isDeclaration(), LLVMUtil::isIntrinsicFun(func),
259  func->hasAddressTaken(), func->isVarArg(), new SVFLoopAndDomInfo);
260  svfModule->addFunctionSet(svfFunc);
261  addFunctionMap(func, svfFunc);
262 
263  for (const Argument& arg : func->args())
264  {
265  SVFArgument* svfarg = new SVFArgument(
266  getSVFType(arg.getType()), svfFunc, arg.getArgNo(),
268  // Setting up arg name
269  if (!arg.hasName())
270  svfarg->setName(std::to_string(arg.getArgNo()));
271 
272  svfFunc->addArgument(svfarg);
273  addArgumentMap(&arg, svfarg);
274  }
275 
276  for (const BasicBlock& bb : *func)
277  {
278  SVFBasicBlock* svfBB =
279  new SVFBasicBlock(getSVFType(bb.getType()), svfFunc);
280  svfFunc->addBasicBlock(svfBB);
281  addBasicBlockMap(&bb, svfBB);
282  for (const Instruction& inst : bb)
283  {
284  SVFInstruction* svfInst = nullptr;
285  if (const CallBase* call = SVFUtil::dyn_cast<CallBase>(&inst))
286  {
287  if (cppUtil::isVirtualCallSite(call))
288  svfInst = new SVFVirtualCallInst(
289  getSVFType(call->getType()), svfBB,
290  call->getFunctionType()->isVarArg(),
291  inst.isTerminator());
292  else
293  svfInst = new SVFCallInst(
294  getSVFType(call->getType()), svfBB,
295  call->getFunctionType()->isVarArg(),
296  inst.isTerminator());
297  }
298  else
299  {
300  svfInst =
301  new SVFInstruction(getSVFType(inst.getType()),
302  svfBB, inst.isTerminator(),
303  SVFUtil::isa<ReturnInst>(inst));
304  }
305 
306  addInstructionMap(&inst, svfInst);
307  }
308  }
309 }
void addInstructionMap(const Instruction *inst, SVFInstruction *svfInst)
Definition: LLVMModule.h:178
void addBasicBlockMap(const BasicBlock *bb, SVFBasicBlock *svfBB)
Definition: LLVMModule.h:173
void addArgumentMap(const Argument *arg, SVFArgument *svfArg)
Definition: LLVMModule.h:183
void addFunctionMap(const Function *func, SVFFunction *svfFunc)
Definition: LLVMModule.h:168
void addBasicBlock(const SVFBasicBlock *bb)
a 'single' basic block having no successors and containing return instruction in a function
Definition: SVFValue.h:326
void addArgument(SVFArgument *arg)
Definition: SVFValue.h:331
void addFunctionSet(SVFFunction *svfFunc)
Definition: SVFModule.h:106
void setName(const std::string &n)
Definition: SVFValue.h:247
bool isArgOfUncalledFunction(const Value *val)
Return true if the argument in a function does not have a caller.
Definition: LLVMUtil.h:151
bool isIntrinsicFun(const Function *func)
Definition: LLVMUtil.cpp:191
bool isVirtualCallSite(const CallBase *cs)
Definition: CppUtil.cpp:352
llvm::CallBase CallBase
Definition: BasicTypes.h:146
llvm::Argument Argument
Definition: BasicTypes.h:145

◆ dumpModulesToFile()

void LLVMModuleSet::dumpModulesToFile ( const std::string suffix)

Definition at line 1188 of file LLVMModule.cpp.

1189 {
1190  for (Module& mod : modules)
1191  {
1192  std::string moduleName = mod.getName().str();
1193  std::string OutputFilename;
1194  std::size_t pos = moduleName.rfind('.');
1195  if (pos != std::string::npos)
1196  OutputFilename = moduleName.substr(0, pos) + suffix;
1197  else
1198  OutputFilename = moduleName + suffix;
1199 
1200  std::error_code EC;
1201  raw_fd_ostream OS(OutputFilename.c_str(), EC, llvm::sys::fs::OF_None);
1202 
1203 #if (LLVM_VERSION_MAJOR >= 7)
1204  WriteBitcodeToFile(mod, OS);
1205 #else
1206  WriteBitcodeToFile(&mod, OS);
1207 #endif
1208 
1209  OS.flush();
1210  }
1211 }
llvm::raw_fd_ostream raw_fd_ostream
LLVM outputs.
Definition: BasicTypes.h:264

◆ empty()

bool SVF::LLVMModuleSet::empty ( ) const
inline

Definition at line 355 of file LLVMModule.h.

356  {
357  return getModuleNum() == 0;
358  }

◆ getCallBlock()

CallICFGNode* SVF::LLVMModuleSet::getCallBlock ( const Instruction cs)
inlineprivate

Get/Add a call node.

Definition at line 406 of file LLVMModule.h.

407  {
408  CSToCallNodeMapTy::const_iterator it = CSToCallNodeMap.find(cs);
409  if (it == CSToCallNodeMap.end())
410  return nullptr;
411  return it->second;
412  }
CSToCallNodeMapTy CSToCallNodeMap
map a callsite to its CallICFGNode
Definition: LLVMModule.h:103

◆ getCallICFGNode()

CallICFGNode * LLVMModuleSet::getCallICFGNode ( const Instruction cs)

get a call node

Definition at line 1426 of file LLVMModule.cpp.

1427 {
1428  assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
1429  assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
1430  CallICFGNode* node = getCallBlock(inst);
1431  assert (node!=nullptr && "no CallICFGNode for this instruction?");
1432  return node;
1433 }
CallICFGNode * getCallBlock(const Instruction *cs)
Get/Add a call node.
Definition: LLVMModule.h:406
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
Definition: LLVMUtil.h:45
bool isNonInstricCallSite(const Instruction *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
Definition: LLVMUtil.cpp:649

◆ getContext()

LLVMContext& SVF::LLVMModuleSet::getContext ( ) const
inline

Definition at line 349 of file LLVMModule.h.

350  {
351  assert(!empty() && "empty LLVM module!!");
352  return getMainLLVMModule()->getContext();
353  }
bool empty() const
Definition: LLVMModule.h:355

◆ getFunEntryBlock()

FunEntryICFGNode* SVF::LLVMModuleSet::getFunEntryBlock ( const Function fun)
inlineprivate

Get/Add a function entry node.

Definition at line 432 of file LLVMModule.h.

433  {
434  FunToFunEntryNodeMapTy::const_iterator it = FunToFunEntryNodeMap.find(fun);
435  if (it == FunToFunEntryNodeMap.end())
436  return nullptr;
437  return it->second;
438  }
FunToFunEntryNodeMapTy FunToFunEntryNodeMap
map a function to its FunExitICFGNode
Definition: LLVMModule.h:106

◆ getFunEntryICFGNode()

FunEntryICFGNode* SVF::LLVMModuleSet::getFunEntryICFGNode ( const Function fun)
inline

Add a function entry node.

Definition at line 305 of file LLVMModule.h.

306  {
307  FunEntryICFGNode* b = getFunEntryBlock(fun);
308  assert(b && "Function entry not created?");
309  return b;
310  }
const cJSON *const b
Definition: cJSON.h:255
FunEntryICFGNode * getFunEntryBlock(const Function *fun)
Get/Add a function entry node.
Definition: LLVMModule.h:432

◆ getFunExitBlock()

FunExitICFGNode* SVF::LLVMModuleSet::getFunExitBlock ( const Function fun)
inlineprivate

Get/Add a function exit node.

Definition at line 441 of file LLVMModule.h.

442  {
443  FunToFunExitNodeMapTy::const_iterator it = FunToFunExitNodeMap.find(fun);
444  if (it == FunToFunExitNodeMap.end())
445  return nullptr;
446  return it->second;
447  }
FunToFunExitNodeMapTy FunToFunExitNodeMap
map a function to its FunEntryICFGNode
Definition: LLVMModule.h:107

◆ getFunExitICFGNode()

FunExitICFGNode* SVF::LLVMModuleSet::getFunExitICFGNode ( const Function fun)
inline

Add a function exit node.

Definition at line 312 of file LLVMModule.h.

313  {
314  FunExitICFGNode* b = getFunExitBlock(fun);
315  assert(b && "Function exit not created?");
316  return b;
317  }
FunExitICFGNode * getFunExitBlock(const Function *fun)
Get/Add a function exit node.
Definition: LLVMModule.h:441

◆ getGlobalRep()

GlobalVariable* SVF::LLVMModuleSet::getGlobalRep ( const GlobalVariable val) const
inline

Definition at line 327 of file LLVMModule.h.

328  {
329  GlobalDefToRepMapTy::const_iterator it = GlobalDefToRepMap.find(val);
330  assert(it != GlobalDefToRepMap.end() && "has no rep?");
331  return it->second;
332  }

◆ getICFG()

ICFG* SVF::LLVMModuleSet::getICFG ( )
inline

Definition at line 367 of file LLVMModule.h.

368  {
369  return icfg;
370  }

◆ getICFGNode()

ICFGNode * LLVMModuleSet::getICFGNode ( const Instruction inst)

Get a basic block ICFGNode.

Definition at line 1399 of file LLVMModule.cpp.

1400 {
1401  ICFGNode* node;
1403  node = getCallICFGNode(inst);
1404  else if(LLVMUtil::isIntrinsicInst(inst))
1405  node = getIntraICFGNode(inst);
1406  else
1407  node = getIntraICFGNode(inst);
1408 
1409  assert (node!=nullptr && "no ICFGNode for this instruction?");
1410  return node;
1411 }
CallICFGNode * getCallICFGNode(const Instruction *cs)
get a call node
IntraICFGNode * getIntraICFGNode(const Instruction *inst)
get a intra node
bool isIntrinsicInst(const Instruction *inst)
Return true if it is an intrinsic instruction.
Definition: LLVMUtil.cpp:204

◆ getIntraBlock()

IntraICFGNode* SVF::LLVMModuleSet::getIntraBlock ( const Instruction inst)
inlineprivate

Definition at line 423 of file LLVMModule.h.

424  {
425  InstToBlockNodeMapTy::const_iterator it = InstToBlockNodeMap.find(inst);
426  if (it == InstToBlockNodeMap.end())
427  return nullptr;
428  return it->second;
429  }
InstToBlockNodeMapTy InstToBlockNodeMap
map a basic block to its ICFGNode
Definition: LLVMModule.h:105

◆ getIntraICFGNode()

IntraICFGNode * LLVMModuleSet::getIntraICFGNode ( const Instruction inst)

get a intra node

Definition at line 1444 of file LLVMModule.cpp.

1445 {
1446  IntraICFGNode* node = getIntraBlock(inst);
1447  assert (node!=nullptr && "no IntraICFGNode for this instruction?");
1448  return node;
1449 }
IntraICFGNode * getIntraBlock(const Instruction *inst)
Definition: LLVMModule.h:423

◆ getLLVMGlobalFunctions()

std::vector< const Function * > LLVMModuleSet::getLLVMGlobalFunctions ( const GlobalVariable global)
private

Definition at line 625 of file LLVMModule.cpp.

626 {
627  // This function is used to extract constructor and destructor functions
628  // sorted by their priority from @llvm.global_ctors or @llvm.global_dtors.
629  // For example, given following @llvm.global_ctors, the returning sorted
630  // function list should be [ctor3, ctor1, ctor2].
631  // ------------------------------------------------------------------
632  // ; Each struct in the array is {priority, function, associated data}
633  //
634  // @llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }]
635  // [{ i32, void ()*, i8* } { i32 1234, void ()* @ctor1.cpp, i8* null },
636  // { i32, void ()*, i8* } { i32 2345, void ()* @ctor2.cpp, i8* null },
637  // { i32, void ()*, i8* } { i32 345, void ()* @ctor3.cpp, i8* null }]
638  // ------------------------------------------------------------------
639  // TODO: According to LLVM language reference, if the third field is
640  // non-null, and points to a global variable or function, the initializer
641  // function will only run if the associated data from the current module is
642  // not discarded. However the associated data is currently ignored.
643 
644 
645  // This class is used for the priority queue that sorts the functions by
646  // their priority. Each object of this class stands for an item in the
647  // function array.
648  class LLVMGlobalFunction
649  {
650  public:
651  u32_t priority;
652  const Function* func;
653  LLVMGlobalFunction() {};
654  LLVMGlobalFunction(u32_t _priority, const Function* _func)
655  : priority(_priority), func(_func) {};
656  bool operator>(const LLVMGlobalFunction &other) const
657  {
658  if (priority != other.priority)
659  {
660  return priority > other.priority;
661  }
662  else
663  {
664  return func > other.func;
665  }
666  }
667  };
668 
669  std::priority_queue<LLVMGlobalFunction, std::vector<LLVMGlobalFunction>,
670  greater<LLVMGlobalFunction>>
671  queue;
672  std::vector<const Function* > result;
673 
674  // The @llvm.global_ctors/dtors global variable is an array of struct. Each
675  // struct has three fields: {i32 priority, void ()* @ctor/dtor, i8* @data}.
676  // First get the array here.
677  if(const ConstantArray *globalFuncArray =
678  SVFUtil::dyn_cast<ConstantArray>(global->getInitializer()))
679  {
680  // Get each struct in the array.
681  for (unsigned int i = 0; i < globalFuncArray->getNumOperands(); ++i)
682  {
683  if (
684  const ConstantStruct *globalFuncItem =
685  SVFUtil::dyn_cast<ConstantStruct>(
686  globalFuncArray->getOperand(i)))
687  {
688 
689  // Extract priority and function from the struct
690  const ConstantInt* priority = SVFUtil::dyn_cast<ConstantInt>(
691  globalFuncItem->getOperand(0));
692  const Function* func = SVFUtil::dyn_cast<Function>(
693  globalFuncItem->getOperand(1));
694 
695  if (priority && func)
696  {
697  queue.push(LLVMGlobalFunction(priority
698  ->getZExtValue(),
699  func));
700  }
701  }
702  }
703  }
704 
705  // Generate a sorted vector of functions from the priority queue.
706  while (!queue.empty())
707  {
708  result.push_back(queue.top().func);
709  queue.pop();
710  }
711  return result;
712 }
llvm::ConstantInt ConstantInt
Definition: BasicTypes.h:125
IntervalValue operator>(const IntervalValue &lhs, const IntervalValue &rhs)

◆ getLLVMModules()

const std::vector<std::reference_wrapper<Module> >& SVF::LLVMModuleSet::getLLVMModules ( ) const
inline

Definition at line 149 of file LLVMModule.h.

150  {
151  return modules;
152  }

◆ getLLVMModuleSet()

static LLVMModuleSet* SVF::LLVMModuleSet::getLLVMModuleSet ( )
inlinestatic

Definition at line 118 of file LLVMModule.h.

119  {
120  if (!llvmModuleSet)
122  return llvmModuleSet;
123  }
LLVMModuleSet()
Constructor.
Definition: LLVMModule.cpp:80
static LLVMModuleSet * llvmModuleSet
Definition: LLVMModule.h:75

◆ getLLVMType()

const Type * LLVMModuleSet::getLLVMType ( const SVFType T) const

Get LLVM Type.

Definition at line 1370 of file LLVMModule.cpp.

1371 {
1372  for(LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.begin(), eit = LLVMType2SVFType.end(); it!=eit; ++it)
1373  {
1374  if (it->second == T)
1375  return it->first;
1376  }
1377  assert(false && "can't find the corresponding LLVM Type");
1378  abort();
1379 }

◆ getLLVMValue() [1/2]

const Value* SVF::LLVMModuleSet::getLLVMValue ( const SVFBaseNode value) const
inline

Definition at line 223 of file LLVMModule.h.

224  {
225  SVFBaseNode2LLVMValueMap ::const_iterator it = SVFBaseNode2LLVMValue.find(value);
226  assert(it!=SVFBaseNode2LLVMValue.end() && "can't find corresponding llvm value!");
227  return it->second;
228  }
SVFBaseNode2LLVMValueMap SVFBaseNode2LLVMValue
Definition: LLVMModule.h:102

◆ getLLVMValue() [2/2]

const Value* SVF::LLVMModuleSet::getLLVMValue ( const SVFValue value) const
inline

Definition at line 216 of file LLVMModule.h.

217  {
218  SVFValue2LLVMValueMap::const_iterator it = SVFValue2LLVMValue.find(value);
219  assert(it!=SVFValue2LLVMValue.end() && "can't find corresponding llvm value!");
220  return it->second;
221  }
SVFValue2LLVMValueMap SVFValue2LLVMValue
Definition: LLVMModule.h:97

◆ getMainLLVMModule()

Module* SVF::LLVMModuleSet::getMainLLVMModule ( ) const
inline

Definition at line 334 of file LLVMModule.h.

335  {
336  assert(!empty() && "empty LLVM module!!");
337  for (size_t i = 0; i < getModuleNum(); ++i)
338  {
339  Module& module = getModuleRef(i);
340  if (module.getName().str() != ExtAPI::getExtAPI()->getExtBcPath())
341  {
342  return &module;
343  }
344  }
345  assert(false && "no main module found!");
346  return nullptr;
347  }
Module & getModuleRef(u32_t idx) const
Definition: LLVMModule.h:159

◆ getModule()

Module* SVF::LLVMModuleSet::getModule ( u32_t  idx) const
inline

Definition at line 154 of file LLVMModule.h.

155  {
156  return &getModuleRef(idx);
157  }

◆ getModuleNum()

u32_t SVF::LLVMModuleSet::getModuleNum ( ) const
inline

Definition at line 144 of file LLVMModule.h.

145  {
146  return modules.size();
147  }

◆ getModuleRef()

Module& SVF::LLVMModuleSet::getModuleRef ( u32_t  idx) const
inline

Definition at line 159 of file LLVMModule.h.

160  {
161  assert(idx < getModuleNum() && "Out of range.");
162  return modules[idx];
163  }

◆ getOtherSVFConstant()

SVFConstant * LLVMModuleSet::getOtherSVFConstant ( const Constant oc)

Definition at line 1312 of file LLVMModule.cpp.

1313 {
1314  LLVMConst2SVFConstMap::const_iterator it = LLVMConst2SVFConst.find(oc);
1315  if(it!=LLVMConst2SVFConst.end())
1316  {
1317  return it->second;
1318  }
1319  else
1320  {
1321  SVFConstant* svfoc = new SVFConstant(getSVFType(oc->getType()));
1322  svfModule->addConstant(svfoc);
1323  addOtherConstantMap(oc,svfoc);
1324  return svfoc;
1325  }
1326 }
void addOtherConstantMap(const Constant *cons, SVFConstant *svfcons)
Definition: LLVMModule.h:203
void addConstant(SVFConstant *cd)
Definition: SVFModule.h:120

◆ getRetBlock()

RetICFGNode* SVF::LLVMModuleSet::getRetBlock ( const Instruction cs)
inlineprivate

Get/Add a return node.

Definition at line 415 of file LLVMModule.h.

416  {
417  CSToRetNodeMapTy::const_iterator it = CSToRetNodeMap.find(cs);
418  if (it == CSToRetNodeMap.end())
419  return nullptr;
420  return it->second;
421  }
CSToRetNodeMapTy CSToRetNodeMap
map a callsite to its RetICFGNode
Definition: LLVMModule.h:104

◆ getRetICFGNode()

RetICFGNode * LLVMModuleSet::getRetICFGNode ( const Instruction cs)

get a return node

Definition at line 1435 of file LLVMModule.cpp.

1436 {
1437  assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
1438  assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
1439  RetICFGNode* node = getRetBlock(inst);
1440  assert (node!=nullptr && "no RetICFGNode for this instruction?");
1441  return node;
1442 }
RetICFGNode * getRetBlock(const Instruction *cs)
Get/Add a return node.
Definition: LLVMModule.h:415

◆ getSVFArgument()

SVFArgument* SVF::LLVMModuleSet::getSVFArgument ( const Argument arg) const
inline

Definition at line 251 of file LLVMModule.h.

252  {
253  LLVMArgument2SVFArgumentMap::const_iterator it = LLVMArgument2SVFArgument.find(arg);
254  assert(it!=LLVMArgument2SVFArgument.end() && "SVF Argument not found!");
255  return it->second;
256  }

◆ getSVFBasicBlock()

SVFBasicBlock* SVF::LLVMModuleSet::getSVFBasicBlock ( const BasicBlock bb) const
inline

Definition at line 237 of file LLVMModule.h.

238  {
239  LLVMBB2SVFBBMap::const_iterator it = LLVMBB2SVFBB.find(bb);
240  assert(it!=LLVMBB2SVFBB.end() && "SVF BasicBlock not found!");
241  return it->second;
242  }

◆ getSVFConstantData()

SVFConstantData * LLVMModuleSet::getSVFConstantData ( const ConstantData cd)

bitwidth == 1 : cint has value from getZExtValue() because bool true will be translated to -1 using sign extension (i.e., getSExtValue). bitwidth <=64 1 : cint has value from getSExtValue() bitwidth >64 1 : cint has value 0 because it represents an invalid int

Definition at line 1247 of file LLVMModule.cpp.

1248 {
1249  LLVMConst2SVFConstMap::const_iterator it = LLVMConst2SVFConst.find(cd);
1250  if(it!=LLVMConst2SVFConst.end())
1251  {
1252  assert(SVFUtil::isa<SVFConstantData>(it->second) && "not a SVFConstantData type!");
1253  return SVFUtil::cast<SVFConstantData>(it->second);
1254  }
1255  else
1256  {
1257  SVFConstantData* svfcd = nullptr;
1258  if(const ConstantInt* cint = SVFUtil::dyn_cast<ConstantInt>(cd))
1259  {
1263  if(cint->getBitWidth() == 1)
1264  svfcd = new SVFConstantInt(getSVFType(cint->getType()), cint->getZExtValue(), cint->getZExtValue());
1265  else if(cint->getBitWidth() <= 64 && cint->getBitWidth() > 1)
1266  svfcd = new SVFConstantInt(getSVFType(cint->getType()), cint->getZExtValue(), cint->getSExtValue());
1267  else
1268  svfcd = new SVFConstantInt(getSVFType(cint->getType()), 0, 0);
1269  }
1270  else if(const ConstantFP* cfp = SVFUtil::dyn_cast<ConstantFP>(cd))
1271  {
1272  double dval = 0;
1273  // TODO: Why only double is considered? What about float?
1274  if (cfp->isNormalFP())
1275  {
1276  const llvm::fltSemantics& semantics = cfp->getValueAPF().getSemantics();
1277  if (&semantics == &llvm::APFloat::IEEEhalf() ||
1278  &semantics == &llvm::APFloat::IEEEsingle() ||
1279  &semantics == &llvm::APFloat::IEEEdouble() ||
1280  &semantics == &llvm::APFloat::IEEEquad() ||
1281  &semantics == &llvm::APFloat::x87DoubleExtended())
1282  {
1283  dval = cfp->getValueAPF().convertToDouble();
1284  }
1285  else
1286  {
1287  assert (false && "Unsupported floating point type");
1288  abort();
1289  }
1290  }
1291  else
1292  {
1293  // other cfp type, like isZero(), isInfinity(), isNegative(), etc.
1294  // do nothing
1295  }
1296  svfcd = new SVFConstantFP(getSVFType(cd->getType()), dval);
1297  }
1298  else if(SVFUtil::isa<ConstantPointerNull>(cd))
1299  svfcd = new SVFConstantNullPtr(getSVFType(cd->getType()));
1300  else if (SVFUtil::isa<UndefValue>(cd))
1301  svfcd = new SVFBlackHoleValue(getSVFType(cd->getType()));
1302  else
1303  svfcd = new SVFConstantData(getSVFType(cd->getType()));
1304 
1305 
1306  svfModule->addConstant(svfcd);
1307  addConstantDataMap(cd,svfcd);
1308  return svfcd;
1309  }
1310 }
void addConstantDataMap(const ConstantData *cd, SVFConstantData *svfcd)
Definition: LLVMModule.h:198
llvm::ConstantFP ConstantFP
Definition: BasicTypes.h:126

◆ getSVFFunction() [1/2]

SVFFunction* SVF::LLVMModuleSet::getSVFFunction ( const Function fun) const
inline

Definition at line 230 of file LLVMModule.h.

231  {
232  LLVMFun2SVFFunMap::const_iterator it = LLVMFunc2SVFFunc.find(fun);
233  assert(it!=LLVMFunc2SVFFunc.end() && "SVF Function not found!");
234  return it->second;
235  }

◆ getSVFFunction() [2/2]

const SVFFunction* SVF::LLVMModuleSet::getSVFFunction ( const std::string name)
inline

Get the corresponding Function based on its name.

Definition at line 277 of file LLVMModule.h.

278  {
279  Function* fun = nullptr;
280 
281  for (u32_t i = 0; i < llvmModuleSet->getModuleNum(); ++i)
282  {
283  Module* mod = llvmModuleSet->getModule(i);
284  fun = mod->getFunction(name);
285  if (fun)
286  {
287  return llvmModuleSet->getSVFFunction(fun);
288  }
289  }
290  return nullptr;
291  }
Module * getModule(u32_t idx) const
Definition: LLVMModule.h:154

◆ getSVFGlobalValue()

SVFGlobalValue* SVF::LLVMModuleSet::getSVFGlobalValue ( const GlobalValue g) const
inline

Definition at line 258 of file LLVMModule.h.

259  {
260  if (auto glob_var = llvm::dyn_cast<llvm::GlobalVariable>(g);
261  hasGlobalRep(glob_var))
262  {
263  g = getGlobalRep(glob_var);
264  }
265  LLVMConst2SVFConstMap::const_iterator it = LLVMConst2SVFConst.find(g);
266  assert(it!=LLVMConst2SVFConst.end() && "SVF Global not found!");
267  assert(SVFUtil::isa<SVFGlobalValue>(it->second) && "not a SVFGlobal type!");
268  return SVFUtil::cast<SVFGlobalValue>(it->second);
269  }

◆ getSVFInstruction()

SVFInstruction* SVF::LLVMModuleSet::getSVFInstruction ( const Instruction inst) const
inline

Definition at line 244 of file LLVMModule.h.

245  {
246  LLVMInst2SVFInstMap::const_iterator it = LLVMInst2SVFInst.find(inst);
247  assert(it!=LLVMInst2SVFInst.end() && "SVF Instruction not found!");
248  return it->second;
249  }

◆ getSVFModule()

SVFModule* SVF::LLVMModuleSet::getSVFModule ( )
inline

Definition at line 137 of file LLVMModule.h.

138  {
139  return svfModule;
140  }

◆ getSVFOtherValue()

SVFOtherValue * LLVMModuleSet::getSVFOtherValue ( const Value ov)

Definition at line 1328 of file LLVMModule.cpp.

1329 {
1330  LLVMValue2SVFOtherValueMap::const_iterator it = LLVMValue2SVFOtherValue.find(ov);
1331  if(it!=LLVMValue2SVFOtherValue.end())
1332  {
1333  return it->second;
1334  }
1335  else
1336  {
1337  SVFOtherValue* svfov =
1338  SVFUtil::isa<MetadataAsValue>(ov)
1339  ? new SVFMetadataAsValue(getSVFType(ov->getType()))
1340  : new SVFOtherValue(getSVFType(ov->getType()));
1341  svfModule->addOtherValue(svfov);
1342  addOtherValueMap(ov,svfov);
1343  return svfov;
1344  }
1345 }
void addOtherValueMap(const Value *ov, SVFOtherValue *svfov)
Definition: LLVMModule.h:208
void addOtherValue(SVFOtherValue *ov)
Definition: SVFModule.h:124

◆ getSVFType()

SVFType * LLVMModuleSet::getSVFType ( const Type T)

Get or create SVFType and typeinfo.

Get or create SVFType and typeinfo

Definition at line 1384 of file LLVMModule.cpp.

1385 {
1386  assert(T && "SVFType should not be null");
1387  LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.find(T);
1388  if (it != LLVMType2SVFType.end())
1389  return it->second;
1390 
1391  SVFType* svfType = addSVFTypeInfo(T);
1392  StInfo* stinfo = collectTypeInfo(T);
1393  svfType->setTypeInfo(stinfo);
1394  return svfType;
1395 }
SVFType * addSVFTypeInfo(const Type *t)
Create SVFTypes.
void setTypeInfo(StInfo *ti)
Definition: SVFType.h:225

◆ getSVFValue()

SVFValue * LLVMModuleSet::getSVFValue ( const Value value)

Definition at line 1347 of file LLVMModule.cpp.

1348 {
1349  if (const Function* fun = SVFUtil::dyn_cast<Function>(value))
1350  return getSVFFunction(fun);
1351  else if (const BasicBlock* bb = SVFUtil::dyn_cast<BasicBlock>(value))
1352  return getSVFBasicBlock(bb);
1353  else if(const Instruction* inst = SVFUtil::dyn_cast<Instruction>(value))
1354  return getSVFInstruction(inst);
1355  else if (const Argument* arg = SVFUtil::dyn_cast<Argument>(value))
1356  return getSVFArgument(arg);
1357  else if (const Constant* cons = SVFUtil::dyn_cast<Constant>(value))
1358  {
1359  if (const ConstantData* cd = SVFUtil::dyn_cast<ConstantData>(cons))
1360  return getSVFConstantData(cd);
1361  else if (const GlobalValue* glob = SVFUtil::dyn_cast<GlobalValue>(cons))
1362  return getSVFGlobalValue(glob);
1363  else
1364  return getOtherSVFConstant(cons);
1365  }
1366  else
1367  return getSVFOtherValue(value);
1368 }
SVFOtherValue * getSVFOtherValue(const Value *ov)
SVFConstantData * getSVFConstantData(const ConstantData *cd)
SVFGlobalValue * getSVFGlobalValue(const GlobalValue *g) const
Definition: LLVMModule.h:258
SVFConstant * getOtherSVFConstant(const Constant *oc)
SVFBasicBlock * getSVFBasicBlock(const BasicBlock *bb) const
Definition: LLVMModule.h:237
SVFArgument * getSVFArgument(const Argument *arg) const
Definition: LLVMModule.h:251
SVFInstruction * getSVFInstruction(const Instruction *inst) const
Definition: LLVMModule.h:244
llvm::GlobalValue GlobalValue
Definition: BasicTypes.h:88
llvm::ConstantData ConstantData
Definition: BasicTypes.h:116
llvm::Constant Constant
Definition: BasicTypes.h:124

◆ getTypeInference()

ObjTypeInference * LLVMModuleSet::getTypeInference ( )

Definition at line 97 of file LLVMModule.cpp.

98 {
99  return typeInference;
100 }

◆ hasGlobalRep()

bool SVF::LLVMModuleSet::hasGlobalRep ( const GlobalVariable val) const
inline

Global to rep.

Definition at line 321 of file LLVMModule.h.

322  {
323  GlobalDefToRepMapTy::const_iterator it = GlobalDefToRepMap.find(val);
324  return it != GlobalDefToRepMap.end();
325  }

◆ hasICFGNode()

bool LLVMModuleSet::hasICFGNode ( const Instruction inst)

Definition at line 1413 of file LLVMModule.cpp.

1414 {
1415  ICFGNode* node;
1417  node = getCallBlock(inst);
1418  else if(LLVMUtil::isIntrinsicInst(inst))
1419  node = getIntraBlock(inst);
1420  else
1421  node = getIntraBlock(inst);
1422 
1423  return node != nullptr;
1424 }

◆ initDomTree()

void LLVMModuleSet::initDomTree ( SVFFunction func,
const Function f 
)
private

Definition at line 403 of file LLVMModule.cpp.

404 {
405  if (fun->isDeclaration())
406  return;
407  //process and stored dt & df
408  DominatorTree dt;
410  dt.recalculate(const_cast<Function&>(*fun));
411  df.analyze(dt);
412  LoopInfo loopInfo = LoopInfo(dt);
413  PostDominatorTree pdt = PostDominatorTree(const_cast<Function&>(*fun));
414  SVFLoopAndDomInfo* ld = svffun->getLoopAndDomInfo();
415 
417  for (DominanceFrontierBase::const_iterator dfIter = df.begin(), eDfIter = df.end(); dfIter != eDfIter; dfIter++)
418  {
419  const BasicBlock* keyBB = dfIter->first;
420  const std::set<BasicBlock* >& domSet = dfIter->second;
421  Set<const SVFBasicBlock*>& valueBasicBlocks = dfBBsMap[getSVFBasicBlock(keyBB)];
422  for (const BasicBlock* bbValue:domSet)
423  {
424  valueBasicBlocks.insert(getSVFBasicBlock(bbValue));
425  }
426  }
427  std::vector<const SVFBasicBlock*> reachableBBs;
428  LLVMUtil::getFunReachableBBs(fun, reachableBBs);
429  ld->setReachableBBs(reachableBBs);
430 
431  for (Function::const_iterator bit = fun->begin(), beit = fun->end(); bit!=beit; ++bit)
432  {
433  const BasicBlock &bb = *bit;
434  SVFBasicBlock* svfBB = getSVFBasicBlock(&bb);
435  if (DomTreeNode* dtNode = dt.getNode(&bb))
436  {
437  SVFLoopAndDomInfo::BBSet& bbSet = ld->getDomTreeMap()[svfBB];
438  for (const auto domBB : *dtNode)
439  {
440  const auto* domSVFBB = getSVFBasicBlock(domBB->getBlock());
441  bbSet.insert(domSVFBB);
442  }
443  }
444 
445  if (DomTreeNode* pdtNode = pdt.getNode(&bb))
446  {
447  u32_t level = pdtNode->getLevel();
448  ld->getBBPDomLevel()[svfBB] = level;
449  BasicBlock* idomBB = pdtNode->getIDom()->getBlock();
450  const SVFBasicBlock* idom = idomBB == NULL ? NULL: getSVFBasicBlock(idomBB);
451  ld->getBB2PIdom()[svfBB] = idom;
452 
453  SVFLoopAndDomInfo::BBSet& bbSet = ld->getPostDomTreeMap()[svfBB];
454  for (const auto domBB : *pdtNode)
455  {
456  const auto* domSVFBB = getSVFBasicBlock(domBB->getBlock());
457  bbSet.insert(domSVFBB);
458  }
459  }
460 
461  if (const Loop* loop = loopInfo.getLoopFor(&bb))
462  {
463  for (const BasicBlock* loopBlock : loop->getBlocks())
464  {
465  const SVFBasicBlock* loopbb = getSVFBasicBlock(loopBlock);
466  ld->addToBB2LoopMap(svfBB, loopbb);
467  }
468  }
469  }
470 }
Map< const SVFBasicBlock *, BBSet > & getDomTreeMap()
Definition: SVFValue.h:139
const Map< const SVFBasicBlock *, u32_t > & getBBPDomLevel() const
Definition: SVFValue.h:118
void setReachableBBs(BBList &bbs)
Definition: SVFValue.h:160
const Map< const SVFBasicBlock *, BBSet > & getPostDomTreeMap() const
Definition: SVFValue.h:108
Set< const SVFBasicBlock * > BBSet
Definition: SVFValue.h:55
const Map< const SVFBasicBlock *, BBSet > & getDomFrontierMap() const
Definition: SVFValue.h:75
const Map< const SVFBasicBlock *, const SVFBasicBlock * > & getBB2PIdom() const
Definition: SVFValue.h:128
void addToBB2LoopMap(const SVFBasicBlock *bb, const SVFBasicBlock *loopBB)
Definition: SVFValue.h:103
void getFunReachableBBs(const Function *svfFun, std::vector< const SVFBasicBlock * > &bbs)
Get reachable basic block from function entry.
Definition: LLVMUtil.cpp:74
llvm::LoopInfo LoopInfo
Definition: BasicTypes.h:141
llvm::DomTreeNode DomTreeNode
Definition: BasicTypes.h:134
llvm::PostDominatorTree PostDominatorTree
Definition: BasicTypes.h:136
llvm::DominanceFrontier DominanceFrontier
Definition: BasicTypes.h:135
llvm::Loop Loop
LLVM Loop.
Definition: BasicTypes.h:140
llvm::DominatorTree DominatorTree
LLVM Dominators.
Definition: BasicTypes.h:133

◆ initSVFBasicBlock()

void LLVMModuleSet::initSVFBasicBlock ( const Function func)
private

set exit block: exit basic block must have no successors and have a return instruction

Definition at line 329 of file LLVMModule.cpp.

330 {
331  SVFFunction *svfFun = getSVFFunction(func);
332  for (Function::const_iterator bit = func->begin(), ebit = func->end(); bit != ebit; ++bit)
333  {
334  const BasicBlock* bb = &*bit;
335  SVFBasicBlock* svfbb = getSVFBasicBlock(bb);
336  for (succ_const_iterator succ_it = succ_begin(bb); succ_it != succ_end(bb); succ_it++)
337  {
338  const SVFBasicBlock* svf_scc_bb = getSVFBasicBlock(*succ_it);
339  svfbb->addSuccBasicBlock(svf_scc_bb);
340  }
341  for (const_pred_iterator pred_it = pred_begin(bb); pred_it != pred_end(bb); pred_it++)
342  {
343  const SVFBasicBlock* svf_pred_bb = getSVFBasicBlock(*pred_it);
344  svfbb->addPredBasicBlock(svf_pred_bb);
345  }
346 
348  if (svfbb->getSuccessors().empty())
349  {
351  {
352  assert((LLVMUtil::functionDoesNotRet(func) ||
353  SVFUtil::isa<ReturnInst>(bb->back())) &&
354  "last inst must be return inst");
355  svfFun->setExitBlock(svfbb);
356  }
357  }
358 
359  for (BasicBlock::const_iterator iit = bb->begin(), eiit = bb->end(); iit != eiit; ++iit)
360  {
361  const Instruction* inst = &*iit;
362  if(const CallBase* call = SVFUtil::dyn_cast<CallBase>(inst))
363  {
364  SVFInstruction* svfinst = getSVFInstruction(call);
365  SVFCallInst* svfcall = SVFUtil::cast<SVFCallInst>(svfinst);
366  auto called_llvmval = call->getCalledOperand()->stripPointerCasts();
367  if (const Function* called_llvmfunc = SVFUtil::dyn_cast<Function>(called_llvmval))
368  {
369  SVFFunction* callee = getSVFFunction(called_llvmfunc);
370  svfcall->setCalledOperand(callee);
371  }
372  else
373  {
374  svfcall->setCalledOperand(getSVFValue(called_llvmval));
375  }
376  if(SVFVirtualCallInst* virtualCall = SVFUtil::dyn_cast<SVFVirtualCallInst>(svfcall))
377  {
378  virtualCall->setVtablePtr(getSVFValue(cppUtil::getVCallVtblPtr(call)));
379  virtualCall->setFunIdxInVtable(cppUtil::getVCallIdx(call));
380  virtualCall->setFunNameOfVirtualCall(cppUtil::getFunNameOfVCallSite(call));
381  }
382  for(u32_t i = 0; i < call->arg_size(); i++)
383  {
384  SVFValue* svfval = getSVFValue(call->getArgOperand(i));
385  svfcall->addArgument(svfval);
386  }
387  }
388  }
389  }
390  // For no return functions, we set the last block as exit BB
391  // This ensures that each function that has definition must have an exit BB
392  if (svfFun->exitBlock == nullptr && svfFun->hasBasicBlock())
393  {
394  SVFBasicBlock* retBB = const_cast<SVFBasicBlock*>(svfFun->back());
395  assert((LLVMUtil::functionDoesNotRet(func) ||
396  SVFUtil::isa<ReturnInst>(&func->back().back())) &&
397  "last inst must be return inst");
398  svfFun->setExitBlock(retBB);
399  }
400 }
SVFValue * getSVFValue(const Value *value)
void addPredBasicBlock(const SVFBasicBlock *pred)
Definition: SVFValue.h:552
const std::vector< const SVFBasicBlock * > & getSuccessors() const
Definition: SVFValue.h:606
void addSuccBasicBlock(const SVFBasicBlock *succ)
Definition: SVFValue.h:547
void setCalledOperand(const SVFValue *v)
Definition: SVFValue.h:682
void addArgument(const SVFValue *a)
attributes to be set only through Module builders e.g., LLVMModule
Definition: SVFValue.h:678
SVFBasicBlock * exitBlock
all formal arguments of this function
Definition: SVFValue.h:322
const SVFBasicBlock * back() const
Definition: SVFValue.h:426
bool hasBasicBlock() const
Definition: SVFValue.h:404
void setExitBlock(SVFBasicBlock *bb)
Definition: SVFValue.cpp:193
bool functionDoesNotRet(const Function *fun)
Definition: LLVMUtil.cpp:123
bool basicBlockHasRetInst(const BasicBlock *bb)
Return true if the function has a return instruction.
Definition: LLVMUtil.cpp:109
std::string getFunNameOfVCallSite(const CallBase *cs)
Definition: CppUtil.cpp:635
s32_t getVCallIdx(const CallBase *cs)
Definition: CppUtil.cpp:646
const Value * getVCallVtblPtr(const CallBase *cs)
Definition: CppUtil.cpp:537
llvm::succ_const_iterator succ_const_iterator
LLVM Iterators.
Definition: BasicTypes.h:276
llvm::const_pred_iterator const_pred_iterator
Definition: BasicTypes.h:254

◆ initSVFFunction()

void LLVMModuleSet::initSVFFunction ( )
private

Function

Definition at line 311 of file LLVMModule.cpp.

312 {
313  for (Module& mod : modules)
314  {
316  for (const Function& f : mod.functions())
317  {
318  SVFFunction* svffun = getSVFFunction(&f);
319  initSVFBasicBlock(&f);
320 
321  if (!SVFUtil::isExtCall(svffun))
322  {
323  initDomTree(svffun, &f);
324  }
325  }
326  }
327 }
void initSVFBasicBlock(const Function *func)
Definition: LLVMModule.cpp:329
void initDomTree(SVFFunction *func, const Function *f)
Definition: LLVMModule.cpp:403
bool isExtCall(const SVFFunction *fun)
Definition: SVFUtil.h:278

◆ loadExtAPIModules()

void LLVMModuleSet::loadExtAPIModules ( )
private

Definition at line 586 of file LLVMModule.cpp.

587 {
588  // This function loads the ExtAPI bitcode file as an LLVM module. Note that it is important that
589  // the same LLVMContext object is used to load this bitcode file as is used by the other modules
590  // being analysed.
591  // When the modules are loaded from bitcode files (i.e. passing filenames to files containing
592  // LLVM IR to `buildSVFModule({file1.bc, file2.bc, ...})) the context is created while loading
593  // the modules in `loadModules()`, which populates this->modules and this->owned_modules.
594  // If, however, an LLVM Module object is passed to `buildSVFModule` (e.g. from an LLVM pass),
595  // the context should be retrieved from the module itself (note that the garbage collection from
596  // `std::unique_ptr<LLVMContext> LLVMModuleSet::owned_ctx` should be avoided in this case). This
597  // function populates only this->modules.
598  // In both cases, fetching the context from the main LLVM module (through `getContext`) works
599  assert(!empty() && "LLVMModuleSet contains no modules; cannot load ExtAPI module without LLVMContext!");
600 
601  // Load external API module (extapi.bc)
602  if (!ExtAPI::getExtAPI()->getExtBcPath().empty())
603  {
604  std::string extModuleName = ExtAPI::getExtAPI()->getExtBcPath();
605  if (!LLVMUtil::isIRFile(extModuleName))
606  {
607  SVFUtil::errs() << "not an external IR file: " << extModuleName << std::endl;
608  abort();
609  }
610  SMDiagnostic Err;
611  std::unique_ptr<Module> mod = parseIRFile(extModuleName, Err, getContext());
612  if (mod == nullptr)
613  {
614  SVFUtil::errs() << "load external module: " << extModuleName << "failed!!\n\n";
615  Err.print("SVFModuleLoader", llvm::errs());
616  abort();
617  }
618  // The module of extapi.bc needs to be inserted before applications modules, like std::vector<std::reference_wrapper<Module>> modules{extapi_module, app_module}.
619  // Otherwise, when overwriting the app function with SVF extern function, the corresponding SVFFunction of the extern function will not be found.
620  modules.insert(modules.begin(), *mod);
621  owned_modules.insert(owned_modules.begin(),std::move(mod));
622  }
623 }
LLVMContext & getContext() const
Definition: LLVMModule.h:349
bool isIRFile(const std::string &filename)
Check whether a file is an LLVM IR file.
Definition: LLVMUtil.cpp:316
std::ostream & errs()
Overwrite llvm::errs()
Definition: SVFUtil.h:56
llvm::SMDiagnostic SMDiagnostic
Definition: BasicTypes.h:90

◆ loadModules()

void LLVMModuleSet::loadModules ( const std::vector< std::string > &  moduleNameVec)
private

Definition at line 521 of file LLVMModule.cpp.

522 {
523 
524  // We read SVFIR from LLVM IR
525  if(Options::Graphtxt().empty())
526  {
527  if(moduleNameVec.empty())
528  {
529  SVFUtil::outs() << "no LLVM bc file is found!\n";
530  exit(0);
531  }
532  //assert(!moduleNameVec.empty() && "no LLVM bc file is found!");
533  }
534  // We read SVFIR from a user-defined txt instead of parsing SVFIR from LLVM IR
535  else
537 
538  //
539  // LLVMContext objects separate global LLVM settings (from which e.g. types are
540  // derived); multiple LLVMContext objects can coexist and each context can "own"
541  // multiple modules (modules can only have one context). Mixing contexts can lead
542  // to unintended inequalities, such as the following:
543  //
544  // ------------------------------------------------------------------
545  // LLVMContext ctxa,ctxb;
546  // IntegerType * t1 = IntegerType::get(ctxa,32);
547  // IntegerType * t2 = IntegerType::get(ctxa,32);
548  // assert(t1 == t2);
549  // IntegerType * t3 = IntegerType::get(ctxb,32);
550  // IntegerType * t4 = IntegerType::get(ctxb,32);
551  // assert(t3 == t4);
552  // assert(t1 != t3);
553  // ------------------------------------------------------------------
554  //
555  // When loading bytecode files, SVF will use the same LLVMContext object for all
556  // modules (i.e. the context owns all loaded modules). This applies to ExtAPI as
557  // well, which *must* be loaded using the same LLVMContext object. Hence, when
558  // loading modules from bitcode files, a new LLVMContext is created (using a
559  // `std::unique_ptr<LLVMContext>` type to ensure automatic garbage collection).
560  //
561  // This garbage collection should be avoided when building an SVF module from an LLVM
562  // module instance; see the comment(s) in `buildSVFModule` and `loadExtAPIModules()`
563 
564  owned_ctx = std::make_unique<LLVMContext>();
565  for (const std::string& moduleName : moduleNameVec)
566  {
567  if (!LLVMUtil::isIRFile(moduleName))
568  {
569  SVFUtil::errs() << "not an IR file: " << moduleName << std::endl;
570  abort();
571  }
572 
573  SMDiagnostic Err;
574  std::unique_ptr<Module> mod = parseIRFile(moduleName, Err, *owned_ctx);
575  if (mod == nullptr)
576  {
577  SVFUtil::errs() << "load module: " << moduleName << "failed!!\n\n";
578  Err.print("SVFModuleLoader", llvm::errs());
579  abort();
580  }
581  modules.emplace_back(*mod);
582  owned_modules.emplace_back(std::move(mod));
583  }
584 }
std::unique_ptr< LLVMContext > owned_ctx
Definition: LLVMModule.h:80
static const Option< std::string > Graphtxt
Definition: Options.h:182
static void setPagFromTXT(const std::string &txt)
Definition: SVFModule.h:83

◆ prePassSchedule()

void LLVMModuleSet::prePassSchedule ( )
private

Invoke llvm passes to modify module.

Invoke llvm passes to modify module

BreakConstantGEPs Pass

MergeFunctionRets Pass

Definition at line 476 of file LLVMModule.cpp.

477 {
479  std::unique_ptr<BreakConstantGEPs> p1 = std::make_unique<BreakConstantGEPs>();
480  for (Module &M : getLLVMModules())
481  {
482  p1->runOnModule(M);
483  }
484 
486  std::unique_ptr<UnifyFunctionExitNodes> p2 =
487  std::make_unique<UnifyFunctionExitNodes>();
488  for (Module &M : getLLVMModules())
489  {
490  for (auto F = M.begin(), E = M.end(); F != E; ++F)
491  {
492  Function &fun = *F;
493  if (fun.isDeclaration())
494  continue;
495  p2->runOnFunction(fun);
496  }
497  }
498 }
#define F(f)
const std::vector< std::reference_wrapper< Module > > & getLLVMModules() const
Definition: LLVMModule.h:149

◆ preProcessBCs()

void LLVMModuleSet::preProcessBCs ( std::vector< std::string > &  moduleNameVec)
static

Definition at line 500 of file LLVMModule.cpp.

501 {
503  mset->loadModules(moduleNameVec);
504  mset->loadExtAPIModules();
505  mset->prePassSchedule();
506 
507  std::string preProcessSuffix = ".pre.bc";
508  // Get the existing module names, remove old extension, add preProcessSuffix
509  for (u32_t i = 0; i < moduleNameVec.size(); i++)
510  {
511  u32_t lastIndex = moduleNameVec[i].find_last_of(".");
512  std::string rawName = moduleNameVec[i].substr(0, lastIndex);
513  moduleNameVec[i] = (rawName + preProcessSuffix);
514  }
515 
516  mset->dumpModulesToFile(preProcessSuffix);
517  preProcessed = true;
519 }
static void releaseLLVMModuleSet()
Definition: LLVMModule.h:125
void dumpModulesToFile(const std::string &suffix)

◆ releaseLLVMModuleSet()

static void SVF::LLVMModuleSet::releaseLLVMModuleSet ( )
inlinestatic

Definition at line 125 of file LLVMModule.h.

126  {
127  delete llvmModuleSet;
128  llvmModuleSet = nullptr;
129  }

◆ setValueAttr() [1/2]

void LLVMModuleSet::setValueAttr ( const Value val,
SVF::SVFBaseNode svfBaseNode 
)
private

Definition at line 1241 of file LLVMModule.cpp.

1242 {
1243  SVFBaseNode2LLVMValue[svfBaseNode] = val;
1244  svfBaseNode->setSourceLoc(LLVMUtil::getSourceLoc(val));
1245 }
virtual void setSourceLoc(const std::string &sourceCodeInfo)
Definition: GenericGraph.h:276
const std::string getSourceLoc(const Value *val)
Definition: LLVMUtil.cpp:430

◆ setValueAttr() [2/2]

void LLVMModuleSet::setValueAttr ( const Value val,
SVFValue value 
)
private

Definition at line 1213 of file LLVMModule.cpp.

1214 {
1215  SVFValue2LLVMValue[svfvalue] = val;
1216 
1217  if(val->hasName())
1218  svfvalue->setName(val->getName().str());
1220  svfvalue->setPtrInUncalledFunction();
1222  svfvalue->setConstDataOrAggData();
1223 
1224  if (SVFGlobalValue* glob = SVFUtil::dyn_cast<SVFGlobalValue>(svfvalue))
1225  {
1226  const Value* llvmVal = LLVMUtil::getGlobalRep(val);
1227  assert(SVFUtil::isa<GlobalValue>(llvmVal) && "not a GlobalValue?");
1228  glob->setDefGlobalForMultipleModule(getSVFGlobalValue(SVFUtil::cast<GlobalValue>(llvmVal)));
1229  }
1230  if (SVFFunction* svffun = SVFUtil::dyn_cast<SVFFunction>(svfvalue))
1231  {
1232  const Function* func = SVFUtil::cast<Function>(val);
1233  svffun->setIsNotRet(LLVMUtil::functionDoesNotRet(func));
1234  svffun->setIsUncalledFunction(LLVMUtil::isUncalledFunction(func));
1235  svffun->setDefFunForMultipleModule(getSVFFunction(func));
1236  }
1237 
1238  svfvalue->setSourceLoc(LLVMUtil::getSourceLoc(val));
1239 }
bool isPtrInUncalledFunction(const Value *value)
Return true if this is value in a dead function (function without any caller)
Definition: LLVMUtil.cpp:176
bool isUncalledFunction(const Function *fun)
whether this is a function without any possible caller?
Definition: LLVMUtil.cpp:159
bool isConstDataOrAggData(const Value *val)
Return true if the value refers to constant data, e.g., i32 0.
Definition: LLVMUtil.h:327
const Value * getGlobalRep(const Value *val)
find the unique defined global across multiple modules
Definition: LLVMUtil.cpp:417

Friends And Related Function Documentation

◆ ICFGBuilder

friend class ICFGBuilder
friend

Definition at line 47 of file LLVMModule.h.

◆ SVFIRBuilder

friend class SVFIRBuilder
friend

Definition at line 46 of file LLVMModule.h.

Member Data Documentation

◆ callgraph

PTACallGraph* SVF::LLVMModuleSet::callgraph
private

Definition at line 108 of file LLVMModule.h.

◆ CSToCallNodeMap

CSToCallNodeMapTy SVF::LLVMModuleSet::CSToCallNodeMap
private

map a callsite to its CallICFGNode

Definition at line 103 of file LLVMModule.h.

◆ CSToRetNodeMap

CSToRetNodeMapTy SVF::LLVMModuleSet::CSToRetNodeMap
private

map a callsite to its RetICFGNode

Definition at line 104 of file LLVMModule.h.

◆ ExtFun2Annotations

Fun2AnnoMap SVF::LLVMModuleSet::ExtFun2Annotations
private

Record annotations of function in extapi.bc.

Definition at line 87 of file LLVMModule.h.

◆ ExtFuncsVec

FunctionSetType SVF::LLVMModuleSet::ExtFuncsVec
private

Record some "sse_" function declarations used in other ext function definition, e.g., svf_ext_foo(), and svf_ext_foo() used in app functions.

Definition at line 85 of file LLVMModule.h.

◆ FunToFunEntryNodeMap

FunToFunEntryNodeMapTy SVF::LLVMModuleSet::FunToFunEntryNodeMap
private

map a function to its FunExitICFGNode

Definition at line 106 of file LLVMModule.h.

◆ FunToFunExitNodeMap

FunToFunExitNodeMapTy SVF::LLVMModuleSet::FunToFunExitNodeMap
private

map a function to its FunEntryICFGNode

Definition at line 107 of file LLVMModule.h.

◆ GlobalDefToRepMap

GlobalDefToRepMapTy SVF::LLVMModuleSet::GlobalDefToRepMap
private

Global definition to a rep definition map.

Definition at line 89 of file LLVMModule.h.

◆ icfg

ICFG* SVF::LLVMModuleSet::icfg
private

Definition at line 79 of file LLVMModule.h.

◆ InstToBlockNodeMap

InstToBlockNodeMapTy SVF::LLVMModuleSet::InstToBlockNodeMap
private

map a basic block to its ICFGNode

Definition at line 105 of file LLVMModule.h.

◆ LLVMArgument2SVFArgument

LLVMArgument2SVFArgumentMap SVF::LLVMModuleSet::LLVMArgument2SVFArgument
private

Definition at line 94 of file LLVMModule.h.

◆ LLVMBB2SVFBB

LLVMBB2SVFBBMap SVF::LLVMModuleSet::LLVMBB2SVFBB
private

Definition at line 92 of file LLVMModule.h.

◆ LLVMConst2SVFConst

LLVMConst2SVFConstMap SVF::LLVMModuleSet::LLVMConst2SVFConst
private

Definition at line 95 of file LLVMModule.h.

◆ LLVMFunc2SVFFunc

LLVMFun2SVFFunMap SVF::LLVMModuleSet::LLVMFunc2SVFFunc
private

Map an LLVM Function to an SVF Function.

Definition at line 91 of file LLVMModule.h.

◆ LLVMInst2SVFInst

LLVMInst2SVFInstMap SVF::LLVMModuleSet::LLVMInst2SVFInst
private

Definition at line 93 of file LLVMModule.h.

◆ llvmModuleSet

LLVMModuleSet * LLVMModuleSet::llvmModuleSet = nullptr
staticprivate

Definition at line 75 of file LLVMModule.h.

◆ LLVMType2SVFType

LLVMType2SVFTypeMap SVF::LLVMModuleSet::LLVMType2SVFType
private

Definition at line 98 of file LLVMModule.h.

◆ LLVMValue2SVFOtherValue

LLVMValue2SVFOtherValueMap SVF::LLVMModuleSet::LLVMValue2SVFOtherValue
private

Definition at line 96 of file LLVMModule.h.

◆ modules

std::vector<std::reference_wrapper<Module> > SVF::LLVMModuleSet::modules
private

Definition at line 82 of file LLVMModule.h.

◆ owned_ctx

std::unique_ptr<LLVMContext> SVF::LLVMModuleSet::owned_ctx
private

Definition at line 80 of file LLVMModule.h.

◆ owned_modules

std::vector<std::unique_ptr<Module> > SVF::LLVMModuleSet::owned_modules
private

Definition at line 81 of file LLVMModule.h.

◆ preProcessed

bool LLVMModuleSet::preProcessed = false
staticprivate

Definition at line 76 of file LLVMModule.h.

◆ SVFBaseNode2LLVMValue

SVFBaseNode2LLVMValueMap SVF::LLVMModuleSet::SVFBaseNode2LLVMValue
private

Definition at line 102 of file LLVMModule.h.

◆ svfModule

SVFModule* SVF::LLVMModuleSet::svfModule
private

Borrowed from singleton SVFModule::svfModule.

Definition at line 78 of file LLVMModule.h.

◆ SVFValue2LLVMValue

SVFValue2LLVMValueMap SVF::LLVMModuleSet::SVFValue2LLVMValue
private

Definition at line 97 of file LLVMModule.h.

◆ symInfo

SymbolTableInfo* SVF::LLVMModuleSet::symInfo
private

Definition at line 77 of file LLVMModule.h.

◆ Type2TypeInfo

Type2TypeInfoMap SVF::LLVMModuleSet::Type2TypeInfo
private

Definition at line 99 of file LLVMModule.h.

◆ typeInference

ObjTypeInference* SVF::LLVMModuleSet::typeInference
private

Definition at line 100 of file LLVMModule.h.


The documentation for this class was generated from the following files: