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)
 
LLVMModuleSet * llvmModuleSet ()
 
ObjTypeInference * getTypeInference ()
 
const Type * inferObjType (const Value *startValue)
 Forward collect all possible infer sites starting from a value.
 
const Type * inferTypeOfHeapObjOrStaticObj (const Instruction *inst)
 Get the reference type of heap/static object from an allocation site.
 
ObjTypeInfo * createObjTypeInfo (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.
 
StInfo * getOrAddSVFTypeInfo (const Type *T)
 Get a reference to StructInfo.
 
ObjTypeInfo * createBlkObjTypeInfo (NodeID symId)
 
ObjTypeInfo * createConstantObjTypeInfo (NodeID symId)
 

Private Attributes

SVFIR * svfir
 

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

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

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

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

804{
806 analyzeObjType(typeinfo, val);
807 const Type* objTy = llvmModuleSet()->getLLVMType(typeinfo->getType());
808 if(SVFUtil::isa<ArrayType>(objTy))
809 return getNumOfElements(objTy);
810 else if(const StructType* st = SVFUtil::dyn_cast<StructType>(objTy))
811 {
815 typeinfo->resetTypeForHeapStaticObj(llvmModuleSet()->getSVFType(
816 llvmModuleSet()->getTypeInference()->ptrType()));
817 else
818 return getNumOfElements(objTy);
819 }
820 return typeinfo->getMaxFieldOffsetLimit();
821}
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:581
llvm::Type Type
Definition BasicTypes.h:87
llvm::StructType StructType
LLVM types.
Definition BasicTypes.h:98

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

696{
697 const Type *elemTy = llvmModuleSet()->getLLVMType(typeinfo->getType());
698 // Find the inter nested array element
699 while (const ArrayType* AT = SVFUtil::dyn_cast<ArrayType>(elemTy))
700 {
701 elemTy = AT->getElementType();
702 if (SVFUtil::isa<GlobalVariable>(val) &&
703 SVFUtil::cast<GlobalVariable>(val)->hasInitializer() &&
704 SVFUtil::isa<ConstantArray>(
705 SVFUtil::cast<GlobalVariable>(val)->getInitializer()))
707 else
709 }
710 if (SVFUtil::isa<StructType>(elemTy))
711 {
712 if (SVFUtil::isa<GlobalVariable>(val) &&
713 SVFUtil::cast<GlobalVariable>(val)->hasInitializer() &&
714 SVFUtil::isa<ConstantStruct>(
715 SVFUtil::cast<GlobalVariable>(val)->getInitializer()))
717 else
719 }
720}
llvm::ArrayType ArrayType
Definition BasicTypes.h:99

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

827{
829 {
831 analyzeObjType(typeinfo,castUse);
832 }
833 else
834 {
836 }
837}
const Value * getFirstUseViaCastInst(const Value *val)
Definition LLVMUtil.cpp:279
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:86

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

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

◆ collectObj()

void SymbolTableBuilder::collectObj ( const Value *  val)
protected

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

Definition at line 330 of file SymbolTableBuilder.cpp.

331{
333 LLVMModuleSet::ValueToIDMapTy::iterator iter = llvmModuleSet()->objSymMap.find(val);
334 if (iter == llvmModuleSet()->objSymMap.end())
335 {
336 // if the object pointed by the pointer is a constant data (e.g., i32 0) or a global constant object (e.g. string)
337 // then we treat them as one ConstantObj
338 // the IR features can't be modelled, like Blockaddress still maps to the ConstantObj
339 const bool mcUnmodelled = isConstDataOrAggData(val) && val->getType()->isPointerTy();
341 {
342 llvmModuleSet()->objSymMap.insert(std::make_pair(val, svfir->constantSymID()));
343 }
344 // otherwise, we will create an object for each abstract memory location
345 else
346 {
347 // create obj sym and sym type
349 llvmModuleSet()->objSymMap.insert(std::make_pair(val, id));
351 outs() << "create a new obj sym " << id << "\n");
352
353 // create a memory object
355 assert(svfir->objTypeInfoMap.find(id) == svfir->objTypeInfoMap.end());
356 svfir->objTypeInfoMap[id] = ti;
357 }
358 }
359}
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define DMemModel
Definition SVFType.h:585
NodeID constantSymID() const
Definition IRGraph.h:192
IDToTypeInfoMapTy objTypeInfoMap
map a memory sym id to its obj
Definition IRGraph.h:86
ValueToIDMapTy objSymMap
map a obj reference to its sym id
Definition LLVMModule.h:121
NodeID allocateObjectId(void)
Allocate an object ID as determined by the strategy.
static Option< bool > ModelConsts
Definition Options.h:178
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:684
bool isConstDataOrAggData(const Value *val)
Return true if the value refers to constant data, e.g., i32 0.
Definition LLVMUtil.h:415
const Value * getGlobalRep(const Value *val)
find the unique defined global across multiple modules
Definition LLVMUtil.cpp:441
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:58
u32_t NodeID
Definition GeneralType.h:76

◆ collectRet()

void SymbolTableBuilder::collectRet ( const Function *  val)
protected

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

Definition at line 364 of file SymbolTableBuilder.cpp.

365{
366
367 LLVMModuleSet::FunToIDMapTy::iterator iter =
369 if (iter == llvmModuleSet()->returnSymMap.end())
370 {
372 llvmModuleSet()->returnSymMap.insert(std::make_pair(val, id));
373 DBOUT(DMemModel, outs() << "create a return sym " << id << "\n");
374 }
375}
FunToIDMapTy returnSymMap
return map
Definition LLVMModule.h:122
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 252 of file SymbolTableBuilder.cpp.

253{
254 Type *valType = val->getType();
256 if(isGepConstantExpr(val) || SVFUtil::isa<GetElementPtrInst>(val))
257 {
259 gi = bridge_gep_begin(SVFUtil::cast<User>(val)),
260 ge = bridge_gep_end(SVFUtil::cast<User>(val));
261 gi != ge; ++gi)
262 {
263 const Type* gepTy = *gi;
265 }
266 }
267}
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:235
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 272 of file SymbolTableBuilder.cpp.

273{
274
275 //TODO: filter the non-pointer type // if (!SVFUtil::isa<PointerType>(val->getType())) return;
276
278 outs() << "collect sym from ##" << LLVMUtil::dumpValue(val) << "\n");
279 //TODO handle constant expression value here??
280 handleCE(val);
281
282 // create a value sym
284
287
288 // create an object If it is a heap, stack, global, function.
289 if (isObject(val))
290 {
292 }
293}
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:61
std::string dumpValue(const Value *val)
Definition LLVMUtil.cpp:616

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

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

◆ collectVararg()

void SymbolTableBuilder::collectVararg ( const Function *  val)
protected

Create vararg sym, if not available create a new one

Definition at line 380 of file SymbolTableBuilder.cpp.

381{
382 LLVMModuleSet::FunToIDMapTy::iterator iter =
384 if (iter == llvmModuleSet()->varargSymMap.end())
385 {
387 llvmModuleSet()->varargSymMap.insert(std::make_pair(val, id));
388 DBOUT(DMemModel, outs() << "create a vararg sym " << id << "\n");
389 }
390}
FunToIDMapTy varargSymMap
vararg map
Definition LLVMModule.h:123

◆ createBlkObjTypeInfo()

ObjTypeInfo * SymbolTableBuilder::createBlkObjTypeInfo ( NodeID  symId)
protected

Definition at line 46 of file SymbolTableBuilder.cpp.

47{
51 {
53 IntegerType::get(llvmset->getContext(), 32)));
56 }
58 return ti;
59}
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:248
static bool isBlkObj(NodeID id)
Definition IRGraph.h:164
void setNumOfElements(u32_t num)
Set the number of elements of this object.

◆ createConstantObjTypeInfo()

ObjTypeInfo * SymbolTableBuilder::createConstantObjTypeInfo ( NodeID  symId)
protected

Definition at line 61 of file SymbolTableBuilder.cpp.

62{
66 {
68 llvmset->getSVFType(IntegerType::get(llvmset->getContext(), 32)));
71 }
73 return ti;
74}
static bool isConstantSym(NodeID id)
Definition IRGraph.h:173

◆ createObjTypeInfo()

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

Create an objectInfo based on LLVM value.

Definition at line 626 of file SymbolTableBuilder.cpp.

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

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

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

947{
950 else
952}
static Option< bool > ModelArrays
Definition Options.h:179
u32_t getNumOfFlattenElements() const
Return number of elements after flattening (including array elements)
Definition SVFType.h:164
u32_t getNumOfFlattenFields() const
Return the number of fields after flattening (ignoring array elements)
Definition SVFType.h:170

◆ getOrAddSVFTypeInfo()

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

Get a reference to StructInfo.

Definition at line 954 of file SymbolTableBuilder.cpp.

955{
957}
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
StInfo * getTypeInfo()
Definition SVFType.h:273

◆ getTypeInference()

ObjTypeInference * SymbolTableBuilder::getTypeInference ( )
protected

Definition at line 574 of file SymbolTableBuilder.cpp.

575{
577}
ObjTypeInference * getTypeInference()

◆ handleCE()

void SymbolTableBuilder::handleCE ( const Value *  val)
protected

Handle constant expression

Definition at line 395 of file SymbolTableBuilder.cpp.

396{
397 if (const Constant* ref = SVFUtil::dyn_cast<Constant>(val))
398 {
399 if (const ConstantExpr* ce = isGepConstantExpr(ref))
400 {
401 DBOUT(DMemModelCE, outs() << "handle constant expression "
402 << LLVMUtil::dumpValue(ref) << "\n");
403 collectVal(ce);
404
405 // handle the recursive constant express case
406 // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
407 for (u32_t i = 0; i < ce->getNumOperands(); ++i)
408 {
409 collectVal(ce->getOperand(i));
410 handleCE(ce->getOperand(i));
411 }
412 }
413 else if (const ConstantExpr* ce = isCastConstantExpr(ref))
414 {
415 DBOUT(DMemModelCE, outs() << "handle constant expression "
416 << LLVMUtil::dumpValue(ref) << "\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 << LLVMUtil::dumpValue(ref) << "\n");
427 collectVal(ce);
428 collectVal(ce->getOperand(0));
429 collectVal(ce->getOperand(1));
430 collectVal(ce->getOperand(2));
431 // handle the recursive constant express case
432 // like (gep (bitcast (gep X 1)) 1); the inner gep is ce->getOperand(0)
433 handleCE(ce->getOperand(0));
434 handleCE(ce->getOperand(1));
435 handleCE(ce->getOperand(2));
436 }
437 // if we meet a int2ptr, then it points-to black hole
439 {
441 const Constant* opnd = int2Ptrce->getOperand(0);
442 handleCE(opnd);
443 }
445 {
447 const Constant* opnd = ptr2Intce->getOperand(0);
448 handleCE(opnd);
449 }
451 {
453 }
454 else if (isBinaryConstantExpr(ref))
455 {
457 }
458 else if (isUnaryConstantExpr(ref))
459 {
460 // we don't handle unary constant expression like fneg(x) now
462 }
463 else if (SVFUtil::isa<ConstantAggregate>(ref))
464 {
465 // we don't handle constant aggregate like constant vectors
467 }
468 else
469 {
470 assert(!SVFUtil::isa<ConstantExpr>(val) &&
471 "we don't handle all other constant expression for now!");
473 }
474 }
475}
#define DMemModelCE
Definition SVFType.h:586
const ConstantExpr * isBinaryConstantExpr(const Value *val)
Definition LLVMUtil.h:310
const ConstantExpr * isInt2PtrConstantExpr(const Value *val)
Definition LLVMUtil.h:245
const ConstantExpr * isSelectConstantExpr(const Value *val)
Definition LLVMUtil.h:275
const ConstantExpr * isTruncConstantExpr(const Value *val)
Definition LLVMUtil.h:285
const ConstantExpr * isPtr2IntConstantExpr(const Value *val)
Definition LLVMUtil.h:255
const ConstantExpr * isUnaryConstantExpr(const Value *val)
Definition LLVMUtil.h:321
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition LLVMUtil.h:265
const ConstantExpr * isCmpConstantExpr(const Value *val)
Definition LLVMUtil.h:299
llvm::Constant Constant
Definition BasicTypes.h:128
llvm::ConstantExpr ConstantExpr
Definition BasicTypes.h:124

◆ handleGlobalCE()

void SymbolTableBuilder::handleGlobalCE ( const GlobalVariable *  G)
protected

Handle constant expression.

Handle global constant expression

Definition at line 480 of file SymbolTableBuilder.cpp.

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

◆ handleGlobalInitializerCE()

void SymbolTableBuilder::handleGlobalInitializerCE ( const Constant *  C)
protected

Handle global variable initialization

Definition at line 519 of file SymbolTableBuilder.cpp.

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

◆ inferObjType()

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

Forward collect all possible infer sites starting from a value.

Definition at line 580 of file SymbolTableBuilder.cpp.

581{
583}
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 588 of file SymbolTableBuilder.cpp.

589{
590 const Value* startValue = inst;
591 const PointerType *originalPType = SVFUtil::dyn_cast<PointerType>(inst->getType());
592 const Type* inferedType = nullptr;
593 assert(originalPType && "empty type?");
595 {
596 if(const Value* v = getFirstUseViaCastInst(inst))
597 {
598 if (const PointerType *newTy = SVFUtil::dyn_cast<PointerType>(v->getType()))
599 {
601 }
602 }
604 }
606 {
607 const CallBase* cs = LLVMUtil::getLLVMCallSite(inst);
608 u32_t arg_pos = LLVMUtil::getHeapAllocHoldingArgPosition(cs->getCalledFunction());
609 const Value* arg = cs->getArgOperand(arg_pos);
610 originalPType = SVFUtil::dyn_cast<PointerType>(arg->getType());
612 }
613 else
614 {
615 assert( false && "not a heap allocation instruction?");
616 }
617
619
620 return inferedType;
621}
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:649
bool isHeapAllocExtCallViaArg(const Instruction *inst)
Definition LLVMUtil.cpp:664
u32_t getHeapAllocHoldingArgPosition(const Function *fun)
Definition LLVMUtil.cpp:402
llvm::PointerType PointerType
Definition BasicTypes.h:100

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

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

◆ llvmModuleSet()

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

Definition at line 87 of file SymbolTableBuilder.h.

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

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: