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

83{
84}
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 86 of file LLVMModule.cpp.

87{
88
89 delete typeInference;
90 typeInference = nullptr;
91
92}

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

490{
491 std::vector<const Function*> ctor_funcs;
492 std::vector<const Function*> dtor_funcs;
493 Function* orgMain = 0;
494 Module* mainMod = nullptr;
495
496 for (Module &mod : modules)
497 {
498 // Collect ctor and dtor functions
499 for (const GlobalVariable& global : mod.globals())
500 {
501 if (global.getName().equals(SVF_GLOBAL_CTORS) && global.hasInitializer())
502 {
504 }
505 else if (global.getName().equals(SVF_GLOBAL_DTORS) && global.hasInitializer())
506 {
508 }
509 }
510
511 // Find main function
512 for (auto &func : mod)
513 {
514 auto funName = func.getName();
515
516 assert(!funName.equals(SVF_MAIN_FUNC_NAME) && SVF_MAIN_FUNC_NAME " already defined");
517
518 if (funName.equals("main"))
519 {
520 orgMain = &func;
521 mainMod = &mod;
522 }
523 }
524 }
525
526 // Only create svf.main when the original main function is found, and also
527 // there are global constructor or destructor functions.
528 if (orgMain && getModuleNum() > 0 &&
529 (ctor_funcs.size() > 0 || dtor_funcs.size() > 0))
530 {
531 assert(mainMod && "Module with main function not found.");
532 Module& M = *mainMod;
533 // char **
534 Type* ptr = PointerType::getUnqual(M.getContext());
535 Type* i32 = IntegerType::getInt32Ty(M.getContext());
536 // define void @svf.main(i32, i8**, i8**)
537#if (LLVM_VERSION_MAJOR >= 9)
538 FunctionCallee svfmainFn = M.getOrInsertFunction(
540 Type::getVoidTy(M.getContext()),
541 i32,ptr,ptr
542 );
543 Function* svfmain = SVFUtil::dyn_cast<Function>(svfmainFn.getCallee());
544#else
545 Function* svfmain = SVFUtil::dyn_cast<Function>(M.getOrInsertFunction(
547 Type::getVoidTy(M.getContext()),
549 ));
550#endif
551 svfmain->setCallingConv(llvm::CallingConv::C);
552 BasicBlock* block = BasicBlock::Create(M.getContext(), "entry", svfmain);
554 // emit "call void @ctor()". ctor_funcs is sorted so the functions are
555 // emitted in the order of priority
556 for (auto& ctor : ctor_funcs)
557 {
558 auto target = M.getOrInsertFunction(
559 ctor->getName(),
560 Type::getVoidTy(M.getContext())
561 );
562 Builder.CreateCall(target);
563 }
564 // main() should be called after all ctor functions and before dtor
565 // functions.
566 Function::arg_iterator arg_it = svfmain->arg_begin();
567 Value* args[] = {arg_it, arg_it + 1, arg_it + 2};
568 size_t cnt = orgMain->arg_size();
569 assert(cnt <= 3 && "Too many arguments for main()");
570 Builder.CreateCall(orgMain, llvm::ArrayRef<Value*>(args, args + cnt));
571 // emit "call void @dtor()". dtor_funcs is sorted so the functions are
572 // emitted in the order of priority
573 for (auto& dtor : dtor_funcs)
574 {
575 auto target = M.getOrInsertFunction(dtor->getName(), Type::getVoidTy(M.getContext()));
576 Builder.CreateCall(target);
577 }
578 // return;
579 Builder.CreateRetVoid();
580 }
581}
#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: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::Module Module
Definition BasicTypes.h:84

◆ addSVFTypeInfo()

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

Create SVFTypes.

Definition at line 1265 of file LLVMModule.cpp.

