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 (SVFIR *ir)
 Constructor.
 
void buildMemModel ()
 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)
 
LLVMModuleSetllvmModuleSet ()
 
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.
 
ObjTypeInfocreateBlkObjTypeInfo (NodeID symId)
 
ObjTypeInfocreateConstantObjTypeInfo (NodeID symId)
 

Private Attributes

SVFIRsvfir
 

Friends

class SVFIRBuilder
 

Detailed Description

Definition at line 44 of file SymbolTableBuilder.h.

Constructor & Destructor Documentation

◆ SymbolTableBuilder()

SVF::SymbolTableBuilder::SymbolTableBuilder ( SVFIR ir)
inline

Constructor.

Definition at line 52 of file SymbolTableBuilder.h.

52 : svfir(ir)
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 std::vector<const Value*> args;
747 // Heap alloc functions have annoation like "AllocSize:Arg1"
748 for (std::string annotation : llvmModuleSet()->getExtFuncAnnotations(calledFunction))
749 {
750 if (annotation.find("AllocSize:") != std::string::npos)
751 {
752 std::string allocSize = annotation.substr(10);
753 std::stringstream ss(allocSize);
754 std::string token;
755 // Analyaze annotation string and attract Arg list
756 while (std::getline(ss, token, '*'))
757 {
758 if (token.rfind("Arg", 0) == 0)
759 {
761 std::istringstream(token.substr(3)) >> argIndex;
763 {
764 args.push_back(
765 callInst->getArgOperand(argIndex));
766 }
767 }
768 }
769 }
770 }
771 u64_t product = 1;
772 if (args.size() > 0)
773 {
774 // for annotations like "AllocSize:Arg0*Arg1"
775 for (const llvm::Value* arg : args)
776 {
777 if (const llvm::ConstantInt* constIntArg =
778 llvm::dyn_cast<llvm::ConstantInt>(arg))
779 {
780 // Multiply the constant Value if all Args are const
782 }
783 else
784 {
785 // if Arg list has non-const value, return 0 to indicate it is non const byte size
786 return 0;
787 }
788 }
789 // If all the Args are const, return product
790 return product;
791 }
792 else
793 {
794 // for annotations like "AllocSize:UNKNOWN"
795 return 0;
796 }
797 }
798 }
799 // if it is not CallInst or CallInst has no CalledFunction, return 0 to indicate it is non const byte size
800 return 0;
801}
unsigned u32_t
Definition CommandLine.h:18
LLVMModuleSet * llvmModuleSet()
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
Definition LLVMUtil.h:82
unsigned long long u64_t
Definition GeneralType.h:49

◆ 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 806 of file SymbolTableBuilder.cpp.

