Static Value-Flow Analysis
Loading...
Searching...
No Matches
Public Member Functions | Protected Member Functions | Private Attributes | Friends | List of all members
SVF::SymbolTableBuilder Class Reference

#include <SymbolTableBuilder.h>

Public Member Functions

 SymbolTableBuilder (SymbolTableInfo *si)
 Constructor.
 
void buildMemModel (SVFModule *svfModule)
 Start building memory model.
 
u32_t getNumOfElements (const Type *ety)
 Return size of this object based on LLVM value.
 

Protected Member Functions

void collectSVFTypeInfo (const Value *val)
 collect the syms
 
void collectSym (const Value *val)
 
void collectVal (const Value *val)
 
void collectObj (const Value *val)
 
void collectRet (const Function *val)
 
void collectVararg (const Function *val)
 
void handleGlobalCE (const GlobalVariable *G)
 Handle constant expression.
 
void handleGlobalInitializerCE (const Constant *C)
 
void handleCE (const Value *val)
 
ObjTypeInferencegetTypeInference ()
 
const TypeinferObjType (const Value *startValue)
 Forward collect all possible infer sites starting from a value.
 
const TypeinferTypeOfHeapObjOrStaticObj (const Instruction *inst)
 Get the reference type of heap/static object from an allocation site.
 
ObjTypeInfocreateObjTypeInfo (const Value *val)
 Create an objectInfo based on LLVM value.
 
void initTypeInfo (ObjTypeInfo *typeinfo, const Value *value, const Type *ty)
 Initialize TypeInfo based on LLVM Value.
 
void analyzeObjType (ObjTypeInfo *typeinfo, const Value *val)
 Analyse types of all flattened fields of this object.
 
u32_t analyzeHeapObjType (ObjTypeInfo *typeinfo, const Value *val)
 Analyse types of heap and static objects.
 
void analyzeStaticObjType (ObjTypeInfo *typeinfo, const Value *val)
 Analyse types of heap and static objects.
 
u32_t analyzeHeapAllocByteSize (const Value *val)
 Analyze byte size of heap alloc function (e.g. malloc/calloc/...)
 
u32_t getNumOfFlattenElements (const Type *T)
 Number of flattened elements of an array or struct.
 
StInfogetOrAddSVFTypeInfo (const Type *T)
 Get a reference to StructInfo.
 
MemObjcreateBlkObj (SymID symId)
 
MemObjcreateConstantObj (SymID symId)
 

Private Attributes

SymbolTableInfosymInfo
 

Friends

class SVFIRBuilder
 

Detailed Description

Definition at line 44 of file SymbolTableBuilder.h.

Constructor & Destructor Documentation

◆ SymbolTableBuilder()

SVF::SymbolTableBuilder::SymbolTableBuilder ( SymbolTableInfo si)
inline

Constructor.

Definition at line 52 of file SymbolTableBuilder.h.

52 : symInfo(si)
53 {
54 }
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74

Member Function Documentation

◆ analyzeHeapAllocByteSize()

u32_t SymbolTableBuilder::analyzeHeapAllocByteSize ( const Value val)
protected

Analyze byte size of heap alloc function (e.g. malloc/calloc/...)