1266{
1267 assert(LLVMType2SVFType.find(T) == LLVMType2SVFType.end() &&
1268 "SVFType has been added before");
1269
1270 // add SVFType's LLVM byte size iff T isSized(), otherwise byteSize is 1 (default value)
1271 u32_t byteSize = 1;
1272 if (T->isSized())
1273 {
1274 const llvm::DataLayout &DL = LLVMModuleSet::getLLVMModuleSet()->
1275 getMainLLVMModule()->getDataLayout();
1276 Type *mut_T = const_cast<Type *>(T);
1277 byteSize = DL.getTypeAllocSize(mut_T);
1278 }
1279
1281
1283 if (SVFUtil::isa<PointerType>(T))
1284 {
1285 svftype = new SVFPointerType(id, byteSize);
1286 }
1287 else if (const IntegerType* intT = SVFUtil::dyn_cast<IntegerType>(T))
1288 {
1289 auto svfIntT = new SVFIntegerType(id, byteSize);
1290 unsigned signWidth = intT->getBitWidth();
1291 assert(signWidth < INT16_MAX && "Integer width too big");
1292 svfIntT->setSignAndWidth(intT->getSignBit() ? -signWidth : signWidth);
1293 svftype = svfIntT;
1294 }
1295 else if (const FunctionType* ft = SVFUtil::dyn_cast<FunctionType>(T))
1296 {
1297 std::vector<const SVFType*> paramTypes;
1298 for (const auto& t: ft->params())
1299 {
1300 paramTypes.push_back(getSVFType(t));
1301 }
1302 svftype = new SVFFunctionType(id, getSVFType(ft->getReturnType()), paramTypes, ft->isVarArg());
1303 }
1304 else if (const StructType* st = SVFUtil::dyn_cast<StructType>(T))
1305 {
1306 std::vector<const SVFType*> fieldTypes;
1307
1308 for (const auto& t: st->elements())
1309 {
1310 fieldTypes.push_back(getSVFType(t));
1311 }
1312 auto svfst = new SVFStructType(id, fieldTypes, byteSize);
1313 if (st->hasName())
1314 svfst->setName(st->getName().str());
1315 svftype = svfst;
1316 }
1317 else if (const auto at = SVFUtil::dyn_cast<ArrayType>(T))
1318 {
1319 auto svfat = new SVFArrayType(id, byteSize);
1320 svfat->setNumOfElement(at->getNumElements());
1321 svfat->setTypeOfElement(getSVFType(at->getElementType()));
1322 svftype = svfat;
1323 }
1324 else
1325 {
1326 std::string buffer;
1327 auto ot = new SVFOtherType(id, T->isSingleValueType(), byteSize);
1328 llvm::raw_string_ostream(buffer) << *T;
1329 ot->setRepr(std::move(buffer));
1330 svftype = ot;
1331 }
1332
1335
1336 return svftype;
1337}
unsigned u32_t
Definition CommandLine.h:18
char * buffer
Definition cJSON.h:163
void addTypeInfo(const SVFType *ty)
Definition IRGraph.h:356
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:94
llvm::IntegerType IntegerType
Definition BasicTypes.h:97
llvm::FunctionType FunctionType
Definition BasicTypes.h:98

◆ addToSVFVar2LLVMValueMap()

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

Definition at line 1127 of file LLVMModule.cpp.

1129{
1131 svfBaseNode->setSourceLoc(LLVMUtil::getSourceLoc(val));
1132 svfBaseNode->setName(val->getName().str());
1133}
const std::string getSourceLoc(const Value *val)
Definition LLVMUtil.cpp:452

◆ build()

void LLVMModuleSet::build ( )
private

Definition at line 161 of file LLVMModule.cpp.

162{
163 if(preProcessed==false)
165
168
169 if (Options::SVFMain())
170 addSVFMain();
171
173
174}
static bool preProcessed
Definition LLVMModule.h:82
void createSVFDataStructure()
void prePassSchedule()
Invoke llvm passes to modify module.
void buildGlobalDefToRepMap()
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 651 of file LLVMModule.cpp.

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

◆ buildGlobalDefToRepMap()

void LLVMModuleSet::buildGlobalDefToRepMap ( )
private

Definition at line 981 of file LLVMModule.cpp.

982{
985 for (Module &mod : modules)
986 {
987 // Collect ctor and dtor functions
989 {
990 if (global.hasPrivateLinkage())
991 continue;
992 string name = global.getName().str();
993 if (name.empty())
994 continue;
995 nameToGlobalsMap[std::move(name)].insert(&global);
996 }
997 }
998
999 for (const auto& pair : nameToGlobalsMap)
1000 {
1001 const Set<GlobalVariable*> &globals = pair.second;
1002
1003 const auto repIt =
1004 std::find_if(globals.begin(), globals.end(),
1005 [](GlobalVariable* g)
1006 {
1007 return g->hasInitializer();
1008 });
1009 GlobalVariable* rep =
1010 repIt != globals.end()
1011 ? *repIt
1012 // When there is no initializer, just pick the first one.
1013 : (assert(!globals.empty() && "Empty global set"),
1014 *globals.begin());
1015
1016 for (const GlobalVariable* cur : globals)
1017 {
1018 GlobalDefToRepMap[cur] = rep;
1019 }
1020 }
1021}
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 123 of file LLVMModule.cpp.

124{
125 double startSVFModuleTime = SVFStat::getClk(true);
126
128
129 mset->loadModules(moduleNameVec); // Populates `modules`; can get context via `this->getContext()`
130 mset->loadExtAPIModules(); // Uses context from first module through `this->getContext()`
131
132 if (!moduleNameVec.empty())
133 {
135 }
136
137 mset->build();
138
139 double endSVFModuleTime = SVFStat::getClk(true);
142
143 mset->buildSymbolTable();
144}
#define TIMEINTERVAL
Definition SVFType.h:540
void setModuleIdentifier(const std::string &moduleIdentifier)
Definition SVFIR.h:217
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 108 of file LLVMModule.cpp.

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

◆ buildSymbolTable()

void LLVMModuleSet::buildSymbolTable ( ) const
private

building symbol table

Definition at line 146 of file LLVMModule.cpp.

147{
148 double startSymInfoTime = SVFStat::getClk(true);
150 {
152 DBOUT(DGENERAL, SVFUtil::outs() << SVFUtil::pasMsg("Building Symbol table ...\n"));
154 builder.buildMemModel();
155 }
156 double endSymInfoTime = SVFStat::getClk(true);
159}
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:512
#define DGENERAL
Definition SVFType.h:518
static bool pagReadFromTXT()
Definition SVFIR.h:207
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 1342 of file LLVMModule.cpp.

1343{
1344 u64_t totalElemNum = ty->getNumElements();
1345 const Type* elemTy = ty->getElementType();
1346 while (const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(elemTy))
1347 {
1348 totalElemNum *= aty->getNumElements();
1349 elemTy = aty->getElementType();
1350 }
1351
1354
1356 if (totalElemNum == 0)
1357 {
1358 stInfo->addFldWithType(0, elemSvfType, 0);
1359 stInfo->setNumOfFieldsAndElems(1, 1);
1360 stInfo->getFlattenFieldTypes().push_back(elemSvfType);
1361 stInfo->getFlattenElementTypes().push_back(elemSvfType);
1362 return stInfo;
1363 }
1364
1368 u32_t nfF = elemStInfo->getNumOfFlattenFields();
1369 u32_t nfE = elemStInfo->getNumOfFlattenElements();
1370 for (u32_t j = 0; j < nfF; j++)
1371 {
1372 const SVFType* fieldTy = elemStInfo->getFlattenFieldTypes()[j];
1373 stInfo->getFlattenFieldTypes().push_back(fieldTy);
1374 }
1375
1378 u32_t outArrayElemNum = ty->getNumElements();
1379 for (u32_t i = 0; i < outArrayElemNum; ++i)
1380 {
1381 auto idx = (i * nfE * totalElemNum) / outArrayElemNum;
1382 stInfo->addFldWithType(0, elemSvfType, idx);
1383 }
1384
1385 for (u32_t i = 0; i < totalElemNum; ++i)
1386 {
1387 for (u32_t j = 0; j < nfE; ++j)
1388 {
1389 const SVFType* et = elemStInfo->getFlattenElementTypes()[j];
1390 stInfo->getFlattenElementTypes().push_back(et);
1391 }
1392 }
1393
1394 assert(stInfo->getFlattenElementTypes().size() == nfE * totalElemNum &&
1395 "typeForArray size incorrect!!!");
1396 stInfo->setNumOfFieldsAndElems(nfF, nfE * totalElemNum);
1397
1398 return stInfo;
1399}
StInfo * collectTypeInfo(const Type *ty)
Collect a type info.
llvm::ArrayType ArrayType
Definition BasicTypes.h:95
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 583 of file LLVMModule.cpp.

584{
585 GlobalVariable *glob = mod->getGlobalVariable("llvm.global.annotations");
586 if (glob == nullptr || !glob->hasInitializer())
587 return;
588
589 ConstantArray *ca = SVFUtil::dyn_cast<ConstantArray>(glob->getInitializer());
590 if (ca == nullptr)
591 return;
592
593 for (unsigned i = 0; i < ca->getNumOperands(); ++i)
594 {
595 ConstantStruct *structAn = SVFUtil::dyn_cast<ConstantStruct>(ca->getOperand(i));
596 if (structAn == nullptr || structAn->getNumOperands() == 0)
597 continue;
598
599 // Check if the annotation is for a function
600 Function* fun = nullptr;
601 GlobalVariable *annotateStr = nullptr;
603 if (ConstantExpr *expr = SVFUtil::dyn_cast<ConstantExpr>(structAn->getOperand(0)))
604 {
605 if (expr->getOpcode() == Instruction::BitCast && SVFUtil::isa<Function>(expr->getOperand(0)))
606 fun = SVFUtil::cast<Function>(expr->getOperand(0));
607
608 ConstantExpr *note = SVFUtil::cast<ConstantExpr>(structAn->getOperand(1));
609 if (note->getOpcode() != Instruction::GetElementPtr)
610 continue;
611
612 annotateStr = SVFUtil::dyn_cast<GlobalVariable>(note->getOperand(0));
613 }
615 else
616 {
617 fun = SVFUtil::dyn_cast<Function>(structAn->getOperand(0));
618 annotateStr = SVFUtil::dyn_cast<GlobalVariable>(structAn->getOperand(1));
619 }
620
621 if (!fun || annotateStr == nullptr || !annotateStr->hasInitializer())
622 continue;;
623
624 ConstantDataSequential *data = SVFUtil::dyn_cast<ConstantDataSequential>(annotateStr->getInitializer());
625 if (data && data->isString())
626 {
627 std::string annotation = data->getAsString().str();
628 if (!annotation.empty())
629 ExtFun2Annotations[fun->getName().str()].push_back(annotation);
630 }
631 }
632}
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 1462 of file LLVMModule.cpp.