807{
809 analyzeObjType(typeinfo, val);
810 const Type* objTy = llvmModuleSet()->getLLVMType(typeinfo->getType());
811 if(SVFUtil::isa<ArrayType>(objTy))
812 return getNumOfElements(objTy);
813 else if(const StructType* st = SVFUtil::dyn_cast<StructType>(objTy))
814 {
818 typeinfo->resetTypeForHeapStaticObj(llvmModuleSet()->getSVFType(
819 llvmModuleSet()->getTypeInference()->ptrType()));
820 else
821 return getNumOfElements(objTy);
822 }
823 return typeinfo->getMaxFieldOffsetLimit();
824}
const Type * getLLVMType(const SVFType *T) const
Get LLVM Type.
void resetTypeForHeapStaticObj(const SVFType *t)
Definition ObjTypeInfo.h:79
u32_t getMaxFieldOffsetLimit()
Get max field offset limit.
const SVFType * getType() const
Get LLVM type.
Definition ObjTypeInfo.h:98
void setFlag(MEMTYPE mask)
Flag for this object 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{
700 const Type *elemTy = llvmModuleSet()->getLLVMType(typeinfo->getType());
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 829 of file SymbolTableBuilder.cpp.

830{
832 {
834 analyzeObjType(typeinfo,castUse);
835 }
836 else
837 {
839 }
840}
const Value * getFirstUseViaCastInst(const Value *val)
Definition LLVMUtil.cpp:277
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:82

◆ buildMemModel()

void SymbolTableBuilder::buildMemModel ( )

Start building memory model.

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

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

Definition at line 78 of file SymbolTableBuilder.cpp.

79{
81
82 // Pointer #0 always represents the null pointer.
83 assert(svfir->totalSymNum++ == IRGraph::NullPtr && "Something changed!");
84
85 // Pointer #1 always represents the pointer points-to black hole.
86 assert(svfir->totalSymNum++ == IRGraph::BlkPtr && "Something changed!");
87
88 // Object #2 is black hole the object that may point to any object
89 assert(svfir->totalSymNum++ == IRGraph::BlackHole && "Something changed!");
91
92 // Object #3 always represents the unique constant of a program (merging all constants if Options::ModelConsts is disabled)
93 assert(svfir->totalSymNum++ == IRGraph::ConstantObj && "Something changed!");
95
96 for (Module &M : llvmModuleSet()->getLLVMModules())
97 {
98 // Add symbols for all the globals .
99 for (const GlobalVariable& gv : M.globals())
100 {
101 collectSym(&gv);
102 }
103
104 // Add symbols for all the global aliases
105 for (const GlobalAlias& ga : M.aliases())
106 {
107 collectSym(&ga);
108 collectSym(ga.getAliasee());
109 }
110
111 // Add symbols for all of the functions and the instructions in them.
112 for (const Function& fun : M.functions())
113 {
114 collectSym(&fun);
115 collectRet(&fun);
116 if (fun.getFunctionType()->isVarArg())
117 collectVararg(&fun);
118
119 // Add symbols for all formal parameters.
120 for (const Argument& arg : fun.args())
121 {
122 collectSym(&arg);
123 }
124
125 // collect and create symbols inside the function body
126 for (const Instruction& inst : instructions(fun))
127 {
128 collectSym(&inst);
129
130 // initialization for some special instructions
131 //{@
132 if (const StoreInst* st = SVFUtil::dyn_cast<StoreInst>(&inst))
133 {
134 collectSym(st->getPointerOperand());
135 collectSym(st->getValueOperand());
136 }
137 else if (const LoadInst* ld =
138 SVFUtil::dyn_cast<LoadInst>(&inst))
139 {
140 collectSym(ld->getPointerOperand());
141 }
142 else if (const AllocaInst* alloc =
143 SVFUtil::dyn_cast<AllocaInst>(&inst))
144 {
145 collectSym(alloc->getArraySize());
146 }
147 else if (const PHINode* phi = SVFUtil::dyn_cast<PHINode>(&inst))
148 {
149 for (u32_t i = 0; i < phi->getNumIncomingValues(); ++i)
150 {
151 collectSym(phi->getIncomingValue(i));
152 }
153 }
154 else if (const GetElementPtrInst* gep =
155 SVFUtil::dyn_cast<GetElementPtrInst>(&inst))
156 {
157 collectSym(gep->getPointerOperand());
158 for (u32_t i = 0; i < gep->getNumOperands(); ++i)
159 {
160 collectSym(gep->getOperand(i));
161 }
162 }
163 else if (const SelectInst* sel =
164 SVFUtil::dyn_cast<SelectInst>(&inst))
165 {
166 collectSym(sel->getTrueValue());
167 collectSym(sel->getFalseValue());
168 collectSym(sel->getCondition());
169 }
170 else if (const BinaryOperator* binary =
171 SVFUtil::dyn_cast<BinaryOperator>(&inst))
172 {
173 for (u32_t i = 0; i < binary->getNumOperands(); i++)
174 collectSym(binary->getOperand(i));
175 }
176 else if (const UnaryOperator* unary =
177 SVFUtil::dyn_cast<UnaryOperator>(&inst))
178 {
179 for (u32_t i = 0; i < unary->getNumOperands(); i++)
180 collectSym(unary->getOperand(i));
181 }
182 else if (const CmpInst* cmp = SVFUtil::dyn_cast<CmpInst>(&inst))
183 {
184 for (u32_t i = 0; i < cmp->getNumOperands(); i++)
185 collectSym(cmp->getOperand(i));
186 }
187 else if (const CastInst* cast =
188 SVFUtil::dyn_cast<CastInst>(&inst))
189 {
190 collectSym(cast->getOperand(0));
191 }
192 else if (const ReturnInst* ret =
193 SVFUtil::dyn_cast<ReturnInst>(&inst))
194 {
195 if (ret->getReturnValue())
196 collectSym(ret->getReturnValue());
197 }
198 else if (const BranchInst* br =
199 SVFUtil::dyn_cast<BranchInst>(&inst))
200 {
201 Value* opnd = br->isConditional() ? br->getCondition() : br->getOperand(0);
203 }
204 else if (const SwitchInst* sw =
205 SVFUtil::dyn_cast<SwitchInst>(&inst))
206 {
207 collectSym(sw->getCondition());
208 }
209 else if (const FreezeInst* fz = SVFUtil::dyn_cast<FreezeInst>(&inst))
210 {
211
212 for (u32_t i = 0; i < fz->getNumOperands(); i++)
213 {
214 Value* opnd = inst.getOperand(i);
216 }
217 }
218 else if (isNonInstricCallSite(&inst))
219 {
220
221 const CallBase* cs = LLVMUtil::getLLVMCallSite(&inst);
222 for (u32_t i = 0; i < cs->arg_size(); i++)
223 {
224 collectSym(cs->getArgOperand(i));
225 }
226 // Calls to inline asm need to be added as well because the
227 // callee isn't referenced anywhere else.
228 const Value* Callee = cs->getCalledOperand();
230
231 // TODO handle inlineAsm
234 {
236 }
237 }
239 }
240 }
241 }
242
245 {
247 }
248}
NodeID totalSymNum
total number of symbols
Definition IRGraph.h:101
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)
ObjTypeInfo * createBlkObjTypeInfo(NodeID symId)
ObjTypeInfo * createConstantObjTypeInfo(NodeID symId)
void collectSym(const Value *val)
void collectVararg(const Function *val)
const CallBase * getLLVMCallSite(const Value *value)
Return LLVM callsite given a value.
Definition LLVMUtil.h:91
bool isNonInstricCallSite(const Instruction *inst)
Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls.
Definition LLVMUtil.cpp:720
void increaseStackSize()
Increase the stack size limit.
Definition SVFUtil.cpp:229
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::FreezeInst FreezeInst
Definition BasicTypes.h:169
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 326 of file SymbolTableBuilder.cpp.

