Static Value-Flow Analysis
Loading...
Searching...
No Matches
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 *, FunObjVar * > LLVMFun2FunObjVarMap
 
typedef Map< const BasicBlock *, SVFBasicBlock * > LLVMBB2SVFBBMap
 
typedef Map< const SVFValue *, 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
 
typedef OrderedMap< const Value *, NodeIDValueToIDMapTy
 
typedef OrderedMap< const Function *, NodeIDFunToIDMapTy
 
typedef std::vector< const Function * > FunctionSet
 
typedef Map< const Function *, const BasicBlock * > FunToExitBBMap
 
typedef Map< const Function *, const Function * > FunToRealDefFunMap
 

Public Member Functions

 ~LLVMModuleSet ()
 
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)
 
const BasicBlockgetFunExitBB (const Function *fun) const
 
const FunctiongetRealDefFun (const Function *fun) const
 
const FunctionSetgetFunctionSet () const
 
u32_t getValueNodeNum () const
 
u32_t getObjNodeNum () const
 
ValueToIDMapTyvalSyms ()
 
ValueToIDMapTyobjSyms ()
 
NodeID getValueNode (const Value *V)
 
bool hasValueNode (const Value *V)
 
NodeID getObjectNode (const Value *V)
 
void dumpSymTable ()
 
void addBasicBlock (FunObjVar *fun, const BasicBlock *bb)
 
void addInstructionMap (const Instruction *inst, CallICFGNode *svfInst)
 
void addInstructionMap (const Instruction *inst, RetICFGNode *svfInst)
 
void addInstructionMap (const Instruction *inst, IntraICFGNode *svfInst)
 
bool hasLLVMValue (const SVFValue *value) const
 
const ValuegetLLVMValue (const SVFValue *value) const
 
const FunObjVargetFunObjVar (const Function *fun) const
 
FunToIDMapTyretSyms ()
 
FunToIDMapTyvarargSyms ()
 
NodeID getReturnNode (const Function *func) const
 
NodeID getVarargNode (const Function *func) const
 
SVFBasicBlockgetSVFBasicBlock (const BasicBlock *bb)
 
const FunctiongetFunction (const std::string &name)
 Get the corresponding Function based on its name.
 
const FunObjVargetFunObjVar (const std::string &name)
 Get the corresponding Function based on its name.
 
ICFGNodegetICFGNode (const Instruction *inst)
 Get a basic block ICFGNode.
 
bool hasICFGNode (const Instruction *inst)
 
CallICFGNodegetCallICFGNode (const Instruction *cs)
 get a call node
 
RetICFGNodegetRetICFGNode (const Instruction *cs)
 get a return node
 
IntraICFGNodegetIntraICFGNode (const Instruction *inst)
 get a intra node
 
FunEntryICFGNodegetFunEntryICFGNode (const Function *fun)
 Add a function entry node.
 
FunExitICFGNodegetFunExitICFGNode (const Function *fun)
 Add a function exit node.
 
bool hasGlobalRep (const GlobalVariable *val) const
 Global to rep.
 
GlobalVariablegetGlobalRep (const GlobalVariable *val) const
 
ModulegetMainLLVMModule () const
 
LLVMContextgetContext () const
 
bool empty () const
 
SVFTypegetSVFType (const Type *T)
 Get or create SVFType and typeinfo.
 
const TypegetLLVMType (const SVFType *T) const
 Get LLVM Type.
 
ObjTypeInferencegetTypeInference ()
 
DominatorTreegetDomTree (const Function *fun)
 
std::string getExtFuncAnnotation (const Function *fun, const std::string &funcAnnotation)
 
const std::vector< std::string > & getExtFuncAnnotations (const Function *fun)
 
bool hasExtFuncAnnotation (const Function *fun, const std::string &funcAnnotation)
 
bool has_static (const Function *F)
 
bool is_memcpy (const Function *F)
 
bool is_memset (const Function *F)
 
bool is_alloc (const Function *F)
 
bool is_arg_alloc (const Function *F)
 
bool is_alloc_stack_ret (const Function *F)
 
s32_t get_alloc_arg_pos (const Function *F)
 
bool is_realloc (const Function *F)
 
bool is_ext (const Function *F)
 
void setExtFuncAnnotations (const Function *fun, const std::vector< std::string > &funcAnnotations)
 

Static Public Member Functions

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

Private Member Functions

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

Private Attributes

SVFIRsvfir
 
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.
 
Fun2AnnoMap ExtFun2Annotations
 Record annotations of function in extapi.bc.
 
Map< const Function *, std::vector< std::string > > func2Annotations
 
GlobalDefToRepMapTy GlobalDefToRepMap
 Global definition to a rep definition map.
 
LLVMFun2FunObjVarMap LLVMFun2FunObjVar
 Map an LLVM Function to an SVF Funobjvar.
 
LLVMBB2SVFBBMap LLVMBB2SVFBB
 
LLVMType2SVFTypeMap LLVMType2SVFType
 
Type2TypeInfoMap Type2TypeInfo
 
ObjTypeInferencetypeInference
 
SVFBaseNode2LLVMValueMap SVFBaseNode2LLVMValue
 
CSToCallNodeMapTy CSToCallNodeMap
 map a callsite to its CallICFGNode
 
CSToRetNodeMapTy CSToRetNodeMap
 map a callsite to its RetICFGNode
 
InstToBlockNodeMapTy InstToBlockNodeMap
 map a basic block to its ICFGNode
 
FunToFunEntryNodeMapTy FunToFunEntryNodeMap
 map a function to its FunExitICFGNode
 
FunToFunExitNodeMapTy FunToFunExitNodeMap
 map a function to its FunEntryICFGNode
 
Map< const Function *, DominatorTreeFunToDominatorTree
 
ValueToIDMapTy valSymMap
 map a value to its sym id
 
ValueToIDMapTy objSymMap
 map a obj reference to its sym id
 
FunToIDMapTy returnSymMap
 return map
 
FunToIDMapTy varargSymMap
 vararg map
 
FunctionSet funSet
 
FunToExitBBMap funToExitBB
 
FunToRealDefFunMap funToRealDefFun
 

Static Private Attributes

static LLVMModuleSetllvmModuleSet = nullptr
 
static bool preProcessed = false
 

Friends

class SVFIRBuilder
 
class ICFGBuilder
 
class SymbolTableBuilder
 

Detailed Description

Definition at line 44 of file LLVMModule.h.

Member Typedef Documentation

◆ CSToCallNodeMapTy

Definition at line 64 of file LLVMModule.h.

◆ CSToRetNodeMapTy

Definition at line 65 of file LLVMModule.h.

◆ Fun2AnnoMap

typedef Map<std::string, std::vector<std::string> > SVF::LLVMModuleSet::Fun2AnnoMap

Definition at line 62 of file LLVMModule.h.

◆ FunctionSet

Definition at line 76 of file LLVMModule.h.

◆ FunctionSetType

Definition at line 52 of file LLVMModule.h.

◆ FunDeclToDefMapTy

Definition at line 53 of file LLVMModule.h.

◆ FunDefToDeclsMapTy

Definition at line 54 of file LLVMModule.h.

◆ FunToExitBBMap

Definition at line 77 of file LLVMModule.h.

◆ FunToFunEntryNodeMapTy

Definition at line 67 of file LLVMModule.h.

◆ FunToFunExitNodeMapTy

Definition at line 68 of file LLVMModule.h.

◆ FunToIDMapTy

Definition at line 74 of file LLVMModule.h.

◆ FunToRealDefFunMap

Definition at line 78 of file LLVMModule.h.

◆ GlobalDefToRepMapTy

Definition at line 55 of file LLVMModule.h.

◆ InstToBlockNodeMapTy

Definition at line 66 of file LLVMModule.h.

◆ LLVMBB2SVFBBMap

Definition at line 58 of file LLVMModule.h.

◆ LLVMFun2FunObjVarMap

Definition at line 57 of file LLVMModule.h.

◆ LLVMType2SVFTypeMap

Definition at line 60 of file LLVMModule.h.

◆ SVFBaseNode2LLVMValueMap

Definition at line 59 of file LLVMModule.h.

◆ Type2TypeInfoMap

Definition at line 61 of file LLVMModule.h.

◆ ValueToIDMapTy

llvm value to sym id map local (%) and global (@) identifiers are pointer types which have a value node id.

Definition at line 72 of file LLVMModule.h.

Constructor & Destructor Documentation

◆ LLVMModuleSet()

LLVMModuleSet::LLVMModuleSet ( )
private

Constructor.

Definition at line 85 of file LLVMModule.cpp.

87{
88}
ObjTypeInference * typeInference
Definition LLVMModule.h:103
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:116

◆ ~LLVMModuleSet()

LLVMModuleSet::~LLVMModuleSet ( )

Definition at line 90 of file LLVMModule.cpp.

91{
92
93 delete typeInference;
94 typeInference = nullptr;
95
96}

Member Function Documentation

◆ addBasicBlock()

void SVF::LLVMModuleSet::addBasicBlock ( FunObjVar fun,
const BasicBlock bb 
)
inline

Definition at line 232 of file LLVMModule.h.

233 {
234 SVFBasicBlock* svfBB = fun->getBasicBlockGraph()->addBasicBlock(bb->getName().str());
235 LLVMBB2SVFBB[bb] = svfBB;
237 }
LLVMBB2SVFBBMap LLVMBB2SVFBB
Definition LLVMModule.h:100
SVFBaseNode2LLVMValueMap SVFBaseNode2LLVMValue
Definition LLVMModule.h:105
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74

◆ addFunctionSet()

void SVF::LLVMModuleSet::addFunctionSet ( const Function svfFunc)
inlineprivate

Definition at line 440 of file LLVMModule.h.

441 {
442 funSet.push_back(svfFunc);
443 }
FunctionSet funSet
Definition LLVMModule.h:119

◆ addInstructionMap() [1/3]

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

Definition at line 239 of file LLVMModule.h.

240 {
241 CSToCallNodeMap[inst] = svfInst;
243 }
void addToSVFVar2LLVMValueMap(const Value *val, SVFValue *svfBaseNode)
CSToCallNodeMapTy CSToCallNodeMap
map a callsite to its CallICFGNode
Definition LLVMModule.h:106

◆ addInstructionMap() [2/3]

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

Definition at line 249 of file LLVMModule.h.

250 {
253 }
InstToBlockNodeMapTy InstToBlockNodeMap
map a basic block to its ICFGNode
Definition LLVMModule.h:108

◆ addInstructionMap() [3/3]

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

Definition at line 244 of file LLVMModule.h.

245 {
246 CSToRetNodeMap[inst] = svfInst;
248 }
CSToRetNodeMapTy CSToRetNodeMap
map a callsite to its RetICFGNode
Definition LLVMModule.h:107

◆ addSVFMain()

void LLVMModuleSet::addSVFMain ( )
private

Definition at line 509 of file LLVMModule.cpp.

510{
511 std::vector<const Function*> ctor_funcs;
512 std::vector<const Function*> dtor_funcs;
513 Function* orgMain = 0;
514 Module* mainMod = nullptr;
515
516 for (Module &mod : modules)
517 {
518 // Collect ctor and dtor functions
519 for (const GlobalVariable& global : mod.globals())
520 {
521 if (global.getName().equals(SVF_GLOBAL_CTORS) && global.hasInitializer())
522 {
524 }
525 else if (global.getName().equals(SVF_GLOBAL_DTORS) && global.hasInitializer())
526 {
528 }
529 }
530
531 // Find main function
532 for (auto &func : mod)
533 {
534 auto funName = func.getName();
535
536 assert(!funName.equals(SVF_MAIN_FUNC_NAME) && SVF_MAIN_FUNC_NAME " already defined");
537
538 if (funName.equals("main"))
539 {
540 orgMain = &func;
541 mainMod = &mod;
542 }
543 }
544 }
545
546 // Only create svf.main when the original main function is found, and also
547 // there are global constructor or destructor functions.
548 if (orgMain && getModuleNum() > 0 &&
549 (ctor_funcs.size() > 0 || dtor_funcs.size() > 0))
550 {
551 assert(mainMod && "Module with main function not found.");
552 Module& M = *mainMod;
553 // char **
554 Type* ptr = PointerType::getUnqual(M.getContext());
555 Type* i32 = IntegerType::getInt32Ty(M.getContext());
556 // define void @svf.main(i32, i8**, i8**)
557#if (LLVM_VERSION_MAJOR >= 9)
558 FunctionCallee svfmainFn = M.getOrInsertFunction(
560 Type::getVoidTy(M.getContext()),
561 i32,ptr,ptr
562 );
563 Function* svfmain = SVFUtil::dyn_cast<Function>(svfmainFn.getCallee());
564#else
565 Function* svfmain = SVFUtil::dyn_cast<Function>(M.getOrInsertFunction(
567 Type::getVoidTy(M.getContext()),
569 ));
570#endif
571 svfmain->setCallingConv(llvm::CallingConv::C);
572 BasicBlock* block = BasicBlock::Create(M.getContext(), "entry", svfmain);
574 // emit "call void @ctor()". ctor_funcs is sorted so the functions are
575 // emitted in the order of priority
576 for (auto& ctor : ctor_funcs)
577 {
578 auto target = M.getOrInsertFunction(
579 ctor->getName(),
580 Type::getVoidTy(M.getContext())
581 );
582 Builder.CreateCall(target);
583 }
584 // main() should be called after all ctor functions and before dtor
585 // functions.
586 Function::arg_iterator arg_it = svfmain->arg_begin();
587 Value* args[] = {arg_it, arg_it + 1, arg_it + 2};
588 size_t cnt = orgMain->arg_size();
589 assert(cnt <= 3 && "Too many arguments for main()");
590 Builder.CreateCall(orgMain, llvm::ArrayRef<Value*>(args, args + cnt));
591 // emit "call void @dtor()". dtor_funcs is sorted so the functions are
592 // emitted in the order of priority
593 for (auto& dtor : dtor_funcs)
594 {
595 auto target = M.getOrInsertFunction(dtor->getName(), Type::getVoidTy(M.getContext()));
596 Builder.CreateCall(target);
597 }
598 // return;
599 Builder.CreateRetVoid();
600 }
601}
#define SVF_MAIN_FUNC_NAME
#define SVF_GLOBAL_DTORS
#define SVF_GLOBAL_CTORS
std::vector< const Function * > getLLVMGlobalFunctions(const GlobalVariable *global)
std::vector< std::reference_wrapper< Module > > modules
Definition LLVMModule.h:86
u32_t getModuleNum() const
Definition LLVMModule.h:152
llvm::GlobalVariable GlobalVariable
Definition BasicTypes.h:132
llvm::Type Type
Definition BasicTypes.h:85
llvm::BasicBlock BasicBlock
Definition BasicTypes.h:88
llvm::Function Function
Definition BasicTypes.h:87
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:84
llvm::Module Module
Definition BasicTypes.h:86

◆ addSVFTypeInfo()

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

Create SVFTypes.

Definition at line 1285 of file LLVMModule.cpp.

1286{
1287 assert(LLVMType2SVFType.find(T) == LLVMType2SVFType.end() &&
1288 "SVFType has been added before");
1289
1290 // add SVFType's LLVM byte size iff T isSized(), otherwise byteSize is 1 (default value)
1291 u32_t byteSize = 1;
1292 if (T->isSized())
1293 {
1294 const llvm::DataLayout &DL = LLVMModuleSet::getLLVMModuleSet()->
1295 getMainLLVMModule()->getDataLayout();
1296 Type *mut_T = const_cast<Type *>(T);
1297 byteSize = DL.getTypeAllocSize(mut_T);
1298 }
1299
1301
1303 if (SVFUtil::isa<PointerType>(T))
1304 {
1305 svftype = new SVFPointerType(id, byteSize);
1306 }
1307 else if (const IntegerType* intT = SVFUtil::dyn_cast<IntegerType>(T))
1308 {
1309 auto svfIntT = new SVFIntegerType(id, byteSize);
1310 unsigned signWidth = intT->getBitWidth();
1311 assert(signWidth < INT16_MAX && "Integer width too big");
1312 svfIntT->setSignAndWidth(intT->getSignBit() ? -signWidth : signWidth);
1313 svftype = svfIntT;
1314 }
1315 else if (const FunctionType* ft = SVFUtil::dyn_cast<FunctionType>(T))
1316 {
1317 std::vector<const SVFType*> paramTypes;
1318 for (const auto& t: ft->params())
1319 {
1320 paramTypes.push_back(getSVFType(t));
1321 }
1322 svftype = new SVFFunctionType(id, getSVFType(ft->getReturnType()), paramTypes, ft->isVarArg());
1323 }
1324 else if (const StructType* st = SVFUtil::dyn_cast<StructType>(T))
1325 {
1326 std::vector<const SVFType*> fieldTypes;
1327
1328 for (const auto& t: st->elements())
1329 {
1330 fieldTypes.push_back(getSVFType(t));
1331 }
1332 auto svfst = new SVFStructType(id, fieldTypes, byteSize);
1333 if (st->hasName())
1334 svfst->setName(st->getName().str());
1335 svftype = svfst;
1336 }
1337 else if (const auto at = SVFUtil::dyn_cast<ArrayType>(T))
1338 {
1339 auto svfat = new SVFArrayType(id, byteSize);
1340 svfat->setNumOfElement(at->getNumElements());
1341 svfat->setTypeOfElement(getSVFType(at->getElementType()));
1342 svftype = svfat;
1343 }
1344 else
1345 {
1346 std::string buffer;
1347 auto ot = new SVFOtherType(id, T->isSingleValueType(), byteSize);
1348 llvm::raw_string_ostream(buffer) << *T;
1349 ot->setRepr(std::move(buffer));
1350 svftype = ot;
1351 }
1352
1355
1356 return svftype;
1357}
unsigned u32_t
Definition CommandLine.h:18
char * buffer
Definition cJSON.h:163
void addTypeInfo(const SVFType *ty)
Definition IRGraph.h:365
LLVMType2SVFTypeMap LLVMType2SVFType
Definition LLVMModule.h:101
Module * getMainLLVMModule() const
Definition LLVMModule.h:366
static LLVMModuleSet * getLLVMModuleSet()
Definition LLVMModule.h:131
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
static NodeIDAllocator * get(void)
Return (singleton) allocator.
NodeID allocateTypeId(void)
Allocate an type ID as determined by the strategy.
llvm::StructType StructType
LLVM types.
Definition BasicTypes.h:96
llvm::IntegerType IntegerType
Definition BasicTypes.h:99
llvm::FunctionType FunctionType
Definition BasicTypes.h:100

◆ addToSVFVar2LLVMValueMap()

void LLVMModuleSet::addToSVFVar2LLVMValueMap ( const Value val,
SVFValue svfBaseNode 
)
private

Definition at line 1147 of file LLVMModule.cpp.

1149{
1151 svfBaseNode->setSourceLoc(LLVMUtil::getSourceLoc(val));
1152 svfBaseNode->setName(val->getName().str());
1153}
const std::string getSourceLoc(const Value *val)
Definition LLVMUtil.cpp:452

◆ build()

void LLVMModuleSet::build ( )
private

Definition at line 165 of file LLVMModule.cpp.

166{
167 if(preProcessed==false)
169
172
173 if (Options::SVFMain())
174 addSVFMain();
175
177
178}
static bool preProcessed
Definition LLVMModule.h:82
void createSVFDataStructure()
void prePassSchedule()
Invoke llvm passes to modify module.
static const Option< bool > SVFMain
Definition Options.h:180

◆ 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 671 of file LLVMModule.cpp.

672{
676 Module* appModule = nullptr;
677 Module* extModule = nullptr;
678
679 for (Module& mod : modules)
680 {
681 // extapi.bc functions
682 if (mod.getName().str() == ExtAPI::getExtAPI()->getExtBcPath())
683 {
685 extModule = &mod;
686 for (const Function& fun : mod.functions())
687 {
688 // there is main declaration in ext bc, it should be mapped to
689 // main definition in app bc.
690 if (fun.getName().str() == "main")
691 {
692 appFunDecls.insert(&fun);
693 appFuncDeclNames.insert(fun.getName().str());
694 }
696 else if (fun.getName().str() == "svf__main")
697 {
698 ExtFuncsVec.push_back(&fun);
699 }
700 else
701 {
702 extFuncs.insert(&fun);
703 extFunDefNames.insert(fun.getName().str());
704 }
705 }
706 }
707 else
708 {
709 appModule = &mod;
711 for (const Function& fun : mod.functions())
712 {
713 if (fun.isDeclaration())
714 {
715 appFunDecls.insert(&fun);
716 appFuncDeclNames.insert(fun.getName().str());
717 }
718 else
719 {
720 appFunDefs.insert(&fun);
721 appFuncDefNames.insert(fun.getName().str());
722 }
723 }
724 }
725 }
726
727 // Find the intersectNames between appFuncDefNames and externalFunDefNames
728 std::set_intersection(
729 appFuncDefNames.begin(), appFuncDefNames.end(), extFunDefNames.begin(), extFunDefNames.end(),
730 std::inserter(intersectNames, intersectNames.end()));
731
733 {
734 assert(!(appFunToReplace == NULL && appModule == NULL) && "appFunToReplace and appModule cannot both be NULL");
735
736 if (appFunToReplace)
737 {
738 appModule = appFunToReplace->getParent();
739 }
740 // Create a new function with the same signature as extFunToClone
741 Function *clonedFunction = Function::Create(extFunToClone->getFunctionType(), Function::ExternalLinkage, extFunToClone->getName(), appModule);
742 // Map the arguments of the new function to the arguments of extFunToClone
743 llvm::ValueToValueMapTy valueMap;
744 Function::arg_iterator destArg = clonedFunction->arg_begin();
745 for (Function::const_arg_iterator srcArg = extFunToClone->arg_begin(); srcArg != extFunToClone->arg_end(); ++srcArg)
746 {
747 destArg->setName(srcArg->getName()); // Copy the name of the original argument
748 valueMap[&*srcArg] = &*destArg++; // Add a mapping from the old arg to the new arg
749 }
750 if (cloneBody)
751 {
752 // Collect global variables referenced by extFunToClone
753 // This step identifies all global variables used within the function to be cloned
754 std::set<GlobalVariable*> referencedGlobals;
755 for (const BasicBlock& BB : *extFunToClone)
756 {
757 for (const Instruction& I : BB)
758 {
759 for (const Value* operand : I.operands())
760 {
761 // Check if the operand is a global variable
762 if (const GlobalVariable* GV = SVFUtil::dyn_cast<GlobalVariable>(operand))
763 {
764 referencedGlobals.insert(const_cast<GlobalVariable*>(GV));
765 }
766 }
767 }
768 }
769
770 // Copy global variables to target module and update valueMap
771 // When cloning a function, we need to ensure all global variables it references are available in the target module
773 {
774 // Check if the global variable already exists in the target module
775 GlobalVariable* existingGV = appModule->getGlobalVariable(GV->getName());
776 if (existingGV)
777 {
778 // If the global variable already exists, ensure type consistency
779 assert(existingGV->getType() == GV->getType() && "Global variable type mismatch in client module!");
780 // Map the original global to the existing one in the target module
781 valueMap[GV] = existingGV; // Map to existing global variable
782 }
783 else
784 {
785 // If the global variable doesn't exist in the target module, create a new one with the same properties
787 *appModule, // Target module
788 GV->getValueType(), // Type of the global variable
789 GV->isConstant(), // Whether it's constant
790 GV->getLinkage(), // Linkage type
791 nullptr, // No initializer yet
792 GV->getName(), // Same name
793 nullptr, // No insert before instruction
794 GV->getThreadLocalMode(), // Thread local mode
795 GV->getAddressSpace() // Address space
796 );
797
798 // Copy initializer if present to maintain the global's value
799 if (GV->hasInitializer())
800 {
801 Constant* init = GV->getInitializer();
802 newGV->setInitializer(init); // Simple case: direct copy
803 }
804
805 // Copy other attributes like alignment to ensure identical behavior
806 newGV->copyAttributesFrom(GV);
807
808 // Add mapping from original global to the new one for use during function cloning
809 valueMap[GV] = newGV;
810 }
811 }
812
813 // Clone function body with updated valueMap
814 llvm::SmallVector<ReturnInst*, 8> ignoredReturns;
815 CloneFunctionInto(clonedFunction, extFunToClone, valueMap, llvm::CloneFunctionChangeType::LocalChangesOnly, ignoredReturns, "", nullptr);
816 }
817 if (appFunToReplace)
818 {
819 // Replace all uses of appFunToReplace with clonedFunction
820 appFunToReplace->replaceAllUsesWith(clonedFunction);
821 std::string oldFunctionName = appFunToReplace->getName().str();
822 // Delete the old function
823 appFunToReplace->eraseFromParent();
825 }
826 return clonedFunction;
827 };
828
830 for (const Function* appFunDecl : appFunDecls)
831 {
832 std::string appFunDeclName = LLVMUtil::restoreFuncName(appFunDecl->getName().str());
833 for (const Function* extFun : extFuncs)
834 {
835 if (extFun->getName().str().compare(appFunDeclName) == 0)
836 {
837 auto it = ExtFun2Annotations.find(extFun->getName().str());
838 // Without annotations, this function is normal function with useful function body
839 if (it == ExtFun2Annotations.end())
840 {
841 Function* clonedFunction = cloneAndReplaceFunction(const_cast<Function*>(extFun), const_cast<Function*>(appFunDecl), nullptr, true);
844 }
845 else
846 {
847 ExtFuncsVec.push_back(appFunDecl);
848 }
849 break;
850 }
851 }
852 }
853
856 for (string sameFuncDef: intersectNames)
857 {
858 Function* appFuncDef = appModule->getFunction(sameFuncDef);
859 Function* extFuncDef = extModule->getFunction(sameFuncDef);
860 if (appFuncDef == nullptr || extFuncDef == nullptr)
861 continue;
862
863 FunctionType *appFuncDefType = appFuncDef->getFunctionType();
864 FunctionType *extFuncDefType = extFuncDef->getFunctionType();
866 continue;
867
868 auto it = ExtFun2Annotations.find(sameFuncDef);
869 if (it != ExtFun2Annotations.end())
870 {
871 std::vector<std::string> annotations = it->second;
872 if (annotations.size() == 1 && annotations[0].find("OVERWRITE") != std::string::npos)
873 {
874 Function* clonedFunction = cloneAndReplaceFunction(const_cast<Function*>(extFuncDef), const_cast<Function*>(appFuncDef), nullptr, true);
877 }
878 else
879 {
880 if (annotations.size() >= 2)
881 {
882 for (const auto& annotation : annotations)
883 {
884 if(annotation.find("OVERWRITE") != std::string::npos)
885 {
886 assert(false && "overwrite and other annotations cannot co-exist");
887 }
888 }
889 }
890 }
891 }
892 }
893
895 {
896 for (inst_iterator I = inst_begin(caller), E = inst_end(caller); I != E; ++I)
897 {
898 Instruction *inst = &*I;
899
900 if (CallInst *callInst = SVFUtil::dyn_cast<CallInst>(inst))
901 {
902 Function *calledFunc = callInst->getCalledFunction();
903
904 if (calledFunc && calledFunc->getName() == callee->getName())
905 {
906 callInst->setCalledFunction(callee);
907 }
908 }
909 }
910 };
911
912 std::function<void(const Function*, Function*)> cloneAndLinkFunction;
914 {
915 if (clonedFuncs.find(extFunToClone) != clonedFuncs.end())
916 return;
917
918 Module* appModule = appClonedFun->getParent();
919 // Check if the function already exists in the parent module
920 if (appModule->getFunction(extFunToClone->getName()))
921 {
922 // The function already exists, no need to clone, but need to link it with the caller
923 Function* func = appModule->getFunction(extFunToClone->getName());
925 return;
926 }
927 // Decide whether to clone the function body based on ExtFun2Annotations
928 bool cloneBody = true;
929 auto it = ExtFun2Annotations.find(extFunToClone->getName().str());
930 if (it != ExtFun2Annotations.end())
931 {
932 std::vector<std::string> annotations = it->second;
933 if (!(annotations.size() == 1 && annotations[0].find("OVERWRITE") != std::string::npos))
934 {
935 cloneBody = false;
936 }
937 }
938
940
942 // Add the cloned function to ExtFuncsVec for further processing
943 ExtFuncsVec.push_back(clonedFunction);
944
946
947 std::vector<const Function*> calledFunctions = LLVMUtil::getCalledFunctions(extFunToClone);
948
949 for (const auto& calledFunction : calledFunctions)
950 {
952 }
953 };
954
955 // Recursive clone called functions
956 for (const auto& pair : extFuncs2ClonedFuncs)
957 {
958 Function* extFun = const_cast<Function*>(pair.first);
959 Function* clonedExtFun = const_cast<Function*>(pair.second);
960 std::vector<const Function*> extCalledFuns = LLVMUtil::getCalledFunctions(extFun);
961
962 for (const auto& extCalledFun : extCalledFuns)
963 {
965 }
966 }
967
968 // Remove unused annotations in ExtFun2Annotations according to the functions in ExtFuncsVec
970 for (const Function* extFun : ExtFuncsVec)
971 {
972 std::string name = LLVMUtil::restoreFuncName(extFun->getName().str());
973 auto it = ExtFun2Annotations.find(name);
974 if (it != ExtFun2Annotations.end())
975 {
976 std::string newKey = name;
977 if (name != extFun->getName().str())
978 {
979 newKey = extFun->getName().str();
980 }
981 newFun2AnnoMap.insert({newKey, it->second});
982 }
983 }
985
986 // Remove ExtAPI module from modules
987 auto it = std::find_if(modules.begin(), modules.end(),
988 [&extModule](const std::reference_wrapper<llvm::Module>& moduleRef)
989 {
990 return &moduleRef.get() == extModule;
991 });
992
993 if (it != modules.end())
994 {
995 size_t index = std::distance(modules.begin(), it);
996 modules.erase(it);
997 owned_modules.erase(owned_modules.begin() + index);
998 }
999}
const char *const name
Definition cJSON.h:264
int index
Definition cJSON.h:170
std::string getExtBcPath()
Definition ExtAPI.cpp:136
static ExtAPI * getExtAPI()
Definition ExtAPI.cpp:44
Fun2AnnoMap ExtFun2Annotations
Record annotations of function in extapi.bc.
Definition LLVMModule.h:91
FunctionSetType ExtFuncsVec
Record some "sse_" function declarations used in other ext function definition, e....
Definition LLVMModule.h:89
Map< std::string, std::vector< std::string > > Fun2AnnoMap
Definition LLVMModule.h:62
std::vector< std::unique_ptr< Module > > owned_modules
Definition LLVMModule.h:85
void collectExtFunAnnotations(const Module *mod)
#define NULL
Definition extapi.c:5
std::vector< const Function * > getCalledFunctions(const Function *F)
Get all called funcions in a parent function.
Definition LLVMUtil.cpp:363
std::string restoreFuncName(std::string funcName)
Definition LLVMUtil.cpp:406
llvm::inst_iterator inst_iterator
Definition BasicTypes.h:251
llvm::Instruction Instruction
Definition BasicTypes.h:89
llvm::Constant Constant
Definition BasicTypes.h:126
llvm::CallInst CallInst
Definition BasicTypes.h:149

◆ buildGlobalDefToRepMap()

void LLVMModuleSet::buildGlobalDefToRepMap ( )
private

Definition at line 1001 of file LLVMModule.cpp.

1002{
1005 for (Module &mod : modules)
1006 {
1007 // Collect ctor and dtor functions
1008 for (GlobalVariable& global : mod.globals())
1009 {
1010 if (global.hasPrivateLinkage())
1011 continue;
1012 string name = global.getName().str();
1013 if (name.empty())
1014 continue;
1015 nameToGlobalsMap[std::move(name)].insert(&global);
1016 }
1017 }
1018
1019 for (const auto& pair : nameToGlobalsMap)
1020 {
1021 const Set<GlobalVariable*> &globals = pair.second;
1022
1023 const auto repIt =
1024 std::find_if(globals.begin(), globals.end(),
1025 [](GlobalVariable* g)
1026 {
1027 return g->hasInitializer();
1028 });
1029 GlobalVariable* rep =
1030 repIt != globals.end()
1031 ? *repIt
1032 // When there is no initializer, just pick the first one.
1033 : (assert(!globals.empty() && "Empty global set"),
1034 *globals.begin());
1035
1036 for (const GlobalVariable* cur : globals)
1037 {
1038 GlobalDefToRepMap[cur] = rep;
1039 }
1040 }
1041}
GlobalDefToRepMapTy GlobalDefToRepMap
Global definition to a rep definition map.
Definition LLVMModule.h:97

◆ buildSVFModule() [1/2]

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

Definition at line 127 of file LLVMModule.cpp.