1463{
1465 StInfo* stInfo = new StInfo(1);
1467 stInfo->addFldWithType(0, svfType, 0);
1468
1469 stInfo->getFlattenFieldTypes().push_back(svfType);
1470 stInfo->getFlattenElementTypes().push_back(svfType);
1471 stInfo->setNumOfFieldsAndElems(1,1);
1472
1473 return stInfo;
1474}

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

1407{
1409 StInfo* stInfo = new StInfo(1);
1410
1411 // Number of fields after flattening the struct
1412 numFields = 0;
1413 // The offset when considering array stride info
1414 u32_t strideOffset = 0;
1415 for (const Type* elemTy : structTy->elements())
1416 {
1418 // offset with int_32 (s32_t) is large enough and won't overflow
1419 stInfo->addFldWithType(numFields, elemSvfTy, strideOffset);
1420
1421 if (SVFUtil::isa<StructType, ArrayType>(elemTy))
1422 {
1424 u32_t nfF = subStInfo->getNumOfFlattenFields();
1425 u32_t nfE = subStInfo->getNumOfFlattenElements();
1426 // Copy ST's info, whose element 0 is the size of ST itself.
1427 for (u32_t j = 0; j < nfF; ++j)
1428 {
1429 const SVFType* elemTy = subStInfo->getFlattenFieldTypes()[j];
1430 stInfo->getFlattenFieldTypes().push_back(elemTy);
1431 }
1432 numFields += nfF;
1433 strideOffset += nfE;
1434 for (u32_t tpj = 0; tpj < nfE; ++tpj)
1435 {
1436 const SVFType* ty = subStInfo->getFlattenElementTypes()[tpj];
1437 stInfo->getFlattenElementTypes().push_back(ty);
1438 }
1439
1440 }
1441 else
1442 {
1443 // Simple type
1444 numFields += 1;
1445 strideOffset += 1;
1446 stInfo->getFlattenFieldTypes().push_back(elemSvfTy);
1447 stInfo->getFlattenElementTypes().push_back(elemSvfTy);
1448 }
1449 }
1450
1451 assert(stInfo->getFlattenElementTypes().size() == strideOffset &&
1452 "typeForStruct size incorrect!");
1453 stInfo->setNumOfFieldsAndElems(numFields,strideOffset);
1454
1455 return stInfo;
1456}

◆ collectTypeInfo()

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

Collect a type info.

Definition at line 1233 of file LLVMModule.cpp.

1234{
1235 Type2TypeInfoMap::iterator tit = Type2TypeInfo.find(T);
1236 if (tit != Type2TypeInfo.end())
1237 {
1238 return tit->second;
1239 }
1240 // No such StInfo for T, create it now.
1241 StInfo* stInfo;
1242 if (const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(T))
1243 {
1245 }
1246 else if (const StructType* sty = SVFUtil::dyn_cast<StructType>(T))
1247 {
1248 u32_t nf;
1250 if (nf > svfir->maxStSize)
1251 {
1253 svfir->maxStSize = nf;
1254 }
1255 }
1256 else
1257 {
1259 }
1260 Type2TypeInfo.emplace(T, stInfo);
1262 return stInfo;
1263}
const SVFType * maxStruct
The struct type with the most fields.
Definition IRGraph.h:351
void addStInfo(StInfo *stInfo)
Definition IRGraph.h:363
u32_t maxStSize
The number of fields in max_struct.
Definition IRGraph.h:354
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 176 of file LLVMModule.cpp.

177{
180 // Functions need to be retrieved in the order of insertion
181 // candidateDefs is the vector for all used defined functions
182 // candidateDecls is the vector for all used declared functions
183 std::vector<const Function*> candidateDefs, candidateDecls;
184
185 for (Module& mod : modules)
186 {
188 for (Function& func : mod.functions())
189 {
190 if (func.isDeclaration())
191 {
192 candidateDecls.push_back(&func);
193 }
194 else
195 {
196 candidateDefs.push_back(&func);
197 }
198 }
199 }
200
201 for (const Function* func: candidateDefs)
202 {
204 }
205 for (const Function* func: candidateDecls)
206 {
208 }
209
210 // set function exit block
211 for (const auto& func: funSet)
212 {
213 for (Function::const_iterator bit = func->begin(), ebit = func->end(); bit != ebit; ++bit)
214 {
215 const BasicBlock* bb = &*bit;
217 if (succ_size(bb) == 0)
218 {
220 {
222 SVFUtil::isa<ReturnInst>(bb->back())) &&
223 "last inst must be return inst");
224 setFunExitBB(func, bb);
225 }
226 }
227 }
228 // For no return functions, we set the last block as exit BB
229 // This ensures that each function that has definition must have an exit BB
230 if (func->size() != 0 && !getFunExitBB(func))
231 {
233 SVFUtil::isa<ReturnInst>(&func->back().back())) &&
234 "last inst must be return inst");
235 setFunExitBB(func, &func->back());
236 }
237 }
238
239 // Store annotations of functions in extapi.bc
240 for (const auto& pair : ExtFun2Annotations)
241 {
242 const Function* fun = getFunction(pair.first);
243 setExtFuncAnnotations(fun, pair.second);
244 }
245
246}
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:192
static SVFType * svfI8Ty
8-bit int type
Definition SVFType.h:193
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 1024 of file LLVMModule.cpp.