327{
329 LLVMModuleSet::ValueToIDMapTy::iterator iter = llvmModuleSet()->objSymMap.find(val);
330 if (iter == llvmModuleSet()->objSymMap.end())
331 {
332 // if the object pointed by the pointer is a constant data (e.g., i32 0) or a global constant object (e.g. string)
333 // then we treat them as one ConstantObj
335 {
336 llvmModuleSet()->objSymMap.insert(std::make_pair(val, svfir->constantSymID()));
337 }
338 // otherwise, we will create an object for each abstract memory location
339 else
340 {
341 // create obj sym and sym type
343 llvmModuleSet()->objSymMap.insert(std::make_pair(val, id));
345 outs() << "create a new obj sym " << id << "\n");
346
347 // create a memory object
349 assert(svfir->objTypeInfoMap.find(id) == svfir->objTypeInfoMap.end());
350 svfir->objTypeInfoMap[id] = ti;
351 }
352 }
353}
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:498
#define DMemModel
Definition SVFType.h:507
NodeID constantSymID() const
Definition IRGraph.h:188
IDToTypeInfoMapTy objTypeInfoMap
map a memory sym id to its obj
Definition IRGraph.h:88
ValueToIDMapTy objSymMap
map a obj reference to its sym id
Definition LLVMModule.h:113
NodeID allocateObjectId(void)
Allocate an object ID as determined by the strategy.
static Option< bool > ModelConsts
Definition Options.h:187
ObjTypeInfo * createObjTypeInfo(const Value *val)
Create an objectInfo based on LLVM value.
bool isConstantObjSym(const Value *val)
Check whether this value points-to a constant object.
Definition CppUtil.cpp:672
const Value * getGlobalRep(const Value *val)
find the unique defined global across multiple modules
Definition LLVMUtil.cpp:439
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
u32_t NodeID
Definition GeneralType.h:56

◆ collectRet()

void SymbolTableBuilder::collectRet ( const Function val)
protected

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

Definition at line 358 of file SymbolTableBuilder.cpp.

359{
360
361 LLVMModuleSet::FunToIDMapTy::iterator iter =
363 if (iter == llvmModuleSet()->returnSymMap.end())
364 {
366 llvmModuleSet()->returnSymMap.insert(std::make_pair(val, id));
367 DBOUT(DMemModel, outs() << "create a return sym " << id << "\n");
368 }
369}
FunToIDMapTy returnSymMap
return map
Definition LLVMModule.h:114
NodeID allocateValueId(void)
Allocate a value ID as determined by the strategy.

◆ collectSVFTypeInfo()

void SymbolTableBuilder::collectSVFTypeInfo ( const Value val)
protected

collect the syms

Definition at line 250 of file SymbolTableBuilder.cpp.

251{
252 Type *valType = val->getType();
254 if(isGepConstantExpr(val) || SVFUtil::isa<GetElementPtrInst>(val))
255 {
257 gi = bridge_gep_begin(SVFUtil::cast<User>(val)),
258 ge = bridge_gep_end(SVFUtil::cast<User>(val));
259 gi != ge; ++gi)
260 {
261 const Type* gepTy = *gi;
263 }
264 }
265}
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:215
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 270 of file SymbolTableBuilder.cpp.

271{
272
273 //TODO: filter the non-pointer type // if (!SVFUtil::isa<PointerType>(val->getType())) return;
274
276 outs()
277 << "collect sym from ##"
278 << llvmModuleSet()->getSVFValue(val)->toString()
279 << " \n");
280 //TODO handle constant expression value here??
281 handleCE(val);
282
283 // create a value sym
285
288
289 // create an object If it is a heap, stack, global, function.
290 if (isObject(val))
291 {
293 }
294}
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 299 of file SymbolTableBuilder.cpp.

300{
301 // collect and record special sym here
303 {
304 return;
305 }
306 LLVMModuleSet::ValueToIDMapTy::iterator iter = llvmModuleSet()->valSymMap.find(val);
307 if (iter == llvmModuleSet()->valSymMap.end())
308 {
309 // create val sym and sym type
311 llvmModuleSet()->valSymMap.insert(std::make_pair(val, id));
313 outs() << "create a new value sym " << id << "\n");
315 if (const GlobalVariable* globalVar = SVFUtil::dyn_cast<GlobalVariable>(val))
317 }
318
321}
ValueToIDMapTy valSymMap
map a value to its sym id
Definition LLVMModule.h:112
void handleGlobalCE(const GlobalVariable *G)
Handle constant expression.
bool isNullPtrSym(const Value *val)
Check whether this value is a black hole.
Definition LLVMUtil.h:125
bool isBlackholeSym(const Value *val)
Check whether this value is a black hole.
Definition LLVMUtil.h:119

◆ collectVararg()

void SymbolTableBuilder::collectVararg ( const Function val)
protected

Create vararg sym, if not available create a new one

Definition at line 374 of file SymbolTableBuilder.cpp.

375{
376 LLVMModuleSet::FunToIDMapTy::iterator iter =
378 if (iter == llvmModuleSet()->varargSymMap.end())
379 {
381 llvmModuleSet()->varargSymMap.insert(std::make_pair(val, id));
382 DBOUT(DMemModel, outs() << "create a vararg sym " << id << "\n");
383 }
384}
FunToIDMapTy varargSymMap
vararg map
Definition LLVMModule.h:115

◆ createBlkObjTypeInfo()

ObjTypeInfo * SymbolTableBuilder::createBlkObjTypeInfo ( NodeID  symId)
protected

Definition at line 46 of file SymbolTableBuilder.cpp.

47{
51 {
53 IntegerType::get(llvmset->getContext(), 32)));
55 }
57 return ti;
58}
ObjTypeInfo * createObjTypeInfo(const SVFType *type)
Create an objectInfo based on LLVM type (value is null, and type could be null, representing a dummy ...
Definition IRGraph.cpp:231
static bool isBlkObj(NodeID id)
Definition IRGraph.h:165

◆ createConstantObjTypeInfo()

ObjTypeInfo * SymbolTableBuilder::createConstantObjTypeInfo ( NodeID  symId)
protected

Definition at line 60 of file SymbolTableBuilder.cpp.

61{
65 {
67 llvmset->getSVFType(IntegerType::get(llvmset->getContext(), 32)));
69 }
71 return ti;
72}
static bool isConstantSym(NodeID id)
Definition IRGraph.h:169

