Skip to content

Commit

Permalink
2nd PR. Add SVF's byte size and fix some api use (#1260)
Browse files Browse the repository at this point in the history
* 1. add LLVM Byte size helper functions to AddrStmt
2. add MaxByteLimit Option

* 1) remove superfluous apis in AddrStmt, to improve coverage
2) add isStaticDeterminedByteSize and getByteSizeOfObj in ObjTypeInfo (with getter/setter) and MemObj(only getter)
3) fulfill SymbolTableBuilder::initTypeInfo() to init the ByteSize related field

* remove MaxByteLimit Option

* 1) rename staticDetermined -> ConstantOffset
2) fix a bug in IntervalValue compare Op
3) remove ConstantOffset bool flag. Instead, if byteSize != 0, it is signal of constant offset. If byteSize = 0, it can be zero byte size or non-const offset.
4) add analyzeHeapAllocByteSize(const Value*), which accepts a CallInst like (malloc/calloc/..) and analyze the allocation byte Size of heap function
5) remove the hard code (99999) of maxByteLimit in SVFIR2ItvExeState::getBytefromGepTypePair, and replace it with Options::MaxFieldLimit()

* 1) remove getLLVMByteSize
2) add getByteSize and SetByteSize in SVFType

* fix CI compile err

* fix interval cmp err

* imporve the efficiency of function's annotation processing

* merge with master

* refactor GepStmt's API

* remove setByteSize() and move assignments to Constructor

* switch the order of SVFOtherType's constructor arguments

* rename and refactor some api related to GepStmt

---------

Co-authored-by: jiawei.wang <[email protected]>
  • Loading branch information
bjjwwang and jiawei.wang authored Nov 28, 2023
1 parent e179327 commit 914e226
Show file tree
Hide file tree
Showing 12 changed files with 232 additions and 217 deletions.
20 changes: 15 additions & 5 deletions svf-llvm/lib/LLVMModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1256,14 +1256,23 @@ SVFType* LLVMModuleSet::addSVFTypeInfo(const Type* T)
assert(LLVMType2SVFType.find(T) == LLVMType2SVFType.end() &&
"SVFType has been added before");

// add SVFType's LLVM byte size iff T isSized(), otherwise byteSize is 0(default value)
u32_t byteSize = 0;
if (T->isSized()) {
const llvm::DataLayout &DL = LLVMModuleSet::getLLVMModuleSet()->
getMainLLVMModule()->getDataLayout();
Type *mut_T = const_cast<Type *>(T);
byteSize = DL.getTypeAllocSize(mut_T);
}

SVFType* svftype;
if (SVFUtil::isa<PointerType>(T))
{
svftype = new SVFPointerType();
svftype = new SVFPointerType(byteSize);
}
else if (const IntegerType* intT = SVFUtil::dyn_cast<IntegerType>(T))
{
auto svfIntT = new SVFIntegerType();
auto svfIntT = new SVFIntegerType(byteSize);
unsigned signWidth = intT->getBitWidth();
assert(signWidth < INT16_MAX && "Integer width too big");
svfIntT->setSignAndWidth(intT->getSignBit() ? -signWidth : signWidth);
Expand All @@ -1273,22 +1282,22 @@ SVFType* LLVMModuleSet::addSVFTypeInfo(const Type* T)
svftype = new SVFFunctionType(getSVFType(ft->getReturnType()));
else if (const StructType* st = SVFUtil::dyn_cast<StructType>(T))
{
auto svfst = new SVFStructType();
auto svfst = new SVFStructType(byteSize);
if (st->hasName())
svfst->setName(st->getName().str());
svftype = svfst;
}
else if (const auto at = SVFUtil::dyn_cast<ArrayType>(T))
{
auto svfat = new SVFArrayType();
auto svfat = new SVFArrayType(byteSize);
svfat->setNumOfElement(at->getNumElements());
svfat->setTypeOfElement(getSVFType(at->getElementType()));
svftype = svfat;
}
else
{
std::string buffer;
auto ot = new SVFOtherType(T->isSingleValueType());
auto ot = new SVFOtherType(byteSize, T->isSingleValueType());
llvm::raw_string_ostream(buffer) << *T;
ot->setRepr(std::move(buffer));
svftype = ot;
Expand All @@ -1303,6 +1312,7 @@ SVFType* LLVMModuleSet::addSVFTypeInfo(const Type* T)
assert(svfPtrType && "this is not SVFPointerType");
svfPtrType->setPtrElementType(getSVFType(LLVMUtil::getPtrElementType(pt)));
}

return svftype;
}

Expand Down
9 changes: 0 additions & 9 deletions svf-llvm/lib/LLVMUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1268,15 +1268,6 @@ s64_t LLVMUtil::getCaseValue(const SwitchInst &switchInst, SuccBBAndCondValPair

namespace SVF
{
// getLLVMByteSize
u32_t SVFType::getLLVMByteSize() const
{
const llvm::DataLayout &DL = LLVMModuleSet::getLLVMModuleSet()->
getMainLLVMModule()->getDataLayout();
const Type* T = LLVMModuleSet::getLLVMModuleSet()->getLLVMType(this);
Type* mut_T = const_cast<Type*>(T);
return DL.getTypeAllocSize(mut_T);
}

std::string SVFValue::toString() const
{
Expand Down
8 changes: 4 additions & 4 deletions svf-llvm/lib/SymbolTableBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,7 @@ void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val,
if(const ConstantInt* sz = SVFUtil::dyn_cast<ConstantInt>(allocaInst->getArraySize()))
{
elemNum = sz->getZExtValue() * getNumOfElements(objTy);
byteSize = sz->getZExtValue() * typeinfo->getType()->getLLVMByteSize();
byteSize = sz->getZExtValue() * typeinfo->getType()->getByteSize();
}
/// if ArraySize is not constant, byteSize is not static determined.
else
Expand All @@ -836,7 +836,7 @@ void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val,
typeinfo->setFlag(ObjTypeInfo::CONST_GLOBAL_OBJ);
analyzeObjType(typeinfo,val);
elemNum = getNumOfElements(objTy);
byteSize = typeinfo->getType()->getLLVMByteSize();
byteSize = typeinfo->getType()->getByteSize();
}
/// if val is heap alloc
else if (SVFUtil::isa<Instruction>(val) &&
Expand All @@ -858,13 +858,13 @@ void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val,
analyzeStaticObjType(typeinfo,val);
// user input data, label its field as infinite here
elemNum = typeinfo->getMaxFieldOffsetLimit();
byteSize = typeinfo->getType()->getLLVMByteSize();
byteSize = typeinfo->getType()->getByteSize();
}
else if(LLVMUtil::isConstDataOrAggData(val))
{
typeinfo->setFlag(ObjTypeInfo::CONST_DATA);
elemNum = getNumOfFlattenElements(val->getType());
byteSize = typeinfo->getType()->getLLVMByteSize();
byteSize = typeinfo->getType()->getByteSize();
}
else
{
Expand Down
6 changes: 3 additions & 3 deletions svf/include/AbstractExecution/IntervalValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -661,9 +661,9 @@ inline IntervalValue operator<(const IntervalValue &lhs, const IntervalValue &rh
}
// Return [0,0] means lhs is totally impossible to be less than rhs
// i.e., lhs is totally greater than or equal to rhs
// When lhs.ub >= rhs.lb, e.g., lhs:[3, 4] rhs:[4,5]
// lhs.ub(4) >= rhs.lb(4)
else if (rhs.ub().geq(lhs.lb()))
// When lhs.lb >= rhs.ub, e.g., lhs:[4,5] rhs:[3,4]
// lhs.lb(4) >= rhs.ub(4)
else if (lhs.lb().geq(rhs.ub()))
{
return IntervalValue(0, 0);
}
Expand Down
10 changes: 5 additions & 5 deletions svf/include/AbstractExecution/SVFIR2ItvExeState.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,20 @@ class SVFIR2ItvExeState
VAddrs getGepObjAddress(u32_t pointer, APOffset offset);

/// Return the byte offset from one gep param offset
std::pair<APOffset, APOffset> getBytefromGepTypePair(const AccessPath::VarAndGepTypePair& gep_pair, const GepStmt *gep);
IntervalValue getByteOffsetfromGepTypePair(const AccessPath::IdxVarAndGepTypePair& gep_pair, const GepStmt *gep);

/// Return the Index offset from one gep param offset
std::pair<APOffset, APOffset> getIndexfromGepTypePair(const AccessPath::VarAndGepTypePair& gep_pair, const GepStmt *gep);
IntervalValue getItvOfFlattenedElemIndexFromGepTypePair(const AccessPath::IdxVarAndGepTypePair& gep_pair, const GepStmt *gep);

/// Return the byte offset expression of a GepStmt
/// elemBytesize is the element byte size of an static alloc or heap alloc array
/// e.g. GepStmt* gep = [i32*10], x, and x is [0,3]
/// std::pair<s32_t, s32_t> byteOffset = getGepByteOffset(gep);
/// std::pair<s32_t, s32_t> byteOffset = getByteOffset(gep);
/// byteOffset should be [0, 12] since i32 is 4 bytes.
std::pair<APOffset, APOffset> getGepByteOffset(const GepStmt *gep);
IntervalValue getByteOffset(const GepStmt *gep);

/// Return the offset expression of a GepStmt
std::pair<APOffset, APOffset> getGepOffset(const GepStmt *gep);
IntervalValue getItvOfFlattenedElemIndex(const GepStmt *gep);


static z3::context &getContext()
Expand Down
11 changes: 6 additions & 5 deletions svf/include/MemoryModel/AccessPath.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ class AccessPath
NonOverlap, Overlap, Subset, Superset, Same
};

typedef std::pair<const SVFVar*, const SVFType*> VarAndGepTypePair;
typedef std::vector<VarAndGepTypePair> OffsetVarAndGepTypePairs;
typedef std::pair<const SVFVar*, const SVFType*> IdxVarAndGepTypePair;
typedef std::vector<IdxVarAndGepTypePair> IdxVarAndGepTypePairs;

/// Constructor
AccessPath(APOffset o = 0) : fldIdx(o) {}
Expand Down Expand Up @@ -103,7 +103,7 @@ class AccessPath
{
fldIdx = idx;
}
inline const OffsetVarAndGepTypePairs& getOffsetVarAndGepTypePairVec() const
inline const IdxVarAndGepTypePairs& getOffsetVarAndGepTypePairVec() const
{
return offsetVarAndGepTypePairs;
}
Expand Down Expand Up @@ -163,7 +163,8 @@ class AccessPath
NodeBS computeAllLocations() const;

APOffset fldIdx; ///< Accumulated Constant Offsets
OffsetVarAndGepTypePairs offsetVarAndGepTypePairs; ///< a vector of actual offset in the form of <SVF Var, iterator type>s
IdxVarAndGepTypePairs
offsetVarAndGepTypePairs; ///< a vector of actual offset in the form of <SVF Var, iterator type>s
};

} // End namespace SVF
Expand All @@ -173,7 +174,7 @@ template <> struct std::hash<SVF::AccessPath>
size_t operator()(const SVF::AccessPath &ap) const
{
SVF::Hash<std::pair<SVF::NodeID, SVF::NodeID>> h;
std::hash<SVF::AccessPath::OffsetVarAndGepTypePairs> v;
std::hash<SVF::AccessPath::IdxVarAndGepTypePairs> v;
return h(std::make_pair(ap.getConstantFieldIdx(),
v(ap.getOffsetVarAndGepTypePairVec())));
}
Expand Down
4 changes: 3 additions & 1 deletion svf/include/SVFIR/SVFStatements.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ class AddrStmt: public AssignStmt
AddrStmt(SVFVar* s, SVFVar* d) : AssignStmt(s, d, SVFStmt::Addr) {}