1025{
1026 for (Module& mod : modules)
1027 {
1028 std::string moduleName = mod.getName().str();
1029 std::string OutputFilename;
1030 std::size_t pos = moduleName.rfind('.');
1031 if (pos != std::string::npos)
1032 OutputFilename = moduleName.substr(0, pos) + suffix;
1033 else
1034 OutputFilename = moduleName + suffix;
1035
1036 std::error_code EC;
1037 raw_fd_ostream OS(OutputFilename.c_str(), EC, llvm::sys::fs::OF_None);
1038
1039#if (LLVM_VERSION_MAJOR >= 7)
1041#else
1043#endif
1044
1045 OS.flush();
1046 }
1047}
llvm::raw_fd_ostream raw_fd_ostream
LLVM outputs.
Definition BasicTypes.h:264

◆ dumpSymTable()

void LLVMModuleSet::dumpSymTable ( )

Definition at line 1080 of file LLVMModule.cpp.

1081{
1083 for (ValueToIDMapTy::iterator iter = valSymMap.begin(); iter != valSymMap.end();
1084 ++iter)
1085 {
1086 const NodeID i = iter->second;
1087 idmap[i] = iter->first;
1088 }
1089 for (ValueToIDMapTy::iterator iter = objSymMap.begin(); iter != objSymMap.end();
1090 ++iter)
1091 {
1092 const NodeID i = iter->second;
1093 idmap[i] = iter->first;
1094 }
1095 for (FunToIDMapTy::iterator iter = retSyms().begin(); iter != retSyms().end();
1096 ++iter)
1097 {
1098 const NodeID i = iter->second;
1099 idmap[i] = iter->first;
1100 }
1101 for (FunToIDMapTy::iterator iter = varargSyms().begin(); iter != varargSyms().end();
1102 ++iter)
1103 {
1104 const NodeID i = iter->second;
1105 idmap[i] = iter->first;
1106 }
1107 SVFUtil::outs() << "{SymbolTableInfo \n";
1108
1109
1110
1111
1112 for (auto iter : idmap)
1113 {
1114 std::string str;
1115 llvm::raw_string_ostream rawstr(str);
1116 auto llvmVal = iter.second;
1117 if (llvmVal)
1118 rawstr << " " << *llvmVal << " ";
1119 else
1120 rawstr << " No llvmVal found";
1122 SVFUtil::outs() << iter.first << " " << rawstr.str() << "\n";
1123 }
1124 SVFUtil::outs() << "}\n";
1125}
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 1546 of file LLVMModule.cpp.

1547{
1548 std::string allocArg = getExtFuncAnnotation(F, "ALLOC_HEAP_ARG");
1549 assert(!allocArg.empty() && "Not an alloc call via argument or incorrect extern function annotation!");
1550
1551 std::string number;
1552 for (char c : allocArg)
1553 {
1554 if (isdigit(c))
1555 number.push_back(c);
1556 }
1557 assert(!number.empty() && "Incorrect naming convention for svf external functions(ALLOC_HEAP_ARG + number)?");
1558 return std::stoi(number);
1559}
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 1208 of file LLVMModule.cpp.

1209{
1210 assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
1211 assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
1212 CallICFGNode* node = getCallBlock(inst);
1213 assert (node!=nullptr && "no CallICFGNode for this instruction?");
1214 return node;
1215}
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:720

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

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

◆ getExtFuncAnnotation()

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

Definition at line 1495 of file LLVMModule.cpp.

1496{
1497 assert(fun && "Null Function* pointer");
1498 auto it = func2Annotations.find(fun);
1499 if (it != func2Annotations.end())
1500 {
1501 for (const std::string& annotation : it->second)
1502 if (annotation.find(funcAnnotation) != std::string::npos)
1504 }
1505 return "";
1506}
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 1508 of file LLVMModule.cpp.

1509{
1510 assert(fun && "Null Function* pointer");
1511 auto it = func2Annotations.find(fun);
1512 if (it != func2Annotations.end())
1513 return it->second;
1514 return func2Annotations[fun];
1515}

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

1136{
1137 Function* fun = nullptr;
1138
1139 for (u32_t i = 0; i < llvmModuleSet->getModuleNum(); ++i)
1140 {
1142 fun = mod->getFunction(name);
1143 if (fun)
1144 {
1145 return llvmModuleSet->getFunObjVar(fun);
1146 }
1147 }
1148 return nullptr;
1149}
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 1181 of file LLVMModule.cpp.

1182{
1183 ICFGNode* node;
1185 node = getCallICFGNode(inst);
1186 else if(LLVMUtil::isIntrinsicInst(inst))
1187 node = getIntraICFGNode(inst);
1188 else
1189 node = getIntraICFGNode(inst);
1190
1191 assert (node!=nullptr && "no ICFGNode for this instruction?");
1192 return node;
1193}
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 1226 of file LLVMModule.cpp.

1227{
1228 IntraICFGNode* node = getIntraBlock(inst);
1229 assert (node!=nullptr && "no IntraICFGNode for this instruction?");
1230 return node;
1231}
IntraICFGNode * getIntraBlock(const Instruction *inst)
Definition LLVMModule.h:500

◆ getLLVMGlobalFunctions()

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

Definition at line 401 of file LLVMModule.cpp.

402{
403 // This function is used to extract constructor and destructor functions
404 // sorted by their priority from @llvm.global_ctors or @llvm.global_dtors.
405 // For example, given following @llvm.global_ctors, the returning sorted
406 // function list should be [ctor3, ctor1, ctor2].
407 // ------------------------------------------------------------------
408 // ; Each struct in the array is {priority, function, associated data}
409 //
410 // @llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }]
411 // [{ i32, void ()*, i8* } { i32 1234, void ()* @ctor1.cpp, i8* null },
412 // { i32, void ()*, i8* } { i32 2345, void ()* @ctor2.cpp, i8* null },
413 // { i32, void ()*, i8* } { i32 345, void ()* @ctor3.cpp, i8* null }]
414 // ------------------------------------------------------------------
415 // TODO: According to LLVM language reference, if the third field is
416 // non-null, and points to a global variable or function, the initializer
417 // function will only run if the associated data from the current module is
418 // not discarded. However the associated data is currently ignored.
419
420
421 // This class is used for the priority queue that sorts the functions by
422 // their priority. Each object of this class stands for an item in the
423 // function array.
425 {
426 public:
428 const Function* func;
432 bool operator>(const LLVMGlobalFunction &other) const
433 {
434 if (priority != other.priority)
435 {
436 return priority > other.priority;
437 }
438 else
439 {
440 return func > other.func;
441 }
442 }
443 };
444
445 std::priority_queue<LLVMGlobalFunction, std::vector<LLVMGlobalFunction>,
447 queue;
448 std::vector<const Function* > result;
449
450 // The @llvm.global_ctors/dtors global variable is an array of struct. Each
451 // struct has three fields: {i32 priority, void ()* @ctor/dtor, i8* @data}.
452 // First get the array here.
454 SVFUtil::dyn_cast<ConstantArray>(global->getInitializer()))
455 {
456 // Get each struct in the array.
457 for (unsigned int i = 0; i < globalFuncArray->getNumOperands(); ++i)
458 {
459 if (
461 SVFUtil::dyn_cast<ConstantStruct>(
462 globalFuncArray->getOperand(i)))
463 {
464
465 // Extract priority and function from the struct
466 const ConstantInt* priority = SVFUtil::dyn_cast<ConstantInt>(
467 globalFuncItem->getOperand(0));
468 const Function* func = SVFUtil::dyn_cast<Function>(
469 globalFuncItem->getOperand(1));
470
471 if (priority && func)
472 {
474 func));
475 }
476 }
477 }
478 }
479
480 // Generate a sorted vector of functions from the priority queue.
481 while (!queue.empty())
482 {
483 result.push_back(queue.top().func);
484 queue.pop();
485 }
486 return result;
487}
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
Definition LLVMUtil.h:82
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 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 1152 of file LLVMModule.cpp.

1153{
1154 for(LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.begin(), eit = LLVMType2SVFType.end(); it!=eit; ++it)
1155 {
1156 if (it->second == T)
1157 return it->first;
1158 }
1159 assert(false && "can't find the corresponding LLVM Type");
1160 abort();
1161}

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

1071{
1072 if (const GlobalVariable* glob = SVFUtil::dyn_cast<GlobalVariable>(llvm_value))
1074 ValueToIDMapTy::const_iterator iter = objSymMap.find(llvm_value);
1075 assert(iter!=objSymMap.end() && "obj sym not found");
1076 return iter->second;
1077}
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 1217 of file LLVMModule.cpp.

1218{
1219 assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
1220 assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
1221 RetICFGNode* node = getRetBlock(inst);
1222 assert (node!=nullptr && "no RetICFGNode for this instruction?");
1223 return node;
1224}
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 1166 of file LLVMModule.cpp.

1167{
1168 assert(T && "SVFType should not be null");
1169 LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.find(T);
1170 if (it != LLVMType2SVFType.end())
1171 return it->second;
1172
1175 svfType->setTypeInfo(stinfo);
1176 return svfType;
1177}
SVFType * addSVFTypeInfo(const Type *t)
Create SVFTypes.

◆ getTypeInference()

ObjTypeInference * LLVMModuleSet::getTypeInference ( )

Definition at line 94 of file LLVMModule.cpp.

95{
96 return typeInference;
97}

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

1050{
1051 if (SVFUtil::isa<ConstantPointerNull>(llvm_value))
1052 return svfir->nullPtrSymID();
1053 else if (SVFUtil::isa<UndefValue>(llvm_value))
1054 return svfir->blkPtrSymID();
1055 else
1056 {
1057 ValueToIDMapTy::const_iterator iter = valSymMap.find(llvm_value);
1058 assert(iter!=valSymMap.end() &&"value sym not found");
1059 return iter->second;
1060 }
1061}
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 1482 of file LLVMModule.cpp.

1483{
1484 assert(fun && "Null SVFFunction* pointer");
1485 auto it = func2Annotations.find(fun);
1486 if (it != func2Annotations.end())
1487 {
1488 for (const std::string& annotation : it->second)
1489 if (annotation.find(funcAnnotation) != std::string::npos)
1490 return true;
1491 }
1492 return false;
1493}
#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 1195 of file LLVMModule.cpp.

1196{
1197 ICFGNode* node;
1199 node = getCallBlock(inst);
1200 else if(LLVMUtil::isIntrinsicInst(inst))
1201 node = getIntraBlock(inst);
1202 else
1203 node = getIntraBlock(inst);
1204
1205 return node != nullptr;
1206}

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

1063{
1064 if (SVFUtil::isa<ConstantPointerNull, UndefValue>(val))
1065 return true;
1066 else
1067 return (valSymMap.find(val) != valSymMap.end());
1068}

◆ is_alloc()

bool LLVMModuleSet::is_alloc ( const Function F)

Definition at line 1529 of file LLVMModule.cpp.

1530{
1531 return F && hasExtFuncAnnotation(F, "ALLOC_HEAP_RET");
1532}
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 1540 of file LLVMModule.cpp.

1541{
1542 return F && hasExtFuncAnnotation(F, "ALLOC_STACK_RET");
1543}

◆ is_arg_alloc()

bool LLVMModuleSet::is_arg_alloc ( const Function F)

Definition at line 1535 of file LLVMModule.cpp.

1536{
1537 return F && hasExtFuncAnnotation(F, "ALLOC_HEAP_ARG");
1538}

◆ is_ext()

bool LLVMModuleSet::is_ext ( const Function F)

Definition at line 1570 of file LLVMModule.cpp.

1571{
1572 assert(F && "Null SVFFunction* pointer");
1573 if (F->isDeclaration() || F->isIntrinsic())
1574 return true;
1575 else if (hasExtFuncAnnotation(F, "OVERWRITE") && getExtFuncAnnotations(F).size() == 1)
1576 return false;
1577 else
1578 return !getExtFuncAnnotations(F).empty();
1579}
const std::vector< std::string > & getExtFuncAnnotations(const Function *fun)

◆ is_memcpy()

bool LLVMModuleSet::is_memcpy ( const Function F)

Definition at line 1517 of file LLVMModule.cpp.

1518{
1519 return F &&
1520 (hasExtFuncAnnotation(F, "MEMCPY") || hasExtFuncAnnotation(F, "STRCPY")
1521 || hasExtFuncAnnotation(F, "STRCAT"));
1522}

◆ is_memset()

bool LLVMModuleSet::is_memset ( const Function F)

Definition at line 1524 of file LLVMModule.cpp.

1525{
1526 return F && hasExtFuncAnnotation(F, "MEMSET");
1527}

◆ is_realloc()

bool LLVMModuleSet::is_realloc ( const Function F)

Definition at line 1562 of file LLVMModule.cpp.

1563{
1564 return F && hasExtFuncAnnotation(F, "REALLOC_HEAP_RET");
1565}

◆ loadExtAPIModules()

void LLVMModuleSet::loadExtAPIModules ( )
private

Definition at line 362 of file LLVMModule.cpp.

363{
364 // This function loads the ExtAPI bitcode file as an LLVM module. Note that it is important that
365 // the same LLVMContext object is used to load this bitcode file as is used by the other modules
366 // being analysed.
367 // When the modules are loaded from bitcode files (i.e. passing filenames to files containing
368 // LLVM IR to `buildSVFModule({file1.bc, file2.bc, ...})) the context is created while loading
369 // the modules in `loadModules()`, which populates this->modules and this->owned_modules.
370 // If, however, an LLVM Module object is passed to `buildSVFModule` (e.g. from an LLVM pass),
371 // the context should be retrieved from the module itself (note that the garbage collection from
372 // `std::unique_ptr<LLVMContext> LLVMModuleSet::owned_ctx` should be avoided in this case). This
373 // function populates only this->modules.
374 // In both cases, fetching the context from the main LLVM module (through `getContext`) works
375 assert(!empty() && "LLVMModuleSet contains no modules; cannot load ExtAPI module without LLVMContext!");
376
377 // Load external API module (extapi.bc)
378 if (!ExtAPI::getExtAPI()->getExtBcPath().empty())
379 {
382 {
383 SVFUtil::errs() << "not an external IR file: " << extModuleName << std::endl;
384 abort();
385 }
387 std::unique_ptr<Module> mod = parseIRFile(extModuleName, Err, getContext());
388 if (mod == nullptr)
389 {
390 SVFUtil::errs() << "load external module: " << extModuleName << "failed!!\n\n";
391 Err.print("SVFModuleLoader", llvm::errs());
392 abort();
393 }
394 // The module of extapi.bc needs to be inserted before applications modules, like std::vector<std::reference_wrapper<Module>> modules{extapi_module, app_module}.
395 // Otherwise, when overwriting the app function with SVF extern function, the corresponding SVFFunction of the extern function will not be found.
396 modules.insert(modules.begin(), *mod);
397 owned_modules.insert(owned_modules.begin(),std::move(mod));
398 }
399}
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:90

