Static Value-Flow Analysis
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Protected Member Functions | Private Member Functions | Private Attributes | Friends | List of all members
SVF::AccessPath Class Reference

#include <AccessPath.h>

Public Types

enum  LSRelation {
  NonOverlap , Overlap , Subset , Superset ,
  Same
}
 
typedef std::pair< const ValVar *, const SVFType * > IdxOperandPair
 
typedef std::vector< IdxOperandPairIdxOperandPairs
 

Public Member Functions

 AccessPath (APOffset o=0, const SVFType *srcTy=nullptr)
 Constructor.
 
 AccessPath (const AccessPath &ap)
 Copy Constructor.
 
 ~AccessPath ()
 
AccessPath operator+ (const AccessPath &rhs) const
 Overload operators.
 
bool operator< (const AccessPath &rhs) const
 
const AccessPathoperator= (const AccessPath &rhs)
 
bool operator== (const AccessPath &rhs) const
 
APOffset getConstantStructFldIdx () const
 Get methods.
 
void setFldIdx (APOffset idx)
 
const IdxOperandPairsgetIdxOperandPairVec () const
 
const SVFTypegepSrcPointeeType () const
 
APOffset computeConstantByteOffset () const
 
APOffset computeConstantOffset () const
 For example,.
 
u32_t getElementNum (const SVFType *type) const
 Return element number of a type.
 
bool addOffsetVarAndGepTypePair (const ValVar *var, const SVFType *gepIterType)
 
bool isConstantOffset () const
 Return TRUE if this is a constant location set.
 
bool intersects (const AccessPath &RHS) const
 Return TRUE if we share any location in common with RHS.
 
u32_t getStructFieldOffset (const ValVar *idxOperandVar, const SVFStructType *idxOperandType) const
 Return byte offset from the beginning of the structure to the field where it is located for struct type.
 
std::string dump () const
 Dump location set.
 

Protected Member Functions

void addIdxOperandPair (std::pair< const ValVar *, const SVFType * > pair)
 

Private Member Functions

LSRelation checkRelation (const AccessPath &LHS, const AccessPath &RHS)
 Check relations of two location sets.
 
NodeBS computeAllLocations () const
 Compute all possible locations according to offset and number-stride pairs.
 

Private Attributes

APOffset fldIdx
 Accumulated Constant Offsets.
 
IdxOperandPairs idxOperandPairs
 a vector of actual offset in the form of <SVF Var, iterator type>
 
const SVFTypegepPointeeType
 

Friends

class GraphDBClient
 

Detailed Description

Definition at line 57 of file AccessPath.h.

Member Typedef Documentation

◆ IdxOperandPair

Definition at line 66 of file AccessPath.h.

◆ IdxOperandPairs

Definition at line 67 of file AccessPath.h.

Member Enumeration Documentation

◆ LSRelation

Enumerator
NonOverlap 
Overlap 
Subset 
Superset 
Same 

Definition at line 61 of file AccessPath.h.

Constructor & Destructor Documentation

◆ AccessPath() [1/2]

SVF::AccessPath::AccessPath ( APOffset  o = 0,
const SVFType srcTy = nullptr 
)
inline

Constructor.

Definition at line 70 of file AccessPath.h.

const SVFType * gepPointeeType
Definition AccessPath.h:185
APOffset fldIdx
Accumulated Constant Offsets.
Definition AccessPath.h:183
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76

◆ AccessPath() [2/2]

SVF::AccessPath::AccessPath ( const AccessPath ap)
inline

Copy Constructor.

Definition at line 73 of file AccessPath.h.

74 : fldIdx(ap.fldIdx),
75 idxOperandPairs(ap.getIdxOperandPairVec()),
76 gepPointeeType(ap.gepSrcPointeeType())
77 {
78 }
IdxOperandPairs idxOperandPairs
a vector of actual offset in the form of <SVF Var, iterator type>
Definition AccessPath.h:184

◆ ~AccessPath()

SVF::AccessPath::~AccessPath ( )
inline

Definition at line 80 of file AccessPath.h.

80{}

Member Function Documentation

◆ addIdxOperandPair()

void SVF::AccessPath::addIdxOperandPair ( std::pair< const ValVar *, const SVFType * >  pair)
inlineprotected

Definition at line 170 of file AccessPath.h.

171 {
172 idxOperandPairs.push_back(pair);
173 }

◆ addOffsetVarAndGepTypePair()

bool AccessPath::addOffsetVarAndGepTypePair ( const ValVar var,
const SVFType gepIterType 
)

Add offset value to vector offsetVarAndGepTypePairs

Definition at line 44 of file AccessPath.cpp.

45{
46 idxOperandPairs.emplace_back(var, gepIterType);
47 return true;
48}

◆ checkRelation()

SVF::AccessPath::LSRelation AccessPath::checkRelation ( const AccessPath LHS,
const AccessPath RHS 
)
private

Check relations of two location sets.

Definition at line 312 of file AccessPath.cpp.

313{
314 NodeBS lhsLocations = LHS.computeAllLocations();
315 NodeBS rhsLocations = RHS.computeAllLocations();
316 if (lhsLocations.intersects(rhsLocations))
317 {
319 return Same;
320 else if (lhsLocations.contains(rhsLocations))
321 return Superset;
322 else if (rhsLocations.contains(lhsLocations))
323 return Subset;
324 else
325 return Overlap;
326 }
327 else
328 {
329 return NonOverlap;
330 }
331}

◆ computeAllLocations()

NodeBS AccessPath::computeAllLocations ( ) const
private

Compute all possible locations according to offset and number-stride pairs.

Compute all possible locations according to offset and number-stride pairs.

Definition at line 270 of file AccessPath.cpp.

271{
274 return result;
275}
APOffset getConstantStructFldIdx() const
Get methods.
Definition AccessPath.h:102
void set(unsigned Idx)

◆ computeConstantByteOffset()

APOffset AccessPath::computeConstantByteOffset ( ) const

Computes the total constant byte offset of an access path. This function iterates over the offset-variable-type pairs in reverse order, accumulating the total byte offset for constant offsets. For each pair, it retrieves the corresponding SVFValue and determines the type of offset (whether it's an array, pointer, or structure). If the offset corresponds to a structure, it further resolves the actual element type based on the offset value. It then multiplies the offset value by the size of the type to compute the byte offset. This is used to handle composite types where offsets are derived from the type's internal structure, such as arrays or structures with fields of various types and sizes. The function asserts that the access path must have a constant offset, and it is intended to be used when the offset is known to be constant at compile time.

Returns
APOffset representing the computed total constant byte offset. e.g. GepStmt* gep = [i32*4], 2 APOffset byteOffset = gep->accumulateConstantByteOffset(); byteOffset should be 8 since i32 is 4 bytes and index is 2.

Return accumulated constant offset

"value" is the offset variable (must be a constant) "type" is the location where we want to compute offset Given a vector and elem byte size: [(value1,type1), (value2,type2), (value3,type3)], bytesize totalConstByteOffset = ByteOffset(value1,type1) * ByteOffset(value2,type2) + ByteOffset(value3,type3) For a pointer type (e.g., t1 is PointerType), we will retrieve the pointee type and times the offset, i.e., getElementNum(t1) X off1

For example, there is struct DEST{int a, char b[10], int c[5]} (1) c = getelementptr inbounds struct.DEST, struct.DEST* arr, i32 0, i32 2

for (1) offsetVarAndGepTypePairs.size() = 2 i = 0, type: struct.DEST*, PtrType, op = 0 i = 1, type: struct.DEST, StructType, op = 2 for (2) offsetVarAndGepTypePairs.size() = 2 i = 0, type: [10 x i8]*, PtrType, op = 0 i = 1, type: [10 x i8], ArrType, op = 8

if offsetVarAndGepTypePairs[i].second is nullptr, it means GepStmt comes from external API, this GepStmt is assigned in SVFIRExtAPI.cpp at SVFIRBuilder::getBaseTypeAndFlattenedFields ls.addOffsetVarAndGepTypePair()

for (2) i = 1, arrType: [10 x i8], type2 = i8

for (1) i = 0, ptrType: struct.DEST*, type2: struct.DEST for (2) i = 0, ptrType: [10 x i8]*, type2 = [10 x i8]

for (1) structType: struct.DEST structField = 0, flattenIdx = 0, type2: int structField = 1, flattenIdx = 1, type2: char[10] structField = 2, flattenIdx = 11, type2: int[5]

for (2) i = 0, op: 0, type: [10 x i8]*(Ptr), type2: [10 x i8](Arr) i = 1, op: 8, type: [10 x i8](Arr), type2: i8

Definition at line 126 of file AccessPath.cpp.

127{
128 assert(isConstantOffset() && "not a constant offset");
129
131 for(int i = idxOperandPairs.size() - 1; i >= 0; i--)
132 {
135 // (2) %arrayidx = getelementptr inbounds [10 x i8], [10 x i8]* %b, i64 0, i64 8
136 const ValVar* var = idxOperandPairs[i].first;
143 const SVFType* type = idxOperandPairs[i].second;
147 assert(type && "this GepStmt comes from ExternalAPI cannot call this api");
148 const SVFType* type2 = type;
149 if (const SVFArrayType* arrType = SVFUtil::dyn_cast<SVFArrayType>(type))
150 {
152 type2 = arrType->getTypeOfElement();
153 }
154 else if (SVFUtil::isa<SVFPointerType>(type))
155 {
159 }
160
161 const ConstIntValVar* op = SVFUtil::dyn_cast<ConstIntValVar>(var);
162 if (const SVFStructType* structType = SVFUtil::dyn_cast<SVFStructType>(type))
163 {
168 for (u32_t structField = 0; structField < (u32_t)op->getSExtValue(); ++structField)
169 {
170 u32_t flattenIdx = structType->getTypeInfo()->getFlattenedFieldIdxVec()[structField];
171 type2 = structType->getTypeInfo()->getOriginalElemType(flattenIdx);
172 totalConstOffset += type2->getByteSize();
173 }
174 }
175 else
176 {
179 totalConstOffset += op->getSExtValue() * type2->getByteSize();
180 }
181 }
183 return totalConstOffset;
184}
unsigned u32_t
Definition CommandLine.h:18
newitem type
Definition cJSON.cpp:2739
bool isConstantOffset() const
Return TRUE if this is a constant location set.
const SVFType * gepSrcPointeeType() const
Definition AccessPath.h:114
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:34
s64_t APOffset
Definition GeneralType.h:80
unsigned u32_t
Definition GeneralType.h:67

◆ computeConstantOffset()

APOffset AccessPath::computeConstantOffset ( ) const

For example,.

Return accumulated constant offset given OffsetVarVec compard to computeConstantByteOffset, it is field offset rather than byte offset e.g. GepStmt* gep = [i32*4], 2 APOffset byteOffset = gep->computeConstantOffset(); byteOffset should be 2 since it is field offset.

Return accumulated constant offset

"value" is the offset variable (must be a constant) "type" is the location where we want to compute offset Given a vector: [(value1,type1), (value2,type2), (value3,type3)] totalConstOffset = flattenOffset(value1,type1) * flattenOffset(value2,type2) + flattenOffset(value3,type3) For a pointer type (e.g., t1 is PointerType), we will retrieve the pointee type and times the offset, i.e., getElementNum(t1) X off1 %5 = getelementptr inbounds struct.Student, struct.Student* %4, i64 1 value1: i64 1 type1: struct.Student* computeConstantOffset = 32 %6 = getelementptr inbounds struct.Student, struct.Student* %5, i32 0, i32 1 value1: i32 0 type1: struct.Student* value2: i32 1 type2: struct.Student = type { struct.inner, [10 x [3 x i8]] } computeConstantOffset = 2 %7 = getelementptr inbounds [10 x [3 x i8]], [10 x [3 x i8]]* %6, i64 0, i64 3 value1: i64 0 type1: [10 x [3 x i8]]* value2: i64 3 type2: [10 x [3 x i8]] computeConstantOffset = 9 %8 = getelementptr inbounds [3 x i8], [3 x i8]* %7, i64 0, i64 2 value1: i64 0 type1: [3 x i8]* value2: i64 2 type2: [3 x i8] computeConstantOffset = 2

Definition at line 214 of file AccessPath.cpp.

215{
216
217 assert(isConstantOffset() && "not a constant offset");
218
220 //After the model-const and model-array options are turned on,
221 // the gepstmt offset generated by the array on the global
222 // node will be saved in getConstantStructFldIdx
223 if (idxOperandPairs.size() == 0)
225 for(int i = idxOperandPairs.size() - 1; i >= 0; i--)
226 {
227 const ValVar* var = idxOperandPairs[i].first;
228 const SVFType* type = idxOperandPairs[i].second;
229 assert(SVFUtil::isa<ConstIntValVar>(var) && "not a constant offset?");
230 s64_t constOffset = SVFUtil::dyn_cast<ConstIntValVar>(var)->getSExtValue();
231
232 if(type==nullptr)
233 {
235 continue;
236 }
237
238 if(SVFUtil::isa<SVFPointerType>(type))
240 else
241 {
243 if (offset >= 0)
244 {
245 const std::vector<u32_t>& so = PAG::getPAG()->getTypeInfo(type)->getFlattenedElemIdxVec();
246 // if offset is larger than the size of getFlattenedElemIdxVec (overflow)
247 // set offset the last index of getFlattenedElemIdxVec to avoid assertion
248 if (offset >= (APOffset)so.size())
249 {
250 SVFUtil::errs() << "It is an overflow access, hence it is the last idx\n";
251 offset = so.size() - 1;
252 }
253 else
254 {
255
256 }
257
260 offset);
262 }
263 }
264 }
265 return totalConstOffset;
266}
buffer offset
Definition cJSON.cpp:1113
u32_t getElementNum(const SVFType *type) const
Return element number of a type.
u32_t getFlattenedElemIdx(const SVFType *T, u32_t origId)
Flattened element idx of an array or struct by considering stride.
Definition IRGraph.cpp:148
const StInfo * getTypeInfo(const SVFType *T) const
Get struct info.
Definition IRGraph.cpp:246
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:120
std::vector< u32_t > & getFlattenedElemIdxVec()
Definition SVFType.h:123
std::ostream & errs()
Overwrite llvm::errs()
Definition SVFUtil.h:58
signed long long s64_t
Definition GeneralType.h:70

◆ dump()

std::string AccessPath::dump ( ) const

Dump location set.

Definition at line 334 of file AccessPath.cpp.

335{
336 std::string str;
337 std::stringstream rawstr(str);
338
339 rawstr << "AccessPath\tField_Index: " << getConstantStructFldIdx();
340 rawstr << ",\tNum-Stride: {";
342 IdxOperandPairs::const_iterator it = vec.begin();
343 IdxOperandPairs::const_iterator eit = vec.end();
344 for (; it != eit; ++it)
345 {
346 const SVFType* ty = it->second;
347 rawstr << " (Svf var: " << it->first->toString() << ", Iter type: " << *ty << ")";
348 }
349 rawstr << " }\n";
350 return rawstr.str();
351}
std::vector< IdxOperandPair > IdxOperandPairs
Definition AccessPath.h:67
const IdxOperandPairs & getIdxOperandPairVec() const
Definition AccessPath.h:110
std::string toString() const

◆ gepSrcPointeeType()

const SVFType * SVF::AccessPath::gepSrcPointeeType ( ) const
inline

Definition at line 114 of file AccessPath.h.

115 {
116 return gepPointeeType;
117 }

◆ getConstantStructFldIdx()

APOffset SVF::AccessPath::getConstantStructFldIdx ( ) const
inline

Get methods.

Definition at line 102 of file AccessPath.h.

103 {
104 return fldIdx;
105 }

◆ getElementNum()

u32_t AccessPath::getElementNum ( const SVFType type) const

Return element number of a type.

Return element number of a type (1) StructType or Array, return flattened number elements. (2) Pointer type, return max field limit (3) Non-pointer SingleValueType or Function Type, return 1

Definition at line 65 of file AccessPath.cpp.

66{
67 if (SVFUtil::isa<SVFArrayType, SVFStructType>(type))
68 {
70 }
71 else if (type->isPointerTy())
72 {
73 // if type is a pointer, should be like:
74 // %2 = getelementptr inbounds i32*, i32** %1, ...
75 // where gepSrcPointee is of pointer type (i32*).
76 // this can be transformed to:
77 // %2 = getelementptr inbounds [N x i32], [N x i32]* %1, ...
78 // However, we do not know N without context information. int** implies non-contiguous blocks of memory
79 // In this case, we conservatively return max field limit
81 }
82 else if (type->isSingleValueType() || SVFUtil::isa<SVFFunctionType>(type))
83 {
84 return 1;
85 }
86 else
87 {
88 SVFUtil::outs() << "GepIter Type" << *type << "\n";
89 assert(false && "What other types for this gep?");
90 abort();
91 }
92}
u32_t getNumOfFlattenElements(const SVFType *T)
Definition IRGraph.cpp:173
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52

◆ getIdxOperandPairVec()

const IdxOperandPairs & SVF::AccessPath::getIdxOperandPairVec ( ) const
inline

Definition at line 110 of file AccessPath.h.

111 {
112 return idxOperandPairs;
113 }

◆ getStructFieldOffset()

u32_t AccessPath::getStructFieldOffset ( const ValVar idxOperandVar,
const SVFStructType idxOperandType 
) const

Return byte offset from the beginning of the structure to the field where it is located for struct type.

Return byte offset from the beginning of the structure to the field where it is located for struct type

Definition at line 100 of file AccessPath.cpp.

101{
103 if (const ConstIntValVar*op = SVFUtil::dyn_cast<ConstIntValVar>(idxOperandVar))
104 {
105 for (u32_t structField = 0; structField < (u32_t) op->getSExtValue(); ++structField)
106 {
107 u32_t flattenIdx = idxOperandType->getTypeInfo()->getFlattenedFieldIdxVec()[structField];
108 structByteOffset += idxOperandType->getTypeInfo()->getOriginalElemType(flattenIdx)->getByteSize();
109 }
110 return structByteOffset;
111 }
112 else
113 {
114 assert(false && "struct type can only pair with constant idx");
115 abort();
116 }
117}

◆ intersects()

bool SVF::AccessPath::intersects ( const AccessPath RHS) const
inline

Return TRUE if we share any location in common with RHS.

Definition at line 158 of file AccessPath.h.

159 {
160 return computeAllLocations().intersects(RHS.computeAllLocations());
161 }
NodeBS computeAllLocations() const
Compute all possible locations according to offset and number-stride pairs.
bool intersects(const SparseBitVector< ElementSize > *RHS) const

◆ isConstantOffset()

bool AccessPath::isConstantOffset ( ) const

Return TRUE if this is a constant location set.

Return true if all offset values are constants.

Definition at line 51 of file AccessPath.cpp.

52{
53 for(auto it : idxOperandPairs)
54 {
55 if(SVFUtil::isa<ConstIntValVar>(it.first) == false)
56 return false;
57 }
58 return true;
59}

◆ operator+()

AccessPath AccessPath::operator+ ( const AccessPath rhs) const

Overload operators.

Definition at line 277 of file AccessPath.cpp.

278{
279 assert(gepPointeeType == rhs.gepSrcPointeeType() && "source element type not match");
280 AccessPath ap(rhs);
281 ap.fldIdx += getConstantStructFldIdx();
282 for (auto &p : ap.getIdxOperandPairVec())
284
285 return ap;
286}
cJSON * p
Definition cJSON.cpp:2559
bool addOffsetVarAndGepTypePair(const ValVar *var, const SVFType *gepIterType)

◆ operator<()

bool AccessPath::operator< ( const AccessPath rhs) const

Definition at line 288 of file AccessPath.cpp.

289{
290 if (fldIdx != rhs.fldIdx)
291 return (fldIdx < rhs.fldIdx);
292 else
293 {
295 const IdxOperandPairs& rhsPairVec = rhs.getIdxOperandPairVec();
296 if (pairVec.size() != rhsPairVec.size())
297 return (pairVec.size() < rhsPairVec.size());
298 else
299 {
300 IdxOperandPairs::const_iterator it = pairVec.begin();
301 IdxOperandPairs::const_iterator rhsIt = rhsPairVec.begin();
302 for (; it != pairVec.end() && rhsIt != rhsPairVec.end(); ++it, ++rhsIt)
303 {
304 return (*it) < (*rhsIt);
305 }
306
307 return false;
308 }
309 }
310}

◆ operator=()

const AccessPath & SVF::AccessPath::operator= ( const AccessPath rhs)
inline

Definition at line 86 of file AccessPath.h.

87 {
88 fldIdx = rhs.fldIdx;
89 idxOperandPairs = rhs.getIdxOperandPairVec();
90 gepPointeeType = rhs.gepPointeeType;
91 return *this;
92 }

◆ operator==()

bool SVF::AccessPath::operator== ( const AccessPath rhs) const
inline

Definition at line 93 of file AccessPath.h.

94 {
95 return this->fldIdx == rhs.fldIdx &&
96 this->idxOperandPairs == rhs.idxOperandPairs && this->gepPointeeType == rhs.gepPointeeType;
97 }

◆ setFldIdx()

void SVF::AccessPath::setFldIdx ( APOffset  idx)
inline

Definition at line 106 of file AccessPath.h.

107 {
108 fldIdx = idx;
109 }

Friends And Related Symbol Documentation

◆ GraphDBClient

friend class GraphDBClient
friend

Definition at line 59 of file AccessPath.h.

Member Data Documentation

◆ fldIdx

APOffset SVF::AccessPath::fldIdx
private

Accumulated Constant Offsets.

Definition at line 183 of file AccessPath.h.

◆ gepPointeeType

const SVFType* SVF::AccessPath::gepPointeeType
private

Definition at line 185 of file AccessPath.h.

◆ idxOperandPairs

IdxOperandPairs SVF::AccessPath::idxOperandPairs
private

a vector of actual offset in the form of <SVF Var, iterator type>

Definition at line 184 of file AccessPath.h.


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