Static Value-Flow Analysis
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 
33 #include "SVFIR/SymbolTableInfo.h"
34 #include "Util/Options.h"
35 #include "SVFIR/SVFModule.h"
36 
37 
38 using namespace std;
39 using namespace SVF;
40 using namespace SVFUtil;
41 
42 SymbolTableInfo* SymbolTableInfo::symInfo = nullptr;
43 
44 
45 ObjTypeInfo::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  {
73  typeInfo->setFlag(ObjTypeInfo::HEAP_OBJ);
74  }
75  return typeInfo;
76 }
77 
82 {
83  if (symInfo == nullptr)
84  {
85  symInfo = new SymbolTableInfo();
87  }
88  return symInfo;
89 }
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;
116  else if (Options::MaxFieldLimit() < maxOffset)
120  offset = offset % maxOffset;
121  else if ((u32_t)offset > maxOffset - 1)
122  {
123  if (Options::CyclicFldIdx())
127  offset = offset % maxOffset;
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 
173 {
176  else
177  return getTypeInfo(T)->getNumOfFlattenFields();
178 }
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 
206 const SVFType* SymbolTableInfo::getOriginalElemType(const SVFType* baseType, u32_t origId) const
207 {
208  return getTypeInfo(baseType)->getOriginalElemType(origId);
209 }
210 
212 const SVFType* SymbolTableInfo::getFlatternedElemType(const SVFType* baseType, u32_t flatten_idx)
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 
229 const std::vector<const SVFType*>& SymbolTableInfo::getFlattenFieldTypes(const SVFStructType *T)
230 {
231  return getTypeInfo(T)->getFlattenFieldTypes();
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  {
287  case SYMTYPE::BlackHole:
288  {
289  return "BlackHole";
290  }
291  case SYMTYPE::ConstantObj:
292  {
293  return "ConstantObj";
294  }
295  case SYMTYPE::BlkPtr:
296  {
297  return "BlkPtr";
298  }
299  case SYMTYPE::NullPtr:
300  {
301  return "NullPtr";
302  }
303  case SYMTYPE::ValSymbol:
304  {
305  return "ValSym";
306  }
307  case SYMTYPE::ObjSymbol:
308  {
309  return "ObjSym";
310  }
311  case SYMTYPE::RetSymbol:
312  {
313  return "RetSym";
314  }
315  case SYMTYPE::VarargSymbol:
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 
369 {
371 }
372 
373 
377 MemObj::MemObj(SymID id, ObjTypeInfo* ti, const SVFValue* val, const SVFBaseNode* node) :
378  typeInfo(ti), refVal(val), symId(id), gNode(node)
379 {
380 }
381 
386 {
388 }
389 
392 {
393  return typeInfo->getNumOfElements();
394 }
395 
398 {
399  return typeInfo->getByteSizeOfObj();
400 }
401 
404 {
405  return typeInfo->isConstantByteSize();
406 }
407 
408 
411 {
412  return typeInfo->setNumOfElements(num);
413 }
414 
416 const SVFType* MemObj::getType() const
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 
431 {
433 }
434 
437 {
438  return getMaxFieldOffsetLimit() == 0;
439 }
440 
443 {
445 }
446 
447 bool MemObj::isFunction() const
448 {
449  return typeInfo->isFunction();
450 }
451 
453 {
454  return typeInfo->isGlobalObj();
455 }
456 
458 {
459  return typeInfo->isStaticObj();
460 }
461 
462 bool MemObj::isStack() const
463 {
464  return typeInfo->isStack();
465 }
466 
467 bool MemObj::isHeap() const
468 {
469  return typeInfo->isHeap();
470 }
471 
472 bool MemObj::isStruct() const
473 {
474  return typeInfo->isStruct();
475 }
476 
477 bool MemObj::isArray() const
478 {
479  return typeInfo->isArray();
480 }
481 
483 {
484  return typeInfo->isVarStruct();
485 }
486 
487 bool MemObj::isVarArray() const
488 {
489  return typeInfo->isVarArray();
490 }
491 
493 {
494  return typeInfo->isConstantStruct();
495 }
496 
498 {
499  return typeInfo->isConstantArray();
500 }
501 
503 {
505 }
506 
508 {
509  return typeInfo->isConstDataOrAggData();
510 }
511 
512 
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
const char *const string
Definition: cJSON.h:172
bool isConstantStruct() const
bool isStruct() const
const SVFType * getType() const
Get obj type.
bool isConstDataOrConstGlobal() const
void destroy()
Clean up memory.
const SVFValue * getValue() const
Get the reference value to this object.
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
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.
u32_t getMaxFieldOffsetLimit()
Get max field offset limit.
bool isConstDataOrConstGlobal()
u32_t getNumOfElements() const
Get the number of elements of this object.
bool isConstantByteSize() const
Check if byte size is a const value.
void setMaxFieldOffsetLimit(u32_t limit)
Get max field offset limit.
const SVFType * getType() const
Get LLVM type.
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:663
bool isNullPtr() const
Definition: SVFValue.h:272
bool isblackHole() const
Definition: SVFValue.h:268
std::vector< const SVFType * > & getFlattenElementTypes()
Definition: SVFType.h:102
const SVFType * getOriginalElemType(u32_t fldIdx) const
Definition: SVFValue.cpp:20
u32_t getNumOfFlattenElements() const
Return number of elements after flattening (including array elements)
Definition: SVFType.h:139
std::vector< u32_t > & getFlattenedElemIdxVec()
Definition: SVFType.h:98
std::vector< u32_t > & getFlattenedFieldIdxVec()
Definition: SVFType.h:94
std::vector< const SVFType * > & getFlattenFieldTypes()
Definition: SVFType.h:106
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:66
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
s64_t APOffset
Definition: GeneralType.h:60
unsigned SymID
Definition: GeneralType.h:57
unsigned u32_t
Definition: GeneralType.h:46
std::map< Key, Value, Compare, Allocator > OrderedMap
Definition: GeneralType.h:109