◆ loadModules()

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

Definition at line 296 of file LLVMModule.cpp.

297{
298
299 // We read SVFIR from LLVM IR
301 {
302 if(moduleNameVec.empty())
303 {
304 SVFUtil::outs() << "no LLVM bc file is found!\n";
305 exit(0);
306 }
307 //assert(!moduleNameVec.empty() && "no LLVM bc file is found!");
308 }
309 // We read SVFIR from a user-defined txt instead of parsing SVFIR from LLVM IR
310 else
311 {
313 }
314 //
315 // LLVMContext objects separate global LLVM settings (from which e.g. types are
316 // derived); multiple LLVMContext objects can coexist and each context can "own"
317 // multiple modules (modules can only have one context). Mixing contexts can lead
318 // to unintended inequalities, such as the following:
319 //
320 // ------------------------------------------------------------------
321 // LLVMContext ctxa,ctxb;
322 // IntegerType * t1 = IntegerType::get(ctxa,32);
323 // IntegerType * t2 = IntegerType::get(ctxa,32);
324 // assert(t1 == t2);
325 // IntegerType * t3 = IntegerType::get(ctxb,32);
326 // IntegerType * t4 = IntegerType::get(ctxb,32);
327 // assert(t3 == t4);
328 // assert(t1 != t3);
329 // ------------------------------------------------------------------
330 //
331 // When loading bytecode files, SVF will use the same LLVMContext object for all
332 // modules (i.e. the context owns all loaded modules). This applies to ExtAPI as
333 // well, which *must* be loaded using the same LLVMContext object. Hence, when
334 // loading modules from bitcode files, a new LLVMContext is created (using a
335 // `std::unique_ptr<LLVMContext>` type to ensure automatic garbage collection).
336 //
337 // This garbage collection should be avoided when building an SVF module from an LLVM
338 // module instance; see the comment(s) in `buildSVFModule` and `loadExtAPIModules()`
339
340 owned_ctx = std::make_unique<LLVMContext>();
341 for (const std::string& moduleName : moduleNameVec)
342 {
343 if (!LLVMUtil::isIRFile(moduleName))
344 {
345 SVFUtil::errs() << "not an IR file: " << moduleName << std::endl;
346 abort();
347 }
348
350 std::unique_ptr<Module> mod = parseIRFile(moduleName, Err, *owned_ctx);
351 if (mod == nullptr)
352 {
353 SVFUtil::errs() << "load module: " << moduleName << "failed!!\n\n";
354 Err.print("SVFModuleLoader", llvm::errs());
355 abort();
356 }
357 modules.emplace_back(*mod);
358 owned_modules.emplace_back(std::move(mod));
359 }
360}
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:212

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

252{
254 std::unique_ptr<BreakConstantGEPs> p1 = std::make_unique<BreakConstantGEPs>();
255 for (Module &M : getLLVMModules())
256 {
257 p1->runOnModule(M);
258 }
259
261 std::unique_ptr<UnifyFunctionExitNodes> p2 =
262 std::make_unique<UnifyFunctionExitNodes>();
263 for (Module &M : getLLVMModules())
264 {
265 for (auto F = M.begin(), E = M.end(); F != E; ++F)
266 {
267 Function &fun = *F;
268 if (fun.isDeclaration())
269 continue;
270 p2->runOnFunction(fun);
271 }
272 }
273}
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 275 of file LLVMModule.cpp.

276{
278 mset->loadModules(moduleNameVec);
279 mset->loadExtAPIModules();
280 mset->prePassSchedule();
281
282 std::string preProcessSuffix = ".pre.bc";
283 // Get the existing module names, remove old extension, add preProcessSuffix
284 for (u32_t i = 0; i < moduleNameVec.size(); i++)
285 {
286 u32_t lastIndex = moduleNameVec[i].find_last_of(".");
287 std::string rawName = moduleNameVec[i].substr(0, lastIndex);
289 }
290
291 mset->dumpModulesToFile(preProcessSuffix);
292 preProcessed = true;
294}
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 1476 of file LLVMModule.cpp.

1477{
1478 assert(fun && "Null SVFFunction* pointer");
1480}

◆ 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: