Static Value-Flow Analysis
Public Types | Public Member Functions | Static Public Member Functions | Protected Attributes | Friends | List of all members
SVF::AbstractState Class Reference

#include <AbstractState.h>

Public Types

typedef Map< u32_t, AbstractValueVarToAbsValMap
 
typedef VarToAbsValMap AddrToAbsValMap
 

Public Member Functions

 AbstractState ()
 default constructor More...
 
 AbstractState (VarToAbsValMap &_varToValMap, AddrToAbsValMap &_locToValMap)
 
 AbstractState (const AbstractState &rhs)
 copy constructor More...
 
virtual ~AbstractState ()=default
 
AddressValue getGepObjAddrs (u32_t pointer, IntervalValue offset)
 
void initObjVar (ObjVar *objVar)
 
IntervalValue getElementIndex (const GepStmt *gep)
 
IntervalValue getByteOffset (const GepStmt *gep)
 
AbstractValue loadValue (NodeID varId)
 
void storeValue (NodeID varId, AbstractValue val)
 
u32_t getAllocaInstByteSize (const AddrStmt *addr)
 
AbstractStateoperator= (const AbstractState &rhs)
 
 AbstractState (AbstractState &&rhs)
 move constructor More...
 
AbstractStateoperator= (AbstractState &&rhs)
 operator= move constructor More...
 
AbstractState bottom () const
 Set all value bottom. More...
 
AbstractState top () const
 Set all value top. More...
 
AbstractState sliceState (Set< u32_t > &sl)
 Copy some values and return a new IntervalExeState. More...
 
virtual AbstractValueoperator[] (u32_t varId)
 get abstract value of variable More...
 
virtual const AbstractValueoperator[] (u32_t varId) const
 get abstract value of variable More...
 
bool inVarToAddrsTable (u32_t id) const
 whether the variable is in varToAddrs table More...
 
virtual bool inVarToValTable (u32_t id) const
 whether the variable is in varToVal table More...
 
bool inAddrToAddrsTable (u32_t id) const
 whether the memory address stores memory addresses More...
 
virtual bool inAddrToValTable (u32_t id) const
 whether the memory address stores abstract value More...
 
const VarToAbsValMapgetVarToVal () const
 get var2val map More...
 
const AddrToAbsValMapgetLocToVal () const
 get loc2val map More...
 
AbstractState widening (const AbstractState &other)
 domain widen with other, and return the widened domain More...
 
AbstractState narrowing (const AbstractState &other)
 domain narrow with other, and return the narrowed domain More...
 
void joinWith (const AbstractState &other)
 domain join with other, important! other widen this. More...
 
void meetWith (const AbstractState &other)
 domain meet with other, important! other widen this. More...
 
const SVFTypegetPointeeElement (NodeID id)
 
u32_t hash () const
 
void store (u32_t addr, const AbstractValue &val)
 
virtual AbstractValueload (u32_t addr)
 
void printAbstractState () const
 
std::string toString () const
 
bool equals (const AbstractState &other) const
 
bool operator== (const AbstractState &rhs) const
 
bool operator!= (const AbstractState &rhs) const
 
bool operator< (const AbstractState &rhs) const
 
bool operator>= (const AbstractState &rhs) const
 
void clear ()
 

Static Public Member Functions

static u32_t getVirtualMemAddress (u32_t idx)
 The physical address starts with 0x7f...... + idx. More...
 
static bool isVirtualMemAddress (u32_t val)
 Check bit value of val start with 0x7F000000, filter by 0xFF000000. More...
 
static u32_t getInternalID (u32_t idx)
 Return the internal index if idx is an address otherwise return the value of idx. More...
 
static bool isNullPtr (u32_t addr)
 
static bool eqVarToValMap (const VarToAbsValMap &lhs, const VarToAbsValMap &rhs)
 
static bool lessThanVarToValMap (const VarToAbsValMap &lhs, const VarToAbsValMap &rhs)
 
static bool geqVarToValMap (const VarToAbsValMap &lhs, const VarToAbsValMap &rhs)
 

Protected Attributes

VarToAbsValMap _varToAbsVal
 Map a variable (symbol) to its abstract value. More...
 
AddrToAbsValMap _addrToAbsVal
 Map a memory address to its stored abstract value. More...
 

Friends

class SVFIR2AbsState
 
class RelationSolver
 

Detailed Description

Definition at line 58 of file AbstractState.h.

Member Typedef Documentation

◆ AddrToAbsValMap

Definition at line 65 of file AbstractState.h.

◆ VarToAbsValMap

Definition at line 63 of file AbstractState.h.

Constructor & Destructor Documentation

◆ AbstractState() [1/4]

SVF::AbstractState::AbstractState ( )
inline

default constructor

Definition at line 69 of file AbstractState.h.

70  {
71  }

◆ AbstractState() [2/4]

SVF::AbstractState::AbstractState ( VarToAbsValMap _varToValMap,
AddrToAbsValMap _locToValMap 
)
inline

Definition at line 73 of file AbstractState.h.

73 : _varToAbsVal(_varToValMap), _addrToAbsVal(_locToValMap) {}
VarToAbsValMap _varToAbsVal
Map a variable (symbol) to its abstract value.
AddrToAbsValMap _addrToAbsVal
Map a memory address to its stored abstract value.

◆ AbstractState() [3/4]

SVF::AbstractState::AbstractState ( const AbstractState rhs)
inline

copy constructor

Definition at line 76 of file AbstractState.h.

76  : _varToAbsVal(rhs.getVarToVal()), _addrToAbsVal(rhs.getLocToVal())
77  {
78 
79  }

◆ ~AbstractState()

virtual SVF::AbstractState::~AbstractState ( )
virtualdefault

◆ AbstractState() [4/4]

SVF::AbstractState::AbstractState ( AbstractState &&  rhs)
inline

move constructor

Definition at line 135 of file AbstractState.h.

135  : _varToAbsVal(std::move(rhs._varToAbsVal)),
136  _addrToAbsVal(std::move(rhs._addrToAbsVal))
137  {
138 
139  }
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
Definition: SVFUtil.h:447

Member Function Documentation

◆ bottom()

AbstractState SVF::AbstractState::bottom ( ) const
inline

Set all value bottom.

Definition at line 153 of file AbstractState.h.

154  {
155  AbstractState inv = *this;
156  for (auto &item: inv._varToAbsVal)
157  {
158  if (item.second.isInterval())
159  item.second.getInterval().set_to_bottom();
160  }
161  return inv;
162  }
cJSON * item
Definition: cJSON.h:222
AbstractState()
default constructor
Definition: AbstractState.h:69

◆ clear()

void SVF::AbstractState::clear ( )
inline

Definition at line 395 of file AbstractState.h.

396  {
397  _addrToAbsVal.clear();
398  _varToAbsVal.clear();
399  }

◆ equals()

bool AbstractState::equals ( const AbstractState other) const

Definition at line 37 of file AbstractState.cpp.

38 {
39  return *this == other;
40 }

◆ eqVarToValMap()

static bool SVF::AbstractState::eqVarToValMap ( const VarToAbsValMap lhs,
const VarToAbsValMap rhs 
)
inlinestatic

Definition at line 326 of file AbstractState.h.

327  {
328  if (lhs.size() != rhs.size()) return false;
329  for (const auto &item: lhs)
330  {
331  auto it = rhs.find(item.first);
332  if (it == rhs.end())
333  return false;
334  if (!item.second.equals(it->second))
335  return false;
336  else
337  {
338  }
339  }
340  return true;
341  }

◆ geqVarToValMap()

static bool SVF::AbstractState::geqVarToValMap ( const VarToAbsValMap lhs,
const VarToAbsValMap rhs 
)
inlinestatic

Definition at line 357 of file AbstractState.h.

358  {
359  if (rhs.empty()) return true;
360  for (const auto &item: rhs)
361  {
362  auto it = lhs.find(item.first);
363  if (it == lhs.end()) return false;
364  // judge from expr id
365  if (!it->second.getInterval().contain(
366  item.second.getInterval()))
367  return false;
368 
369  }
370  return true;
371  }

◆ getAllocaInstByteSize()

u32_t AbstractState::getAllocaInstByteSize ( const AddrStmt addr)

Definition at line 494 of file AbstractState.cpp.

495 {
496  SVFIR* svfir = PAG::getPAG();
497  if (const ObjVar* objvar = SVFUtil::dyn_cast<ObjVar>(addr->getRHSVar()))
498  {
499  objvar->getType();
500  if (objvar->getMemObj()->isConstantByteSize())
501  {
502  u32_t sz = objvar->getMemObj()->getByteSizeOfObj();
503  return sz;
504  }
505 
506  else
507  {
508  const std::vector<SVFValue*>& sizes = addr->getArrSize();
509  // Default element size is set to 1.
510  u32_t elementSize = 1;
511  u64_t res = elementSize;
512  for (const SVFValue* value: sizes)
513  {
514  if (!inVarToValTable(svfir->getValueNode(value)))
515  {
516  (*this)[svfir->getValueNode(value)] = IntervalValue(Options::MaxFieldLimit());
517  }
518  IntervalValue itv =
519  (*this)[svfir->getValueNode(value)].getInterval();
520  res = res * itv.ub().getIntNumeral() > Options::MaxFieldLimit()? Options::MaxFieldLimit(): res * itv.ub().getIntNumeral();
521  }
522  return (u32_t)res;
523  }
524  }
525  assert (false && "Addr rhs value is not ObjVar");
526  abort();
527 }
unsigned u32_t
Definition: CommandLine.h:18
virtual bool inVarToValTable(u32_t id) const
whether the variable is in varToVal table
const std::vector< SVFValue * > & getArrSize() const
SVFVar * getRHSVar() const
s64_t getIntNumeral() const
Definition: NumericValue.h:703
NodeID getValueNode(const SVFValue *V)
Definition: IRGraph.h:137
const BoundedInt & ub() const
Return the upper bound.
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition: Options.h:38
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115
unsigned long long u64_t
Definition: GeneralType.h:48

◆ getByteOffset()

IntervalValue AbstractState::getByteOffset ( const GepStmt gep)

Definition at line 305 of file AbstractState.cpp.

