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 42 of file LLVMModule.h.

Member Typedef Documentation

◆ CSToCallNodeMapTy

Definition at line 62 of file LLVMModule.h.

◆ CSToRetNodeMapTy

Definition at line 63 of file LLVMModule.h.

◆ Fun2AnnoMap

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

Definition at line 60 of file LLVMModule.h.

◆ FunctionSet

Definition at line 74 of file LLVMModule.h.

◆ FunctionSetType

Definition at line 50 of file LLVMModule.h.

◆ FunDeclToDefMapTy

Definition at line 51 of file LLVMModule.h.

◆ FunDefToDeclsMapTy

Definition at line 52 of file LLVMModule.h.

◆ FunToExitBBMap

Definition at line 75 of file LLVMModule.h.

◆ FunToFunEntryNodeMapTy

Definition at line 65 of file LLVMModule.h.

◆ FunToFunExitNodeMapTy

Definition at line 66 of file LLVMModule.h.

◆ FunToIDMapTy

Definition at line 72 of file LLVMModule.h.

◆ FunToRealDefFunMap

Definition at line 76 of file LLVMModule.h.

◆ GlobalDefToRepMapTy

Definition at line 53 of file LLVMModule.h.

◆ InstToBlockNodeMapTy

Definition at line 64 of file LLVMModule.h.

◆ LLVMBB2SVFBBMap

Definition at line 56 of file LLVMModule.h.

◆ LLVMFun2FunObjVarMap

Definition at line 55 of file LLVMModule.h.

◆ LLVMType2SVFTypeMap

Definition at line 58 of file LLVMModule.h.

◆ SVFBaseNode2LLVMValueMap

Definition at line 57 of file LLVMModule.h.

◆ Type2TypeInfoMap

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

Constructor & Destructor Documentation

◆ LLVMModuleSet()

LLVMModuleSet::LLVMModuleSet ( )
private

Constructor.

Definition at line 79 of file LLVMModule.cpp.

81{
82}
ObjTypeInference * typeInference
Definition LLVMModule.h:101
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 84 of file LLVMModule.cpp.

85{
86
87 delete typeInference;
88 typeInference = nullptr;
89
90}

Member Function Documentation

◆ addBasicBlock()

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

Definition at line 230 of file LLVMModule.h.

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

◆ addFunctionSet()

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

Definition at line 438 of file LLVMModule.h.

439 {
440 funSet.push_back(svfFunc);
441 }
FunctionSet funSet
Definition LLVMModule.h:117

◆ addInstructionMap() [1/3]

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

Definition at line 237 of file LLVMModule.h.

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

◆ addInstructionMap() [2/3]

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

Definition at line 247 of file LLVMModule.h.

248 {
251 }
InstToBlockNodeMapTy InstToBlockNodeMap
map a basic block to its ICFGNode
Definition LLVMModule.h:106

◆ addInstructionMap() [3/3]

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

Definition at line 242 of file LLVMModule.h.

243 {
244 CSToRetNodeMap[inst] = svfInst;
246 }
CSToRetNodeMapTy CSToRetNodeMap
map a callsite to its RetICFGNode
Definition LLVMModule.h:105

◆ addSVFMain()

void LLVMModuleSet::addSVFMain ( )
private

Definition at line 487 of file LLVMModule.cpp.

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

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

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

◆ build()

void LLVMModuleSet::build ( )
private

Definition at line 159 of file LLVMModule.cpp.

160{
161 if(preProcessed==false)
163
166
167 if (Options::SVFMain())
168 addSVFMain();
169
171
172}
static bool preProcessed
Definition LLVMModule.h:80
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 649 of file LLVMModule.cpp.

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

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

◆ buildSVFModule() [1/2]

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

Definition at line 121 of file LLVMModule.cpp.

122{
123 double startSVFModuleTime = SVFStat::getClk(true);
124
126
127 mset->loadModules(moduleNameVec); // Populates `modules`; can get context via `this->getContext()`
128 mset->loadExtAPIModules(); // Uses context from first module through `this->getContext()`
129
130 if (!moduleNameVec.empty())
131 {
133 }
134
135 mset->build();
136
137 double endSVFModuleTime = SVFStat::getClk(true);
140
141 mset->buildSymbolTable();
142}
#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 106 of file LLVMModule.cpp.

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

◆ buildSymbolTable()

void LLVMModuleSet::buildSymbolTable ( ) const
private

building symbol table

Definition at line 144 of file LLVMModule.cpp.

145{
146 double startSymInfoTime = SVFStat::getClk(true);
148 {
150 DBOUT(DGENERAL, SVFUtil::outs() << SVFUtil::pasMsg("Building Symbol table ...\n"));
152 builder.buildMemModel();
153 }
154 double endSymInfoTime = SVFStat::getClk(true);
157}
#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 1340 of file LLVMModule.cpp.

1341{
1342 u64_t totalElemNum = ty->getNumElements();
1343 const Type* elemTy = ty->getElementType();
1344 while (const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(elemTy))
1345 {
1346 totalElemNum *= aty->getNumElements();
1347 elemTy = aty->getElementType();
1348 }
1349
1352
1354 if (totalElemNum == 0)
1355 {
1356 stInfo->addFldWithType(0, elemSvfType, 0);
1357 stInfo->setNumOfFieldsAndElems(1, 1);
1358 stInfo->getFlattenFieldTypes().push_back(elemSvfType);
1359 stInfo->getFlattenElementTypes().push_back(elemSvfType);
1360 return stInfo;
1361 }
1362
1366 u32_t nfF = elemStInfo->getNumOfFlattenFields();
1367 u32_t nfE = elemStInfo->getNumOfFlattenElements();
1368 for (u32_t j = 0; j < nfF; j++)
1369 {
1370 const SVFType* fieldTy = elemStInfo->getFlattenFieldTypes()[j];
1371 stInfo->getFlattenFieldTypes().push_back(fieldTy);
1372 }
1373
1376 u32_t outArrayElemNum = ty->getNumElements();
1377 for (u32_t i = 0; i < outArrayElemNum; ++i)
1378 {
1379 auto idx = (i * nfE * totalElemNum) / outArrayElemNum;
1380 stInfo->addFldWithType(0, elemSvfType, idx);
1381 }
1382
1383 for (u32_t i = 0; i < totalElemNum; ++i)
1384 {
1385 for (u32_t j = 0; j < nfE; ++j)
1386 {
1387 const SVFType* et = elemStInfo->getFlattenElementTypes()[j];
1388 stInfo->getFlattenElementTypes().push_back(et);
1389 }
1390 }
1391
1392 assert(stInfo->getFlattenElementTypes().size() == nfE * totalElemNum &&
1393 "typeForArray size incorrect!!!");
1394 stInfo->setNumOfFieldsAndElems(nfF, nfE * totalElemNum);
1395
1396 return stInfo;
1397}
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 581 of file LLVMModule.cpp.

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

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

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

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

◆ collectTypeInfo()

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

Collect a type info.

Definition at line 1231 of file LLVMModule.cpp.

1232{
1233 Type2TypeInfoMap::iterator tit = Type2TypeInfo.find(T);
1234 if (tit != Type2TypeInfo.end())
1235 {
1236 return tit->second;
1237 }
1238 // No such StInfo for T, create it now.
1239 StInfo* stInfo;
1240 if (const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(T))
1241 {
1243 }
1244 else if (const StructType* sty = SVFUtil::dyn_cast<StructType>(T))
1245 {
1246 u32_t nf;
1248 if (nf > svfir->maxStSize)
1249 {
1251 svfir->maxStSize = nf;
1252 }
1253 }
1254 else
1255 {
1257 }
1258 Type2TypeInfo.emplace(T, stInfo);
1260 return stInfo;
1261}
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:100

◆ createSVFDataStructure()

void LLVMModuleSet::createSVFDataStructure ( )
private

Function

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

Definition at line 174 of file LLVMModule.cpp.

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

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

◆ dumpSymTable()

void LLVMModuleSet::dumpSymTable ( )

Definition at line 1078 of file LLVMModule.cpp.

