Static Value-Flow Analysis
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. More...
 
void buildMemModel (SVFModule *svfModule)
 Start building memory model. More...
 
u32_t getNumOfElements (const Type *ety)
 Return size of this object based on LLVM value. More...
 

Protected Member Functions

void collectSVFTypeInfo (const Value *val)
 collect the syms More...
 
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. More...
 
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. More...
 
const TypeinferTypeOfHeapObjOrStaticObj (const Instruction *inst)
 Get the reference type of heap/static object from an allocation site. More...
 
ObjTypeInfocreateObjTypeInfo (const Value *val)
 Create an objectInfo based on LLVM value. More...
 
void initTypeInfo (ObjTypeInfo *typeinfo, const Value *value, const Type *ty)
 Initialize TypeInfo based on LLVM Value. More...
 
void analyzeObjType (ObjTypeInfo *typeinfo, const Value *val)
 Analyse types of all flattened fields of this object. More...
 
u32_t analyzeHeapObjType (ObjTypeInfo *typeinfo, const Value *val)
 Analyse types of heap and static objects. More...
 
void analyzeStaticObjType (ObjTypeInfo *typeinfo, const Value *val)
 Analyse types of heap and static objects. More...
 
u32_t analyzeHeapAllocByteSize (const Value *val)
 Analyze byte size of heap alloc function (e.g. malloc/calloc/...) More...
 
u32_t getNumOfFlattenElements (const Type *T)
 Number of flattened elements of an array or struct. More...
 
StInfogetOrAddSVFTypeInfo (const Type *T)
 Get a reference to StructInfo. More...
 
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  }
SymbolTableInfo * symInfo

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_RET"), annotate("AllocSize:Arg0"))) void* safe_malloc(unsigned long size). Byte Size is the size(Arg0) 2)__attribute__((annotate("ALLOC_RET"), annotate("AllocSize:Arg0*Arg1"))) char* safecalloc(int a, int b) Byte Size is a(Arg0) * b(Arg1) 3)__attribute__((annotate("ALLOC_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 =
748  calledFunction);
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  {
763  u32_t argIndex;
764  std::istringstream(token.substr(3)) >> argIndex;
765  if (argIndex < callInst->getNumOperands() - 1)
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
const char *const string
Definition: cJSON.h:172
static ExtAPI * getExtAPI()
Definition: ExtAPI.cpp:42
SVFFunction * getSVFFunction(const Function *fun) const
Definition: LLVMModule.h:230
static LLVMModuleSet * getLLVMModuleSet()
Definition: LLVMModule.h:118
unsigned long long u64_t
Definition: GeneralType.h:48
llvm::Function Function
Definition: BasicTypes.h:85
llvm::Value Value
LLVM Basic classes.
Definition: BasicTypes.h:82
llvm::CallInst CallInst
Definition: BasicTypes.h:147
llvm::ConstantInt ConstantInt
Definition: BasicTypes.h:125

◆ 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 {
811  typeinfo->setFlag(ObjTypeInfo::HEAP_OBJ);
812  analyzeObjType(typeinfo, val);
813  const Type* objTy = LLVMModuleSet::getLLVMModuleSet()->getLLVMType(typeinfo->getType());
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 {
700  const Type *elemTy = LLVMModuleSet::getLLVMModuleSet()->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 832 of file SymbolTableBuilder.cpp.

833 {
834  if(const Value* castUse = getFirstUseViaCastInst(val))
835  {
836  typeinfo->setFlag(ObjTypeInfo::STATIC_OBJ);
837  analyzeObjType(typeinfo,castUse);
838  }
839  else
840  {
841  typeinfo->setFlag(ObjTypeInfo::HEAP_OBJ);
842  }
843 }
const Value * getFirstUseViaCastInst(const Value *val)
Definition: LLVMUtil.cpp:279

◆ 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);
201  collectSym(opnd);
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();
219  collectSym(Callee);
220 
221  // TODO handle inlineAsm
224  {
226  }
227  }
229  }
230  }
231  }
232 
234  if (Options::SymTabPrint())
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:649
void increaseStackSize()
Increase the stack size limit.
Definition: SVFUtil.cpp:227
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::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 {
320  val = LLVMUtil::getGlobalRep(val);
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 =
343  new MemObj(id, createObjTypeInfo(val),
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:417
bool isConstantObjSym(const SVFValue *val)
Check whether this value points-to a constant object.
Definition: LLVMUtil.cpp:579
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 =
359  symInfo->returnSymMap.find(svffun);
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();
243  (void)getOrAddSVFTypeInfo(valType);
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;
252  (void)getOrAddSVFTypeInfo(gepTy);
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
274  collectVal(val);
275 
276  collectSVFTypeInfo(val);
278 
279  // create an object If it is a heap, stack, global, function.
280  if (isObject(val))
281  {
282  collectObj(val);
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))
308  handleGlobalCE(globalVar);
309  }
310 
311  if (isConstantObjSym(val))
312  collectObj(val);
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 =
376  symInfo->varargSymMap.find(svffun);
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 }
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
LLVMContext & getContext() const
Definition: LLVMModule.h:349
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 {
61  assert(symInfo->isConstantObj(symId));
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  {
659  SVFUtil::errs() << dumpValueAndDbgInfo(val) << "\n";
660  assert(false && "not an allocation or global?");
661  }
662  }
663  }
664 
665  if (objTy)
666  {
667  (void) getOrAddSVFTypeInfo(objTy);
668  ObjTypeInfo* typeInfo = new ObjTypeInfo(
669  LLVMModuleSet::getLLVMModuleSet()->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("(" + LLVMModuleSet::getLLVMModuleSet()->getSVFValue(val)->getSourceLoc() + ")");
679  if (isConstantObjSym(val))
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:607
const std::string getSourceLoc(const Value *val)
Definition: LLVMUtil.cpp:430
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition: SVFUtil.cpp:66
std::ostream & errs()
Overwrite llvm::errs()
Definition: SVFUtil.h:56
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  {
946  numOfFields = getNumOfFlattenElements(ety);
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 }
StInfo * getTypeInfo()
Definition: SVFType.h:230

◆ getTypeInference()

ObjTypeInference * SymbolTableBuilder::getTypeInference ( )
protected

Definition at line 576 of file SymbolTableBuilder.cpp.

577 {
579 }
ObjTypeInference * getTypeInference()
Definition: LLVMModule.cpp:97

◆ 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
440  else if (const ConstantExpr* int2Ptrce = isInt2PtrConstantExpr(ref))
441  {
442  collectVal(int2Ptrce);
443  const Constant* opnd = int2Ptrce->getOperand(0);
444  handleCE(opnd);
445  }
446  else if (const ConstantExpr* ptr2Intce = isPtr2IntConstantExpr(ref))
447  {
448  collectVal(ptr2Intce);
449  const Constant* opnd = ptr2Intce->getOperand(0);
450  handleCE(opnd);
451  }
452  else if (isTruncConstantExpr(ref) || isCmpConstantExpr(ref))
453  {
454  collectVal(ref);
455  }
456  else if (isBinaryConstantExpr(ref))
457  {
458  collectVal(ref);
459  }
460  else if (isUnaryConstantExpr(ref))
461  {
462  // we don't handle unary constant expression like fneg(x) now
463  collectVal(ref);
464  }
465  else if (SVFUtil::isa<ConstantAggregate>(ref))
466  {
467  // we don't handle constant aggregate like constant vectors
468  collectVal(ref);
469  }
470  else
471  {
472  assert(!SVFUtil::isa<ConstantExpr>(val) &&
473  "we don't handle all other constant expression for now!");
474  collectVal(ref);
475  }
476  }
477 }
#define DMemModelCE
Definition: SVFType.h:494
const ConstantExpr * isUnaryConstantExpr(const Value *val)
Definition: LLVMUtil.h:267
const ConstantExpr * isPtr2IntConstantExpr(const Value *val)
Definition: LLVMUtil.h:201
const ConstantExpr * isBinaryConstantExpr(const Value *val)
Definition: LLVMUtil.h:256
const ConstantExpr * isTruncConstantExpr(const Value *val)
Definition: LLVMUtil.h:231
const ConstantExpr * isCmpConstantExpr(const Value *val)
Definition: LLVMUtil.h:245
const ConstantExpr * isInt2PtrConstantExpr(const Value *val)
Definition: LLVMUtil.h:191
const ConstantExpr * isSelectConstantExpr(const Value *val)
Definition: LLVMUtil.h:221
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition: LLVMUtil.h:211
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  {
551  if (Options::ModelConsts())
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 {
584  return getTypeInference()->inferObjType(startValue);
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  {
603  originalPType = newTy;
604  }
605  }
606  inferedType = inferObjType(startValue);
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());
614  inferedType = inferObjType(startValue = arg);
615  }
616  else
617  {
618  assert( false && "not a heap allocation instruction?");
619  }
620 
621  getTypeInference()->typeSizeDiffTest(originalPType, inferedType, startValue);
622 
623  return inferedType;
624 }
SVFInstruction * getSVFInstruction(const Instruction *inst) const
Definition: LLVMModule.h:244
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:618
bool isHeapAllocExtCallViaArg(const Instruction *inst)
Definition: LLVMUtil.cpp:634
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  {
868  typeinfo->setFlag(ObjTypeInfo::STACK_OBJ);
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  {
889  if(isConstantObjSym(val))
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  }
907  else if(ArgInProgEntryFunction(val))
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  }
914  else if(LLVMUtil::isConstDataOrAggData(val))
915  {
916  typeinfo->setFlag(ObjTypeInfo::CONST_DATA);
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

Friends And Related Function Documentation

◆ SVFIRBuilder

friend class SVFIRBuilder
friend

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: