From 65b6f2095b89d50b29545bd4e3821f2477ee996f Mon Sep 17 00:00:00 2001 From: bjjwwang Date: Thu, 4 Apr 2024 16:38:42 +1100 Subject: [PATCH] remove ExeState and rename SVFIR2ItvExeState to SVFIR2AbsState --- svf-llvm/tools/Example/svf-ex.cpp | 4 +- svf/include/AE/Core/AbstractState.h | 5 +- svf/include/AE/Core/ConsExeState.h | 453 ---------- svf/include/AE/Core/ExeState.h | 304 ------- svf/include/AE/Core/IntervalValue.h | 1 + svf/include/AE/Core/RelExeState.h | 2 +- svf/include/AE/Core/SingleAbsValue.h | 477 ----------- svf/include/AE/Core/SymState.h | 221 ----- .../AE/Svfexe/AbstractInterpretation.h | 7 +- svf/include/AE/Svfexe/ICFGSimplification.h | 3 +- .../{SVFIR2ItvExeState.h => SVFIR2AbsState.h} | 17 +- svf/include/AE/Svfexe/SVFIR2ConsExeState.h | 148 ---- svf/lib/AE/Core/ConsExeState.cpp | 603 -------------- svf/lib/AE/Core/ExeState.cpp | 117 --- svf/lib/AE/Core/SVFIR2Relation.cpp | 20 +- svf/lib/AE/Core/SymState.cpp | 37 - svf/lib/AE/Svfexe/AbstractInterpretation.cpp | 10 +- ...FIR2ItvExeState.cpp => SVFIR2AbsState.cpp} | 66 +- svf/lib/AE/Svfexe/SVFIR2ConsExeState.cpp | 772 ------------------ 19 files changed, 66 insertions(+), 3201 deletions(-) delete mode 100644 svf/include/AE/Core/ConsExeState.h delete mode 100644 svf/include/AE/Core/ExeState.h delete mode 100644 svf/include/AE/Core/SingleAbsValue.h delete mode 100644 svf/include/AE/Core/SymState.h rename svf/include/AE/Svfexe/{SVFIR2ItvExeState.h => SVFIR2AbsState.h} (93%) delete mode 100644 svf/include/AE/Svfexe/SVFIR2ConsExeState.h delete mode 100644 svf/lib/AE/Core/ConsExeState.cpp delete mode 100644 svf/lib/AE/Core/ExeState.cpp delete mode 100644 svf/lib/AE/Core/SymState.cpp rename svf/lib/AE/Svfexe/{SVFIR2ItvExeState.cpp => SVFIR2AbsState.cpp} (94%) delete mode 100644 svf/lib/AE/Svfexe/SVFIR2ConsExeState.cpp diff --git a/svf-llvm/tools/Example/svf-ex.cpp b/svf-llvm/tools/Example/svf-ex.cpp index 4b56fc6b7..8d59722d2 100644 --- a/svf-llvm/tools/Example/svf-ex.cpp +++ b/svf-llvm/tools/Example/svf-ex.cpp @@ -26,7 +26,7 @@ // Author: Yulei Sui, */ -#include "AE/Svfexe/SVFIR2ItvExeState.h" +#include "AE/Svfexe/SVFIR2AbsState.h" #include "Graphs/SVFG.h" #include "SVF-LLVM/LLVMUtil.h" #include "SVF-LLVM/SVFIRBuilder.h" @@ -77,7 +77,7 @@ std::string printPts(PointerAnalysis* pta, const SVFValue* svfval) */ void traverseOnSVFStmt(const ICFGNode* node) { - SVFIR2ItvExeState* svfir2ExeState = new SVFIR2ItvExeState(SVFIR::getPAG()); + SVFIR2AbsState* svfir2ExeState = new SVFIR2AbsState(SVFIR::getPAG()); for (const SVFStmt* stmt: node->getSVFStmts()) { if (const AddrStmt *addr = SVFUtil::dyn_cast(stmt)) diff --git a/svf/include/AE/Core/AbstractState.h b/svf/include/AE/Core/AbstractState.h index 2b377484e..2a8157fa4 100644 --- a/svf/include/AE/Core/AbstractState.h +++ b/svf/include/AE/Core/AbstractState.h @@ -43,7 +43,6 @@ #ifndef Z3_EXAMPLE_INTERVAL_DOMAIN_H #define Z3_EXAMPLE_INTERVAL_DOMAIN_H -#include "AE/Core/ExeState.h" #include "AE/Core/IntervalValue.h" #include "AE/Core/AbstractValue.h" #include "Util/Z3Expr.h" @@ -54,7 +53,7 @@ namespace SVF { class AbstractState { - friend class SVFIR2ItvExeState; + friend class SVFIR2AbsState; friend class RelationSolver; public: typedef Map VarToAbsValMap; @@ -439,7 +438,7 @@ class AbstractState class SparseAbstractState : public AbstractState { - friend class SVFIR2ItvExeState; + friend class SVFIR2AbsState; friend class RelationSolver; public: diff --git a/svf/include/AE/Core/ConsExeState.h b/svf/include/AE/Core/ConsExeState.h deleted file mode 100644 index 6b595fe0e..000000000 --- a/svf/include/AE/Core/ConsExeState.h +++ /dev/null @@ -1,453 +0,0 @@ -//===- ConsExeState.h ----Constant Execution State-------------------------// -// -// SVF: Static Value-Flow Analysis -// -// Copyright (C) <2013-2022> -// - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . -// -//===----------------------------------------------------------------------===// -// -// Created by jiawei and xiao on 6/1/23. -// - -#ifndef SVF_CONSEXESTATE_H -#define SVF_CONSEXESTATE_H - -#include "AE/Core/ExeState.h" -#include "AE/Core/SingleAbsValue.h" - -#define NullptrID 0 - -namespace SVF -{ - -/*! - * Constant Expr Execution State - * - * Constant expr execution state support z3 symbolic value - * and gives a top value when two different constants join - * - * lattice: ⊤ may be constant - * / / | \ \ \ - * true ... c0 c1 ... false constant - * \ \ \ | | | - * ⊥ not constant - */ -class ConsExeState final : public ExeState -{ - friend class SVFIR2ConsExeState; - -public: - typedef Map VarToValMap; - typedef VarToValMap LocToValMap; - - static ConsExeState globalConsES; - -public: - ConsExeState(): ExeState(ExeState::SingleValueK) {} - - - /// Constructor - ConsExeState(VarToValMap varToValMap, LocToValMap locToValMap) : ExeState(ExeState::SingleValueK), _varToVal( - SVFUtil::move(varToValMap)), _locToVal(SVFUtil::move(locToValMap)) {} - - /// Copy Constructor - ConsExeState(const ConsExeState &rhs) : ExeState(rhs), _varToVal(rhs.getVarToVal()), - _locToVal(rhs.getLocToVal()) - { - - } - - /// Destructor - ~ConsExeState() override - { - _varToVal.clear(); - _locToVal.clear(); - } - - /// Copy operator - ConsExeState &operator=(const ConsExeState &rhs); - - /// Move Constructor - ConsExeState(ConsExeState &&rhs) noexcept: ExeState(std::move(rhs)), - _varToVal(SVFUtil::move(rhs._varToVal)), _locToVal(SVFUtil::move(rhs._locToVal)) - { - - } - - /// Move operator - ConsExeState &operator=(ConsExeState &&rhs) noexcept; - - /// Name - static inline std::string name() - { - return "ConstantExpr"; - } - - using ExeState::operator==; - using ExeState::operator!=; - - bool operator==(const ConsExeState &rhs) const; - - bool operator!=(const ConsExeState &other) const - { - return !(*this == other); - } - - bool operator<(const ConsExeState &rhs) const; - - u32_t hash() const override; - -protected: - - VarToValMap _varToVal; ///< Map a variable (symbol) to its constant value - LocToValMap _locToVal; ///< Map a memory address to its stored constant value - -public: - - /// get memory addresses of variable - virtual Addrs &getAddrs(u32_t id) override - { - auto it = globalConsES._varToAddrs.find(id); - if (it != globalConsES._varToAddrs.end()) return it->second; - return _varToAddrs[id]; - } - - /// get constant value of variable - inline SingleAbsValue &operator[](u32_t varId) - { - auto it = globalConsES._varToVal.find(varId); - if (it != globalConsES._varToVal.end()) - return it->second; - else - return _varToVal[varId]; - } - - /// whether the variable is in varToAddrs table - virtual inline bool inVarToAddrsTable(u32_t id) const override - { - return _varToAddrs.find(id) != _varToAddrs.end() || - globalConsES._varToAddrs.find(id) != globalConsES._varToAddrs.end(); - } - - /// whether the variable is in varToVal table - inline bool inVarToValTable(u32_t varId) const - { - return _varToVal.count(varId) || globalConsES._varToVal.count(varId); - } - - /// whether the memory address stores memory addresses - virtual inline bool inLocToAddrsTable(u32_t id) const override - { - return globalConsES._locToAddrs.find(id) != globalConsES._locToAddrs.end() || inLocalLocToAddrsTable(id); - } - - /// whether the memory address stores constant value - inline bool inLocToValTable(u32_t varId) const - { - return inLocalLocToValTable(varId) || globalConsES._locToVal.count(varId); - } - - inline const VarToValMap &getVarToVal() const - { - return _varToVal; - } - - inline const LocToValMap &getLocToVal() const - { - return _locToVal; - } - - virtual inline bool inLocalLocToAddrsTable(u32_t id) const - { - return _locToAddrs.find(id) != _locToAddrs.end(); - } - - inline bool inLocalLocToValTable(u32_t varId) const - { - return _locToVal.count(varId); - } - - inline bool inLocalLocToValTable(const SingleAbsValue& addr) const - { - return _locToVal.count(getInternalID(addr.getNumeral())); - } - -public: - - /// Merge rhs into this - bool joinWith(const ConsExeState &rhs); - - /// Build global execution state - void buildGlobES(ConsExeState &globES, Set &vars); - - /// Update symbolic states based on the summary/side-effect of callee - void applySummary(const ConsExeState &summary); - - inline bool equalVar(u32_t lhs, u32_t rhs) - { - if (!inVarToValTable(lhs) || !inVarToValTable(rhs)) return false; - return eq((*this)[lhs], (*this)[rhs]); - } - - /// Whether state is null state (uninitialized state) - inline bool isNullState() const - { - return _varToVal.size() == 1 && eq((*_varToVal.begin()).second, -1) && _locToVal.empty(); - } - - /// Print values of all expressions - void printExprValues() const; - - /// Print values of all expressions - void printExprValues(std::ostream &oss) const override; - - std::string toString() const override; - - std::string pcToString() const; - - std::string varToString(u32_t varId) const; - - std::string locToString(u32_t objId) const; - - bool applySelect(u32_t res, u32_t cond, u32_t top, u32_t fop); - - bool applyPhi(u32_t res, std::vector &ops); - - virtual Addrs &loadAddrs(u32_t addr) override - { - assert(isVirtualMemAddress(addr) && "not virtual address?"); - u32_t objId = getInternalID(addr); - auto it = _locToAddrs.find(objId); - if (it != _locToAddrs.end()) - { - return it->second; - } - else - { - auto globIt = globalConsES._locToAddrs.find(objId); - if (globIt != globalConsES._locToAddrs.end()) - { - return globIt->second; - } - else - { - return getAddrs(0); - } - } - } - - virtual std::string varToAddrs(u32_t varId) const override - { - std::stringstream exprName; - auto it = _varToAddrs.find(varId); - if (it == _varToAddrs.end()) - { - auto git = globalConsES._varToAddrs.find(varId); - if (git == globalConsES._varToAddrs.end()) - exprName << "Var not in varToAddrs!\n"; - else - { - const Addrs &vaddrs = git->second; - if (vaddrs.size() == 1) - { - exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n"; - } - else - { - exprName << "addr: {"; - for (const auto &addr: vaddrs) - { - exprName << std::dec << getInternalID(addr) << ", "; - } - exprName << "}\n"; - } - } - } - else - { - const Addrs &vaddrs = it->second; - if (vaddrs.size() == 1) - { - exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n"; - } - else - { - exprName << "addr: {"; - for (const auto &addr: vaddrs) - { - exprName << std::dec << getInternalID(addr) << ", "; - } - exprName << "}\n"; - } - } - return SVFUtil::move(exprName.str()); - } - - virtual std::string locToAddrs(u32_t objId) const override - { - std::stringstream exprName; - auto it = _locToAddrs.find(objId); - if (it == _locToAddrs.end()) - { - auto git = globalConsES._locToAddrs.find(objId); - if (git == globalConsES._locToAddrs.end()) - exprName << "Obj not in locToVal!\n"; - else - { - const Addrs &vaddrs = git->second; - if (vaddrs.size() == 1) - { - exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n"; - } - else - { - exprName << "addr: {"; - for (const auto &addr: vaddrs) - { - exprName << std::dec << getInternalID(addr) << ", "; - } - exprName << "}\n"; - } - } - } - else - { - const Addrs &vaddrs = it->second; - if (vaddrs.size() == 1) - { - exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n"; - } - else - { - exprName << "addr: {"; - for (const auto &addr: vaddrs) - { - exprName << std::dec << getInternalID(addr) << ", "; - } - exprName << "}\n"; - } - } - return SVFUtil::move(exprName.str()); - } - - /// Empty execution state with a true path constraint - static inline ConsExeState initExeState() - { - VarToValMap mp; - ConsExeState exeState(mp, SVFUtil::move(mp)); - return SVFUtil::move(exeState); - } - - /// Empty execution state with a null expr - static inline ConsExeState nullExeState() - { - VarToValMap mp; - ConsExeState exeState(mp, SVFUtil::move(mp)); - exeState._varToVal[NullptrID] = -1; - return SVFUtil::move(exeState); - } - -public: - - - - s64_t getNumber(u32_t lhs); - - static inline SingleAbsValue getIntOneZ3Expr() - { - return getContext().int_val(1); - } - - static inline SingleAbsValue getIntZeroZ3Expr() - { - return getContext().int_val(0); - } - - static inline SingleAbsValue getTrueZ3Expr() - { - return getContext().bool_val(true); - } - - static inline SingleAbsValue getFalseZ3Expr() - { - return getContext().bool_val(false); - } - -public: - - /// Store value to location - bool store(const SingleAbsValue &loc, const SingleAbsValue &value); - - /// Load value at location - SingleAbsValue load(const SingleAbsValue &loc); - - /// Return int value from an expression if it is a numeral, otherwise return an approximate value - static inline s32_t z3Expr2NumValue(const SingleAbsValue &e) - { - assert(e.is_numeral() && "not numeral?"); - int64_t i; - if(e.getExpr().is_numeral_i64(i)) - return e.get_numeral_int64(); - else - { - return e.leq(0) ? INT32_MIN : INT32_MAX; - } - } - - /// Whether two var to value map is equivalent - static bool eqVarToValMap(const VarToValMap &pre, const VarToValMap &nxt); - - - /// Whether lhs is less than rhs - static bool lessThanVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs); - - -private: - - - static bool assign(SingleAbsValue &lhs, const SingleAbsValue &rhs); - - inline bool store(u32_t objId, const SingleAbsValue &z3Expr) - { - SingleAbsValue &lhs = _locToVal[objId]; - if (!eq(lhs, z3Expr.simplify())) - { - lhs = z3Expr.simplify(); - return true; - } - else - return false; - } - - inline SingleAbsValue load(u32_t objId); -}; // end class ConExeState - -} // end namespace SVF - -/// Specialized hash for ConExeState -template<> -struct std::hash -{ - size_t operator()(const SVF::ConsExeState &exeState) const - { - return exeState.hash(); - } -}; - - - -#endif // SVF_CONSEXESTATE_H diff --git a/svf/include/AE/Core/ExeState.h b/svf/include/AE/Core/ExeState.h deleted file mode 100644 index c6b4970e9..000000000 --- a/svf/include/AE/Core/ExeState.h +++ /dev/null @@ -1,304 +0,0 @@ -//===- ExeState.h ----General Execution States-------------------------// -// -// SVF: Static Value-Flow Analysis -// -// Copyright (C) <2013-2022> -// - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . -// -//===----------------------------------------------------------------------===// -/* - * ExeState.h - * - * Created on: Aug 4, 2022 - * Author: Xiao Cheng - * - */ - - -#ifndef Z3_EXAMPLE_EXESTATE_H -#define Z3_EXAMPLE_EXESTATE_H - -#include "AE/Core/NumericLiteral.h" -#include "AE/Core/AddressValue.h" -#include "Util/Z3Expr.h" -#include "Util/SVFUtil.h" - -namespace SVF -{ - -class SparseAbstractState; - -/*! - * Base execution state - */ -class ExeState -{ - friend class SVFIR2ItvExeState; - -public: - - typedef AddressValue Addrs; - typedef Map VarToAddrs; - /// Execution state type - enum ExeState_TYPE - { - IntervalK, SingleValueK - }; -private: - ExeState_TYPE _kind; - -public: - ExeState(ExeState_TYPE kind) : _kind(kind) {} - - virtual ~ExeState() = default; - - ExeState(const ExeState &rhs) : _varToAddrs(rhs._varToAddrs), - _locToAddrs(rhs._locToAddrs) {} - - ExeState(ExeState &&rhs) noexcept: _varToAddrs(std::move(rhs._varToAddrs)), - _locToAddrs(std::move(rhs._locToAddrs)) {} - - ExeState &operator=(const ExeState &rhs) - { - if(*this != rhs) - { - _varToAddrs = rhs._varToAddrs; - _locToAddrs = rhs._locToAddrs; - } - return *this; - } - - ExeState &operator=(ExeState &&rhs) noexcept - { - if (this != &rhs) - { - _varToAddrs = std::move(rhs._varToAddrs); - _locToAddrs = std::move(rhs._locToAddrs); - } - return *this; - } - - -protected: - VarToAddrs _varToAddrs{{0, getVirtualMemAddress(0)}}; ///< Map a variable (symbol) to its memory addresses - VarToAddrs _locToAddrs; ///< Map a memory address to its stored memory addresses - -public: - - /// get memory addresses of variable - virtual Addrs &getAddrs(u32_t id) - { - return _varToAddrs[id]; - } - - /// whether the variable is in varToAddrs table - inline virtual bool inVarToAddrsTable(u32_t id) const - { - return _varToAddrs.find(id) != _varToAddrs.end(); - } - - /// whether the memory address stores memory addresses - inline virtual bool inLocToAddrsTable(u32_t id) const - { - return _locToAddrs.find(id) != _locToAddrs.end(); - } - - - inline virtual const VarToAddrs &getVarToAddrs() const - { - return _varToAddrs; - } - - inline virtual const VarToAddrs &getLocToAddrs() const - { - return _locToAddrs; - } - -public: - /// Make all value join with the other - bool joinWith(const ExeState &other); - - /// Make all value meet with the other - bool meetWith(const ExeState &other); - - virtual u32_t hash() const; - - /// Print values of all expressions - virtual void printExprValues(std::ostream &oss) const {} - - virtual std::string toString() const - { - return ""; - } - - inline ExeState_TYPE getExeStateKind() const - { - return _kind; - } - - - -public: - inline virtual void storeAddrs(u32_t addr, const Addrs &vaddrs) - { - assert(isVirtualMemAddress(addr) && "not virtual address?"); - if(isNullPtr(addr)) return; - u32_t objId = getInternalID(addr); - _locToAddrs[objId] = vaddrs; - } - - inline virtual Addrs &loadAddrs(u32_t addr) - { - assert(isVirtualMemAddress(addr) && "not virtual address?"); - u32_t objId = getInternalID(addr); - return _locToAddrs[objId]; - } - - inline bool isNullPtr(u32_t addr) - { - return getInternalID(addr) == 0; - } - -public: - - virtual bool operator==(const ExeState &rhs) const; - - inline virtual bool operator!=(const ExeState &rhs) const - { - return !(*this == rhs); - } - - bool equals(const ExeState *other) const - { - return false; - } - -protected: - - static bool eqVarToAddrs(const VarToAddrs &lhs, const VarToAddrs &rhs) - { - if (lhs.size() != rhs.size()) return false; - for (const auto &item: lhs) - { - auto it = rhs.find(item.first); - if (it == rhs.end()) - return false; - if (item.second.equals(it->second)) - { - return false; - } - } - return true; - } - -public: - - virtual std::string varToAddrs(u32_t varId) const - { - std::stringstream exprName; - auto it = _varToAddrs.find(varId); - if (it == _varToAddrs.end()) - { - exprName << "Var not in varToAddrs!\n"; - } - else - { - const Addrs &vaddrs = it->second; - if (vaddrs.size() == 1) - { - exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n"; - } - else - { - exprName << "addr: {"; - for (const auto &addr: vaddrs) - { - exprName << std::dec << getInternalID(addr) << ", "; - } - exprName << "}\n"; - } - } - return SVFUtil::move(exprName.str()); - } - - virtual std::string locToAddrs(u32_t objId) const - { - std::stringstream exprName; - auto it = _locToAddrs.find(objId); - if (it == _locToAddrs.end()) - { - exprName << "Var not in varToAddrs!\n"; - } - else - { - const Addrs &vaddrs = it->second; - if (vaddrs.size() == 1) - { - exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n"; - } - else - { - exprName << "addr: {"; - for (const auto &addr: vaddrs) - { - exprName << std::dec << getInternalID(addr) << ", "; - } - exprName << "}\n"; - } - } - return SVFUtil::move(exprName.str()); - } - -public: - static z3::context &getContext() - { - return Z3Expr::getContext(); - } - - /// The physical address starts with 0x7f...... + idx - static inline u32_t getVirtualMemAddress(u32_t idx) - { - return AddressValue::getVirtualMemAddress(idx); - } - - /// Check bit value of val start with 0x7F000000, filter by 0xFF000000 - static inline bool isVirtualMemAddress(u32_t val) - { - return AddressValue::isVirtualMemAddress(val); - } - - /// Return the internal index if idx is an address otherwise return the value of idx - static inline u32_t getInternalID(u32_t idx) - { - return AddressValue::getInternalID(idx); - } - - -}; // end class ExeState - - - -} // end namespace SVF - -template<> -struct std::hash -{ - size_t operator()(const SVF::ExeState &es) const - { - return es.hash(); - } -}; -#endif //Z3_EXAMPLE_EXESTATE_H diff --git a/svf/include/AE/Core/IntervalValue.h b/svf/include/AE/Core/IntervalValue.h index 3962fb7d0..7ad7a9b10 100644 --- a/svf/include/AE/Core/IntervalValue.h +++ b/svf/include/AE/Core/IntervalValue.h @@ -32,6 +32,7 @@ #define Z3_EXAMPLE_IntervalValue_H #include "AE/Core/NumericLiteral.h" +#include namespace SVF { diff --git a/svf/include/AE/Core/RelExeState.h b/svf/include/AE/Core/RelExeState.h index 4809f5eff..b2c6291b6 100644 --- a/svf/include/AE/Core/RelExeState.h +++ b/svf/include/AE/Core/RelExeState.h @@ -38,7 +38,7 @@ namespace SVF class RelExeState { - friend class SVFIR2ItvExeState; + friend class SVFIR2AbsState; public: typedef Map VarToValMap; diff --git a/svf/include/AE/Core/SingleAbsValue.h b/svf/include/AE/Core/SingleAbsValue.h deleted file mode 100644 index d2faadd54..000000000 --- a/svf/include/AE/Core/SingleAbsValue.h +++ /dev/null @@ -1,477 +0,0 @@ -// -// Created by Xiao and Jiawei on 2023/5/29. -// - -#ifndef SVF_SINGLEABSVALUE_H -#define SVF_SINGLEABSVALUE_H - -#include "AE/Core/BoundedZ3Expr.h" - -namespace SVF -{ - -/*! - * Atom Z3 expr for constant execution state - */ -class SingleAbsValue : public BoundedZ3Expr -{ -public: - - SingleAbsValue() = default; - - SingleAbsValue(const Z3Expr &z3Expr) : BoundedZ3Expr(z3Expr.getExpr()) {} - - SingleAbsValue(const BoundedZ3Expr &z3Bound) : BoundedZ3Expr(z3Bound) {} - - SingleAbsValue(const z3::expr &e) : BoundedZ3Expr(e) {} - - SingleAbsValue(s32_t i) : BoundedZ3Expr(i) {} - - SingleAbsValue(const SingleAbsValue &_z3Expr) : BoundedZ3Expr(_z3Expr) {} - - inline SingleAbsValue &operator=(const SingleAbsValue &rhs) - { - BoundedZ3Expr::operator=(rhs); - return *this; - } - - SingleAbsValue(SingleAbsValue &&_z3Expr) : BoundedZ3Expr(_z3Expr) - { - } - - inline SingleAbsValue &operator=(SingleAbsValue &&rhs) - { - BoundedZ3Expr::operator=(rhs); - return *this; - } - - static z3::context &getContext() - { - return BoundedZ3Expr::getContext(); - } - - static SingleAbsValue topConstant() - { - return getContext().int_const("⊤"); - } - - static SingleAbsValue bottomConstant() - { - return getContext().int_const("⊥"); - } - - void join_with(const SingleAbsValue& other) - { - if (this->isBottom()) - { - if (other.isBottom()) - { - return; - } - else - { - *this = other; - } - } - else if (other.isBottom()) - { - return; - } - else - { - if (!eq(*this, other)) - { - set_to_top(); - } - } - } - - void set_to_top() - { - *this = topConstant(); - } - - static bool isTopAbsValue(const SingleAbsValue &expr) - { - return eq(expr, topConstant()); - } - - static bool isBottomAbsValue(const SingleAbsValue &expr) - { - return eq(expr, bottomConstant()); - } - - inline bool isBottom() const - { - return isBottomAbsValue(*this); - } - - inline bool isTop() const - { - return isTopAbsValue(*this); - } - - inline bool isSym() const - { - return isSymbolAbsValue(*this); - } - - static bool isSymbolAbsValue(const SingleAbsValue &expr) - { - return !eq(expr, topConstant()) && !eq(expr, bottomConstant()) && !expr.is_numeral(); - } - - /// Less then or equal - bool leq(const SingleAbsValue &rhs) const - { - assert(is_numeral() && rhs.is_numeral()); - return (getExpr() <= rhs.getExpr()).simplify().is_true(); - } - - // Greater than or equal - bool geq(const SingleAbsValue &rhs) const - { - assert(is_numeral() && rhs.is_numeral()); - return (getExpr() >= rhs.getExpr()).simplify().is_true(); - } - - - /// Reload operator - //{% - friend SingleAbsValue operator==(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs)) - { - return bottomConstant(); - } - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - { - return topConstant(); - } - else - { - return static_cast(lhs) == static_cast(rhs); - } - } - - friend SingleAbsValue operator!=(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs)) - { - return bottomConstant(); - } - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return static_cast(lhs) != static_cast(rhs); - } - - friend SingleAbsValue operator>(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs)) - { - return bottomConstant(); - } - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return static_cast(lhs) > static_cast(rhs); - } - - friend SingleAbsValue operator<(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs)) - { - return bottomConstant(); - } - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return static_cast(lhs) < static_cast(rhs); - } - - friend SingleAbsValue operator<=(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs)) - { - return bottomConstant(); - } - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return static_cast(lhs) <= static_cast(rhs); - } - - friend SingleAbsValue operator>=(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs)) - { - return bottomConstant(); - } - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return static_cast(lhs) >= static_cast(rhs); - } - - friend SingleAbsValue operator+(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs)) - { - return bottomConstant(); - } - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return static_cast(lhs) + static_cast(rhs); - } - - friend SingleAbsValue operator-(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs)) - { - return bottomConstant(); - } - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return static_cast(lhs) - static_cast(rhs); - } - - friend SingleAbsValue operator*(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs)) - { - return bottomConstant(); - } - else if (isZero(lhs) || isZero(rhs)) - return 0; - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return static_cast(lhs) * static_cast(rhs); - } - - friend SingleAbsValue operator/(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs) || isZero(rhs)) - { - return bottomConstant(); - } - else if (isZero(lhs)) - return 0; - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return static_cast(lhs) / static_cast(rhs); - } - - friend SingleAbsValue operator%(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs) || isZero(rhs)) - { - return bottomConstant(); - } - else if (isZero(lhs)) - return 0; - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return static_cast(lhs) % static_cast(rhs); - } - - friend SingleAbsValue operator^(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs)) - return bottomConstant(); - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return static_cast(lhs) ^ static_cast(rhs); - } - - friend SingleAbsValue operator&(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs)) - { - return bottomConstant(); - } - else if (isZero(lhs) || isZero(rhs)) - return 0; - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return static_cast(lhs) & static_cast(rhs); - } - - friend SingleAbsValue operator|(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs)) - { - return bottomConstant(); - } - else if ((lhs.is_numeral() && eq(lhs, -1)) || - (rhs.is_numeral() && eq(rhs, -1))) - return -1; - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return static_cast(lhs) | static_cast(rhs); - } - - friend SingleAbsValue ashr(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs) || (rhs.is_numeral() && !rhs.geq(0))) - return bottomConstant(); - else if (isZero(lhs)) - return 0; - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return ashr(static_cast(lhs), static_cast(rhs)); - } - - friend SingleAbsValue shl(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs) || (rhs.is_numeral() && !rhs.geq(0))) - return bottomConstant(); - else if (isZero(lhs)) - return 0; - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return shl(static_cast(lhs), static_cast(rhs)); - } - - friend SingleAbsValue lshr(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs) || (rhs.is_numeral() && !rhs.geq(0))) - return bottomConstant(); - else if (isZero(lhs)) - return 0; - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return lshr(static_cast(lhs), static_cast(rhs)); - } - - friend SingleAbsValue int2bv(u32_t n, const SingleAbsValue &e) - { - if (isBottomAbsValue(e)) - { - return bottomConstant(); - } - else if (isTopAbsValue(e)) - return topConstant(); - else - return int2bv(n, static_cast(e)); - } - - friend SingleAbsValue bv2int(const SingleAbsValue &e, bool isSigned) - { - if (isBottomAbsValue(e)) - { - return bottomConstant(); - } - else if (isTopAbsValue(e)) - return topConstant(); - else - return bv2int(static_cast(e), isSigned); - } - - friend SingleAbsValue operator&&(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs)) - { - return bottomConstant(); - } - else if (eq(lhs, getContext().bool_val(false)) || eq(rhs, getContext().bool_val(false))) - return getContext().bool_val(false); - else if (eq(lhs, getContext().bool_val(true))) - return rhs; - else if (eq(rhs, getContext().bool_val(true))) - return lhs; - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return static_cast(lhs) && static_cast(rhs); - } - - friend SingleAbsValue operator||(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs)) - { - return bottomConstant(); - } - else if (eq(lhs, getContext().bool_val(true)) || eq(rhs, getContext().bool_val(true))) - return getContext().bool_val(true); - else if (eq(lhs, getContext().bool_val(false))) - return rhs; - else if (eq(rhs, getContext().bool_val(false))) - return lhs; - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs)) - return topConstant(); - else - return static_cast(lhs) || static_cast(rhs); - } - - friend SingleAbsValue operator!(const SingleAbsValue &lhs) - { - if (isBottomAbsValue(lhs)) - { - return bottomConstant(); - } - else if (isTopAbsValue(lhs)) - return topConstant(); - else - return !static_cast(lhs); - } - - friend SingleAbsValue ite(const SingleAbsValue &cond, const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - if (isBottomAbsValue(lhs) || isBottomAbsValue(rhs) || isBottomAbsValue(cond)) - { - return bottomConstant(); - } - else if (eq(cond, getContext().bool_val(true))) - return lhs; - else if (eq(cond, getContext().bool_val(false))) - return rhs; - else if (isTopAbsValue(lhs) || isTopAbsValue(rhs) || isTopAbsValue(cond)) - return topConstant(); - else - return ite(static_cast(cond), static_cast(lhs), - static_cast(rhs)); - } - - friend std::ostream &operator<<(std::ostream &out, const SingleAbsValue &expr) - { - out << static_cast(expr); - return out; - } - - friend bool eq(const SingleAbsValue &lhs, const SingleAbsValue &rhs) - { - return eq(static_cast(lhs), static_cast(rhs)); - } - - inline SingleAbsValue simplify() const - { - return getExpr().simplify(); - } - //%} -}; // end class ConZ3Expr -} // end namespace SVF - -/// Specialise hash for ConZ3Expr -template<> -struct std::hash -{ - size_t operator()(const SVF::SingleAbsValue &z3Expr) const - { - return z3Expr.hash(); - } -}; - - -#endif //SVF_SINGLEABSVALUE_H diff --git a/svf/include/AE/Core/SymState.h b/svf/include/AE/Core/SymState.h deleted file mode 100644 index cccc41a63..000000000 --- a/svf/include/AE/Core/SymState.h +++ /dev/null @@ -1,221 +0,0 @@ -//===- SymState.h ----Symbolic State-------------------------// -// -// SVF: Static Value-Flow Analysis -// -// Copyright (C) <2013-2022> -// - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . -// -//===----------------------------------------------------------------------===// - -// -// Created by jiawei and xiao on 6/1/23. -// - -#ifndef SVF_SYMSTATE_H -#define SVF_SYMSTATE_H - -#include "AE/Core/ConsExeState.h" - -namespace SVF -{ -/*! - * Symbolic state - * - * Execution State + Type State - */ -class SymState -{ - -public: - typedef std::string TypeState; - typedef std::vector KeyNodes; - typedef Set KeyNodesSet; - -private: - ConsExeState _exeState; ///< Execution state: values of variables - TypeState _typeState; ///< Type state: FSM node - -private: - /// Only for bug report - KeyNodesSet _keyNodesSet; ///< The nodes where abstract state changes - Z3Expr _branchCondition; ///< The branches current state passes - -public: - /// Constructor - SymState() : _exeState(ConsExeState::nullExeState()), _typeState("") {} - - /// Constructor - SymState(ConsExeState _es, TypeState _as); - - /// Destructor - virtual ~SymState() = default; - - /// Copy Constructor - SymState(const SymState &rhs) : _exeState(rhs._exeState), _typeState(rhs._typeState), _keyNodesSet(rhs._keyNodesSet), - _branchCondition(rhs._branchCondition) - { - - } - - /// Operator= - SymState &operator=(const SymState &rhs) - { - if (*this != rhs) - { - _typeState = rhs._typeState; - _exeState = rhs._exeState; - _keyNodesSet = rhs._keyNodesSet; - _branchCondition = rhs._branchCondition; - } - return *this; - } - - - /// Move Constructor - SymState(SymState &&rhs) noexcept: _exeState(SVFUtil::move(rhs._exeState)), - _typeState(SVFUtil::move(rhs._typeState)), - _keyNodesSet(SVFUtil::move(rhs._keyNodesSet)), - _branchCondition(rhs._branchCondition) - { - - } - - /// Move operator= - SymState &operator=(SymState &&rhs) noexcept - { - if (this != &rhs) - { - _typeState = SVFUtil::move(rhs._typeState); - _exeState = SVFUtil::move(rhs._exeState); - _keyNodesSet = SVFUtil::move(rhs._keyNodesSet); - _branchCondition = rhs._branchCondition; - } - return *this; - } - - const KeyNodesSet &getKeyNodesSet() const - { - return _keyNodesSet; - } - - - void insertKeyNode(NodeID id) - { - if (_keyNodesSet.empty()) - { - _keyNodesSet.insert(KeyNodes{id}); - } - else - { - for (const auto &df: _keyNodesSet) - { - const_cast(df).push_back(id); - } - } - } - - void setKeyNodesSet(KeyNodesSet ns) - { - _keyNodesSet = SVFUtil::move(ns); - } - - void clearKeyNodesSet() - { - _keyNodesSet.clear(); - } - - inline const Z3Expr &getBranchCondition() const - { - return _branchCondition; - } - - inline void setBranchCondition(const Z3Expr &br) - { - _branchCondition = br; - } - - const TypeState &getAbstractState() const - { - return _typeState; - } - - TypeState &getAbstractState() - { - return _typeState; - } - - void setAbsState(const TypeState &absState) - { - _typeState = absState; - } - - const ConsExeState &getExecutionState() const - { - return _exeState; - } - - ConsExeState &getExecutionState() - { - return _exeState; - } - - /// Overloading Operator== - inline bool operator==(const SymState &rhs) const - { - return _typeState == rhs.getAbstractState() && _exeState == rhs.getExecutionState(); - } - - /// Overloading Operator!= - inline bool operator!=(const SymState &rhs) const - { - return !(*this == rhs); - } - - /// Overloading Operator== - inline bool operator<(const SymState &rhs) const - { - if (_typeState != rhs.getAbstractState()) - return _typeState < rhs.getAbstractState(); - if (_exeState != rhs.getExecutionState()) - return _exeState < rhs.getExecutionState(); - return false; - } - - inline bool isNullSymState() const - { - return getExecutionState().isNullState() && getAbstractState().empty(); - } - -}; - -} // end namespace SVF - - - -/// Specialise hash for SymState -template<> -struct std::hash -{ - size_t operator()(const SVF::SymState &symState) const - { - - SVF::Hash> pairH; - - return pairH(make_pair(symState.getAbstractState(), symState.getExecutionState())); - } -}; - -#endif // SVF_SYMSTATE_H diff --git a/svf/include/AE/Svfexe/AbstractInterpretation.h b/svf/include/AE/Svfexe/AbstractInterpretation.h index 7040b134c..fdb649437 100644 --- a/svf/include/AE/Svfexe/AbstractInterpretation.h +++ b/svf/include/AE/Svfexe/AbstractInterpretation.h @@ -28,17 +28,16 @@ // Created by Jiawei Wang on 2024/1/10. // -#include "Util/SVFBugReport.h" #include "AE/Core/ICFGWTO.h" +#include "AE/Svfexe/SVFIR2AbsState.h" +#include "Util/SVFBugReport.h" #include "WPA/Andersen.h" -#include "AE/Svfexe/SVFIR2ItvExeState.h" namespace SVF { class AbstractInterpretation; class AEStat; class AEAPI; -class ExeState; template class FILOWorkList; @@ -343,7 +342,7 @@ class AbstractInterpretation SVFIR* _svfir; PTACallGraph* _callgraph; /// Execution State, used to store the Interval Value of every SVF variable - SVFIR2ItvExeState* _svfir2ExeState; + SVFIR2AbsState* _svfir2ExeState; AEAPI* _api{nullptr}; ICFG* _icfg; diff --git a/svf/include/AE/Svfexe/ICFGSimplification.h b/svf/include/AE/Svfexe/ICFGSimplification.h index eada0a8be..827a4f655 100644 --- a/svf/include/AE/Svfexe/ICFGSimplification.h +++ b/svf/include/AE/Svfexe/ICFGSimplification.h @@ -27,9 +27,8 @@ // // Created by Jiawei Wang on 2024/2/25. // +#include "AE/Svfexe/SVFIR2AbsState.h" #include "Graphs/ICFG.h" -#include "AE/Svfexe/SVFIR2ItvExeState.h" - namespace SVF { diff --git a/svf/include/AE/Svfexe/SVFIR2ItvExeState.h b/svf/include/AE/Svfexe/SVFIR2AbsState.h similarity index 93% rename from svf/include/AE/Svfexe/SVFIR2ItvExeState.h rename to svf/include/AE/Svfexe/SVFIR2AbsState.h index b27e8abbb..e2c868874 100644 --- a/svf/include/AE/Svfexe/SVFIR2ItvExeState.h +++ b/svf/include/AE/Svfexe/SVFIR2AbsState.h @@ -1,4 +1,4 @@ -//===- SVFIR2ItvExeState.h -- SVF IR Translation to Interval Domain-----// +//===- SVFIR2AbsState.h -- SVF IR Translation to Interval Domain-----// // // SVF: Static Value-Flow Analysis // @@ -23,7 +23,7 @@ // 46th International Conference on Software Engineering. (ICSE24) //===----------------------------------------------------------------------===// /* - * SVFIR2ItvExeState.h + * SVFIR2AbsState.h * * Created on: Aug 7, 2022 * Author: Jiawei Wang, Xiao Cheng @@ -34,25 +34,24 @@ #define Z3_EXAMPLE_SVFIR2ITVEXESTATE_H #include "AE/Core/AbstractState.h" -#include "AE/Core/ExeState.h" #include "AE/Core/RelExeState.h" #include "SVFIR/SVFIR.h" namespace SVF { -class SVFIR2ItvExeState +class SVFIR2AbsState { public: static AbstractValue globalNulladdrs; public: - SVFIR2ItvExeState(SVFIR *ir) : _svfir(ir) {} + SVFIR2AbsState(SVFIR *ir) : _svfir(ir) {} void setEs(const SparseAbstractState&es) { _es = es; } - SparseAbstractState&getEs() + SparseAbstractState& getEs() { return _es; } @@ -172,19 +171,19 @@ class SVFIR2ItvExeState /// Return the internal index if idx is an address otherwise return the value of idx static inline u32_t getInternalID(u32_t idx) { - return ExeState::getInternalID(idx); + return AbstractState::getInternalID(idx); } /// The physical address starts with 0x7f...... + idx static inline u32_t getVirtualMemAddress(u32_t idx) { - return ExeState::getVirtualMemAddress(idx); + return AbstractState::getVirtualMemAddress(idx); } /// Check bit value of val start with 0x7F000000, filter by 0xFF000000 static inline bool isVirtualMemAddress(u32_t val) { - return ExeState::isVirtualMemAddress(val); + return AbstractState::isVirtualMemAddress(val); } protected: diff --git a/svf/include/AE/Svfexe/SVFIR2ConsExeState.h b/svf/include/AE/Svfexe/SVFIR2ConsExeState.h deleted file mode 100644 index 93fb433a1..000000000 --- a/svf/include/AE/Svfexe/SVFIR2ConsExeState.h +++ /dev/null @@ -1,148 +0,0 @@ -//===- SVFIR2ConsExeState.h ----SVFIR2ConsExeState-------------------------// -// -// SVF: Static Value-Flow Analysis -// -// Copyright (C) <2013-2022> -// - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . -// -//===----------------------------------------------------------------------===// - -// -// Created by jiawei and xiao on 6/1/23. -// - -#ifndef SVF_SVFIR2CONSEXESTATE_H -#define SVF_SVFIR2CONSEXESTATE_H - -#include "AE/Core/ConsExeState.h" -#include "SVFIR/SVFIR.h" - -namespace SVF -{ -class SVFIR2ConsExeState -{ -public: - typedef ExeState::Addrs Addrs; - - SVFIR2ConsExeState() = default; - - void setEs(ConsExeState *es) - { - _es = es; - } - - ConsExeState *getEs() - { - return _es; - } - - virtual ~SVFIR2ConsExeState(); - - /// Translator for llvm ir - //{% - /// https://llvm.org/docs/LangRef.html#alloca-instruction - void translateAddr(const AddrStmt *addr); - - /// https://llvm.org/docs/LangRef.html#binary-operations - void translateBinary(const BinaryOPStmt *binary); - - /// https://llvm.org/docs/LangRef.html#icmp-instruction - void translateCmp(const CmpStmt *cmp); - - /// https://llvm.org/docs/LangRef.html#load-instruction - void translateLoad(const LoadStmt *load); - - /// https://llvm.org/docs/LangRef.html#store-instruction - void translateStore(const StoreStmt *store); - - /// https://llvm.org/docs/LangRef.html#conversion-operations - void translateCopy(const CopyStmt *copy); - - /// https://llvm.org/docs/LangRef.html#call-instruction - void translateCall(const CallPE *callPE); - - void translateRet(const RetPE *retPE); - - /// https://llvm.org/docs/LangRef.html#getelementptr-instruction - void translateGep(const GepStmt *gep, bool isGlobal); - - /// https://llvm.org/docs/LangRef.html#select-instruction - void translateSelect(const SelectStmt *select); - - /// https://llvm.org/docs/LangRef.html#i-phi - void translatePhi(const PhiStmt *phi); - - //%} - //%} - - /// Return the expr of gep object given a base and offset - Addrs getGepObjAddress(u32_t base, s32_t offset); - - /// Return the offset expression of a GepStmt - std::pair getGepOffset(const GepStmt *gep); - - /// Init ConZ3Expr for ObjVar - void initObjVar(const ObjVar *objVar, u32_t varId); - - - void initSVFVar(u32_t varId); - - void moveToGlobal(); - - /// The physical address starts with 0x7f...... + idx - static inline u32_t getVirtualMemAddress(u32_t idx) - { - return ExeState::getVirtualMemAddress(idx); - } - - /// Check bit value of val start with 0x7F000000, filter by 0xFF000000 - static inline bool isVirtualMemAddress(u32_t val) - { - return ExeState::isVirtualMemAddress(val); - } - - /// Return the internal index if idx is an address otherwise return the value of idx - static inline u32_t getInternalID(u32_t idx) - { - return ExeState::getInternalID(idx); - } - - inline bool inVarToValTable(u32_t id) const - { - return _es->inVarToValTable(id); - } - - inline bool inVarToAddrsTable(u32_t id) const - { - return _es->inVarToAddrsTable(id); - } - - inline bool inLocToValTable(u32_t id) const - { - return _es->inLocToValTable(id); - } - - inline bool inLocToAddrsTable(u32_t id) const - { - return _es->inLocToAddrsTable(id); - } - -protected: - ConsExeState *_es{nullptr}; -}; // end class SVFIR2ConsExeState -} // end namespace SVF - -#endif // SVF_SVFIR2CONSEXESTATE_H diff --git a/svf/lib/AE/Core/ConsExeState.cpp b/svf/lib/AE/Core/ConsExeState.cpp deleted file mode 100644 index 677a45cf5..000000000 --- a/svf/lib/AE/Core/ConsExeState.cpp +++ /dev/null @@ -1,603 +0,0 @@ -//===- ConsExeState.cpp ----Constant Execution State-------------------------// -// -// SVF: Static Value-Flow Analysis -// -// Copyright (C) <2013-2022> -// - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . -// -//===----------------------------------------------------------------------===// - -// -// Created by jiawei and xiao on 6/1/23. -// - -#include "AE/Core/ConsExeState.h" -#include "Util/Options.h" -#include - -using namespace SVF; -using namespace SVFUtil; - - -ConsExeState ConsExeState::globalConsES(initExeState()); - -/*! - * Copy operator - * @param rhs - * @return - */ -ConsExeState &ConsExeState::operator=(const ConsExeState &rhs) -{ - if (*this != rhs) - { - _varToVal = rhs.getVarToVal(); - _locToVal = rhs.getLocToVal(); - ExeState::operator=(rhs); - } - return *this; -} - -/*! - * Move operator - * @param rhs - * @return - */ -ConsExeState &ConsExeState::operator=(ConsExeState &&rhs) noexcept -{ - if (this != &rhs) - { - _varToVal = SVFUtil::move(rhs._varToVal); - _locToVal = SVFUtil::move(rhs._locToVal); - ExeState::operator=(std::move(rhs)); - } - return *this; -} - -/*! - * Overloading Operator== - * @param rhs - * @return - */ -bool ConsExeState::operator==(const ConsExeState &rhs) const -{ - // if values of variables are not changed, fix-point is reached - return ExeState::operator==(rhs) && eqVarToValMap(_varToVal, rhs.getVarToVal()) && - eqVarToValMap(_locToVal, rhs.getLocToVal()); -} - -/*! - * Overloading Operator< - * @param rhs - * @return - */ -bool ConsExeState::operator<(const ConsExeState &rhs) const -{ - // judge from path constraint - if (lessThanVarToValMap(_varToVal, rhs.getVarToVal()) || lessThanVarToValMap(_locToVal, rhs.getLocToVal())) - return true; - return false; -} - -u32_t ConsExeState::hash() const -{ - size_t bas = ExeState::hash(); - size_t h = getVarToVal().size() * 2; - SVF::Hash hf; - for (const auto &t: getVarToVal()) - { - h ^= hf(t.first) + 0x9e3779b9 + (h << 6) + (h >> 2); - h ^= hf(t.second.id()) + 0x9e3779b9 + (h << 6) + (h >> 2); - } - - size_t h2 = getVarToVal().size() * 2; - - for (const auto &t: getLocToVal()) - { - h2 ^= hf(t.first) + 0x9e3779b9 + (h2 << 6) + (h2 >> 2); - h2 ^= hf(t.second.id()) + 0x9e3779b9 + (h2 << 6) + (h2 >> 2); - } - SVF::Hash> pairH; - - return pairH(std::make_pair(bas, pairH(std::make_pair(h, h2)))); -} - -/*! - * Build global execution state - * @param globES - * @param vars - */ -void ConsExeState::buildGlobES(ConsExeState &globES, Set &vars) -{ - for (const auto &varId: vars) - { - SingleAbsValue &expr = globES[varId]; - if (expr.is_numeral() && isVirtualMemAddress(expr.get_numeral_int())) - { - if (globES.inLocalLocToValTable(expr)) - { - store(expr, globES.load(expr)); - } - } - } -} - -/*! - * Merge rhs into this - * @param rhs - * @return - */ -bool ConsExeState::joinWith(const SVF::ConsExeState &rhs) -{ - bool changed = ExeState::joinWith(rhs); - for (const auto &rhsItem: rhs._varToVal) - { - auto it = _varToVal.find(rhsItem.first); - // Intersection - lhs and rhs have the same var id - if (it != getVarToVal().end()) - { - if (it->second.isTop() || rhsItem.second.isTop()) - { - if (assign(it->second, SingleAbsValue::topConstant())) - changed = true; - } - else if (it->second.isBottom()) - { - if (assign(it->second, rhsItem.second)) - changed = true; - } - else if (rhsItem.second.isBottom()) - { - - } - else - { - if (!eq(it->second, rhsItem.second)) - { - if (assign(it->second, SingleAbsValue::topConstant())) - changed = true; - } - } - } - else - { - _varToVal.emplace(rhsItem.first, rhsItem.second); - changed = true; - } - } - - for (const auto &rhsItem: rhs._locToVal) - { - auto it = _locToVal.find(rhsItem.first); - // Intersection - lhs and rhs have the same var id - if (it != getLocToVal().end()) - { - if (it->second.isTop() || rhsItem.second.isTop()) - { - if (assign(it->second, SingleAbsValue::topConstant())) - changed = true; - } - else if (it->second.isBottom()) - { - if (assign(it->second, rhsItem.second)) - changed = true; - } - else if (rhsItem.second.isBottom()) - { - - } - else - { - if (!eq(it->second, rhsItem.second)) - { - if (assign(it->second, SingleAbsValue::topConstant())) - changed = true; - } - } - } - else - { - _locToVal.emplace(rhsItem.first, rhsItem.second); - changed = true; - } - } - return changed; -} - -/*! - * We should build a summary for each actual params to boost precision. - * The summary of callee only contains the side-effects of callee - * (input obj value, return value, global value) without irrelevant caller information. - * We apply the summary to the exestate at each callsite. - * @param summary - */ -void ConsExeState::applySummary(const ConsExeState &summary) -{ - for (const auto &item: summary._varToVal) - { - _varToVal[item.first] = item.second; - } - for (const auto &item: summary._locToVal) - { - _locToVal[item.first] = item.second; - } - for (const auto &item: summary._varToAddrs) - { - _varToAddrs[item.first] = item.second; - } - for (const auto &item: summary._locToAddrs) - { - _locToAddrs[item.first] = item.second; - } -} - -/*! - * Print values of all expressions - */ -void ConsExeState::printExprValues() const -{ - std::cout << "\n"; - std::cout.flags(std::ios::left); - std::cout << "\t-----------------Var and Value-----------------\n"; - for (const auto &item: getVarToVal()) - { - std::stringstream exprName; - exprName << "\tVar" << item.first; - std::cout << std::setw(20) << exprName.str(); - const SingleAbsValue &sim = item.second.simplify(); - if (sim.is_numeral() && isVirtualMemAddress(z3Expr2NumValue(sim))) - { - std::cout << "\t\t Value: " << std::hex << "0x" << z3Expr2NumValue(sim) << "\n"; - } - else - { - std::cout << "\t\t Value: " << std::dec << sim << "\n"; - } - } - std::cout << "\t-----------------------------------------------\n"; - std::cout << "\t-----------------Loc and Value-----------------\n"; - for (const auto &item: getLocToVal()) - { - std::stringstream exprName; - exprName << "\tVar" << item.first; - std::cout << std::setw(20) << exprName.str(); - const SingleAbsValue &sim = item.second.simplify(); - if (sim.is_numeral() && isVirtualMemAddress(z3Expr2NumValue(sim))) - { - std::cout << "\t\t Value: " << std::hex << "0x" << z3Expr2NumValue(sim) << "\n"; - } - else - { - std::cout << "\t\t Value: " << std::dec << sim << "\n"; - } - } - std::cout << "\t-----------------------------------------------\n"; -} - -void ConsExeState::printExprValues(std::ostream &oss) const -{ - oss << "\n"; - oss.flags(std::ios::left); - oss << "\t-----------------Var and Value-----------------\n"; - for (const auto &item: getVarToVal()) - { - std::stringstream exprName; - exprName << "\tVar" << item.first; - oss << std::setw(20) << exprName.str(); - const SingleAbsValue &sim = item.second.simplify(); - if (sim.is_numeral() && isVirtualMemAddress(z3Expr2NumValue(sim))) - { - oss << "\t\t Value: " << std::hex << "0x" << z3Expr2NumValue(sim) << "\n"; - } - else - { - oss << "\t\t Value: " << std::dec << sim << "\n"; - } - } - oss << "\t-----------------------------------------------\n"; - oss << "\t-----------------Loc and Value-----------------\n"; - for (const auto &item: getLocToVal()) - { - std::stringstream exprName; - exprName << "\tVar" << item.first; - oss << std::setw(20) << exprName.str(); - const SingleAbsValue &sim = item.second.simplify(); - if (sim.is_numeral() && isVirtualMemAddress(z3Expr2NumValue(sim))) - { - oss << "\t\t Value: " << std::hex << "0x" << z3Expr2NumValue(sim) << "\n"; - } - else - { - oss << "\t\t Value: " << std::dec << sim << "\n"; - } - } - oss << "\t-----------------------------------------------\n"; -} - -std::string ConsExeState::pcToString() const -{ - std::stringstream exprName; - exprName << "Path Constraint:\n"; - return SVFUtil::move(exprName.str()); -} - -std::string ConsExeState::varToString(u32_t valId) const -{ - std::stringstream exprName; - auto it = getVarToVal().find(valId); - if (it == getVarToVal().end()) - { - auto it2 = globalConsES._varToVal.find(valId); - if (it2 == globalConsES._varToVal.end()) - { - exprName << "Var not in varToVal!\n"; - } - else - { - const SingleAbsValue &sim = it2->second.simplify(); - if (sim.is_numeral() && isVirtualMemAddress(z3Expr2NumValue(sim))) - { - exprName << "addr: " << std::dec << getInternalID(z3Expr2NumValue(sim)) << "\n"; - } - else - { - if (sim.is_numeral()) - exprName << std::dec << z3Expr2NumValue(sim) << "\n"; - else - exprName << sim.to_string() << "\n"; - } - } - } - else - { - const SingleAbsValue &sim = it->second.simplify(); - if (sim.is_numeral() && isVirtualMemAddress(z3Expr2NumValue(sim))) - { - exprName << "addr: " << std::dec << getInternalID(z3Expr2NumValue(sim)) << "\n"; - } - else - { - if (sim.is_numeral()) - exprName << std::dec << z3Expr2NumValue(sim) << "\n"; - else - exprName << sim.to_string() << "\n"; - } - } - return SVFUtil::move(exprName.str()); -} - -std::string ConsExeState::locToString(u32_t objId) const -{ - std::stringstream exprName; - auto it = getLocToVal().find(objId); - if (it == getLocToVal().end()) - { - exprName << "Obj not in locToVal!\n"; - } - else - { - const SingleAbsValue &sim = it->second.simplify(); - if (sim.is_numeral() && isVirtualMemAddress(z3Expr2NumValue(sim))) - { - exprName << "addr: " << std::dec << getInternalID(z3Expr2NumValue(sim)) << "\n"; - } - else - { - if (sim.is_numeral()) - exprName << std::dec << z3Expr2NumValue(sim) << "\n"; - else - exprName << sim.to_string() << "\n"; - } - } - return SVFUtil::move(exprName.str()); -} - -std::string ConsExeState::toString() const -{ - std::stringstream exprName; - exprName << pcToString(); - exprName << "VarToVal:\n"; - for (const auto &item: getVarToVal()) - { - exprName << "Var" << std::to_string(item.first) << ":\n"; - const SingleAbsValue &sim = item.second.simplify(); - if (sim.is_numeral() && isVirtualMemAddress(z3Expr2NumValue(sim))) - { - exprName << " \tValue" << std::dec << getInternalID(z3Expr2NumValue(sim)) << "\n"; - } - else - { - exprName << " \tValue" << std::dec << z3Expr2NumValue(sim) << "\n"; - } - } - - exprName << "LocToVal:\n"; - for (const auto &item: getLocToVal()) - { - exprName << "Var" << std::to_string(item.first) << ":\n"; - const SingleAbsValue &sim = item.second.simplify(); - if (sim.is_numeral() && isVirtualMemAddress(z3Expr2NumValue(sim))) - { - exprName << " \tValue" << std::dec << getInternalID(z3Expr2NumValue(sim)) << "\n"; - } - else - { - exprName << " \tValue" << std::dec << z3Expr2NumValue(sim) << "\n"; - } - } - return SVFUtil::move(exprName.str()); -} - -bool ConsExeState::applySelect(u32_t res, u32_t cond, u32_t top, u32_t fop) -{ - if (inVarToValTable(top) && inVarToValTable(fop) && inVarToValTable(cond)) - { - SingleAbsValue &tExpr = (*this)[top], &fExpr = (*this)[fop], &condExpr = (*this)[cond]; - - return assign((*this)[res], ite(condExpr == 1, tExpr, fExpr)); - } - else if (inVarToAddrsTable(top) && inVarToAddrsTable(fop) && inVarToValTable(cond)) - { - SingleAbsValue &condExpr = (*this)[cond]; - if (condExpr.is_numeral()) - { - getAddrs(res) = condExpr.is_zero() ? getAddrs(fop) : getAddrs(top); - } - } - return false; -} - -bool ConsExeState::applyPhi(u32_t res, std::vector &ops) -{ - for (u32_t i = 0; i < ops.size(); i++) - { - NodeID curId = ops[i]; - if (inVarToValTable(curId)) - { - const SingleAbsValue &cur = (*this)[curId]; - if (!inVarToValTable(res)) - { - (*this)[res] = cur; - } - else - { - (*this)[res].join_with(cur); - } - } - else if (inVarToAddrsTable(curId)) - { - const Addrs &cur = getAddrs(curId); - if (!inVarToAddrsTable(res)) - { - getAddrs(res) = cur; - } - else - { - getAddrs(res).join_with(cur); - } - } - } - return true; -} - -s64_t ConsExeState::getNumber(u32_t lhs) -{ - return z3Expr2NumValue((*this)[lhs]); -} - -/*! - * Store value to location - * @param loc location, e.g., int_val(0x7f..01) - * @param value - */ -bool ConsExeState::store(const SingleAbsValue &loc, const SingleAbsValue &value) -{ - assert(loc.is_numeral() && "location must be numeral"); - s32_t virAddr = z3Expr2NumValue(loc); - assert(isVirtualMemAddress(virAddr) && "Pointer operand is not a physical address?"); - return store(getInternalID(virAddr), value); -} - -/*! - * Load value at location - * @param loc location, e.g., int_val(0x7f..01) - * @return - */ -SingleAbsValue ConsExeState::load(const SingleAbsValue &loc) -{ - assert(loc.is_numeral() && "location must be numeral"); - s32_t virAddr = z3Expr2NumValue(loc); - assert(isVirtualMemAddress(virAddr) && "Pointer operand is not a physical address?"); - u32_t objId = getInternalID(virAddr); - assert(getInternalID(objId) == objId && "SVFVar idx overflow > 0x7f000000?"); - return load(objId); -} - - -/*! - * Whether two var to value map is equivalent - * @param pre - * @param nxt - * @return - */ -bool ConsExeState::eqVarToValMap(const VarToValMap &pre, const VarToValMap &nxt) -{ - if (pre.size() != nxt.size()) return false; - for (const auto &item: nxt) - { - auto it = pre.find(item.first); - // return false if SVFVar not exists in rhs - if (it == pre.end()) - return false; - if (!eq(it->second, item.second)) - return false; - } - return true; -} - -/*! - * Whether lhs is less than rhs - * @param lhs - * @param rhs - * @return - */ -bool ConsExeState::lessThanVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs) -{ - if (lhs.size() != rhs.size()) return lhs.size() < rhs.size(); - for (const auto &item: lhs) - { - auto it = rhs.find(item.first); - // lhs > rhs if SVFVar not exists in rhs - if (it == rhs.end()) - return false; - // judge from expr id - if (!eq(item.second, it->second)) - return item.second.id() < it->second.id(); - } - return false; -} - -SingleAbsValue ConsExeState::load(u32_t objId) -{ - auto it = _locToVal.find(objId); - if (it != _locToVal.end()) - { - return it->second; - } - else - { - auto globIt = globalConsES._locToVal.find(objId); - if (globIt != globalConsES._locToVal.end()) - return globIt->second; - else - { - SVFUtil::writeWrnMsg("Null dereference"); - return SingleAbsValue::topConstant(); - } - } -} - -bool ConsExeState::assign(SingleAbsValue &lhs, const SingleAbsValue &rhs) -{ - if (!eq(lhs, rhs)) - { - lhs = rhs; - return true; - } - else - { - return false; - } -} diff --git a/svf/lib/AE/Core/ExeState.cpp b/svf/lib/AE/Core/ExeState.cpp deleted file mode 100644 index 7e1a98b0f..000000000 --- a/svf/lib/AE/Core/ExeState.cpp +++ /dev/null @@ -1,117 +0,0 @@ -//===- ExeState.cpp ----General Execution States-------------------------// -// -// SVF: Static Value-Flow Analysis -// -// Copyright (C) <2013-2022> -// - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . -// -//===----------------------------------------------------------------------===// -/* - * ExeState.cpp - * - * Created on: Aug 4, 2022 - * Author: Xiao Cheng - * - */ - -#include "AE/Core/ExeState.h" -#include "AE/Core/AbstractState.h" - -using namespace SVF; - -bool ExeState::operator==(const ExeState &rhs) const -{ - return eqVarToAddrs(_varToAddrs, rhs._varToAddrs) && eqVarToAddrs(_locToAddrs, rhs._locToAddrs); -} - -bool ExeState::joinWith(const ExeState &other) -{ - bool changed = false; - for (auto it = other._varToAddrs.begin(); it != other._varToAddrs.end(); ++it) - { - auto key = it->first; - auto oit = _varToAddrs.find(key); - if (oit != _varToAddrs.end()) - { - if(oit->second.join_with(it->second)) - changed = true; - } - else - { - changed = true; - _varToAddrs.emplace(key, it->second); - } - } - for (auto it = other._locToAddrs.begin(); it != other._locToAddrs.end(); ++it) - { - auto key = it->first; - auto oit = _locToAddrs.find(key); - if (oit != _locToAddrs.end()) - { - if(oit->second.join_with(it->second)) - changed = true; - } - else - { - changed = true; - _locToAddrs.emplace(key, it->second); - } - } - return changed; -} - -bool ExeState::meetWith(const ExeState &other) -{ - bool changed = false; - for (auto it = other._varToAddrs.begin(); it != other._varToAddrs.end(); ++it) - { - auto key = it->first; - auto oit = _varToAddrs.find(key); - if (oit != _varToAddrs.end()) - { - if(oit->second.meet_with(it->second)) - changed = true; - } - } - for (auto it = other._locToAddrs.begin(); it != other._locToAddrs.end(); ++it) - { - auto key = it->first; - auto oit = _locToAddrs.find(key); - if (oit != _locToAddrs.end()) - { - if(oit->second.meet_with(it->second)) - changed = true; - } - } - return changed; -} - -u32_t ExeState::hash() const -{ - size_t h = getVarToAddrs().size() * 2; - Hash hf; - for (const auto &t: getVarToAddrs()) - { - h ^= hf(t.first) + 0x9e3779b9 + (h << 6) + (h >> 2); - } - size_t h2 = getLocToAddrs().size() * 2; - for (const auto &t: getLocToAddrs()) - { - h2 ^= hf(t.first) + 0x9e3779b9 + (h2 << 6) + (h2 >> 2); - } - Hash> pairH; - return pairH(std::make_pair(h, h2)); -} diff --git a/svf/lib/AE/Core/SVFIR2Relation.cpp b/svf/lib/AE/Core/SVFIR2Relation.cpp index b7a461eaf..cdab4692d 100644 --- a/svf/lib/AE/Core/SVFIR2Relation.cpp +++ b/svf/lib/AE/Core/SVFIR2Relation.cpp @@ -2,12 +2,12 @@ // Created by Xiao on 2022/8/18. // -#include "AE/Svfexe/SVFIR2ItvExeState.h" +#include "AE/Svfexe/SVFIR2AbsState.h" using namespace SVF; using namespace SVFUtil; -void SVFIR2ItvExeState::translateBinaryRel(const BinaryOPStmt *binary) +void SVFIR2AbsState::translateBinaryRel(const BinaryOPStmt *binary) { NodeID op0 = binary->getOpVarID(0); NodeID op1 = binary->getOpVarID(1); @@ -57,7 +57,7 @@ void SVFIR2ItvExeState::translateBinaryRel(const BinaryOPStmt *binary) } } -void SVFIR2ItvExeState::translateCmpRel(const CmpStmt *cmp) +void SVFIR2AbsState::translateCmpRel(const CmpStmt *cmp) { NodeID op0 = cmp->getOpVarID(0); NodeID op1 = cmp->getOpVarID(1); @@ -108,14 +108,14 @@ void SVFIR2ItvExeState::translateCmpRel(const CmpStmt *cmp) } } -void SVFIR2ItvExeState::translateLoadRel(const LoadStmt *load) +void SVFIR2AbsState::translateLoadRel(const LoadStmt *load) { u32_t rhs = load->getRHSVarID(); u32_t lhs = load->getLHSVarID(); _relEs[lhs] = _relEs.load(Z3Expr((int) _es[rhs].getInterval().lb().getNumeral())); } -void SVFIR2ItvExeState::translateStoreRel(const StoreStmt *store) +void SVFIR2AbsState::translateStoreRel(const StoreStmt *store) { u32_t rhs = store->getRHSVarID(); u32_t lhs = store->getLHSVarID(); @@ -124,14 +124,14 @@ void SVFIR2ItvExeState::translateStoreRel(const StoreStmt *store) } -void SVFIR2ItvExeState::translateCopyRel(const CopyStmt *copy) +void SVFIR2AbsState::translateCopyRel(const CopyStmt *copy) { u32_t rhs = copy->getRHSVarID(); u32_t lhs = copy->getLHSVarID(); _relEs[lhs] = _relEs.toZ3Expr(rhs); } -void SVFIR2ItvExeState::translateSelectRel(const SelectStmt *select) +void SVFIR2AbsState::translateSelectRel(const SelectStmt *select) { u32_t res = select->getResID(); u32_t tval = select->getTrueValue()->getId(); @@ -148,7 +148,7 @@ void SVFIR2ItvExeState::translateSelectRel(const SelectStmt *select) } } -void SVFIR2ItvExeState::translatePhiRel(const PhiStmt *phi, const ICFGNode *srcNode, +void SVFIR2AbsState::translatePhiRel(const PhiStmt *phi, const ICFGNode *srcNode, const std::vector &path) { u32_t res = phi->getResID(); @@ -176,14 +176,14 @@ void SVFIR2ItvExeState::translatePhiRel(const PhiStmt *phi, const ICFGNode *srcN assert(false && "predecessor ICFGNode of this PhiStmt not found?"); } -void SVFIR2ItvExeState::translateCallRel(const CallPE *callPE) +void SVFIR2AbsState::translateCallRel(const CallPE *callPE) { u32_t rhs = callPE->getRHSVarID(); u32_t lhs = callPE->getLHSVarID(); _relEs[lhs] = _relEs.toZ3Expr(rhs); } -void SVFIR2ItvExeState::translateRetRel(const RetPE *retPE) +void SVFIR2AbsState::translateRetRel(const RetPE *retPE) { u32_t lhs = retPE->getLHSVarID(); u32_t rhs = retPE->getRHSVarID(); diff --git a/svf/lib/AE/Core/SymState.cpp b/svf/lib/AE/Core/SymState.cpp deleted file mode 100644 index b21ff7b4a..000000000 --- a/svf/lib/AE/Core/SymState.cpp +++ /dev/null @@ -1,37 +0,0 @@ -//===- SymState.cpp ----Symbolic State-------------------------// -// -// SVF: Static Value-Flow Analysis -// -// Copyright (C) <2013-2022> -// - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . -// -//===----------------------------------------------------------------------===// - -// -// Created by jiawei and xiao on 6/1/23. -// - - -#include "AE/Core/SymState.h" - -using namespace SVF; - - -SymState::SymState(ConsExeState es, TypeState ts) : _exeState(SVFUtil::move(es)), _typeState(SVFUtil::move(ts)), - _branchCondition(Z3Expr::getContext().bool_val(true)) -{ - -} \ No newline at end of file diff --git a/svf/lib/AE/Svfexe/AbstractInterpretation.cpp b/svf/lib/AE/Svfexe/AbstractInterpretation.cpp index da5ad4616..c158b8417 100644 --- a/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +++ b/svf/lib/AE/Svfexe/AbstractInterpretation.cpp @@ -92,7 +92,7 @@ void AbstractInterpretation::runOnModule(ICFG *icfg) _svfir = PAG::getPAG(); _ander = AndersenWaveDiff::createAndersenWaveDiff(_svfir); // init SVF Execution States - _svfir2ExeState = new SVFIR2ItvExeState(_svfir); + _svfir2ExeState = new SVFIR2AbsState(_svfir); // init SSE External API Handler _callgraph = _ander->getPTACallGraph(); @@ -373,7 +373,7 @@ bool AbstractInterpretation::hasCmpBranchES(const CmpStmt* cmpStmt, s64_t succ, } else {} // change interval range according to the compare predicate - ExeState::Addrs addrs; + AddressValue addrs; if(load_op0 && new_es.inVarToAddrsTable(load_op0->getRHSVarID())) addrs = new_es.getAddrs(load_op0->getRHSVarID()).getAddrs(); @@ -517,7 +517,7 @@ bool AbstractInterpretation::hasSwitchBranchES(const SVFVar* var, s64_t succ, { if (new_es.inVarToAddrsTable(load->getRHSVarID())) { - ExeState::Addrs &addrs = new_es.getAddrs(load->getRHSVarID()).getAddrs(); + AddressValue &addrs = new_es.getAddrs(load->getRHSVarID()).getAddrs(); for (const auto &addr: addrs) { NodeID objId = new_es.getInternalID(addr); @@ -1631,7 +1631,7 @@ void AbstractInterpretation::handleMemcpy(const SVF::SVFValue *dst, const SVF::S { for (const auto &src: expr_src.getAddrs()) { - u32_t objId = ExeState::getInternalID(src); + u32_t objId = AbstractState::getInternalID(src); if (es.inLocToValTable(objId)) { es.store(dst, es.load(src)); @@ -1701,7 +1701,7 @@ void AbstractInterpretation::handleMemset(const SVF::SVFValue *dst, AbstractValu AbstractValue lhs_gep = _svfir2ExeState->getGepObjAddress(dstId, index); for (const auto &addr: lhs_gep.getAddrs()) { - u32_t objId = ExeState::getInternalID(addr); + u32_t objId = AbstractState::getInternalID(addr); if (es.inLocToValTable(objId)) { AbstractValue tmp = es.load(addr); diff --git a/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp b/svf/lib/AE/Svfexe/SVFIR2AbsState.cpp similarity index 94% rename from svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp rename to svf/lib/AE/Svfexe/SVFIR2AbsState.cpp index 8a3414dc0..3f3c874aa 100644 --- a/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp +++ b/svf/lib/AE/Svfexe/SVFIR2AbsState.cpp @@ -1,4 +1,4 @@ -//===- SVFIR2ItvExeState.cpp -- SVF IR Translation to Interval Domain-----// +//===- SVFIR2AbsState.cpp -- SVF IR Translation to Interval Domain-----// // // SVF: Static Value-Flow Analysis // @@ -20,20 +20,20 @@ // //===----------------------------------------------------------------------===// /* - * SVFIR2ItvExeState.cpp + * SVFIR2AbsState.cpp * * Created on: Aug 7, 2022 * Author: Jiawei Wang, Xiao Cheng * */ -#include "AE/Svfexe/SVFIR2ItvExeState.h" +#include "AE/Svfexe/SVFIR2AbsState.h" #include "Util/Options.h" using namespace SVF; using namespace SVFUtil; -AbstractValue SVF::SVFIR2ItvExeState::globalNulladdrs = AddressValue(); +AbstractValue SVF::SVFIR2AbsState::globalNulladdrs = AddressValue(); /** * This function, getRangeLimitFromType, calculates the lower and upper bounds of @@ -46,7 +46,7 @@ AbstractValue SVF::SVFIR2ItvExeState::globalNulladdrs = AddressValue(); * * @return An IntervalValue representing the lower and upper bounds of the range. */ -AbstractValue SVFIR2ItvExeState::getRangeLimitFromType(const SVFType* type) +AbstractValue SVFIR2AbsState::getRangeLimitFromType(const SVFType* type) { if (const SVFIntegerType* intType = SVFUtil::dyn_cast(type)) { @@ -108,7 +108,7 @@ AbstractValue SVFIR2ItvExeState::getRangeLimitFromType(const SVFType* type) } } -AbstractValue SVFIR2ItvExeState::getZExtValue(const SVFVar* var) +AbstractValue SVFIR2AbsState::getZExtValue(const SVFVar* var) { const SVFType* type = var->getType(); if (SVFUtil::isa(type)) @@ -153,12 +153,12 @@ AbstractValue SVFIR2ItvExeState::getZExtValue(const SVFVar* var) assert(false && "cannot support non-integer type"); } -AbstractValue SVFIR2ItvExeState::getSExtValue(const SVFVar* var) +AbstractValue SVFIR2AbsState::getSExtValue(const SVFVar* var) { return _es[var->getId()].getInterval(); } -AbstractValue SVFIR2ItvExeState::getFPToSIntValue(const SVF::SVFVar* var) +AbstractValue SVFIR2AbsState::getFPToSIntValue(const SVF::SVFVar* var) { if (_es[var->getId()].getInterval().is_real()) { @@ -176,7 +176,7 @@ AbstractValue SVFIR2ItvExeState::getFPToSIntValue(const SVF::SVFVar* var) } } -AbstractValue SVFIR2ItvExeState::getFPToUIntValue(const SVF::SVFVar* var) +AbstractValue SVFIR2AbsState::getFPToUIntValue(const SVF::SVFVar* var) { if (_es[var->getId()].getInterval().is_real()) { @@ -194,7 +194,7 @@ AbstractValue SVFIR2ItvExeState::getFPToUIntValue(const SVF::SVFVar* var) } } -AbstractValue SVFIR2ItvExeState::getSIntToFPValue(const SVF::SVFVar* var) +AbstractValue SVFIR2AbsState::getSIntToFPValue(const SVF::SVFVar* var) { // get the sint value of ub and lb s64_t sint_lb = _es[var->getId()].getInterval().lb().getIntNumeral(); @@ -205,7 +205,7 @@ AbstractValue SVFIR2ItvExeState::getSIntToFPValue(const SVF::SVFVar* var) return IntervalValue(float_lb, float_ub); } -AbstractValue SVFIR2ItvExeState::getUIntToFPValue(const SVF::SVFVar* var) +AbstractValue SVFIR2AbsState::getUIntToFPValue(const SVF::SVFVar* var) { // get the uint value of ub and lb u64_t uint_lb = _es[var->getId()].getInterval().lb().getIntNumeral(); @@ -216,7 +216,7 @@ AbstractValue SVFIR2ItvExeState::getUIntToFPValue(const SVF::SVFVar* var) return IntervalValue(float_lb, float_ub); } -AbstractValue SVFIR2ItvExeState::getTruncValue(const SVF::SVFVar* var, const SVFType* dstType) +AbstractValue SVFIR2AbsState::getTruncValue(const SVF::SVFVar* var, const SVFType* dstType) { // get the value of ub and lb s64_t int_lb = _es[var->getId()].getInterval().lb().getIntNumeral(); @@ -265,13 +265,13 @@ AbstractValue SVFIR2ItvExeState::getTruncValue(const SVF::SVFVar* var, const SVF } } -AbstractValue SVFIR2ItvExeState::getFPTruncValue(const SVF::SVFVar* var, const SVFType* dstType) +AbstractValue SVFIR2AbsState::getFPTruncValue(const SVF::SVFVar* var, const SVFType* dstType) { // TODO: now we do not really handle fptrunc return _es[var->getId()].getInterval(); } -void SVFIR2ItvExeState::applySummary(SparseAbstractState&es) +void SVFIR2AbsState::applySummary(SparseAbstractState&es) { for (const auto &item: es._varToAbsVal) { @@ -283,7 +283,7 @@ void SVFIR2ItvExeState::applySummary(SparseAbstractState&es) } } -void SVFIR2ItvExeState::moveToGlobal() +void SVFIR2AbsState::moveToGlobal() { for (const auto &it: _es._varToAbsVal) { @@ -300,7 +300,7 @@ void SVFIR2ItvExeState::moveToGlobal() _es._locToAbsVal.clear(); } -void SVFIR2ItvExeState::widenAddrs(SparseAbstractState&lhs, const SparseAbstractState&rhs) +void SVFIR2AbsState::widenAddrs(SparseAbstractState&lhs, const SparseAbstractState&rhs) { for (const auto &rhsItem: rhs._varToAbsVal) { @@ -346,7 +346,7 @@ void SVFIR2ItvExeState::widenAddrs(SparseAbstractState&lhs, const SparseAbstract } } -void SVFIR2ItvExeState::narrowAddrs(SparseAbstractState&lhs, const SparseAbstractState&rhs) +void SVFIR2AbsState::narrowAddrs(SparseAbstractState&lhs, const SparseAbstractState&rhs) { for (const auto &rhsItem: rhs._varToAbsVal) { @@ -386,7 +386,7 @@ void SVFIR2ItvExeState::narrowAddrs(SparseAbstractState&lhs, const SparseAbstrac } } -AbstractValue SVFIR2ItvExeState::getGepObjAddress(u32_t pointer, APOffset offset) +AbstractValue SVFIR2AbsState::getGepObjAddress(u32_t pointer, APOffset offset) { assert(!getAddrs(pointer).getAddrs().empty()); AbstractValue addrs = getAddrs(pointer); @@ -429,7 +429,7 @@ AbstractValue SVFIR2ItvExeState::getGepObjAddress(u32_t pointer, APOffset offset * Therefore the final byteoffset is [8+4*var1.lb(), 8+4*var1.ub()] * */ -AbstractValue SVFIR2ItvExeState::getByteOffset(const GepStmt *gep) +AbstractValue SVFIR2AbsState::getByteOffset(const GepStmt *gep) { if (gep->isConstantOffset()) return IntervalValue((s64_t)gep->accumulateConstantByteOffset()); @@ -499,7 +499,7 @@ AbstractValue SVFIR2ItvExeState::getByteOffset(const GepStmt *gep) * * @return A pair of APOffset values representing the offset range. */ -AbstractValue SVFIR2ItvExeState::getItvOfFlattenedElemIndex(const GepStmt *gep) +AbstractValue SVFIR2AbsState::getItvOfFlattenedElemIndex(const GepStmt *gep) { if (gep->isConstantOffset()) return IntervalValue((s64_t)gep->accumulateConstantOffset()); @@ -574,7 +574,7 @@ AbstractValue SVFIR2ItvExeState::getItvOfFlattenedElemIndex(const GepStmt *gep) * @param objVar * @param valExprIdToCondValPairMap */ -void SVFIR2ItvExeState::initObjVar(const ObjVar *objVar, u32_t varId) +void SVFIR2AbsState::initObjVar(const ObjVar *objVar, u32_t varId) { if (objVar->hasValue()) @@ -609,7 +609,7 @@ void SVFIR2ItvExeState::initObjVar(const ObjVar *objVar, u32_t varId) SparseAbstractState::globalES[varId] = AddressValue(getVirtualMemAddress(varId)); } -void SVFIR2ItvExeState::initSVFVar(u32_t varId) +void SVFIR2AbsState::initSVFVar(u32_t varId) { if (inVarToValTable(varId) || _es.inVarToAddrsTable(varId)) return; SVFIR *svfir = PAG::getPAG(); @@ -627,7 +627,7 @@ void SVFIR2ItvExeState::initSVFVar(u32_t varId) } -void SVFIR2ItvExeState::translateAddr(const AddrStmt *addr) +void SVFIR2AbsState::translateAddr(const AddrStmt *addr) { initSVFVar(addr->getRHSVarID()); if (inVarToValTable(addr->getRHSVarID())) @@ -653,7 +653,7 @@ void SVFIR2ItvExeState::translateAddr(const AddrStmt *addr) } -void SVFIR2ItvExeState::translateBinary(const BinaryOPStmt *binary) +void SVFIR2AbsState::translateBinary(const BinaryOPStmt *binary) { u32_t op0 = binary->getOpVarID(0); u32_t op1 = binary->getOpVarID(1); @@ -715,7 +715,7 @@ void SVFIR2ItvExeState::translateBinary(const BinaryOPStmt *binary) } } -void SVFIR2ItvExeState::translateCmp(const CmpStmt *cmp) +void SVFIR2AbsState::translateCmp(const CmpStmt *cmp) { u32_t op0 = cmp->getOpVarID(0); u32_t op1 = cmp->getOpVarID(1); @@ -901,7 +901,7 @@ void SVFIR2ItvExeState::translateCmp(const CmpStmt *cmp) } } -void SVFIR2ItvExeState::translateLoad(const LoadStmt *load) +void SVFIR2AbsState::translateLoad(const LoadStmt *load) { u32_t rhs = load->getRHSVarID(); u32_t lhs = load->getLHSVarID(); @@ -927,7 +927,7 @@ void SVFIR2ItvExeState::translateLoad(const LoadStmt *load) } } -void SVFIR2ItvExeState::translateStore(const StoreStmt *store) +void SVFIR2AbsState::translateStore(const StoreStmt *store) { u32_t rhs = store->getRHSVarID(); u32_t lhs = store->getLHSVarID(); @@ -952,7 +952,7 @@ void SVFIR2ItvExeState::translateStore(const StoreStmt *store) } } -void SVFIR2ItvExeState::translateCopy(const CopyStmt *copy) +void SVFIR2AbsState::translateCopy(const CopyStmt *copy) { u32_t lhs = copy->getLHSVarID(); u32_t rhs = copy->getRHSVarID(); @@ -1033,7 +1033,7 @@ void SVFIR2ItvExeState::translateCopy(const CopyStmt *copy) } } -void SVFIR2ItvExeState::translateGep(const GepStmt *gep) +void SVFIR2AbsState::translateGep(const GepStmt *gep) { u32_t rhs = gep->getRHSVarID(); u32_t lhs = gep->getLHSVarID(); @@ -1058,7 +1058,7 @@ void SVFIR2ItvExeState::translateGep(const GepStmt *gep) } } -void SVFIR2ItvExeState::translateSelect(const SelectStmt *select) +void SVFIR2AbsState::translateSelect(const SelectStmt *select) { u32_t res = select->getResID(); u32_t tval = select->getTrueValue()->getId(); @@ -1086,7 +1086,7 @@ void SVFIR2ItvExeState::translateSelect(const SelectStmt *select) } } -void SVFIR2ItvExeState::translatePhi(const PhiStmt *phi) +void SVFIR2AbsState::translatePhi(const PhiStmt *phi) { u32_t res = phi->getResID(); AbstractValue rhs(AbstractValue::UnknownType); @@ -1104,7 +1104,7 @@ void SVFIR2ItvExeState::translatePhi(const PhiStmt *phi) } -void SVFIR2ItvExeState::translateCall(const CallPE *callPE) +void SVFIR2AbsState::translateCall(const CallPE *callPE) { NodeID lhs = callPE->getLHSVarID(); NodeID rhs = callPE->getRHSVarID(); @@ -1114,7 +1114,7 @@ void SVFIR2ItvExeState::translateCall(const CallPE *callPE) } } -void SVFIR2ItvExeState::translateRet(const RetPE *retPE) +void SVFIR2AbsState::translateRet(const RetPE *retPE) { NodeID lhs = retPE->getLHSVarID(); NodeID rhs = retPE->getRHSVarID(); diff --git a/svf/lib/AE/Svfexe/SVFIR2ConsExeState.cpp b/svf/lib/AE/Svfexe/SVFIR2ConsExeState.cpp deleted file mode 100644 index 0bbc19d01..000000000 --- a/svf/lib/AE/Svfexe/SVFIR2ConsExeState.cpp +++ /dev/null @@ -1,772 +0,0 @@ -//===- SVFIR2ConsExeState.cpp ----SVFIR2ConsExeState-------------------------// -// -// SVF: Static Value-Flow Analysis -// -// Copyright (C) <2013-2022> -// - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . -// -//===----------------------------------------------------------------------===// - -// -// Created by jiawei and xiao on 6/1/23. -// - - -#include "AE/Svfexe/SVFIR2ConsExeState.h" -#include "Util/Options.h" - -using namespace SVF; -using namespace SVFUtil; -using namespace std; - -SVFIR2ConsExeState::~SVFIR2ConsExeState() -{ - ConsExeState::globalConsES._varToVal.clear(); - ConsExeState::globalConsES._varToAddrs.clear(); - ConsExeState::globalConsES._locToVal.clear(); - ConsExeState::globalConsES._locToAddrs.clear(); -} -/// Translator for llvm ir -//{% -/*! - * https://llvm.org/docs/LangRef.html#alloca-instruction - * @param addr - * @return - */ -void SVFIR2ConsExeState::translateAddr(const AddrStmt *addr) -{ - initSVFVar(addr->getRHSVarID()); - if (inVarToValTable(addr->getRHSVarID())) - { - _es->globalConsES._varToVal[addr->getLHSVarID()] = _es->globalConsES._varToVal[addr->getRHSVarID()]; - } - else if (inVarToAddrsTable(addr->getRHSVarID())) - { - _es->globalConsES._varToAddrs[addr->getLHSVarID()] = _es->globalConsES._varToAddrs[addr->getRHSVarID()]; - } - else - { - assert(false && "not number or virtual addrs?"); - } -} - -/*! - * https://llvm.org/docs/LangRef.html#binary-operations - * @param binary - * @return - */ -void SVFIR2ConsExeState::translateBinary(const BinaryOPStmt *binary) -{ - u32_t op0 = binary->getOpVarID(0); - u32_t op1 = binary->getOpVarID(1); - u32_t res = binary->getResID(); - // rhs is not initialized - if (!_es->inVarToValTable(op0) || !_es->inVarToValTable(op1)) - return; - - SingleAbsValue &lhs = (*_es)[op0], &rhs = (*_es)[op1]; - SingleAbsValue resVal; - switch (binary->getOpcode()) - { - case BinaryOPStmt::Add: - case BinaryOPStmt::FAdd: - resVal = (lhs + rhs).simplify(); - break; - case BinaryOPStmt::Sub: - case BinaryOPStmt::FSub: - resVal = (lhs - rhs).simplify(); - break; - case BinaryOPStmt::Mul: - case BinaryOPStmt::FMul: - resVal = (lhs * rhs).simplify(); - break; - case BinaryOPStmt::SDiv: - case BinaryOPStmt::FDiv: - case BinaryOPStmt::UDiv: - resVal = (lhs / rhs).simplify(); - break; - case BinaryOPStmt::SRem: - case BinaryOPStmt::FRem: - case BinaryOPStmt::URem: - resVal = (lhs % rhs).simplify(); - break; - case BinaryOPStmt::Xor: - resVal = (lhs ^ rhs).simplify(); - break; - case BinaryOPStmt::And: - resVal = (lhs & rhs).simplify(); - break; - case BinaryOPStmt::Or: - resVal = (lhs | rhs).simplify(); - break; - case BinaryOPStmt::AShr: - resVal = ashr(lhs, rhs).simplify(); - break; - case BinaryOPStmt::Shl: - resVal = shl(lhs, rhs).simplify(); - break; - case BinaryOPStmt::LShr: - resVal = lshr(lhs, rhs).simplify(); - break; - default: - { - assert(false && "undefined binary"); - } - } - (*_es)[res] = resVal; -} - -/*! - * https://llvm.org/docs/LangRef.html#icmp-instruction - * @param cmp - * @return - */ -void SVFIR2ConsExeState::translateCmp(const CmpStmt *cmp) -{ - u32_t op0 = cmp->getOpVarID(0); - u32_t op1 = cmp->getOpVarID(1); - u32_t res = cmp->getResID(); - if (inVarToValTable(op0) && inVarToValTable(op1)) - { - SingleAbsValue &lhs = (*_es)[op0], &rhs = (*_es)[op1]; - SingleAbsValue resVal; - auto predicate = cmp->getPredicate(); - switch (predicate) - { - case CmpStmt::ICMP_EQ: - case CmpStmt::FCMP_OEQ: - case CmpStmt::FCMP_UEQ: - resVal = ite(lhs == rhs, 1, 0).simplify(); - break; - case CmpStmt::ICMP_NE: - case CmpStmt::FCMP_ONE: - case CmpStmt::FCMP_UNE: - resVal = ite(lhs != rhs, 1, 0).simplify(); - break; - case CmpStmt::ICMP_UGT: - case CmpStmt::ICMP_SGT: - case CmpStmt::FCMP_OGT: - case CmpStmt::FCMP_UGT: - resVal = ite(lhs > rhs, 1, 0).simplify(); - break; - case CmpStmt::ICMP_UGE: - case CmpStmt::ICMP_SGE: - case CmpStmt::FCMP_OGE: - case CmpStmt::FCMP_UGE: - resVal = ite(lhs >= rhs, 1, 0).simplify(); - break; - case CmpStmt::ICMP_ULT: - case CmpStmt::ICMP_SLT: - case CmpStmt::FCMP_OLT: - case CmpStmt::FCMP_ULT: - resVal = ite(lhs < rhs, 1, 0).simplify(); - break; - case CmpStmt::ICMP_ULE: - case CmpStmt::ICMP_SLE: - case CmpStmt::FCMP_OLE: - case CmpStmt::FCMP_ULE: - resVal = ite(lhs <= rhs, 1, 0).simplify(); - break; - case CmpStmt::FCMP_FALSE: - resVal = 0; - break; - case CmpStmt::FCMP_TRUE: - resVal = 1; - break; - default: - { - assert(false && "undefined compare"); - } - } - (*_es)[res] = resVal; - } - else if (inVarToAddrsTable(op0) && inVarToAddrsTable(op1)) - { - - Addrs &lhs = _es->getAddrs(op0), &rhs = _es->getAddrs(op1); - if (lhs.size() == 1) - { - (*_es)[res] = SingleAbsValue::topConstant(); - return; - } - if (rhs.size() == 1) - { - (*_es)[res] = SingleAbsValue::topConstant(); - return; - } - assert(!lhs.empty() && !rhs.empty() && "empty address?"); - auto predicate = cmp->getPredicate(); - switch (predicate) - { - case CmpStmt::ICMP_EQ: - case CmpStmt::FCMP_OEQ: - case CmpStmt::FCMP_UEQ: - { - if (lhs.size() == 1 && rhs.size() == 1) - { - (*_es)[res] = (lhs.getVals() == rhs.getVals()); - } - else - { - if (lhs.hasIntersect(rhs)) - { - (*_es)[res] = SingleAbsValue::topConstant(); - } - else - { - (*_es)[res] = 0; - } - } - return; - } - case CmpStmt::ICMP_NE: - case CmpStmt::FCMP_ONE: - case CmpStmt::FCMP_UNE: - { - if (lhs.size() == 1 && rhs.size() == 1) - { - (*_es)[res] = (lhs.getVals() != rhs.getVals()); - } - else - { - if (lhs.hasIntersect(rhs)) - { - (*_es)[res] = SingleAbsValue::topConstant(); - } - else - { - (*_es)[res] = 1; - } - } - return; - } - case CmpStmt::ICMP_UGT: - case CmpStmt::ICMP_SGT: - case CmpStmt::FCMP_OGT: - case CmpStmt::FCMP_UGT: - { - if (lhs.size() == 1 && rhs.size() == 1) - { - (*_es)[res] = *lhs.begin() > *rhs.begin(); - } - else - { - (*_es)[res] = SingleAbsValue::topConstant(); - } - return; - } - case CmpStmt::ICMP_UGE: - case CmpStmt::ICMP_SGE: - case CmpStmt::FCMP_OGE: - case CmpStmt::FCMP_UGE: - { - if (lhs.size() == 1 && rhs.size() == 1) - { - (*_es)[res] = *lhs.begin() >= *rhs.begin(); - } - else - { - (*_es)[res] = SingleAbsValue::topConstant(); - } - return; - } - case CmpStmt::ICMP_ULT: - case CmpStmt::ICMP_SLT: - case CmpStmt::FCMP_OLT: - case CmpStmt::FCMP_ULT: - { - if (lhs.size() == 1 && rhs.size() == 1) - { - (*_es)[res] = *lhs.begin() < *rhs.begin(); - } - else - { - (*_es)[res] = SingleAbsValue::topConstant(); - } - return; - } - case CmpStmt::ICMP_ULE: - case CmpStmt::ICMP_SLE: - case CmpStmt::FCMP_OLE: - case CmpStmt::FCMP_ULE: - { - if (lhs.size() == 1 && rhs.size() == 1) - { - (*_es)[res] = *lhs.begin() <= *rhs.begin(); - } - else - { - (*_es)[res] = SingleAbsValue::topConstant(); - } - return; - } - case CmpStmt::FCMP_FALSE: - (*_es)[res] = 0; - return; - case CmpStmt::FCMP_TRUE: - (*_es)[res] = 1; - return; - default: - { - assert(false && "undefined compare"); - } - } - } - else if (inVarToAddrsTable(op0)) - { - (*_es)[res] = SingleAbsValue::topConstant(); - } - else if (inVarToAddrsTable(op1)) - { - (*_es)[res] = SingleAbsValue::topConstant(); - } -} - -/*! - * https://llvm.org/docs/LangRef.html#load-instruction - * @param load - * @return - */ -void SVFIR2ConsExeState::translateLoad(const LoadStmt *load) -{ - u32_t rhs = load->getRHSVarID(); - u32_t lhs = load->getLHSVarID(); - if (inVarToAddrsTable(rhs)) - { - const Addrs &addrs = _es->getAddrs(rhs); - for (const auto &addr: addrs) - { - assert(isVirtualMemAddress(addr) && "not addr?"); - u32_t objId = getInternalID(addr); - if (load->getLHSVar()->getType() && load->getLHSVar()->getType()->isPointerTy()) - { - if (inLocToAddrsTable(objId)) - { - _es->getAddrs(lhs).setBottom(); - } - break; - } - else if (!load->getLHSVar()->getType() && inLocToAddrsTable(objId)) - { - _es->getAddrs(lhs).setBottom(); - break; - } - else if (inLocToValTable(objId)) - { - (*_es)[lhs] = SingleAbsValue::bottomConstant(); - break; - } - } - - for (const auto &addr: addrs) - { - assert(isVirtualMemAddress(addr) && "not addr?"); - u32_t objId = getInternalID(addr); - if (load->getLHSVar()->getType() && load->getLHSVar()->getType()->isPointerTy()) - { - if (inLocToAddrsTable(objId)) - { - if (!inVarToAddrsTable(lhs)) - { - _es->getAddrs(lhs) = _es->loadAddrs(addr); - } - else - { - _es->getAddrs(lhs).join_with(_es->loadAddrs(addr)); - } - } - } - else if (!load->getLHSVar()->getType() && inLocToAddrsTable(objId)) - { - if (!inVarToAddrsTable(lhs)) - { - _es->getAddrs(lhs) = _es->loadAddrs(addr); - } - else - { - _es->getAddrs(lhs).join_with(_es->loadAddrs(addr)); - } - } - else if (inLocToValTable(objId)) - { - if (!inVarToValTable(lhs)) - { - (*_es)[lhs] = _es->load(SingleAbsValue(getVirtualMemAddress(objId))); - } - else - { - (*_es)[lhs].join_with(_es->load(SingleAbsValue(getVirtualMemAddress(objId)))); - } - } - } - } -} - -/*! - * https://llvm.org/docs/LangRef.html#store-instruction - * @param store - * @return - */ -void SVFIR2ConsExeState::translateStore(const StoreStmt *store) -{ - u32_t rhs = store->getRHSVarID(); - u32_t lhs = store->getLHSVarID(); - if (inVarToAddrsTable(lhs)) - { - if (inVarToValTable(rhs)) - { - const Addrs &addrs = _es->getAddrs(lhs); - for (const auto &addr: addrs) - { - assert(isVirtualMemAddress(addr) && "not addr?"); - _es->store(SingleAbsValue(addr), (*_es)[rhs]); - } - } - else if (inVarToAddrsTable(rhs)) - { - const Addrs &addrs = _es->getAddrs(lhs); - for (const auto &addr: addrs) - { - assert(isVirtualMemAddress(addr) && "not addr?"); - _es->storeAddrs(addr, _es->getAddrs(rhs)); - } - } - } -} - -/*! - * https://llvm.org/docs/LangRef.html#conversion-operations - * @param copy - * @return - */ -void SVFIR2ConsExeState::translateCopy(const CopyStmt *copy) -{ - u32_t lhs = copy->getLHSVarID(); - u32_t rhs = copy->getRHSVarID(); - if (PAG::getPAG()->isBlkPtr(lhs)) - { - _es->globalConsES._varToVal[lhs] = SingleAbsValue::topConstant(); - } - else - { - if (inVarToValTable(rhs)) - { - (*_es)[lhs] = (*_es)[rhs]; - } - else if (inVarToAddrsTable(rhs)) - { - _es->getAddrs(lhs) = _es->getAddrs(rhs); - } - } -} - -/*! - * https://llvm.org/docs/LangRef.html#call-instruction - * @param callPE - * @return - */ -void SVFIR2ConsExeState::translateCall(const CallPE *callPE) -{ - NodeID lhs = callPE->getLHSVarID(); - NodeID rhs = callPE->getRHSVarID(); - if (inVarToValTable(rhs)) - { - (*_es)[lhs] = (*_es)[rhs]; - } - else if (inVarToAddrsTable(rhs)) - { - _es->getAddrs(lhs) = _es->getAddrs(rhs); - } -} - -void SVFIR2ConsExeState::translateRet(const RetPE *retPE) -{ - NodeID lhs = retPE->getLHSVarID(); - NodeID rhs = retPE->getRHSVarID(); - if (inVarToValTable(rhs)) - { - (*_es)[lhs] = (*_es)[rhs]; - } - else if (inVarToAddrsTable(rhs)) - { - _es->getAddrs(lhs) = _es->getAddrs(rhs); - } -} - -/*! - * https://llvm.org/docs/LangRef.html#getelementptr-instruction - * @param gep - * @return - */ -void SVFIR2ConsExeState::translateGep(const GepStmt *gep, bool isGlobal) -{ - u32_t rhs = gep->getRHSVarID(); - u32_t lhs = gep->getLHSVarID(); - // rhs is not initialized - if (!inVarToAddrsTable(rhs)) return; - const Addrs &rhsVal = _es->getAddrs(rhs); - if (rhsVal.empty()) return; - std::pair offset = getGepOffset(gep); - if (offset.first == -1 && offset.second == -1) return; - if (!isVirtualMemAddress(*rhsVal.begin())) - { - return; - } - Addrs gepAddrs; - s32_t ub = offset.second; - if (offset.second > (s32_t) Options::MaxFieldLimit() - 1) - { - ub = Options::MaxFieldLimit() - 1; - } - for (s32_t i = offset.first; i <= ub; i++) - { - gepAddrs.join_with(getGepObjAddress(rhs, i)); - } - if (gepAddrs.empty()) return; - _es->getAddrs(lhs) = gepAddrs; - return; -} - -/*! - * https://llvm.org/docs/LangRef.html#select-instruction - * @param select - * @return - */ -void SVFIR2ConsExeState::translateSelect(const SelectStmt *select) -{ - u32_t res = select->getResID(); - u32_t tval = select->getTrueValue()->getId(); - u32_t fval = select->getFalseValue()->getId(); - u32_t cond = select->getCondition()->getId(); - _es->applySelect(res, cond, tval, fval); -} - -/*! - * https://llvm.org/docs/LangRef.html#i-phi - * @param phi - * @return - */ -void SVFIR2ConsExeState::translatePhi(const PhiStmt *phi) -{ - u32_t res = phi->getResID(); - std::vector ops; - for (u32_t i = 0; i < phi->getOpVarNum(); i++) - { - ops.push_back(phi->getOpVarID(i)); - } - _es->applyPhi(res, ops); -} - -//%} -//%} - -/*! - * Return the expr of gep object given a base and offset - * @param base - * @param offset - * @return - */ -SVFIR2ConsExeState::Addrs SVFIR2ConsExeState::getGepObjAddress(u32_t base, s32_t offset) -{ - const Addrs &addrs = _es->getAddrs(base); - Addrs ret; - for (const auto &addr: addrs) - { - int64_t baseObj = getInternalID(addr); - if (baseObj == 0) - { - ret.insert(getVirtualMemAddress(0)); - continue; - } - assert(SVFUtil::isa(PAG::getPAG()->getGNode(baseObj)) && "Fail to get the base object address!"); - NodeID gepObj = PAG::getPAG()->getGepObjVar(baseObj, offset); - initSVFVar(gepObj); - if (offset == 0 && baseObj != gepObj) _es->getAddrs(gepObj) = _es->getAddrs(base); - ret.insert(getVirtualMemAddress(gepObj)); - } - return ret; -} - -/*! - * Return the offset expression of a GepStmt - * @param gep - * @return - */ -std::pair SVFIR2ConsExeState::getGepOffset(const SVF::GepStmt *gep) -{ - /// for instant constant index, e.g. gep arr, 1 - if (gep->getOffsetVarAndGepTypePairVec().empty()) - return std::make_pair(gep->getConstantStructFldIdx(), - gep->getConstantStructFldIdx()); - - s32_t totalOffset = 0; - /// default value of MaxFieldLimit is 512 - u32_t maxFieldLimit = Options::MaxFieldLimit() - 1; - /// for variable index and nested indexes, e.g. 1) gep arr, idx 2) gep arr idx0, idx1 - for (int i = gep->getOffsetVarAndGepTypePairVec().size() - 1; i >= 0; i--) - { - const SVFValue *value = - gep->getOffsetVarAndGepTypePairVec()[i].first->getValue(); - const SVFType *type = gep->getOffsetVarAndGepTypePairVec()[i].second; - const SVFConstantInt *op = SVFUtil::dyn_cast(value); - s32_t offset = 0; - /// offset is constant but stored in variable - if (op) - { - offset = op->getSExtValue(); - } - /// offset is variable, the concrete value isn't sure util runtime, and maybe not a concrete value. - /// e.g. - else - { - u32_t idx = PAG::getPAG()->getValueNode(value); - if (!inVarToValTable(idx)) return std::make_pair(-1, -1); - if ((*_es)[idx].isBottom() || (*_es)[idx].isTop() || (*_es)[idx].isSym()) - { - return std::make_pair(0, (s32_t) Options::MaxFieldLimit()); - } - - // if idxVal is a concrete value - offset = ConsExeState::z3Expr2NumValue((*_es)[idx]); - } - if (type == nullptr) - { - if ((long long) (totalOffset + offset) > maxFieldLimit) - { - totalOffset = maxFieldLimit; - } - else - { - totalOffset += offset; - } - continue; - } - - if (SVFUtil::isa(type)) - { - offset = offset * gep->getAccessPath().getElementNum(gep->getAccessPath().gepSrcPointeeType()); - } - else - { - const std::vector &so = SymbolTableInfo::SymbolInfo()->getTypeInfo( - type)->getFlattenedElemIdxVec(); - if (so.empty() || (u32_t) offset >= so.size()) - return std::make_pair(-1, -1); - offset = SymbolTableInfo::SymbolInfo()->getFlattenedElemIdx(type, offset); - } - if ((long long) (totalOffset + offset) > maxFieldLimit) - { - totalOffset = maxFieldLimit; - } - else - { - totalOffset += offset; - } - } - std::pair offSetPair; - offSetPair.first = totalOffset; - offSetPair.second = totalOffset; - return offSetPair; -} - - -/*! - * Init Z3Expr for ObjVar - * @param objVar - * @param valExprIdToCondValPairMap - */ -void SVFIR2ConsExeState::initObjVar(const ObjVar *objVar, u32_t varId) -{ - if (objVar->hasValue()) - { - const MemObj *obj = objVar->getMemObj(); - /// constant data - if (obj->isConstDataOrAggData() || obj->isConstantArray() || obj->isConstantStruct()) - { - if (const SVFConstantInt *consInt = SVFUtil::dyn_cast(obj->getValue())) - { - _es->globalConsES._varToVal[varId] = consInt->getSExtValue(); - } - else if (const SVFConstantFP *consFP = SVFUtil::dyn_cast(obj->getValue())) - _es->globalConsES._varToVal[varId] = consFP->getFPValue(); - else if (SVFUtil::isa(obj->getValue())) - _es->globalConsES._varToVal[varId] = 0; - else if (SVFUtil::isa(obj->getValue())) - _es->globalConsES._varToAddrs[varId] = getVirtualMemAddress(varId); - else if (obj->isConstDataOrAggData()) - { - // TODO - // assert(false && "implement this part"); - _es->globalConsES._varToVal[varId] = SingleAbsValue::topConstant(); - } - else - { - _es->globalConsES._varToVal[varId] = SingleAbsValue::topConstant(); - } - } - else - { - _es->globalConsES._varToAddrs[varId] = getVirtualMemAddress(varId); - } - } - else - { - _es->globalConsES._varToAddrs[varId] = getVirtualMemAddress(varId); - } -} - - -void SVFIR2ConsExeState::initSVFVar(u32_t varId) -{ - if (_es->inVarToValTable(varId)) return; - SVFIR *svfir = PAG::getPAG(); - SVFVar *svfVar = svfir->getGNode(varId); - // write objvar into cache instead of exestate - if (const ObjVar *objVar = dyn_cast(svfVar)) - { - initObjVar(objVar, varId); - return; - } - else - { - assert(false && "not an obj var?"); - } -} - -void SVFIR2ConsExeState::moveToGlobal() -{ - for (const auto &it: _es->_varToVal) - { - ConsExeState::globalConsES._varToVal.insert(it); - } - for (const auto &it: _es->_locToVal) - { - ConsExeState::globalConsES._locToVal.insert(it); - } - for (const auto &it: _es->_varToAddrs) - { - ConsExeState::globalConsES._varToAddrs.insert(it); - } - for (const auto &it: _es->_locToAddrs) - { - ConsExeState::globalConsES._locToAddrs.insert(it); - } - ConsExeState::globalConsES._varToAddrs[0] = ConsExeState::getVirtualMemAddress(0); - _es->_varToVal.clear(); - _es->_locToVal.clear(); - _es->_varToAddrs.clear(); - _es->_locToAddrs.clear(); -}