306 {
307  // If the GEP statement has a constant byte offset, return it directly as the interval value
308  if (gep->isConstantOffset())
310 
311  IntervalValue res(0); // Initialize the result interval 'res' to 0.
312 
313  // Loop through the offsetVarAndGepTypePairVec in reverse order.
314  for (int i = gep->getOffsetVarAndGepTypePairVec().size() - 1; i >= 0; i--)
315  {
316  const SVFVar* idxOperandVar = gep->getOffsetVarAndGepTypePairVec()[i].first;
317  const SVFType* idxOperandType = gep->getOffsetVarAndGepTypePairVec()[i].second;
318 
319  // Calculate the byte offset for array or pointer types
320  if (SVFUtil::isa<SVFArrayType>(idxOperandType) || SVFUtil::isa<SVFPointerType>(idxOperandType))
321  {
322  u32_t elemByteSize = 1;
323  if (const SVFArrayType* arrOperandType = SVFUtil::dyn_cast<SVFArrayType>(idxOperandType))
324  elemByteSize = arrOperandType->getTypeOfElement()->getByteSize();
325  else if (SVFUtil::isa<SVFPointerType>(idxOperandType))
326  elemByteSize = gep->getAccessPath().gepSrcPointeeType()->getByteSize();
327  else
328  assert(false && "idxOperandType must be ArrType or PtrType");
329 
330  if (const SVFConstantInt* op = SVFUtil::dyn_cast<SVFConstantInt>(idxOperandVar->getValue()))
331  {
332  // Calculate the lower bound (lb) of the interval value
333  s64_t lb = (double)Options::MaxFieldLimit() / elemByteSize >= op->getSExtValue()
334  ? op->getSExtValue() * elemByteSize
336  res = res + IntervalValue(lb, lb);
337  }
338  else
339  {
340  u32_t idx = PAG::getPAG()->getValueNode(idxOperandVar->getValue());
341  IntervalValue idxVal = (*this)[idx].getInterval();
342 
343  if (idxVal.isBottom())
344  res = res + IntervalValue(0, 0);
345  else
346  {
347  // Ensure the bounds are non-negative and within the field limit
348  s64_t ub = (idxVal.ub().getIntNumeral() < 0) ? 0
349  : (double)Options::MaxFieldLimit() / elemByteSize >= idxVal.ub().getIntNumeral()
350  ? elemByteSize * idxVal.ub().getIntNumeral()
352  s64_t lb = (idxVal.lb().getIntNumeral() < 0) ? 0
353  : (double)Options::MaxFieldLimit() / elemByteSize >= idxVal.lb().getIntNumeral()
354  ? elemByteSize * idxVal.lb().getIntNumeral()
356  res = res + IntervalValue(lb, ub);
357  }
358  }
359  }
360  // Process struct subtypes by calculating the byte offset from the beginning to the field of the struct
361  else if (const SVFStructType* structOperandType = SVFUtil::dyn_cast<SVFStructType>(idxOperandType))
362  {
363  res = res + IntervalValue(gep->getAccessPath().getStructFieldOffset(idxOperandVar, structOperandType));
364  }
365  else
366  {
367  assert(false && "gep type pair only support arr/ptr/struct");
368  }
369  }
370  return res; // Return the resulting byte offset as an IntervalValue.
371 }
u32_t getStructFieldOffset(const SVFVar *idxOperandVar, const SVFStructType *idxOperandType) const
Return byte offset from the beginning of the structure to the field where it is located for struct ty...
Definition: AccessPath.cpp:98
const SVFType * gepSrcPointeeType() const
Definition: AccessPath.h:112
APOffset accumulateConstantByteOffset() const
const AccessPath::IdxOperandPairs getOffsetVarAndGepTypePairVec() const
const AccessPath & getAccessPath() const
bool isConstantOffset() const
Return TRUE if this is a constant location set.
const BoundedInt & lb() const
Return the lower bound.
bool isBottom() const
Definition: IntervalValue.h:71
u32_t getByteSize() const
Definition: SVFType.h:244
const SVFValue * getValue() const
Get/has methods of the components.
Definition: SVFVariables.h:83
signed long long s64_t
Definition: GeneralType.h:49

◆ getElementIndex()

IntervalValue AbstractState::getElementIndex ( const GepStmt gep)

Definition at line 232 of file AbstractState.cpp.

233 {
234  // If the GEP statement has a constant offset, return it directly as the interval value
235  if (gep->isConstantOffset())
237 
238  IntervalValue res(0);
239  // Iterate over the list of offset variable and type pairs in reverse order
240  for (int i = gep->getOffsetVarAndGepTypePairVec().size() - 1; i >= 0; i--)
241  {
243  const SVFValue* value = gep->getOffsetVarAndGepTypePairVec()[i].first->getValue();
244  const SVFType* type = IdxVarAndType.second;
245 
246  // Variables to store the lower and upper bounds of the index value
247  s64_t idxLb;
248  s64_t idxUb;
249 
250  // Determine the lower and upper bounds based on whether the value is a constant
251  if (const SVFConstantInt* constInt = SVFUtil::dyn_cast<SVFConstantInt>(value))
252  idxLb = idxUb = constInt->getSExtValue();
253  else
254  {
255  IntervalValue idxItv = (*this)[PAG::getPAG()->getValueNode(value)].getInterval();
256  if (idxItv.isBottom())
257  idxLb = idxUb = 0;
258  else
259  {
260  idxLb = idxItv.lb().getIntNumeral();
261  idxUb = idxItv.ub().getIntNumeral();
262  }
263  }
264 
265  // Adjust the bounds if the type is a pointer
266  if (SVFUtil::isa<SVFPointerType>(type))
267  {
269  idxLb = (double)Options::MaxFieldLimit() / elemNum < idxLb ? Options::MaxFieldLimit() : idxLb * elemNum;
270  idxUb = (double)Options::MaxFieldLimit() / elemNum < idxUb ? Options::MaxFieldLimit() : idxUb * elemNum;
271  }
272  // Adjust the bounds for array or struct types using the symbol table info
273  else
274  {
275  if (Options::ModelArrays())
276  {
277  const std::vector<u32_t>& so = SymbolTableInfo::SymbolInfo()->getTypeInfo(type)->getFlattenedElemIdxVec();
278  if (so.empty() || idxUb >= (APOffset)so.size() || idxLb < 0)
279  {
280  idxLb = idxUb = 0;
281  }
282  else
283  {
286  }
287  }
288  else
289  idxLb = idxUb = 0;
290  }
291 
292  // Add the calculated interval to the result
293  res = res + IntervalValue(idxLb, idxUb);
294  }
295 
296  // Ensure the result is within the bounds of [0, MaxFieldLimit]
297  res.meet_with(IntervalValue((s64_t)0, (s64_t)Options::MaxFieldLimit()));
298  if (res.isBottom())
299  {
300  res = IntervalValue(0);
301  }
302  return res;
303 }
newitem type
Definition: cJSON.cpp:2739
u32_t getElementNum(const SVFType *type) const
Return element number of a type.
Definition: AccessPath.cpp:63
std::pair< const SVFVar *, const SVFType * > IdxOperandPair
Definition: AccessPath.h:64
APOffset accumulateConstantOffset() const
Return accumulated constant offset (when accessing array or struct) if this offset is a constant.
static const Option< bool > ModelArrays
Definition: Options.h:188
std::vector< u32_t > & getFlattenedElemIdxVec()
Definition: SVFType.h:98
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.
const StInfo * getTypeInfo(const SVFType *T) const
Get struct info.
s64_t APOffset
Definition: GeneralType.h:60

◆ getGepObjAddrs()

AddressValue AbstractState::getGepObjAddrs ( u32_t  pointer,
IntervalValue  offset 
)

Definition at line 156 of file AbstractState.cpp.

157 {
158  AddressValue gepAddrs;
159  APOffset lb = offset.lb().getIntNumeral() < Options::MaxFieldLimit() ? offset.lb().getIntNumeral()
161  APOffset ub = offset.ub().getIntNumeral() < Options::MaxFieldLimit() ? offset.ub().getIntNumeral()
163  for (APOffset i = lb; i <= ub; i++)
164  {
165  AbstractValue addrs = (*this)[pointer];
166  for (const auto& addr : addrs.getAddrs())
167  {
168  s64_t baseObj = AbstractState::getInternalID(addr);
169  assert(SVFUtil::isa<ObjVar>(PAG::getPAG()->getGNode(baseObj)) && "Fail to get the base object address!");
170  NodeID gepObj = PAG::getPAG()->getGepObjVar(baseObj, i);
171  (*this)[gepObj] = AddressValue(AbstractState::getVirtualMemAddress(gepObj));
173  }
174  }
175 
176  return gepAddrs;
177 }
buffer offset
Definition: cJSON.cpp:1113
static u32_t getVirtualMemAddress(u32_t idx)
The physical address starts with 0x7f...... + idx.
static u32_t getInternalID(u32_t idx)
Return the internal index if idx is an address otherwise return the value of idx.
AddressValue & getAddrs()
std::pair< AddressValue::AddrSet::iterator, bool > insert(u32_t id)
Definition: AddressValue.h:112
NodeID getGepObjVar(const MemObj *obj, const APOffset &ap)
Get a field SVFIR Object node according to base mem obj and offset.
Definition: SVFIR.cpp:422
u32_t NodeID
Definition: GeneralType.h:55

◆ getInternalID()

static u32_t SVF::AbstractState::getInternalID ( u32_t  idx)
inlinestatic

Return the internal index if idx is an address otherwise return the value of idx.

Definition at line 114 of file AbstractState.h.

115  {
116  return AddressValue::getInternalID(idx);
117  }
static u32_t getInternalID(u32_t idx)
Return the internal index if idx is an address otherwise return the value of idx.
Definition: AddressValue.h:226

◆ getLocToVal()

const AddrToAbsValMap& SVF::AbstractState::getLocToVal ( ) const
inline

get loc2val map

Definition at line 266 of file AbstractState.h.

267  {
268  return _addrToAbsVal;
269  }

◆ getPointeeElement()

const SVFType * AbstractState::getPointeeElement ( NodeID  id)

if this NodeID in SVFIR is a pointer, get the pointee type e.g arr = (int*) malloc(10*sizeof(int)) getPointeeType(arr) -> return int we can set arr[0]='c', arr[1]='c', arr[2]='\0'

Parameters
callcallnode of memset like api

Definition at line 473 of file AbstractState.cpp.

474 {
475  SVFIR* svfir = PAG::getPAG();
476  if (inVarToAddrsTable(id))
477  {
478  const AbstractValue& addrs = (*this)[id];
479  for (auto addr: addrs.getAddrs())
480  {
481  NodeID addr_id = AbstractState::getInternalID(addr);
482  if (addr_id == 0) // nullptr has no memobj, skip
483  continue;
484  return SVFUtil::dyn_cast<ObjVar>(svfir->getGNode(addr_id))->getMemObj()->getType();
485  }
486  }
487  else
488  {
489  // do nothing if no record in addrs table.
490  }
491  return nullptr;
492 }
bool inVarToAddrsTable(u32_t id) const
whether the variable is in varToAddrs table
NodeType * getGNode(NodeID id) const
Get a node.
Definition: GenericGraph.h:653

◆ getVarToVal()

const VarToAbsValMap& SVF::AbstractState::getVarToVal ( ) const
inline

get var2val map

Definition at line 260 of file AbstractState.h.

261  {
262  return _varToAbsVal;
263  }

◆ getVirtualMemAddress()

static u32_t SVF::AbstractState::getVirtualMemAddress ( u32_t  idx)
inlinestatic

The physical address starts with 0x7f...... + idx.

Definition at line 102 of file AbstractState.h.

103  {
105  }
static u32_t getVirtualMemAddress(u32_t idx)
The physical address starts with 0x7f...... + idx.
Definition: AddressValue.h:212

◆ hash()

u32_t AbstractState::hash ( ) const

Definition at line 42 of file AbstractState.cpp.

43 {
44  size_t h = getVarToVal().size() * 2;
45  Hash<u32_t> hf;
46  for (const auto &t: getVarToVal())
47  {
48  h ^= hf(t.first) + 0x9e3779b9 + (h << 6) + (h >> 2);
49  }
50  size_t h2 = getLocToVal().size() * 2;
51  for (const auto &t: getLocToVal())
52  {
53  h2 ^= hf(t.first) + 0x9e3779b9 + (h2 << 6) + (h2 >> 2);
54  }
56  return pairH({h, h2});
57 }
const VarToAbsValMap & getVarToVal() const
get var2val map
const AddrToAbsValMap & getLocToVal() const
get loc2val map
provide extra hash function for std::pair handling
Definition: GeneralType.h:85

◆ inAddrToAddrsTable()

bool SVF::AbstractState::inAddrToAddrsTable ( u32_t  id) const
inline

whether the memory address stores memory addresses

Definition at line 234 of file AbstractState.h.

235  {
236  if (_addrToAbsVal.find(id)!= _addrToAbsVal.end())
237  {
238  if (_addrToAbsVal.at(id).isAddr())
239  {
240  return true;
241  }
242  }
243  return false;
244  }

◆ inAddrToValTable()

virtual bool SVF::AbstractState::inAddrToValTable ( u32_t  id) const
inlinevirtual

whether the memory address stores abstract value

Definition at line 247 of file AbstractState.h.

248  {
249  if (_addrToAbsVal.find(id) != _addrToAbsVal.end())
250  {
251  if (_addrToAbsVal.at(id).isInterval())
252  {
253  return true;
254  }
255  }
256  return false;
257  }

◆ initObjVar()

void AbstractState::initObjVar ( ObjVar objVar)

Definition at line 179 of file AbstractState.cpp.

180 {
181  NodeID varId = objVar->getId();
182 
183  // Check if the object variable has an associated value
184  if (objVar->hasValue())
185  {
186  const MemObj* obj = objVar->getMemObj();
187 
188  // Handle constant data, arrays, and structures
189  if (obj->isConstDataOrConstGlobal() || obj->isConstantArray() || obj->isConstantStruct())
190  {
191  if (const SVFConstantInt* consInt = SVFUtil::dyn_cast<SVFConstantInt>(obj->getValue()))
192  {
193  s64_t numeral = consInt->getSExtValue();
194  (*this)[varId] = IntervalValue(numeral, numeral);
195  }
196  else if (const SVFConstantFP* consFP = SVFUtil::dyn_cast<SVFConstantFP>(obj->getValue()))
197  {
198  (*this)[varId] = IntervalValue(consFP->getFPValue(), consFP->getFPValue());
199  }
200  else if (SVFUtil::isa<SVFConstantNullPtr>(obj->getValue()))
201  {
202  (*this)[varId] = IntervalValue(0, 0);
203  }
204  else if (SVFUtil::isa<SVFGlobalValue>(obj->getValue()))
205  {
206  (*this)[varId] = AddressValue(AbstractState::getVirtualMemAddress(varId));
207  }
208  else if (obj->isConstantArray() || obj->isConstantStruct())
209  {
210  (*this)[varId] = IntervalValue::top();
211  }
212  else
213  {
214  (*this)[varId] = IntervalValue::top();
215  }
216  }
217  // Handle non-constant memory objects
218  else
219  {
220  (*this)[varId] = AddressValue(AbstractState::getVirtualMemAddress(varId));
221  }
222  }
223  // If the object variable does not have an associated value, set it to a virtual memory address
224  else
225  {
226  (*this)[varId] = AddressValue(AbstractState::getVirtualMemAddress(varId));
227  }
228  return;
229 }
static IntervalValue top()
Create the IntervalValue [-inf, +inf].
Definition: IntervalValue.h:94
bool isConstantStruct() const
bool isConstDataOrConstGlobal() const
const SVFValue * getValue() const
Get the reference value to this object.
bool isConstantArray() const
const MemObj * getMemObj() const
Return memory object.
Definition: SVFVariables.h:358
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
bool hasValue() const
Definition: SVFVariables.h:101

◆ inVarToAddrsTable()

bool SVF::AbstractState::inVarToAddrsTable ( u32_t  id) const
inline

whether the variable is in varToAddrs table

Definition at line 208 of file AbstractState.h.

209  {
210  if (_varToAbsVal.find(id)!= _varToAbsVal.end())
211  {
212  if (_varToAbsVal.at(id).isAddr())
213  {
214  return true;
215  }
216  }
217  return false;
218  }

◆ inVarToValTable()

virtual bool SVF::AbstractState::inVarToValTable ( u32_t  id) const
inlinevirtual

whether the variable is in varToVal table

Definition at line 221 of file AbstractState.h.

222  {
223  if (_varToAbsVal.find(id) != _varToAbsVal.end())
224  {
225  if (_varToAbsVal.at(id).isInterval())
226  {
227  return true;
228  }
229  }
230  return false;
231  }

◆ isNullPtr()

static bool SVF::AbstractState::isNullPtr ( u32_t  addr)
inlinestatic

Definition at line 119 of file AbstractState.h.

120  {
121  return getInternalID(addr) == 0;
122  }

◆ isVirtualMemAddress()

static bool SVF::AbstractState::isVirtualMemAddress ( u32_t  val)
inlinestatic

Check bit value of val start with 0x7F000000, filter by 0xFF000000.

Definition at line 108 of file AbstractState.h.

109  {
111  }
static bool isVirtualMemAddress(u32_t val)
Check bit value of val start with 0x7F000000, filter by 0xFF000000.
Definition: AddressValue.h:220

◆ joinWith()

void AbstractState::joinWith ( const AbstractState other)

domain join with other, important! other widen this.

Definition at line 102 of file AbstractState.cpp.

103 {
104  for (auto it = other._varToAbsVal.begin(); it != other._varToAbsVal.end(); ++it)
105  {
106  auto key = it->first;
107  auto oit = _varToAbsVal.find(key);
108  if (oit != _varToAbsVal.end())
109  {
110  oit->second.join_with(it->second);
111  }
112  else
113  {
114  _varToAbsVal.emplace(key, it->second);
115  }
116  }
117  for (auto it = other._addrToAbsVal.begin(); it != other._addrToAbsVal.end(); ++it)
118  {
119  auto key = it->first;
120  auto oit = _addrToAbsVal.find(key);
121  if (oit != _addrToAbsVal.end())
122  {
123  oit->second.join_with(it->second);
124  }
125  else
126  {
127  _addrToAbsVal.emplace(key, it->second);
128  }
129  }
130 }

◆ lessThanVarToValMap()

static bool SVF::AbstractState::lessThanVarToValMap ( const VarToAbsValMap lhs,
const VarToAbsValMap rhs 
)
inlinestatic

Definition at line 343 of file AbstractState.h.

344  {
345  if (lhs.empty()) return !rhs.empty();
346  for (const auto &item: lhs)
347  {
348  auto it = rhs.find(item.first);
349  if (it == rhs.end()) return false;
350  // judge from expr id
351  if (item.second.getInterval().contain(it->second.getInterval())) return false;
352  }
353  return true;
354  }

◆ load()

virtual AbstractValue& SVF::AbstractState::load ( u32_t  addr)
inlinevirtual

Definition at line 307 of file AbstractState.h.

308  {
309  assert(isVirtualMemAddress(addr) && "not virtual address?");
310  u32_t objId = getInternalID(addr);
311  return _addrToAbsVal[objId];
312 
313  }
static bool isVirtualMemAddress(u32_t val)
Check bit value of val start with 0x7F000000, filter by 0xFF000000.

◆ loadValue()

AbstractValue AbstractState::loadValue ( NodeID  varId)

Definition at line 373 of file AbstractState.cpp.

374 {
375  AbstractValue res;
376  for (auto addr : (*this)[varId].getAddrs())
377  {
378  res.join_with(load(addr)); // q = *p
379  }
380  return res;
381 }
virtual AbstractValue & load(u32_t addr)
void join_with(const AbstractValue &other)

◆ meetWith()

void AbstractState::meetWith ( const AbstractState other)

domain meet with other, important! other widen this.

Definition at line 133 of file AbstractState.cpp.

134 {
135  for (auto it = other._varToAbsVal.begin(); it != other._varToAbsVal.end(); ++it)
136  {
137  auto key = it->first;
138  auto oit = _varToAbsVal.find(key);
139  if (oit != _varToAbsVal.end())
140  {
141  oit->second.meet_with(it->second);
142  }
143  }
144  for (auto it = other._addrToAbsVal.begin(); it != other._addrToAbsVal.end(); ++it)
145  {
146  auto key = it->first;
147  auto oit = _addrToAbsVal.find(key);
148  if (oit != _addrToAbsVal.end())
149  {
150  oit->second.meet_with(it->second);
151  }
152  }
153 }

◆ narrowing()

AbstractState AbstractState::narrowing ( const AbstractState other)

domain narrow with other, and return the narrowed domain

Definition at line 80 of file AbstractState.cpp.

81 {
82  AbstractState es = *this;
83  for (auto it = es._varToAbsVal.begin(); it != es._varToAbsVal.end(); ++it)
84  {
85  auto key = it->first;
86  if (other._varToAbsVal.find(key) != other._varToAbsVal.end())
87  if (it->second.isInterval() && other._varToAbsVal.at(key).isInterval())
88  it->second.getInterval().narrow_with(other._varToAbsVal.at(key).getInterval());
89  }
90  for (auto it = es._addrToAbsVal.begin(); it != es._addrToAbsVal.end(); ++it)
91  {
92  auto key = it->first;
93  if (other._addrToAbsVal.find(key) != other._addrToAbsVal.end())
94  if (it->second.isInterval() && other._addrToAbsVal.at(key).isInterval())
95  it->second.getInterval().narrow_with(other._addrToAbsVal.at(key).getInterval());
96  }
97  return es;
98 
99 }

◆ operator!=()

bool SVF::AbstractState::operator!= ( const AbstractState rhs) const
inline

Definition at line 379 of file AbstractState.h.

380  {
381  return !(*this == rhs);
382  }

◆ operator<()

bool SVF::AbstractState::operator< ( const AbstractState rhs) const
inline

Definition at line 384 of file AbstractState.h.

385  {
386  return !(*this >= rhs);
387  }

◆ operator=() [1/2]

AbstractState& SVF::AbstractState::operator= ( AbstractState &&  rhs)
inline

operator= move constructor

Definition at line 142 of file AbstractState.h.

143  {
144  if (&rhs != this)
145  {
146  _varToAbsVal = std::move(rhs._varToAbsVal);
147  _addrToAbsVal = std::move(rhs._addrToAbsVal);
148  }
149  return *this;
150  }

◆ operator=() [2/2]

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

Definition at line 124 of file AbstractState.h.

125  {
126  if (rhs != *this)
127  {
128  _varToAbsVal = rhs._varToAbsVal;
129  _addrToAbsVal = rhs._addrToAbsVal;
130  }
131  return *this;
132  }

◆ operator==()

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

Definition at line 373 of file AbstractState.h.

374  {
375  return eqVarToValMap(_varToAbsVal, rhs.getVarToVal()) &&
376  eqVarToValMap(_addrToAbsVal, rhs.getLocToVal());
377  }
static bool eqVarToValMap(const VarToAbsValMap &lhs, const VarToAbsValMap &rhs)

◆ operator>=()

bool SVF::AbstractState::operator>= ( const AbstractState rhs) const
inline

Definition at line 390 of file AbstractState.h.

391  {
392  return geqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && geqVarToValMap(_addrToAbsVal, rhs.getLocToVal());
393  }
static bool geqVarToValMap(const VarToAbsValMap &lhs, const VarToAbsValMap &rhs)

◆ operator[]() [1/2]

virtual AbstractValue& SVF::AbstractState::operator[] ( u32_t  varId)
inlinevirtual

get abstract value of variable

Definition at line 196 of file AbstractState.h.

197  {
198  return _varToAbsVal[varId];
199  }

◆ operator[]() [2/2]

virtual const AbstractValue& SVF::AbstractState::operator[] ( u32_t  varId) const
inlinevirtual

get abstract value of variable

Definition at line 202 of file AbstractState.h.

203  {
204  return _varToAbsVal.at(varId);
205  }

◆ printAbstractState()

void AbstractState::printAbstractState ( ) const

Definition at line 391 of file AbstractState.cpp.

392 {
393  SVFUtil::outs() << "-----------Var and Value-----------\n";
394  u32_t fieldWidth = 20;
395  SVFUtil::outs().flags(std::ios::left);
396  std::vector<std::pair<u32_t, AbstractValue>> varToAbsValVec(_varToAbsVal.begin(), _varToAbsVal.end());
397  std::sort(varToAbsValVec.begin(), varToAbsValVec.end(), [](const auto &a, const auto &b)
398  {
399  return a.first < b.first;
400  });
401  for (const auto &item: varToAbsValVec)
402  {
403  SVFUtil::outs() << std::left << std::setw(fieldWidth) << ("Var" + std::to_string(item.first));
404  if (item.second.isInterval())
405  {
406  SVFUtil::outs() << " Value: " << item.second.getInterval().toString() << "\n";
407  }
408  else if (item.second.isAddr())
409  {
410  SVFUtil::outs() << " Value: {";
411  u32_t i = 0;
412  for (const auto& addr: item.second.getAddrs())
413  {
414  ++i;
415  if (i < item.second.getAddrs().size())
416  {
417  SVFUtil::outs() << "0x" << std::hex << addr << ", ";
418  }
419  else
420  {
421  SVFUtil::outs() << "0x" << std::hex << addr;
422  }
423  }
424  SVFUtil::outs() << "}\n";
425  }
426  else
427  {
428  SVFUtil::outs() << " Value: ⊥\n";
429  }
430  }
431 
432  std::vector<std::pair<u32_t, AbstractValue>> addrToAbsValVec(_addrToAbsVal.begin(), _addrToAbsVal.end());
433  std::sort(addrToAbsValVec.begin(), addrToAbsValVec.end(), [](const auto &a, const auto &b)
434  {
435  return a.first < b.first;
436  });
437 
438  for (const auto& item: addrToAbsValVec)
439  {
440  std::ostringstream oss;
441  oss << "0x" << std::hex << AbstractState::getVirtualMemAddress(item.first);
442  SVFUtil::outs() << std::left << std::setw(fieldWidth) << oss.str();
443  if (item.second.isInterval())
444  {
445  SVFUtil::outs() << " Value: " << item.second.getInterval().toString() << "\n";
446  }
447  else if (item.second.isAddr())
448  {
449  SVFUtil::outs() << " Value: {";
450  u32_t i = 0;
451  for (const auto& addr: item.second.getAddrs())
452  {
453  ++i;
454  if (i < item.second.getAddrs().size())
455  {
456  SVFUtil::outs() << "0x" << std::hex << addr << ", ";
457  }
458  else
459  {
460  SVFUtil::outs() << "0x" << std::hex << addr;
461  }
462  }
463  SVFUtil::outs() << "}\n";
464  }
465  else
466  {
467  SVFUtil::outs() << " Value: ⊥\n";
468  }
469  }
470  SVFUtil::outs() << "-----------------------------------------\n";
471 }
cJSON * a
Definition: cJSON.cpp:2560
const cJSON *const b
Definition: cJSON.h:255
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50

◆ sliceState()

AbstractState SVF::AbstractState::sliceState ( Set< u32_t > &  sl)
inline

Copy some values and return a new IntervalExeState.

Definition at line 177 of file AbstractState.h.

178  {
179  AbstractState inv;
180  for (u32_t id: sl)
181  {
182  inv._varToAbsVal[id] = _varToAbsVal[id];
183  }
184  return inv;
185  }

◆ store()

void SVF::AbstractState::store ( u32_t  addr,
const AbstractValue val 
)
inline

Definition at line 299 of file AbstractState.h.

300  {
301  assert(isVirtualMemAddress(addr) && "not virtual address?");
302  if (isNullPtr(addr)) return;
303  u32_t objId = getInternalID(addr);
304  _addrToAbsVal[objId] = val;
305  }
static bool isNullPtr(u32_t addr)

◆ storeValue()

void AbstractState::storeValue ( NodeID  varId,
AbstractValue  val 
)

Definition at line 383 of file AbstractState.cpp.

384 {
385  for (auto addr : (*this)[varId].getAddrs())
386  {
387  store(addr, val); // *p = q
388  }
389 }
void store(u32_t addr, const AbstractValue &val)

◆ top()

AbstractState SVF::AbstractState::top ( ) const
inline

Set all value top.

Definition at line 165 of file AbstractState.h.

166  {
167  AbstractState inv = *this;
168  for (auto &item: inv._varToAbsVal)
169  {
170  if (item.second.isInterval())
171  item.second.getInterval().set_to_top();
172  }
173  return inv;
174  }

◆ toString()

std::string SVF::AbstractState::toString ( ) const
inline

Definition at line 318 of file AbstractState.h.

319  {
320  return "";
321  }

◆ widening()

AbstractState AbstractState::widening ( const AbstractState other)

domain widen with other, and return the widened domain

Definition at line 59 of file AbstractState.cpp.

60 {
61  // widen interval
62  AbstractState es = *this;
63  for (auto it = es._varToAbsVal.begin(); it != es._varToAbsVal.end(); ++it)
64  {
65  auto key = it->first;
66  if (other._varToAbsVal.find(key) != other._varToAbsVal.end())
67  if (it->second.isInterval() && other._varToAbsVal.at(key).isInterval())
68  it->second.getInterval().widen_with(other._varToAbsVal.at(key).getInterval());
69  }
70  for (auto it = es._addrToAbsVal.begin(); it != es._addrToAbsVal.end(); ++it)
71  {
72  auto key = it->first;
73  if (other._addrToAbsVal.find(key) != other._addrToAbsVal.end())
74  if (it->second.isInterval() && other._addrToAbsVal.at(key).isInterval())
75  it->second.getInterval().widen_with(other._addrToAbsVal.at(key).getInterval());
76  }
77  return es;
78 }

Friends And Related Function Documentation

◆ RelationSolver

friend class RelationSolver
friend

Definition at line 61 of file AbstractState.h.

◆ SVFIR2AbsState

friend class SVFIR2AbsState
friend

Definition at line 60 of file AbstractState.h.

Member Data Documentation

◆ _addrToAbsVal

AddrToAbsValMap SVF::AbstractState::_addrToAbsVal
protected

Map a memory address to its stored abstract value.

Definition at line 190 of file AbstractState.h.

◆ _varToAbsVal

VarToAbsValMap SVF::AbstractState::_varToAbsVal
protected

Map a variable (symbol) to its abstract value.

Definition at line 188 of file AbstractState.h.


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