Static Value-Flow Analysis
Loading...
Searching...
No Matches
SymbolTableInfo.cpp
Go to the documentation of this file.
1//===- SymbolTableInfo.cpp -- Symbol information from IR------------------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-> <Yulei Sui>
6//
7
8// This program is free software: you can redistribute it and/or modify
9// it under the terms of the GNU Affero General Public License as published by
10// the Free Software Foundation, either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU Affero General Public License for more details.
17
18// You should have received a copy of the GNU Affero General Public License
19// along with this program. If not, see <http://www.gnu.org/licenses/>.
20//
21//===----------------------------------------------------------------------===//
22
23
24/*
25 * SymbolTableInfo.cpp
26 *
27 * Created on: Nov 11, 2013
28 * Author: Yulei Sui
29 */
30
31#include <memory>
32
34#include "Util/Options.h"
35#include "SVFIR/SVFModule.h"
36
37
38using namespace std;
39using namespace SVF;
40using namespace SVFUtil;
41
43
44
45ObjTypeInfo::ObjTypeInfo(const SVFType* t, u32_t max) : type(t), flags(0), maxOffsetLimit(max), elemNum(max)
46{
47 assert(t && "no type information for this object?");
48}
49
50
52{
53 assert((isStaticObj() || isHeap()) && "can only reset the inferred type for heap and static objects!");
54 type = t;
55}
56
58{
59 assert(T);
60 SVFTypeSet::const_iterator it = svfTypes.find(T);
61 assert(it != svfTypes.end() && "type info not found? collect them first during SVFIR Building");
62 return (*it)->getTypeInfo();
63}
64
65/*
66 * Initial the memory object here (for a dummy object)
67 */
69{
71 if(type && type->isPointerTy())
72 {
74 }
75 return typeInfo;
76}
77
90
95{
96
100
101 APOffset offset = apOffset;
102 if(offset < 0)
103 {
104 writeWrnMsg("try to create a gep node with negative offset.");
105 offset = abs(offset);
106 }
107 u32_t maxOffset = obj->getMaxFieldOffsetLimit();
108
114 if (maxOffset == 0)
115 offset = 0;
121 else if ((u32_t)offset > maxOffset - 1)
122 {
128 else
132 offset = maxOffset - 1;
133 }
134
135 return offset;
136}
137
138
139
144{
145
146 for (auto &pair: objMap)
147 {
148 if (MemObj* memObj = pair.second)
149 delete memObj;
150 }
151
152 for (const SVFType* type : svfTypes)
153 delete type;
154 svfTypes.clear();
155
156 for (const StInfo* st : stInfos)
157 delete st;
158 stInfos.clear();
159
160 mod = nullptr;
161}
162
164{
165 assert(objMap.find(symId)==objMap.end() && "this dummy obj has been created before");
166 MemObj* memObj = new MemObj(symId, createObjTypeInfo(type));
167 objMap[symId] = memObj;
168 return memObj;
169}
170
179
182{
184 {
185 const std::vector<u32_t>& so = getTypeInfo(T)->getFlattenedElemIdxVec();
186 assert ((unsigned)origId < so.size() && !so.empty() && "element index out of bounds, can't get flattened index!");
187 return so[origId];
188 }
189 else
190 {
191 if(SVFUtil::isa<SVFStructType>(T))
192 {
193 const std::vector<u32_t>& so = getTypeInfo(T)->getFlattenedFieldIdxVec();
194 assert ((unsigned)origId < so.size() && !so.empty() && "Struct index out of bounds, can't get flattened index!");
195 return so[origId];
196 }
197 else
198 {
200 assert(SVFUtil::isa<SVFArrayType>(T) && "Only accept struct or array type if Options::ModelArrays is disabled!");
201 return 0;
202 }
203 }
204}
205
210
213{
215 {
216 const std::vector<const SVFType*>& so = getTypeInfo(baseType)->getFlattenElementTypes();
217 assert (flatten_idx < so.size() && !so.empty() && "element index out of bounds or struct opaque type, can't get element type!");
218 return so[flatten_idx];
219 }
220 else
221 {
222 const std::vector<const SVFType*>& so = getTypeInfo(baseType)->getFlattenFieldTypes();
223 assert (flatten_idx < so.size() && !so.empty() && "element index out of bounds or struct opaque type, can't get element type!");
224 return so[flatten_idx];
225 }
226}
227
228
229const std::vector<const SVFType*>& SymbolTableInfo::getFlattenFieldTypes(const SVFStructType *T)
230{
232}
233
234/*
235 * Print out the composite type information
236 */
238{
239
240 if (const SVFArrayType* at = SVFUtil::dyn_cast<SVFArrayType>(type))
241 {
242 outs() << " {Type: " << *at << "}\n"
243 << "\tarray type "
244 << "\t [element size = " << getNumOfFlattenElements(at) << "]\n"
245 << "\n";
246 }
247 else if (const SVFStructType *st = SVFUtil::dyn_cast<SVFStructType>(type))
248 {
249 outs() <<" {Type: " << *st << "}\n";
250 const std::vector<const SVFType*>& finfo = getTypeInfo(st)->getFlattenFieldTypes();
251 int field_idx = 0;
252 for(const SVFType* type : finfo)
253 {
254 outs() << " \tField_idx = " << ++field_idx
255 << ", field type: " << *type << "\n";
256 }
257 outs() << "\n";
258 }
259 else if (const SVFPointerType* pt= SVFUtil::dyn_cast<SVFPointerType>(type))
260 {
261 outs() << *pt << "\n";
262 }
263 else if (const SVFFunctionType* fu =
264 SVFUtil::dyn_cast<SVFFunctionType>(type))
265 {
266 outs() << " {Type: " << *fu << "}\n\n";
267 }
268 else if (const SVFOtherType* ot = SVFUtil::dyn_cast<SVFOtherType>(type))
269 {
270 outs() << " {Type: "<< *ot << "(SVFOtherType)}\n\n";
271 }
272 else
273 {
274 assert(type->isSingleValueType() && "not a single value type, then what else!!");
277 outs() << " {Type: " << *type << "}\n"
278 << "\t [object size = " << eSize << "]\n"
279 << "\n";
280 }
281}
282
284{
285 switch (symtype)
286 {
288 {
289 return "BlackHole";
290 }
292 {
293 return "ConstantObj";
294 }
295 case SYMTYPE::BlkPtr:
296 {
297 return "BlkPtr";
298 }
299 case SYMTYPE::NullPtr:
300 {
301 return "NullPtr";
302 }
304 {
305 return "ValSym";
306 }
308 {
309 return "ObjSym";
310 }
312 {
313 return "RetSym";
314 }
316 {
317 return "VarargSym";
318 }
319 default:
320 {
321 return "Invalid SYMTYPE";
322 }
323 }
324}
325
327{
329 for (ValueToIDMapTy::iterator iter = valSymMap.begin(); iter != valSymMap.end();
330 ++iter)
331 {
332 const SymID i = iter->second;
333 SVFValue* val = (SVFValue*) iter->first;
334 idmap[i] = val;
335 }
336 for (ValueToIDMapTy::iterator iter = objSymMap.begin(); iter != objSymMap.end();
337 ++iter)
338 {
339 const SymID i = iter->second;
340 SVFValue* val = (SVFValue*) iter->first;
341 idmap[i] = val;
342 }
343 for (FunToIDMapTy::iterator iter = returnSymMap.begin(); iter != returnSymMap.end();
344 ++iter)
345 {
346 const SymID i = iter->second;
347 SVFValue* val = (SVFValue*) iter->first;
348 idmap[i] = val;
349 }
350 for (FunToIDMapTy::iterator iter = varargSymMap.begin(); iter != varargSymMap.end();
351 ++iter)
352 {
353 const SymID i = iter->second;
354 SVFValue* val = (SVFValue*) iter->first;
355 idmap[i] = val;
356 }
357 outs() << "{SymbolTableInfo \n";
358 for (auto iter : idmap)
359 {
360 outs() << iter.first << " " << iter.second->toString() << "\n";
361 }
362 outs() << "}\n";
363}
364
372
373
378 typeInfo(ti), refVal(val), symId(id), gNode(node)
379{
380}
381
386{
388}
389
395
401
404{
406}
407
408
414
417{
418 return typeInfo->getType();
419}
420/*
421 * Destroy the fields of the memory object
422 */
424{
425 delete typeInfo;
426 typeInfo = nullptr;
427}
428
434
437{
438 return getMaxFieldOffsetLimit() == 0;
439}
440
446
448{
449 return typeInfo->isFunction();
450}
451
453{
454 return typeInfo->isGlobalObj();
455}
456
458{
459 return typeInfo->isStaticObj();
460}
461
462bool MemObj::isStack() const
463{
464 return typeInfo->isStack();
465}
466
467bool MemObj::isHeap() const
468{
469 return typeInfo->isHeap();
470}
471
473{
474 return typeInfo->isStruct();
475}
476
477bool MemObj::isArray() const
478{
479 return typeInfo->isArray();
480}
481
483{
484 return typeInfo->isVarStruct();
485}
486
488{
489 return typeInfo->isVarArray();
490}
491
493{
494 return typeInfo->isConstantStruct();
495}
496
498{
499 return typeInfo->isConstantArray();
500}
501
506
508{
510}
511
512
513const std::string MemObj::toString() const
514{
515 std::string str;
516 std::stringstream rawstr(str);
517 rawstr << "MemObj : " << getId() << getValue()->toString() << "\n";
518 return rawstr.str();
519}
520
522
524{
525
526 if(val->isNullPtr())
527 return nullPtrSymID();
528 else if (val->isblackHole())
529 return blkPtrSymID();
530 else
531 {
532 ValueToIDMapTy::const_iterator iter = valSymMap.find(val);
533 assert(iter!=valSymMap.end() &&"value sym not found");
534 return iter->second;
535 }
536}
537
539{
540 if (val->isNullPtr() || val->isblackHole())
541 return true;
542 else
543 return (valSymMap.find(val) != valSymMap.end());
544}
newitem type
Definition cJSON.cpp:2739
buffer offset
Definition cJSON.cpp:1113
bool isConstantStruct() const
bool isStruct() const
const SVFType * getType() const
Get obj type.
bool isConstDataOrConstGlobal() const
void destroy()
Clean up memory.
bool isConstDataOrAggData() const
SymID getId() const
Get the memory object id.
bool isGlobalObj() const
bool isFieldInsensitive() const
Return true if its field limit is 0.
MemObj(SymID id, ObjTypeInfo *ti, const SVFValue *val=nullptr, const SVFBaseNode *node=nullptr)
Constructor.
u32_t getMaxFieldOffsetLimit() const
Get max field offset limit.
virtual const std::string toString() const
bool isVarArray() const
ObjTypeInfo * typeInfo
Type information of this object.
bool isBlackHoleObj() const
Whether it is a black hole object.
bool isConstantArray() const
const SVFValue * getValue() const
Get the reference value to this object.
bool isHeap() const
void setNumOfElements(u32_t num)
Set the number of elements of this object.
bool isStaticObj() const
void setFieldSensitive()
Set the memory object to be field sensitive (up to max field limit)
u32_t getNumOfElements() const
Get the number of elements of this object.
void setFieldInsensitive()
Set the memory object to be field insensitive.
u32_t getByteSizeOfObj() const
Get the byte size of this object.
bool isVarStruct() const
bool isFunction() const
object attributes methods
bool isConstantByteSize() const
Check if byte size is a const value.
bool isArray() const
bool isStack() const
const SVFType * type
SVF type.
ObjTypeInfo(const SVFType *t, u32_t max)
Constructors.
u32_t getMaxFieldOffsetLimit()
Get max field offset limit.
bool isConstDataOrConstGlobal()
u32_t getNumOfElements() const
Get the number of elements of this object.
const SVFType * getType() const
Get LLVM type.
bool isConstantByteSize() const
Check if byte size is a const value.
void setMaxFieldOffsetLimit(u32_t limit)
Get max field offset limit.
bool isFunction()
Object attributes.
u32_t getByteSizeOfObj() const
Get the byte size of this object.
void setFlag(MEMTYPE mask)
Flag for this object type.
void resetTypeForHeapStaticObj(const SVFType *type)
void setNumOfElements(u32_t num)
Set the number of elements of this object.
static const Option< bool > ModelConsts
Definition Options.h:187
static const Option< bool > CyclicFldIdx
Definition Options.h:189
static const Option< bool > ModelArrays
Definition Options.h:188
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:38
std::string toString() const
Needs to be implemented by a SVF front end.
Definition LLVMUtil.cpp:721
const SVFType * getOriginalElemType(u32_t fldIdx) const
Definition SVFValue.cpp:20
std::vector< const SVFType * > & getFlattenElementTypes()
Definition SVFType.h:102
std::vector< u32_t > & getFlattenedElemIdxVec()
Definition SVFType.h:98
u32_t getNumOfFlattenElements() const
Return number of elements after flattening (including array elements)
Definition SVFType.h:139
std::vector< const SVFType * > & getFlattenFieldTypes()
Definition SVFType.h:106
std::vector< u32_t > & getFlattenedFieldIdxVec()
Definition SVFType.h:94
u32_t getNumOfFlattenFields() const
Return the number of fields after flattening (ignoring array elements)
Definition SVFType.h:145
SymID blkPtrSymID() const
void printFlattenFields(const SVFType *type)
Debug method.
const std::vector< const SVFType * > & getFlattenFieldTypes(const SVFStructType *T)
Return the flattened field type for struct type only.
u32_t getFlattenedElemIdx(const SVFType *T, u32_t origId)
Flattened element idx of an array or struct by considering stride.
static SymbolTableInfo * SymbolInfo()
Singleton design here to make sure we only have one instance during any analysis.
ObjTypeInfo * createObjTypeInfo(const SVFType *type)
Create an objectInfo based on LLVM type (value is null, and type could be null, representing a dummy ...
const SVFType * getOriginalElemType(const SVFType *baseType, u32_t origId) const
void setModelConstants(bool _modelConstants)
Set / Get modelConstants.
static SymbolTableInfo * symInfo
ValueToIDMapTy valSymMap
map a value to its sym id
virtual APOffset getModulusOffset(const MemObj *obj, const APOffset &apOffset)
Given an offset from a Gep Instruction, return it modulus offset by considering memory layout.
ValueToIDMapTy objSymMap
map a obj reference to its sym id
const StInfo * getTypeInfo(const SVFType *T) const
Get struct info.
SymID getValSym(const SVFValue *val)
Get different kinds of syms.
static std::string toString(SYMTYPE symtype)
const SVFType * getFlatternedElemType(const SVFType *baseType, u32_t flatten_idx)
Return the type of a flattened element given a flattened index.
u32_t getNumOfFlattenElements(const SVFType *T)
Number of flattened elements of an array or struct.
void destroy()
Clean up memory.
FunToIDMapTy varargSymMap
vararg map
Set< const StInfo * > stInfos
(owned) All StInfo
virtual void dump()
Another debug method.
static bool isBlkObj(NodeID id)
SymID nullPtrSymID() const
const MemObj * createDummyObj(SymID symId, const SVFType *type)
Can only be invoked by SVFIR::addDummyNode() when creating SVFIR from file.
FunToIDMapTy returnSymMap
return map
IDToMemMapTy objMap
map a memory sym id to its obj
bool hasValSym(const SVFValue *val)
SVFModule * mod
Module.
SymbolTableInfo(void)
Constructor.
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:67
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50
for isBitcode
Definition BasicTypes.h:68
s64_t APOffset
Definition GeneralType.h:60
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
unsigned SymID
Definition GeneralType.h:57
unsigned u32_t
Definition GeneralType.h:46