◆ 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(
669 llvmModuleSet()->getSVFType(objTy),
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("(" + getSourceLoc(val) + ")");
680 {
681 ObjTypeInfo* typeInfo = new ObjTypeInfo(
682 llvmModuleSet()->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:622
const std::string getSourceLoc(const Value *val)
Definition LLVMUtil.cpp:452
std::ostream & errs()
Overwrite llvm::errs()
Definition SVFUtil.h:58
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:68
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 937 of file SymbolTableBuilder.cpp.

938{
939 assert(ety && "type is null?");
940 u32_t numOfFields = 1;
941 if (SVFUtil::isa<StructType, ArrayType>(ety))
942 {
944 }
945 return numOfFields;
946}
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 949 of file SymbolTableBuilder.cpp.

950{
953 else
955}
static 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 957 of file SymbolTableBuilder.cpp.

958{
960}
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 577 of file SymbolTableBuilder.cpp.

578{
580}
ObjTypeInference * getTypeInference()

◆ handleCE()

void SymbolTableBuilder::handleCE ( const Value val)
protected

Handle constant expression

Definition at line 389 of file SymbolTableBuilder.cpp.

390{
391 if (const Constant* ref = SVFUtil::dyn_cast<Constant>(val))
392 {
393 if (const ConstantExpr* ce = isGepConstantExpr(ref))
394 {
395 DBOUT(DMemModelCE, outs() << "handle constant expression "
396 << llvmModuleSet()
398 ->toString()
399 << "\n");
400 collectVal(ce);
401
402 // handle the recursive constant express case
403 // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
404 for (u32_t i = 0; i < ce->getNumOperands(); ++i)
405 {
406 collectVal(ce->getOperand(i));
407 handleCE(ce->getOperand(i));
408 }
409 }
410 else if (const ConstantExpr* ce = isCastConstantExpr(ref))
411 {
412 DBOUT(DMemModelCE, outs() << "handle constant expression "
413 << llvmModuleSet()
415 ->toString()
416 << "\n");
417 collectVal(ce);
418 collectVal(ce->getOperand(0));
419 // handle the recursive constant express case
420 // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
421 handleCE(ce->getOperand(0));
422 }
423 else if (const ConstantExpr* ce = isSelectConstantExpr(ref))
424 {
425 DBOUT(DMemModelCE, outs() << "handle constant expression "
426 << llvmModuleSet()
428 ->toString()
429 << "\n");
430 collectVal(ce);
431 collectVal(ce->getOperand(0));
432 collectVal(ce->getOperand(1));
433 collectVal(ce->getOperand(2));
434 // handle the recursive constant express case
435 // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
436 handleCE(ce->getOperand(0));
437 handleCE(ce->getOperand(1));
438 handleCE(ce->getOperand(2));
439 }
440 // if we meet a int2ptr, then it points-to black hole
442 {
444 const Constant* opnd = int2Ptrce->getOperand(0);
445 handleCE(opnd);
446 }
448 {
450 const Constant* opnd = ptr2Intce->getOperand(0);
451 handleCE(opnd);
452 }
454 {
456 }
457 else if (isBinaryConstantExpr(ref))
458 {
460 }
461 else if (isUnaryConstantExpr(ref))
462 {
463 // we don't handle unary constant expression like fneg(x) now
465 }
466 else if (SVFUtil::isa<ConstantAggregate>(ref))
467 {
468 // we don't handle constant aggregate like constant vectors
470 }
471 else
472 {
473 assert(!SVFUtil::isa<ConstantExpr>(val) &&
474 "we don't handle all other constant expression for now!");
476 }
477 }
478}
#define DMemModelCE
Definition SVFType.h:508
const ConstantExpr * isBinaryConstantExpr(const Value *val)
Definition LLVMUtil.h:290
const ConstantExpr * isInt2PtrConstantExpr(const Value *val)
Definition LLVMUtil.h:225
const ConstantExpr * isSelectConstantExpr(const Value *val)
Definition LLVMUtil.h:255
const ConstantExpr * isTruncConstantExpr(const Value *val)
Definition LLVMUtil.h:265
const ConstantExpr * isPtr2IntConstantExpr(const Value *val)
Definition LLVMUtil.h:235
const ConstantExpr * isUnaryConstantExpr(const Value *val)
Definition LLVMUtil.h:301
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition LLVMUtil.h:245
const ConstantExpr * isCmpConstantExpr(const Value *val)
Definition LLVMUtil.h:279
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 483 of file SymbolTableBuilder.cpp.

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

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

584{
586}
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 591 of file SymbolTableBuilder.cpp.

592{
593 const Value* startValue = inst;
594 const PointerType *originalPType = SVFUtil::dyn_cast<PointerType>(inst->getType());
595 const Type* inferedType = nullptr;
596 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 = LLVMUtil::getHeapAllocHoldingArgPosition(cs->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}
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:633
bool isHeapAllocExtCallViaArg(const Instruction *inst)
Definition LLVMUtil.cpp:648
u32_t getHeapAllocHoldingArgPosition(const Function *fun)
Definition LLVMUtil.cpp:400
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 845 of file SymbolTableBuilder.cpp.

847{
848
849 u32_t elemNum = 1;
850 // init byteSize = 0, If byteSize is changed in the following process,
851 // it means that ObjTypeInfo has a Constant Byte Size
852 u32_t byteSize = 0;
853 // Global variable
854 // if val is Function Obj, byteSize is not set
855 if (SVFUtil::isa<Function>(val))
856 {
858 analyzeObjType(typeinfo,val);
859 elemNum = getNumOfElements(objTy);
860 }
863 else if(const AllocaInst* allocaInst = SVFUtil::dyn_cast<AllocaInst>(val))
864 {
866 analyzeObjType(typeinfo,val);
869 if(const ConstantInt* sz = SVFUtil::dyn_cast<ConstantInt>(allocaInst->getArraySize()))
870 {
872 byteSize = LLVMUtil::getIntegerValue(sz).second * typeinfo->getType()->getByteSize();
873 }
875 else
876 {
877 elemNum = getNumOfElements(objTy);
878 byteSize = 0;
879 }
880 }
883 else if(SVFUtil::isa<GlobalVariable>(val))
884 {
888 analyzeObjType(typeinfo,val);
889 elemNum = getNumOfElements(objTy);
890 byteSize = typeinfo->getType()->getByteSize();
891 }
893 else if (SVFUtil::isa<Instruction>(val) &&
895 SVFUtil::cast<Instruction>(val)))
896 {
897 elemNum = analyzeHeapObjType(typeinfo,val);
898 // analyze heap alloc like (malloc/calloc/...), the alloc functions have
899 // annotation like "AllocSize:Arg1". Please refer to extapi.c.
900 // e.g. calloc(4, 10), annotation is "AllocSize:Arg0*Arg1",
901 // it means byteSize = 4 (Arg0) * 10 (Arg1) = 40
902 byteSize = analyzeHeapAllocByteSize(val);
903 }
905 {
906 analyzeStaticObjType(typeinfo,val);
907 // user input data, label its field as infinite here
908 elemNum = typeinfo->getMaxFieldOffsetLimit();
909 byteSize = typeinfo->getType()->getByteSize();
910 }
912 {
914 elemNum = getNumOfFlattenElements(val->getType());
915 byteSize = typeinfo->getType()->getByteSize();
916 }
917 else
918 {
919 assert("what other object do we have??");
920 abort();
921 }
922
923 // Reset maxOffsetLimit if it is over the total fieldNum of this object
924 if(typeinfo->getMaxFieldOffsetLimit() > elemNum)
925 typeinfo->setNumOfElements(elemNum);
926
927 // set ByteSize. If ByteSize > 0, this typeinfo has constant type.
928 // If ByteSize == 0, this typeinfo has 1) zero byte 2) non-const byte size
929 // If ByteSize>MaxFieldLimit, set MaxFieldLimit to the byteSize;
930 byteSize = Options::MaxFieldLimit() > byteSize? byteSize: Options::MaxFieldLimit();
931 typeinfo->setByteSizeOfObj(byteSize);
932}
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:396
bool isConstDataOrAggData(const Value *val)
Return true if the value refers to constant data, e.g., i32 0.
Definition LLVMUtil.h:368
bool ArgInProgEntryFunction(const Value *val)
Return true if this is an argument of a program entry function (e.g. main)
Definition LLVMUtil.h:164
llvm::ConstantInt ConstantInt
Definition BasicTypes.h:125

◆ llvmModuleSet()

LLVMModuleSet * SVF::SymbolTableBuilder::llvmModuleSet ( )
inlineprotected

Definition at line 87 of file SymbolTableBuilder.h.

88 {
90 }
static LLVMModuleSet * getLLVMModuleSet()
Definition LLVMModule.h:129

Friends And Related Symbol Documentation

◆ SVFIRBuilder

Definition at line 46 of file SymbolTableBuilder.h.

Member Data Documentation

◆ svfir

SVFIR* SVF::SymbolTableBuilder::svfir
private

Definition at line 48 of file SymbolTableBuilder.h.


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