41 using namespace SVFUtil;
43 u32_t StInfo::maxFieldLimit = 0;
48 void ObjTypeInfo::analyzeGlobalStackObjType(
const Value* val)
52 assert(SVFUtil::isa<PointerType>(refty) &&
"this value should be a pointer type!");
53 Type* elemTy = refty->getElementType();
54 bool isPtrObj =
false;
56 while (
const ArrayType *AT= SVFUtil::dyn_cast<ArrayType>(elemTy))
58 elemTy = AT->getElementType();
59 if(elemTy->isPointerTy())
61 if(SVFUtil::isa<GlobalVariable>(val) && SVFUtil::cast<GlobalVariable>(val)->hasInitializer()
62 && SVFUtil::isa<ConstantArray>(SVFUtil::cast<GlobalVariable>(val)->getInitializer()))
64 setFlag(CONST_ARRAY_OBJ);
67 setFlag(VAR_ARRAY_OBJ);
69 if (
const StructType *ST= SVFUtil::dyn_cast<StructType>(elemTy))
71 const std::vector<FieldInfo>& flattenFields = SymbolTableInfo::SymbolInfo()->getFlattenFieldInfoVec(ST);
72 for(std::vector<FieldInfo>::const_iterator it = flattenFields.begin(), eit = flattenFields.end();
75 if((*it).getFlattenElemTy()->isPointerTy())
78 if(SVFUtil::isa<GlobalVariable>(val) && SVFUtil::cast<GlobalVariable>(val)->hasInitializer()
79 && SVFUtil::isa<ConstantStruct>(SVFUtil::cast<GlobalVariable>(val)->getInitializer()))
80 setFlag(CONST_STRUCT_OBJ);
82 setFlag(VAR_STRUCT_OBJ);
84 else if (elemTy->isPointerTy())
96 void ObjTypeInfo::analyzeHeapStaticObjType(
const Value*)
109 Type* ety = SVFUtil::cast<PointerType>(val->getType())->getElementType();
110 u32_t numOfFields = 1;
111 if (SVFUtil::isa<StructType>(ety) || SVFUtil::isa<ArrayType>(ety))
113 numOfFields = SymbolTableInfo::SymbolInfo()->getFlattenFieldInfoVec(ety).size();
121 void ObjTypeInfo::init(
const Value* val)
126 if (SVFUtil::isa<Function>(val))
128 setFlag(FUNCTION_OBJ);
129 analyzeGlobalStackObjType(val);
130 objSize = getObjSize(val);
132 else if(SVFUtil::isa<AllocaInst>(val))
135 analyzeGlobalStackObjType(val);
136 objSize = getObjSize(val);
138 else if(SVFUtil::isa<GlobalVariable>(val))
140 setFlag(GLOBVAR_OBJ);
141 if(SymbolTableInfo::SymbolInfo()->isConstantObjSym(val))
143 analyzeGlobalStackObjType(val);
144 objSize = getObjSize(val);
146 else if (SVFUtil::isa<Instruction>(val) &&
isHeapAllocExtCall(SVFUtil::cast<Instruction>(val)))
149 analyzeHeapStaticObjType(val);
153 else if (SVFUtil::isa<Instruction>(val) &&
isStaticExtCall(SVFUtil::cast<Instruction>(val)))
156 analyzeHeapStaticObjType(val);
163 analyzeHeapStaticObjType(val);
168 assert(
"what other object do we have??");
171 if(objSize > 0 && maxOffsetLimit > objSize)
172 maxOffsetLimit = objSize;
181 if (isHeap() || isStaticObj())
184 const Type* ety = getType();
185 while (
const ArrayType *AT= SVFUtil::dyn_cast<ArrayType>(ety))
187 ety = AT->getElementType();
190 if (SVFUtil::isa<StructType>(ety) || SVFUtil::isa<ArrayType>(ety))
192 bool hasIntersection =
false;
193 const vector<FieldInfo> &infovec = SymbolTableInfo::SymbolInfo()->getFlattenFieldInfoVec(ety);
194 vector<FieldInfo>::const_iterator it = infovec.begin();
195 vector<FieldInfo>::const_iterator eit = infovec.end();
196 for (; it != eit; ++it)
201 hasIntersection =
true;
206 assert(hasIntersection &&
"cannot find field of specified offset");
211 if (isStaticObj() || isHeap())
227 return (hasPtrObj() ==
false);
236 void MemObj::setFieldSensitive()
238 typeInfo->setMaxFieldOffsetLimit(StInfo::getMaxFieldLimit());
243 void MemObj::init(
const Type* type)
245 typeInfo =
new ObjTypeInfo(StInfo::getMaxFieldLimit(),type);
246 typeInfo->setFlag(ObjTypeInfo::HEAP_OBJ);
247 typeInfo->setFlag(ObjTypeInfo::HASPTR_OBJ);
254 refVal(val), GSymID(id), typeInfo(nullptr)
283 return type->getElementType();
312 gi != ge; ++gi, ++index)
314 if(SVFUtil::isa<ConstantInt>(gi.getOperand()) ==
false)
320 gi != ge; ++gi, ++index)
323 if (index <= baseIndex)
327 if (
const PointerType* pty = SVFUtil::dyn_cast<PointerType>(*gi))
329 const Type* et = pty->getElementType();
330 Size_t sz = getTypeSizeInBytes(et);
333 if (
const ArrayType* aty = SVFUtil::dyn_cast<ArrayType>(et))
334 num = aty->getNumElements();
341 else if(
const ArrayType* at = SVFUtil::dyn_cast<ArrayType>(*gi))
343 const Type* et = at->getElementType();
344 Size_t sz = getTypeSizeInBytes(et);
345 Size_t num = at->getNumElements();
349 assert(
false &&
"what other types?");
354 assert(SVFUtil::isa<ConstantInt>(gi.getOperand()) &&
"expecting a constant");
356 ConstantInt *op = SVFUtil::cast<ConstantInt>(gi.getOperand());
359 Size_t idx = op->getSExtValue();
364 if (
const PointerType* pty = SVFUtil::dyn_cast<PointerType>(*gi))
366 const Type* et = pty->getElementType();
367 Size_t sz = getTypeSizeInBytes(et);
371 else if(
const ArrayType* at = SVFUtil::dyn_cast<ArrayType>(*gi))
373 const Type* et = at->getElementType();
374 Size_t sz = getTypeSizeInBytes(et);
378 else if (
const StructType *ST = SVFUtil::dyn_cast<StructType>(*gi))
380 assert(op &&
"non-const struct index in GEP");
382 if ((
unsigned)idx >= so.size())
384 outs() <<
"!! Struct index out of bounds" << idx <<
"\n";
391 assert(
false &&
"what other types?");
497 if (SVFUtil::isa<StructType>(ety) || SVFUtil::isa<ArrayType>(ety))
501 std::vector<FieldInfo>::const_iterator it = infovec.begin();
502 std::vector<FieldInfo>::const_iterator eit = infovec.end();
503 for (; it != eit; ++it)
522 assert(
false &&
"cannot find an appropriate field for specified LocationSet");
556 writeWrnMsg(
"try to create a gep node with negative offset.");
557 offset = abs(offset);
561 offset = offset % maxOffset;
581 u32_t strideSize = 0;
582 FieldInfo::ElemNumStridePairVec::const_iterator pit = stinfo->
getFlattenFieldInfoVec().back().elemStridePairBegin();
583 FieldInfo::ElemNumStridePairVec::const_iterator epit = stinfo->
getFlattenFieldInfoVec().back().elemStridePairEnd();
584 for(; pit!=epit; ++pit)
585 strideSize += pit->first * pit->second;
589 assert((structSize == lastOff + strideSize + lastSize) &&
"struct size not consistent");
599 Type* ety = SVFUtil::cast<PointerType>(val->getType())->getElementType();
ObjTypeInfo * typeInfo
Type information of this object.
const Type * getFlattenElemTy() const
bool isBlackHoleObj() const
Whether it is a black hole object.
static bool isBlkObj(NodeID id)
bool intersects(const LocationSet &RHS) const
Return TRUE if we share any location in common with RHS.
void setByteOffset(Size_t os)
MemObj(const Value *val, SymID id)
Constructor.
void init(const Value *val)
Initialize the object.
bool ArgInProgEntryFunction(const Value *val)
Return true if this is an argument of a program entry function (e.g. main)
Size_t getByteOffset() const
llvm::PointerType PointerType
const llvm::Type * getType() const
Get obj type.
virtual LocationSet getModulusOffset(const MemObj *obj, const LocationSet &ls)
Given an offset from a Gep Instruction, return it modulus offset by considering memory layout...
llvm::ArrayType ArrayType
llvm::ConstantInt ConstantInt
virtual void collectArrayInfo(const ArrayType *T)
Collect the array info.
bool isConstantOffset() const
Return TRUE if this is a constant location set.
void writeWrnMsg(std::string msg)
Writes a message run through wrnMsg.
const std::vector< FieldInfo > & getFlattenFieldInfoVec(const Type *T)
void addElemNumStridePair(const NodePair &pair)
std::vector< FieldInfo > & getFlattenFieldInfoVec()
bridge_gep_iterator bridge_gep_begin(const User *GEP)
llvm::StructType StructType
LLVM types.
const std::vector< u32_t > & getFattenFieldOffsetVec(const Type *T)
const Type * getType() const
Get LLVM type.
static u32_t getMaxFieldLimit()
void verifyStructSize(StInfo *stInfo, u32_t structSize)
Verify struct size construction.
bool isStaticExtCall(const CallSite cs)
static SymbolTableInfo * SymbolInfo()
Singleton design here to make sure we only have one instance during any analysis. ...
static LSRelation checkRelation(const LocationSet &LHS, const LocationSet &RHS)
Check relations of two location sets.
bool isHeapAllocExtCall(const CallSite cs)
raw_ostream & outs()
Overwrite llvm::outs()
void destroy()
Clean up memory.
bridge_gep_iterator bridge_gep_end(const User *GEP)
u32_t getTypeSizeInBytes(const Type *type)
Helper method to get the size of the type from target data layout.
Size_t getOffset() const
Get methods.
const Value * refVal
The unique pointer value refer this object.
SymID GSymID
The unique id in the graph.
virtual void collectStructInfo(const StructType *T)
Collect the struct info.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
virtual bool computeGepOffset(const User *V, LocationSet &ls)
Compute gep offset.
Size_t getMaxFieldOffsetLimit() const
Get max field offset limit.
const Type * getTypeOfHeapAlloc(const llvm::Instruction *inst)
Get the type of the heap allocation.
u32_t getObjSize(const Value *val)
Get the size of this object.