Static Value-Flow Analysis
RelExeState.cpp
Go to the documentation of this file.
1 //===- RelExeState.cpp ----Relation Execution States for Interval Domains-------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-2022> <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  * RelExeState.cpp
24  *
25  * Created on: Aug 15, 2022
26  * Author: Jiawei Ren, Xiao Cheng
27  *
28  */
29 
30 #include "AE/Core/RelExeState.h"
31 #include "Util/GeneralType.h"
32 #include "Util/SVFUtil.h"
33 #include <iomanip>
34 
35 using namespace SVF;
36 using namespace SVFUtil;
37 
46 {
47  if (expr.getExpr().num_args() == 0)
48  if (!expr.getExpr().is_true() && !expr.getExpr().is_false() && !expr.is_numeral())
49  {
50  const std::string &exprStr = expr.to_string();
51  res.insert(std::stoi(exprStr.substr(1, exprStr.size() - 1)));
52  }
53  for (u32_t i = 0; i < expr.getExpr().num_args(); ++i)
54  {
55  const z3::expr &e = expr.getExpr().arg(i);
56  extractSubVars(e, res);
57  }
58 }
59 
67 {
68  Set<u32_t> r;
69  extractSubVars(expr, r);
70  res.insert(r.begin(), r.end());
71  assert(!r.empty() && "symbol not init?");
72  if (r.size() == 1 && eq(expr, toZ3Expr(*r.begin())))
73  {
74  return;
75  }
76  for (const auto &id: r)
77  {
78  extractCmpVars((*this)[id], res);
79  }
80 }
81 
91 {
92  Z3Expr res = (getZ3Expr(cmp) == succ).simplify();
93  extractSubVars(res, initVars);
94  extractCmpVars(res, vars);
95  for (const auto &id: vars)
96  {
97  res = (res && toZ3Expr(id) == getZ3Expr(id)).simplify();
98  }
99  res = (res && (toZ3Expr(cmp) == getZ3Expr(cmp))).simplify();
100  vars.insert(cmp);
101  return res;
102 }
103 
105 {
106  if (*this != rhs)
107  {
108  _varToVal = rhs.getVarToVal();
109  _addrToVal = rhs.getLocToVal();
110  }
111  return *this;
112 }
113 
119 bool RelExeState::operator==(const RelExeState &rhs) const
120 {
121  return eqVarToValMap(_varToVal, rhs.getVarToVal()) &&
122  eqVarToValMap(_addrToVal, rhs.getLocToVal());
123 }
124 
130 bool RelExeState::operator<(const RelExeState &rhs) const
131 {
132  return lessThanVarToValMap(_varToVal, rhs.getVarToVal()) ||
133  lessThanVarToValMap(_addrToVal, rhs.getLocToVal());
134 }
135 
136 bool RelExeState::eqVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs) const
137 {
138  if (lhs.size() != rhs.size()) return false;
139  for (const auto &item: lhs)
140  {
141  auto it = rhs.find(item.first);
142  // return false if SVFVar not exists in rhs or z3Expr not equal
143  if (it == rhs.end() || !eq(item.second, it->second))
144  return false;
145  }
146  return true;
147 }
148 
149 bool RelExeState::lessThanVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs) const
150 {
151  if (lhs.size() != rhs.size()) return lhs.size() < rhs.size();
152  for (const auto &item: lhs)
153  {
154  auto it = rhs.find(item.first);
155  // lhs > rhs if SVFVar not exists in rhs
156  if (it == rhs.end())
157  return false;
158  // judge from expr id
159  if (!eq(item.second, it->second))
160  return item.second.id() < it->second.id();
161  }
162  return false;
163 }
164 
170 void RelExeState::store(const Z3Expr &loc, const Z3Expr &value)
171 {
172  assert(loc.is_numeral() && "location must be numeral");
173  s32_t virAddr = z3Expr2NumValue(loc);
174  assert(isVirtualMemAddress(virAddr) && "Pointer operand is not a physical address?");
175  store(getInternalID(virAddr), value);
176 }
177 
184 {
185  assert(loc.is_numeral() && "location must be numeral");
186  s32_t virAddr = z3Expr2NumValue(loc);
187  assert(isVirtualMemAddress(virAddr) && "Pointer operand is not a physical address?");
188  u32_t objId = getInternalID(virAddr);
189  assert(getInternalID(objId) == objId && "SVFVar idx overflow > 0x7f000000?");
190  return load(objId);
191 }
192 
197 {
198  std::cout.flags(std::ios::left);
199  std::cout << "-----------Var and Value-----------\n";
200  for (const auto &item: getVarToVal())
201  {
202  std::stringstream exprName;
203  exprName << "Var" << item.first;
204  std::cout << std::setw(25) << exprName.str();
205  const Z3Expr &sim = item.second.simplify();
206  if (sim.is_numeral() && isVirtualMemAddress(z3Expr2NumValue(sim)))
207  {
208  std::cout << "\t Value: " << std::hex << "0x" << z3Expr2NumValue(sim) << "\n";
209  }
210  else
211  {
212  std::cout << "\t Value: " << std::dec << sim << "\n";
213  }
214  }
215  std::cout << "-----------------------------------------\n";
216 }
cJSON * item
Definition: cJSON.h:222
const char *const string
Definition: cJSON.h:172
bool lessThanVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs) const
void extractSubVars(const Z3Expr &expr, Set< u32_t > &res)
Extract sub SVFVar IDs of a Z3Expr.
Definition: RelExeState.cpp:45
void printExprValues()
Print values of all expressions.
void store(const Z3Expr &loc, const Z3Expr &value)
Store value to location.
RelExeState & operator=(const RelExeState &rhs)
const AddrToValMap & getLocToVal() const
Definition: RelExeState.h:104
const VarToValMap & getVarToVal() const
Definition: RelExeState.h:99
Z3Expr & load(const Z3Expr &loc)
Load value at location.
bool eqVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs) const
Z3Expr buildRelZ3Expr(u32_t cmp, s32_t succ, Set< u32_t > &vars, Set< u32_t > &initVars)
Build relational Z3Expr.
Definition: RelExeState.cpp:90
bool operator==(const RelExeState &rhs) const
Overloading Operator==.
bool operator<(const RelExeState &rhs) const
Overloading Operator==.
void extractCmpVars(const Z3Expr &expr, Set< u32_t > &res)
Extract all related SVFVar IDs based on compare expr.
Definition: RelExeState.cpp:66
Map< u32_t, Z3Expr > VarToValMap
Definition: RelExeState.h:44
const std::string to_string() const
Definition: Z3Expr.h:122
const z3::expr & getExpr() const
Definition: Z3Expr.h:86
bool is_numeral() const
Definition: Z3Expr.h:127
Z3Expr simplify() const
Definition: Z3Expr.h:137
for isBitcode
Definition: BasicTypes.h:68
signed s32_t
Definition: GeneralType.h:47
unsigned u32_t
Definition: GeneralType.h:46
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96