virtual const std::string toString() const override;

};

/*!
Expand Down Expand Up @@ -491,7 +492,8 @@ class GepStmt: public AssignStmt
{
return ap;
}
inline const AccessPath::OffsetVarAndGepTypePairs getOffsetVarAndGepTypePairVec() const
inline const AccessPath::IdxVarAndGepTypePairs
getOffsetVarAndGepTypePairVec() const
{
return getAccessPath().getOffsetVarAndGepTypePairVec();
}
Expand Down
28 changes: 17 additions & 11 deletions svf/include/SVFIR/SVFType.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,13 @@ class SVFType
getPointerToTy; /// Return a pointer to the current type
StInfo* typeinfo; ///< SVF's TypeInfo
bool isSingleValTy; ///< The type represents a single value, not struct or
u32_t byteSize; ///< LLVM Byte Size
///< array

protected:
SVFType(bool svt, SVFTyKind k)
SVFType(bool svt, SVFTyKind k, u32_t Sz)
: kind(k), getPointerToTy(nullptr), typeinfo(nullptr),
isSingleValTy(svt)
isSingleValTy(svt), byteSize(Sz)
{
}

Expand Down Expand Up @@ -299,7 +300,6 @@ class SVFType
return getPointerToTy;
}

u32_t getLLVMByteSize() const;

inline void setTypeInfo(StInfo* ti)
{
Expand All @@ -318,6 +318,12 @@ class SVFType
return typeinfo;
}

/// if Type is not sized, byteSize is 0
/// if Type is sized, byteSize is the LLVM Byte Size.
inline u32_t getByteSize() const {
return byteSize;
}

inline bool isPointerTy() const
{
return kind == SVFPointerTy;
Expand Down Expand Up @@ -350,8 +356,8 @@ class SVFPointerType : public SVFType
const SVFType* ptrElementType;

public:
SVFPointerType()
: SVFType(true, SVFPointerTy), ptrElementType(nullptr)
SVFPointerType(u32_t byteSize)
: SVFType(true, SVFPointerTy, byteSize), ptrElementType(nullptr)
{
}

Expand Down Expand Up @@ -382,7 +388,7 @@ class SVFIntegerType : public SVFType
short signAndWidth; ///< For printing

public:
SVFIntegerType() : SVFType(true, SVFIntegerTy) {}
SVFIntegerType(u32_t byteSize) : SVFType(true, SVFIntegerTy, byteSize) {}
static inline bool classof(const SVFType* node)
{
return node->getKind() == SVFIntegerTy;
Expand Down Expand Up @@ -411,7 +417,7 @@ class SVFFunctionType : public SVFType

public:
SVFFunctionType(const SVFType* rt)
: SVFType(false, SVFFunctionTy), retTy(rt)
: SVFType(false, SVFFunctionTy, 0), retTy(rt)
{
}
static inline bool classof(const SVFType* node)
Expand All @@ -436,7 +442,7 @@ class SVFStructType : public SVFType
std::string name;

public:
SVFStructType() : SVFType(false, SVFStructTy) {}
SVFStructType(u32_t byteSize) : SVFType(false, SVFStructTy, byteSize) {}

static inline bool classof(const SVFType* node)
{
Expand Down Expand Up @@ -469,8 +475,8 @@ class SVFArrayType : public SVFType
const SVFType* typeOfElement; /// For printing & debugging

public:
SVFArrayType()
: SVFType(false, SVFArrayTy), numOfElement(0), typeOfElement(nullptr)
SVFArrayType(u32_t byteSize)
: SVFType(false, SVFArrayTy, byteSize), numOfElement(0), typeOfElement(nullptr)
{
}

Expand Down Expand Up @@ -508,7 +514,7 @@ class SVFOtherType : public SVFType
std::string repr; /// Field representation for printing

public:
SVFOtherType(bool isSingleValueTy) : SVFType(isSingleValueTy, SVFOtherTy) {}
SVFOtherType(u32_t byteSize, bool isSingleValueTy) : SVFType(isSingleValueTy, SVFOtherTy, byteSize) {}

static inline bool classof(const SVFType* node)
{
Expand Down
Loading

0 comments on commit 914e226

Please sign in to comment.