Analyze byte size of heap alloc function (e.g. malloc/calloc/...) 1) attribute((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0"))) void* safe_malloc(unsigned long size). Byte Size is the size(Arg0) 2)__attribute__((annotate("ALLOC_HEAP_RET"), annotate("AllocSize:Arg0*Arg1"))) char* safecalloc(int a, int b) Byte Size is a(Arg0) * b(Arg1) 3)__attribute__((annotate("ALLOC_HEAP_RET"), annotate("UNKNOWN"))) void* __sysv_signal(int a, void *b) Byte Size is Unknown If all required arg values are constant, byte Size is also constant, otherwise return ByteSize 0

Definition at line 739 of file SymbolTableBuilder.cpp.

740{
741 if(const llvm::CallInst* callInst = llvm::dyn_cast<llvm::CallInst>(val))
742 {
743 if (const llvm::Function* calledFunction =
744 callInst->getCalledFunction())
745 {
746 const SVFFunction* svfFunction =
749 std::vector<const Value*> args;
750 // Heap alloc functions have annoation like "AllocSize:Arg1"
751 for (std::string annotation : ExtAPI::getExtAPI()->getExtFuncAnnotations(svfFunction))
752 {
753 if (annotation.find("AllocSize:") != std::string::npos)
754 {
755 std::string allocSize = annotation.substr(10);
756 std::stringstream ss(allocSize);
757 std::string token;
758 // Analyaze annotation string and attract Arg list
759 while (std::getline(ss, token, '*'))
760 {
761 if (token.rfind("Arg", 0) == 0)
762 {
764 std::istringstream(token.substr(3)) >> argIndex;
766 {
767 args.push_back(
768 callInst->getArgOperand(argIndex));
769 }
770 }
771 }
772 }
773 }
774 u64_t product = 1;
775 if (args.size() > 0)
776 {
777 // for annotations like "AllocSize:Arg0*Arg1"
778 for (const llvm::Value* arg : args)
779 {
780 if (const llvm::ConstantInt* constIntArg =
781 llvm::dyn_cast<llvm::ConstantInt>(arg))
782 {
783 // Multiply the constant Value if all Args are const
784 product *= constIntArg->getZExtValue();
785 }
786 else
787 {
788 // if Arg list has non-const value, return 0 to indicate it is non const byte size
789 return 0;
790 }
791 }
792 // If all the Args are const, return product
793 return product;
794 }
795 else
796 {
797 // for annotations like "AllocSize:UNKNOWN"
798 return 0;
799 }
800 }
801 }
802 // if it is not CallInst or CallInst has no CalledFunction, return 0 to indicate it is non const byte size
803 return 0;
804}
unsigned u32_t
Definition CommandLine.h:18
static LLVMModuleSet * getLLVMModuleSet()
Definition LLVMModule.h:122
SVFFunction * getSVFFunction(const Function *fun) const
Definition LLVMModule.h:260
unsigned long long u64_t
Definition GeneralType.h:48

◆ analyzeHeapObjType()

u32_t SymbolTableBuilder::analyzeHeapObjType ( ObjTypeInfo typeinfo,
const Value val 
)
protected

Analyse types of heap and static objects.

Analyse types of heap and static objects

For an C++ class, it can have variant elements depending on the vtable size, Hence we only handle non-cpp-class object, the type of the cpp class is treated as default PointerType

Definition at line 809 of file SymbolTableBuilder.cpp.

810{
812 analyzeObjType(typeinfo, val);
814 if(SVFUtil::isa<ArrayType>(objTy))
815 return getNumOfElements(objTy);
816 else if(const StructType* st = SVFUtil::dyn_cast<StructType>(objTy))
817 {
823 else
824 return getNumOfElements(objTy);
825 }
826 return typeinfo->getMaxFieldOffsetLimit();
827}
const Type * getLLVMType(const SVFType *T) const
Get LLVM Type.
u32_t getMaxFieldOffsetLimit()
Get max field offset limit.
const SVFType * getType() const
Get LLVM type.
void setFlag(MEMTYPE mask)
Flag for this object type.
void resetTypeForHeapStaticObj(const SVFType *type)
ObjTypeInference * getTypeInference()
u32_t getNumOfElements(const Type *ety)
Return size of this object based on LLVM value.
void analyzeObjType(ObjTypeInfo *typeinfo, const Value *val)
Analyse types of all flattened fields of this object.
bool classTyHasVTable(const StructType *ty)
Definition CppUtil.cpp:569
llvm::Type Type
Definition BasicTypes.h:83
llvm::StructType StructType
LLVM types.
Definition BasicTypes.h:94

◆ analyzeObjType()

void SymbolTableBuilder::analyzeObjType ( ObjTypeInfo typeinfo,
const Value val 
)
protected

Analyse types of all flattened fields of this object.

Analyse types of all flattened fields of this object

Definition at line 698 of file SymbolTableBuilder.cpp.

699{
701 // Find the inter nested array element
702 while (const ArrayType* AT = SVFUtil::dyn_cast<ArrayType>(elemTy))
703 {
704 elemTy = AT->getElementType();
705 if (SVFUtil::isa<GlobalVariable>(val) &&
706 SVFUtil::cast<GlobalVariable>(val)->hasInitializer() &&
707 SVFUtil::isa<ConstantArray>(
708 SVFUtil::cast<GlobalVariable>(val)->getInitializer()))
710 else
712 }
713 if (SVFUtil::isa<StructType>(elemTy))
714 {
715 if (SVFUtil::isa<GlobalVariable>(val) &&
716 SVFUtil::cast<GlobalVariable>(val)->hasInitializer() &&
717 SVFUtil::isa<ConstantStruct>(
718 SVFUtil::cast<GlobalVariable>(val)->getInitializer()))
720 else
722 }
723}
llvm::ArrayType ArrayType
Definition BasicTypes.h:95

◆ analyzeStaticObjType()

void SymbolTableBuilder::analyzeStaticObjType ( ObjTypeInfo typeinfo,
const Value val 
)
protected

Analyse types of heap and static objects.

Analyse types of heap and static objects

Definition at line 832 of file SymbolTableBuilder.cpp.

833{
835 {
837 analyzeObjType(typeinfo,castUse);
838 }
839 else
840 {
842 }
843}
const Value * getFirstUseViaCastInst(const Value *val)
Definition LLVMUtil.cpp:278
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:82

◆ buildMemModel()

void SymbolTableBuilder::buildMemModel ( SVFModule svfModule)

Start building memory model.

This method identify which is value sym and which is object sym

if (SVFUtil::isa<InlineAsm>(Callee))

Definition at line 75 of file SymbolTableBuilder.cpp.

76{
78
79 symInfo->setModule(svfModule);
80
81 // Pointer #0 always represents the null pointer.
82 assert(symInfo->totalSymNum++ == SymbolTableInfo::NullPtr && "Something changed!");
83
84 // Pointer #1 always represents the pointer points-to black hole.
85 assert(symInfo->totalSymNum++ == SymbolTableInfo::BlkPtr && "Something changed!");
86
87 // Object #2 is black hole the object that may point to any object
88 assert(symInfo->totalSymNum++ == SymbolTableInfo::BlackHole && "Something changed!");
90
91 // Object #3 always represents the unique constant of a program (merging all constants if Options::ModelConsts is disabled)
92 assert(symInfo->totalSymNum++ == SymbolTableInfo::ConstantObj && "Something changed!");
94
95 for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
96 {
97 // Add symbols for all the globals .
98 for (const GlobalVariable& gv : M.globals())
99 {
100 collectSym(&gv);
101 }
102
103 // Add symbols for all the global aliases
104 for (const GlobalAlias& ga : M.aliases())
105 {
106 collectSym(&ga);
107 collectSym(ga.getAliasee());
108 }
109
110 // Add symbols for all of the functions and the instructions in them.
111 for (const Function& fun : M.functions())
112 {
113 collectSym(&fun);
114 collectRet(&fun);
115 if (fun.getFunctionType()->isVarArg())
116 collectVararg(&fun);
117
118 // Add symbols for all formal parameters.
119 for (const Argument& arg : fun.args())
120 {
121 collectSym(&arg);
122 }
123
124 // collect and create symbols inside the function body
125 for (const Instruction& inst : instructions(fun))
126 {
127 collectSym(&inst);
128
129 // initialization for some special instructions
130 //{@
131 if (const StoreInst* st = SVFUtil::dyn_cast<StoreInst>(&inst))
132 {
133 collectSym(st->getPointerOperand());
134 collectSym(st->getValueOperand());
135 }
136 else if (const LoadInst* ld =
137 SVFUtil::dyn_cast<LoadInst>(&inst))
138 {
139 collectSym(ld->getPointerOperand());
140 }
141 else if (const AllocaInst* alloc =
142 SVFUtil::dyn_cast<AllocaInst>(&inst))
143 {
144 collectSym(alloc->getArraySize());
145 }
146 else if (const PHINode* phi = SVFUtil::dyn_cast<PHINode>(&inst))
147 {
148 for (u32_t i = 0; i < phi->getNumIncomingValues(); ++i)
149 {
150 collectSym(phi->getIncomingValue(i));
151 }
152 }
153 else if (const GetElementPtrInst* gep =
154 SVFUtil::dyn_cast<GetElementPtrInst>(&inst))
155 {
156 collectSym(gep->getPointerOperand());
157 for (u32_t i = 0; i < gep->getNumOperands(); ++i)
158 {
159 collectSym(gep->getOperand(i));
160 }
161 }
162 else if (const SelectInst* sel =
163 SVFUtil::dyn_cast<SelectInst>(&inst))
164 {
165 collectSym(sel->getTrueValue());
166 collectSym(sel->getFalseValue());
167 collectSym(sel->getCondition());
168 }
169 else if (const BinaryOperator* binary =
170 SVFUtil::dyn_cast<BinaryOperator>(&inst))
171 {
172 for (u32_t i = 0; i < binary->getNumOperands(); i++)
173 collectSym(binary->getOperand(i));
174 }
175 else if (const UnaryOperator* unary =
176 SVFUtil::dyn_cast<UnaryOperator>(&inst))
177 {
178 for (u32_t i = 0; i < unary->getNumOperands(); i++)
179 collectSym(unary->getOperand(i));
180 }
181 else if (const CmpInst* cmp = SVFUtil::dyn_cast<CmpInst>(&inst))
182 {
183 for (u32_t i = 0; i < cmp->getNumOperands(); i++)
184 collectSym(cmp->getOperand(i));
185 }
186 else if (const CastInst* cast =
187 SVFUtil::dyn_cast<CastInst>(&inst))
188 {
189 collectSym(cast->getOperand(0));
190 }
191 else if (const ReturnInst* ret =
192 SVFUtil::dyn_cast<ReturnInst>(&inst))
193 {
194 if (ret->getReturnValue())
195 collectSym(ret->getReturnValue());
196 }
197 else if (const BranchInst* br =
198 SVFUtil::dyn_cast<BranchInst>(&inst))
199 {
200 Value* opnd = br->isConditional() ? br->getCondition() : br->getOperand(0);
202 }
203 else if (const SwitchInst* sw =
204 SVFUtil::dyn_cast<SwitchInst>(&inst))
205 {
206 collectSym(sw->getCondition());
207 }
208 else if (isNonInstricCallSite(&inst))
209 {
210
211 const CallBase* cs = LLVMUtil::getLLVMCallSite(&inst);
212 for (u32_t i = 0; i < cs->arg_size(); i++)
213 {
214 collectSym(cs->getArgOperand(i));
215 }
216 // Calls to inline asm need to be added as well because the
217 // callee isn't referenced anywhere else.
218 const Value* Callee = cs->getCalledOperand();
220
221 // TODO handle inlineAsm
224 {
226 }
227 }
229 }
230 }
231 }
232
235 {
236 symInfo->dump();
237 }
238}
static NodeIDAllocator * get(void)
Return (singleton) allocator.
NodeID endSymbolAllocation(void)
Notify the allocator that all symbols have had IDs allocated.
void validateTypeCheck(const CallBase *cs)
validate type inference
static const Option< bool > EnableTypeCheck
Definition Options.h:131
static const Option< bool > SymTabPrint
Definition Options.h:190
void collectRet(const Function *val)
MemObj * createBlkObj(SymID symId)
MemObj * createConstantObj(SymID symId)
void collectSym(const Value *val)
void collectVararg(const Function *val)
SymID totalSymNum
total number of symbols
void setModule(SVFModule *m)
Module.
virtual void dump()
Another debug method.
const CallBase * getLLVMCallSite(const Value *value)
Return LLVM callsite given a value.
Definition LLVMUtil.h:57
bool isNonInstricCallSite(const Instruction *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
Definition LLVMUtil.cpp:707
void increaseStackSize()
Increase the stack size limit.
Definition SVFUtil.cpp:228
std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > cast(const Y &Val)
Definition Casting.h:360
llvm::GlobalVariable GlobalVariable
Definition BasicTypes.h:130
llvm::GlobalAlias GlobalAlias
Definition BasicTypes.h:128
llvm::CallBase CallBase
Definition BasicTypes.h:146
llvm::UnaryOperator UnaryOperator
Definition BasicTypes.h:180
llvm::AllocaInst AllocaInst
Definition BasicTypes.h:150
llvm::SwitchInst SwitchInst
Definition BasicTypes.h:155
llvm::Argument Argument
Definition BasicTypes.h:145
llvm::LoadInst LoadInst
Definition BasicTypes.h:149
llvm::CmpInst CmpInst
Definition BasicTypes.h:159
llvm::Function Function
Definition BasicTypes.h:85
llvm::Instruction Instruction
Definition BasicTypes.h:87
llvm::CastInst CastInst
Definition BasicTypes.h:158
llvm::Module Module
Definition BasicTypes.h:84
llvm::BinaryOperator BinaryOperator
Definition BasicTypes.h:179
llvm::StoreInst StoreInst
Definition BasicTypes.h:148
llvm::SelectInst SelectInst
Definition BasicTypes.h:174
llvm::GetElementPtrInst GetElementPtrInst
Definition BasicTypes.h:162
llvm::ReturnInst ReturnInst
Definition BasicTypes.h:157
llvm::PHINode PHINode
Definition BasicTypes.h:165
llvm::BranchInst BranchInst
Definition BasicTypes.h:154

◆ collectObj()

void SymbolTableBuilder::collectObj ( const Value val)
protected

Get memory object sym, if not available create a new one

Definition at line 318 of file SymbolTableBuilder.cpp.

319{
322 SymbolTableInfo::ValueToIDMapTy::iterator iter = symInfo->objSymMap.find(llvmModuleSet->getSVFValue(val));
323 if (iter == symInfo->objSymMap.end())
324 {
325 SVFValue* svfVal = llvmModuleSet->getSVFValue(val);
326 // if the object pointed by the pointer is a constant data (e.g., i32 0) or a global constant object (e.g. string)
327 // then we treat them as one ConstantObj
329 {
330 symInfo->objSymMap.insert(std::make_pair(svfVal, symInfo->constantSymID()));
331 }
332 // otherwise, we will create an object for each abstract memory location
333 else
334 {
335 // create obj sym and sym type
337 symInfo->objSymMap.insert(std::make_pair(svfVal, id));
339 outs() << "create a new obj sym " << id << "\n");
340
341 // create a memory object
342 MemObj* mem =
344 llvmModuleSet->getSVFValue(val));
345 assert(symInfo->objMap.find(id) == symInfo->objMap.end());
346 symInfo->objMap[id] = mem;
347 }
348 }
349}
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:484
#define DMemModel
Definition SVFType.h:493
SVFValue * getSVFValue(const Value *value)
NodeID allocateObjectId(void)
Allocate an object ID as determined by the strategy.
ObjTypeInfo * createObjTypeInfo(const Value *val)
Create an objectInfo based on LLVM value.
ValueToIDMapTy objSymMap
map a obj reference to its sym id
bool getModelConstants() const
SymID constantSymID() const
IDToMemMapTy objMap
map a memory sym id to its obj
const Value * getGlobalRep(const Value *val)
find the unique defined global across multiple modules
Definition LLVMUtil.cpp:416
bool isConstantObjSym(const SVFValue *val)
Check whether this value points-to a constant object.
Definition LLVMUtil.cpp:578
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50
unsigned SymID
Definition GeneralType.h:57

◆ collectRet()

void SymbolTableBuilder::collectRet ( const Function val)
protected

Create unique return sym, if not available create a new one

Definition at line 354 of file SymbolTableBuilder.cpp.

355{
356 const SVFFunction* svffun =
358 SymbolTableInfo::FunToIDMapTy::iterator iter =
360 if (iter == symInfo->returnSymMap.end())
361 {
363 symInfo->returnSymMap.insert(std::make_pair(svffun, id));
364 DBOUT(DMemModel, outs() << "create a return sym " << id << "\n");
365 }
366}
NodeID allocateValueId(void)
Allocate a value ID as determined by the strategy.
FunToIDMapTy returnSymMap
return map

◆ collectSVFTypeInfo()

void SymbolTableBuilder::collectSVFTypeInfo ( const Value val)
protected

collect the syms

Definition at line 240 of file SymbolTableBuilder.cpp.

241{
242 Type *valType = val->getType();
244 if(isGepConstantExpr(val) || SVFUtil::isa<GetElementPtrInst>(val))
245 {
247 gi = bridge_gep_begin(SVFUtil::cast<User>(val)),
248 ge = bridge_gep_end(SVFUtil::cast<User>(val));
249 gi != ge; ++gi)
250 {
251 const Type* gepTy = *gi;
253 }
254 }
255}
StInfo * getOrAddSVFTypeInfo(const Type *T)
Get a reference to StructInfo.
const ConstantExpr * isGepConstantExpr(const Value *val)
Return corresponding constant expression, otherwise return nullptr.
Definition LLVMUtil.h:181
bridge_gep_iterator bridge_gep_end(const User *GEP)
bridge_gep_iterator bridge_gep_begin(const User *GEP)