1079{
1081 for (ValueToIDMapTy::iterator iter = valSymMap.begin(); iter != valSymMap.end();
1082 ++iter)
1083 {
1084 const NodeID i = iter->second;
1085 idmap[i] = iter->first;
1086 }
1087 for (ValueToIDMapTy::iterator iter = objSymMap.begin(); iter != objSymMap.end();
1088 ++iter)
1089 {
1090 const NodeID i = iter->second;
1091 idmap[i] = iter->first;
1092 }
1093 for (FunToIDMapTy::iterator iter = retSyms().begin(); iter != retSyms().end();
1094 ++iter)
1095 {
1096 const NodeID i = iter->second;
1097 idmap[i] = iter->first;
1098 }
1099 for (FunToIDMapTy::iterator iter = varargSyms().begin(); iter != varargSyms().end();
1100 ++iter)
1101 {
1102 const NodeID i = iter->second;
1103 idmap[i] = iter->first;
1104 }
1105 SVFUtil::outs() << "{SymbolTableInfo \n";
1106
1107
1108
1109
1110 for (auto iter : idmap)
1111 {
1112 std::string str;
1113 llvm::raw_string_ostream rawstr(str);
1114 auto llvmVal = iter.second;
1115 if (llvmVal)
1116 rawstr << " " << *llvmVal << " ";
1117 else
1118 rawstr << " No llvmVal found";
1120 SVFUtil::outs() << iter.first << " " << rawstr.str() << "\n";
1121 }
1122 SVFUtil::outs() << "}\n";
1123}
FunToIDMapTy & retSyms()
Definition LLVMModule.h:272
ValueToIDMapTy valSymMap
map a value to its sym id
Definition LLVMModule.h:112
ValueToIDMapTy objSymMap
map a obj reference to its sym id
Definition LLVMModule.h:113
FunToIDMapTy & varargSyms()
Definition LLVMModule.h:277
u32_t NodeID
Definition GeneralType.h:56

◆ empty()

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

Definition at line 385 of file LLVMModule.h.

386 {
387 return getModuleNum() == 0;
388 }

◆ get_alloc_arg_pos()

s32_t LLVMModuleSet::get_alloc_arg_pos ( const Function F)

Definition at line 1544 of file LLVMModule.cpp.

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

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

◆ getCallICFGNode()

CallICFGNode * LLVMModuleSet::getCallICFGNode ( const Instruction cs)

get a call node

Definition at line 1206 of file LLVMModule.cpp.

1207{
1208 assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
1209 assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
1210 CallICFGNode* node = getCallBlock(inst);
1211 assert (node!=nullptr && "no CallICFGNode for this instruction?");
1212 return node;
1213}
CallICFGNode * getCallBlock(const Instruction *cs)
Get/Add a call node.
Definition LLVMModule.h:481
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 379 of file LLVMModule.h.

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

◆ getDomTree()

DominatorTree & LLVMModuleSet::getDomTree ( const Function fun)

Definition at line 97 of file LLVMModule.cpp.

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

◆ getExtFuncAnnotation()

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

Definition at line 1493 of file LLVMModule.cpp.

1494{
1495 assert(fun && "Null Function* pointer");
1496 auto it = func2Annotations.find(fun);
1497 if (it != func2Annotations.end())
1498 {
1499 for (const std::string& annotation : it->second)
1500 if (annotation.find(funcAnnotation) != std::string::npos)
1502 }
1503 return "";
1504}
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:92

◆ getExtFuncAnnotations()

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

Definition at line 1506 of file LLVMModule.cpp.

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

◆ getFunction()

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

Get the corresponding Function based on its name.

Definition at line 304 of file LLVMModule.h.

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

◆ getFunctionSet()

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

Definition at line 190 of file LLVMModule.h.

191 {
192 return funSet;
193 }

◆ getFunEntryBlock()

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

Get/Add a function entry node.

Definition at line 507 of file LLVMModule.h.

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

◆ getFunEntryICFGNode()

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

Add a function entry node.

Definition at line 335 of file LLVMModule.h.

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

◆ getFunExitBB()

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

Definition at line 176 of file LLVMModule.h.

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

◆ getFunExitBlock()

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

Get/Add a function exit node.

Definition at line 516 of file LLVMModule.h.

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

◆ getFunExitICFGNode()

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

Add a function exit node.

Definition at line 342 of file LLVMModule.h.

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

◆ getFunObjVar() [1/2]

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

Definition at line 265 of file LLVMModule.h.

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

◆ getFunObjVar() [2/2]

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

Get the corresponding Function based on its name.

Definition at line 1133 of file LLVMModule.cpp.

1134{
1135 Function* fun = nullptr;
1136
1137 for (u32_t i = 0; i < llvmModuleSet->getModuleNum(); ++i)
1138 {
1140 fun = mod->getFunction(name);
1141 if (fun)
1142 {
1143 return llvmModuleSet->getFunObjVar(fun);
1144 }
1145 }
1146 return nullptr;
1147}
const FunObjVar * getFunObjVar(const Function *fun) const
Definition LLVMModule.h:265

◆ getGlobalRep()

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

Definition at line 357 of file LLVMModule.h.

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

◆ getICFGNode()

ICFGNode * LLVMModuleSet::getICFGNode ( const Instruction inst)

Get a basic block ICFGNode.

Definition at line 1179 of file LLVMModule.cpp.

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

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

◆ getIntraICFGNode()

IntraICFGNode * LLVMModuleSet::getIntraICFGNode ( const Instruction inst)

get a intra node

Definition at line 1224 of file LLVMModule.cpp.

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

◆ getLLVMGlobalFunctions()

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

Definition at line 399 of file LLVMModule.cpp.

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

156 {
157 return modules;
158 }

◆ getLLVMModuleSet()

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

Definition at line 129 of file LLVMModule.h.

130 {
131 if (!llvmModuleSet)
133 return llvmModuleSet;
134 }
LLVMModuleSet()
Constructor.

◆ getLLVMType()

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

Get LLVM Type.

Definition at line 1150 of file LLVMModule.cpp.

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

◆ getLLVMValue()

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

Definition at line 258 of file LLVMModule.h.

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

◆ getMainLLVMModule()

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

Definition at line 364 of file LLVMModule.h.

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

◆ getModule()

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

Definition at line 160 of file LLVMModule.h.

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

◆ getModuleNum()

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

Definition at line 150 of file LLVMModule.h.

151 {
152 return modules.size();
153 }

◆ getModuleRef()

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

Definition at line 165 of file LLVMModule.h.

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

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

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

201 {
202 return objSymMap.size();
203 }

◆ getRealDefFun()

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

Definition at line 183 of file LLVMModule.h.

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

◆ getRetBlock()

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

Get/Add a return node.

Definition at line 490 of file LLVMModule.h.

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

◆ getRetICFGNode()

RetICFGNode * LLVMModuleSet::getRetICFGNode ( const Instruction cs)

get a return node

Definition at line 1215 of file LLVMModule.cpp.

1216{
1217 assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
1218 assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
1219 RetICFGNode* node = getRetBlock(inst);
1220 assert (node!=nullptr && "no RetICFGNode for this instruction?");
1221 return node;
1222}
RetICFGNode * getRetBlock(const Instruction *cs)
Get/Add a return node.
Definition LLVMModule.h:490

◆ getReturnNode()

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

Definition at line 282 of file LLVMModule.h.

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

◆ getSVFBasicBlock()

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

Definition at line 296 of file LLVMModule.h.

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

◆ getSVFType()

SVFType * LLVMModuleSet::getSVFType ( const Type T)

Get or create SVFType and typeinfo.

Get or create SVFType and typeinfo

Definition at line 1164 of file LLVMModule.cpp.

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

◆ getTypeInference()

ObjTypeInference * LLVMModuleSet::getTypeInference ( )

Definition at line 92 of file LLVMModule.cpp.

93{
94 return typeInference;
95}

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

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

196 {
197 return valSymMap.size();
198 }

◆ getVarargNode()

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

Definition at line 289 of file LLVMModule.h.

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

◆ has_static()

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

◆ hasExtFuncAnnotation()

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

Definition at line 1480 of file LLVMModule.cpp.

1481{
1482 assert(fun && "Null SVFFunction* pointer");
1483 auto it = func2Annotations.find(fun);
1484 if (it != func2Annotations.end())
1485 {
1486 for (const std::string& annotation : it->second)
1487 if (annotation.find(funcAnnotation) != std::string::npos)
1488 return true;
1489 }
1490 return false;
1491}
#define true
Definition cJSON.cpp:65

◆ hasGlobalRep()

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

Global to rep.

Definition at line 351 of file LLVMModule.h.

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

◆ hasICFGNode()

bool LLVMModuleSet::hasICFGNode ( const Instruction inst)

Definition at line 1193 of file LLVMModule.cpp.

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

◆ hasLLVMValue()

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

Definition at line 253 of file LLVMModule.h.

254 {
255 return SVFBaseNode2LLVMValue.find(value) != SVFBaseNode2LLVMValue.end();
256 }

◆ hasValueNode()

bool LLVMModuleSet::hasValueNode ( const Value V)

Definition at line 1060 of file LLVMModule.cpp.

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

◆ is_alloc()

bool LLVMModuleSet::is_alloc ( const Function F)

Definition at line 1527 of file LLVMModule.cpp.

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

1539{
1540 return F && hasExtFuncAnnotation(F, "ALLOC_STACK_RET");
1541}

◆ is_arg_alloc()

bool LLVMModuleSet::is_arg_alloc ( const Function F)

Definition at line 1533 of file LLVMModule.cpp.