128{
129 double startSVFModuleTime = SVFStat::getClk(true);
130
132
133 mset->loadModules(moduleNameVec); // Populates `modules`; can get context via `this->getContext()`
134 mset->loadExtAPIModules(); // Uses context from first module through `this->getContext()`
135
136 if (!moduleNameVec.empty())
137 {
139 }
140
141 mset->build();
142
143 double endSVFModuleTime = SVFStat::getClk(true);
146
147 mset->buildSymbolTable();
148}
#define TIMEINTERVAL
Definition SVFType.h:621
void setModuleIdentifier(const std::string &moduleIdentifier)
Definition SVFIR.h:222
static double timeOfBuildingLLVMModule
Definition SVFStat.h:93
static double getClk(bool mark=false)
Definition SVFStat.cpp:48

◆ buildSVFModule() [2/2]

void LLVMModuleSet::buildSVFModule ( Module mod)
static

Definition at line 112 of file LLVMModule.cpp.

113{
115
116 double startSVFModuleTime = SVFStat::getClk(true);
117 PAG::getPAG()->setModuleIdentifier(mod.getModuleIdentifier());
118 mset->modules.emplace_back(mod); // Populates `modules`; can get context via `this->getContext()`
119 mset->loadExtAPIModules(); // Uses context from module through `this->getContext()`
120 mset->build();
121 double endSVFModuleTime = SVFStat::getClk(true);
123
124 mset->buildSymbolTable();
125}

◆ buildSymbolTable()

void LLVMModuleSet::buildSymbolTable ( ) const
private

building symbol table

Definition at line 150 of file LLVMModule.cpp.

151{
152 double startSymInfoTime = SVFStat::getClk(true);
154 {
156 DBOUT(DGENERAL, SVFUtil::outs() << SVFUtil::pasMsg("Building Symbol table ...\n"));
158 builder.buildMemModel();
159 }
160 double endSymInfoTime = SVFStat::getClk(true);
163}
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:593
#define DGENERAL
Definition SVFType.h:599
static bool pagReadFromTXT()
Definition SVFIR.h:212
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:101
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52

◆ 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 1362 of file LLVMModule.cpp.

1363{
1364 u64_t totalElemNum = ty->getNumElements();
1365 const Type* elemTy = ty->getElementType();
1366 while (const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(elemTy))
1367 {
1368 totalElemNum *= aty->getNumElements();
1369 elemTy = aty->getElementType();
1370 }
1371
1374
1376 if (totalElemNum == 0)
1377 {
1378 stInfo->addFldWithType(0, elemSvfType, 0);
1379 stInfo->setNumOfFieldsAndElems(1, 1);
1380 stInfo->getFlattenFieldTypes().push_back(elemSvfType);
1381 stInfo->getFlattenElementTypes().push_back(elemSvfType);
1382 return stInfo;
1383 }
1384
1388 u32_t nfF = elemStInfo->getNumOfFlattenFields();
1389 u32_t nfE = elemStInfo->getNumOfFlattenElements();
1390 for (u32_t j = 0; j < nfF; j++)
1391 {
1392 const SVFType* fieldTy = elemStInfo->getFlattenFieldTypes()[j];
1393 stInfo->getFlattenFieldTypes().push_back(fieldTy);
1394 }
1395
1398 u32_t outArrayElemNum = ty->getNumElements();
1399 for (u32_t i = 0; i < outArrayElemNum; ++i)
1400 {
1401 auto idx = (i * nfE * totalElemNum) / outArrayElemNum;
1402 stInfo->addFldWithType(0, elemSvfType, idx);
1403 }
1404
1405 for (u32_t i = 0; i < totalElemNum; ++i)
1406 {
1407 for (u32_t j = 0; j < nfE; ++j)
1408 {
1409 const SVFType* et = elemStInfo->getFlattenElementTypes()[j];
1410 stInfo->getFlattenElementTypes().push_back(et);
1411 }
1412 }
1413
1414 assert(stInfo->getFlattenElementTypes().size() == nfE * totalElemNum &&
1415 "typeForArray size incorrect!!!");
1416 stInfo->setNumOfFieldsAndElems(nfF, nfE * totalElemNum);
1417
1418 return stInfo;
1419}
StInfo * collectTypeInfo(const Type *ty)
Collect a type info.
llvm::ArrayType ArrayType
Definition BasicTypes.h:97
unsigned long long u64_t
Definition GeneralType.h:49

◆ collectExtFunAnnotations()

void LLVMModuleSet::collectExtFunAnnotations ( const Module mod)
private

Non-opaque pointer

Opaque pointer

Definition at line 603 of file LLVMModule.cpp.

604{
605 GlobalVariable *glob = mod->getGlobalVariable("llvm.global.annotations");
606 if (glob == nullptr || !glob->hasInitializer())
607 return;
608
609 ConstantArray *ca = SVFUtil::dyn_cast<ConstantArray>(glob->getInitializer());
610 if (ca == nullptr)
611 return;
612
613 for (unsigned i = 0; i < ca->getNumOperands(); ++i)
614 {
615 ConstantStruct *structAn = SVFUtil::dyn_cast<ConstantStruct>(ca->getOperand(i));
616 if (structAn == nullptr || structAn->getNumOperands() == 0)
617 continue;
618
619 // Check if the annotation is for a function
620 Function* fun = nullptr;
621 GlobalVariable *annotateStr = nullptr;
623 if (ConstantExpr *expr = SVFUtil::dyn_cast<ConstantExpr>(structAn->getOperand(0)))
624 {
625 if (expr->getOpcode() == Instruction::BitCast && SVFUtil::isa<Function>(expr->getOperand(0)))
626 fun = SVFUtil::cast<Function>(expr->getOperand(0));
627
628 ConstantExpr *note = SVFUtil::cast<ConstantExpr>(structAn->getOperand(1));
629 if (note->getOpcode() != Instruction::GetElementPtr)
630 continue;
631
632 annotateStr = SVFUtil::dyn_cast<GlobalVariable>(note->getOperand(0));
633 }
635 else
636 {
637 fun = SVFUtil::dyn_cast<Function>(structAn->getOperand(0));
638 annotateStr = SVFUtil::dyn_cast<GlobalVariable>(structAn->getOperand(1));
639 }
640
641 if (!fun || annotateStr == nullptr || !annotateStr->hasInitializer())
642 continue;;
643
644 ConstantDataSequential *data = SVFUtil::dyn_cast<ConstantDataSequential>(annotateStr->getInitializer());
645 if (data && data->isString())
646 {
647 std::string annotation = data->getAsString().str();
648 if (!annotation.empty())
649 ExtFun2Annotations[fun->getName().str()].push_back(annotation);
650 }
651 }
652}
llvm::ConstantStruct ConstantStruct
Definition BasicTypes.h:108
llvm::ConstantArray ConstantArray
Definition BasicTypes.h:125
llvm::ConstantDataSequential ConstantDataSequential
Definition BasicTypes.h:121
llvm::ConstantExpr ConstantExpr
Definition BasicTypes.h:122

◆ 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 1482 of file LLVMModule.cpp.

1483{
1485 StInfo* stInfo = new StInfo(1);
1487 stInfo->addFldWithType(0, svfType, 0);
1488
1489 stInfo->getFlattenFieldTypes().push_back(svfType);
1490 stInfo->getFlattenElementTypes().push_back(svfType);
1491 stInfo->setNumOfFieldsAndElems(1,1);
1492
1493 return stInfo;
1494}

◆ 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 1425 of file LLVMModule.cpp.

1427{
1429 StInfo* stInfo = new StInfo(1);
1430
1431 // Number of fields after flattening the struct
1432 numFields = 0;
1433 // The offset when considering array stride info
1434 u32_t strideOffset = 0;
1435 for (const Type* elemTy : structTy->elements())
1436 {
1438 // offset with int_32 (s32_t) is large enough and won't overflow
1439 stInfo->addFldWithType(numFields, elemSvfTy, strideOffset);
1440
1441 if (SVFUtil::isa<StructType, ArrayType>(elemTy))
1442 {
1444 u32_t nfF = subStInfo->getNumOfFlattenFields();
1445 u32_t nfE = subStInfo->getNumOfFlattenElements();
1446 // Copy ST's info, whose element 0 is the size of ST itself.
1447 for (u32_t j = 0; j < nfF; ++j)
1448 {
1449 const SVFType* elemTy = subStInfo->getFlattenFieldTypes()[j];
1450 stInfo->getFlattenFieldTypes().push_back(elemTy);
1451 }
1452 numFields += nfF;
1453 strideOffset += nfE;
1454 for (u32_t tpj = 0; tpj < nfE; ++tpj)
1455 {
1456 const SVFType* ty = subStInfo->getFlattenElementTypes()[tpj];
1457 stInfo->getFlattenElementTypes().push_back(ty);
1458 }
1459
1460 }
1461 else
1462 {
1463 // Simple type
1464 numFields += 1;
1465 strideOffset += 1;
1466 stInfo->getFlattenFieldTypes().push_back(elemSvfTy);
1467 stInfo->getFlattenElementTypes().push_back(elemSvfTy);
1468 }
1469 }
1470
1471 assert(stInfo->getFlattenElementTypes().size() == strideOffset &&
1472 "typeForStruct size incorrect!");
1473 stInfo->setNumOfFieldsAndElems(numFields,strideOffset);
1474
1475 return stInfo;
1476}

◆ collectTypeInfo()

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

Collect a type info.

Definition at line 1253 of file LLVMModule.cpp.

1254{
1255 Type2TypeInfoMap::iterator tit = Type2TypeInfo.find(T);
1256 if (tit != Type2TypeInfo.end())
1257 {
1258 return tit->second;
1259 }
1260 // No such StInfo for T, create it now.
1261 StInfo* stInfo;
1262 if (const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(T))
1263 {
1265 }
1266 else if (const StructType* sty = SVFUtil::dyn_cast<StructType>(T))
1267 {
1268 u32_t nf;
1270 if (nf > svfir->maxStSize)
1271 {
1273 svfir->maxStSize = nf;
1274 }
1275 }
1276 else
1277 {
1279 }
1280 Type2TypeInfo.emplace(T, stInfo);
1282 return stInfo;
1283}
const SVFType * maxStruct
The struct type with the most fields.
Definition IRGraph.h:360
void addStInfo(StInfo *stInfo)
Definition IRGraph.h:372
u32_t maxStSize
The number of fields in max_struct.
Definition IRGraph.h:363
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:102

◆ createSVFDataStructure()

void LLVMModuleSet::createSVFDataStructure ( )
private

Function

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

Definition at line 180 of file LLVMModule.cpp.

181{
184 // Functions need to be retrieved in the order of insertion
185 // candidateDefs is the vector for all used defined functions
186 // candidateDecls is the vector for all used declared functions
187 std::vector<const Function*> candidateDefs, candidateDecls;
188
189 for (Module& mod : modules)
190 {
192 for (Function& func : mod.functions())
193 {
194 if (func.isDeclaration())
195 {
196 candidateDecls.push_back(&func);
197 }
198 else
199 {
200 candidateDefs.push_back(&func);
201 }
202 }
203 }
204
205 for (const Function* func: candidateDefs)
206 {
208 }
209 for (const Function* func: candidateDecls)
210 {
212 }
213
214 // set function exit block
215 for (const auto& func: funSet)
216 {
217 for (Function::const_iterator bit = func->begin(), ebit = func->end(); bit != ebit; ++bit)
218 {
219 const BasicBlock* bb = &*bit;
221 if (succ_size(bb) == 0)
222 {
224 {
226 SVFUtil::isa<ReturnInst>(bb->back())) &&
227 "last inst must be return inst");
228 setFunExitBB(func, bb);
229 }
230 }
231 }
232 // For no return functions, we set the last block as exit BB
233 // This ensures that each function that has definition must have an exit BB
234 if (func->size() != 0 && !getFunExitBB(func))
235 {
237 SVFUtil::isa<ReturnInst>(&func->back().back())) &&
238 "last inst must be return inst");
239 setFunExitBB(func, &func->back());
240 }
241 }
242
243 // Store annotations of functions in extapi.bc
244 for (const auto& pair : ExtFun2Annotations)
245 {
246 const Function* fun = getFunction(pair.first);
247 setExtFuncAnnotations(fun, pair.second);
248 }
249
250}
void setFunExitBB(const Function *fun, const BasicBlock *bb)
Definition LLVMModule.h:445
void setExtFuncAnnotations(const Function *fun, const std::vector< std::string > &funcAnnotations)
const Function * getFunction(const std::string &name)
Get the corresponding Function based on its name.
Definition LLVMModule.h:306
const BasicBlock * getFunExitBB(const Function *fun) const
Definition LLVMModule.h:178
void addFunctionSet(const Function *svfFunc)
Definition LLVMModule.h:440
ObjTypeInference * getTypeInference()
static SVFType * svfPtrTy
ptr type
Definition SVFType.h:232
static SVFType * svfI8Ty
8-bit int type
Definition SVFType.h:233
bool functionDoesNotRet(const Function *fun)
Definition LLVMUtil.cpp:122
bool basicBlockHasRetInst(const BasicBlock *bb)
Return true if the function has a return instruction.
Definition LLVMUtil.cpp:108

◆ dumpModulesToFile()

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

Definition at line 1044 of file LLVMModule.cpp.

1045{
1046 for (Module& mod : modules)
1047 {
1048 std::string moduleName = mod.getName().str();
1049 std::string OutputFilename;
1050 std::size_t pos = moduleName.rfind('.');
1051 if (pos != std::string::npos)
1052 OutputFilename = moduleName.substr(0, pos) + suffix;
1053 else
1054 OutputFilename = moduleName + suffix;
1055
1056 std::error_code EC;
1057 raw_fd_ostream OS(OutputFilename.c_str(), EC, llvm::sys::fs::OF_None);
1058
1059#if (LLVM_VERSION_MAJOR >= 7)
1061#else
1063#endif
1064
1065 OS.flush();
1066 }
1067}
llvm::raw_fd_ostream raw_fd_ostream
LLVM outputs.
Definition BasicTypes.h:266

◆ dumpSymTable()

void LLVMModuleSet::dumpSymTable ( )

Definition at line 1100 of file LLVMModule.cpp.

1101{
1103 for (ValueToIDMapTy::iterator iter = valSymMap.begin(); iter != valSymMap.end();
1104 ++iter)
1105 {
1106 const NodeID i = iter->second;
1107 idmap[i] = iter->first;
1108 }
1109 for (ValueToIDMapTy::iterator iter = objSymMap.begin(); iter != objSymMap.end();
1110 ++iter)
1111 {
1112 const NodeID i = iter->second;
1113 idmap[i] = iter->first;
1114 }
1115 for (FunToIDMapTy::iterator iter = retSyms().begin(); iter != retSyms().end();
1116 ++iter)
1117 {
1118 const NodeID i = iter->second;
1119 idmap[i] = iter->first;
1120 }
1121 for (FunToIDMapTy::iterator iter = varargSyms().begin(); iter != varargSyms().end();
1122 ++iter)
1123 {
1124 const NodeID i = iter->second;
1125 idmap[i] = iter->first;
1126 }
1127 SVFUtil::outs() << "{SymbolTableInfo \n";
1128
1129
1130
1131
1132 for (auto iter : idmap)
1133 {
1134 std::string str;
1135 llvm::raw_string_ostream rawstr(str);
1136 auto llvmVal = iter.second;
1137 if (llvmVal)
1138 rawstr << " " << *llvmVal << " ";
1139 else
1140 rawstr << " No llvmVal found";
1142 SVFUtil::outs() << iter.first << " " << rawstr.str() << "\n";
1143 }
1144 SVFUtil::outs() << "}\n";
1145}
FunToIDMapTy & retSyms()
Definition LLVMModule.h:274
ValueToIDMapTy valSymMap
map a value to its sym id
Definition LLVMModule.h:114
ValueToIDMapTy objSymMap
map a obj reference to its sym id
Definition LLVMModule.h:115
FunToIDMapTy & varargSyms()
Definition LLVMModule.h:279
u32_t NodeID
Definition GeneralType.h:56

◆ empty()

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

Definition at line 387 of file LLVMModule.h.

388 {
389 return getModuleNum() == 0;
390 }

◆ get_alloc_arg_pos()

s32_t LLVMModuleSet::get_alloc_arg_pos ( const Function F)

Definition at line 1566 of file LLVMModule.cpp.

1567{
1568 std::string allocArg = getExtFuncAnnotation(F, "ALLOC_HEAP_ARG");
1569 assert(!allocArg.empty() && "Not an alloc call via argument or incorrect extern function annotation!");
1570
1571 std::string number;
1572 for (char c : allocArg)
1573 {
1574 if (isdigit(c))
1575 number.push_back(c);
1576 }
1577 assert(!number.empty() && "Incorrect naming convention for svf external functions(ALLOC_HEAP_ARG + number)?");
1578 return std::stoi(number);
1579}
const char *const const double number
Definition cJSON.h:268
std::string getExtFuncAnnotation(const Function *fun, const std::string &funcAnnotation)
int isdigit(int c)
Definition extapi.c:937

◆ getCallBlock()

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

Get/Add a call node.

Definition at line 483 of file LLVMModule.h.

484 {
485 CSToCallNodeMapTy::const_iterator it = CSToCallNodeMap.find(cs);
486 if (it == CSToCallNodeMap.end())
487 return nullptr;
488 return it->second;
489 }

◆ getCallICFGNode()

CallICFGNode * LLVMModuleSet::getCallICFGNode ( const Instruction cs)

get a call node

Definition at line 1228 of file LLVMModule.cpp.

1229{
1230 assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
1231 assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
1232 CallICFGNode* node = getCallBlock(inst);
1233 assert (node!=nullptr && "no CallICFGNode for this instruction?");
1234 return node;
1235}
CallICFGNode * getCallBlock(const Instruction *cs)
Get/Add a call node.
Definition LLVMModule.h:483
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
Definition LLVMUtil.h:44
bool isNonInstricCallSite(const Instruction *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
Definition LLVMUtil.cpp:724

◆ getContext()

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

Definition at line 381 of file LLVMModule.h.

382 {
383 assert(!empty() && "empty LLVM module!!");
384 return getMainLLVMModule()->getContext();
385 }
bool empty() const
Definition LLVMModule.h:387

◆ getDomTree()

DominatorTree & LLVMModuleSet::getDomTree ( const Function fun)

Definition at line 103 of file LLVMModule.cpp.

104{
105 auto it = FunToDominatorTree.find(fun);
106 if(it != FunToDominatorTree.end()) return it->second;
108 dt.recalculate(const_cast<Function&>(*fun));
109 return dt;
110}
Map< const Function *, DominatorTree > FunToDominatorTree
Definition LLVMModule.h:112
llvm::DominatorTree DominatorTree
LLVM Dominators.
Definition BasicTypes.h:135

◆ getExtFuncAnnotation()

std::string LLVMModuleSet::getExtFuncAnnotation ( const Function fun,
const std::string &  funcAnnotation 
)

Definition at line 1515 of file LLVMModule.cpp.

1516{
1517 assert(fun && "Null Function* pointer");
1518 auto it = func2Annotations.find(fun);
1519 if (it != func2Annotations.end())
1520 {
1521 for (const std::string& annotation : it->second)
1522 if (annotation.find(funcAnnotation) != std::string::npos)
1524 }
1525 return "";
1526}
if(prebuffer< 0)
Definition cJSON.cpp:1269
return(char *) p.buffer
const char *const string
Definition cJSON.h:172
Map< const Function *, std::vector< std::string > > func2Annotations
Definition LLVMModule.h:94

◆ getExtFuncAnnotations()

const std::vector< std::string > & LLVMModuleSet::getExtFuncAnnotations ( const Function fun)

Definition at line 1528 of file LLVMModule.cpp.

1529{
1530 assert(fun && "Null Function* pointer");
1531 auto it = func2Annotations.find(fun);
1532 if (it != func2Annotations.end())
1533 return it->second;
1534 return func2Annotations[fun];
1535}

◆ getFunction()

const Function * SVF::LLVMModuleSet::getFunction ( const std::string &  name)
inline

Get the corresponding Function based on its name.

Definition at line 306 of file LLVMModule.h.

307 {
308 Function* fun = nullptr;
309
310 for (u32_t i = 0; i < llvmModuleSet->getModuleNum(); ++i)
311 {
313 fun = mod->getFunction(name);
314 if (fun)
315 {
316 return fun;
317 }
318 }
319 return nullptr;
320 }
Module * getModule(u32_t idx) const
Definition LLVMModule.h:162
static LLVMModuleSet * llvmModuleSet
Definition LLVMModule.h:81

◆ getFunctionSet()

const FunctionSet & SVF::LLVMModuleSet::getFunctionSet ( ) const
inline

Definition at line 192 of file LLVMModule.h.

193 {
194 return funSet;
195 }

◆ getFunEntryBlock()

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

Get/Add a function entry node.

Definition at line 509 of file LLVMModule.h.

510 {
511 FunToFunEntryNodeMapTy::const_iterator it = FunToFunEntryNodeMap.find(fun);
512 if (it == FunToFunEntryNodeMap.end())
513 return nullptr;
514 return it->second;
515 }
FunToFunEntryNodeMapTy FunToFunEntryNodeMap
map a function to its FunExitICFGNode
Definition LLVMModule.h:109

◆ getFunEntryICFGNode()

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

Add a function entry node.

Definition at line 337 of file LLVMModule.h.

338 {
339 FunEntryICFGNode* b = getFunEntryBlock(fun);
340 assert(b && "Function entry not created?");
341 return b;
342 }
const cJSON *const b
Definition cJSON.h:255
FunEntryICFGNode * getFunEntryBlock(const Function *fun)
Get/Add a function entry node.
Definition LLVMModule.h:509

◆ getFunExitBB()

const BasicBlock * SVF::LLVMModuleSet::getFunExitBB ( const Function fun) const
inline

Definition at line 178 of file LLVMModule.h.

179 {
180 auto it = funToExitBB.find(fun);
181 if (it == funToExitBB.end()) return nullptr;
182 else return it->second;
183 }
FunToExitBBMap funToExitBB
Definition LLVMModule.h:120

◆ getFunExitBlock()

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

Get/Add a function exit node.

Definition at line 518 of file LLVMModule.h.

519 {
520 FunToFunExitNodeMapTy::const_iterator it = FunToFunExitNodeMap.find(fun);
521 if (it == FunToFunExitNodeMap.end())
522 return nullptr;
523 return it->second;
524 }
FunToFunExitNodeMapTy FunToFunExitNodeMap
map a function to its FunEntryICFGNode
Definition LLVMModule.h:110

◆ getFunExitICFGNode()

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

Add a function exit node.

Definition at line 344 of file LLVMModule.h.

345 {
346 FunExitICFGNode* b = getFunExitBlock(fun);
347 assert(b && "Function exit not created?");
348 return b;
349 }
FunExitICFGNode * getFunExitBlock(const Function *fun)
Get/Add a function exit node.
Definition LLVMModule.h:518

◆ getFunObjVar() [1/2]

const FunObjVar * SVF::LLVMModuleSet::getFunObjVar ( const Function fun) const
inline

Definition at line 267 of file LLVMModule.h.

268 {
269 LLVMFun2FunObjVarMap::const_iterator it = LLVMFun2FunObjVar.find(fun);
270 assert(it!=LLVMFun2FunObjVar.end() && "SVF Function not found!");
271 return it->second;
272 }
LLVMFun2FunObjVarMap LLVMFun2FunObjVar
Map an LLVM Function to an SVF Funobjvar.
Definition LLVMModule.h:99

◆ getFunObjVar() [2/2]

const FunObjVar * LLVMModuleSet::getFunObjVar ( const std::string &  name)

Get the corresponding Function based on its name.

Definition at line 1155 of file LLVMModule.cpp.

1156{
1157 Function* fun = nullptr;
1158
1159 for (u32_t i = 0; i < llvmModuleSet->getModuleNum(); ++i)
1160 {
1162 fun = mod->getFunction(name);
1163 if (fun)
1164 {
1165 return llvmModuleSet->getFunObjVar(fun);
1166 }
1167 }
1168 return nullptr;
1169}
const FunObjVar * getFunObjVar(const Function *fun) const
Definition LLVMModule.h:267

◆ getGlobalRep()

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

Definition at line 359 of file LLVMModule.h.

360 {
361 GlobalDefToRepMapTy::const_iterator it = GlobalDefToRepMap.find(val);
362 assert(it != GlobalDefToRepMap.end() && "has no rep?");
363 return it->second;
364 }

◆ getICFGNode()

ICFGNode * LLVMModuleSet::getICFGNode ( const Instruction inst)

Get a basic block ICFGNode.

Definition at line 1201 of file LLVMModule.cpp.

1202{
1203 ICFGNode* node;
1205 node = getCallICFGNode(inst);
1206 else if(LLVMUtil::isIntrinsicInst(inst))
1207 node = getIntraICFGNode(inst);
1208 else
1209 node = getIntraICFGNode(inst);
1210
1211 assert (node!=nullptr && "no ICFGNode for this instruction?");
1212 return node;
1213}
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:202

◆ getIntraBlock()

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

Definition at line 500 of file LLVMModule.h.

501 {
502 InstToBlockNodeMapTy::const_iterator it = InstToBlockNodeMap.find(inst);
503 if (it == InstToBlockNodeMap.end())
504 return nullptr;
505 return it->second;
506 }

◆ getIntraICFGNode()

IntraICFGNode * LLVMModuleSet::getIntraICFGNode ( const Instruction inst)

get a intra node

Definition at line 1246 of file LLVMModule.cpp.

1247{
1248 IntraICFGNode* node = getIntraBlock(inst);
1249 assert (node!=nullptr && "no IntraICFGNode for this instruction?");
1250 return node;
1251}
IntraICFGNode * getIntraBlock(const Instruction *inst)
Definition LLVMModule.h:500

◆ getLLVMGlobalFunctions()

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

Definition at line 421 of file LLVMModule.cpp.

422{
423 // This function is used to extract constructor and destructor functions
424 // sorted by their priority from @llvm.global_ctors or @llvm.global_dtors.
425 // For example, given following @llvm.global_ctors, the returning sorted
426 // function list should be [ctor3, ctor1, ctor2].
427 // ------------------------------------------------------------------
428 // ; Each struct in the array is {priority, function, associated data}
429 //
430 // @llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }]
431 // [{ i32, void ()*, i8* } { i32 1234, void ()* @ctor1.cpp, i8* null },
432 // { i32, void ()*, i8* } { i32 2345, void ()* @ctor2.cpp, i8* null },
433 // { i32, void ()*, i8* } { i32 345, void ()* @ctor3.cpp, i8* null }]
434 // ------------------------------------------------------------------
435 // TODO: According to LLVM language reference, if the third field is
436 // non-null, and points to a global variable or function, the initializer
437 // function will only run if the associated data from the current module is
438 // not discarded. However the associated data is currently ignored.
439
440
441 // This class is used for the priority queue that sorts the functions by
442 // their priority. Each object of this class stands for an item in the
443 // function array.
445 {
446 public:
448 const Function* func;
452 bool operator>(const LLVMGlobalFunction &other) const
453 {
454 if (priority != other.priority)
455 {
456 return priority > other.priority;
457 }
458 else
459 {
460 return func > other.func;
461 }
462 }
463 };
464
465 std::priority_queue<LLVMGlobalFunction, std::vector<LLVMGlobalFunction>,
467 queue;
468 std::vector<const Function* > result;
469
470 // The @llvm.global_ctors/dtors global variable is an array of struct. Each
471 // struct has three fields: {i32 priority, void ()* @ctor/dtor, i8* @data}.
472 // First get the array here.
474 SVFUtil::dyn_cast<ConstantArray>(global->getInitializer()))
475 {
476 // Get each struct in the array.
477 for (unsigned int i = 0; i < globalFuncArray->getNumOperands(); ++i)
478 {
479 if (
481 SVFUtil::dyn_cast<ConstantStruct>(
482 globalFuncArray->getOperand(i)))
483 {
484
485 // Extract priority and function from the struct
486 const ConstantInt* priority = SVFUtil::dyn_cast<ConstantInt>(
487 globalFuncItem->getOperand(0));
488 const Function* func = SVFUtil::dyn_cast<Function>(
489 globalFuncItem->getOperand(1));
490
491 if (priority && func)
492 {
494 func));
495 }
496 }
497 }
498 }
499
500 // Generate a sorted vector of functions from the priority queue.
501 while (!queue.empty())
502 {
503 result.push_back(queue.top().func);
504 queue.pop();
505 }
506 return result;
507}
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
Definition LLVMUtil.h:82
llvm::ConstantInt ConstantInt
Definition BasicTypes.h:127
IntervalValue operator>(const IntervalValue &lhs, const IntervalValue &rhs)

◆ getLLVMModules()

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

Definition at line 157 of file LLVMModule.h.

158 {
159 return modules;
160 }

◆ getLLVMModuleSet()

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

Definition at line 131 of file LLVMModule.h.

132 {
133 if (!llvmModuleSet)
135 return llvmModuleSet;
136 }
LLVMModuleSet()
Constructor.

◆ getLLVMType()

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

Get LLVM Type.

Definition at line 1172 of file LLVMModule.cpp.

1173{
1174 for(LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.begin(), eit = LLVMType2SVFType.end(); it!=eit; ++it)
1175 {
1176 if (it->second == T)
1177 return it->first;
1178 }
1179 assert(false && "can't find the corresponding LLVM Type");
1180 abort();
1181}

◆ getLLVMValue()

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

Definition at line 260 of file LLVMModule.h.

261 {
262 SVFBaseNode2LLVMValueMap ::const_iterator it = SVFBaseNode2LLVMValue.find(value);
263 assert(it != SVFBaseNode2LLVMValue.end() && "can't find corresponding llvm value!");
264 return it->second;
265 }

◆ getMainLLVMModule()

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

Definition at line 366 of file LLVMModule.h.

367 {
368 assert(!empty() && "empty LLVM module!!");
369 for (size_t i = 0; i < getModuleNum(); ++i)
370 {
371 Module& module = getModuleRef(i);
372 if (module.getName().str() != ExtAPI::getExtAPI()->getExtBcPath())
373 {
374 return &module;
375 }
376 }
377 assert(false && "no main module found!");
378 return nullptr;
379 }

◆ getModule()

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

Definition at line 162 of file LLVMModule.h.

163 {
164 return &getModuleRef(idx);
165 }
Module & getModuleRef(u32_t idx) const
Definition LLVMModule.h:167

◆ getModuleNum()

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

Definition at line 152 of file LLVMModule.h.

153 {
154 return modules.size();
155 }

◆ getModuleRef()

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

Definition at line 167 of file LLVMModule.h.

168 {
169 assert(idx < getModuleNum() && "Out of range.");
170 return modules[idx];
171 }

◆ getObjectNode()

NodeID LLVMModuleSet::getObjectNode ( const Value V)

getObject - Return the obj node id refer to the memory object for the specified global, heap or alloca instruction according to llvm value.

Definition at line 1090 of file LLVMModule.cpp.

1091{
1092 if (const GlobalVariable* glob = SVFUtil::dyn_cast<GlobalVariable>(llvm_value))
1094 ValueToIDMapTy::const_iterator iter = objSymMap.find(llvm_value);
1095 assert(iter!=objSymMap.end() && "obj sym not found");
1096 return iter->second;
1097}
const Value * getGlobalRep(const Value *val)
find the unique defined global across multiple modules
Definition LLVMUtil.cpp:439

◆ getObjNodeNum()

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

Definition at line 202 of file LLVMModule.h.

203 {
204 return objSymMap.size();
205 }

◆ getRealDefFun()

const Function * SVF::LLVMModuleSet::getRealDefFun ( const Function fun) const
inline

Definition at line 185 of file LLVMModule.h.

186 {
187 auto it = funToRealDefFun.find(fun);
188 if (it == funToRealDefFun.end()) return nullptr;
189 else return it->second;
190 }
FunToRealDefFunMap funToRealDefFun
Definition LLVMModule.h:121

◆ getRetBlock()

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

Get/Add a return node.

Definition at line 492 of file LLVMModule.h.

493 {
494 CSToRetNodeMapTy::const_iterator it = CSToRetNodeMap.find(cs);
495 if (it == CSToRetNodeMap.end())
496 return nullptr;
497 return it->second;
498 }

◆ getRetICFGNode()

RetICFGNode * LLVMModuleSet::getRetICFGNode ( const Instruction cs)

get a return node

Definition at line 1237 of file LLVMModule.cpp.

1238{
1239 assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
1240 assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
1241 RetICFGNode* node = getRetBlock(inst);
1242 assert (node!=nullptr && "no RetICFGNode for this instruction?");
1243 return node;
1244}
RetICFGNode * getRetBlock(const Instruction *cs)
Get/Add a return node.
Definition LLVMModule.h:492

◆ getReturnNode()

NodeID SVF::LLVMModuleSet::getReturnNode ( const Function func) const
inline

Definition at line 284 of file LLVMModule.h.

285 {
286 FunToIDMapTy::const_iterator iter = returnSymMap.find(func);
287 assert(iter!=returnSymMap.end() && "ret sym not found");
288 return iter->second;
289 }
FunToIDMapTy returnSymMap
return map
Definition LLVMModule.h:116

◆ getSVFBasicBlock()

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

Definition at line 298 of file LLVMModule.h.

299 {
300 LLVMBB2SVFBBMap::const_iterator it = LLVMBB2SVFBB.find(bb);
301 assert(it!=LLVMBB2SVFBB.end() && "SVF BasicBlock not found!");
302 return it->second;
303 }

◆ getSVFType()

SVFType * LLVMModuleSet::getSVFType ( const Type T)

Get or create SVFType and typeinfo.

Get or create SVFType and typeinfo

Definition at line 1186 of file LLVMModule.cpp.

1187{
1188 assert(T && "SVFType should not be null");
1189 LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.find(T);
1190 if (it != LLVMType2SVFType.end())
1191 return it->second;
1192
1195 svfType->setTypeInfo(stinfo);
1196 return svfType;
1197}
SVFType * addSVFTypeInfo(const Type *t)
Create SVFTypes.

◆ getTypeInference()

ObjTypeInference * LLVMModuleSet::getTypeInference ( )

Definition at line 98 of file LLVMModule.cpp.

99{
100 return typeInference;
101}

◆ getValueNode()

NodeID LLVMModuleSet::getValueNode ( const Value V)

Get SVFIR Node according to LLVM value getNode - Return the node corresponding to the specified pointer.

Definition at line 1069 of file LLVMModule.cpp.

1070{
1071 if (SVFUtil::isa<ConstantPointerNull>(llvm_value))
1072 return svfir->nullPtrSymID();
1073 else if (SVFUtil::isa<UndefValue>(llvm_value))
1074 return svfir->blkPtrSymID();
1075 else
1076 {
1077 ValueToIDMapTy::const_iterator iter = valSymMap.find(llvm_value);
1078 assert(iter!=valSymMap.end() &&"value sym not found");
1079 return iter->second;
1080 }
1081}
NodeID blkPtrSymID() const
Definition IRGraph.h:178
NodeID nullPtrSymID() const
Definition IRGraph.h:183

◆ getValueNodeNum()

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

Definition at line 197 of file LLVMModule.h.

198 {
199 return valSymMap.size();
200 }

◆ getVarargNode()

NodeID SVF::LLVMModuleSet::getVarargNode ( const Function func) const
inline

Definition at line 291 of file LLVMModule.h.

292 {
293 FunToIDMapTy::const_iterator iter = varargSymMap.find(func);
294 assert(iter!=varargSymMap.end() && "vararg sym not found");
295 return iter->second;
296 }
FunToIDMapTy varargSymMap
vararg map
Definition LLVMModule.h:117

◆ has_static()

bool SVF::LLVMModuleSet::has_static ( const Function F)

◆ hasExtFuncAnnotation()

bool LLVMModuleSet::hasExtFuncAnnotation ( const Function fun,
const std::string &  funcAnnotation 
)

Definition at line 1502 of file LLVMModule.cpp.

1503{
1504 assert(fun && "Null SVFFunction* pointer");
1505 auto it = func2Annotations.find(fun);
1506 if (it != func2Annotations.end())
1507 {
1508 for (const std::string& annotation : it->second)
1509 if (annotation.find(funcAnnotation) != std::string::npos)
1510 return true;
1511 }
1512 return false;
1513}
#define true
Definition cJSON.cpp:65

◆ hasGlobalRep()

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

Global to rep.

Definition at line 353 of file LLVMModule.h.

354 {
355 GlobalDefToRepMapTy::const_iterator it = GlobalDefToRepMap.find(val);
356 return it != GlobalDefToRepMap.end();
357 }

◆ hasICFGNode()

bool LLVMModuleSet::hasICFGNode ( const Instruction inst)

Definition at line 1215 of file LLVMModule.cpp.

1216{
1217 ICFGNode* node;
1219 node = getCallBlock(inst);
1220 else if(LLVMUtil::isIntrinsicInst(inst))
1221 node = getIntraBlock(inst);
1222 else
1223 node = getIntraBlock(inst);
1224
1225 return node != nullptr;
1226}

◆ hasLLVMValue()

bool SVF::LLVMModuleSet::hasLLVMValue ( const SVFValue value) const
inline

Definition at line 255 of file LLVMModule.h.

256 {
257 return SVFBaseNode2LLVMValue.find(value) != SVFBaseNode2LLVMValue.end();
258 }

◆ hasValueNode()

bool LLVMModuleSet::hasValueNode ( const Value V)

Definition at line 1082 of file LLVMModule.cpp.

1083{
1084 if (SVFUtil::isa<ConstantPointerNull, UndefValue>(val))
1085 return true;
1086 else
1087 return (valSymMap.find(val) != valSymMap.end());
1088}

◆ is_alloc()

bool LLVMModuleSet::is_alloc ( const Function F)

Definition at line 1549 of file LLVMModule.cpp.

1550{
1551 return F && hasExtFuncAnnotation(F, "ALLOC_HEAP_RET");
1552}
bool hasExtFuncAnnotation(const Function *fun, const std::string &funcAnnotation)

◆ is_alloc_stack_ret()

bool LLVMModuleSet::is_alloc_stack_ret ( const Function F)

Definition at line 1560 of file LLVMModule.cpp.

1561{
1562 return F && hasExtFuncAnnotation(F, "ALLOC_STACK_RET");
1563}

◆ is_arg_alloc()

bool LLVMModuleSet::is_arg_alloc ( const Function F)

Definition at line 1555 of file LLVMModule.cpp.

1556{
1557 return F && hasExtFuncAnnotation(F, "ALLOC_HEAP_ARG");
1558}

◆ is_ext()

bool LLVMModuleSet::is_ext ( const Function F)

Definition at line 1590 of file LLVMModule.cpp.

1591{
1592 assert(F && "Null SVFFunction* pointer");
1593 if (F->isDeclaration() || F->isIntrinsic())
1594 return true;
1595 else if (hasExtFuncAnnotation(F, "OVERWRITE") && getExtFuncAnnotations(F).size() == 1)
1596 return false;
1597 else
1598 return !getExtFuncAnnotations(F).empty();
1599}
const std::vector< std::string > & getExtFuncAnnotations(const Function *fun)

◆ is_memcpy()

bool LLVMModuleSet::is_memcpy ( const Function F)

Definition at line 1537 of file LLVMModule.cpp.

1538{
1539 return F &&
1540 (hasExtFuncAnnotation(F, "MEMCPY") || hasExtFuncAnnotation(F, "STRCPY")
1541 || hasExtFuncAnnotation(F, "STRCAT"));
1542}

◆ is_memset()

bool LLVMModuleSet::is_memset ( const Function F)

Definition at line 1544 of file LLVMModule.cpp.

1545{
1546 return F && hasExtFuncAnnotation(F, "MEMSET");
1547}

◆ is_realloc()

bool LLVMModuleSet::is_realloc ( const Function F)

Definition at line 1582 of file LLVMModule.cpp.

1583{
1584 return F && hasExtFuncAnnotation(F, "REALLOC_HEAP_RET");
1585}

◆ loadExtAPIModules()

void LLVMModuleSet::loadExtAPIModules ( )
private

Definition at line 382 of file LLVMModule.cpp.

383{
384 // This function loads the ExtAPI bitcode file as an LLVM module. Note that it is important that
385 // the same LLVMContext object is used to load this bitcode file as is used by the other modules
386 // being analysed.
387 // When the modules are loaded from bitcode files (i.e. passing filenames to files containing
388 // LLVM IR to `buildSVFModule({file1.bc, file2.bc, ...})) the context is created while loading
389 // the modules in `loadModules()`, which populates this->modules and this->owned_modules.
390 // If, however, an LLVM Module object is passed to `buildSVFModule` (e.g. from an LLVM pass),
391 // the context should be retrieved from the module itself (note that the garbage collection from
392 // `std::unique_ptr<LLVMContext> LLVMModuleSet::owned_ctx` should be avoided in this case). This
393 // function populates only this->modules.
394 // In both cases, fetching the context from the main LLVM module (through `getContext`) works
395 assert(!empty() && "LLVMModuleSet contains no modules; cannot load ExtAPI module without LLVMContext!");
396
397 // Load external API module (extapi.bc)
398 if (!ExtAPI::getExtAPI()->getExtBcPath().empty())
399 {
402 {
403 SVFUtil::errs() << "not an external IR file: " << extModuleName << std::endl;
404 abort();
405 }
407 std::unique_ptr<Module> mod = parseIRFile(extModuleName, Err, getContext());
408 if (mod == nullptr)
409 {
410 SVFUtil::errs() << "load external module: " << extModuleName << "failed!!\n\n";
411 Err.print("SVFModuleLoader", llvm::errs());
412 abort();
413 }
414 // The module of extapi.bc needs to be inserted before applications modules, like std::vector<std::reference_wrapper<Module>> modules{extapi_module, app_module}.
415 // Otherwise, when overwriting the app function with SVF extern function, the corresponding SVFFunction of the extern function will not be found.
416 modules.insert(modules.begin(), *mod);
417 owned_modules.insert(owned_modules.begin(),std::move(mod));
418 }
419}
LLVMContext & getContext() const
Definition LLVMModule.h:381
bool isIRFile(const std::string &filename)
Check whether a file is an LLVM IR file.
Definition LLVMUtil.cpp:314
std::ostream & errs()
Overwrite llvm::errs()
Definition SVFUtil.h:58
llvm::SMDiagnostic SMDiagnostic
Definition BasicTypes.h:92

◆ loadModules()

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

Definition at line 316 of file LLVMModule.cpp.

317{
318
319 // We read SVFIR from LLVM IR
321 {
322 if(moduleNameVec.empty())
323 {
324 SVFUtil::outs() << "no LLVM bc file is found!\n";
325 exit(0);
326 }
327 //assert(!moduleNameVec.empty() && "no LLVM bc file is found!");
328 }
329 // We read SVFIR from a user-defined txt instead of parsing SVFIR from LLVM IR
330 else
331 {
333 }
334 //
335 // LLVMContext objects separate global LLVM settings (from which e.g. types are
336 // derived); multiple LLVMContext objects can coexist and each context can "own"
337 // multiple modules (modules can only have one context). Mixing contexts can lead
338 // to unintended inequalities, such as the following:
339 //
340 // ------------------------------------------------------------------
341 // LLVMContext ctxa,ctxb;
342 // IntegerType * t1 = IntegerType::get(ctxa,32);
343 // IntegerType * t2 = IntegerType::get(ctxa,32);
344 // assert(t1 == t2);
345 // IntegerType * t3 = IntegerType::get(ctxb,32);
346 // IntegerType * t4 = IntegerType::get(ctxb,32);
347 // assert(t3 == t4);
348 // assert(t1 != t3);
349 // ------------------------------------------------------------------
350 //
351 // When loading bytecode files, SVF will use the same LLVMContext object for all
352 // modules (i.e. the context owns all loaded modules). This applies to ExtAPI as
353 // well, which *must* be loaded using the same LLVMContext object. Hence, when
354 // loading modules from bitcode files, a new LLVMContext is created (using a
355 // `std::unique_ptr<LLVMContext>` type to ensure automatic garbage collection).
356 //
357 // This garbage collection should be avoided when building an SVF module from an LLVM
358 // module instance; see the comment(s) in `buildSVFModule` and `loadExtAPIModules()`
359
360 owned_ctx = std::make_unique<LLVMContext>();
361 for (const std::string& moduleName : moduleNameVec)
362 {
363 if (!LLVMUtil::isIRFile(moduleName))
364 {
365 SVFUtil::errs() << "not an IR file: " << moduleName << std::endl;
366 abort();
367 }
368
370 std::unique_ptr<Module> mod = parseIRFile(moduleName, Err, *owned_ctx);
371 if (mod == nullptr)
372 {
373 SVFUtil::errs() << "load module: " << moduleName << "failed!!\n\n";
374 Err.print("SVFModuleLoader", llvm::errs());
375 abort();
376 }
377 modules.emplace_back(*mod);
378 owned_modules.emplace_back(std::move(mod));
379 }
380}
std::unique_ptr< LLVMContext > owned_ctx
Definition LLVMModule.h:84
static const Option< std::string > Graphtxt
Definition Options.h:179
static void setPagFromTXT(const std::string &txt)
Definition SVFIR.h:217

◆ objSyms()

ValueToIDMapTy & SVF::LLVMModuleSet::objSyms ( )
inline

Definition at line 212 of file LLVMModule.h.

213 {
214 return objSymMap;
215 }

◆ prePassSchedule()

void LLVMModuleSet::prePassSchedule ( )
private

Invoke llvm passes to modify module.

Invoke llvm passes to modify module

BreakConstantGEPs Pass

MergeFunctionRets Pass

Definition at line 255 of file LLVMModule.cpp.

256{
258 std::unique_ptr<BreakConstantGEPs> p1 = std::make_unique<BreakConstantGEPs>();
259 for (Module &M : getLLVMModules())
260 {
261 p1->runOnModule(M);
262 }
263
265 std::unique_ptr<UnifyFunctionExitNodes> p2 =
266 std::make_unique<UnifyFunctionExitNodes>();
267 for (Module &M : getLLVMModules())
268 {
269 for (auto F = M.begin(), E = M.end(); F != E; ++F)
270 {
271 Function &fun = *F;
272 if (fun.isDeclaration())
273 continue;
274#if LLVM_VERSION_MAJOR <= 16
275 p2->runOnFunction(fun);
276#else
277 llvm::PassBuilder PB;
278 llvm::LoopAnalysisManager LAM;
279 llvm::FunctionAnalysisManager FAM;
280 llvm::CGSCCAnalysisManager CGAM;
281 llvm::ModuleAnalysisManager MAM;
282 PB.registerModuleAnalyses(MAM);
283 PB.registerCGSCCAnalyses(CGAM);
284 PB.registerFunctionAnalyses(FAM);
285 PB.registerLoopAnalyses(LAM);
286 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
287 llvm::FunctionPassManager FPM;
288 // FPM.addPass(llvm::UnifyFunctionExitNodesPass());
289 FPM.run(fun, FAM);
290#endif
291 }
292 }
293}
const std::vector< std::reference_wrapper< Module > > & getLLVMModules() const
Definition LLVMModule.h:157

◆ preProcessBCs()

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

Definition at line 295 of file LLVMModule.cpp.

296{
298 mset->loadModules(moduleNameVec);
299 mset->loadExtAPIModules();
300 mset->prePassSchedule();
301
302 std::string preProcessSuffix = ".pre.bc";
303 // Get the existing module names, remove old extension, add preProcessSuffix
304 for (u32_t i = 0; i < moduleNameVec.size(); i++)
305 {
306 u32_t lastIndex = moduleNameVec[i].find_last_of(".");
307 std::string rawName = moduleNameVec[i].substr(0, lastIndex);
309 }
310
311 mset->dumpModulesToFile(preProcessSuffix);
312 preProcessed = true;
314}
static void releaseLLVMModuleSet()
Definition LLVMModule.h:138

◆ releaseLLVMModuleSet()

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

Definition at line 138 of file LLVMModule.h.

139 {
140 delete llvmModuleSet;
141 llvmModuleSet = nullptr;
142 }

◆ retSyms()

FunToIDMapTy & SVF::LLVMModuleSet::retSyms ( )
inline

Definition at line 274 of file LLVMModule.h.

275 {
276 return returnSymMap;
277 }

◆ setExtFuncAnnotations()

void LLVMModuleSet::setExtFuncAnnotations ( const Function fun,
const std::vector< std::string > &  funcAnnotations 
)

Definition at line 1496 of file LLVMModule.cpp.

1497{
1498 assert(fun && "Null SVFFunction* pointer");
1500}

◆ setFunExitBB()

void SVF::LLVMModuleSet::setFunExitBB ( const Function fun,
const BasicBlock bb 
)
inlineprivate

Definition at line 445 of file LLVMModule.h.

446 {
447 funToExitBB[fun] = bb;
448 }

◆ setFunRealDefFun()

void SVF::LLVMModuleSet::setFunRealDefFun ( const Function fun,
const Function realDefFun 
)
inlineprivate

Definition at line 450 of file LLVMModule.h.

451 {
452 funToRealDefFun[fun] = realDefFun;
453 }

◆ valSyms()

ValueToIDMapTy & SVF::LLVMModuleSet::valSyms ( )
inline

Definition at line 207 of file LLVMModule.h.

208 {
209 return valSymMap;
210 }

◆ varargSyms()

FunToIDMapTy & SVF::LLVMModuleSet::varargSyms ( )
inline

Definition at line 279 of file LLVMModule.h.

280 {
281 return varargSymMap;
282 }

Friends And Related Symbol Documentation

◆ ICFGBuilder

Definition at line 47 of file LLVMModule.h.

◆ SVFIRBuilder

Definition at line 46 of file LLVMModule.h.

◆ SymbolTableBuilder

Definition at line 48 of file LLVMModule.h.

Member Data Documentation

◆ CSToCallNodeMap

CSToCallNodeMapTy SVF::LLVMModuleSet::CSToCallNodeMap
private

map a callsite to its CallICFGNode

Definition at line 106 of file LLVMModule.h.

◆ CSToRetNodeMap

CSToRetNodeMapTy SVF::LLVMModuleSet::CSToRetNodeMap
private

map a callsite to its RetICFGNode

Definition at line 107 of file LLVMModule.h.

◆ ExtFun2Annotations

Fun2AnnoMap SVF::LLVMModuleSet::ExtFun2Annotations
private

Record annotations of function in extapi.bc.

Definition at line 91 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 89 of file LLVMModule.h.

◆ func2Annotations

Map<const Function*, std::vector<std::string> > SVF::LLVMModuleSet::func2Annotations
private

Definition at line 94 of file LLVMModule.h.

◆ funSet

FunctionSet SVF::LLVMModuleSet::funSet
private

Definition at line 119 of file LLVMModule.h.

◆ FunToDominatorTree

Map<const Function*, DominatorTree> SVF::LLVMModuleSet::FunToDominatorTree
private

Definition at line 112 of file LLVMModule.h.

◆ funToExitBB

FunToExitBBMap SVF::LLVMModuleSet::funToExitBB
private

Definition at line 120 of file LLVMModule.h.

◆ FunToFunEntryNodeMap

FunToFunEntryNodeMapTy SVF::LLVMModuleSet::FunToFunEntryNodeMap
private

map a function to its FunExitICFGNode

Definition at line 109 of file LLVMModule.h.

◆ FunToFunExitNodeMap

FunToFunExitNodeMapTy SVF::LLVMModuleSet::FunToFunExitNodeMap
private

map a function to its FunEntryICFGNode

Definition at line 110 of file LLVMModule.h.

◆ funToRealDefFun

FunToRealDefFunMap SVF::LLVMModuleSet::funToRealDefFun
private

Definition at line 121 of file LLVMModule.h.

◆ GlobalDefToRepMap

GlobalDefToRepMapTy SVF::LLVMModuleSet::GlobalDefToRepMap
private

Global definition to a rep definition map.

Definition at line 97 of file LLVMModule.h.

◆ InstToBlockNodeMap

InstToBlockNodeMapTy SVF::LLVMModuleSet::InstToBlockNodeMap
private

map a basic block to its ICFGNode

Definition at line 108 of file LLVMModule.h.

◆ LLVMBB2SVFBB

LLVMBB2SVFBBMap SVF::LLVMModuleSet::LLVMBB2SVFBB
private

Definition at line 100 of file LLVMModule.h.

◆ LLVMFun2FunObjVar

LLVMFun2FunObjVarMap SVF::LLVMModuleSet::LLVMFun2FunObjVar
private

Map an LLVM Function to an SVF Funobjvar.

Definition at line 99 of file LLVMModule.h.

◆ llvmModuleSet

LLVMModuleSet * LLVMModuleSet::llvmModuleSet = nullptr
staticprivate

Definition at line 81 of file LLVMModule.h.

◆ LLVMType2SVFType

LLVMType2SVFTypeMap SVF::LLVMModuleSet::LLVMType2SVFType
private

Definition at line 101 of file LLVMModule.h.

◆ modules

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

Definition at line 86 of file LLVMModule.h.

◆ objSymMap

ValueToIDMapTy SVF::LLVMModuleSet::objSymMap
private

map a obj reference to its sym id

Definition at line 115 of file LLVMModule.h.

◆ owned_ctx

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

Definition at line 84 of file LLVMModule.h.

◆ owned_modules

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

Definition at line 85 of file LLVMModule.h.

◆ preProcessed

bool LLVMModuleSet::preProcessed = false
staticprivate

Definition at line 82 of file LLVMModule.h.

◆ returnSymMap

FunToIDMapTy SVF::LLVMModuleSet::returnSymMap
private

return map

Definition at line 116 of file LLVMModule.h.

◆ SVFBaseNode2LLVMValue

SVFBaseNode2LLVMValueMap SVF::LLVMModuleSet::SVFBaseNode2LLVMValue
private

Definition at line 105 of file LLVMModule.h.

◆ svfir

SVFIR* SVF::LLVMModuleSet::svfir
private

Definition at line 83 of file LLVMModule.h.

◆ Type2TypeInfo

Type2TypeInfoMap SVF::LLVMModuleSet::Type2TypeInfo
private

Definition at line 102 of file LLVMModule.h.

◆ typeInference

ObjTypeInference* SVF::LLVMModuleSet::typeInference
private

Definition at line 103 of file LLVMModule.h.

◆ valSymMap

ValueToIDMapTy SVF::LLVMModuleSet::valSymMap
private

map a value to its sym id

Definition at line 114 of file LLVMModule.h.

◆ varargSymMap

FunToIDMapTy SVF::LLVMModuleSet::varargSymMap
private

vararg map

Definition at line 117 of file LLVMModule.h.


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