◆ collectSym()

void SymbolTableBuilder::collectSym ( const Value val)
protected

Collect symbols, including value and object syms

Definition at line 260 of file SymbolTableBuilder.cpp.

261{
262
263 //TODO: filter the non-pointer type // if (!SVFUtil::isa<PointerType>(val->getType())) return;
264
266 outs()
267 << "collect sym from ##"
268 << LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)->toString()
269 << " \n");
270 //TODO handle constant expression value here??
271 handleCE(val);
272
273 // create a value sym
275
278
279 // create an object If it is a heap, stack, global, function.
280 if (isObject(val))
281 {
283 }
284}
void collectSVFTypeInfo(const Value *val)
collect the syms
void collectObj(const Value *val)
void collectVal(const Value *val)
void handleCE(const Value *val)
bool isObject(const Value *ref)
Return true if this value refers to a object.
Definition LLVMUtil.cpp:59

◆ collectVal()

void SymbolTableBuilder::collectVal ( const Value val)
protected

Get value sym, if not available create a new one

handle global constant expression here

Definition at line 289 of file SymbolTableBuilder.cpp.

290{
291 // collect and record special sym here
293 {
294 return;
295 }
296 SymbolTableInfo::ValueToIDMapTy::iterator iter = symInfo->valSymMap.find(
297 LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val));
298 if (iter == symInfo->valSymMap.end())
299 {
300 // create val sym and sym type
303 symInfo->valSymMap.insert(std::make_pair(svfVal, id));
305 outs() << "create a new value sym " << id << "\n");
307 if (const GlobalVariable* globalVar = SVFUtil::dyn_cast<GlobalVariable>(val))
309 }
310
313}
void handleGlobalCE(const GlobalVariable *G)
Handle constant expression.
ValueToIDMapTy valSymMap
map a value to its sym id
bool isNullPtrSym(const Value *val)
Check whether this value is a black hole.
Definition LLVMUtil.h:91
bool isBlackholeSym(const Value *val)
Check whether this value is a black hole.
Definition LLVMUtil.h:85

◆ collectVararg()

void SymbolTableBuilder::collectVararg ( const Function val)
protected

Create vararg sym, if not available create a new one

Definition at line 371 of file SymbolTableBuilder.cpp.

372{
373 const SVFFunction* svffun =
375 SymbolTableInfo::FunToIDMapTy::iterator iter =
377 if (iter == symInfo->varargSymMap.end())
378 {
380 symInfo->varargSymMap.insert(std::make_pair(svffun, id));
381 DBOUT(DMemModel, outs() << "create a vararg sym " << id << "\n");
382 }
383}
FunToIDMapTy varargSymMap
vararg map

◆ createBlkObj()

MemObj * SymbolTableBuilder::createBlkObj ( SymID  symId)
protected

Definition at line 47 of file SymbolTableBuilder.cpp.

48{
49 assert(symInfo->isBlkObj(symId));
50 assert(symInfo->objMap.find(symId)==symInfo->objMap.end());
52 MemObj* obj =
53 new MemObj(symId, symInfo->createObjTypeInfo(llvmset->getSVFType(
54 IntegerType::get(llvmset->getContext(), 32))));
55 symInfo->objMap[symId] = obj;
56 return obj;
57}
ObjTypeInfo * createObjTypeInfo(const SVFType *type)
Create an objectInfo based on LLVM type (value is null, and type could be null, representing a dummy ...
static bool isBlkObj(NodeID id)

◆ createConstantObj()

MemObj * SymbolTableBuilder::createConstantObj ( SymID  symId)
protected

Definition at line 59 of file SymbolTableBuilder.cpp.

60{
62 assert(symInfo->objMap.find(symId)==symInfo->objMap.end());
64 MemObj* obj =
65 new MemObj(symId, symInfo->createObjTypeInfo(llvmset->getSVFType(
66 IntegerType::get(llvmset->getContext(), 32))));
67 symInfo->objMap[symId] = obj;
68 return obj;
69}
static bool isConstantObj(NodeID id)

◆ createObjTypeInfo()

ObjTypeInfo * SymbolTableBuilder::createObjTypeInfo ( const Value val)
protected

Create an objectInfo based on LLVM value.

Definition at line 629 of file SymbolTableBuilder.cpp.

630{
631 const Type* objTy = nullptr;
632
633 const Instruction* I = SVFUtil::dyn_cast<Instruction>(val);
634
635 // We consider two types of objects:
636 // (1) A heap/static object from a callsite
637 if (I && isNonInstricCallSite(I))
638 {
640 }
641 // (2) Other objects (e.g., alloca, global, etc.)
642 else
643 {
644 if (SVFUtil::isa<PointerType>(val->getType()))
645 {
646 if (const AllocaInst *allocaInst = SVFUtil::dyn_cast<AllocaInst>(val))
647 {
648 // get the type of the allocated memory
649 // e.g., for `%retval = alloca i64, align 4`, we return i64
650 objTy = allocaInst->getAllocatedType();
651 }
652 else if (const GlobalValue *global = SVFUtil::dyn_cast<GlobalValue>(val))
653 {
654 // get the pointee type of the global pointer (begins with @ symbol in llvm)
655 objTy = global->getValueType();
656 }
657 else
658 {
660 assert(false && "not an allocation or global?");
661 }
662 }
663 }
664
665 if (objTy)
666 {
668 ObjTypeInfo* typeInfo = new ObjTypeInfo(
671 initTypeInfo(typeInfo,val, objTy);
672 return typeInfo;
673 }
674 else
675 {
676 writeWrnMsg("try to create an object with a non-pointer type.");
677 writeWrnMsg(val->getName().str());
678 writeWrnMsg("(" + LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)->getSourceLoc() + ")");
680 {
681 ObjTypeInfo* typeInfo = new ObjTypeInfo(
682 LLVMModuleSet::getLLVMModuleSet()->getSVFType(val->getType()),
683 0);
684 initTypeInfo(typeInfo,val, val->getType());
685 return typeInfo;
686 }
687 else
688 {
689 assert(false && "Memory object must be either (1) held by a pointer-typed ref value or (2) a constant value (e.g., 10).");
690 abort();
691 }
692 }
693}
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:38
const Type * inferTypeOfHeapObjOrStaticObj(const Instruction *inst)
Get the reference type of heap/static object from an allocation site.
void initTypeInfo(ObjTypeInfo *typeinfo, const Value *value, const Type *ty)
Initialize TypeInfo based on LLVM Value.
std::string dumpValueAndDbgInfo(const Value *val)
Definition LLVMUtil.cpp:606
const std::string getSourceLoc(const Value *val)
Definition LLVMUtil.cpp:429
std::ostream & errs()
Overwrite llvm::errs()
Definition SVFUtil.h:56
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:67
llvm::GlobalValue GlobalValue
Definition BasicTypes.h:88

◆ getNumOfElements()

u32_t SymbolTableBuilder::getNumOfElements ( const Type ety)

Return size of this object based on LLVM value.

Return size of this Object

Definition at line 940 of file SymbolTableBuilder.cpp.

941{
942 assert(ety && "type is null?");
943 u32_t numOfFields = 1;
944 if (SVFUtil::isa<StructType, ArrayType>(ety))
945 {
947 }
948 return numOfFields;
949}
u32_t getNumOfFlattenElements(const Type *T)
Number of flattened elements of an array or struct.

◆ getNumOfFlattenElements()

u32_t SymbolTableBuilder::getNumOfFlattenElements ( const Type T)
protected

Number of flattened elements of an array or struct.

Get a reference to the components of struct_info. Number of flattened elements of an array or struct

Definition at line 952 of file SymbolTableBuilder.cpp.

953{
956 else
958}
static const Option< bool > ModelArrays
Definition Options.h:188
u32_t getNumOfFlattenElements() const
Return number of elements after flattening (including array elements)
Definition SVFType.h:139
u32_t getNumOfFlattenFields() const
Return the number of fields after flattening (ignoring array elements)
Definition SVFType.h:145

◆ getOrAddSVFTypeInfo()

StInfo * SymbolTableBuilder::getOrAddSVFTypeInfo ( const Type T)
protected

Get a reference to StructInfo.

Definition at line 960 of file SymbolTableBuilder.cpp.

961{
963}
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
StInfo * getTypeInfo()
Definition SVFType.h:230

◆ getTypeInference()

ObjTypeInference * SymbolTableBuilder::getTypeInference ( )
protected

Definition at line 576 of file SymbolTableBuilder.cpp.

577{
579}
ObjTypeInference * getTypeInference()

◆ handleCE()

void SymbolTableBuilder::handleCE ( const Value val)
protected

Handle constant expression

Definition at line 388 of file SymbolTableBuilder.cpp.

389{
390 if (const Constant* ref = SVFUtil::dyn_cast<Constant>(val))
391 {
392 if (const ConstantExpr* ce = isGepConstantExpr(ref))
393 {
394 DBOUT(DMemModelCE, outs() << "handle constant expression "
396 ->getSVFValue(ref)
397 ->toString()
398 << "\n");
399 collectVal(ce);
400
401 // handle the recursive constant express case
402 // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
403 for (u32_t i = 0; i < ce->getNumOperands(); ++i)
404 {
405 collectVal(ce->getOperand(i));
406 handleCE(ce->getOperand(i));
407 }
408 }
409 else if (const ConstantExpr* ce = isCastConstantExpr(ref))
410 {
411 DBOUT(DMemModelCE, outs() << "handle constant expression "
413 ->getSVFValue(ref)
414 ->toString()
415 << "\n");
416 collectVal(ce);
417 collectVal(ce->getOperand(0));
418 // handle the recursive constant express case
419 // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
420 handleCE(ce->getOperand(0));
421 }
422 else if (const ConstantExpr* ce = isSelectConstantExpr(ref))
423 {
424 DBOUT(DMemModelCE, outs() << "handle constant expression "
426 ->getSVFValue(ref)
427 ->toString()
428 << "\n");
429 collectVal(ce);
430 collectVal(ce->getOperand(0));
431 collectVal(ce->getOperand(1));
432 collectVal(ce->getOperand(2));
433 // handle the recursive constant express case
434 // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
435 handleCE(ce->getOperand(0));
436 handleCE(ce->getOperand(1));
437 handleCE(ce->getOperand(2));
438 }
439 // if we meet a int2ptr, then it points-to black hole
441 {
443 const Constant* opnd = int2Ptrce->getOperand(0);
444 handleCE(opnd);
445 }
447 {
449 const Constant* opnd = ptr2Intce->getOperand(0);
450 handleCE(opnd);
451 }
453 {
455 }
456 else if (isBinaryConstantExpr(ref))
457 {
459 }
460 else if (isUnaryConstantExpr(ref))
461 {
462 // we don't handle unary constant expression like fneg(x) now
464 }
465 else if (SVFUtil::isa<ConstantAggregate>(ref))
466 {
467 // we don't handle constant aggregate like constant vectors
469 }
470 else
471 {
472 assert(!SVFUtil::isa<ConstantExpr>(val) &&
473 "we don't handle all other constant expression for now!");
475 }
476 }
477}
#define DMemModelCE
Definition SVFType.h:494
const ConstantExpr * isBinaryConstantExpr(const Value *val)
Definition LLVMUtil.h:256
const ConstantExpr * isInt2PtrConstantExpr(const Value *val)
Definition LLVMUtil.h:191
const ConstantExpr * isSelectConstantExpr(const Value *val)
Definition LLVMUtil.h:221
const ConstantExpr * isTruncConstantExpr(const Value *val)
Definition LLVMUtil.h:231
const ConstantExpr * isPtr2IntConstantExpr(const Value *val)
Definition LLVMUtil.h:201
const ConstantExpr * isUnaryConstantExpr(const Value *val)
Definition LLVMUtil.h:267
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition LLVMUtil.h:211
const ConstantExpr * isCmpConstantExpr(const Value *val)
Definition LLVMUtil.h:245
llvm::Constant Constant
Definition BasicTypes.h:124
llvm::ConstantExpr ConstantExpr
Definition BasicTypes.h:120

◆ handleGlobalCE()

void SymbolTableBuilder::handleGlobalCE ( const GlobalVariable G)
protected

Handle constant expression.

Handle global constant expression

Definition at line 482 of file SymbolTableBuilder.cpp.

483{
484 assert(G);
485
486 //The type this global points to
487 const Type* T = G->getValueType();
488 bool is_array = 0;
489 //An array is considered a single variable of its type.
490 while (const ArrayType* AT = SVFUtil::dyn_cast<ArrayType>(T))
491 {
492 T = AT->getElementType();
493 is_array = true;
494 }
495
496 if (SVFUtil::isa<StructType>(T))
497 {
498 //A struct may be used in constant GEP expr.
499 for (const User* user : G->users())
500 {
501 handleCE(user);
502 }
503 }
504 else if (is_array)
505 {
506 for (const User* user : G->users())
507 {
508 handleCE(user);
509 }
510 }
511
512 if (G->hasInitializer())
513 {
514 handleGlobalInitializerCE(G->getInitializer());
515 }
516}
void handleGlobalInitializerCE(const Constant *C)
llvm::User User
Definition BasicTypes.h:142

◆ handleGlobalInitializerCE()

void SymbolTableBuilder::handleGlobalInitializerCE ( const Constant C)
protected

Handle global variable initialization

Definition at line 521 of file SymbolTableBuilder.cpp.

522{
523
524 if (C->getType()->isSingleValueType())
525 {
526 if (const ConstantExpr* E = SVFUtil::dyn_cast<ConstantExpr>(C))
527 {
528 handleCE(E);
529 }
530 else
531 {
532 collectVal(C);
533 }
534 }
535 else if (SVFUtil::isa<ConstantArray>(C))
536 {
537 for (u32_t i = 0, e = C->getNumOperands(); i != e; i++)
538 {
539 handleGlobalInitializerCE(SVFUtil::cast<Constant>(C->getOperand(i)));
540 }
541 }
542 else if (SVFUtil::isa<ConstantStruct>(C))
543 {
544 for (u32_t i = 0, e = C->getNumOperands(); i != e; i++)
545 {
546 handleGlobalInitializerCE(SVFUtil::cast<Constant>(C->getOperand(i)));
547 }
548 }
549 else if(const ConstantData* data = SVFUtil::dyn_cast<ConstantData>(C))
550 {
552 {
553 if (const ConstantDataSequential* seq =
554 SVFUtil::dyn_cast<ConstantDataSequential>(data))
555 {
556 for(u32_t i = 0; i < seq->getNumElements(); i++)
557 {
558 const Constant* ct = seq->getElementAsConstant(i);
560 }
561 }
562 else
563 {
564 assert(
565 (SVFUtil::isa<ConstantAggregateZero, UndefValue>(data)) &&
566 "Single value type data should have been handled!");
567 }
568 }
569 }
570 else
571 {
572 //TODO:assert(SVFUtil::isa<ConstantVector>(C),"what else do we have");
573 }
574}
static const Option< bool > ModelConsts
Definition Options.h:187
llvm::ConstantData ConstantData
Definition BasicTypes.h:116
llvm::ConstantDataSequential ConstantDataSequential
Definition BasicTypes.h:119

◆ inferObjType()

const Type * SymbolTableBuilder::inferObjType ( const Value startValue)
protected

Forward collect all possible infer sites starting from a value.

Definition at line 582 of file SymbolTableBuilder.cpp.

583{
585}
const Type * inferObjType(const Value *var)
get or infer the type of the object pointed by the value

◆ inferTypeOfHeapObjOrStaticObj()

const Type * SymbolTableBuilder::inferTypeOfHeapObjOrStaticObj ( const Instruction inst)
protected

Get the reference type of heap/static object from an allocation site.

Return the type of the object from a heap allocation

Definition at line 590 of file SymbolTableBuilder.cpp.

591{
592 const Value* startValue = inst;
593 const PointerType *originalPType = SVFUtil::dyn_cast<PointerType>(inst->getType());
594 const Type* inferedType = nullptr;
595 assert(originalPType && "empty type?");
598 {
599 if(const Value* v = getFirstUseViaCastInst(inst))
600 {
601 if (const PointerType *newTy = SVFUtil::dyn_cast<PointerType>(v->getType()))
602 {
604 }
605 }
607 }
609 {
610 const CallBase* cs = LLVMUtil::getLLVMCallSite(inst);
611 u32_t arg_pos = SVFUtil::getHeapAllocHoldingArgPosition(SVFUtil::cast<SVFCallInst>(svfinst)->getCalledFunction());
612 const Value* arg = cs->getArgOperand(arg_pos);
613 originalPType = SVFUtil::dyn_cast<PointerType>(arg->getType());
615 }
616 else
617 {
618 assert( false && "not a heap allocation instruction?");
619 }
620
622
623 return inferedType;
624}
SVFInstruction * getSVFInstruction(const Instruction *inst) const
Definition LLVMModule.h:274
void typeSizeDiffTest(const PointerType *oPTy, const Type *iTy, const Value *val)
const Type * inferObjType(const Value *startValue)
Forward collect all possible infer sites starting from a value.
bool isHeapAllocExtCallViaRet(const Instruction *inst)
Definition LLVMUtil.cpp:617
bool isHeapAllocExtCallViaArg(const Instruction *inst)
Definition LLVMUtil.cpp:633
u32_t getHeapAllocHoldingArgPosition(const SVFFunction *fun)
Get the position of argument that holds an allocated heap object.
Definition SVFUtil.h:309
llvm::PointerType PointerType
Definition BasicTypes.h:96

◆ initTypeInfo()

void SymbolTableBuilder::initTypeInfo ( ObjTypeInfo typeinfo,
const Value val,
const Type objTy 
)
protected

Initialize TypeInfo based on LLVM Value.

Initialize the type info of an object

if val is AllocaInst, byteSize is Type's LLVM ByteSize * ArraySize e.g. alloc i32, 10. byteSize is 4 (i32's size) * 10 (ArraySize) = 40

This is for alloca <ty> <NumElements>. For example, alloca i64 3 allocates 3 i64 on the stack (objSize=3) In most cases, NumElements is not specified in the instruction, which means there is only one element (objSize=1).

if ArraySize is not constant, byteSize is not static determined.

if val is GlobalVar, byteSize is Type's LLVM ByteSize All GlobalVariable must have constant size

if val is heap alloc

Definition at line 848 of file SymbolTableBuilder.cpp.

850{
851
852 u32_t elemNum = 1;
853 // init byteSize = 0, If byteSize is changed in the following process,
854 // it means that ObjTypeInfo has a Constant Byte Size
855 u32_t byteSize = 0;
856 // Global variable
857 // if val is Function Obj, byteSize is not set
858 if (SVFUtil::isa<Function>(val))
859 {
861 analyzeObjType(typeinfo,val);
862 elemNum = getNumOfElements(objTy);
863 }
866 else if(const AllocaInst* allocaInst = SVFUtil::dyn_cast<AllocaInst>(val))
867 {
869 analyzeObjType(typeinfo,val);
872 if(const ConstantInt* sz = SVFUtil::dyn_cast<ConstantInt>(allocaInst->getArraySize()))
873 {
874 elemNum = sz->getZExtValue() * getNumOfElements(objTy);
875 byteSize = sz->getZExtValue() * typeinfo->getType()->getByteSize();
876 }
878 else
879 {
880 elemNum = getNumOfElements(objTy);
881 byteSize = 0;
882 }
883 }
886 else if(SVFUtil::isa<GlobalVariable>(val))
887 {
891 analyzeObjType(typeinfo,val);
892 elemNum = getNumOfElements(objTy);
893 byteSize = typeinfo->getType()->getByteSize();
894 }
896 else if (SVFUtil::isa<Instruction>(val) &&
898 SVFUtil::cast<Instruction>(val)))
899 {
900 elemNum = analyzeHeapObjType(typeinfo,val);
901 // analyze heap alloc like (malloc/calloc/...), the alloc functions have
902 // annotation like "AllocSize:Arg1". Please refer to extapi.c.
903 // e.g. calloc(4, 10), annotation is "AllocSize:Arg0*Arg1",
904 // it means byteSize = 4 (Arg0) * 10 (Arg1) = 40
905 byteSize = analyzeHeapAllocByteSize(val);
906 }
908 {
909 analyzeStaticObjType(typeinfo,val);
910 // user input data, label its field as infinite here
911 elemNum = typeinfo->getMaxFieldOffsetLimit();
912 byteSize = typeinfo->getType()->getByteSize();
913 }
915 {
917 elemNum = getNumOfFlattenElements(val->getType());
918 byteSize = typeinfo->getType()->getByteSize();
919 }
920 else
921 {
922 assert("what other object do we have??");
923 abort();
924 }
925
926 // Reset maxOffsetLimit if it is over the total fieldNum of this object
927 if(typeinfo->getMaxFieldOffsetLimit() > elemNum)
928 typeinfo->setNumOfElements(elemNum);
929
930 // set ByteSize. If ByteSize > 0, this typeinfo has constant type.
931 // If ByteSize == 0, this typeinfo has 1) zero byte 2) non-const byte size
932 // If ByteSize>MaxFieldLimit, set MaxFieldLimit to the byteSize;
933 byteSize = Options::MaxFieldLimit() > byteSize? byteSize: Options::MaxFieldLimit();
934 typeinfo->setByteSizeOfObj(byteSize);
935}
void setByteSizeOfObj(u32_t size)
Set the byte size of this object.
void setNumOfElements(u32_t num)
Set the number of elements of this object.
u32_t getByteSize() const
Definition SVFType.h:244
u32_t analyzeHeapObjType(ObjTypeInfo *typeinfo, const Value *val)
Analyse types of heap and static objects.
u32_t analyzeHeapAllocByteSize(const Value *val)
Analyze byte size of heap alloc function (e.g. malloc/calloc/...)
void analyzeStaticObjType(ObjTypeInfo *typeinfo, const Value *val)
Analyse types of heap and static objects.
bool isHeapAllocExtCall(const Instruction *inst)
Definition LLVMUtil.h:358
bool isConstDataOrAggData(const Value *val)
Return true if the value refers to constant data, e.g., i32 0.
Definition LLVMUtil.h:327
bool ArgInProgEntryFunction(const Value *val)
Return true if this is an argument of a program entry function (e.g. main)
Definition LLVMUtil.h:130
llvm::ConstantInt ConstantInt
Definition BasicTypes.h:125

Friends And Related Symbol Documentation

◆ SVFIRBuilder

Definition at line 46 of file SymbolTableBuilder.h.

Member Data Documentation

◆ symInfo

SymbolTableInfo* SVF::SymbolTableBuilder::symInfo
private

Definition at line 48 of file SymbolTableBuilder.h.


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