1534{
1535 return F && hasExtFuncAnnotation(F, "ALLOC_HEAP_ARG");
1536}

◆ is_ext()

bool LLVMModuleSet::is_ext ( const Function F)

Definition at line 1568 of file LLVMModule.cpp.

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

◆ is_memcpy()

bool LLVMModuleSet::is_memcpy ( const Function F)

Definition at line 1515 of file LLVMModule.cpp.

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

◆ is_memset()

bool LLVMModuleSet::is_memset ( const Function F)

Definition at line 1522 of file LLVMModule.cpp.

1523{
1524 return F && hasExtFuncAnnotation(F, "MEMSET");
1525}

◆ is_realloc()

bool LLVMModuleSet::is_realloc ( const Function F)

Definition at line 1560 of file LLVMModule.cpp.

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

◆ loadExtAPIModules()

void LLVMModuleSet::loadExtAPIModules ( )
private

Definition at line 360 of file LLVMModule.cpp.

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

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

211 {
212 return objSymMap;
213 }

◆ prePassSchedule()

void LLVMModuleSet::prePassSchedule ( )
private

Invoke llvm passes to modify module.

Invoke llvm passes to modify module

BreakConstantGEPs Pass

MergeFunctionRets Pass

Definition at line 249 of file LLVMModule.cpp.

250{
252 std::unique_ptr<BreakConstantGEPs> p1 = std::make_unique<BreakConstantGEPs>();
253 for (Module &M : getLLVMModules())
254 {
255 p1->runOnModule(M);
256 }
257
259 std::unique_ptr<UnifyFunctionExitNodes> p2 =
260 std::make_unique<UnifyFunctionExitNodes>();
261 for (Module &M : getLLVMModules())
262 {
263 for (auto F = M.begin(), E = M.end(); F != E; ++F)
264 {
265 Function &fun = *F;
266 if (fun.isDeclaration())
267 continue;
268 p2->runOnFunction(fun);
269 }
270 }
271}
const std::vector< std::reference_wrapper< Module > > & getLLVMModules() const
Definition LLVMModule.h:155

◆ preProcessBCs()

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

Definition at line 273 of file LLVMModule.cpp.

274{
276 mset->loadModules(moduleNameVec);
277 mset->loadExtAPIModules();
278 mset->prePassSchedule();
279
280 std::string preProcessSuffix = ".pre.bc";
281 // Get the existing module names, remove old extension, add preProcessSuffix
282 for (u32_t i = 0; i < moduleNameVec.size(); i++)
283 {
284 u32_t lastIndex = moduleNameVec[i].find_last_of(".");
285 std::string rawName = moduleNameVec[i].substr(0, lastIndex);
287 }
288
289 mset->dumpModulesToFile(preProcessSuffix);
290 preProcessed = true;
292}
static void releaseLLVMModuleSet()
Definition LLVMModule.h:136

◆ releaseLLVMModuleSet()

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

Definition at line 136 of file LLVMModule.h.

137 {
138 delete llvmModuleSet;
139 llvmModuleSet = nullptr;
140 }

◆ retSyms()

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

Definition at line 272 of file LLVMModule.h.

273 {
274 return returnSymMap;
275 }

◆ setExtFuncAnnotations()

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

Definition at line 1474 of file LLVMModule.cpp.

1475{
1476 assert(fun && "Null SVFFunction* pointer");
1478}

◆ setFunExitBB()

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

Definition at line 443 of file LLVMModule.h.

444 {
445 funToExitBB[fun] = bb;
446 }

◆ setFunRealDefFun()

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

Definition at line 448 of file LLVMModule.h.

449 {
450 funToRealDefFun[fun] = realDefFun;
451 }

◆ valSyms()

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

Definition at line 205 of file LLVMModule.h.

206 {
207 return valSymMap;
208 }

◆ varargSyms()

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

Definition at line 277 of file LLVMModule.h.

278 {
279 return varargSymMap;
280 }

Friends And Related Symbol Documentation

◆ ICFGBuilder

Definition at line 45 of file LLVMModule.h.

◆ SVFIRBuilder

Definition at line 44 of file LLVMModule.h.

◆ SymbolTableBuilder

Definition at line 46 of file LLVMModule.h.

Member Data Documentation

◆ CSToCallNodeMap

CSToCallNodeMapTy SVF::LLVMModuleSet::CSToCallNodeMap
private

map a callsite to its CallICFGNode

Definition at line 104 of file LLVMModule.h.

◆ CSToRetNodeMap

CSToRetNodeMapTy SVF::LLVMModuleSet::CSToRetNodeMap
private

map a callsite to its RetICFGNode

Definition at line 105 of file LLVMModule.h.

◆ ExtFun2Annotations

Fun2AnnoMap SVF::LLVMModuleSet::ExtFun2Annotations
private

Record annotations of function in extapi.bc.

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

◆ func2Annotations

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

Definition at line 92 of file LLVMModule.h.

◆ funSet

FunctionSet SVF::LLVMModuleSet::funSet
private

Definition at line 117 of file LLVMModule.h.

◆ FunToDominatorTree

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

Definition at line 110 of file LLVMModule.h.

◆ funToExitBB

FunToExitBBMap SVF::LLVMModuleSet::funToExitBB
private

Definition at line 118 of file LLVMModule.h.

◆ FunToFunEntryNodeMap

FunToFunEntryNodeMapTy SVF::LLVMModuleSet::FunToFunEntryNodeMap
private

map a function to its FunExitICFGNode

Definition at line 107 of file LLVMModule.h.

◆ FunToFunExitNodeMap

FunToFunExitNodeMapTy SVF::LLVMModuleSet::FunToFunExitNodeMap
private

map a function to its FunEntryICFGNode

Definition at line 108 of file LLVMModule.h.

◆ funToRealDefFun

FunToRealDefFunMap SVF::LLVMModuleSet::funToRealDefFun
private

Definition at line 119 of file LLVMModule.h.

◆ GlobalDefToRepMap

GlobalDefToRepMapTy SVF::LLVMModuleSet::GlobalDefToRepMap
private

Global definition to a rep definition map.

Definition at line 95 of file LLVMModule.h.

◆ InstToBlockNodeMap

InstToBlockNodeMapTy SVF::LLVMModuleSet::InstToBlockNodeMap
private

map a basic block to its ICFGNode

Definition at line 106 of file LLVMModule.h.

◆ LLVMBB2SVFBB

LLVMBB2SVFBBMap SVF::LLVMModuleSet::LLVMBB2SVFBB
private

Definition at line 98 of file LLVMModule.h.

◆ LLVMFun2FunObjVar

LLVMFun2FunObjVarMap SVF::LLVMModuleSet::LLVMFun2FunObjVar
private

Map an LLVM Function to an SVF Funobjvar.

Definition at line 97 of file LLVMModule.h.

◆ llvmModuleSet

LLVMModuleSet * LLVMModuleSet::llvmModuleSet = nullptr
staticprivate

Definition at line 79 of file LLVMModule.h.

◆ LLVMType2SVFType

LLVMType2SVFTypeMap SVF::LLVMModuleSet::LLVMType2SVFType
private

Definition at line 99 of file LLVMModule.h.

◆ modules

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

Definition at line 84 of file LLVMModule.h.

◆ objSymMap

ValueToIDMapTy SVF::LLVMModuleSet::objSymMap
private

map a obj reference to its sym id

Definition at line 113 of file LLVMModule.h.

◆ owned_ctx

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

Definition at line 82 of file LLVMModule.h.

◆ owned_modules

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

Definition at line 83 of file LLVMModule.h.

◆ preProcessed

bool LLVMModuleSet::preProcessed = false
staticprivate

Definition at line 80 of file LLVMModule.h.

◆ returnSymMap

FunToIDMapTy SVF::LLVMModuleSet::returnSymMap
private

return map

Definition at line 114 of file LLVMModule.h.

◆ SVFBaseNode2LLVMValue

SVFBaseNode2LLVMValueMap SVF::LLVMModuleSet::SVFBaseNode2LLVMValue
private

Definition at line 103 of file LLVMModule.h.

◆ svfir

SVFIR* SVF::LLVMModuleSet::svfir
private

Definition at line 81 of file LLVMModule.h.

◆ Type2TypeInfo

Type2TypeInfoMap SVF::LLVMModuleSet::Type2TypeInfo
private

Definition at line 100 of file LLVMModule.h.

◆ typeInference

ObjTypeInference* SVF::LLVMModuleSet::typeInference
private

Definition at line 101 of file LLVMModule.h.

◆ valSymMap

ValueToIDMapTy SVF::LLVMModuleSet::valSymMap
private

map a value to its sym id

Definition at line 112 of file LLVMModule.h.

◆ varargSymMap

FunToIDMapTy SVF::LLVMModuleSet::varargSymMap
private

vararg map

Definition at line 115 of file LLVMModule.h.


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