From a765d6c35e9a76432b15f0339e7df6f18ff6c993 Mon Sep 17 00:00:00 2001 From: bjjwwang Date: Tue, 2 Apr 2024 21:20:05 +1100 Subject: [PATCH 1/7] first commit of Abstract Value and its related changes --- svf/include/AE/Core/AbstractValue.h | 470 ++++++++++++++++++--- svf/include/AE/Core/AddressValue.h | 56 +-- svf/include/AE/Core/ExeState.h | 2 +- svf/include/AE/Core/IntervalExeState.h | 460 +++++++++++--------- svf/include/AE/Core/IntervalValue.h | 31 +- svf/include/AE/Svfexe/AbstractExecution.h | 13 +- svf/include/AE/Svfexe/BufOverflowChecker.h | 2 +- svf/include/AE/Svfexe/SVFIR2ItvExeState.h | 32 +- svf/lib/AE/Core/IntervalExeState.cpp | 203 +++++---- svf/lib/AE/Core/SVFIR2Relation.cpp | 11 +- svf/lib/AE/Svfexe/AbstractExecution.cpp | 121 +++--- svf/lib/AE/Svfexe/BufOverflowChecker.cpp | 69 +-- svf/lib/AE/Svfexe/SVFIR2ConsExeState.cpp | 4 +- svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp | 394 ++++++++--------- 14 files changed, 1113 insertions(+), 755 deletions(-) diff --git a/svf/include/AE/Core/AbstractValue.h b/svf/include/AE/Core/AbstractValue.h index fbee21c4e..e2d09cde1 100644 --- a/svf/include/AE/Core/AbstractValue.h +++ b/svf/include/AE/Core/AbstractValue.h @@ -1,78 +1,424 @@ -//===- AbstractValue.h --Abstract Value for domains---------------------------// -// -// 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 . -// -//===----------------------------------------------------------------------===// -/* - * AbstractValue.h - * - * Created on: Aug 4, 2022 - * Author: Xiao Cheng, Jiawei Wang - * - */ - -#ifndef Z3_EXAMPLE_ABSTRACTVALUE_H -#define Z3_EXAMPLE_ABSTRACTVALUE_H - -#include -#include +#include "AE/Core/IntervalValue.h" +#include "AE/Core/AddressValue.h" namespace SVF { +typedef AddressValue Addrs; -class IntervalValue; - -/*! - * Base class of abstract value - */ -class AbstractValue -{ -public: - /// Abstract value kind - enum AbstractValueK - { - IntervalK, ConcreteK, AddressK +struct AbstractValue { + enum DataType { + IntervalType, //IntervalType + AddressType, // AddressType + UnknownType, //UnknownType }; -private: - AbstractValueK _kind; + DataType type; + IntervalValue interval; + AddressValue addr; -public: - AbstractValue(AbstractValueK kind) : _kind(kind) {} + //AbstractValue() : type(Null) {} + AbstractValue() : type(IntervalType) { interval = IntervalValue::top(); } + AbstractValue(DataType type) : type(type) { + switch (type) { + case IntervalType: + interval = IntervalValue::top(); + break; + case AddressType: + addr = AddressValue(); + break; + case UnknownType: + break; + } + } - virtual ~AbstractValue() = default; + AbstractValue(const AbstractValue& other): type(other.type) { + switch (type) { + case IntervalType: + interval = other.interval; + break; + case AddressType: + addr = other.addr; + break; + case UnknownType: + break; + } + } - AbstractValue(const AbstractValue &) noexcept = default; + inline bool isInterval() const { return type == IntervalType; } + inline bool isAddr() const { return type == AddressType; } + inline bool isUnknown() const { return type == UnknownType; } + // isUnknownType() - AbstractValue(AbstractValue &&) noexcept = default; + inline DataType getType() const { return type; } - AbstractValue &operator=(const AbstractValue &) noexcept = default; + AbstractValue(AbstractValue &&other) : type(other.type) { + switch (type) { + case IntervalType: + interval = other.interval; + break; + case AddressType: + addr = other.addr; + break; + case UnknownType: + break; + } + } - AbstractValue &operator=(AbstractValue &&) noexcept = default; + AbstractValue& operator=(const AbstractValue& other) { + type = other.type; + switch (type) + { + case IntervalType: + interval = other.interval; + break; + case AddressType: + addr = other.addr; + break; + case UnknownType: + break; + } + return *this; + } + AbstractValue operator==(const AbstractValue& other) const + { + assert(isInterval() && other.isInterval()); + return interval == other.interval; + } + + AbstractValue operator==(const IntervalValue& other) const { + assert(isInterval()); + return interval == other; + } - inline AbstractValueK getAbstractValueKind() const + AbstractValue operator!=(const AbstractValue& other) const { - return _kind; + assert(isInterval()); + return interval != other.interval; + } + + AbstractValue operator!=(const IntervalValue& other) const { + assert(isInterval()); + return interval != other; + } + + + AbstractValue(const IntervalValue& ival) : type(IntervalType), interval(ival) {} + + AbstractValue(const AddressValue& addr) : type(AddressType), addr(addr) {} + // TODO: move constructor + IntervalValue& getInterval() { + if (isUnknown()) { + interval = IntervalValue::top(); + } + assert(isInterval()); + return interval; + } + + const IntervalValue getInterval() const { assert(isInterval()); return interval; } + + AddressValue& getAddrs() { assert(isAddr()); return addr; } + + const AddressValue getAddrs() const { assert(isAddr()); return addr; } + ~AbstractValue() {}; + + + // interval visit funcs + bool isTop() const { + assert(isInterval()); + return interval.isTop(); + } + + bool isBottom() const { + assert(isInterval()); + return interval.isBottom(); + } + + const NumericLiteral& lb() const { + assert(isInterval()); + return interval.lb(); + } + + const NumericLiteral& ub() const { + assert(isInterval()); + return interval.ub(); } - virtual bool isTop() const = 0; + void setLb(const NumericLiteral& lb) { + assert(isInterval()); + interval.setLb(lb); + } + + void setUb(const NumericLiteral& ub) { + assert(isInterval()); + interval.setUb(ub); + } + + void setValue(const NumericLiteral &lb, const NumericLiteral &ub) { + assert(isInterval()); + interval.setValue(lb, ub); + } + + bool is_zero() const { + assert(isInterval()); + return interval.is_zero(); + } + + bool is_infinite() const { + assert(isInterval()); + return interval.is_infinite(); + } + + bool is_int() const { + assert(isInterval()); + return interval.is_int(); + } + + bool is_real() const { + assert(isInterval()); + return interval.is_real(); + } + + s64_t getIntNumeral() const { + assert(isInterval()); + return interval.getIntNumeral(); + } + + double getRealNumeral() const { + assert(isInterval()); + return interval.getRealNumeral(); + } + + bool is_numeral() const { + assert(isInterval()); + return interval.is_numeral(); + } + + void set_to_bottom() { + assert(isInterval()); + interval.set_to_bottom(); + } + + void set_to_top() { + assert(isInterval()); + interval.set_to_top(); + } + + bool leq(const AbstractValue &other) const { + assert(isInterval() && other.isInterval()); + return interval.leq(other.interval); + } + + bool geq(const AbstractValue &other) const { + assert(isInterval() && other.isInterval()); + return interval.geq(other.interval); + } + + bool contains(s64_t n) const { + assert(isInterval()); + return interval.contains(n); + } + // operator +-*/%>< >= <= << >> & | ^ + AbstractValue operator+(const AbstractValue &other) const { + assert(isInterval() && other.isInterval()); + return interval + other.interval; + } + AbstractValue operator+(const IntervalValue &other) const { + assert(isInterval()); + return interval + other; + } + + AbstractValue operator-(const AbstractValue &other) const { + assert(isInterval() && other.isInterval()); + return interval - other.interval; + } + AbstractValue operator-(const IntervalValue &other) const { + assert(isInterval()); + return interval - other; + } + + AbstractValue operator*(const AbstractValue &other) const { + assert(isInterval() && other.isInterval()); + return interval * other.interval; + } + AbstractValue operator*(const IntervalValue &other) const { + assert(isInterval()); + return interval * other; + } + + AbstractValue operator/(const AbstractValue &other) const { + assert(isInterval() && other.isInterval()); + return interval / other.interval; + } + AbstractValue operator/(const IntervalValue &other) const { + assert(isInterval()); + return interval / other; + } + + AbstractValue operator%(const AbstractValue &other) const { + assert(isInterval() && other.isInterval()); + return interval % other.interval; + } + AbstractValue operator%(const IntervalValue &other) const { + assert(isInterval()); + return interval % other; + } + + AbstractValue operator>>(const AbstractValue &other) const { + assert(isInterval() && other.isInterval()); + return interval >> other.interval; + } + AbstractValue operator>>(const IntervalValue &other) const { + assert(isInterval()); + return interval >> other; + } + + AbstractValue operator<<(const AbstractValue &other) const { + assert(isInterval() && other.isInterval()); + return interval << other.interval; + } + AbstractValue operator<<(const IntervalValue &other) const { + assert(isInterval()); + return interval << other; + } + + AbstractValue operator&(const AbstractValue &other) const { + assert(isInterval() && other.isInterval()); + return interval & other.interval; + } + AbstractValue operator&(const IntervalValue &other) const { + assert(isInterval()); + return interval & other; + } + + AbstractValue operator|(const AbstractValue &other) const { + assert(isInterval() && other.isInterval()); + return interval | other.interval; + } + AbstractValue operator|(const IntervalValue &other) const { + assert(isInterval()); + return interval | other; + } + + AbstractValue operator^(const AbstractValue &other) const { + assert(isInterval() && other.isInterval()); + return interval ^ other.interval; + } + AbstractValue operator^(const IntervalValue &other) const { + assert(isInterval()); + return interval ^ other; + } + + AbstractValue operator>(const AbstractValue &other) const { + assert(isInterval() && other.isInterval()); + return interval > other.interval; + } + AbstractValue operator>(const IntervalValue &other) const { + assert(isInterval()); + return interval > other; + } + + AbstractValue operator<(const AbstractValue &other) const { + assert(isInterval() && other.isInterval()); + return interval < other.interval; + } + AbstractValue operator<(const IntervalValue &other) const { + assert(isInterval()); + return interval < other; + } + + AbstractValue operator>=(const AbstractValue &other) const { + assert(isInterval() && other.isInterval()); + return interval >= other.interval; + } + AbstractValue operator>=(const IntervalValue &other) const { + assert(isInterval()); + return interval >= other; + } + + AbstractValue operator<=(const AbstractValue &other) const { + assert(isInterval() && other.isInterval()); + return interval <= other.interval; + } + AbstractValue operator<=(const IntervalValue &other) const { + assert(isInterval()); + return interval <= other; + } + + + // address visit funcs + std::pair insertAddr(u32_t id) { // insertAddr + assert(isAddr()); + return addr.insert(id); + } + + // TODO: equals, join_with, meet_with, widen_with, narrow_with, toString, + // These should be merged with AddressValue + + bool equals(const AbstractValue &rhs) const { + if (type != rhs.type) { + return false; + } + if (isInterval()) { + return interval.equals(rhs.interval); + } + if (isAddr()) { + return addr.equals(rhs.addr); + } + return false; + } + + void join_with(const AbstractValue &other) { + if (isUnknown()) { + *this = other; + return; + } + else if (type != other.type) { + return; + } + if (isInterval() && other.isInterval()) { + interval.join_with(other.interval); + } + if (isAddr() && other.isAddr()) { + addr.join_with(other.addr); + } + return; + } + + void meet_with(const AbstractValue &other) { + if (type != other.type) { + return; + } + if (isInterval() && other.isInterval()) { + interval.meet_with(other.interval); + } + if (isAddr() && other.isAddr()) { + addr.meet_with(other.addr); + } + return; + } + + void widen_with(const AbstractValue &other) { + // widen_with only in interval + if (isInterval() && other.isInterval()) { + interval.widen_with(other.interval); + } + } + + void narrow_with(const AbstractValue &other) { + // narrow_with only in interval + if (isInterval() && other.isInterval()) { + interval.narrow_with(other.interval); + } + } + + std::string toString() const { + if (isInterval()) { + return interval.toString(); + } + else if (isAddr()) { + //TODO: write addr to string + } + return ""; + } - virtual bool isBottom() const = 0; -}; // end class AbstractValue -} // end namespace SVF -#endif //Z3_EXAMPLE_ABSTRACTVALUE_H +}; +} \ No newline at end of file diff --git a/svf/include/AE/Core/AddressValue.h b/svf/include/AE/Core/AddressValue.h index 6fa6e2924..1b46526f1 100644 --- a/svf/include/AE/Core/AddressValue.h +++ b/svf/include/AE/Core/AddressValue.h @@ -33,14 +33,14 @@ #define AddressMask 0x7f000000 #define FlippedAddressMask (AddressMask^0xffffffff) // the address of the black hole, getVirtualMemAddress(2); -#define BlackHoleAddr 0x7f000000 + 2; +#define BlackHoleAddr 0x7f000000 + 2 -#include "AE/Core/AbstractValue.h" #include "Util/GeneralType.h" +#include namespace SVF { -class AddressValue : public AbstractValue +class AddressValue { public: typedef Set AddrSet; @@ -48,21 +48,21 @@ class AddressValue : public AbstractValue AddrSet _addrs; public: /// Default constructor - AddressValue() : AbstractValue(AddressK) {} + AddressValue() {} /// Constructor - AddressValue(const Set &addrs) : AbstractValue(AddressK), _addrs(addrs) {} + AddressValue(const Set &addrs) : _addrs(addrs) {} - AddressValue(u32_t addr) : AbstractValue(AddressK), _addrs({addr}) {} + AddressValue(u32_t addr) : _addrs({addr}) {} /// Default destructor ~AddressValue() = default; /// Copy constructor - AddressValue(const AddressValue &other) : AbstractValue(AddressK), _addrs(other._addrs) {} + AddressValue(const AddressValue &other) : _addrs(other._addrs) {} /// Move constructor - AddressValue(AddressValue &&other) noexcept: AbstractValue(AddressK), _addrs(std::move(other._addrs)) {} + AddressValue(AddressValue &&other) noexcept: _addrs(std::move(other._addrs)) {} /// Copy operator= AddressValue &operator=(const AddressValue &other) @@ -70,7 +70,6 @@ class AddressValue : public AbstractValue if (!this->equals(other)) { _addrs = other._addrs; - AbstractValue::operator=(other); } return *this; } @@ -81,7 +80,6 @@ class AddressValue : public AbstractValue if (this != &other) { _addrs = std::move(other._addrs); - AbstractValue::operator=(std::move(other)); } return *this; } @@ -91,17 +89,6 @@ class AddressValue : public AbstractValue return _addrs == rhs._addrs; } - bool operator==(const AddressValue &rhs) const - { - return _addrs == rhs._addrs; - } - - /// Operator != - bool operator!=(const AddressValue &rhs) const - { - return _addrs != rhs._addrs; - } - AddrSet::const_iterator begin() const { return _addrs.cbegin(); @@ -181,19 +168,19 @@ class AddressValue : public AbstractValue return !v.empty(); } - inline bool isTop() const override + inline bool isTop() const { - return *this == BlackHoleAddr; + return *this->begin() == BlackHoleAddr; } - inline bool isBottom() const override + inline bool isBottom() const { return empty(); } inline void setTop() { - *this = BlackHoleAddr; + *this = AddressValue(BlackHoleAddr); } inline void setBottom() @@ -201,6 +188,25 @@ class AddressValue : public AbstractValue _addrs.clear(); } + const std::string toString() const + { + std::string str; + std::stringstream rawStr(str); + if (this->isBottom()) + { + rawStr << "⊥"; + } + else + { + rawStr << "["; + for (auto it = _addrs.begin(), eit = _addrs.end(); it!= eit; ++it) { + rawStr << *it << ", "; + } + rawStr << "]"; + } + return rawStr.str(); + } + /// The physical address starts with 0x7f...... + idx static inline u32_t getVirtualMemAddress(u32_t idx) { diff --git a/svf/include/AE/Core/ExeState.h b/svf/include/AE/Core/ExeState.h index accd1b891..c42dd2782 100644 --- a/svf/include/AE/Core/ExeState.h +++ b/svf/include/AE/Core/ExeState.h @@ -196,7 +196,7 @@ class ExeState auto it = rhs.find(item.first); if (it == rhs.end()) return false; - if (item.second != it->second) + if (item.second.equals(it->second)) { return false; } diff --git a/svf/include/AE/Core/IntervalExeState.h b/svf/include/AE/Core/IntervalExeState.h index affc0489b..a63186c1f 100644 --- a/svf/include/AE/Core/IntervalExeState.h +++ b/svf/include/AE/Core/IntervalExeState.h @@ -45,32 +45,32 @@ #include "AE/Core/ExeState.h" #include "AE/Core/IntervalValue.h" +#include "AE/Core/AbstractValue.h" #include "Util/Z3Expr.h" #include namespace SVF { -class IntervalESBase: public ExeState +class IntervalESBase { friend class SVFIR2ItvExeState; friend class RelationSolver; public: - typedef Map VarToValMap; + typedef Map VarToAbsValMap; - typedef VarToValMap LocToValMap; + typedef VarToAbsValMap LocToAbsValMap; public: /// default constructor - IntervalESBase() : ExeState(ExeState::IntervalK) {} + IntervalESBase() {} - IntervalESBase(VarToValMap &_varToValMap, LocToValMap &_locToValMap) : ExeState(ExeState::IntervalK), - _varToItvVal(_varToValMap), - _locToItvVal(_locToValMap) {} + IntervalESBase(VarToAbsValMap&_varToValMap, LocToAbsValMap&_locToValMap) : _varToAbsVal(_varToValMap), + _locToAbsVal(_locToValMap) {} /// copy constructor - IntervalESBase(const IntervalESBase &rhs) : ExeState(rhs), _varToItvVal(rhs.getVarToVal()), - _locToItvVal(rhs.getLocToVal()) + IntervalESBase(const IntervalESBase &rhs) : _varToAbsVal(rhs.getVarToVal()), + _locToAbsVal(rhs.getLocToVal()) { } @@ -78,21 +78,43 @@ class IntervalESBase: public ExeState virtual ~IntervalESBase() = default; + /// 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); + } + + static inline bool isNullPtr(u32_t addr) + { + return getInternalID(addr) == 0; + } + + IntervalESBase &operator=(const IntervalESBase &rhs) { if (rhs != *this) { - _varToItvVal = rhs._varToItvVal; - _locToItvVal = rhs._locToItvVal; - ExeState::operator=(rhs); + _varToAbsVal = rhs._varToAbsVal; + _locToAbsVal = rhs._locToAbsVal; } return *this; } /// move constructor - IntervalESBase(IntervalESBase &&rhs) : ExeState(std::move(rhs)), - _varToItvVal(std::move(rhs._varToItvVal)), - _locToItvVal(std::move(rhs._locToItvVal)) + IntervalESBase(IntervalESBase &&rhs) : _varToAbsVal(std::move(rhs._varToAbsVal)), + _locToAbsVal(std::move(rhs._locToAbsVal)) { } @@ -102,9 +124,8 @@ class IntervalESBase: public ExeState { if (&rhs != this) { - _varToItvVal = std::move(rhs._varToItvVal); - _locToItvVal = std::move(rhs._locToItvVal); - ExeState::operator=(std::move(rhs)); + _varToAbsVal = std::move(rhs._varToAbsVal); + _locToAbsVal = std::move(rhs._locToAbsVal); } return *this; } @@ -113,9 +134,10 @@ class IntervalESBase: public ExeState IntervalESBase bottom() const { IntervalESBase inv = *this; - for (auto &item: inv._varToItvVal) + for (auto &item: inv._varToAbsVal) { - item.second.set_to_bottom(); + if (item.second.isInterval()) + item.second.getInterval().set_to_bottom(); } return inv; } @@ -124,9 +146,10 @@ class IntervalESBase: public ExeState IntervalESBase top() const { IntervalESBase inv = *this; - for (auto &item: inv._varToItvVal) + for (auto &item: inv._varToAbsVal) { - item.second.set_to_top(); + if (item.second.isInterval()) + item.second.getInterval().set_to_bottom(); } return inv; } @@ -137,64 +160,78 @@ class IntervalESBase: public ExeState IntervalESBase inv; for (u32_t id: sl) { - inv._varToItvVal[id] = _varToItvVal[id]; + inv._varToAbsVal[id] = _varToAbsVal[id]; } return inv; } protected: - - VarToValMap _varToItvVal; ///< Map a variable (symbol) to its interval value - LocToValMap _locToItvVal; ///< Map a memory address to its stored interval value + VarToAbsValMap _varToAbsVal; ///< Map a variable (symbol) to its interval value + LocToAbsValMap _locToAbsVal; ///< Map a memory address to its stored interval value public: - /// get memory addresses of variable - Addrs &getAddrs(u32_t id) override - { - return _varToAddrs[id]; - } /// get interval value of variable - inline virtual IntervalValue &operator[](u32_t varId) + inline virtual AbstractValue &operator[](u32_t varId) { - return _varToItvVal[varId]; + return _varToAbsVal[varId]; } /// whether the variable is in varToAddrs table - inline bool inVarToAddrsTable(u32_t id) const override + inline bool inVarToAddrsTable(u32_t id) const { - return _varToAddrs.find(id) != _varToAddrs.end(); + if (_varToAbsVal.find(id)!= _varToAbsVal.end()) { + if (_varToAbsVal.at(id).isAddr()) { + return true; + } + } + return false; } /// whether the variable is in varToVal table inline virtual bool inVarToValTable(u32_t id) const { - return _varToItvVal.find(id) != _varToItvVal.end(); + if (_varToAbsVal.find(id) != _varToAbsVal.end()) { + if (_varToAbsVal.at(id).isInterval()) { + return true; + } + } + return false; } /// whether the memory address stores memory addresses - inline bool inLocToAddrsTable(u32_t id) const override + inline bool inLocToAddrsTable(u32_t id) const { - return _locToAddrs.find(id) != _locToAddrs.end(); + if (_locToAbsVal.find(id)!= _locToAbsVal.end()) { + if (_locToAbsVal.at(id).isAddr()) { + return true; + } + } + return false; } /// whether the memory address stores interval value inline virtual bool inLocToValTable(u32_t id) const { - return _locToItvVal.find(id) != _locToItvVal.end(); + if (_locToAbsVal.find(id) != _locToAbsVal.end()) { + if (_locToAbsVal.at(id).isInterval()) { + return true; + } + } + return false; } /// get var2val map - const VarToValMap &getVarToVal() const + const VarToAbsValMap&getVarToVal() const { - return _varToItvVal; + return _varToAbsVal; } /// get loc2val map - const LocToValMap &getLocToVal() const + const LocToAbsValMap&getLocToVal() const { - return _locToItvVal; + return _locToAbsVal; } public: @@ -228,100 +265,73 @@ class IntervalESBase: public ExeState ///TODO: Create new interval value IntervalValue createIntervalValue(double lb, double ub, NodeID id) { - _varToItvVal[id] = IntervalValue(lb, ub); - return _varToItvVal[id]; + _varToAbsVal[id] = IntervalValue(lb, ub); + return _varToAbsVal[id].getInterval(); } /// Return true if map has bottom value inline bool has_bottom() { - for (auto it = _varToItvVal.begin(); it != _varToItvVal.end(); ++it) + for (auto it = _varToAbsVal.begin(); it != _varToAbsVal.end(); ++it) { - if (it->second.isBottom()) + if (it->second.isInterval()) { - return true; + if (it->second.getInterval().isBottom()) + { + return true; + } } } - for (auto it = _locToItvVal.begin(); it != _locToItvVal.end(); ++it) + for (auto it = _locToAbsVal.begin(); it != _locToAbsVal.end(); ++it) { - if (it->second.isBottom()) + if (it->second.isInterval()) { - return true; + if (it->second.getInterval().isBottom()) + { + return true; + } } } return false; } - u32_t hash() const override; + u32_t hash() const; public: - inline void store(u32_t addr, const IntervalValue &val) + inline void store(u32_t addr, const AbstractValue &val) { assert(isVirtualMemAddress(addr) && "not virtual address?"); if (isNullPtr(addr)) return; u32_t objId = getInternalID(addr); - _locToItvVal[objId] = val; - } - - inline virtual IntervalValue &load(u32_t addr) - { - assert(isVirtualMemAddress(addr) && "not virtual address?"); - u32_t objId = getInternalID(addr); - auto it = _locToItvVal.find(objId); - if(it != _locToItvVal.end()) - return it->second; - else - { - return _locToItvVal[objId]; - } + _locToAbsVal[objId] = val; } - inline virtual Addrs &loadAddrs(u32_t addr) override + inline virtual AbstractValue &load(u32_t addr) { assert(isVirtualMemAddress(addr) && "not virtual address?"); u32_t objId = getInternalID(addr); - auto it = _locToAddrs.find(objId); - if(it != _locToAddrs.end()) - return it->second; - else - { - return _locToAddrs[objId]; - } - } - - inline virtual IntervalValue& getLocVal(u32_t id) - { - auto it = _locToItvVal.find(id); - if(it != _locToItvVal.end()) + auto it = _locToAbsVal.find(objId); + if(it != _locToAbsVal.end()) return it->second; else { - return _locToItvVal[id]; + _locToAbsVal[objId] = IntervalValue::top(); + return _locToAbsVal[objId]; } } - inline virtual Addrs& getLocAddrs(u32_t id) - { - auto it = _locToAddrs.find(id); - if(it != _locToAddrs.end()) - return it->second; - else - { - return _locToAddrs[id]; - } - } /// Print values of all expressions - void printExprValues(std::ostream &oss) const override; + void printExprValues(std::ostream &oss) const; - std::string toString() const override + std::string toString() const { return ""; } bool equals(const IntervalESBase &other) const; - static bool eqVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs) + static bool eqVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs) { if (lhs.size() != rhs.size()) return false; for (const auto &item: lhs) @@ -329,7 +339,23 @@ class IntervalESBase: public ExeState auto it = rhs.find(item.first); if (it == rhs.end()) return false; - if (!item.second.equals(it->second)) + if (item.second.getType() == it->second.getType()) { + if (item.second.isInterval()) + { + if (!item.second.getInterval().equals(it->second.getInterval())) + { + return false; + } + } + else if (item.second.isAddr()) + { + if (!item.second.getAddrs().equals(it->second.getAddrs())) + { + return false; + } + } + } + else { return false; } @@ -338,7 +364,7 @@ class IntervalESBase: public ExeState } - static bool lessThanVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs) + static bool lessThanVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs) { if (lhs.empty()) return !rhs.empty(); for (const auto &item: lhs) @@ -346,13 +372,13 @@ class IntervalESBase: public ExeState auto it = rhs.find(item.first); if (it == rhs.end()) return false; // judge from expr id - if (item.second.geq(it->second)) return false; + if (item.second.getInterval().geq(it->second.getInterval())) return false; } return true; } // lhs >= rhs - static bool geqVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs) + static bool geqVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs) { if (rhs.empty()) return true; for (const auto &item: rhs) @@ -360,17 +386,19 @@ class IntervalESBase: public ExeState auto it = lhs.find(item.first); if (it == lhs.end()) return false; // judge from expr id - if (!it->second.geq(item.second)) return false; + if (it->second.isInterval() && item.second.isInterval()) { + if (!it->second.getInterval().geq(item.second.getInterval())) + return false; + } + } return true; } - using ExeState::operator==; - using ExeState::operator!=; bool operator==(const IntervalESBase &rhs) const { - return ExeState::operator==(rhs) && eqVarToValMap(_varToItvVal, rhs.getVarToVal()) && - eqVarToValMap(_locToItvVal, rhs.getLocToVal()); + return eqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && + eqVarToValMap(_locToAbsVal, rhs.getLocToVal()); } bool operator!=(const IntervalESBase &rhs) const @@ -386,22 +414,19 @@ class IntervalESBase: public ExeState bool operator>=(const IntervalESBase &rhs) const { - return geqVarToValMap(_varToItvVal, rhs.getVarToVal()) && geqVarToValMap(_locToItvVal, rhs.getLocToVal()); + return geqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && geqVarToValMap(_locToAbsVal, rhs.getLocToVal()); } void clear() { - _locToItvVal.clear(); - _varToItvVal.clear(); - _locToAddrs.clear(); - _varToAddrs.clear(); + _locToAbsVal.clear(); + _varToAbsVal.clear(); } protected: - void printTable(const VarToValMap &table, std::ostream &oss) const; + void printTable(const VarToAbsValMap&table, std::ostream &oss) const; - void printTable(const VarToAddrs &table, std::ostream &oss) const; }; class IntervalExeState : public IntervalESBase @@ -416,7 +441,7 @@ class IntervalExeState : public IntervalESBase /// default constructor IntervalExeState() : IntervalESBase() {} - IntervalExeState(VarToValMap &_varToValMap, LocToValMap &_locToValMap) : IntervalESBase(_varToValMap, _locToValMap) {} + IntervalExeState(VarToAbsValMap&_varToValMap, LocToAbsValMap&_locToValMap) : IntervalESBase(_varToValMap, _locToValMap) {} /// copy constructor IntervalExeState(const IntervalExeState &rhs) : IntervalESBase(rhs) @@ -433,7 +458,7 @@ class IntervalExeState : public IntervalESBase return *this; } - virtual void printExprValues(std::ostream &oss) const override; + virtual void printExprValues(std::ostream &oss) const; /// move constructor IntervalExeState(IntervalExeState &&rhs) : IntervalESBase(std::move(rhs)) @@ -451,76 +476,155 @@ class IntervalExeState : public IntervalESBase public: /// get memory addresses of variable - Addrs &getAddrs(u32_t id) override - { - auto it = _varToAddrs.find(id); - if (it != _varToAddrs.end()) - return it->second; - else - return globalES._varToAddrs[id]; + AbstractValue &getAddrs(u32_t id) + { + if (_varToAbsVal.find(id)!= _varToAbsVal.end()) { + return _varToAbsVal[id]; + } else if (globalES._varToAbsVal.find(id)!= globalES._varToAbsVal.end()) { + return globalES._varToAbsVal[id]; + } else { + globalES._varToAbsVal[id] = AddressValue(); + return globalES._varToAbsVal[id]; + } } /// get interval value of variable - inline IntervalValue &operator[](u32_t varId) override + inline AbstractValue &operator[](u32_t varId) { - auto localIt = _varToItvVal.find(varId); - if(localIt != _varToItvVal.end()) + auto localIt = _varToAbsVal.find(varId); + if(localIt != _varToAbsVal.end()) return localIt->second; else { - return globalES._varToItvVal[varId]; + return globalES._varToAbsVal[varId]; } } /// whether the variable is in varToAddrs table - inline bool inVarToAddrsTable(u32_t id) const override + inline bool inVarToAddrsTable(u32_t id) const { - return _varToAddrs.find(id) != _varToAddrs.end() || - globalES._varToAddrs.find(id) != globalES._varToAddrs.end(); + if (_varToAbsVal.find(id)!= _varToAbsVal.end()) { + if (_varToAbsVal.at(id).isAddr()) { + return true; + } + else { + return false; + } + } + else if (globalES._varToAbsVal.find(id)!= globalES._varToAbsVal.end()) { + if (globalES._varToAbsVal[id].isAddr()) { + return true; + } + else { + return false; + } + } + else { + return false; + } } /// whether the variable is in varToVal table - inline bool inVarToValTable(u32_t id) const override + inline bool inVarToValTable(u32_t id) const { - return _varToItvVal.find(id) != _varToItvVal.end() || - globalES._varToItvVal.find(id) != globalES._varToItvVal.end(); + if (_varToAbsVal.find(id)!= _varToAbsVal.end()) { + if (_varToAbsVal.at(id).isInterval()) { + return true; + } + else { + return false; + } + } + else if (globalES._varToAbsVal.find(id)!= globalES._varToAbsVal.end()) { + if (globalES._varToAbsVal[id].isInterval()) { + return true; + } + else { + return false; + } + } + else { + return false; + } } /// whether the memory address stores memory addresses - inline bool inLocToAddrsTable(u32_t id) const override + inline bool inLocToAddrsTable(u32_t id) const { - return _locToAddrs.find(id) != _locToAddrs.end() || - globalES._locToAddrs.find(id) != globalES._locToAddrs.end(); + if (_locToAbsVal.find(id)!= _locToAbsVal.end()) { + if (_locToAbsVal.at(id).isAddr()) { + return true; + } + else { + return false; + } + } + else if (globalES._locToAbsVal.find(id)!= globalES._locToAbsVal.end()) { + if (globalES._locToAbsVal[id].isAddr()) { + return true; + } + else { + return false; + } + } + else { + return false; + } } /// whether the memory address stores interval value - inline bool inLocToValTable(u32_t id) const override + inline bool inLocToValTable(u32_t id) const { - return _locToItvVal.find(id) != _locToItvVal.end() || - globalES._locToItvVal.find(id) != globalES._locToItvVal.end(); + if (_locToAbsVal.find(id)!= _locToAbsVal.end()) { + if (_locToAbsVal.at(id).isInterval()) { + return true; + } + else { + return false; + } + } + else if (globalES._locToAbsVal.find(id)!= globalES._locToAbsVal.end()) { + if (globalES._locToAbsVal[id].isInterval()) { + return true; + } + else { + return false; + } + } + else { + return false; + } } inline bool inLocalLocToValTable(u32_t id) const { - return _locToItvVal.find(id) != _locToItvVal.end(); + if (_locToAbsVal.find(id)!= _locToAbsVal.end()) { + return _locToAbsVal.at(id).isInterval(); + } + else + return false; } inline bool inLocalLocToAddrsTable(u32_t id) const { - return _locToAddrs.find(id) != _locToAddrs.end(); + if (_locToAbsVal.find(id)!= _locToAbsVal.end()) { + return _locToAbsVal.at(id).isAddr(); + } + else + return false; } public: inline void cpyItvToLocal(u32_t varId) { - auto localIt = _varToItvVal.find(varId); + auto localIt = _varToAbsVal.find(varId); // local already have varId - if (localIt != _varToItvVal.end()) return; - auto globIt = globalES._varToItvVal.find(varId); - if (globIt != globalES._varToItvVal.end()) + if (localIt != _varToAbsVal.end()) return; + auto globIt = globalES._varToAbsVal.find(varId); + if (globIt != globalES._varToAbsVal.end()) { - _varToItvVal[varId] = globIt->second; + _varToAbsVal[varId] = globIt->second; } } @@ -542,82 +646,36 @@ class IntervalExeState : public IntervalESBase /// domain meet with other, important! other widen this. void meetWith(const IntervalExeState &other); - u32_t hash() const override; + u32_t hash() const; public: - inline IntervalValue &load(u32_t addr) override - { - assert(isVirtualMemAddress(addr) && "not virtual address?"); - u32_t objId = getInternalID(addr); - auto it = _locToItvVal.find(objId); - if(it != _locToItvVal.end()) - return it->second; - else - { - auto globIt = globalES._locToItvVal.find(objId); - if(globIt != globalES._locToItvVal.end()) - return globIt->second; - else - return _locToItvVal[objId]; - } - } - - inline Addrs &loadAddrs(u32_t addr) override + inline AbstractValue &load(u32_t addr) { assert(isVirtualMemAddress(addr) && "not virtual address?"); u32_t objId = getInternalID(addr); - auto it = _locToAddrs.find(objId); - if(it != _locToAddrs.end()) + auto it = _locToAbsVal.find(objId); + if(it != _locToAbsVal.end()) return it->second; else { - auto globIt = globalES._locToAddrs.find(objId); - if(globIt != globalES._locToAddrs.end()) + auto globIt = globalES._locToAbsVal.find(objId); + if(globIt != globalES._locToAbsVal.end()) return globIt->second; else - return _locToAddrs[objId]; - } - } - - inline IntervalValue& getLocVal(u32_t id) override - { - auto it = _locToItvVal.find(id); - if(it != _locToItvVal.end()) - return it->second; - else - { - auto globIt = globalES._locToItvVal.find(id); - if(globIt != globalES._locToItvVal.end()) - return globIt->second; - else - return _locToItvVal[id]; - } - } + { + return globalES._locToAbsVal[objId]; + } - inline Addrs& getLocAddrs(u32_t id) override - { - auto it = _locToAddrs.find(id); - if(it != _locToAddrs.end()) - return it->second; - else - { - auto globIt = globalES._locToAddrs.find(id); - if(globIt != globalES._locToAddrs.end()) - return globIt->second; - else - return _locToAddrs[id]; } } bool equals(const IntervalExeState &other) const; - using ExeState::operator==; - using ExeState::operator!=; bool operator==(const IntervalExeState &rhs) const { - return ExeState::operator==(rhs) && eqVarToValMap(_varToItvVal, rhs._varToItvVal) && - eqVarToValMap(_locToItvVal, rhs._locToItvVal); + return eqVarToValMap(_varToAbsVal, rhs._varToAbsVal) && + eqVarToValMap(_locToAbsVal, rhs._locToAbsVal); } bool operator!=(const IntervalExeState &rhs) const @@ -633,7 +691,7 @@ class IntervalExeState : public IntervalESBase bool operator>=(const IntervalExeState &rhs) const { - return geqVarToValMap(_varToItvVal, rhs.getVarToVal()) && geqVarToValMap(_locToItvVal, rhs._locToItvVal); + return geqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && geqVarToValMap(_locToAbsVal, rhs._locToAbsVal); } }; } diff --git a/svf/include/AE/Core/IntervalValue.h b/svf/include/AE/Core/IntervalValue.h index cff9b81d8..c7d098ddf 100644 --- a/svf/include/AE/Core/IntervalValue.h +++ b/svf/include/AE/Core/IntervalValue.h @@ -31,7 +31,6 @@ #ifndef Z3_EXAMPLE_IntervalValue_H #define Z3_EXAMPLE_IntervalValue_H -#include "AE/Core/AbstractValue.h" #include "AE/Core/NumericLiteral.h" namespace SVF @@ -40,7 +39,7 @@ namespace SVF /// IntervalValue abstract value /// /// Implemented as a pair of bounds -class IntervalValue final : public AbstractValue +class IntervalValue { private: // Lower bound @@ -52,12 +51,12 @@ class IntervalValue final : public AbstractValue // Invariant: isBottom() <=> _lb = 1 && _ub = 0 public: - bool isTop() const override + bool isTop() const { return this->_lb.is_minus_infinity() && this->_ub.is_plus_infinity(); } - bool isBottom() const override + bool isBottom() const { return !_ub.geq(_lb); } @@ -92,22 +91,21 @@ class IntervalValue final : public AbstractValue } /// Create default IntervalValue - explicit IntervalValue() : AbstractValue(AbstractValue::IntervalK), _lb(minus_infinity()), _ub(plus_infinity()) {} + explicit IntervalValue() : _lb(minus_infinity()), _ub(plus_infinity()) {} /// Create the IntervalValue [n, n] - explicit IntervalValue(s64_t n) : AbstractValue(AbstractValue::IntervalK), _lb(n), _ub(n) {} + explicit IntervalValue(s64_t n) : _lb(n), _ub(n) {} explicit IntervalValue(s32_t n) : IntervalValue((s64_t) n) {} explicit IntervalValue(u32_t n) : IntervalValue((s64_t) n) {} - explicit IntervalValue(double n) : AbstractValue(AbstractValue::IntervalK), _lb(n), _ub(n) {} + explicit IntervalValue(double n) : _lb(n), _ub(n) {} explicit IntervalValue(NumericLiteral n) : IntervalValue(n, n) {} /// Create the IntervalValue [lb, ub] - explicit IntervalValue(NumericLiteral lb, NumericLiteral ub) : AbstractValue(AbstractValue::IntervalK), - _lb(std::move(lb)), _ub(std::move(ub)) {} + explicit IntervalValue(NumericLiteral lb, NumericLiteral ub) : _lb(std::move(lb)), _ub(std::move(ub)) {} explicit IntervalValue(s64_t lb, s64_t ub) : IntervalValue(NumericLiteral(lb), NumericLiteral(ub)) {} @@ -201,20 +199,7 @@ class IntervalValue final : public AbstractValue } /// Destructor - ~IntervalValue() override = default; - - /// Methods for support type inquiry through isa, cast, and dyn_cast: - //@{ - static inline bool classof(const IntervalValue *) - { - return true; - } - - static inline bool classof(const AbstractValue *v) - { - return v->getAbstractValueKind() == AbstractValue::IntervalK; - } - //@} + ~IntervalValue() = default; /// Return the lower bound const NumericLiteral &lb() const diff --git a/svf/include/AE/Svfexe/AbstractExecution.h b/svf/include/AE/Svfexe/AbstractExecution.h index 76de92d01..13beb4d95 100644 --- a/svf/include/AE/Svfexe/AbstractExecution.h +++ b/svf/include/AE/Svfexe/AbstractExecution.h @@ -38,7 +38,6 @@ namespace SVF class AbstractExecution; class AEStat; class AEAPI; -class IntervalValue; class ExeState; template class FILOWorkList; @@ -269,9 +268,9 @@ class AbstractExecution * e.g. source code str = "abc", return 3 * * @param strValue SVFValue of string - * @return IntervalValue of string length + * @return AbstractValue of string length */ - IntervalValue getStrlen(const SVF::SVFValue *strValue); + AbstractValue getStrlen(const SVF::SVFValue *strValue); /** * get memory allocation size @@ -280,9 +279,9 @@ class AbstractExecution * memset(arr, 1, 10* sizeof(int)) * when we trace the 'arr', we can get the alloc size [40, 40] * @param value to be traced - * @return IntervalValue of allocation size + * @return AbstractValue of allocation size */ - IntervalValue traceMemoryAllocationSize(const SVFValue *value); + AbstractValue traceMemoryAllocationSize(const SVFValue *value); /** * execute strcpy in abstract execution * e.g arr = new char[10] @@ -309,7 +308,7 @@ class AbstractExecution * we can set arr[3]='d', arr[4]='e', arr[5]='\0' * @param call callnode of memcpy like api */ - virtual void handleMemcpy(const SVFValue* dst, const SVFValue* src, IntervalValue len, u32_t start_idx); + virtual void handleMemcpy(const SVFValue* dst, const SVFValue* src, AbstractValue len, u32_t start_idx); /** * execute memset in abstract execution * e.g arr = new char[10] @@ -317,7 +316,7 @@ class AbstractExecution * we can set arr[0]='c', arr[1]='c', arr[2]='\0' * @param call callnode of memset like api */ - virtual void handleMemset(const SVFValue* dst, IntervalValue elem, IntervalValue len); + virtual void handleMemset(const SVFValue* dst, AbstractValue elem, AbstractValue len); /** * if this NodeID in SVFIR is a pointer, get the pointee type diff --git a/svf/include/AE/Svfexe/BufOverflowChecker.h b/svf/include/AE/Svfexe/BufOverflowChecker.h index 4fe949024..2615737bc 100644 --- a/svf/include/AE/Svfexe/BufOverflowChecker.h +++ b/svf/include/AE/Svfexe/BufOverflowChecker.h @@ -164,7 +164,7 @@ class BufOverflowChecker: public AbstractExecution * @param len the length of the buffer overflow checkpoint * @return true if the buffer overflow is detected */ - bool canSafelyAccessMemory(const SVFValue *value, const IntervalValue &len, const ICFGNode *curNode); + bool canSafelyAccessMemory(const SVFValue *value, const AbstractValue &len, const ICFGNode *curNode); private: /** diff --git a/svf/include/AE/Svfexe/SVFIR2ItvExeState.h b/svf/include/AE/Svfexe/SVFIR2ItvExeState.h index e3805c2b3..1833a5d86 100644 --- a/svf/include/AE/Svfexe/SVFIR2ItvExeState.h +++ b/svf/include/AE/Svfexe/SVFIR2ItvExeState.h @@ -35,7 +35,6 @@ #include "AE/Core/ExeState.h" #include "AE/Core/IntervalExeState.h" -#include "AE/Core/IntervalValue.h" #include "AE/Core/RelExeState.h" #include "SVFIR/SVFIR.h" @@ -44,8 +43,7 @@ namespace SVF class SVFIR2ItvExeState { public: - typedef ExeState::Addrs Addrs; - static Addrs globalNulladdrs; + static AbstractValue globalNulladdrs; public: SVFIR2ItvExeState(SVFIR *ir) : _svfir(ir) {} @@ -74,29 +72,29 @@ class SVFIR2ItvExeState void narrowAddrs(IntervalExeState &lhs, const IntervalExeState &rhs); /// Return the field address given a pointer points to a struct object and an offset - Addrs getGepObjAddress(u32_t pointer, APOffset offset); + AbstractValue getGepObjAddress(u32_t pointer, APOffset offset); /// Return the value range of Integer SVF Type, e.g. unsigned i8 Type->[0, 255], signed i8 Type->[-128, 127] - IntervalValue getRangeLimitFromType(const SVFType* type); + AbstractValue getRangeLimitFromType(const SVFType* type); - IntervalValue getZExtValue(const SVFVar* var); - IntervalValue getSExtValue(const SVFVar* var); - IntervalValue getFPToSIntValue(const SVFVar* var); - IntervalValue getFPToUIntValue(const SVFVar* var); - IntervalValue getSIntToFPValue(const SVFVar* var); - IntervalValue getUIntToFPValue(const SVFVar* var); - IntervalValue getTruncValue(const SVFVar* var, const SVFType* dstType); - IntervalValue getFPTruncValue(const SVFVar* var, const SVFType* dstType); + AbstractValue getZExtValue(const SVFVar* var); + AbstractValue getSExtValue(const SVFVar* var); + AbstractValue getFPToSIntValue(const SVFVar* var); + AbstractValue getFPToUIntValue(const SVFVar* var); + AbstractValue getSIntToFPValue(const SVFVar* var); + AbstractValue getUIntToFPValue(const SVFVar* var); + AbstractValue getTruncValue(const SVFVar* var, const SVFType* dstType); + AbstractValue getFPTruncValue(const SVFVar* var, const SVFType* dstType); /// Return the byte offset expression of a GepStmt /// elemBytesize is the element byte size of an static alloc or heap alloc array /// e.g. GepStmt* gep = [i32*10], x, and x is [0,3] /// std::pair byteOffset = getByteOffset(gep); /// byteOffset should be [0, 12] since i32 is 4 bytes. - IntervalValue getByteOffset(const GepStmt *gep); + AbstractValue getByteOffset(const GepStmt *gep); /// Return the offset expression of a GepStmt - IntervalValue getItvOfFlattenedElemIndex(const GepStmt *gep); + AbstractValue getItvOfFlattenedElemIndex(const GepStmt *gep); static z3::context &getContext() @@ -113,7 +111,7 @@ class SVFIR2ItvExeState /// Init SVFVar void initSVFVar(u32_t varId); - inline Addrs &getAddrs(u32_t id) + inline AbstractValue &getAddrs(u32_t id) { if (inVarToAddrsTable(id)) return _es.getAddrs(id); @@ -215,7 +213,7 @@ class SVFIR2ItvExeState RelExeState _relEs; Map _br_cond; - IntervalValue getZExtValue(const SVFVar* var, const SVFType*); + AbstractValue getZExtValue(const SVFVar* var, const SVFType*); }; } diff --git a/svf/lib/AE/Core/IntervalExeState.cpp b/svf/lib/AE/Core/IntervalExeState.cpp index e4fb5d80f..abf29073a 100644 --- a/svf/lib/AE/Core/IntervalExeState.cpp +++ b/svf/lib/AE/Core/IntervalExeState.cpp @@ -51,24 +51,28 @@ u32_t IntervalESBase::hash() const { h2 ^= hf(t.first) + 0x9e3779b9 + (h2 << 6) + (h2 >> 2); } - Hash, u32_t>> pairH; - return pairH(std::make_pair(std::make_pair(h, h2), (u32_t) ExeState::hash())); + Hash> pairH; + return pairH({h, h2}); } IntervalESBase IntervalESBase::widening(const IntervalESBase& other) { + // widen interval IntervalESBase es = *this; - for (auto it = es._varToItvVal.begin(); it != es._varToItvVal.end(); ++it) + for (auto it = es._varToAbsVal.begin(); it != es._varToAbsVal.end(); ++it) { auto key = it->first; - if (other._varToItvVal.find(key) != other._varToItvVal.end()) - it->second.widen_with(other._varToItvVal.at(key)); + if (other._varToAbsVal.find(key) != other._varToAbsVal.end()) { + if (it->second.isInterval()) + it->second.getInterval().widen_with(other._varToAbsVal.at(key).getInterval()); + } } - for (auto it = es._locToItvVal.begin(); it != es._locToItvVal.end(); ++it) + for (auto it = es._locToAbsVal.begin(); it != es._locToAbsVal.end(); ++it) { auto key = it->first; - if (other._locToItvVal.find(key) != other._locToItvVal.end()) - it->second.widen_with(other._locToItvVal.at(key)); + if (other._locToAbsVal.find(key) != other._locToAbsVal.end()) + if (it->second.isInterval()) + it->second.getInterval().widen_with(other._locToAbsVal.at(key).getInterval()); } return es; } @@ -76,17 +80,17 @@ IntervalESBase IntervalESBase::widening(const IntervalESBase& other) IntervalESBase IntervalESBase::narrowing(const IntervalESBase& other) { IntervalESBase es = *this; - for (auto it = es._varToItvVal.begin(); it != es._varToItvVal.end(); ++it) + for (auto it = es._varToAbsVal.begin(); it != es._varToAbsVal.end(); ++it) { auto key = it->first; - if (other._varToItvVal.find(key) != other._varToItvVal.end()) - it->second.narrow_with(other._varToItvVal.at(key)); + if (other._varToAbsVal.find(key) != other._varToAbsVal.end()) + it->second.getInterval().narrow_with(other._varToAbsVal.at(key).getInterval()); } - for (auto it = es._locToItvVal.begin(); it != es._locToItvVal.end(); ++it) + for (auto it = es._locToAbsVal.begin(); it != es._locToAbsVal.end(); ++it) { auto key = it->first; - if (other._locToItvVal.find(key) != other._locToItvVal.end()) - it->second.narrow_with(other._locToItvVal.at(key)); + if (other._locToAbsVal.find(key) != other._locToAbsVal.end()) + it->second.getInterval().narrow_with(other._locToAbsVal.at(key).getInterval()); } return es; @@ -95,48 +99,67 @@ IntervalESBase IntervalESBase::narrowing(const IntervalESBase& other) /// domain widen with other, important! other widen this. void IntervalESBase::widenWith(const IntervalESBase& other) { - for (auto it = _varToItvVal.begin(); it != _varToItvVal.end(); ++it) + for (auto it = _varToAbsVal.begin(); it != _varToAbsVal.end(); ++it) { auto key = it->first; if (other.getVarToVal().find(key) != other.getVarToVal().end()) - it->second.widen_with(other._varToItvVal.at(key)); + if (it->second.isInterval() && other._varToAbsVal.at(key).isInterval()) + it->second.getInterval().widen_with(other._varToAbsVal.at(key).getInterval()); } - for (auto it = _locToItvVal.begin(); it != _locToItvVal.end(); ++it) + for (auto it = _locToAbsVal.begin(); it != _locToAbsVal.end(); ++it) { auto key = it->first; - if (other._locToItvVal.find(key) != other._locToItvVal.end()) - it->second.widen_with(other._locToItvVal.at(key)); + if (other._locToAbsVal.find(key) != other._locToAbsVal.end()) + if (it->second.isInterval() && other._varToAbsVal.at(key).isInterval()) + it->second.getInterval().widen_with(other._locToAbsVal.at(key).getInterval()); } } /// domain join with other, important! other widen this. void IntervalESBase::joinWith(const IntervalESBase& other) { - ExeState::joinWith(other); - for (auto it = other._varToItvVal.begin(); it != other._varToItvVal.end(); ++it) + for (auto it = other._varToAbsVal.begin(); it != other._varToAbsVal.end(); ++it) { auto key = it->first; - auto oit = _varToItvVal.find(key); - if (oit != _varToItvVal.end()) + auto oit = _varToAbsVal.find(key); + if (oit != _varToAbsVal.end()) { - oit->second.join_with(it->second); + if (oit->second.isInterval() && it->second.isInterval()) { + oit->second.getInterval().join_with(it->second.getInterval()); + } + else if (oit->second.isAddr() && it->second.isAddr()) + { + oit->second.getAddrs().join_with(it->second.getAddrs()); + } + else { + // do nothing + } } else { - _varToItvVal.emplace(key, it->second); + _varToAbsVal.emplace(key, it->second); } } - for (auto it = other._locToItvVal.begin(); it != other._locToItvVal.end(); ++it) + for (auto it = other._locToAbsVal.begin(); it != other._locToAbsVal.end(); ++it) { auto key = it->first; - auto oit = _locToItvVal.find(key); - if (oit != _locToItvVal.end()) + auto oit = _locToAbsVal.find(key); + if (oit != _locToAbsVal.end()) { - oit->second.join_with(it->second); + if (oit->second.isInterval() && it->second.isInterval()) { + oit->second.getInterval().join_with(it->second.getInterval()); + } + else if (oit->second.isAddr() && it->second.isAddr()) + { + oit->second.getAddrs().join_with(it->second.getAddrs()); + } + else { + // do nothing + } } else { - _locToItvVal.emplace(key, it->second); + _locToAbsVal.emplace(key, it->second); } } } @@ -144,42 +167,61 @@ void IntervalESBase::joinWith(const IntervalESBase& other) /// domain narrow with other, important! other widen this. void IntervalESBase::narrowWith(const IntervalESBase& other) { - for (auto it = _varToItvVal.begin(); it != _varToItvVal.end(); ++it) + for (auto it = _varToAbsVal.begin(); it != _varToAbsVal.end(); ++it) { auto key = it->first; auto oit = other.getVarToVal().find(key); if (oit != other.getVarToVal().end()) - it->second.narrow_with(oit->second); + if (it->second.isInterval() && oit->second.isInterval()) + it->second.getInterval().narrow_with(oit->second.getInterval()); } - for (auto it = _locToItvVal.begin(); it != _locToItvVal.end(); ++it) + for (auto it = _locToAbsVal.begin(); it != _locToAbsVal.end(); ++it) { auto key = it->first; - auto oit = other._locToItvVal.find(key); - if (oit != other._locToItvVal.end()) - it->second.narrow_with(oit->second); + auto oit = other._locToAbsVal.find(key); + if (oit != other._locToAbsVal.end()) + if (it->second.isInterval() && oit->second.isInterval()) + it->second.getInterval().narrow_with(oit->second.getInterval()); } } /// domain meet with other, important! other widen this. void IntervalESBase::meetWith(const IntervalESBase& other) { - ExeState::meetWith(other); - for (auto it = other._varToItvVal.begin(); it != other._varToItvVal.end(); ++it) + for (auto it = other._varToAbsVal.begin(); it != other._varToAbsVal.end(); ++it) { auto key = it->first; - auto oit = _varToItvVal.find(key); - if (oit != _varToItvVal.end()) + auto oit = _varToAbsVal.find(key); + if (oit != _varToAbsVal.end()) { - oit->second.meet_with(it->second); + if (oit->second.isInterval() && it->second.isInterval()) { + oit->second.getInterval().meet_with(it->second.getInterval()); + } + else if (oit->second.isAddr() && it->second.isAddr()) + { + oit->second.getAddrs().meet_with(it->second.getAddrs()); + } + else { + // do nothing + } } } - for (auto it = other._locToItvVal.begin(); it != other._locToItvVal.end(); ++it) + for (auto it = other._locToAbsVal.begin(); it != other._locToAbsVal.end(); ++it) { auto key = it->first; - auto oit = _locToItvVal.find(key); - if (oit != _locToItvVal.end()) + auto oit = _locToAbsVal.find(key); + if (oit != _locToAbsVal.end()) { - oit->second.meet_with(it->second); + if (oit->second.isInterval() && it->second.isInterval()) { + oit->second.getInterval().meet_with(it->second.getInterval()); + } + else if (oit->second.isAddr() && it->second.isAddr()) + { + oit->second.getAddrs().meet_with(it->second.getAddrs()); + } + else { + // do nothing + } } } } @@ -188,14 +230,12 @@ void IntervalESBase::meetWith(const IntervalESBase& other) void IntervalESBase::printExprValues(std::ostream &oss) const { oss << "-----------Var and Value-----------\n"; - printTable(_varToItvVal, oss); - printTable(_locToItvVal, oss); - printTable(_varToAddrs, oss); - printTable(_locToAddrs, oss); + printTable(_varToAbsVal, oss); + printTable(_locToAbsVal, oss); oss << "-----------------------------------------\n"; } -void IntervalESBase::printTable(const VarToValMap &table, std::ostream &oss) const +void IntervalESBase::printTable(const VarToAbsValMap&table, std::ostream &oss) const { oss.flags(std::ios::left); std::set ordered; @@ -206,7 +246,7 @@ void IntervalESBase::printTable(const VarToValMap &table, std::ostream &oss) con for (const auto &item: ordered) { oss << "Var" << std::to_string(item); - IntervalValue sim = table.at(item); + IntervalValue sim = table.at(item).getInterval(); if (sim.is_numeral() && isVirtualMemAddress(Interval2NumValue(sim))) { oss << "\t Value: " << std::hex << "0x" << Interval2NumValue(sim) << "\n"; @@ -218,27 +258,6 @@ void IntervalESBase::printTable(const VarToValMap &table, std::ostream &oss) con } } -void IntervalESBase::printTable(const VarToAddrs &table, std::ostream &oss) const -{ - oss.flags(std::ios::left); - std::set ordered; - for (const auto &item: table) - { - ordered.insert(item.first); - } - for (const auto &item: ordered) - { - oss << "Var" << std::to_string(item); - Addrs sim = table.at(item); - oss << "\t Value: " << std::hex << "[ "; - for (auto it = sim.begin(); it != sim.end(); ++it) - { - oss << std::hex << "0x" << *it << "(" << std::to_string(*it&(0x00ffffff)) << ") ,"; - } - oss << "]\n"; - } -} - IntervalExeState IntervalExeState::globalES; bool IntervalExeState::equals(const IntervalExeState &other) const { @@ -253,17 +272,19 @@ u32_t IntervalExeState::hash() const IntervalExeState IntervalExeState::widening(const IntervalExeState& other) { IntervalExeState es = *this; - for (auto it = es._varToItvVal.begin(); it != es._varToItvVal.end(); ++it) + for (auto it = es._varToAbsVal.begin(); it != es._varToAbsVal.end(); ++it) { auto key = it->first; - if (other._varToItvVal.find(key) != other._varToItvVal.end()) - it->second.widen_with(other._varToItvVal.at(key)); + if (other._varToAbsVal.find(key) != other._varToAbsVal.end()) + if (it->second.isInterval() && other._varToAbsVal.at(key).isInterval()) + it->second.getInterval().widen_with(other._varToAbsVal.at(key).getInterval()); } - for (auto it = es._locToItvVal.begin(); it != es._locToItvVal.end(); ++it) + for (auto it = es._locToAbsVal.begin(); it != es._locToAbsVal.end(); ++it) { auto key = it->first; - if (other._locToItvVal.find(key) != other._locToItvVal.end()) - it->second.widen_with(other._locToItvVal.at(key)); + if (other._locToAbsVal.find(key) != other._locToAbsVal.end()) + if (it->second.isInterval() && other._locToAbsVal.at(key).isInterval()) + it->second.getInterval().widen_with(other._locToAbsVal.at(key).getInterval()); } return es; } @@ -271,17 +292,19 @@ IntervalExeState IntervalExeState::widening(const IntervalExeState& other) IntervalExeState IntervalExeState::narrowing(const IntervalExeState& other) { IntervalExeState es = *this; - for (auto it = es._varToItvVal.begin(); it != es._varToItvVal.end(); ++it) + for (auto it = es._varToAbsVal.begin(); it != es._varToAbsVal.end(); ++it) { auto key = it->first; - if (other._varToItvVal.find(key) != other._varToItvVal.end()) - it->second.narrow_with(other._varToItvVal.at(key)); + if (other._varToAbsVal.find(key) != other._varToAbsVal.end()) + if (it->second.isInterval() && other._varToAbsVal.at(key).isInterval()) + it->second.getInterval().narrow_with(other._varToAbsVal.at(key).getInterval()); } - for (auto it = es._locToItvVal.begin(); it != es._locToItvVal.end(); ++it) + for (auto it = es._locToAbsVal.begin(); it != es._locToAbsVal.end(); ++it) { auto key = it->first; - if (other._locToItvVal.find(key) != other._locToItvVal.end()) - it->second.narrow_with(other._locToItvVal.at(key)); + if (other._locToAbsVal.find(key) != other._locToAbsVal.end()) + if (it->second.isInterval() && other._locToAbsVal.at(key).isInterval()) + it->second.getInterval().narrow_with(other._locToAbsVal.at(key).getInterval()); } return es; @@ -316,14 +339,10 @@ void IntervalExeState::meetWith(const IntervalExeState& other) void IntervalExeState::printExprValues(std::ostream &oss) const { oss << "-----------Var and Value-----------\n"; - printTable(_varToItvVal, oss); - printTable(_locToItvVal, oss); - printTable(_varToAddrs, oss); - printTable(_locToAddrs, oss); + printTable(_varToAbsVal, oss); + printTable(_locToAbsVal, oss); oss << "------------Global---------------------\n"; - printTable(globalES._varToItvVal, oss); - printTable(globalES._locToItvVal, oss); - printTable(globalES._varToAddrs, oss); - printTable(globalES._locToAddrs, oss); + printTable(globalES._varToAbsVal, oss); + printTable(globalES._locToAbsVal, oss); } diff --git a/svf/lib/AE/Core/SVFIR2Relation.cpp b/svf/lib/AE/Core/SVFIR2Relation.cpp index d207927d7..b7a461eaf 100644 --- a/svf/lib/AE/Core/SVFIR2Relation.cpp +++ b/svf/lib/AE/Core/SVFIR2Relation.cpp @@ -112,15 +112,15 @@ void SVFIR2ItvExeState::translateLoadRel(const LoadStmt *load) { u32_t rhs = load->getRHSVarID(); u32_t lhs = load->getLHSVarID(); - _relEs[lhs] = _relEs.load(Z3Expr((int) _es[rhs].lb().getNumeral())); + _relEs[lhs] = _relEs.load(Z3Expr((int) _es[rhs].getInterval().lb().getNumeral())); } void SVFIR2ItvExeState::translateStoreRel(const StoreStmt *store) { u32_t rhs = store->getRHSVarID(); u32_t lhs = store->getLHSVarID(); - assert(_es[lhs].is_numeral() && "loc not numeral?"); - _relEs.store(Z3Expr((int) _es[lhs].lb().getNumeral()), _relEs.toZ3Expr(rhs)); + assert(_es[lhs].getInterval().is_numeral() && "loc not numeral?"); + _relEs.store(Z3Expr((int) _es[lhs].getInterval().lb().getNumeral()), _relEs.toZ3Expr(rhs)); } @@ -137,9 +137,10 @@ void SVFIR2ItvExeState::translateSelectRel(const SelectStmt *select) u32_t tval = select->getTrueValue()->getId(); u32_t fval = select->getFalseValue()->getId(); u32_t cond = select->getCondition()->getId(); - if (_es[cond].is_numeral()) + IntervalValue& condVal = _es[cond].getInterval(); + if (condVal.is_numeral()) { - _relEs[res] = _es[cond].is_zero() ? _relEs.toZ3Expr(fval) : _relEs.toZ3Expr(tval); + _relEs[res] = condVal.is_zero() ? _relEs.toZ3Expr(fval) : _relEs.toZ3Expr(tval); } else { diff --git a/svf/lib/AE/Svfexe/AbstractExecution.cpp b/svf/lib/AE/Svfexe/AbstractExecution.cpp index d114ca36d..05ceb1b7e 100644 --- a/svf/lib/AE/Svfexe/AbstractExecution.cpp +++ b/svf/lib/AE/Svfexe/AbstractExecution.cpp @@ -319,7 +319,7 @@ bool AbstractExecution::hasCmpBranchES(const CmpStmt* cmpStmt, s64_t succ, Inter } // for const X const, we may get concrete resVal instantly // for var X const, we may get [0,1] if the intersection of var and const is not empty set - IntervalValue resVal = new_es[res_id]; + IntervalValue resVal = new_es[res_id].getInterval(); resVal.meet_with(IntervalValue((s64_t) succ, succ)); // If Var X const generates bottom value, it means this branch path is not feasible. if (resVal.isBottom()) @@ -327,8 +327,8 @@ bool AbstractExecution::hasCmpBranchES(const CmpStmt* cmpStmt, s64_t succ, Inter return false; } - bool b0 = new_es[op0].is_numeral(); - bool b1 = new_es[op1].is_numeral(); + bool b0 = new_es[op0].getInterval().is_numeral(); + bool b1 = new_es[op1].getInterval().is_numeral(); // if const X var, we should reverse op0 and op1. if (b0 && !b1) @@ -372,9 +372,9 @@ bool AbstractExecution::hasCmpBranchES(const CmpStmt* cmpStmt, s64_t succ, Inter // change interval range according to the compare predicate ExeState::Addrs addrs; if(load_op0 && new_es.inVarToAddrsTable(load_op0->getRHSVarID())) - addrs = new_es.getAddrs(load_op0->getRHSVarID()); + addrs = new_es.getAddrs(load_op0->getRHSVarID()).getAddrs(); - IntervalValue &lhs = new_es[op0], &rhs = new_es[op1]; + IntervalValue &lhs = new_es[op0].getInterval(), &rhs = new_es[op1].getInterval(); switch (predicate) { case CmpStmt::Predicate::ICMP_EQ: @@ -489,7 +489,7 @@ bool AbstractExecution::hasSwitchBranchES(const SVFVar* var, s64_t succ, Interva { IntervalExeState new_es = es; new_es.cpyItvToLocal(var->getId()); - IntervalValue& switch_cond = new_es[var->getId()]; + IntervalValue& switch_cond = new_es[var->getId()].getInterval(); s64_t value = succ; FIFOWorkList workList; for (SVFStmt *cmpVarInStmt: var->getInEdges()) @@ -506,14 +506,14 @@ bool AbstractExecution::hasSwitchBranchES(const SVFVar* var, s64_t succ, Interva const SVFStmt* stmt = workList.pop(); if (SVFUtil::isa(stmt)) { - IntervalValue& copy_cond = new_es[var->getId()]; + IntervalValue& copy_cond = new_es[var->getId()].getInterval(); copy_cond.meet_with(IntervalValue(value, value)); } else if (const LoadStmt* load = SVFUtil::dyn_cast(stmt)) { if (new_es.inVarToAddrsTable(load->getRHSVarID())) { - ExeState::Addrs &addrs = new_es.getAddrs(load->getRHSVarID()); //3108 + ExeState::Addrs &addrs = new_es.getAddrs(load->getRHSVarID()).getAddrs(); for (const auto &addr: addrs) { NodeID objId = new_es.getInternalID(addr); @@ -687,8 +687,8 @@ void AbstractExecution::indirectCallFunPass(const SVF::CallICFGNode *callNode) { return; } - ExeState::Addrs Addrs = _svfir2ExeState->getAddrs(call_id); - NodeID addr = *Addrs.begin(); + AbstractValue Addrs = _svfir2ExeState->getAddrs(call_id); //_svfir2ExeState->getEs() + NodeID addr = *Addrs.getAddrs().begin(); SVFVar *func_var = _svfir->getGNode(_svfir2ExeState->getInternalID(addr)); const SVFFunction *callfun = SVFUtil::dyn_cast(func_var->getValue()); if (callfun) @@ -865,6 +865,7 @@ void AbstractExecution::handleFunc(const SVFFunction *func) void AbstractExecution::handleSVFStatement(const SVFStmt *stmt) { + std::cout << "handle stmt: " << stmt->toString() << std::endl; if (const AddrStmt *addr = SVFUtil::dyn_cast(stmt)) { _svfir2ExeState->translateAddr(addr); @@ -971,9 +972,8 @@ void AbstractExecution::SkipRecursiveFunc(const SVFFunction *func) { if (!rhsVar->isPointer() && !rhsVar->isConstDataOrAggDataButNotNullPtr()) { - const SVFIR2ItvExeState::Addrs &addrs =curES.getAddrs(lhs); - assert(!addrs.empty()); - for (const auto &addr: addrs) + const AbstractValue &addrs =curES.getAddrs(lhs); + for (const auto &addr: addrs.getAddrs()) { curES.store(addr, IntervalValue::top()); } @@ -992,8 +992,6 @@ void AEStat::countStateSize() { generalNumMap["Global_ES_Var_AVG_Num"] = IntervalExeState::globalES.getVarToVal().size(); generalNumMap["Global_ES_Loc_AVG_Num"] = IntervalExeState::globalES.getLocToVal().size(); - generalNumMap["Global_ES_Var_Addr_AVG_Num"] = IntervalExeState::globalES.getVarToAddrs().size(); - generalNumMap["Global_ES_Loc_Addr_AVG_Num"] = IntervalExeState::globalES.getLocToAddrs().size(); generalNumMap["ES_Var_AVG_Num"] = 0; generalNumMap["ES_Loc_AVG_Num"] = 0; generalNumMap["ES_Var_Addr_AVG_Num"] = 0; @@ -1002,8 +1000,6 @@ void AEStat::countStateSize() ++count; generalNumMap["ES_Var_AVG_Num"] += _ae->_svfir2ExeState->getEs().getVarToVal().size(); generalNumMap["ES_Loc_AVG_Num"] += _ae->_svfir2ExeState->getEs().getLocToVal().size(); - generalNumMap["ES_Var_Addr_AVG_Num"] += _ae->_svfir2ExeState->getEs().getVarToAddrs().size(); - generalNumMap["ES_Loc_Addr_AVG_Num"] += _ae->_svfir2ExeState->getEs().getLocToAddrs().size(); } void AEStat::finializeStat() @@ -1042,8 +1038,6 @@ void AEStat::finializeStat() generalNumMap["Func_Num"] = funs.size(); generalNumMap["EXT_CallSite_Num"] = extCallSiteNum; generalNumMap["NonEXT_CallSite_Num"] = callSiteNum; - generalNumMap["VarToAddrSize"] = _ae->_svfir2ExeState->getEs().getVarToAddrs().size(); - generalNumMap["LocToAddrSize"] = _ae->_svfir2ExeState->getEs().getLocToAddrs().size(); generalNumMap["Bug_Num"] = _ae->_nodeToBugInfo.size(); timeStatMap["Total_Time(sec)"] = (double)(endTime - startTime) / TIMEINTERVAL; @@ -1118,7 +1112,7 @@ void AbstractExecution::initExtFunMap() IntervalExeState &es = _svfir2ExeState->getEs(); \ u32_t rhs_id = _svfir->getValueNode(cs.getArgument(0)); \ if (!es.inVarToValTable(rhs_id)) return; \ - u32_t rhs = _svfir2ExeState->getEs()[rhs_id].lb().getIntNumeral(); \ + u32_t rhs = _svfir2ExeState->getEs()[rhs_id].getInterval().lb().getIntNumeral(); \ s32_t res = FUNC_NAME(rhs); \ u32_t lhsId = _svfir->getValueNode(cs.getInstruction()); \ _svfir2ExeState->getEs()[lhsId] = IntervalValue(res); \ @@ -1151,8 +1145,8 @@ void AbstractExecution::initExtFunMap() _checkpoints.erase(callNode); u32_t arg0 = _svfir->getValueNode(cs.getArgument(0)); IntervalExeState &es = _svfir2ExeState->getEs(); - es[arg0].meet_with(IntervalValue(1, 1)); - if (es[arg0].equals(IntervalValue(1, 1))) + es[arg0].getInterval().meet_with(IntervalValue(1, 1)); + if (es[arg0].getInterval().equals(IntervalValue(1, 1))) { SVFUtil::outs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n"); } @@ -1172,7 +1166,7 @@ void AbstractExecution::initExtFunMap() u32_t num_id = _svfir->getValueNode(cs.getArgument(0)); std::string text = strRead(cs.getArgument(1)); assert(es.inVarToValTable(num_id) && "print() should pass integer"); - IntervalValue itv = es[num_id]; + IntervalValue itv = es[num_id].getInterval(); std::cout << "Text: " << text <<", Value: " << cs.getArgument(0)->toString() << ", PrintVal: " << itv.toString() << std::endl; return; }; @@ -1192,12 +1186,14 @@ std::string AbstractExecution::strRead(const SVFValue* rhs) { // dead loop for string and break if there's a \0. If no \0, it will throw err. if (!es.inVarToAddrsTable(_svfir->getValueNode(rhs))) continue; - ExeState::Addrs expr0 = _svfir2ExeState->getGepObjAddress(_svfir->getValueNode(rhs), index); - IntervalValue val = IntervalValue::bottom(); - for (const auto &addr: expr0) + AbstractValue expr0 = _svfir2ExeState->getGepObjAddress(_svfir->getValueNode(rhs), index); + AbstractValue val(AbstractValue::UnknownType); + for (const auto &addr: expr0.getAddrs()) { val.join_with(es.load(addr)); } + if (val.isUnknown()) + return str0; if (!val.is_numeral()) { break; @@ -1206,7 +1202,7 @@ std::string AbstractExecution::strRead(const SVFValue* rhs) { break; } - str0.push_back((char) val.getIntNumeral()); + str0.push_back((char) val.getInterval().getIntNumeral()); } return str0; } @@ -1252,14 +1248,14 @@ void AbstractExecution::handleExtAPI(const CallICFGNode *call) // 1. memcpy functions like memcpy_chk, strncpy, annotate("MEMCPY"), annotate("BUF_CHECK:Arg0, Arg2"), annotate("BUF_CHECK:Arg1, Arg2") else if (extType == MEMCPY) { - IntervalValue len = _svfir2ExeState->getEs()[_svfir->getValueNode(cs.getArgument(2))]; + AbstractValue len = _svfir2ExeState->getEs()[_svfir->getValueNode(cs.getArgument(2))]; handleMemcpy(cs.getArgument(0), cs.getArgument(1), len, 0); } else if (extType == MEMSET) { // memset dst is arg0, elem is arg1, size is arg2 - IntervalValue len = _svfir2ExeState->getEs()[_svfir->getValueNode(cs.getArgument(2))]; - IntervalValue elem = _svfir2ExeState->getEs()[_svfir->getValueNode(cs.getArgument(1))]; + AbstractValue len = _svfir2ExeState->getEs()[_svfir->getValueNode(cs.getArgument(2))]; + AbstractValue elem = _svfir2ExeState->getEs()[_svfir->getValueNode(cs.getArgument(1))]; handleMemset(cs.getArgument(0), elem, len); } else if (extType == STRCPY) @@ -1322,7 +1318,7 @@ void AbstractExecution::handleStrcpy(const CallICFGNode *call) CallSite cs = SVFUtil::getSVFCallSite(call->getCallSite()); const SVFValue* arg0Val = cs.getArgument(0); const SVFValue* arg1Val = cs.getArgument(1); - IntervalValue strLen = getStrlen(arg1Val); + AbstractValue strLen = getStrlen(arg1Val); // no need to -1, since it has \0 as the last byte handleMemcpy(arg0Val, arg1Val, strLen,strLen.lb().getIntNumeral()); } @@ -1350,7 +1346,7 @@ u32_t AbstractExecution::getAllocaInstByteSize(const AddrStmt *addr) { _svfir2ExeState->getEs()[_svfir->getValueNode(value)] = IntervalValue(Options::MaxFieldLimit()); } - IntervalValue itv = _svfir2ExeState->getEs()[_svfir->getValueNode(value)]; + AbstractValue itv = _svfir2ExeState->getEs()[_svfir->getValueNode(value)]; res = res * itv.ub().getIntNumeral() > Options::MaxFieldLimit()? Options::MaxFieldLimit(): res * itv.ub().getIntNumeral(); } return (u32_t)res; @@ -1360,7 +1356,7 @@ u32_t AbstractExecution::getAllocaInstByteSize(const AddrStmt *addr) abort(); } -IntervalValue AbstractExecution::traceMemoryAllocationSize(const SVFValue *value) +AbstractValue AbstractExecution::traceMemoryAllocationSize(const SVFValue *value) { /// Usually called by a GepStmt overflow check, or external API (like memcpy) overflow check /// Defitions of Terms: @@ -1441,7 +1437,7 @@ IntervalValue AbstractExecution::traceMemoryAllocationSize(const SVFValue *value } else { - IntervalValue byteOffset = _svfir2ExeState->getByteOffset(gep); + IntervalValue byteOffset = _svfir2ExeState->getByteOffset(gep).getInterval(); } // for variable offset, join with accumulate gep offset gep_offsets[gep->getICFGNode()] = byteOffset; @@ -1492,10 +1488,10 @@ IntervalValue AbstractExecution::traceMemoryAllocationSize(const SVFValue *value } -IntervalValue AbstractExecution::getStrlen(const SVF::SVFValue *strValue) +AbstractValue AbstractExecution::getStrlen(const SVF::SVFValue *strValue) { IntervalExeState &es = _svfir2ExeState->getEs(); - IntervalValue dst_size = traceMemoryAllocationSize(strValue); + AbstractValue dst_size = traceMemoryAllocationSize(strValue); u32_t len = 0; NodeID dstid = _svfir->getValueNode(strValue); u32_t elemSize = 1; @@ -1503,12 +1499,15 @@ IntervalValue AbstractExecution::getStrlen(const SVF::SVFValue *strValue) { for (u32_t index = 0; index < dst_size.lb().getIntNumeral(); index++) { - ExeState::Addrs expr0 = _svfir2ExeState->getGepObjAddress(dstid, index); - IntervalValue val = IntervalValue::bottom(); - for (const auto &addr: expr0) + AbstractValue expr0 = _svfir2ExeState->getGepObjAddress(dstid, index); + AbstractValue val(AbstractValue::UnknownType); + for (const auto &addr: expr0.getAddrs()) { val.join_with(es.load(addr)); } + if (val.isUnknown()) { + return IntervalValue((s64_t)0, (s64_t)Options::MaxFieldLimit()); + } if (val.is_numeral() && (char) val.getIntNumeral() == '\0') { break; @@ -1558,9 +1557,9 @@ void AbstractExecution::handleStrcat(const SVF::CallICFGNode *call) CallSite cs = SVFUtil::getSVFCallSite(call->getCallSite()); const SVFValue* arg0Val = cs.getArgument(0); const SVFValue* arg1Val = cs.getArgument(1); - IntervalValue strLen0 = getStrlen(arg0Val); - IntervalValue strLen1 = getStrlen(arg1Val); - IntervalValue totalLen = strLen0 + strLen1; + AbstractValue strLen0 = getStrlen(arg0Val); + AbstractValue strLen1 = getStrlen(arg1Val); + AbstractValue totalLen = strLen0 + strLen1; handleMemcpy(arg0Val, arg1Val, strLen1, strLen0.lb().getIntNumeral()); // do memcpy } @@ -1570,9 +1569,9 @@ void AbstractExecution::handleStrcat(const SVF::CallICFGNode *call) const SVFValue* arg0Val = cs.getArgument(0); const SVFValue* arg1Val = cs.getArgument(1); const SVFValue* arg2Val = cs.getArgument(2); - IntervalValue arg2Num = _svfir2ExeState->getEs()[_svfir->getValueNode(arg2Val)]; - IntervalValue strLen0 = getStrlen(arg0Val); - IntervalValue totalLen = strLen0 + arg2Num; + AbstractValue arg2Num = _svfir2ExeState->getEs()[_svfir->getValueNode(arg2Val)]; + AbstractValue strLen0 = getStrlen(arg0Val); + AbstractValue totalLen = strLen0 + arg2Num; handleMemcpy(arg0Val, arg1Val, arg2Num, strLen0.lb().getIntNumeral()); // do memcpy } @@ -1582,7 +1581,7 @@ void AbstractExecution::handleStrcat(const SVF::CallICFGNode *call) } } -void AbstractExecution::handleMemcpy(const SVF::SVFValue *dst, const SVF::SVFValue *src, SVF::IntervalValue len, u32_t start_idx) +void AbstractExecution::handleMemcpy(const SVF::SVFValue *dst, const SVF::SVFValue *src, AbstractValue len, u32_t start_idx) { IntervalExeState &es = _svfir2ExeState->getEs(); u32_t dstId = _svfir->getValueNode(dst); // pts(dstId) = {objid} objbar objtypeinfo->getType(). @@ -1618,11 +1617,11 @@ void AbstractExecution::handleMemcpy(const SVF::SVFValue *dst, const SVF::SVFVal for (u32_t index = 0; index < range_val; index++) { // dead loop for string and break if there's a \0. If no \0, it will throw err. - ExeState::Addrs expr_src = _svfir2ExeState->getGepObjAddress(srcId, index); - ExeState::Addrs expr_dst = _svfir2ExeState->getGepObjAddress(dstId, index + start_idx); - for (const auto &dst: expr_dst) + AbstractValue expr_src = _svfir2ExeState->getGepObjAddress(srcId, index); + AbstractValue expr_dst = _svfir2ExeState->getGepObjAddress(dstId, index + start_idx); + for (const auto &dst: expr_dst.getAddrs()) { - for (const auto &src: expr_src) + for (const auto &src: expr_src.getAddrs()) { u32_t objId = ExeState::getInternalID(src); if (es.inLocToValTable(objId)) @@ -1631,7 +1630,7 @@ void AbstractExecution::handleMemcpy(const SVF::SVFValue *dst, const SVF::SVFVal } else if (es.inLocToAddrsTable(objId)) { - es.storeAddrs(dst, es.loadAddrs(src)); + es.store(dst, es.load(src)); } } } @@ -1644,8 +1643,8 @@ const SVFType* AbstractExecution::getPointeeElement(NodeID id) assert(_svfir2ExeState->inVarToAddrsTable(id) && "id is not in varToAddrsTable"); if (_svfir2ExeState->inVarToAddrsTable(id)) { - const ExeState::Addrs& addrs = _svfir2ExeState->getAddrs(id); - for (auto addr: addrs) + const AbstractValue& addrs = _svfir2ExeState->getAddrs(id); + for (auto addr: addrs.getAddrs()) { NodeID addr_id = _svfir2ExeState->getInternalID(addr); if (addr_id == 0) // nullptr has no memobj, skip @@ -1656,7 +1655,7 @@ const SVFType* AbstractExecution::getPointeeElement(NodeID id) return nullptr; } -void AbstractExecution::handleMemset(const SVF::SVFValue *dst, SVF::IntervalValue elem, SVF::IntervalValue len) +void AbstractExecution::handleMemset(const SVF::SVFValue *dst, AbstractValue elem, AbstractValue len) { IntervalExeState &es = _svfir2ExeState->getEs(); u32_t dstId = _svfir->getValueNode(dst); @@ -1688,19 +1687,19 @@ void AbstractExecution::handleMemset(const SVF::SVFValue *dst, SVF::IntervalValu // dead loop for string and break if there's a \0. If no \0, it will throw err. if (_svfir2ExeState->inVarToAddrsTable(dstId)) { - ExeState::Addrs lhs_gep = _svfir2ExeState->getGepObjAddress(dstId, index); - for (const auto &addr: lhs_gep) + AbstractValue lhs_gep = _svfir2ExeState->getGepObjAddress(dstId, index); + for (const auto &addr: lhs_gep.getAddrs()) { u32_t objId = ExeState::getInternalID(addr); if (es.inLocToValTable(objId)) { - IntervalValue tmp = es.load(addr); - tmp.join_with(IntervalValue(elem)); + AbstractValue tmp = es.load(addr); + tmp.join_with(elem); es.store(addr, tmp); } else { - es.store(addr, IntervalValue(elem)); + es.store(addr, elem); } } } @@ -1749,8 +1748,8 @@ void AbstractExecution::AccessMemoryViaLoadStmt(const LoadStmt *load, SVF::FILOW { if (_svfir2ExeState->inVarToAddrsTable(load->getLHSVarID())) { - const ExeState::Addrs &Addrs = _svfir2ExeState->getAddrs(load->getLHSVarID()); - for (auto vaddr: Addrs) + const AbstractValue &Addrs = _svfir2ExeState->getAddrs(load->getLHSVarID()); + for (auto vaddr: Addrs.getAddrs()) { NodeID id = _svfir2ExeState->getInternalID(vaddr); if (id == 0) // nullptr has no memobj, skip diff --git a/svf/lib/AE/Svfexe/BufOverflowChecker.cpp b/svf/lib/AE/Svfexe/BufOverflowChecker.cpp index fad354fc0..052e415cb 100644 --- a/svf/lib/AE/Svfexe/BufOverflowChecker.cpp +++ b/svf/lib/AE/Svfexe/BufOverflowChecker.cpp @@ -65,7 +65,8 @@ void BufOverflowChecker::handleSVFStatement(const SVFStmt *stmt) // for gep stmt, add the gep stmt to the addrToGep map if (const GepStmt *gep = SVFUtil::dyn_cast(stmt)) { - for (NodeID addrID: _svfir2ExeState->getAddrs(gep->getLHSVarID())) + for (NodeID addrID: + _svfir2ExeState->getAddrs(gep->getLHSVarID()).getAddrs()) { NodeID objId = _svfir2ExeState->getInternalID(addrID); _addrToGep[objId] = gep; @@ -125,7 +126,7 @@ bool BufOverflowChecker::detectStrcpy(const CallICFGNode *call) CallSite cs = SVFUtil::getSVFCallSite(call->getCallSite()); const SVFValue* arg0Val = cs.getArgument(0); const SVFValue* arg1Val = cs.getArgument(1); - IntervalValue strLen = getStrlen(arg1Val); + AbstractValue strLen = getStrlen(arg1Val); // no need to -1, since it has \0 as the last byte return canSafelyAccessMemory(arg0Val, strLen, call); } @@ -147,11 +148,11 @@ void BufOverflowChecker::initExtFunMap() } else { - ExeState::Addrs Addrs = _svfir2ExeState->getAddrs(dst_id); - for (auto vaddr: Addrs) + AbstractValue Addrs = _svfir2ExeState->getAddrs(dst_id); + for (auto vaddr: Addrs.getAddrs()) { u32_t objId = _svfir2ExeState->getInternalID(vaddr); - IntervalValue range = _svfir2ExeState->getRangeLimitFromType(_svfir->getGNode(objId)->getType()); + AbstractValue range = _svfir2ExeState->getRangeLimitFromType(_svfir->getGNode(objId)->getType()); es.store(vaddr, range); } } @@ -170,11 +171,11 @@ void BufOverflowChecker::initExtFunMap() } else { - ExeState::Addrs Addrs = _svfir2ExeState->getAddrs(dst_id); - for (auto vaddr: Addrs) + AbstractValue Addrs = _svfir2ExeState->getAddrs(dst_id); + for (auto vaddr: Addrs.getAddrs()) { u32_t objId = _svfir2ExeState->getInternalID(vaddr); - IntervalValue range = _svfir2ExeState->getRangeLimitFromType(_svfir->getGNode(objId)->getType()); + AbstractValue range = _svfir2ExeState->getRangeLimitFromType(_svfir->getGNode(objId)->getType()); es.store(vaddr, range); } } @@ -195,9 +196,9 @@ void BufOverflowChecker::initExtFunMap() IntervalExeState &es = _svfir2ExeState->getEs(); u32_t block_count_id = _svfir->getValueNode(cs.getArgument(2)); u32_t block_size_id = _svfir->getValueNode(cs.getArgument(1)); - IntervalValue block_count = es[block_count_id]; - IntervalValue block_size = es[block_size_id]; - IntervalValue block_byte = block_count * block_size; + AbstractValue block_count = es[block_count_id]; + AbstractValue block_size = es[block_size_id]; + AbstractValue block_byte = block_count * block_size; canSafelyAccessMemory(cs.getArgument(0), block_byte, _svfir->getICFG()->getICFGNode(cs.getInstruction())); }; _func_map["fread"] = sse_fread; @@ -228,7 +229,7 @@ void BufOverflowChecker::initExtFunMap() return; // assert(false && "we cannot support this type"); } - IntervalValue size = es[size_id] * IntervalValue(elemSize) - IntervalValue(1); + AbstractValue size = es[size_id] * IntervalValue(elemSize) - IntervalValue(1); if (!es.inVarToAddrsTable(dst_id)) { if (Options::BufferOverflowCheck()) @@ -262,9 +263,9 @@ void BufOverflowChecker::initExtFunMap() IntervalExeState &es = _svfir2ExeState->getEs(); u32_t num_id = _svfir->getValueNode(cs.getArgument(0)); - u32_t num = (u32_t) es[num_id].getNumeral(); + u32_t num = (u32_t) es[num_id].getInterval().getNumeral(); std::string snum = std::to_string(num); - canSafelyAccessMemory(cs.getArgument(1), IntervalValue((s32_t)snum.size()), _svfir->getICFG()->getICFGNode(cs.getInstruction())); + canSafelyAccessMemory(cs.getArgument(1), AbstractValue((s32_t)snum.size()), _svfir->getICFG()->getICFGNode(cs.getInstruction())); }; _func_map["itoa"] = sse_itoa; @@ -275,7 +276,7 @@ void BufOverflowChecker::initExtFunMap() if (cs.arg_size() < 1) return; const SVFValue* strValue = cs.getArgument(0); IntervalExeState &es = _svfir2ExeState->getEs(); - IntervalValue dst_size = getStrlen(strValue); + AbstractValue dst_size = getStrlen(strValue); u32_t elemSize = 1; if (strValue->getType()->isArrayTy()) { @@ -297,7 +298,7 @@ void BufOverflowChecker::initExtFunMap() if (cs.arg_size() < 4) return; IntervalExeState &es = _svfir2ExeState->getEs(); u32_t len_id = _svfir->getValueNode(cs.getArgument(2)); - IntervalValue len = es[len_id] - IntervalValue(1); + AbstractValue len = es[len_id] - IntervalValue(1); u32_t lhsId = _svfir->getValueNode(cs.getInstruction()); es[lhsId] = len; canSafelyAccessMemory(cs.getArgument(1), len, _svfir->getICFG()->getICFGNode(cs.getInstruction()));; @@ -312,7 +313,7 @@ void BufOverflowChecker::initExtFunMap() if (cs.arg_size() < 2) return; IntervalExeState &es = _svfir2ExeState->getEs(); u32_t size_id = _svfir->getValueNode(cs.getArgument(1)); - IntervalValue val = es[size_id]; + AbstractValue val = es[size_id]; if (val.isBottom()) { val = IntervalValue(0); @@ -342,7 +343,7 @@ void BufOverflowChecker::initExtFunMap() if (cs.arg_size() < 2) return; IntervalExeState &es = _svfir2ExeState->getEs(); u32_t size_id = _svfir->getValueNode(cs.getArgument(1)); - IntervalValue val = es[size_id]; + AbstractValue val = es[size_id]; if (val.isBottom()) { assert(false && "UNSAFE_BUFACCESS size is bottom"); @@ -385,9 +386,9 @@ bool BufOverflowChecker::detectStrcat(const CallICFGNode *call) CallSite cs = SVFUtil::getSVFCallSite(call->getCallSite()); const SVFValue* arg0Val = cs.getArgument(0); const SVFValue* arg1Val = cs.getArgument(1); - IntervalValue strLen0 = getStrlen(arg0Val); - IntervalValue strLen1 = getStrlen(arg1Val); - IntervalValue totalLen = strLen0 + strLen1; + AbstractValue strLen0 = getStrlen(arg0Val); + AbstractValue strLen1 = getStrlen(arg1Val); + AbstractValue totalLen = strLen0 + strLen1; return canSafelyAccessMemory(arg0Val, totalLen, call); } else if (std::find(strncatGroup.begin(), strncatGroup.end(), fun->getName()) != strncatGroup.end()) @@ -395,9 +396,9 @@ bool BufOverflowChecker::detectStrcat(const CallICFGNode *call) CallSite cs = SVFUtil::getSVFCallSite(call->getCallSite()); const SVFValue* arg0Val = cs.getArgument(0); const SVFValue* arg2Val = cs.getArgument(2); - IntervalValue arg2Num = _svfir2ExeState->getEs()[_svfir->getValueNode(arg2Val)]; - IntervalValue strLen0 = getStrlen(arg0Val); - IntervalValue totalLen = strLen0 + arg2Num; + AbstractValue arg2Num = _svfir2ExeState->getEs()[_svfir->getValueNode(arg2Val)]; + AbstractValue strLen0 = getStrlen(arg0Val); + AbstractValue totalLen = strLen0 + arg2Num; return canSafelyAccessMemory(arg0Val, totalLen, call); } else @@ -446,7 +447,7 @@ void BufOverflowChecker::handleExtAPI(const CallICFGNode *call) // loop the args and check the offset for (auto arg: args) { - IntervalValue offset = _svfir2ExeState->getEs()[_svfir->getValueNode(cs.getArgument(arg.second))] - IntervalValue(1); + AbstractValue offset = _svfir2ExeState->getEs()[_svfir->getValueNode(cs.getArgument(arg.second))] - IntervalValue(1); canSafelyAccessMemory(cs.getArgument(arg.first), offset, call); } } @@ -463,7 +464,7 @@ void BufOverflowChecker::handleExtAPI(const CallICFGNode *call) // loop the args and check the offset for (auto arg: args) { - IntervalValue offset = _svfir2ExeState->getEs()[_svfir->getValueNode(cs.getArgument(arg.second))] - IntervalValue(1); + AbstractValue offset = _svfir2ExeState->getEs()[_svfir->getValueNode(cs.getArgument(arg.second))] - IntervalValue(1); canSafelyAccessMemory(cs.getArgument(arg.first), offset, call); } } @@ -482,7 +483,7 @@ void BufOverflowChecker::handleExtAPI(const CallICFGNode *call) return; } -bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue *value, const IntervalValue &len, const ICFGNode *curNode) +bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue *value, const AbstractValue &len, const ICFGNode *curNode) { const SVFValue *firstValue = value; /// Usually called by a GepStmt overflow check, or external API (like memcpy) overflow check @@ -497,7 +498,7 @@ bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue *value, const Inte Set visited; visited.insert(value); Map gep_offsets; - IntervalValue total_bytes = len; + IntervalValue total_bytes = len.getInterval(); worklist.push(value); std::vector callstack = _callSiteStack; while (!worklist.empty()) @@ -551,7 +552,7 @@ bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue *value, const Inte } else { - byteOffset = _svfir2ExeState->getByteOffset(gep); + byteOffset = _svfir2ExeState->getByteOffset(gep).getInterval(); } // for variable offset, join with accumulate gep offset gep_offsets[gep->getICFGNode()] = byteOffset; @@ -580,7 +581,7 @@ bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue *value, const Inte else { u32_t idx = _svfir->getValueNode(idxValue); - IntervalValue idxVal = _svfir2ExeState->getEs()[idx]; + IntervalValue idxVal = _svfir2ExeState->getEs()[idx].getInterval(); if (idxVal.isBottom()) { gepArrTotalByte = gepArrTotalByte + IntervalValue(0, 0); @@ -757,8 +758,8 @@ bool BufOverflowChecker::detectBufOverflow(const ICFGNode *node) { if (_svfir2ExeState->inVarToAddrsTable(load->getRHSVarID())) { - ExeState::Addrs Addrs = _svfir2ExeState->getAddrs(load->getRHSVarID()); - for (auto vaddr: Addrs) + AbstractValue Addrs = _svfir2ExeState->getAddrs(load->getRHSVarID()); + for (auto vaddr: Addrs.getAddrs()) { u32_t objId = _svfir2ExeState->getInternalID(vaddr); if (_addrToGep.find(objId) != _addrToGep.end()) @@ -773,8 +774,8 @@ bool BufOverflowChecker::detectBufOverflow(const ICFGNode *node) { if (_svfir2ExeState->inVarToAddrsTable(store->getLHSVarID())) { - ExeState::Addrs Addrs = _svfir2ExeState->getAddrs(store->getLHSVarID()); - for (auto vaddr: Addrs) + AbstractValue Addrs = _svfir2ExeState->getAddrs(store->getLHSVarID()); + for (auto vaddr: Addrs.getAddrs()) { u32_t objId = _svfir2ExeState->getInternalID(vaddr); if (_addrToGep.find(objId) != _addrToGep.end()) diff --git a/svf/lib/AE/Svfexe/SVFIR2ConsExeState.cpp b/svf/lib/AE/Svfexe/SVFIR2ConsExeState.cpp index 4bd02d7be..0bbc19d01 100644 --- a/svf/lib/AE/Svfexe/SVFIR2ConsExeState.cpp +++ b/svf/lib/AE/Svfexe/SVFIR2ConsExeState.cpp @@ -217,7 +217,7 @@ void SVFIR2ConsExeState::translateCmp(const CmpStmt *cmp) { if (lhs.size() == 1 && rhs.size() == 1) { - (*_es)[res] = lhs == rhs; + (*_es)[res] = (lhs.getVals() == rhs.getVals()); } else { @@ -238,7 +238,7 @@ void SVFIR2ConsExeState::translateCmp(const CmpStmt *cmp) { if (lhs.size() == 1 && rhs.size() == 1) { - (*_es)[res] = lhs != rhs; + (*_es)[res] = (lhs.getVals() != rhs.getVals()); } else { diff --git a/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp b/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp index fc2b09df5..34b680246 100644 --- a/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp +++ b/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp @@ -33,8 +33,7 @@ using namespace SVF; using namespace SVFUtil; -SVF::SVFIR2ItvExeState::Addrs SVF::SVFIR2ItvExeState::globalNulladdrs = - AddressValue(); +AbstractValue SVF::SVFIR2ItvExeState::globalNulladdrs = AddressValue(); /** * This function, getRangeLimitFromType, calculates the lower and upper bounds of @@ -47,7 +46,7 @@ SVF::SVFIR2ItvExeState::Addrs SVF::SVFIR2ItvExeState::globalNulladdrs = * * @return An IntervalValue representing the lower and upper bounds of the range. */ -IntervalValue SVFIR2ItvExeState::getRangeLimitFromType(const SVFType* type) +AbstractValue SVFIR2ItvExeState::getRangeLimitFromType(const SVFType* type) { if (const SVFIntegerType* intType = SVFUtil::dyn_cast(type)) { @@ -109,35 +108,35 @@ IntervalValue SVFIR2ItvExeState::getRangeLimitFromType(const SVFType* type) } } -IntervalValue SVFIR2ItvExeState::getZExtValue(const SVFVar* var) +AbstractValue SVFIR2ItvExeState::getZExtValue(const SVFVar* var) { const SVFType* type = var->getType(); if (SVFUtil::isa(type)) { u32_t bits = type->getByteSize() * 8; - if (_es[var->getId()].is_numeral()) + if (_es[var->getId()].getInterval().is_numeral()) { if (bits == 8) { - int8_t signed_i8_value = _es[var->getId()].getIntNumeral(); + int8_t signed_i8_value = _es[var->getId()].getInterval().getIntNumeral(); u32_t unsigned_value = static_cast(signed_i8_value); return IntervalValue(unsigned_value, unsigned_value); } else if (bits == 16) { - s16_t signed_i16_value = _es[var->getId()].getIntNumeral(); + s16_t signed_i16_value = _es[var->getId()].getInterval().getIntNumeral(); u32_t unsigned_value = static_cast(signed_i16_value); return IntervalValue(unsigned_value, unsigned_value); } else if (bits == 32) { - s32_t signed_i32_value = _es[var->getId()].getIntNumeral(); + s32_t signed_i32_value = _es[var->getId()].getInterval().getIntNumeral(); u32_t unsigned_value = static_cast(signed_i32_value); return IntervalValue(unsigned_value, unsigned_value); } else if (bits == 64) { - s64_t signed_i64_value = _es[var->getId()].getIntNumeral(); + s64_t signed_i64_value = _es[var->getId()].getInterval().getIntNumeral(); return IntervalValue((s64_t)signed_i64_value, (s64_t)signed_i64_value); // we only support i64 at most } @@ -154,18 +153,18 @@ IntervalValue SVFIR2ItvExeState::getZExtValue(const SVFVar* var) assert(false && "cannot support non-integer type"); } -IntervalValue SVFIR2ItvExeState::getSExtValue(const SVFVar* var) +AbstractValue SVFIR2ItvExeState::getSExtValue(const SVFVar* var) { - return _es[var->getId()]; + return _es[var->getId()].getInterval(); } -IntervalValue SVFIR2ItvExeState::getFPToSIntValue(const SVF::SVFVar* var) +AbstractValue SVFIR2ItvExeState::getFPToSIntValue(const SVF::SVFVar* var) { - if (_es[var->getId()].is_real()) + if (_es[var->getId()].getInterval().is_real()) { // get the float value of ub and lb - double float_lb = _es[var->getId()].lb().getRealNumeral(); - double float_ub = _es[var->getId()].ub().getRealNumeral(); + double float_lb = _es[var->getId()].getInterval().lb().getRealNumeral(); + double float_ub = _es[var->getId()].getInterval().ub().getRealNumeral(); // get the int value of ub and lb s64_t int_lb = static_cast(float_lb); s64_t int_ub = static_cast(float_ub); @@ -177,13 +176,13 @@ IntervalValue SVFIR2ItvExeState::getFPToSIntValue(const SVF::SVFVar* var) } } -IntervalValue SVFIR2ItvExeState::getFPToUIntValue(const SVF::SVFVar* var) +AbstractValue SVFIR2ItvExeState::getFPToUIntValue(const SVF::SVFVar* var) { - if (_es[var->getId()].is_real()) + if (_es[var->getId()].getInterval().is_real()) { // get the float value of ub and lb - double float_lb = _es[var->getId()].lb().getRealNumeral(); - double float_ub = _es[var->getId()].ub().getRealNumeral(); + double float_lb = _es[var->getId()].getInterval().lb().getRealNumeral(); + double float_ub = _es[var->getId()].getInterval().ub().getRealNumeral(); // get the int value of ub and lb u64_t int_lb = static_cast(float_lb); u64_t int_ub = static_cast(float_ub); @@ -195,33 +194,33 @@ IntervalValue SVFIR2ItvExeState::getFPToUIntValue(const SVF::SVFVar* var) } } -IntervalValue SVFIR2ItvExeState::getSIntToFPValue(const SVF::SVFVar* var) +AbstractValue SVFIR2ItvExeState::getSIntToFPValue(const SVF::SVFVar* var) { // get the sint value of ub and lb - s64_t sint_lb = _es[var->getId()].lb().getIntNumeral(); - s64_t sint_ub = _es[var->getId()].ub().getIntNumeral(); + s64_t sint_lb = _es[var->getId()].getInterval().lb().getIntNumeral(); + s64_t sint_ub = _es[var->getId()].getInterval().ub().getIntNumeral(); // get the float value of ub and lb double float_lb = static_cast(sint_lb); double float_ub = static_cast(sint_ub); return IntervalValue(float_lb, float_ub); } -IntervalValue SVFIR2ItvExeState::getUIntToFPValue(const SVF::SVFVar* var) +AbstractValue SVFIR2ItvExeState::getUIntToFPValue(const SVF::SVFVar* var) { // get the uint value of ub and lb - u64_t uint_lb = _es[var->getId()].lb().getIntNumeral(); - u64_t uint_ub = _es[var->getId()].ub().getIntNumeral(); + u64_t uint_lb = _es[var->getId()].getInterval().lb().getIntNumeral(); + u64_t uint_ub = _es[var->getId()].getInterval().ub().getIntNumeral(); // get the float value of ub and lb double float_lb = static_cast(uint_lb); double float_ub = static_cast(uint_ub); return IntervalValue(float_lb, float_ub); } -IntervalValue SVFIR2ItvExeState::getTruncValue(const SVF::SVFVar* var, const SVFType* dstType) +AbstractValue SVFIR2ItvExeState::getTruncValue(const SVF::SVFVar* var, const SVFType* dstType) { // get the value of ub and lb - s64_t int_lb = _es[var->getId()].lb().getIntNumeral(); - s64_t int_ub = _es[var->getId()].ub().getIntNumeral(); + s64_t int_lb = _es[var->getId()].getInterval().lb().getIntNumeral(); + s64_t int_ub = _es[var->getId()].getInterval().ub().getIntNumeral(); // get dst type u32_t dst_bits = dstType->getByteSize() * 8; if (dst_bits == 8) @@ -266,90 +265,79 @@ IntervalValue SVFIR2ItvExeState::getTruncValue(const SVF::SVFVar* var, const SVF } } -IntervalValue SVFIR2ItvExeState::getFPTruncValue(const SVF::SVFVar* var, const SVFType* dstType) +AbstractValue SVFIR2ItvExeState::getFPTruncValue(const SVF::SVFVar* var, const SVFType* dstType) { // TODO: now we do not really handle fptrunc - return _es[var->getId()]; + return _es[var->getId()].getInterval(); } void SVFIR2ItvExeState::applySummary(IntervalExeState &es) { - for (const auto &item: es._varToItvVal) + for (const auto &item: es._varToAbsVal) { - _es._varToItvVal[item.first] = item.second; + _es._varToAbsVal[item.first] = item.second; } - for (const auto &item: es._locToItvVal) + for (const auto &item: es._locToAbsVal) { - _es._locToItvVal[item.first] = item.second; - } - for (const auto &item: es._varToAddrs) - { - _es._varToAddrs[item.first] = item.second; - } - for (const auto &item: es._locToAddrs) - { - _es._locToAddrs[item.first] = item.second; + _es._locToAbsVal[item.first] = item.second; } } void SVFIR2ItvExeState::moveToGlobal() { - for (const auto &it: _es._varToItvVal) + for (const auto &it: _es._varToAbsVal) { - IntervalExeState::globalES._varToItvVal.insert(it); + IntervalExeState::globalES._varToAbsVal.insert(it); } - for (const auto &it: _es._locToItvVal) + for (const auto &it: _es._locToAbsVal) { - IntervalExeState::globalES._locToItvVal.insert(it); - } - for (const auto &_varToVAddr: _es._varToAddrs) - { - IntervalExeState::globalES._varToAddrs.insert(_varToVAddr); - } - for (const auto &_locToVAddr: _es._locToAddrs) - { - IntervalExeState::globalES._locToAddrs.insert(_locToVAddr); + IntervalExeState::globalES._locToAbsVal.insert(it); } - _es._varToItvVal.clear(); - IntervalExeState::globalES._varToItvVal.erase(PAG::getPAG()->getBlkPtr()); - _es._varToItvVal[PAG::getPAG()->getBlkPtr()] = IntervalValue::top(); - _es._locToItvVal.clear(); - _es._varToAddrs.clear(); - _es._locToAddrs.clear(); + _es._varToAbsVal.clear(); + IntervalExeState::globalES._varToAbsVal.erase(PAG::getPAG()->getBlkPtr()); + _es._varToAbsVal[PAG::getPAG()->getBlkPtr()] = IntervalValue::top(); + _es._locToAbsVal.clear(); } void SVFIR2ItvExeState::widenAddrs(IntervalExeState &lhs, const IntervalExeState &rhs) { - for (const auto &rhsItem: rhs._varToAddrs) + for (const auto &rhsItem: rhs._varToAbsVal) { - auto lhsIter = lhs._varToAddrs.find(rhsItem.first); - if (lhsIter != lhs._varToAddrs.end()) + auto lhsIter = lhs._varToAbsVal.find(rhsItem.first); + if (lhsIter != lhs._varToAbsVal.end()) { - for (const auto &addr: rhsItem.second) - { - if (!lhsIter->second.contains(addr)) + if (rhsItem.second.isAddr()) { + for (const auto &addr: rhsItem.second.getAddrs()) { - for (s32_t i = 0; i < (s32_t) Options::MaxFieldLimit(); i++) + if (!lhsIter->second.getAddrs().contains(addr)) { - lhsIter->second.join_with(getGepObjAddress(getInternalID(addr), i)); + for (s32_t i = 0; i < (s32_t) Options::MaxFieldLimit(); i++) + { + lhsIter->second.join_with(getGepObjAddress(getInternalID(addr), i)); + } } } } } } - for (const auto &rhsItem: rhs._locToAddrs) + for (const auto &rhsItem: rhs._locToAbsVal) { - auto lhsIter = lhs._locToAddrs.find(rhsItem.first); - if (lhsIter != lhs._locToAddrs.end()) + auto lhsIter = lhs._locToAbsVal.find(rhsItem.first); + if (lhsIter != lhs._locToAbsVal.end()) { - for (const auto &addr: rhsItem.second) + if (rhsItem.second.isAddr()) { - if (!lhsIter->second.contains(addr)) + for (const auto& addr : rhsItem.second.getAddrs()) { - for (s32_t i = 0; i < (s32_t) Options::MaxFieldLimit(); i++) + if (!lhsIter->second.getAddrs().contains(addr)) { - lhsIter->second.join_with(getGepObjAddress(getInternalID(addr), i)); + for (s32_t i = 0; i < (s32_t)Options::MaxFieldLimit(); + i++) + { + lhsIter->second.join_with( + getGepObjAddress(getInternalID(addr), i)); + } } } } @@ -359,55 +347,61 @@ void SVFIR2ItvExeState::widenAddrs(IntervalExeState &lhs, const IntervalExeState void SVFIR2ItvExeState::narrowAddrs(IntervalExeState &lhs, const IntervalExeState &rhs) { - for (const auto &rhsItem: rhs._varToAddrs) + for (const auto &rhsItem: rhs._varToAbsVal) { - auto lhsIter = lhs._varToAddrs.find(rhsItem.first); - if (lhsIter != lhs._varToAddrs.end()) + auto lhsIter = lhs._varToAbsVal.find(rhsItem.first); + if (lhsIter != lhs._varToAbsVal.end()) { - for (const auto &addr: lhsIter->second) + if (lhsIter->second.isAddr()) { - if (!rhsItem.second.contains(addr)) + for (const auto &addr: lhsIter->second.getAddrs()) { - lhsIter->second = rhsItem.second; - break; + if (!rhsItem.second.getAddrs().contains(addr)) + { + lhsIter->second = rhsItem.second; + break; + } } } } } - for (const auto &rhsItem: rhs._locToAddrs) + for (const auto &rhsItem: rhs._locToAbsVal) { - auto lhsIter = lhs._locToAddrs.find(rhsItem.first); - if (lhsIter != lhs._locToAddrs.end()) + auto lhsIter = lhs._locToAbsVal.find(rhsItem.first); + if (lhsIter != lhs._locToAbsVal.end()) { - for (const auto &addr: lhsIter->second) + if (lhsIter->second.isAddr()) { - if (!rhsItem.second.contains(addr)) + for (const auto& addr : lhsIter->second.getAddrs()) { - lhsIter->second = rhsItem.second; - break; + if (!rhsItem.second.getAddrs().contains(addr)) + { + lhsIter->second = rhsItem.second; + break; + } } } } } } -SVFIR2ItvExeState::Addrs SVFIR2ItvExeState::getGepObjAddress(u32_t pointer, APOffset offset) +AbstractValue SVFIR2ItvExeState::getGepObjAddress(u32_t pointer, APOffset offset) { - assert(!getAddrs(pointer).empty()); - Addrs &addrs = getAddrs(pointer); - Addrs ret; - for (const auto &addr: addrs) + assert(!getAddrs(pointer).getAddrs().empty()); + AbstractValue addrs = getAddrs(pointer); + AbstractValue ret = AddressValue(); + for (const auto &addr: addrs.getAddrs()) { s64_t baseObj = getInternalID(addr); if (baseObj == 0) { - ret.insert(getVirtualMemAddress(0)); + ret.insertAddr(getVirtualMemAddress(0)); continue; } assert(SVFUtil::isa(_svfir->getGNode(baseObj)) && "Fail to get the base object address!"); NodeID gepObj = _svfir->getGepObjVar(baseObj, offset); initSVFVar(gepObj); - ret.insert(getVirtualMemAddress(gepObj)); + ret.insertAddr(getVirtualMemAddress(gepObj)); } return ret; } @@ -434,11 +428,11 @@ SVFIR2ItvExeState::Addrs SVFIR2ItvExeState::getGepObjAddress(u32_t pointer, APOf * Therefore the final byteoffset is [8+4*var1.lb(), 8+4*var1.ub()] * */ -IntervalValue SVFIR2ItvExeState::getByteOffset(const GepStmt *gep) +AbstractValue SVFIR2ItvExeState::getByteOffset(const GepStmt *gep) { if (gep->isConstantOffset()) return IntervalValue((s64_t)gep->accumulateConstantByteOffset()); - IntervalValue res(0); // Initialize the result interval 'res' to 0. + AbstractValue res = IntervalValue(0); // Initialize the result interval 'res' to 0. // Loop through the offsetVarAndGepTypePairVec in reverse order. for (int i = gep->getOffsetVarAndGepTypePairVec().size() - 1; i >= 0; i--) { @@ -465,7 +459,7 @@ IntervalValue SVFIR2ItvExeState::getByteOffset(const GepStmt *gep) else { u32_t idx = _svfir->getValueNode(idxOperandVar->getValue()); - IntervalValue idxVal = _es[idx]; + IntervalValue idxVal = _es[idx].getInterval(); if (idxVal.isBottom()) res = res + IntervalValue(0, 0); else @@ -504,11 +498,11 @@ IntervalValue SVFIR2ItvExeState::getByteOffset(const GepStmt *gep) * * @return A pair of APOffset values representing the offset range. */ -IntervalValue SVFIR2ItvExeState::getItvOfFlattenedElemIndex(const GepStmt *gep) +AbstractValue SVFIR2ItvExeState::getItvOfFlattenedElemIndex(const GepStmt *gep) { if (gep->isConstantOffset()) return IntervalValue((s64_t)gep->accumulateConstantOffset()); - IntervalValue res(0); + AbstractValue res = IntervalValue(0); for (int i = gep->getOffsetVarAndGepTypePairVec().size() - 1; i >= 0; i--) { AccessPath::IdxOperandPair IdxVarAndType = @@ -524,7 +518,7 @@ IntervalValue SVFIR2ItvExeState::getItvOfFlattenedElemIndex(const GepStmt *gep) idxLb = idxUb = constInt->getSExtValue(); else { - IntervalValue idxItv = _es[_svfir->getValueNode(value)]; + IntervalValue idxItv = _es[_svfir->getValueNode(value)].getInterval(); if (idxItv.isBottom()) idxLb = idxUb = 0; else @@ -597,18 +591,20 @@ void SVFIR2ItvExeState::initObjVar(const ObjVar *objVar, u32_t varId) IntervalExeState::globalES[varId] = IntervalValue(consFP->getFPValue(), consFP->getFPValue()); else if (SVFUtil::isa(obj->getValue())) IntervalExeState::globalES[varId] = IntervalValue(0, 0); - else if (SVFUtil::isa(obj->getValue())) - IntervalExeState::globalES.getAddrs(varId).insert(getVirtualMemAddress(varId)); + else if (SVFUtil::isa(obj->getValue())) { + IntervalExeState::globalES[varId] = AddressValue(getVirtualMemAddress(varId)); + } + else if (obj->isConstantArray() || obj->isConstantStruct()) IntervalExeState::globalES[varId] = IntervalValue::top(); else IntervalExeState::globalES[varId] = IntervalValue::top(); } else - IntervalExeState::globalES.getAddrs(varId).insert(getVirtualMemAddress(varId)); + IntervalExeState::globalES[varId] = AddressValue(getVirtualMemAddress(varId)); } else - IntervalExeState::globalES.getAddrs(varId).insert(getVirtualMemAddress(varId)); + IntervalExeState::globalES[varId] = AddressValue(getVirtualMemAddress(varId)); } void SVFIR2ItvExeState::initSVFVar(u32_t varId) @@ -637,16 +633,14 @@ void SVFIR2ItvExeState::translateAddr(const AddrStmt *addr) // if addr RHS is integerType(i8 i32 etc), value should be limited. if (addr->getRHSVar()->getType()->getKind() == SVFType::SVFIntegerTy) { - IntervalExeState::globalES[addr->getRHSVarID()].meet_with( - getRangeLimitFromType(addr->getRHSVar()->getType())); + IntervalExeState::globalES[addr->getRHSVarID()].meet_with(getRangeLimitFromType(addr->getRHSVar()->getType())); } IntervalExeState::globalES[addr->getLHSVarID()] = IntervalExeState::globalES[addr->getRHSVarID()]; } else if (inVarToAddrsTable(addr->getRHSVarID())) { - IntervalExeState::globalES.getAddrs(addr->getLHSVarID()) = IntervalExeState::globalES.getAddrs( - addr->getRHSVarID()); + IntervalExeState::globalES[addr->getLHSVarID()] = IntervalExeState::globalES[addr->getRHSVarID()]; } else { @@ -664,8 +658,8 @@ void SVFIR2ItvExeState::translateBinary(const BinaryOPStmt *binary) if (!inVarToValTable(op1)) _es[op1] = IntervalValue::top(); if (inVarToValTable(op0) && inVarToValTable(op1)) { - IntervalValue &lhs = _es[op0], &rhs = _es[op1]; - IntervalValue resVal; + AbstractValue &lhs = _es[op0], &rhs = _es[op1]; + AbstractValue resVal; switch (binary->getOpcode()) { case BinaryOPStmt::Add: @@ -724,8 +718,9 @@ void SVFIR2ItvExeState::translateCmp(const CmpStmt *cmp) u32_t res = cmp->getResID(); if (inVarToValTable(op0) && inVarToValTable(op1)) { - IntervalValue resVal; - IntervalValue &lhs = _es[op0], &rhs = _es[op1]; + AbstractValue resVal; + AbstractValue &lhs = _es[op0], &rhs = _es[op1]; + //AbstractValue auto predicate = cmp->getPredicate(); switch (predicate) { @@ -733,6 +728,7 @@ void SVFIR2ItvExeState::translateCmp(const CmpStmt *cmp) case CmpStmt::FCMP_OEQ: case CmpStmt::FCMP_UEQ: resVal = (lhs == rhs); + // resVal = (lhs.getInterval() == rhs.getInterval()); break; case CmpStmt::ICMP_NE: case CmpStmt::FCMP_ONE: @@ -779,8 +775,8 @@ void SVFIR2ItvExeState::translateCmp(const CmpStmt *cmp) else if (inVarToAddrsTable(op0) && inVarToAddrsTable(op1)) { IntervalValue resVal; - Addrs &lhs = getAddrs(op0), &rhs = getAddrs(op1); - assert(!lhs.empty() && !rhs.empty() && "empty address?"); + AbstractValue &lhs = getAddrs(op0), &rhs = getAddrs(op1); + assert(!lhs.getAddrs().empty() && !rhs.getAddrs().empty() && "empty address?"); auto predicate = cmp->getPredicate(); switch (predicate) { @@ -788,13 +784,13 @@ void SVFIR2ItvExeState::translateCmp(const CmpStmt *cmp) case CmpStmt::FCMP_OEQ: case CmpStmt::FCMP_UEQ: { - if (lhs.size() == 1 && rhs.size() == 1) + if (lhs.getAddrs().size() == 1 && rhs.getAddrs().size() == 1) { resVal = IntervalValue(lhs.equals(rhs)); } else { - if (lhs.hasIntersect(rhs)) + if (lhs.getAddrs().hasIntersect(rhs.getAddrs())) { resVal = IntervalValue::top(); } @@ -809,13 +805,13 @@ void SVFIR2ItvExeState::translateCmp(const CmpStmt *cmp) case CmpStmt::FCMP_ONE: case CmpStmt::FCMP_UNE: { - if (lhs.size() == 1 && rhs.size() == 1) + if (lhs.getAddrs().size() == 1 && rhs.getAddrs().size() == 1) { resVal = IntervalValue(!lhs.equals(rhs)); } else { - if (lhs.hasIntersect(rhs)) + if (lhs.getAddrs().hasIntersect(rhs.getAddrs())) { resVal = IntervalValue::top(); } @@ -831,9 +827,9 @@ void SVFIR2ItvExeState::translateCmp(const CmpStmt *cmp) case CmpStmt::FCMP_OGT: case CmpStmt::FCMP_UGT: { - if (lhs.size() == 1 && rhs.size() == 1) + if (lhs.getAddrs().size() == 1 && rhs.getAddrs().size() == 1) { - resVal = IntervalValue(*lhs.begin() > *rhs.begin()); + resVal = IntervalValue(*lhs.getAddrs().begin() > *rhs.getAddrs().begin()); } else { @@ -846,9 +842,9 @@ void SVFIR2ItvExeState::translateCmp(const CmpStmt *cmp) case CmpStmt::FCMP_OGE: case CmpStmt::FCMP_UGE: { - if (lhs.size() == 1 && rhs.size() == 1) + if (lhs.getAddrs().size() == 1 && rhs.getAddrs().size() == 1) { - resVal = IntervalValue(*lhs.begin() >= *rhs.begin()); + resVal = IntervalValue(*lhs.getAddrs().begin() >= *rhs.getAddrs().begin()); } else { @@ -861,9 +857,9 @@ void SVFIR2ItvExeState::translateCmp(const CmpStmt *cmp) case CmpStmt::FCMP_OLT: case CmpStmt::FCMP_ULT: { - if (lhs.size() == 1 && rhs.size() == 1) + if (lhs.getAddrs().size() == 1 && rhs.getAddrs().size() == 1) { - resVal = IntervalValue(*lhs.begin() < *rhs.begin()); + resVal = IntervalValue(*lhs.getAddrs().begin() < *rhs.getAddrs().begin()); } else { @@ -876,9 +872,9 @@ void SVFIR2ItvExeState::translateCmp(const CmpStmt *cmp) case CmpStmt::FCMP_OLE: case CmpStmt::FCMP_ULE: { - if (lhs.size() == 1 && rhs.size() == 1) + if (lhs.getAddrs().size() == 1 && rhs.getAddrs().size() == 1) { - resVal = IntervalValue(*lhs.begin() <= *rhs.begin()); + resVal = IntervalValue(*lhs.getAddrs().begin() <= *rhs.getAddrs().begin()); } else { @@ -907,39 +903,23 @@ void SVFIR2ItvExeState::translateLoad(const LoadStmt *load) u32_t lhs = load->getLHSVarID(); if (inVarToAddrsTable(rhs)) { - Addrs &addrs = getAddrs(rhs); - assert(!addrs.empty()); - IntervalValue rhsItv = IntervalValue::bottom(); - AddressValue rhsAddr; - bool isVal = false, isAddr = false; - for (const auto &addr: addrs) + AbstractValue &addrs = getAddrs(rhs); + assert(!addrs.getAddrs().empty()); + AbstractValue rhsVal(AbstractValue::UnknownType); // interval::bottom Address::bottom + // AbstractValue absRhs + for (const auto &addr: addrs.getAddrs()) { + // inLocToAbsVal() + // absRhs.join_with + // es.load() u32_t objId = getInternalID(addr); - if (inLocToValTable(objId)) - { - rhsItv.join_with(_es.load(addr)); - isVal = true; - } - else if (inLocToAddrsTable(objId)) + if (inLocToValTable(objId) || inLocToAddrsTable(objId)) { - rhsAddr.join_with(_es.loadAddrs(addr)); - isAddr = true; + rhsVal.join_with(_es.load(addr)); } } - if (isVal) - { - // lhs var is an integer - _es[lhs] = rhsItv; - } - else if (isAddr) - { - // lhs var is an address - _es.getAddrs(lhs) = rhsAddr; - } - else - { - // rhs not initialized, e.g., absence of a store before load - } + if (!rhsVal.isUnknown()) + _es[lhs] = rhsVal; } } @@ -949,25 +929,20 @@ void SVFIR2ItvExeState::translateStore(const StoreStmt *store) u32_t lhs = store->getLHSVarID(); if (inVarToAddrsTable(lhs)) { - if (inVarToValTable(rhs)) + //es.store() + assert(!getAddrs(lhs).getAddrs().empty()); + AbstractValue &addrs = _es[lhs]; + for (const auto &addr: addrs.getAddrs()) { - assert(!getAddrs(lhs).empty()); - Addrs &addrs = getAddrs(lhs); - for (const auto &addr: addrs) - { - _es.store(addr, _es[rhs]); - } + _es.store(addr, _es[rhs]); } - else if (inVarToAddrsTable(rhs)) - { - assert(!getAddrs(lhs).empty()); - Addrs &addrs = getAddrs(lhs); - for (const auto &addr: addrs) + + if (inVarToValTable(rhs) || inVarToAddrsTable(rhs)) { + assert(!getAddrs(lhs).getAddrs().empty()); + for (const auto &addr: _es[lhs].getAddrs()) { - assert(!getAddrs(rhs).empty()); - _es.storeAddrs(addr, getAddrs(rhs)); + _es.store(addr, _es[rhs]); } - } } } @@ -1022,7 +997,7 @@ void SVFIR2ItvExeState::translateCopy(const CopyStmt *copy) } else if (copy->getCopyKind() == CopyStmt::INTTOPTR) { - _es.getAddrs(lhs).insert(getVirtualMemAddress(0)); //insert nullptr + _es.getAddrs(lhs).getAddrs().insert(getVirtualMemAddress(0)); //insert nullptr } else if (copy->getCopyKind() == CopyStmt::PTRTOINT) { @@ -1036,8 +1011,8 @@ void SVFIR2ItvExeState::translateCopy(const CopyStmt *copy) } else if (inVarToAddrsTable(rhs)) { - assert(!getAddrs(rhs).empty()); - _es.getAddrs(lhs) = getAddrs(rhs); + assert(!getAddrs(rhs).getAddrs().empty()); + _es[lhs] = _es[rhs]; } } } @@ -1047,23 +1022,22 @@ void SVFIR2ItvExeState::translateGep(const GepStmt *gep) u32_t rhs = gep->getRHSVarID(); u32_t lhs = gep->getLHSVarID(); if (!inVarToAddrsTable(rhs)) return; - assert(!getAddrs(rhs).empty()); - Addrs &rhsVal = getAddrs(rhs); - if (rhsVal.empty()) return; - IntervalValue offsetPair = getItvOfFlattenedElemIndex(gep); - if (!isVirtualMemAddress(*rhsVal.begin())) + AbstractValue &rhsVal = _es[rhs]; + assert(!rhsVal.getAddrs().empty()); + AbstractValue offsetPair = getItvOfFlattenedElemIndex(gep); + if (!isVirtualMemAddress(*rhsVal.getAddrs().begin())) return; else { - Addrs gepAddrs; + AbstractValue gepAddrs(AbstractValue::UnknownType); APOffset lb = offsetPair.lb().getIntNumeral() < Options::MaxFieldLimit()? offsetPair.lb().getIntNumeral(): Options::MaxFieldLimit(); APOffset ub = offsetPair.ub().getIntNumeral() < Options::MaxFieldLimit()? offsetPair.ub().getIntNumeral(): Options::MaxFieldLimit(); for (APOffset i = lb; i <= ub; i++) gepAddrs.join_with(getGepObjAddress(rhs, i)); - if(gepAddrs.empty()) return; - _es.getAddrs(lhs) = gepAddrs; + if (!rhsVal.isUnknown()) + _es[lhs] = gepAddrs; return; } } @@ -1076,9 +1050,9 @@ void SVFIR2ItvExeState::translateSelect(const SelectStmt *select) u32_t cond = select->getCondition()->getId(); if (inVarToValTable(tval) && inVarToValTable(fval) && inVarToValTable(cond)) { - if (_es[cond].is_numeral()) + if (_es[cond].getInterval().is_numeral()) { - _es[res] = _es[cond].is_zero() ? _es[fval] : _es[tval]; + _es[res] = _es[cond].getInterval().is_zero() ? _es[fval] : _es[tval]; } else { @@ -1087,11 +1061,11 @@ void SVFIR2ItvExeState::translateSelect(const SelectStmt *select) } else if (inVarToAddrsTable(tval) && inVarToAddrsTable(fval) && inVarToValTable(cond)) { - if (_es[cond].is_numeral()) + if (_es[cond].getInterval().is_numeral()) { - assert(!getAddrs(fval).empty()); - assert(!getAddrs(tval).empty()); - _es.getAddrs(res) = _es[cond].is_zero() ? getAddrs(fval) : getAddrs(tval); + assert(!getAddrs(fval).getAddrs().empty()); + assert(!getAddrs(tval).getAddrs().empty()); + _es.getAddrs(res) = _es[cond].getInterval().is_zero() ? getAddrs(fval) : getAddrs(tval); } } } @@ -1099,34 +1073,18 @@ void SVFIR2ItvExeState::translateSelect(const SelectStmt *select) void SVFIR2ItvExeState::translatePhi(const PhiStmt *phi) { u32_t res = phi->getResID(); - IntervalValue rhsItv = IntervalValue::bottom(); - AddressValue rhsAddr; - bool isVal = false, isAddr = false; + AbstractValue rhs(AbstractValue::UnknownType); for (u32_t i = 0; i < phi->getOpVarNum(); i++) { NodeID curId = phi->getOpVarID(i); - if (inVarToValTable(curId)) - { - rhsItv.join_with(_es[curId]); - isVal = true; - } - else if (inVarToAddrsTable(curId)) + + if (inVarToValTable(curId) || inVarToAddrsTable(curId)) { - assert(!getAddrs(curId).empty()); - rhsAddr.join_with(getAddrs(curId)); - isAddr = true; + rhs.join_with(_es[curId]); } } - if (isVal) - { - // res var is an integer - _es[res] = rhsItv; - } - else if (isAddr) - { - // res var is an address - _es.getAddrs(res) = rhsAddr; - } + if (!rhs.isUnknown()) + _es[res] = rhs; } @@ -1134,28 +1092,16 @@ void SVFIR2ItvExeState::translateCall(const CallPE *callPE) { NodeID lhs = callPE->getLHSVarID(); NodeID rhs = callPE->getRHSVarID(); - if (inVarToValTable(rhs)) - { + if (inVarToValTable(rhs) || inVarToAddrsTable(rhs)) { _es[lhs] = _es[rhs]; } - else if (inVarToAddrsTable(rhs)) - { - assert(!getAddrs(rhs).empty()); - _es.getAddrs(lhs) = getAddrs(rhs); - } } void SVFIR2ItvExeState::translateRet(const RetPE *retPE) { NodeID lhs = retPE->getLHSVarID(); NodeID rhs = retPE->getRHSVarID(); - if (inVarToValTable(rhs)) - { + if (inVarToValTable(rhs) || inVarToAddrsTable(rhs)) { _es[lhs] = _es[rhs]; } - else if (inVarToAddrsTable(rhs)) - { - assert(!getAddrs(rhs).empty()); - _es.getAddrs(lhs) = getAddrs(rhs); - } } From ea97b2ac94cb44d11b185080fcaad3a6b486b15a Mon Sep 17 00:00:00 2001 From: jiawei-95 Date: Tue, 2 Apr 2024 12:03:19 +0000 Subject: [PATCH 2/7] update symabs --- svf-llvm/tools/AE/ae.cpp | 54 ++++++++++++-------------- svf/include/AE/Core/IntervalExeState.h | 8 +++- svf/lib/AE/Core/RelationSolver.cpp | 14 +++---- 3 files changed, 39 insertions(+), 37 deletions(-) diff --git a/svf-llvm/tools/AE/ae.cpp b/svf-llvm/tools/AE/ae.cpp index 71d9ba5f9..74bb6a851 100644 --- a/svf-llvm/tools/AE/ae.cpp +++ b/svf-llvm/tools/AE/ae.cpp @@ -128,9 +128,9 @@ class SymblicAbstractionTest assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) { - outs() << r.first << " " << r.second << "\n"; + outs() << r.first << " " << r.second.getInterval() << "\n"; } - IntervalESBase::VarToValMap intendedRes = {{0, IntervalValue(0, 1)}, {1, IntervalValue(1, 2)}}; + IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 1)}, {1, IntervalValue(1, 2)}}; assert(IntervalESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } @@ -163,9 +163,9 @@ class SymblicAbstractionTest assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) { - outs() << r.first << " " << r.second << "\n"; + outs() << r.first << " " << r.second.getInterval() << "\n"; } - IntervalESBase::VarToValMap intendedRes = {{0, IntervalValue(0, 1)}, {1, IntervalValue(0, 2)}}; + IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 1)}, {1, IntervalValue(0, 2)}}; assert(IntervalESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } @@ -201,10 +201,10 @@ class SymblicAbstractionTest assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) { - outs() << r.first << " " << r.second << "\n"; + outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToValMap intendedRes = {{0, IntervalValue(0, 10)}, + IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10)}, {1, IntervalValue(0, 10)}, {2, IntervalValue(0, 0)} }; @@ -244,10 +244,10 @@ class SymblicAbstractionTest assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) { - outs() << r.first << " " << r.second << "\n"; + outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToValMap intendedRes = {{0, IntervalValue(0, 100)}, + IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 100)}, {1, IntervalValue(0, 100)}, {2, IntervalValue(0, 0)} }; @@ -287,11 +287,10 @@ class SymblicAbstractionTest assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) { - outs() << r.first << " " << r.second << "\n"; + outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - // ground truth - IntervalESBase::VarToValMap intendedRes = {{0, IntervalValue(0, 1000)}, + IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 1000)}, {1, IntervalValue(0, 1000)}, {2, IntervalValue(0, 0)} }; @@ -331,11 +330,10 @@ class SymblicAbstractionTest assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) { - outs() << r.first << " " << r.second << "\n"; + outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - // ground truth - IntervalESBase::VarToValMap intendedRes = {{0, IntervalValue(0, 10000)}, + IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10000)}, {1, IntervalValue(0, 10000)}, {2, IntervalValue(0, 0)} }; @@ -375,11 +373,10 @@ class SymblicAbstractionTest assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) { - outs() << r.first << " " << r.second << "\n"; + outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - // ground truth - IntervalESBase::VarToValMap intendedRes = {{0, IntervalValue(0, 100000)}, + IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 100000)}, {1, IntervalValue(0, 100000)}, {2, IntervalValue(0, 0)} }; @@ -418,10 +415,10 @@ class SymblicAbstractionTest assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) { - outs() << r.first << " " << r.second << "\n"; + outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToValMap intendedRes = {{0, IntervalValue(1, 10)}, + IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 10)}, {1, IntervalValue(1, 10)}, {2, IntervalValue(1, 1)} }; @@ -460,10 +457,10 @@ class SymblicAbstractionTest assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) { - outs() << r.first << " " << r.second << "\n"; + outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToValMap intendedRes = {{0, IntervalValue(1, 1000)}, + IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 1000)}, {1, IntervalValue(1, 1000)}, {2, IntervalValue(1, 1)} }; @@ -502,13 +499,12 @@ class SymblicAbstractionTest assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) { - outs() << r.first << " " << r.second << "\n"; + outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToValMap intendedRes = - Map({{0, IntervalValue(1, 10000)}, + IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 10000)}, {1, IntervalValue(1, 10000)}, - {2, IntervalValue(1, 1)}}); + {2, IntervalValue(1, 1)}}; } void testRelExeState3_4() @@ -543,10 +539,10 @@ class SymblicAbstractionTest assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) { - outs() << r.first << " " << r.second << "\n"; + outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToValMap intendedRes = {{0, IntervalValue(1, 100000)}, + IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 100000)}, {1, IntervalValue(1, 100000)}, {2, IntervalValue(1, 1)} }; @@ -588,10 +584,10 @@ class SymblicAbstractionTest // assert(resRSY == resBS && resBS == resBilateral); for (auto r : resBS.getVarToVal()) { - outs() << r.first << " " << r.second << "\n"; + outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToValMap intendedRes = {{0, IntervalValue(0, 10)}, + IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10)}, {1, IntervalValue(0, 10)}, {2, IntervalValue(IntervalValue::minus_infinity(), IntervalValue::plus_infinity())} }; diff --git a/svf/include/AE/Core/IntervalExeState.h b/svf/include/AE/Core/IntervalExeState.h index a63186c1f..741dded3d 100644 --- a/svf/include/AE/Core/IntervalExeState.h +++ b/svf/include/AE/Core/IntervalExeState.h @@ -149,7 +149,7 @@ class IntervalESBase for (auto &item: inv._varToAbsVal) { if (item.second.isInterval()) - item.second.getInterval().set_to_bottom(); + item.second.getInterval().set_to_top(); } return inv; } @@ -178,6 +178,12 @@ class IntervalESBase return _varToAbsVal[varId]; } + /// get interval value of variable + inline virtual const AbstractValue &operator[](u32_t varId) const + { + return _varToAbsVal.at(varId); + } + /// whether the variable is in varToAddrs table inline bool inVarToAddrsTable(u32_t id) const { diff --git a/svf/lib/AE/Core/RelationSolver.cpp b/svf/lib/AE/Core/RelationSolver.cpp index 941a40fa2..d279f8ca1 100644 --- a/svf/lib/AE/Core/RelationSolver.cpp +++ b/svf/lib/AE/Core/RelationSolver.cpp @@ -185,7 +185,7 @@ IntervalESBase RelationSolver::abstract_consequence( /// for variable in self.variables: { IntervalESBase proposed = domain.top(); /// proposed = self.top.copy() - proposed._varToItvVal[it->first] = lower._varToItvVal.at(it->first); + proposed[it->first] = lower[it->first].getInterval(); /// proposed.set_interval(variable, lower.interval_of(variable)) /// proposed._locToItvVal if (!(proposed >= upper)) /// if not proposed >= upper: @@ -218,7 +218,7 @@ Z3Expr RelationSolver::gamma_hat(const IntervalESBase& alpha, Z3Expr res(Z3Expr::getContext().bool_val(true)); for (auto& item : exeState.getVarToVal()) { - IntervalValue interval = alpha._varToItvVal.at(item.first); + IntervalValue interval = alpha[item.first].getInterval(); if (interval.isBottom()) return Z3Expr::getContext().bool_val(false); if (interval.isTop()) @@ -247,7 +247,7 @@ IntervalESBase RelationSolver::beta(const Map& sigma, IntervalESBase res; for (const auto& item : exeState.getVarToVal()) { - res._varToItvVal[item.first] = IntervalValue( + res[item.first] = IntervalValue( sigma.at(item.first), sigma.at(item.first)); } return res; @@ -318,16 +318,16 @@ IntervalESBase RelationSolver::BS(const IntervalESBase& domain, const Z3Expr &ph if (item.first >= bias) { if (item.second.equal(infinity)) - retInv._varToItvVal[item.first - bias].setLb(Z3Expr::getContext().int_const("-oo")); + retInv[item.first - bias].getInterval().setLb(Z3Expr::getContext().int_const("-oo")); else - retInv._varToItvVal[item.first - bias].setLb(-item.second); + retInv[item.first - bias].getInterval().setLb(-item.second); } else { if (item.second.equal(infinity)) - retInv._varToItvVal[item.first].setUb(Z3Expr::getContext().int_const("+oo")); + retInv[item.first].getInterval().setUb(Z3Expr::getContext().int_const("+oo")); else - retInv._varToItvVal[item.first].setUb(item.second); + retInv[item.first].getInterval().setUb(item.second); } } return retInv; From 3cff2a653ccd2a4293893c53bd89b0e410017a24 Mon Sep 17 00:00:00 2001 From: bjjwwang Date: Tue, 2 Apr 2024 23:13:02 +1100 Subject: [PATCH 3/7] some modification --- svf/include/AE/Core/AbstractValue.h | 35 ++++++++++++++++++++----- svf/lib/AE/Svfexe/AbstractExecution.cpp | 1 - 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/svf/include/AE/Core/AbstractValue.h b/svf/include/AE/Core/AbstractValue.h index e2d09cde1..d24a14833 100644 --- a/svf/include/AE/Core/AbstractValue.h +++ b/svf/include/AE/Core/AbstractValue.h @@ -1,21 +1,41 @@ +//===- AbstractValue.h ----AbstractValue-------------------------// +// +// 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 . +// +//===----------------------------------------------------------------------===// + #include "AE/Core/IntervalValue.h" #include "AE/Core/AddressValue.h" namespace SVF { -typedef AddressValue Addrs; struct AbstractValue { enum DataType { - IntervalType, //IntervalType - AddressType, // AddressType - UnknownType, //UnknownType + IntervalType, + AddressType, + UnknownType, }; DataType type; IntervalValue interval; AddressValue addr; - //AbstractValue() : type(Null) {} AbstractValue() : type(IntervalType) { interval = IntervalValue::top(); } AbstractValue(DataType type) : type(type) { switch (type) { @@ -46,7 +66,6 @@ struct AbstractValue { inline bool isInterval() const { return type == IntervalType; } inline bool isAddr() const { return type == AddressType; } inline bool isUnknown() const { return type == UnknownType; } - // isUnknownType() inline DataType getType() const { return type; } @@ -63,6 +82,7 @@ struct AbstractValue { } } + // operator overload, supporting both interval and address AbstractValue& operator=(const AbstractValue& other) { type = other.type; switch (type) @@ -113,6 +133,7 @@ struct AbstractValue { return interval; } + // const IntervalValue getInterval() const { assert(isInterval()); return interval; } AddressValue& getAddrs() { assert(isAddr()); return addr; } @@ -415,7 +436,7 @@ struct AbstractValue { return interval.toString(); } else if (isAddr()) { - //TODO: write addr to string + return addr.toString(); } return ""; } diff --git a/svf/lib/AE/Svfexe/AbstractExecution.cpp b/svf/lib/AE/Svfexe/AbstractExecution.cpp index 05ceb1b7e..63f2a7605 100644 --- a/svf/lib/AE/Svfexe/AbstractExecution.cpp +++ b/svf/lib/AE/Svfexe/AbstractExecution.cpp @@ -865,7 +865,6 @@ void AbstractExecution::handleFunc(const SVFFunction *func) void AbstractExecution::handleSVFStatement(const SVFStmt *stmt) { - std::cout << "handle stmt: " << stmt->toString() << std::endl; if (const AddrStmt *addr = SVFUtil::dyn_cast(stmt)) { _svfir2ExeState->translateAddr(addr); From 79249a0cebf8fe4a6d3bad18f65d8f220a156b55 Mon Sep 17 00:00:00 2001 From: bjjwwang Date: Wed, 3 Apr 2024 13:47:47 +1100 Subject: [PATCH 4/7] fix some bugs for big prog --- svf/lib/AE/Svfexe/AbstractExecution.cpp | 3 ++- svf/lib/AE/Svfexe/BufOverflowChecker.cpp | 5 ++++- svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp | 15 ++++++++++++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/svf/lib/AE/Svfexe/AbstractExecution.cpp b/svf/lib/AE/Svfexe/AbstractExecution.cpp index 63f2a7605..9ac0000b9 100644 --- a/svf/lib/AE/Svfexe/AbstractExecution.cpp +++ b/svf/lib/AE/Svfexe/AbstractExecution.cpp @@ -1639,7 +1639,6 @@ void AbstractExecution::handleMemcpy(const SVF::SVFValue *dst, const SVF::SVFVal const SVFType* AbstractExecution::getPointeeElement(NodeID id) { - assert(_svfir2ExeState->inVarToAddrsTable(id) && "id is not in varToAddrsTable"); if (_svfir2ExeState->inVarToAddrsTable(id)) { const AbstractValue& addrs = _svfir2ExeState->getAddrs(id); @@ -1650,6 +1649,8 @@ const SVFType* AbstractExecution::getPointeeElement(NodeID id) continue; return SVFUtil::dyn_cast(_svfir->getGNode(addr_id))->getMemObj()->getType(); } + } else { + // do nothing if no record in addrs table. } return nullptr; } diff --git a/svf/lib/AE/Svfexe/BufOverflowChecker.cpp b/svf/lib/AE/Svfexe/BufOverflowChecker.cpp index 052e415cb..43fcf6f62 100644 --- a/svf/lib/AE/Svfexe/BufOverflowChecker.cpp +++ b/svf/lib/AE/Svfexe/BufOverflowChecker.cpp @@ -284,7 +284,10 @@ void BufOverflowChecker::initExtFunMap() } else if (strValue->getType()->isPointerTy()) { - elemSize = getPointeeElement(_svfir->getValueNode(strValue))->getByteSize(); + if (const SVFType* pointee = getPointeeElement(_svfir->getValueNode(strValue))) + elemSize = pointee->getByteSize(); + else + elemSize = 1; } u32_t lhsId = _svfir->getValueNode(cs.getInstruction()); es[lhsId] = dst_size / IntervalValue(elemSize); diff --git a/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp b/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp index 34b680246..acea11ca1 100644 --- a/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp +++ b/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp @@ -103,8 +103,8 @@ AbstractValue SVFIR2ItvExeState::getRangeLimitFromType(const SVFType* type) } else { - assert(false && "cannot support"); - abort(); + return IntervalValue::top(); + // other types, return top interval } } @@ -1003,8 +1003,17 @@ void SVFIR2ItvExeState::translateCopy(const CopyStmt *copy) { _es[lhs] = IntervalValue::top(); } - else + else if (copy->getCopyKind() == CopyStmt::BITCAST) { + if (_es[rhs].isAddr()) { + _es[lhs] = _es[rhs]; + } + else + { + // do nothing + } + } + else { assert(false && "undefined copy kind"); abort(); } From c3178e84bcb9db8ec241476cb9a93e7d59c6dcbf Mon Sep 17 00:00:00 2001 From: bjjwwang Date: Wed, 3 Apr 2024 23:05:29 +1100 Subject: [PATCH 5/7] rename some key data structure --- svf-llvm/tools/AE/ae.cpp | 185 ++++++++++-------- ...{IntervalExeState.h => AbstractExeState.h} | 123 ++++++------ svf/include/AE/Core/ExeState.h | 2 +- svf/include/AE/Core/IntervalValue.h | 2 +- svf/include/AE/Core/RelationSolver.h | 18 +- svf/include/AE/Svfexe/AbstractExecution.h | 15 +- svf/include/AE/Svfexe/SVFIR2ItvExeState.h | 16 +- ...ervalExeState.cpp => AbstractExeState.cpp} | 62 +++--- svf/lib/AE/Core/ExeState.cpp | 2 +- svf/lib/AE/Core/RelationSolver.cpp | 44 ++--- svf/lib/AE/Svfexe/AbstractExecution.cpp | 66 ++++--- svf/lib/AE/Svfexe/BufOverflowChecker.cpp | 18 +- svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp | 36 ++-- 13 files changed, 300 insertions(+), 289 deletions(-) rename svf/include/AE/Core/{IntervalExeState.h => AbstractExeState.h} (83%) rename svf/lib/AE/Core/{IntervalExeState.cpp => AbstractExeState.cpp} (86%) diff --git a/svf-llvm/tools/AE/ae.cpp b/svf-llvm/tools/AE/ae.cpp index 74bb6a851..cd169ba40 100644 --- a/svf-llvm/tools/AE/ae.cpp +++ b/svf-llvm/tools/AE/ae.cpp @@ -63,11 +63,11 @@ class SymblicAbstractionTest outs() << "hello print\n"; } - IntervalESBase RSY_time(IntervalESBase& inv, const Z3Expr& phi, + AbstractESBase RSY_time(AbstractESBase& inv, const Z3Expr& phi, RelationSolver& rs) { auto start_time = std::chrono::high_resolution_clock::now(); - IntervalESBase resRSY = rs.RSY(inv, phi); + AbstractESBase resRSY = rs.RSY(inv, phi); auto end_time = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast( end_time - start_time); @@ -75,11 +75,11 @@ class SymblicAbstractionTest << " microseconds\n"; return resRSY; } - IntervalESBase Bilateral_time(IntervalESBase& inv, const Z3Expr& phi, + AbstractESBase Bilateral_time(AbstractESBase& inv, const Z3Expr& phi, RelationSolver& rs) { auto start_time = std::chrono::high_resolution_clock::now(); - IntervalESBase resBilateral = rs.bilateral(inv, phi); + AbstractESBase resBilateral = rs.bilateral(inv, phi); auto end_time = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast( end_time - start_time); @@ -87,11 +87,11 @@ class SymblicAbstractionTest << " microseconds\n"; return resBilateral; } - IntervalESBase BS_time(IntervalESBase& inv, const Z3Expr& phi, + AbstractESBase BS_time(AbstractESBase& inv, const Z3Expr& phi, RelationSolver& rs) { auto start_time = std::chrono::high_resolution_clock::now(); - IntervalESBase resBS = rs.BS(inv, phi); + AbstractESBase resBS = rs.BS(inv, phi); auto end_time = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast( end_time - start_time); @@ -103,7 +103,7 @@ class SymblicAbstractionTest void testRelExeState1_1() { outs() << sucMsg("\t SUCCESS :") << "test1_1 start\n"; - IntervalESBase itv; + AbstractESBase itv; RelExeState relation; // var0 := [0, 1]; itv[0] = IntervalValue(0, 1); @@ -116,28 +116,29 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[1], res); assert(res == Set({0, 1}) && "inconsistency occurs"); - IntervalESBase inv = itv.sliceState(res); + AbstractESBase inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - IntervalESBase resRSY = rs.RSY(inv, phi); - IntervalESBase resBilateral = rs.bilateral(inv, phi); - IntervalESBase resBS = rs.BS(inv, phi); + AbstractESBase resRSY = rs.RSY(inv, phi); + AbstractESBase resBilateral = rs.bilateral(inv, phi); + AbstractESBase resBS = rs.BS(inv, phi); // 0:[0,1] 1:[1,2] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) { outs() << r.first << " " << r.second.getInterval() << "\n"; } - IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 1)}, {1, IntervalValue(1, 2)}}; - assert(IntervalESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 1)}, {1, IntervalValue(1, 2)}}; + assert( + AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState1_2() { outs() << "test1_2 start\n"; - IntervalESBase itv; + AbstractESBase itv; RelExeState relation; // var0 := [0, 1]; relation[0] = getContext().int_const("0"); @@ -151,28 +152,29 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[1], res); assert(res == Set({0, 1}) && "inconsistency occurs"); - IntervalESBase inv = itv.sliceState(res); + AbstractESBase inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - IntervalESBase resRSY = rs.RSY(inv, phi); - IntervalESBase resBilateral = rs.bilateral(inv, phi); - IntervalESBase resBS = rs.BS(inv, phi); + AbstractESBase resRSY = rs.RSY(inv, phi); + AbstractESBase resBilateral = rs.bilateral(inv, phi); + AbstractESBase resBS = rs.BS(inv, phi); // 0:[0,1] 1:[0,2] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) { outs() << r.first << " " << r.second.getInterval() << "\n"; } - IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 1)}, {1, IntervalValue(0, 2)}}; - assert(IntervalESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 1)}, {1, IntervalValue(0, 2)}}; + assert( + AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState2_1() { outs() << "test2_1 start\n"; - IntervalESBase itv; + AbstractESBase itv; RelExeState relation; // var0 := [0, 10]; relation[0] = getContext().int_const("0"); @@ -189,14 +191,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - IntervalESBase inv = itv.sliceState(res); + AbstractESBase inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - IntervalESBase resRSY = rs.RSY(inv, phi); - IntervalESBase resBilateral = rs.bilateral(inv, phi); - IntervalESBase resBS = rs.BS(inv, phi); + AbstractESBase resRSY = rs.RSY(inv, phi); + AbstractESBase resBilateral = rs.bilateral(inv, phi); + AbstractESBase resBS = rs.BS(inv, phi); // 0:[0,10] 1:[0,10] 2:[0,0] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -204,17 +206,18 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10)}, + AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10)}, {1, IntervalValue(0, 10)}, {2, IntervalValue(0, 0)} }; - assert(IntervalESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert( + AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState2_2() { outs() << "test2_2 start\n"; - IntervalESBase itv; + AbstractESBase itv; RelExeState relation; // var0 := [0, 100]; relation[0] = getContext().int_const("0"); @@ -232,14 +235,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - IntervalESBase inv = itv.sliceState(res); + AbstractESBase inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - IntervalESBase resRSY = rs.RSY(inv, phi); - IntervalESBase resBilateral = rs.bilateral(inv, phi); - IntervalESBase resBS = rs.BS(inv, phi); + AbstractESBase resRSY = rs.RSY(inv, phi); + AbstractESBase resBilateral = rs.bilateral(inv, phi); + AbstractESBase resBS = rs.BS(inv, phi); // 0:[0,100] 1:[0,100] 2:[0,0] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -247,17 +250,18 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 100)}, + AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 100)}, {1, IntervalValue(0, 100)}, {2, IntervalValue(0, 0)} }; - assert(IntervalESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert( + AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState2_3() { outs() << "test2_3 start\n"; - IntervalESBase itv; + AbstractESBase itv; RelExeState relation; // var0 := [0, 1000]; relation[0] = getContext().int_const("0"); @@ -275,14 +279,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - IntervalESBase inv = itv.sliceState(res); + AbstractESBase inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - IntervalESBase resRSY = rs.RSY(inv, phi); - IntervalESBase resBilateral = rs.bilateral(inv, phi); - IntervalESBase resBS = rs.BS(inv, phi); + AbstractESBase resRSY = rs.RSY(inv, phi); + AbstractESBase resBilateral = rs.bilateral(inv, phi); + AbstractESBase resBS = rs.BS(inv, phi); // 0:[0,1000] 1:[0,1000] 2:[0,0] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -290,17 +294,18 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 1000)}, + AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 1000)}, {1, IntervalValue(0, 1000)}, {2, IntervalValue(0, 0)} }; - assert(IntervalESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert( + AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState2_4() { outs() << "test2_4 start\n"; - IntervalESBase itv; + AbstractESBase itv; RelExeState relation; // var0 := [0, 10000]; relation[0] = getContext().int_const("0"); @@ -318,14 +323,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - IntervalESBase inv = itv.sliceState(res); + AbstractESBase inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - IntervalESBase resRSY = RSY_time(inv, phi, rs); - IntervalESBase resBilateral = Bilateral_time(inv, phi, rs); - IntervalESBase resBS = BS_time(inv, phi, rs); + AbstractESBase resRSY = RSY_time(inv, phi, rs); + AbstractESBase resBilateral = Bilateral_time(inv, phi, rs); + AbstractESBase resBS = BS_time(inv, phi, rs); // 0:[0,10000] 1:[0,10000] 2:[0,0] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -333,17 +338,18 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10000)}, + AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10000)}, {1, IntervalValue(0, 10000)}, {2, IntervalValue(0, 0)} }; - assert(IntervalESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert( + AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState2_5() { outs() << "test2_5 start\n"; - IntervalESBase itv; + AbstractESBase itv; RelExeState relation; // var0 := [0, 100000]; relation[0] = getContext().int_const("0"); @@ -361,14 +367,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - IntervalESBase inv = itv.sliceState(res); + AbstractESBase inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - IntervalESBase resRSY = RSY_time(inv, phi, rs); - IntervalESBase resBilateral = Bilateral_time(inv, phi, rs); - IntervalESBase resBS = BS_time(inv, phi, rs); + AbstractESBase resRSY = RSY_time(inv, phi, rs); + AbstractESBase resBilateral = Bilateral_time(inv, phi, rs); + AbstractESBase resBS = BS_time(inv, phi, rs); // 0:[0,100000] 1:[0,100000] 2:[0,0] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -376,17 +382,18 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 100000)}, + AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 100000)}, {1, IntervalValue(0, 100000)}, {2, IntervalValue(0, 0)} }; - assert(IntervalESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert( + AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState3_1() { outs() << "test3_1 start\n"; - IntervalESBase itv; + AbstractESBase itv; RelExeState relation; // var0 := [1, 10]; relation[0] = getContext().int_const("0"); @@ -403,14 +410,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - IntervalESBase inv = itv.sliceState(res); + AbstractESBase inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - IntervalESBase resRSY = rs.RSY(inv, phi); - IntervalESBase resBilateral = rs.bilateral(inv, phi); - IntervalESBase resBS = rs.BS(inv, phi); + AbstractESBase resRSY = rs.RSY(inv, phi); + AbstractESBase resBilateral = rs.bilateral(inv, phi); + AbstractESBase resBS = rs.BS(inv, phi); // 0:[1,10] 1:[1,10] 2:[1,1] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -418,17 +425,18 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 10)}, + AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 10)}, {1, IntervalValue(1, 10)}, {2, IntervalValue(1, 1)} }; - assert(IntervalESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert( + AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState3_2() { outs() << "test3_2 start\n"; - IntervalESBase itv; + AbstractESBase itv; RelExeState relation; // var0 := [1, 1000]; relation[0] = getContext().int_const("0"); @@ -445,14 +453,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - IntervalESBase inv = itv.sliceState(res); + AbstractESBase inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - IntervalESBase resRSY = rs.RSY(inv, phi); - IntervalESBase resBilateral = rs.bilateral(inv, phi); - IntervalESBase resBS = rs.BS(inv, phi); + AbstractESBase resRSY = rs.RSY(inv, phi); + AbstractESBase resBilateral = rs.bilateral(inv, phi); + AbstractESBase resBS = rs.BS(inv, phi); // 0:[1,1000] 1:[1,1000] 2:[1,1] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -460,17 +468,18 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 1000)}, + AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 1000)}, {1, IntervalValue(1, 1000)}, {2, IntervalValue(1, 1)} }; - assert(IntervalESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert( + AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState3_3() { outs() << "test3_3 start\n"; - IntervalESBase itv; + AbstractESBase itv; RelExeState relation; // var0 := [1, 10000]; relation[0] = getContext().int_const("0"); @@ -487,14 +496,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - IntervalESBase inv = itv.sliceState(res); + AbstractESBase inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - IntervalESBase resRSY = RSY_time(inv, phi, rs); - IntervalESBase resBilateral = Bilateral_time(inv, phi, rs); - IntervalESBase resBS = BS_time(inv, phi, rs); + AbstractESBase resRSY = RSY_time(inv, phi, rs); + AbstractESBase resBilateral = Bilateral_time(inv, phi, rs); + AbstractESBase resBS = BS_time(inv, phi, rs); // 0:[1,10000] 1:[1,10000] 2:[1,1] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -502,7 +511,7 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 10000)}, + AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 10000)}, {1, IntervalValue(1, 10000)}, {2, IntervalValue(1, 1)}}; } @@ -510,7 +519,7 @@ class SymblicAbstractionTest void testRelExeState3_4() { outs() << "test3_4 start\n"; - IntervalESBase itv; + AbstractESBase itv; RelExeState relation; // var0 := [1, 100000]; relation[0] = getContext().int_const("0"); @@ -527,14 +536,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - IntervalESBase inv = itv.sliceState(res); + AbstractESBase inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - IntervalESBase resRSY = RSY_time(inv, phi, rs); - IntervalESBase resBilateral = Bilateral_time(inv, phi, rs); - IntervalESBase resBS = BS_time(inv, phi, rs); + AbstractESBase resRSY = RSY_time(inv, phi, rs); + AbstractESBase resBilateral = Bilateral_time(inv, phi, rs); + AbstractESBase resBS = BS_time(inv, phi, rs); // 0:[1,100000] 1:[1,100000] 2:[1,1] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -542,17 +551,18 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 100000)}, + AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 100000)}, {1, IntervalValue(1, 100000)}, {2, IntervalValue(1, 1)} }; - assert(IntervalESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert( + AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState4_1() { outs() << "test4_1 start\n"; - IntervalESBase itv; + AbstractESBase itv; RelExeState relation; // var0 := [0, 10]; relation[0] = getContext().int_const("0"); @@ -569,7 +579,7 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - IntervalESBase inv = itv.sliceState(res); + AbstractESBase inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); @@ -578,7 +588,7 @@ class SymblicAbstractionTest outs() << "rsy done\n"; // IntervalExeState resBilateral = rs.bilateral(inv, phi); outs() << "bilateral done\n"; - IntervalESBase resBS = rs.BS(inv, phi); + AbstractESBase resBS = rs.BS(inv, phi); outs() << "bs done\n"; // 0:[0,10] 1:[0,10] 2:[-00,+00] // assert(resRSY == resBS && resBS == resBilateral); @@ -587,11 +597,12 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - IntervalESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10)}, + AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10)}, {1, IntervalValue(0, 10)}, {2, IntervalValue(IntervalValue::minus_infinity(), IntervalValue::plus_infinity())} }; - assert(IntervalESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert( + AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testsValidation() diff --git a/svf/include/AE/Core/IntervalExeState.h b/svf/include/AE/Core/AbstractExeState.h similarity index 83% rename from svf/include/AE/Core/IntervalExeState.h rename to svf/include/AE/Core/AbstractExeState.h index 741dded3d..3c72e3466 100644 --- a/svf/include/AE/Core/IntervalExeState.h +++ b/svf/include/AE/Core/AbstractExeState.h @@ -1,4 +1,4 @@ -//===- IntervalExeState.h ----Interval Domain-------------------------// +//===- AbstractExeState.h ----Interval Domain-------------------------// // // SVF: Static Value-Flow Analysis // @@ -52,7 +52,7 @@ namespace SVF { -class IntervalESBase +class AbstractESBase { friend class SVFIR2ItvExeState; friend class RelationSolver; @@ -63,19 +63,19 @@ class IntervalESBase public: /// default constructor - IntervalESBase() {} + AbstractESBase() {} - IntervalESBase(VarToAbsValMap&_varToValMap, LocToAbsValMap&_locToValMap) : _varToAbsVal(_varToValMap), + AbstractESBase(VarToAbsValMap&_varToValMap, LocToAbsValMap&_locToValMap) : _varToAbsVal(_varToValMap), _locToAbsVal(_locToValMap) {} /// copy constructor - IntervalESBase(const IntervalESBase &rhs) : _varToAbsVal(rhs.getVarToVal()), + AbstractESBase(const AbstractESBase&rhs) : _varToAbsVal(rhs.getVarToVal()), _locToAbsVal(rhs.getLocToVal()) { } - virtual ~IntervalESBase() = default; + virtual ~AbstractESBase() = default; /// The physical address starts with 0x7f...... + idx @@ -101,8 +101,7 @@ class IntervalESBase return getInternalID(addr) == 0; } - - IntervalESBase &operator=(const IntervalESBase &rhs) + AbstractESBase&operator=(const AbstractESBase&rhs) { if (rhs != *this) { @@ -113,14 +112,14 @@ class IntervalESBase } /// move constructor - IntervalESBase(IntervalESBase &&rhs) : _varToAbsVal(std::move(rhs._varToAbsVal)), + AbstractESBase(AbstractESBase&&rhs) : _varToAbsVal(std::move(rhs._varToAbsVal)), _locToAbsVal(std::move(rhs._locToAbsVal)) { } /// operator= move constructor - IntervalESBase &operator=(IntervalESBase &&rhs) + AbstractESBase&operator=(AbstractESBase&&rhs) { if (&rhs != this) { @@ -131,9 +130,9 @@ class IntervalESBase } /// Set all value bottom - IntervalESBase bottom() const + AbstractESBase bottom() const { - IntervalESBase inv = *this; + AbstractESBase inv = *this; for (auto &item: inv._varToAbsVal) { if (item.second.isInterval()) @@ -143,9 +142,9 @@ class IntervalESBase } /// Set all value top - IntervalESBase top() const + AbstractESBase top() const { - IntervalESBase inv = *this; + AbstractESBase inv = *this; for (auto &item: inv._varToAbsVal) { if (item.second.isInterval()) @@ -155,9 +154,9 @@ class IntervalESBase } /// Copy some values and return a new IntervalExeState - IntervalESBase sliceState(Set &sl) + AbstractESBase sliceState(Set &sl) { - IntervalESBase inv; + AbstractESBase inv; for (u32_t id: sl) { inv._varToAbsVal[id] = _varToAbsVal[id]; @@ -166,19 +165,19 @@ class IntervalESBase } protected: - VarToAbsValMap _varToAbsVal; ///< Map a variable (symbol) to its interval value - LocToAbsValMap _locToAbsVal; ///< Map a memory address to its stored interval value + VarToAbsValMap _varToAbsVal; ///< Map a variable (symbol) to its abstract value + LocToAbsValMap _locToAbsVal; ///< Map a memory address to its stored abstract value public: - /// get interval value of variable + /// get abstract value of variable inline virtual AbstractValue &operator[](u32_t varId) { return _varToAbsVal[varId]; } - /// get interval value of variable + /// get abstract value of variable inline virtual const AbstractValue &operator[](u32_t varId) const { return _varToAbsVal.at(varId); @@ -217,7 +216,7 @@ class IntervalESBase return false; } - /// whether the memory address stores interval value + /// whether the memory address stores abstract value inline virtual bool inLocToValTable(u32_t id) const { if (_locToAbsVal.find(id) != _locToAbsVal.end()) { @@ -243,22 +242,22 @@ class IntervalESBase public: /// domain widen with other, and return the widened domain - IntervalESBase widening(const IntervalESBase &other); + AbstractESBase widening(const AbstractESBase&other); /// domain narrow with other, and return the narrowed domain - IntervalESBase narrowing(const IntervalESBase &other); + AbstractESBase narrowing(const AbstractESBase&other); /// domain widen with other, important! other widen this. - void widenWith(const IntervalESBase &other); + void widenWith(const AbstractESBase&other); /// domain join with other, important! other widen this. - void joinWith(const IntervalESBase &other); + void joinWith(const AbstractESBase&other); /// domain narrow with other, important! other widen this. - void narrowWith(const IntervalESBase &other); + void narrowWith(const AbstractESBase&other); /// domain meet with other, important! other widen this. - void meetWith(const IntervalESBase &other); + void meetWith(const AbstractESBase&other); /// Return int value from an expression if it is a numeral, otherwise return an approximate value @@ -268,13 +267,6 @@ class IntervalESBase return (s32_t) e.lb().getNumeral(); } - ///TODO: Create new interval value - IntervalValue createIntervalValue(double lb, double ub, NodeID id) - { - _varToAbsVal[id] = IntervalValue(lb, ub); - return _varToAbsVal[id].getInterval(); - } - /// Return true if map has bottom value inline bool has_bottom() { @@ -335,7 +327,7 @@ class IntervalESBase return ""; } - bool equals(const IntervalESBase &other) const; + bool equals(const AbstractESBase&other) const; static bool eqVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs) { @@ -401,24 +393,24 @@ class IntervalESBase return true; } - bool operator==(const IntervalESBase &rhs) const + bool operator==(const AbstractESBase&rhs) const { return eqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && eqVarToValMap(_locToAbsVal, rhs.getLocToVal()); } - bool operator!=(const IntervalESBase &rhs) const + bool operator!=(const AbstractESBase&rhs) const { return !(*this == rhs); } - bool operator<(const IntervalESBase &rhs) const + bool operator<(const AbstractESBase&rhs) const { return !(*this >= rhs); } - bool operator>=(const IntervalESBase &rhs) const + bool operator>=(const AbstractESBase&rhs) const { return geqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && geqVarToValMap(_locToAbsVal, rhs.getLocToVal()); } @@ -435,47 +427,46 @@ class IntervalESBase }; -class IntervalExeState : public IntervalESBase +class AbstractExeState : public AbstractESBase { friend class SVFIR2ItvExeState; friend class RelationSolver; public: - static IntervalExeState globalES; + static AbstractExeState globalES; public: /// default constructor - IntervalExeState() : IntervalESBase() {} + AbstractExeState() : AbstractESBase() {} - IntervalExeState(VarToAbsValMap&_varToValMap, LocToAbsValMap&_locToValMap) : IntervalESBase(_varToValMap, _locToValMap) {} + AbstractExeState(VarToAbsValMap&_varToValMap, LocToAbsValMap&_locToValMap) : AbstractESBase(_varToValMap, _locToValMap) {} /// copy constructor - IntervalExeState(const IntervalExeState &rhs) : IntervalESBase(rhs) + AbstractExeState(const AbstractExeState&rhs) : AbstractESBase(rhs) { } - virtual ~IntervalExeState() = default; - + virtual ~AbstractExeState() = default; - IntervalExeState &operator=(const IntervalExeState &rhs) + AbstractExeState&operator=(const AbstractExeState&rhs) { - IntervalESBase::operator=(rhs); + AbstractESBase::operator=(rhs); return *this; } virtual void printExprValues(std::ostream &oss) const; /// move constructor - IntervalExeState(IntervalExeState &&rhs) : IntervalESBase(std::move(rhs)) + AbstractExeState(AbstractExeState&&rhs) : AbstractESBase(std::move(rhs)) { } /// operator= move constructor - IntervalExeState &operator=(IntervalExeState &&rhs) + AbstractExeState&operator=(AbstractExeState&&rhs) { - IntervalESBase::operator=(std::move(rhs)); + AbstractESBase::operator=(std::move(rhs)); return *this; } @@ -494,7 +485,7 @@ class IntervalExeState : public IntervalESBase } } - /// get interval value of variable + /// get abstract value of variable inline AbstractValue &operator[](u32_t varId) { auto localIt = _varToAbsVal.find(varId); @@ -578,7 +569,7 @@ class IntervalExeState : public IntervalESBase } } - /// whether the memory address stores interval value + /// whether the memory address stores abstract value inline bool inLocToValTable(u32_t id) const { if (_locToAbsVal.find(id)!= _locToAbsVal.end()) { @@ -635,22 +626,22 @@ class IntervalExeState : public IntervalESBase } /// domain widen with other, and return the widened domain - IntervalExeState widening(const IntervalExeState &other); + AbstractExeState widening(const AbstractExeState&other); /// domain narrow with other, and return the narrowed domain - IntervalExeState narrowing(const IntervalExeState &other); + AbstractExeState narrowing(const AbstractExeState&other); /// domain widen with other, important! other widen this. - void widenWith(const IntervalExeState &other); + void widenWith(const AbstractExeState&other); /// domain join with other, important! other widen this. - void joinWith(const IntervalExeState &other); + void joinWith(const AbstractExeState&other); /// domain narrow with other, important! other widen this. - void narrowWith(const IntervalExeState &other); + void narrowWith(const AbstractExeState&other); /// domain meet with other, important! other widen this. - void meetWith(const IntervalExeState &other); + void meetWith(const AbstractExeState&other); u32_t hash() const; @@ -676,26 +667,26 @@ class IntervalExeState : public IntervalESBase } } - bool equals(const IntervalExeState &other) const; + bool equals(const AbstractExeState&other) const; - bool operator==(const IntervalExeState &rhs) const + bool operator==(const AbstractExeState&rhs) const { return eqVarToValMap(_varToAbsVal, rhs._varToAbsVal) && eqVarToValMap(_locToAbsVal, rhs._locToAbsVal); } - bool operator!=(const IntervalExeState &rhs) const + bool operator!=(const AbstractExeState&rhs) const { return !(*this == rhs); } - bool operator<(const IntervalExeState &rhs) const + bool operator<(const AbstractExeState&rhs) const { return !(*this >= rhs); } - bool operator>=(const IntervalExeState &rhs) const + bool operator>=(const AbstractExeState&rhs) const { return geqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && geqVarToValMap(_locToAbsVal, rhs._locToAbsVal); } @@ -703,9 +694,9 @@ class IntervalExeState : public IntervalESBase } template<> -struct std::hash +struct std::hash { - size_t operator()(const SVF::IntervalExeState &exeState) const + size_t operator()(const SVF::AbstractExeState&exeState) const { return exeState.hash(); } diff --git a/svf/include/AE/Core/ExeState.h b/svf/include/AE/Core/ExeState.h index c42dd2782..60f537f9d 100644 --- a/svf/include/AE/Core/ExeState.h +++ b/svf/include/AE/Core/ExeState.h @@ -39,7 +39,7 @@ namespace SVF { -class IntervalExeState; +class AbstractExeState; /*! * Base execution state diff --git a/svf/include/AE/Core/IntervalValue.h b/svf/include/AE/Core/IntervalValue.h index c7d098ddf..3962fb7d0 100644 --- a/svf/include/AE/Core/IntervalValue.h +++ b/svf/include/AE/Core/IntervalValue.h @@ -1,4 +1,4 @@ -//===- IntervalValue.h ----Interval Value for Interval Domain-------------// +//===- IntervalValue.h ----Interval Value for Abstract Domain-------------// // // SVF: Static Value-Flow Analysis // diff --git a/svf/include/AE/Core/RelationSolver.h b/svf/include/AE/Core/RelationSolver.h index dc71a3e5b..b8b7bbbb1 100644 --- a/svf/include/AE/Core/RelationSolver.h +++ b/svf/include/AE/Core/RelationSolver.h @@ -30,7 +30,7 @@ #ifndef Z3_EXAMPLE_RELATIONSOLVER_H #define Z3_EXAMPLE_RELATIONSOLVER_H -#include "AE/Core/IntervalExeState.h" +#include "AE/Core/AbstractExeState.h" #include "Util/Z3Expr.h" namespace SVF @@ -44,17 +44,17 @@ class RelationSolver IntervalESBase (the last element of inputs) for RSY or bilateral solver */ /// Return Z3Expr according to valToValMap - Z3Expr gamma_hat(const IntervalESBase &exeState) const; + Z3Expr gamma_hat(const AbstractESBase&exeState) const; /// Return Z3Expr according to another valToValMap - Z3Expr gamma_hat(const IntervalESBase &alpha, const IntervalESBase &exeState) const; + Z3Expr gamma_hat(const AbstractESBase&alpha, const AbstractESBase&exeState) const; /// Return Z3Expr from a NodeID - Z3Expr gamma_hat(u32_t id, const IntervalESBase &exeState) const; + Z3Expr gamma_hat(u32_t id, const AbstractESBase&exeState) const; - IntervalESBase abstract_consequence(const IntervalESBase &lower, const IntervalESBase &upper, const IntervalESBase &domain) const; + AbstractESBase abstract_consequence(const AbstractESBase&lower, const AbstractESBase&upper, const AbstractESBase&domain) const; - IntervalESBase beta(const Map &sigma, const IntervalESBase &exeState) const; + AbstractESBase beta(const Map &sigma, const AbstractESBase&exeState) const; /// Return Z3 expression lazily based on SVFVar ID @@ -65,13 +65,13 @@ class RelationSolver /* two optional solvers: RSY and bilateral */ - IntervalESBase bilateral(const IntervalESBase& domain, const Z3Expr &phi, u32_t descend_check = 0); + AbstractESBase bilateral(const AbstractESBase& domain, const Z3Expr &phi, u32_t descend_check = 0); - IntervalESBase RSY(const IntervalESBase& domain, const Z3Expr &phi); + AbstractESBase RSY(const AbstractESBase& domain, const Z3Expr &phi); Map BoxedOptSolver(const Z3Expr& phi, Map& ret, Map& low_values, Map& high_values); - IntervalESBase BS(const IntervalESBase& domain, const Z3Expr &phi); + AbstractESBase BS(const AbstractESBase& domain, const Z3Expr &phi); void updateMap(Map& map, u32_t key, const NumericLiteral& value); diff --git a/svf/include/AE/Svfexe/AbstractExecution.h b/svf/include/AE/Svfexe/AbstractExecution.h index 13beb4d95..c78d9821c 100644 --- a/svf/include/AE/Svfexe/AbstractExecution.h +++ b/svf/include/AE/Svfexe/AbstractExecution.h @@ -154,7 +154,7 @@ class AbstractExecution * @param intraEdge the edge from CmpStmt to the next node * @return if this edge is feasible */ - bool hasBranchES(const IntraCFGEdge* intraEdge, IntervalExeState& es); + bool hasBranchES(const IntraCFGEdge* intraEdge, AbstractExeState& es); /** * handle instructions in ICFGNode @@ -219,7 +219,8 @@ class AbstractExecution * @param succ the value of cmpStmt (True or False) * @return if this ICFGNode has preceding execution state */ - bool hasCmpBranchES(const CmpStmt* cmpStmt, s64_t succ, IntervalExeState& es); + bool hasCmpBranchES(const CmpStmt* cmpStmt, s64_t succ, + AbstractExeState& es); /** * Check if this SwitchInst and succ are satisfiable to the execution state. @@ -228,7 +229,7 @@ class AbstractExecution * @param succ the case value of switch inst * @return if this ICFGNode has preceding execution state */ - bool hasSwitchBranchES(const SVFVar* var, s64_t succ, IntervalExeState& es); + bool hasSwitchBranchES(const SVFVar* var, s64_t succ, AbstractExeState& es); /** @@ -372,9 +373,9 @@ class AbstractExecution // helper functions in handleCycle bool widenFixpointPass(const ICFGNode* cycle_head, - IntervalExeState& pre_es); + AbstractExeState& pre_es); bool narrowFixpointPass(const ICFGNode* cycle_head, - IntervalExeState& pre_es); + AbstractExeState& pre_es); protected: // there data should be shared with subclasses @@ -383,8 +384,8 @@ class AbstractExecution Set _checkpoint_names; private: - Map _preES; - Map _postES; + Map _preES; + Map _postES; std::string _moduleName; }; } \ No newline at end of file diff --git a/svf/include/AE/Svfexe/SVFIR2ItvExeState.h b/svf/include/AE/Svfexe/SVFIR2ItvExeState.h index 1833a5d86..7f6af8df6 100644 --- a/svf/include/AE/Svfexe/SVFIR2ItvExeState.h +++ b/svf/include/AE/Svfexe/SVFIR2ItvExeState.h @@ -33,8 +33,8 @@ #ifndef Z3_EXAMPLE_SVFIR2ITVEXESTATE_H #define Z3_EXAMPLE_SVFIR2ITVEXESTATE_H +#include "AE/Core/AbstractExeState.h" #include "AE/Core/ExeState.h" -#include "AE/Core/IntervalExeState.h" #include "AE/Core/RelExeState.h" #include "SVFIR/SVFIR.h" @@ -47,12 +47,12 @@ class SVFIR2ItvExeState public: SVFIR2ItvExeState(SVFIR *ir) : _svfir(ir) {} - void setEs(const IntervalExeState &es) + void setEs(const AbstractExeState&es) { _es = es; } - IntervalExeState &getEs() + AbstractExeState&getEs() { return _es; } @@ -67,9 +67,9 @@ class SVFIR2ItvExeState return _relEs; } - void widenAddrs(IntervalExeState &lhs, const IntervalExeState &rhs); + void widenAddrs(AbstractExeState&lhs, const AbstractExeState&rhs); - void narrowAddrs(IntervalExeState &lhs, const IntervalExeState &rhs); + void narrowAddrs(AbstractExeState&lhs, const AbstractExeState&rhs); /// Return the field address given a pointer points to a struct object and an offset AbstractValue getGepObjAddress(u32_t pointer, APOffset offset); @@ -102,7 +102,7 @@ class SVFIR2ItvExeState return Z3Expr::getContext(); } - void applySummary(IntervalExeState &es); + void applySummary(AbstractExeState&es); /// Init ObjVar @@ -209,10 +209,10 @@ class SVFIR2ItvExeState private: SVFIR *_svfir; - IntervalExeState _es; + AbstractExeState _es; RelExeState _relEs; - Map _br_cond; + Map _br_cond; AbstractValue getZExtValue(const SVFVar* var, const SVFType*); }; } diff --git a/svf/lib/AE/Core/IntervalExeState.cpp b/svf/lib/AE/Core/AbstractExeState.cpp similarity index 86% rename from svf/lib/AE/Core/IntervalExeState.cpp rename to svf/lib/AE/Core/AbstractExeState.cpp index abf29073a..8a21a1f4f 100644 --- a/svf/lib/AE/Core/IntervalExeState.cpp +++ b/svf/lib/AE/Core/AbstractExeState.cpp @@ -20,25 +20,25 @@ // //===----------------------------------------------------------------------===// /* - * IntervalExeState.cpp + * AbstractExeState.cpp * * Created on: Jul 9, 2022 * Author: Xiao Cheng, Jiawei Wang * */ -#include "AE/Core/IntervalExeState.h" +#include "AE/Core/AbstractExeState.h" #include "Util/SVFUtil.h" using namespace SVF; using namespace SVFUtil; -bool IntervalESBase::equals(const IntervalESBase &other) const +bool AbstractESBase::equals(const AbstractESBase&other) const { return *this == other; } -u32_t IntervalESBase::hash() const +u32_t AbstractESBase::hash() const { size_t h = getVarToVal().size() * 2; Hash hf; @@ -55,10 +55,10 @@ u32_t IntervalESBase::hash() const return pairH({h, h2}); } -IntervalESBase IntervalESBase::widening(const IntervalESBase& other) +AbstractESBase AbstractESBase::widening(const AbstractESBase& other) { // widen interval - IntervalESBase es = *this; + AbstractESBase es = *this; for (auto it = es._varToAbsVal.begin(); it != es._varToAbsVal.end(); ++it) { auto key = it->first; @@ -77,9 +77,9 @@ IntervalESBase IntervalESBase::widening(const IntervalESBase& other) return es; } -IntervalESBase IntervalESBase::narrowing(const IntervalESBase& other) +AbstractESBase AbstractESBase::narrowing(const AbstractESBase& other) { - IntervalESBase es = *this; + AbstractESBase es = *this; for (auto it = es._varToAbsVal.begin(); it != es._varToAbsVal.end(); ++it) { auto key = it->first; @@ -97,7 +97,7 @@ IntervalESBase IntervalESBase::narrowing(const IntervalESBase& other) } /// domain widen with other, important! other widen this. -void IntervalESBase::widenWith(const IntervalESBase& other) +void AbstractESBase::widenWith(const AbstractESBase& other) { for (auto it = _varToAbsVal.begin(); it != _varToAbsVal.end(); ++it) { @@ -116,7 +116,7 @@ void IntervalESBase::widenWith(const IntervalESBase& other) } /// domain join with other, important! other widen this. -void IntervalESBase::joinWith(const IntervalESBase& other) +void AbstractESBase::joinWith(const AbstractESBase& other) { for (auto it = other._varToAbsVal.begin(); it != other._varToAbsVal.end(); ++it) { @@ -165,7 +165,7 @@ void IntervalESBase::joinWith(const IntervalESBase& other) } /// domain narrow with other, important! other widen this. -void IntervalESBase::narrowWith(const IntervalESBase& other) +void AbstractESBase::narrowWith(const AbstractESBase& other) { for (auto it = _varToAbsVal.begin(); it != _varToAbsVal.end(); ++it) { @@ -186,7 +186,7 @@ void IntervalESBase::narrowWith(const IntervalESBase& other) } /// domain meet with other, important! other widen this. -void IntervalESBase::meetWith(const IntervalESBase& other) +void AbstractESBase::meetWith(const AbstractESBase& other) { for (auto it = other._varToAbsVal.begin(); it != other._varToAbsVal.end(); ++it) { @@ -227,7 +227,7 @@ void IntervalESBase::meetWith(const IntervalESBase& other) } /// Print values of all expressions -void IntervalESBase::printExprValues(std::ostream &oss) const +void AbstractESBase::printExprValues(std::ostream &oss) const { oss << "-----------Var and Value-----------\n"; printTable(_varToAbsVal, oss); @@ -235,7 +235,7 @@ void IntervalESBase::printExprValues(std::ostream &oss) const oss << "-----------------------------------------\n"; } -void IntervalESBase::printTable(const VarToAbsValMap&table, std::ostream &oss) const +void AbstractESBase::printTable(const VarToAbsValMap&table, std::ostream &oss) const { oss.flags(std::ios::left); std::set ordered; @@ -258,20 +258,20 @@ void IntervalESBase::printTable(const VarToAbsValMap&table, std::ostream &oss) c } } -IntervalExeState IntervalExeState::globalES; -bool IntervalExeState::equals(const IntervalExeState &other) const +AbstractExeState AbstractExeState::globalES; +bool AbstractExeState::equals(const AbstractExeState&other) const { return *this == other; } -u32_t IntervalExeState::hash() const +u32_t AbstractExeState::hash() const { - return IntervalESBase::hash(); + return AbstractESBase::hash(); } -IntervalExeState IntervalExeState::widening(const IntervalExeState& other) +AbstractExeState AbstractExeState::widening(const AbstractExeState& other) { - IntervalExeState es = *this; + AbstractExeState es = *this; for (auto it = es._varToAbsVal.begin(); it != es._varToAbsVal.end(); ++it) { auto key = it->first; @@ -289,9 +289,9 @@ IntervalExeState IntervalExeState::widening(const IntervalExeState& other) return es; } -IntervalExeState IntervalExeState::narrowing(const IntervalExeState& other) +AbstractExeState AbstractExeState::narrowing(const AbstractExeState& other) { - IntervalExeState es = *this; + AbstractExeState es = *this; for (auto it = es._varToAbsVal.begin(); it != es._varToAbsVal.end(); ++it) { auto key = it->first; @@ -311,32 +311,32 @@ IntervalExeState IntervalExeState::narrowing(const IntervalExeState& other) } /// domain widen with other, important! other widen this. -void IntervalExeState::widenWith(const IntervalExeState& other) +void AbstractExeState::widenWith(const AbstractExeState& other) { - IntervalESBase::widenWith(other); + AbstractESBase::widenWith(other); } /// domain join with other, important! other widen this. -void IntervalExeState::joinWith(const IntervalExeState& other) +void AbstractExeState::joinWith(const AbstractExeState& other) { - IntervalESBase::joinWith(other); + AbstractESBase::joinWith(other); } /// domain narrow with other, important! other widen this. -void IntervalExeState::narrowWith(const IntervalExeState& other) +void AbstractExeState::narrowWith(const AbstractExeState& other) { - IntervalESBase::narrowWith(other); + AbstractESBase::narrowWith(other); } /// domain meet with other, important! other widen this. -void IntervalExeState::meetWith(const IntervalExeState& other) +void AbstractExeState::meetWith(const AbstractExeState& other) { - IntervalESBase::meetWith(other); + AbstractESBase::meetWith(other); } /// Print values of all expressions -void IntervalExeState::printExprValues(std::ostream &oss) const +void AbstractExeState::printExprValues(std::ostream &oss) const { oss << "-----------Var and Value-----------\n"; printTable(_varToAbsVal, oss); diff --git a/svf/lib/AE/Core/ExeState.cpp b/svf/lib/AE/Core/ExeState.cpp index b74ed1149..5f53335bc 100644 --- a/svf/lib/AE/Core/ExeState.cpp +++ b/svf/lib/AE/Core/ExeState.cpp @@ -28,7 +28,7 @@ */ #include "AE/Core/ExeState.h" -#include "AE/Core/IntervalExeState.h" +#include "AE/Core/AbstractExeState.h" using namespace SVF; diff --git a/svf/lib/AE/Core/RelationSolver.cpp b/svf/lib/AE/Core/RelationSolver.cpp index d279f8ca1..7f1f4b8ae 100644 --- a/svf/lib/AE/Core/RelationSolver.cpp +++ b/svf/lib/AE/Core/RelationSolver.cpp @@ -33,19 +33,19 @@ using namespace SVF; using namespace SVFUtil; -IntervalESBase RelationSolver::bilateral(const IntervalESBase &domain, const Z3Expr& phi, +AbstractESBase RelationSolver::bilateral(const AbstractESBase&domain, const Z3Expr& phi, u32_t descend_check) { /// init variables - IntervalESBase upper = domain.top(); - IntervalESBase lower = domain.bottom(); + AbstractESBase upper = domain.top(); + AbstractESBase lower = domain.bottom(); u32_t meets_in_a_row = 0; z3::solver solver = Z3Expr::getSolver(); z3::params p(Z3Expr::getContext()); /// TODO: add option for timeout p.set(":timeout", static_cast(600)); // in milliseconds solver.set(p); - IntervalESBase consequence; + AbstractESBase consequence; /// start processing while (lower != upper) @@ -85,9 +85,9 @@ IntervalESBase RelationSolver::bilateral(const IntervalESBase &domain, const Z3E } } solver.pop(); - IntervalESBase newLower = domain.bottom(); + AbstractESBase newLower = domain.bottom(); newLower.joinWith(lower); - IntervalESBase rhs = beta(solution, domain); + AbstractESBase rhs = beta(solution, domain); newLower.joinWith(rhs); lower = newLower; meets_in_a_row = 0; @@ -101,7 +101,7 @@ IntervalESBase RelationSolver::bilateral(const IntervalESBase &domain, const Z3E if (solver.reason_unknown() == "timeout") return upper; } - IntervalESBase newUpper = domain.top(); + AbstractESBase newUpper = domain.top(); newUpper.meetWith(upper); newUpper.meetWith(consequence); upper = newUpper; @@ -111,9 +111,9 @@ IntervalESBase RelationSolver::bilateral(const IntervalESBase &domain, const Z3E return upper; } -IntervalESBase RelationSolver::RSY(const IntervalESBase& domain, const Z3Expr& phi) +AbstractESBase RelationSolver::RSY(const AbstractESBase& domain, const Z3Expr& phi) { - IntervalESBase lower = domain.bottom(); + AbstractESBase lower = domain.bottom(); z3::solver& solver = Z3Expr::getSolver(); z3::params p(Z3Expr::getContext()); /// TODO: add option for timeout @@ -147,7 +147,7 @@ IntervalESBase RelationSolver::RSY(const IntervalESBase& domain, const Z3Expr& p } } solver.pop(); - IntervalESBase newLower = domain.bottom(); + AbstractESBase newLower = domain.bottom(); newLower.joinWith(lower); newLower.joinWith(beta(solution, domain)); lower = newLower; @@ -167,8 +167,8 @@ IntervalESBase RelationSolver::RSY(const IntervalESBase& domain, const Z3Expr& p return lower; } -IntervalESBase RelationSolver::abstract_consequence( - const IntervalESBase& lower, const IntervalESBase& upper, const IntervalESBase& domain) const +AbstractESBase RelationSolver::abstract_consequence( + const AbstractESBase& lower, const AbstractESBase& upper, const AbstractESBase& domain) const { /*Returns the "abstract consequence" of lower and upper. @@ -184,7 +184,7 @@ IntervalESBase RelationSolver::abstract_consequence( it != domain.getVarToVal().end(); ++it) /// for variable in self.variables: { - IntervalESBase proposed = domain.top(); /// proposed = self.top.copy() + AbstractESBase proposed = domain.top(); /// proposed = self.top.copy() proposed[it->first] = lower[it->first].getInterval(); /// proposed.set_interval(variable, lower.interval_of(variable)) /// proposed._locToItvVal @@ -196,7 +196,7 @@ IntervalESBase RelationSolver::abstract_consequence( return lower; /// return lower.copy() } -Z3Expr RelationSolver::gamma_hat(const IntervalESBase& exeState) const +Z3Expr RelationSolver::gamma_hat(const AbstractESBase& exeState) const { Z3Expr res(Z3Expr::getContext().bool_val(true)); for (auto& item : exeState.getVarToVal()) @@ -212,8 +212,8 @@ Z3Expr RelationSolver::gamma_hat(const IntervalESBase& exeState) const return res; } -Z3Expr RelationSolver::gamma_hat(const IntervalESBase& alpha, - const IntervalESBase& exeState) const +Z3Expr RelationSolver::gamma_hat(const AbstractESBase& alpha, + const AbstractESBase& exeState) const { Z3Expr res(Z3Expr::getContext().bool_val(true)); for (auto& item : exeState.getVarToVal()) @@ -230,7 +230,7 @@ Z3Expr RelationSolver::gamma_hat(const IntervalESBase& alpha, return res; } -Z3Expr RelationSolver::gamma_hat(u32_t id, const IntervalESBase& exeState) const +Z3Expr RelationSolver::gamma_hat(u32_t id, const AbstractESBase& exeState) const { auto it = exeState.getVarToVal().find(id); assert(it != exeState.getVarToVal().end() && "id not in varToVal?"); @@ -241,10 +241,10 @@ Z3Expr RelationSolver::gamma_hat(u32_t id, const IntervalESBase& exeState) const return res; } -IntervalESBase RelationSolver::beta(const Map& sigma, - const IntervalESBase& exeState) const +AbstractESBase RelationSolver::beta(const Map& sigma, + const AbstractESBase& exeState) const { - IntervalESBase res; + AbstractESBase res; for (const auto& item : exeState.getVarToVal()) { res[item.first] = IntervalValue( @@ -266,7 +266,7 @@ void RelationSolver::updateMap(Map& map, u32_t key, const } } -IntervalESBase RelationSolver::BS(const IntervalESBase& domain, const Z3Expr &phi) +AbstractESBase RelationSolver::BS(const AbstractESBase& domain, const Z3Expr &phi) { /// because key of _varToItvVal is u32_t, -key may out of range for int /// so we do key + bias for -key @@ -312,7 +312,7 @@ IntervalESBase RelationSolver::BS(const IntervalESBase& domain, const Z3Expr &ph /// optimize each object BoxedOptSolver(new_phi.simplify(), ret, low_values, high_values); /// fill in the return values - IntervalESBase retInv; + AbstractESBase retInv; for (const auto& item: ret) { if (item.first >= bias) diff --git a/svf/lib/AE/Svfexe/AbstractExecution.cpp b/svf/lib/AE/Svfexe/AbstractExecution.cpp index 9ac0000b9..0dbc2806f 100644 --- a/svf/lib/AE/Svfexe/AbstractExecution.cpp +++ b/svf/lib/AE/Svfexe/AbstractExecution.cpp @@ -162,7 +162,7 @@ void AbstractExecution::analyse() /// handle global node void AbstractExecution::handleGlobalNode() { - IntervalExeState es; + AbstractExeState es; const ICFGNode* node = _icfg->getGlobalICFGNode(); _svfir2ExeState->setEs(es); // Global Node, we just need to handle addr, load, store, copy and gep @@ -181,13 +181,13 @@ bool AbstractExecution::hasInEdgesES(const ICFGNode *block) { if (isGlobalEntry(block)) { - _preES[block] = IntervalExeState(); + _preES[block] = AbstractExeState(); return true; } // is common basic block else { - IntervalExeState es; + AbstractExeState es; u32_t inEdgeNum = 0; for (auto& edge: block->getInEdges()) { @@ -196,7 +196,7 @@ bool AbstractExecution::hasInEdgesES(const ICFGNode *block) const IntraCFGEdge *intraCfgEdge = SVFUtil::dyn_cast(edge); if (intraCfgEdge && intraCfgEdge->getCondition()) { - IntervalExeState tmpEs = _postES[edge->getSrcNode()]; + AbstractExeState tmpEs = _postES[edge->getSrcNode()]; if (hasBranchES(intraCfgEdge, tmpEs)) { es.joinWith(tmpEs); @@ -255,9 +255,10 @@ bool AbstractExecution::isGlobalEntry(const SVF::ICFGNode *block) return false; } -bool AbstractExecution::hasCmpBranchES(const CmpStmt* cmpStmt, s64_t succ, IntervalExeState& es) +bool AbstractExecution::hasCmpBranchES(const CmpStmt* cmpStmt, s64_t succ, + AbstractExeState& es) { - IntervalExeState new_es = es; + AbstractExeState new_es = es; // get cmp stmt's op0, op1, and predicate NodeID op0 = cmpStmt->getOpVarID(0); NodeID op1 = cmpStmt->getOpVarID(1); @@ -485,9 +486,10 @@ bool AbstractExecution::hasCmpBranchES(const CmpStmt* cmpStmt, s64_t succ, Inter return true; } -bool AbstractExecution::hasSwitchBranchES(const SVFVar* var, s64_t succ, IntervalExeState& es) +bool AbstractExecution::hasSwitchBranchES(const SVFVar* var, s64_t succ, + AbstractExeState& es) { - IntervalExeState new_es = es; + AbstractExeState new_es = es; new_es.cpyItvToLocal(var->getId()); IntervalValue& switch_cond = new_es[var->getId()].getInterval(); s64_t value = succ; @@ -529,7 +531,8 @@ bool AbstractExecution::hasSwitchBranchES(const SVFVar* var, s64_t succ, Interva return true; } -bool AbstractExecution::hasBranchES(const IntraCFGEdge* intraEdge, IntervalExeState& es) +bool AbstractExecution::hasBranchES(const IntraCFGEdge* intraEdge, + AbstractExeState& es) { const SVFValue *cond = intraEdge->getCondition(); NodeID cmpID = _svfir->getValueNode(cond); @@ -660,7 +663,7 @@ bool AbstractExecution::isDirectCall(const SVF::CallICFGNode *callNode) void AbstractExecution::directCallFunPass(const SVF::CallICFGNode *callNode) { const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite()); - IntervalExeState preES = _svfir2ExeState->getEs(); + AbstractExeState preES = _svfir2ExeState->getEs(); _callSiteStack.push_back(callNode); _postES[callNode] = _svfir2ExeState->getEs(); @@ -693,7 +696,7 @@ void AbstractExecution::indirectCallFunPass(const SVF::CallICFGNode *callNode) const SVFFunction *callfun = SVFUtil::dyn_cast(func_var->getValue()); if (callfun) { - IntervalExeState preES = _svfir2ExeState->getEs(); + AbstractExeState preES = _svfir2ExeState->getEs(); _callSiteStack.push_back(callNode); _postES[callNode] = _svfir2ExeState->getEs(); @@ -737,7 +740,7 @@ void AbstractExecution::handleCycle(const ICFGWTOCycle *cycle) // No ES on the in edges - Infeasible block return; } - IntervalExeState pre_es = _preES[cycle->head()]; + AbstractExeState pre_es = _preES[cycle->head()]; // set -widen-delay s32_t widen_delay = Options::WidenDelay(); bool incresing = true; @@ -794,11 +797,12 @@ void AbstractExecution::handleCycle(const ICFGWTOCycle *cycle) } } -bool AbstractExecution::widenFixpointPass(const ICFGNode* cycle_head, IntervalExeState& pre_es) +bool AbstractExecution::widenFixpointPass(const ICFGNode* cycle_head, + AbstractExeState& pre_es) { // increasing iterations - IntervalExeState new_pre_es = pre_es.widening(_postES[cycle_head]); - IntervalExeState new_pre_vaddr_es = new_pre_es; + AbstractExeState new_pre_es = pre_es.widening(_postES[cycle_head]); + AbstractExeState new_pre_vaddr_es = new_pre_es; _svfir2ExeState->widenAddrs(new_pre_es, _postES[cycle_head]); if (pre_es >= new_pre_es) @@ -816,11 +820,11 @@ bool AbstractExecution::widenFixpointPass(const ICFGNode* cycle_head, IntervalEx } } -bool AbstractExecution::narrowFixpointPass(const SVF::ICFGNode *cycle_head, SVF::IntervalExeState &pre_es) +bool AbstractExecution::narrowFixpointPass(const SVF::ICFGNode *cycle_head, SVF::AbstractExeState&pre_es) { // decreasing iterations - IntervalExeState new_pre_es = pre_es.narrowing(_postES[cycle_head]); - IntervalExeState new_pre_vaddr_es = new_pre_es; + AbstractExeState new_pre_es = pre_es.narrowing(_postES[cycle_head]); + AbstractExeState new_pre_vaddr_es = new_pre_es; _svfir2ExeState->narrowAddrs(new_pre_es, _postES[cycle_head]); if (new_pre_es >= pre_es) { @@ -930,7 +934,7 @@ void AbstractExecution::SkipRecursiveCall(const CallICFGNode *callNode) { if (const RetPE *retPE = SVFUtil::dyn_cast(*retNode->getSVFStmts().begin())) { - IntervalExeState es; + AbstractExeState es; if (!retPE->getLHSVar()->isPointer() && !retPE->getLHSVar()->isConstDataOrAggDataButNotNullPtr()) _svfir2ExeState->getEs()[retPE->getLHSVarID()] = IntervalValue::top(); } @@ -966,7 +970,7 @@ void AbstractExecution::SkipRecursiveFunc(const SVFFunction *func) { const SVFVar *rhsVar = store->getRHSVar(); u32_t lhs = store->getLHSVarID(); - IntervalExeState &curES = _svfir2ExeState->getEs(); + AbstractExeState&curES = _svfir2ExeState->getEs(); if (curES.inVarToAddrsTable(lhs)) { if (!rhsVar->isPointer() && !rhsVar->isConstDataOrAggDataButNotNullPtr()) @@ -989,8 +993,10 @@ void AEStat::countStateSize() { if (count == 0) { - generalNumMap["Global_ES_Var_AVG_Num"] = IntervalExeState::globalES.getVarToVal().size(); - generalNumMap["Global_ES_Loc_AVG_Num"] = IntervalExeState::globalES.getLocToVal().size(); + generalNumMap["Global_ES_Var_AVG_Num"] = + AbstractExeState::globalES.getVarToVal().size(); + generalNumMap["Global_ES_Loc_AVG_Num"] = + AbstractExeState::globalES.getLocToVal().size(); generalNumMap["ES_Var_AVG_Num"] = 0; generalNumMap["ES_Loc_AVG_Num"] = 0; generalNumMap["ES_Var_Addr_AVG_Num"] = 0; @@ -1107,8 +1113,8 @@ void AbstractExecution::initExtFunMap() { #define SSE_FUNC_PROCESS(LLVM_NAME ,FUNC_NAME) \ auto sse_##FUNC_NAME = [this](const CallSite &cs) { \ - /* run real ext function */ \ - IntervalExeState &es = _svfir2ExeState->getEs(); \ + /* run real ext function */ \ + AbstractExeState&es = _svfir2ExeState->getEs(); \ u32_t rhs_id = _svfir->getValueNode(cs.getArgument(0)); \ if (!es.inVarToValTable(rhs_id)) return; \ u32_t rhs = _svfir2ExeState->getEs()[rhs_id].getInterval().lb().getIntNumeral(); \ @@ -1143,7 +1149,7 @@ void AbstractExecution::initExtFunMap() const CallICFGNode* callNode = SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); _checkpoints.erase(callNode); u32_t arg0 = _svfir->getValueNode(cs.getArgument(0)); - IntervalExeState &es = _svfir2ExeState->getEs(); + AbstractExeState&es = _svfir2ExeState->getEs(); es[arg0].getInterval().meet_with(IntervalValue(1, 1)); if (es[arg0].getInterval().equals(IntervalValue(1, 1))) { @@ -1161,7 +1167,7 @@ void AbstractExecution::initExtFunMap() auto svf_print = [&](const CallSite &cs) { if (cs.arg_size() < 2) return; - IntervalExeState &es = _svfir2ExeState->getEs(); + AbstractExeState&es = _svfir2ExeState->getEs(); u32_t num_id = _svfir->getValueNode(cs.getArgument(0)); std::string text = strRead(cs.getArgument(1)); assert(es.inVarToValTable(num_id) && "print() should pass integer"); @@ -1178,7 +1184,7 @@ void AbstractExecution::initExtFunMap() std::string AbstractExecution::strRead(const SVFValue* rhs) { // sse read string nodeID->string - IntervalExeState &es = _svfir2ExeState->getEs(); + AbstractExeState&es = _svfir2ExeState->getEs(); std::string str0; for (u32_t index = 0; index < Options::MaxFieldLimit(); index++) @@ -1489,7 +1495,7 @@ AbstractValue AbstractExecution::traceMemoryAllocationSize(const SVFValue *value AbstractValue AbstractExecution::getStrlen(const SVF::SVFValue *strValue) { - IntervalExeState &es = _svfir2ExeState->getEs(); + AbstractExeState&es = _svfir2ExeState->getEs(); AbstractValue dst_size = traceMemoryAllocationSize(strValue); u32_t len = 0; NodeID dstid = _svfir->getValueNode(strValue); @@ -1582,7 +1588,7 @@ void AbstractExecution::handleStrcat(const SVF::CallICFGNode *call) void AbstractExecution::handleMemcpy(const SVF::SVFValue *dst, const SVF::SVFValue *src, AbstractValue len, u32_t start_idx) { - IntervalExeState &es = _svfir2ExeState->getEs(); + AbstractExeState&es = _svfir2ExeState->getEs(); u32_t dstId = _svfir->getValueNode(dst); // pts(dstId) = {objid} objbar objtypeinfo->getType(). u32_t srcId = _svfir->getValueNode(src); u32_t elemSize = 1; @@ -1657,7 +1663,7 @@ const SVFType* AbstractExecution::getPointeeElement(NodeID id) void AbstractExecution::handleMemset(const SVF::SVFValue *dst, AbstractValue elem, AbstractValue len) { - IntervalExeState &es = _svfir2ExeState->getEs(); + AbstractExeState&es = _svfir2ExeState->getEs(); u32_t dstId = _svfir->getValueNode(dst); u32_t size = std::min((u32_t)Options::MaxFieldLimit(), (u32_t) len.lb().getIntNumeral()); u32_t elemSize = 1; diff --git a/svf/lib/AE/Svfexe/BufOverflowChecker.cpp b/svf/lib/AE/Svfexe/BufOverflowChecker.cpp index 43fcf6f62..cd75a37dd 100644 --- a/svf/lib/AE/Svfexe/BufOverflowChecker.cpp +++ b/svf/lib/AE/Svfexe/BufOverflowChecker.cpp @@ -138,7 +138,7 @@ void BufOverflowChecker::initExtFunMap() { //scanf("%d", &data); if (cs.arg_size() < 2) return; - IntervalExeState &es = _svfir2ExeState->getEs(); + AbstractExeState&es = _svfir2ExeState->getEs(); u32_t dst_id = _svfir->getValueNode(cs.getArgument(1)); if (!_svfir2ExeState->inVarToAddrsTable(dst_id)) { @@ -161,7 +161,7 @@ void BufOverflowChecker::initExtFunMap() { //fscanf(stdin, "%d", &data); if (cs.arg_size() < 3) return; - IntervalExeState &es = _svfir2ExeState->getEs(); + AbstractExeState&es = _svfir2ExeState->getEs(); u32_t dst_id = _svfir->getValueNode(cs.getArgument(2)); if (!_svfir2ExeState->inVarToAddrsTable(dst_id)) { @@ -193,7 +193,7 @@ void BufOverflowChecker::initExtFunMap() auto sse_fread = [&](const CallSite &cs) { if (cs.arg_size() < 3) return; - IntervalExeState &es = _svfir2ExeState->getEs(); + AbstractExeState&es = _svfir2ExeState->getEs(); u32_t block_count_id = _svfir->getValueNode(cs.getArgument(2)); u32_t block_size_id = _svfir->getValueNode(cs.getArgument(1)); AbstractValue block_count = es[block_count_id]; @@ -211,7 +211,7 @@ void BufOverflowChecker::initExtFunMap() auto sse_snprintf = [&](const CallSite &cs) { if (cs.arg_size() < 2) return; - IntervalExeState &es = _svfir2ExeState->getEs(); + AbstractExeState&es = _svfir2ExeState->getEs(); u32_t size_id = _svfir->getValueNode(cs.getArgument(1)); u32_t dst_id = _svfir->getValueNode(cs.getArgument(0)); // get elem size of arg2 @@ -260,7 +260,7 @@ void BufOverflowChecker::initExtFunMap() // itoa(num, ch, 10); // num: int, ch: char*, 10 is decimal if (cs.arg_size() < 3) return; - IntervalExeState &es = _svfir2ExeState->getEs(); + AbstractExeState&es = _svfir2ExeState->getEs(); u32_t num_id = _svfir->getValueNode(cs.getArgument(0)); u32_t num = (u32_t) es[num_id].getInterval().getNumeral(); @@ -275,7 +275,7 @@ void BufOverflowChecker::initExtFunMap() // check the arg size if (cs.arg_size() < 1) return; const SVFValue* strValue = cs.getArgument(0); - IntervalExeState &es = _svfir2ExeState->getEs(); + AbstractExeState&es = _svfir2ExeState->getEs(); AbstractValue dst_size = getStrlen(strValue); u32_t elemSize = 1; if (strValue->getType()->isArrayTy()) @@ -299,7 +299,7 @@ void BufOverflowChecker::initExtFunMap() { // recv(sockfd, buf, len, flags); if (cs.arg_size() < 4) return; - IntervalExeState &es = _svfir2ExeState->getEs(); + AbstractExeState&es = _svfir2ExeState->getEs(); u32_t len_id = _svfir->getValueNode(cs.getArgument(2)); AbstractValue len = es[len_id] - IntervalValue(1); u32_t lhsId = _svfir->getValueNode(cs.getInstruction()); @@ -314,7 +314,7 @@ void BufOverflowChecker::initExtFunMap() _checkpoints.erase(callNode); //void SAFE_BUFACCESS(void* data, int size); if (cs.arg_size() < 2) return; - IntervalExeState &es = _svfir2ExeState->getEs(); + AbstractExeState&es = _svfir2ExeState->getEs(); u32_t size_id = _svfir->getValueNode(cs.getArgument(1)); AbstractValue val = es[size_id]; if (val.isBottom()) @@ -344,7 +344,7 @@ void BufOverflowChecker::initExtFunMap() _checkpoints.erase(callNode); //void UNSAFE_BUFACCESS(void* data, int size); if (cs.arg_size() < 2) return; - IntervalExeState &es = _svfir2ExeState->getEs(); + AbstractExeState&es = _svfir2ExeState->getEs(); u32_t size_id = _svfir->getValueNode(cs.getArgument(1)); AbstractValue val = es[size_id]; if (val.isBottom()) diff --git a/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp b/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp index acea11ca1..ffa078b9e 100644 --- a/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp +++ b/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp @@ -271,7 +271,7 @@ AbstractValue SVFIR2ItvExeState::getFPTruncValue(const SVF::SVFVar* var, const S return _es[var->getId()].getInterval(); } -void SVFIR2ItvExeState::applySummary(IntervalExeState &es) +void SVFIR2ItvExeState::applySummary(AbstractExeState&es) { for (const auto &item: es._varToAbsVal) { @@ -287,20 +287,20 @@ void SVFIR2ItvExeState::moveToGlobal() { for (const auto &it: _es._varToAbsVal) { - IntervalExeState::globalES._varToAbsVal.insert(it); + AbstractExeState::globalES._varToAbsVal.insert(it); } for (const auto &it: _es._locToAbsVal) { - IntervalExeState::globalES._locToAbsVal.insert(it); + AbstractExeState::globalES._locToAbsVal.insert(it); } _es._varToAbsVal.clear(); - IntervalExeState::globalES._varToAbsVal.erase(PAG::getPAG()->getBlkPtr()); + AbstractExeState::globalES._varToAbsVal.erase(PAG::getPAG()->getBlkPtr()); _es._varToAbsVal[PAG::getPAG()->getBlkPtr()] = IntervalValue::top(); _es._locToAbsVal.clear(); } -void SVFIR2ItvExeState::widenAddrs(IntervalExeState &lhs, const IntervalExeState &rhs) +void SVFIR2ItvExeState::widenAddrs(AbstractExeState&lhs, const AbstractExeState&rhs) { for (const auto &rhsItem: rhs._varToAbsVal) { @@ -345,7 +345,7 @@ void SVFIR2ItvExeState::widenAddrs(IntervalExeState &lhs, const IntervalExeState } } -void SVFIR2ItvExeState::narrowAddrs(IntervalExeState &lhs, const IntervalExeState &rhs) +void SVFIR2ItvExeState::narrowAddrs(AbstractExeState&lhs, const AbstractExeState&rhs) { for (const auto &rhsItem: rhs._varToAbsVal) { @@ -585,26 +585,26 @@ void SVFIR2ItvExeState::initObjVar(const ObjVar *objVar, u32_t varId) if (const SVFConstantInt *consInt = SVFUtil::dyn_cast(obj->getValue())) { s64_t numeral = consInt->getSExtValue(); - IntervalExeState::globalES[varId] = IntervalValue(numeral, numeral); + AbstractExeState::globalES[varId] = IntervalValue(numeral, numeral); } else if (const SVFConstantFP* consFP = SVFUtil::dyn_cast(obj->getValue())) - IntervalExeState::globalES[varId] = IntervalValue(consFP->getFPValue(), consFP->getFPValue()); + AbstractExeState::globalES[varId] = IntervalValue(consFP->getFPValue(), consFP->getFPValue()); else if (SVFUtil::isa(obj->getValue())) - IntervalExeState::globalES[varId] = IntervalValue(0, 0); + AbstractExeState::globalES[varId] = IntervalValue(0, 0); else if (SVFUtil::isa(obj->getValue())) { - IntervalExeState::globalES[varId] = AddressValue(getVirtualMemAddress(varId)); + AbstractExeState::globalES[varId] = AddressValue(getVirtualMemAddress(varId)); } else if (obj->isConstantArray() || obj->isConstantStruct()) - IntervalExeState::globalES[varId] = IntervalValue::top(); + AbstractExeState::globalES[varId] = IntervalValue::top(); else - IntervalExeState::globalES[varId] = IntervalValue::top(); + AbstractExeState::globalES[varId] = IntervalValue::top(); } else - IntervalExeState::globalES[varId] = AddressValue(getVirtualMemAddress(varId)); + AbstractExeState::globalES[varId] = AddressValue(getVirtualMemAddress(varId)); } else - IntervalExeState::globalES[varId] = AddressValue(getVirtualMemAddress(varId)); + AbstractExeState::globalES[varId] = AddressValue(getVirtualMemAddress(varId)); } void SVFIR2ItvExeState::initSVFVar(u32_t varId) @@ -633,14 +633,16 @@ void SVFIR2ItvExeState::translateAddr(const AddrStmt *addr) // if addr RHS is integerType(i8 i32 etc), value should be limited. if (addr->getRHSVar()->getType()->getKind() == SVFType::SVFIntegerTy) { - IntervalExeState::globalES[addr->getRHSVarID()].meet_with(getRangeLimitFromType(addr->getRHSVar()->getType())); + AbstractExeState::globalES[addr->getRHSVarID()].meet_with(getRangeLimitFromType(addr->getRHSVar()->getType())); } - IntervalExeState::globalES[addr->getLHSVarID()] = IntervalExeState::globalES[addr->getRHSVarID()]; + AbstractExeState::globalES[addr->getLHSVarID()] = + AbstractExeState::globalES[addr->getRHSVarID()]; } else if (inVarToAddrsTable(addr->getRHSVarID())) { - IntervalExeState::globalES[addr->getLHSVarID()] = IntervalExeState::globalES[addr->getRHSVarID()]; + AbstractExeState::globalES[addr->getLHSVarID()] = + AbstractExeState::globalES[addr->getRHSVarID()]; } else { From b2437593bd9b0e5ac5262e68f01eff2a94744550 Mon Sep 17 00:00:00 2001 From: bjjwwang Date: Thu, 4 Apr 2024 10:52:09 +1100 Subject: [PATCH 6/7] rename some data struct --- svf-llvm/tools/AE/ae.cpp | 185 ++++++++---------- .../{AbstractExeState.h => AbstractState.h} | 98 +++++----- svf/include/AE/Core/ExeState.h | 2 +- svf/include/AE/Core/RelationSolver.h | 18 +- svf/include/AE/Svfexe/AbstractExecution.h | 15 +- svf/include/AE/Svfexe/SVFIR2ItvExeState.h | 16 +- ...AbstractExeState.cpp => AbstractState.cpp} | 60 +++--- svf/lib/AE/Core/ExeState.cpp | 2 +- svf/lib/AE/Core/RelationSolver.cpp | 44 ++--- svf/lib/AE/Svfexe/AbstractExecution.cpp | 100 +++++----- svf/lib/AE/Svfexe/BufOverflowChecker.cpp | 18 +- svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp | 38 ++-- 12 files changed, 294 insertions(+), 302 deletions(-) rename svf/include/AE/Core/{AbstractExeState.h => AbstractState.h} (86%) rename svf/lib/AE/Core/{AbstractExeState.cpp => AbstractState.cpp} (86%) diff --git a/svf-llvm/tools/AE/ae.cpp b/svf-llvm/tools/AE/ae.cpp index cd169ba40..7339f2ee3 100644 --- a/svf-llvm/tools/AE/ae.cpp +++ b/svf-llvm/tools/AE/ae.cpp @@ -63,11 +63,11 @@ class SymblicAbstractionTest outs() << "hello print\n"; } - AbstractESBase RSY_time(AbstractESBase& inv, const Z3Expr& phi, + AbstractState RSY_time(AbstractState& inv, const Z3Expr& phi, RelationSolver& rs) { auto start_time = std::chrono::high_resolution_clock::now(); - AbstractESBase resRSY = rs.RSY(inv, phi); + AbstractState resRSY = rs.RSY(inv, phi); auto end_time = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast( end_time - start_time); @@ -75,11 +75,11 @@ class SymblicAbstractionTest << " microseconds\n"; return resRSY; } - AbstractESBase Bilateral_time(AbstractESBase& inv, const Z3Expr& phi, + AbstractState Bilateral_time(AbstractState& inv, const Z3Expr& phi, RelationSolver& rs) { auto start_time = std::chrono::high_resolution_clock::now(); - AbstractESBase resBilateral = rs.bilateral(inv, phi); + AbstractState resBilateral = rs.bilateral(inv, phi); auto end_time = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast( end_time - start_time); @@ -87,11 +87,11 @@ class SymblicAbstractionTest << " microseconds\n"; return resBilateral; } - AbstractESBase BS_time(AbstractESBase& inv, const Z3Expr& phi, + AbstractState BS_time(AbstractState& inv, const Z3Expr& phi, RelationSolver& rs) { auto start_time = std::chrono::high_resolution_clock::now(); - AbstractESBase resBS = rs.BS(inv, phi); + AbstractState resBS = rs.BS(inv, phi); auto end_time = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast( end_time - start_time); @@ -103,7 +103,7 @@ class SymblicAbstractionTest void testRelExeState1_1() { outs() << sucMsg("\t SUCCESS :") << "test1_1 start\n"; - AbstractESBase itv; + AbstractState itv; RelExeState relation; // var0 := [0, 1]; itv[0] = IntervalValue(0, 1); @@ -116,29 +116,28 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[1], res); assert(res == Set({0, 1}) && "inconsistency occurs"); - AbstractESBase inv = itv.sliceState(res); + AbstractState inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - AbstractESBase resRSY = rs.RSY(inv, phi); - AbstractESBase resBilateral = rs.bilateral(inv, phi); - AbstractESBase resBS = rs.BS(inv, phi); + AbstractState resRSY = rs.RSY(inv, phi); + AbstractState resBilateral = rs.bilateral(inv, phi); + AbstractState resBS = rs.BS(inv, phi); // 0:[0,1] 1:[1,2] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) { outs() << r.first << " " << r.second.getInterval() << "\n"; } - AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 1)}, {1, IntervalValue(1, 2)}}; - assert( - AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 1)}, {1, IntervalValue(1, 2)}}; + assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState1_2() { outs() << "test1_2 start\n"; - AbstractESBase itv; + AbstractState itv; RelExeState relation; // var0 := [0, 1]; relation[0] = getContext().int_const("0"); @@ -152,29 +151,28 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[1], res); assert(res == Set({0, 1}) && "inconsistency occurs"); - AbstractESBase inv = itv.sliceState(res); + AbstractState inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - AbstractESBase resRSY = rs.RSY(inv, phi); - AbstractESBase resBilateral = rs.bilateral(inv, phi); - AbstractESBase resBS = rs.BS(inv, phi); + AbstractState resRSY = rs.RSY(inv, phi); + AbstractState resBilateral = rs.bilateral(inv, phi); + AbstractState resBS = rs.BS(inv, phi); // 0:[0,1] 1:[0,2] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) { outs() << r.first << " " << r.second.getInterval() << "\n"; } - AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 1)}, {1, IntervalValue(0, 2)}}; - assert( - AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 1)}, {1, IntervalValue(0, 2)}}; + assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState2_1() { outs() << "test2_1 start\n"; - AbstractESBase itv; + AbstractState itv; RelExeState relation; // var0 := [0, 10]; relation[0] = getContext().int_const("0"); @@ -191,14 +189,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - AbstractESBase inv = itv.sliceState(res); + AbstractState inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - AbstractESBase resRSY = rs.RSY(inv, phi); - AbstractESBase resBilateral = rs.bilateral(inv, phi); - AbstractESBase resBS = rs.BS(inv, phi); + AbstractState resRSY = rs.RSY(inv, phi); + AbstractState resBilateral = rs.bilateral(inv, phi); + AbstractState resBS = rs.BS(inv, phi); // 0:[0,10] 1:[0,10] 2:[0,0] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -206,18 +204,17 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10)}, + AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10)}, {1, IntervalValue(0, 10)}, {2, IntervalValue(0, 0)} }; - assert( - AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState2_2() { outs() << "test2_2 start\n"; - AbstractESBase itv; + AbstractState itv; RelExeState relation; // var0 := [0, 100]; relation[0] = getContext().int_const("0"); @@ -235,14 +232,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - AbstractESBase inv = itv.sliceState(res); + AbstractState inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - AbstractESBase resRSY = rs.RSY(inv, phi); - AbstractESBase resBilateral = rs.bilateral(inv, phi); - AbstractESBase resBS = rs.BS(inv, phi); + AbstractState resRSY = rs.RSY(inv, phi); + AbstractState resBilateral = rs.bilateral(inv, phi); + AbstractState resBS = rs.BS(inv, phi); // 0:[0,100] 1:[0,100] 2:[0,0] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -250,18 +247,17 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 100)}, + AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 100)}, {1, IntervalValue(0, 100)}, {2, IntervalValue(0, 0)} }; - assert( - AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState2_3() { outs() << "test2_3 start\n"; - AbstractESBase itv; + AbstractState itv; RelExeState relation; // var0 := [0, 1000]; relation[0] = getContext().int_const("0"); @@ -279,14 +275,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - AbstractESBase inv = itv.sliceState(res); + AbstractState inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - AbstractESBase resRSY = rs.RSY(inv, phi); - AbstractESBase resBilateral = rs.bilateral(inv, phi); - AbstractESBase resBS = rs.BS(inv, phi); + AbstractState resRSY = rs.RSY(inv, phi); + AbstractState resBilateral = rs.bilateral(inv, phi); + AbstractState resBS = rs.BS(inv, phi); // 0:[0,1000] 1:[0,1000] 2:[0,0] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -294,18 +290,17 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 1000)}, + AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 1000)}, {1, IntervalValue(0, 1000)}, {2, IntervalValue(0, 0)} }; - assert( - AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState2_4() { outs() << "test2_4 start\n"; - AbstractESBase itv; + AbstractState itv; RelExeState relation; // var0 := [0, 10000]; relation[0] = getContext().int_const("0"); @@ -323,14 +318,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - AbstractESBase inv = itv.sliceState(res); + AbstractState inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - AbstractESBase resRSY = RSY_time(inv, phi, rs); - AbstractESBase resBilateral = Bilateral_time(inv, phi, rs); - AbstractESBase resBS = BS_time(inv, phi, rs); + AbstractState resRSY = RSY_time(inv, phi, rs); + AbstractState resBilateral = Bilateral_time(inv, phi, rs); + AbstractState resBS = BS_time(inv, phi, rs); // 0:[0,10000] 1:[0,10000] 2:[0,0] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -338,18 +333,17 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10000)}, + AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10000)}, {1, IntervalValue(0, 10000)}, {2, IntervalValue(0, 0)} }; - assert( - AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState2_5() { outs() << "test2_5 start\n"; - AbstractESBase itv; + AbstractState itv; RelExeState relation; // var0 := [0, 100000]; relation[0] = getContext().int_const("0"); @@ -367,14 +361,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - AbstractESBase inv = itv.sliceState(res); + AbstractState inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - AbstractESBase resRSY = RSY_time(inv, phi, rs); - AbstractESBase resBilateral = Bilateral_time(inv, phi, rs); - AbstractESBase resBS = BS_time(inv, phi, rs); + AbstractState resRSY = RSY_time(inv, phi, rs); + AbstractState resBilateral = Bilateral_time(inv, phi, rs); + AbstractState resBS = BS_time(inv, phi, rs); // 0:[0,100000] 1:[0,100000] 2:[0,0] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -382,18 +376,17 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 100000)}, + AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 100000)}, {1, IntervalValue(0, 100000)}, {2, IntervalValue(0, 0)} }; - assert( - AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState3_1() { outs() << "test3_1 start\n"; - AbstractESBase itv; + AbstractState itv; RelExeState relation; // var0 := [1, 10]; relation[0] = getContext().int_const("0"); @@ -410,14 +403,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - AbstractESBase inv = itv.sliceState(res); + AbstractState inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - AbstractESBase resRSY = rs.RSY(inv, phi); - AbstractESBase resBilateral = rs.bilateral(inv, phi); - AbstractESBase resBS = rs.BS(inv, phi); + AbstractState resRSY = rs.RSY(inv, phi); + AbstractState resBilateral = rs.bilateral(inv, phi); + AbstractState resBS = rs.BS(inv, phi); // 0:[1,10] 1:[1,10] 2:[1,1] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -425,18 +418,17 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 10)}, + AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 10)}, {1, IntervalValue(1, 10)}, {2, IntervalValue(1, 1)} }; - assert( - AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState3_2() { outs() << "test3_2 start\n"; - AbstractESBase itv; + AbstractState itv; RelExeState relation; // var0 := [1, 1000]; relation[0] = getContext().int_const("0"); @@ -453,14 +445,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - AbstractESBase inv = itv.sliceState(res); + AbstractState inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - AbstractESBase resRSY = rs.RSY(inv, phi); - AbstractESBase resBilateral = rs.bilateral(inv, phi); - AbstractESBase resBS = rs.BS(inv, phi); + AbstractState resRSY = rs.RSY(inv, phi); + AbstractState resBilateral = rs.bilateral(inv, phi); + AbstractState resBS = rs.BS(inv, phi); // 0:[1,1000] 1:[1,1000] 2:[1,1] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -468,18 +460,17 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 1000)}, + AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 1000)}, {1, IntervalValue(1, 1000)}, {2, IntervalValue(1, 1)} }; - assert( - AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState3_3() { outs() << "test3_3 start\n"; - AbstractESBase itv; + AbstractState itv; RelExeState relation; // var0 := [1, 10000]; relation[0] = getContext().int_const("0"); @@ -496,14 +487,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - AbstractESBase inv = itv.sliceState(res); + AbstractState inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - AbstractESBase resRSY = RSY_time(inv, phi, rs); - AbstractESBase resBilateral = Bilateral_time(inv, phi, rs); - AbstractESBase resBS = BS_time(inv, phi, rs); + AbstractState resRSY = RSY_time(inv, phi, rs); + AbstractState resBilateral = Bilateral_time(inv, phi, rs); + AbstractState resBS = BS_time(inv, phi, rs); // 0:[1,10000] 1:[1,10000] 2:[1,1] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -511,7 +502,7 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 10000)}, + AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 10000)}, {1, IntervalValue(1, 10000)}, {2, IntervalValue(1, 1)}}; } @@ -519,7 +510,7 @@ class SymblicAbstractionTest void testRelExeState3_4() { outs() << "test3_4 start\n"; - AbstractESBase itv; + AbstractState itv; RelExeState relation; // var0 := [1, 100000]; relation[0] = getContext().int_const("0"); @@ -536,14 +527,14 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - AbstractESBase inv = itv.sliceState(res); + AbstractState inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); const Z3Expr& phi = (relExpr && initExpr).simplify(); - AbstractESBase resRSY = RSY_time(inv, phi, rs); - AbstractESBase resBilateral = Bilateral_time(inv, phi, rs); - AbstractESBase resBS = BS_time(inv, phi, rs); + AbstractState resRSY = RSY_time(inv, phi, rs); + AbstractState resBilateral = Bilateral_time(inv, phi, rs); + AbstractState resBS = BS_time(inv, phi, rs); // 0:[1,100000] 1:[1,100000] 2:[1,1] assert(resRSY == resBS && resBS == resBilateral && "inconsistency occurs"); for (auto r : resRSY.getVarToVal()) @@ -551,18 +542,17 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 100000)}, + AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(1, 100000)}, {1, IntervalValue(1, 100000)}, {2, IntervalValue(1, 1)} }; - assert( - AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testRelExeState4_1() { outs() << "test4_1 start\n"; - AbstractESBase itv; + AbstractState itv; RelExeState relation; // var0 := [0, 10]; relation[0] = getContext().int_const("0"); @@ -579,7 +569,7 @@ class SymblicAbstractionTest Set res; relation.extractSubVars(relation[2], res); assert(res == Set({0, 1, 2}) && "inconsistency occurs"); - AbstractESBase inv = itv.sliceState(res); + AbstractState inv = itv.sliceState(res); RelationSolver rs; const Z3Expr& relExpr = relation[2] && relation[1]; const Z3Expr& initExpr = rs.gamma_hat(inv); @@ -588,7 +578,7 @@ class SymblicAbstractionTest outs() << "rsy done\n"; // IntervalExeState resBilateral = rs.bilateral(inv, phi); outs() << "bilateral done\n"; - AbstractESBase resBS = rs.BS(inv, phi); + AbstractState resBS = rs.BS(inv, phi); outs() << "bs done\n"; // 0:[0,10] 1:[0,10] 2:[-00,+00] // assert(resRSY == resBS && resBS == resBilateral); @@ -597,12 +587,11 @@ class SymblicAbstractionTest outs() << r.first << " " << r.second.getInterval() << "\n"; } // ground truth - AbstractESBase::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10)}, + AbstractState::VarToAbsValMap intendedRes = {{0, IntervalValue(0, 10)}, {1, IntervalValue(0, 10)}, {2, IntervalValue(IntervalValue::minus_infinity(), IntervalValue::plus_infinity())} }; - assert( - AbstractESBase::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); + assert(AbstractState::eqVarToValMap(resBS.getVarToVal(), intendedRes) && "inconsistency occurs"); } void testsValidation() diff --git a/svf/include/AE/Core/AbstractExeState.h b/svf/include/AE/Core/AbstractState.h similarity index 86% rename from svf/include/AE/Core/AbstractExeState.h rename to svf/include/AE/Core/AbstractState.h index 3c72e3466..1cf3d1b0e 100644 --- a/svf/include/AE/Core/AbstractExeState.h +++ b/svf/include/AE/Core/AbstractState.h @@ -52,7 +52,7 @@ namespace SVF { -class AbstractESBase +class AbstractState { friend class SVFIR2ItvExeState; friend class RelationSolver; @@ -63,19 +63,19 @@ class AbstractESBase public: /// default constructor - AbstractESBase() {} + AbstractState() {} - AbstractESBase(VarToAbsValMap&_varToValMap, LocToAbsValMap&_locToValMap) : _varToAbsVal(_varToValMap), + AbstractState(VarToAbsValMap&_varToValMap, LocToAbsValMap&_locToValMap) : _varToAbsVal(_varToValMap), _locToAbsVal(_locToValMap) {} /// copy constructor - AbstractESBase(const AbstractESBase&rhs) : _varToAbsVal(rhs.getVarToVal()), + AbstractState(const AbstractState&rhs) : _varToAbsVal(rhs.getVarToVal()), _locToAbsVal(rhs.getLocToVal()) { } - virtual ~AbstractESBase() = default; + virtual ~AbstractState() = default; /// The physical address starts with 0x7f...... + idx @@ -101,7 +101,7 @@ class AbstractESBase return getInternalID(addr) == 0; } - AbstractESBase&operator=(const AbstractESBase&rhs) + AbstractState&operator=(const AbstractState&rhs) { if (rhs != *this) { @@ -112,14 +112,14 @@ class AbstractESBase } /// move constructor - AbstractESBase(AbstractESBase&&rhs) : _varToAbsVal(std::move(rhs._varToAbsVal)), + AbstractState(AbstractState&&rhs) : _varToAbsVal(std::move(rhs._varToAbsVal)), _locToAbsVal(std::move(rhs._locToAbsVal)) { } /// operator= move constructor - AbstractESBase&operator=(AbstractESBase&&rhs) + AbstractState&operator=(AbstractState&&rhs) { if (&rhs != this) { @@ -130,9 +130,9 @@ class AbstractESBase } /// Set all value bottom - AbstractESBase bottom() const + AbstractState bottom() const { - AbstractESBase inv = *this; + AbstractState inv = *this; for (auto &item: inv._varToAbsVal) { if (item.second.isInterval()) @@ -142,9 +142,9 @@ class AbstractESBase } /// Set all value top - AbstractESBase top() const + AbstractState top() const { - AbstractESBase inv = *this; + AbstractState inv = *this; for (auto &item: inv._varToAbsVal) { if (item.second.isInterval()) @@ -154,9 +154,9 @@ class AbstractESBase } /// Copy some values and return a new IntervalExeState - AbstractESBase sliceState(Set &sl) + AbstractState sliceState(Set &sl) { - AbstractESBase inv; + AbstractState inv; for (u32_t id: sl) { inv._varToAbsVal[id] = _varToAbsVal[id]; @@ -242,22 +242,22 @@ class AbstractESBase public: /// domain widen with other, and return the widened domain - AbstractESBase widening(const AbstractESBase&other); + AbstractState widening(const AbstractState&other); /// domain narrow with other, and return the narrowed domain - AbstractESBase narrowing(const AbstractESBase&other); + AbstractState narrowing(const AbstractState&other); /// domain widen with other, important! other widen this. - void widenWith(const AbstractESBase&other); + void widenWith(const AbstractState&other); /// domain join with other, important! other widen this. - void joinWith(const AbstractESBase&other); + void joinWith(const AbstractState&other); /// domain narrow with other, important! other widen this. - void narrowWith(const AbstractESBase&other); + void narrowWith(const AbstractState&other); /// domain meet with other, important! other widen this. - void meetWith(const AbstractESBase&other); + void meetWith(const AbstractState&other); /// Return int value from an expression if it is a numeral, otherwise return an approximate value @@ -327,7 +327,7 @@ class AbstractESBase return ""; } - bool equals(const AbstractESBase&other) const; + bool equals(const AbstractState&other) const; static bool eqVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs) { @@ -393,24 +393,24 @@ class AbstractESBase return true; } - bool operator==(const AbstractESBase&rhs) const + bool operator==(const AbstractState&rhs) const { return eqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && eqVarToValMap(_locToAbsVal, rhs.getLocToVal()); } - bool operator!=(const AbstractESBase&rhs) const + bool operator!=(const AbstractState&rhs) const { return !(*this == rhs); } - bool operator<(const AbstractESBase&rhs) const + bool operator<(const AbstractState&rhs) const { return !(*this >= rhs); } - bool operator>=(const AbstractESBase&rhs) const + bool operator>=(const AbstractState&rhs) const { return geqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && geqVarToValMap(_locToAbsVal, rhs.getLocToVal()); } @@ -427,46 +427,46 @@ class AbstractESBase }; -class AbstractExeState : public AbstractESBase +class SparseAbstractState : public AbstractState { friend class SVFIR2ItvExeState; friend class RelationSolver; public: - static AbstractExeState globalES; + static SparseAbstractState globalES; public: /// default constructor - AbstractExeState() : AbstractESBase() {} + SparseAbstractState() : AbstractState() {} - AbstractExeState(VarToAbsValMap&_varToValMap, LocToAbsValMap&_locToValMap) : AbstractESBase(_varToValMap, _locToValMap) {} + SparseAbstractState(VarToAbsValMap&_varToValMap, LocToAbsValMap&_locToValMap) : AbstractState(_varToValMap, _locToValMap) {} /// copy constructor - AbstractExeState(const AbstractExeState&rhs) : AbstractESBase(rhs) + SparseAbstractState(const SparseAbstractState&rhs) : AbstractState(rhs) { } - virtual ~AbstractExeState() = default; + virtual ~SparseAbstractState() = default; - AbstractExeState&operator=(const AbstractExeState&rhs) + SparseAbstractState&operator=(const SparseAbstractState&rhs) { - AbstractESBase::operator=(rhs); + AbstractState::operator=(rhs); return *this; } virtual void printExprValues(std::ostream &oss) const; /// move constructor - AbstractExeState(AbstractExeState&&rhs) : AbstractESBase(std::move(rhs)) + SparseAbstractState(SparseAbstractState&&rhs) : AbstractState(std::move(rhs)) { } /// operator= move constructor - AbstractExeState&operator=(AbstractExeState&&rhs) + SparseAbstractState&operator=(SparseAbstractState&&rhs) { - AbstractESBase::operator=(std::move(rhs)); + AbstractState::operator=(std::move(rhs)); return *this; } @@ -626,22 +626,22 @@ class AbstractExeState : public AbstractESBase } /// domain widen with other, and return the widened domain - AbstractExeState widening(const AbstractExeState&other); + SparseAbstractState widening(const SparseAbstractState&other); /// domain narrow with other, and return the narrowed domain - AbstractExeState narrowing(const AbstractExeState&other); + SparseAbstractState narrowing(const SparseAbstractState&other); /// domain widen with other, important! other widen this. - void widenWith(const AbstractExeState&other); + void widenWith(const SparseAbstractState&other); /// domain join with other, important! other widen this. - void joinWith(const AbstractExeState&other); + void joinWith(const SparseAbstractState&other); /// domain narrow with other, important! other widen this. - void narrowWith(const AbstractExeState&other); + void narrowWith(const SparseAbstractState&other); /// domain meet with other, important! other widen this. - void meetWith(const AbstractExeState&other); + void meetWith(const SparseAbstractState&other); u32_t hash() const; @@ -667,26 +667,26 @@ class AbstractExeState : public AbstractESBase } } - bool equals(const AbstractExeState&other) const; + bool equals(const SparseAbstractState&other) const; - bool operator==(const AbstractExeState&rhs) const + bool operator==(const SparseAbstractState&rhs) const { return eqVarToValMap(_varToAbsVal, rhs._varToAbsVal) && eqVarToValMap(_locToAbsVal, rhs._locToAbsVal); } - bool operator!=(const AbstractExeState&rhs) const + bool operator!=(const SparseAbstractState&rhs) const { return !(*this == rhs); } - bool operator<(const AbstractExeState&rhs) const + bool operator<(const SparseAbstractState&rhs) const { return !(*this >= rhs); } - bool operator>=(const AbstractExeState&rhs) const + bool operator>=(const SparseAbstractState&rhs) const { return geqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && geqVarToValMap(_locToAbsVal, rhs._locToAbsVal); } @@ -694,9 +694,9 @@ class AbstractExeState : public AbstractESBase } template<> -struct std::hash +struct std::hash { - size_t operator()(const SVF::AbstractExeState&exeState) const + size_t operator()(const SVF::SparseAbstractState&exeState) const { return exeState.hash(); } diff --git a/svf/include/AE/Core/ExeState.h b/svf/include/AE/Core/ExeState.h index 60f537f9d..c6b4970e9 100644 --- a/svf/include/AE/Core/ExeState.h +++ b/svf/include/AE/Core/ExeState.h @@ -39,7 +39,7 @@ namespace SVF { -class AbstractExeState; +class SparseAbstractState; /*! * Base execution state diff --git a/svf/include/AE/Core/RelationSolver.h b/svf/include/AE/Core/RelationSolver.h index b8b7bbbb1..f15fe9fe8 100644 --- a/svf/include/AE/Core/RelationSolver.h +++ b/svf/include/AE/Core/RelationSolver.h @@ -30,7 +30,7 @@ #ifndef Z3_EXAMPLE_RELATIONSOLVER_H #define Z3_EXAMPLE_RELATIONSOLVER_H -#include "AE/Core/AbstractExeState.h" +#include "AE/Core/AbstractState.h" #include "Util/Z3Expr.h" namespace SVF @@ -44,17 +44,17 @@ class RelationSolver IntervalESBase (the last element of inputs) for RSY or bilateral solver */ /// Return Z3Expr according to valToValMap - Z3Expr gamma_hat(const AbstractESBase&exeState) const; + Z3Expr gamma_hat(const AbstractState&exeState) const; /// Return Z3Expr according to another valToValMap - Z3Expr gamma_hat(const AbstractESBase&alpha, const AbstractESBase&exeState) const; + Z3Expr gamma_hat(const AbstractState&alpha, const AbstractState&exeState) const; /// Return Z3Expr from a NodeID - Z3Expr gamma_hat(u32_t id, const AbstractESBase&exeState) const; + Z3Expr gamma_hat(u32_t id, const AbstractState&exeState) const; - AbstractESBase abstract_consequence(const AbstractESBase&lower, const AbstractESBase&upper, const AbstractESBase&domain) const; + AbstractState abstract_consequence(const AbstractState&lower, const AbstractState&upper, const AbstractState&domain) const; - AbstractESBase beta(const Map &sigma, const AbstractESBase&exeState) const; + AbstractState beta(const Map &sigma, const AbstractState&exeState) const; /// Return Z3 expression lazily based on SVFVar ID @@ -65,13 +65,13 @@ class RelationSolver /* two optional solvers: RSY and bilateral */ - AbstractESBase bilateral(const AbstractESBase& domain, const Z3Expr &phi, u32_t descend_check = 0); + AbstractState bilateral(const AbstractState& domain, const Z3Expr &phi, u32_t descend_check = 0); - AbstractESBase RSY(const AbstractESBase& domain, const Z3Expr &phi); + AbstractState RSY(const AbstractState& domain, const Z3Expr &phi); Map BoxedOptSolver(const Z3Expr& phi, Map& ret, Map& low_values, Map& high_values); - AbstractESBase BS(const AbstractESBase& domain, const Z3Expr &phi); + AbstractState BS(const AbstractState& domain, const Z3Expr &phi); void updateMap(Map& map, u32_t key, const NumericLiteral& value); diff --git a/svf/include/AE/Svfexe/AbstractExecution.h b/svf/include/AE/Svfexe/AbstractExecution.h index c78d9821c..067ed528b 100644 --- a/svf/include/AE/Svfexe/AbstractExecution.h +++ b/svf/include/AE/Svfexe/AbstractExecution.h @@ -154,7 +154,7 @@ class AbstractExecution * @param intraEdge the edge from CmpStmt to the next node * @return if this edge is feasible */ - bool hasBranchES(const IntraCFGEdge* intraEdge, AbstractExeState& es); + bool hasBranchES(const IntraCFGEdge* intraEdge, SparseAbstractState& es); /** * handle instructions in ICFGNode @@ -220,7 +220,7 @@ class AbstractExecution * @return if this ICFGNode has preceding execution state */ bool hasCmpBranchES(const CmpStmt* cmpStmt, s64_t succ, - AbstractExeState& es); + SparseAbstractState& es); /** * Check if this SwitchInst and succ are satisfiable to the execution state. @@ -229,7 +229,8 @@ class AbstractExecution * @param succ the case value of switch inst * @return if this ICFGNode has preceding execution state */ - bool hasSwitchBranchES(const SVFVar* var, s64_t succ, AbstractExeState& es); + bool hasSwitchBranchES(const SVFVar* var, s64_t succ, + SparseAbstractState& es); /** @@ -373,9 +374,9 @@ class AbstractExecution // helper functions in handleCycle bool widenFixpointPass(const ICFGNode* cycle_head, - AbstractExeState& pre_es); + SparseAbstractState& pre_es); bool narrowFixpointPass(const ICFGNode* cycle_head, - AbstractExeState& pre_es); + SparseAbstractState& pre_es); protected: // there data should be shared with subclasses @@ -384,8 +385,8 @@ class AbstractExecution Set _checkpoint_names; private: - Map _preES; - Map _postES; + Map _preAbstractTrace; + Map _postAbstractTrace; std::string _moduleName; }; } \ No newline at end of file diff --git a/svf/include/AE/Svfexe/SVFIR2ItvExeState.h b/svf/include/AE/Svfexe/SVFIR2ItvExeState.h index 7f6af8df6..b27e8abbb 100644 --- a/svf/include/AE/Svfexe/SVFIR2ItvExeState.h +++ b/svf/include/AE/Svfexe/SVFIR2ItvExeState.h @@ -33,7 +33,7 @@ #ifndef Z3_EXAMPLE_SVFIR2ITVEXESTATE_H #define Z3_EXAMPLE_SVFIR2ITVEXESTATE_H -#include "AE/Core/AbstractExeState.h" +#include "AE/Core/AbstractState.h" #include "AE/Core/ExeState.h" #include "AE/Core/RelExeState.h" #include "SVFIR/SVFIR.h" @@ -47,12 +47,12 @@ class SVFIR2ItvExeState public: SVFIR2ItvExeState(SVFIR *ir) : _svfir(ir) {} - void setEs(const AbstractExeState&es) + void setEs(const SparseAbstractState&es) { _es = es; } - AbstractExeState&getEs() + SparseAbstractState&getEs() { return _es; } @@ -67,9 +67,9 @@ class SVFIR2ItvExeState return _relEs; } - void widenAddrs(AbstractExeState&lhs, const AbstractExeState&rhs); + void widenAddrs(SparseAbstractState&lhs, const SparseAbstractState&rhs); - void narrowAddrs(AbstractExeState&lhs, const AbstractExeState&rhs); + void narrowAddrs(SparseAbstractState&lhs, const SparseAbstractState&rhs); /// Return the field address given a pointer points to a struct object and an offset AbstractValue getGepObjAddress(u32_t pointer, APOffset offset); @@ -102,7 +102,7 @@ class SVFIR2ItvExeState return Z3Expr::getContext(); } - void applySummary(AbstractExeState&es); + void applySummary(SparseAbstractState&es); /// Init ObjVar @@ -209,10 +209,10 @@ class SVFIR2ItvExeState private: SVFIR *_svfir; - AbstractExeState _es; + SparseAbstractState _es; RelExeState _relEs; - Map _br_cond; + Map _br_cond; AbstractValue getZExtValue(const SVFVar* var, const SVFType*); }; } diff --git a/svf/lib/AE/Core/AbstractExeState.cpp b/svf/lib/AE/Core/AbstractState.cpp similarity index 86% rename from svf/lib/AE/Core/AbstractExeState.cpp rename to svf/lib/AE/Core/AbstractState.cpp index 8a21a1f4f..a20ca7560 100644 --- a/svf/lib/AE/Core/AbstractExeState.cpp +++ b/svf/lib/AE/Core/AbstractState.cpp @@ -27,18 +27,18 @@ * */ -#include "AE/Core/AbstractExeState.h" +#include "AE/Core/AbstractState.h" #include "Util/SVFUtil.h" using namespace SVF; using namespace SVFUtil; -bool AbstractESBase::equals(const AbstractESBase&other) const +bool AbstractState::equals(const AbstractState&other) const { return *this == other; } -u32_t AbstractESBase::hash() const +u32_t AbstractState::hash() const { size_t h = getVarToVal().size() * 2; Hash hf; @@ -55,10 +55,10 @@ u32_t AbstractESBase::hash() const return pairH({h, h2}); } -AbstractESBase AbstractESBase::widening(const AbstractESBase& other) +AbstractState AbstractState::widening(const AbstractState& other) { // widen interval - AbstractESBase es = *this; + AbstractState es = *this; for (auto it = es._varToAbsVal.begin(); it != es._varToAbsVal.end(); ++it) { auto key = it->first; @@ -77,9 +77,9 @@ AbstractESBase AbstractESBase::widening(const AbstractESBase& other) return es; } -AbstractESBase AbstractESBase::narrowing(const AbstractESBase& other) +AbstractState AbstractState::narrowing(const AbstractState& other) { - AbstractESBase es = *this; + AbstractState es = *this; for (auto it = es._varToAbsVal.begin(); it != es._varToAbsVal.end(); ++it) { auto key = it->first; @@ -97,7 +97,7 @@ AbstractESBase AbstractESBase::narrowing(const AbstractESBase& other) } /// domain widen with other, important! other widen this. -void AbstractESBase::widenWith(const AbstractESBase& other) +void AbstractState::widenWith(const AbstractState& other) { for (auto it = _varToAbsVal.begin(); it != _varToAbsVal.end(); ++it) { @@ -116,7 +116,7 @@ void AbstractESBase::widenWith(const AbstractESBase& other) } /// domain join with other, important! other widen this. -void AbstractESBase::joinWith(const AbstractESBase& other) +void AbstractState::joinWith(const AbstractState& other) { for (auto it = other._varToAbsVal.begin(); it != other._varToAbsVal.end(); ++it) { @@ -165,7 +165,7 @@ void AbstractESBase::joinWith(const AbstractESBase& other) } /// domain narrow with other, important! other widen this. -void AbstractESBase::narrowWith(const AbstractESBase& other) +void AbstractState::narrowWith(const AbstractState& other) { for (auto it = _varToAbsVal.begin(); it != _varToAbsVal.end(); ++it) { @@ -186,7 +186,7 @@ void AbstractESBase::narrowWith(const AbstractESBase& other) } /// domain meet with other, important! other widen this. -void AbstractESBase::meetWith(const AbstractESBase& other) +void AbstractState::meetWith(const AbstractState& other) { for (auto it = other._varToAbsVal.begin(); it != other._varToAbsVal.end(); ++it) { @@ -227,7 +227,7 @@ void AbstractESBase::meetWith(const AbstractESBase& other) } /// Print values of all expressions -void AbstractESBase::printExprValues(std::ostream &oss) const +void AbstractState::printExprValues(std::ostream &oss) const { oss << "-----------Var and Value-----------\n"; printTable(_varToAbsVal, oss); @@ -235,7 +235,7 @@ void AbstractESBase::printExprValues(std::ostream &oss) const oss << "-----------------------------------------\n"; } -void AbstractESBase::printTable(const VarToAbsValMap&table, std::ostream &oss) const +void AbstractState::printTable(const VarToAbsValMap&table, std::ostream &oss) const { oss.flags(std::ios::left); std::set ordered; @@ -258,20 +258,20 @@ void AbstractESBase::printTable(const VarToAbsValMap&table, std::ostream &oss) c } } -AbstractExeState AbstractExeState::globalES; -bool AbstractExeState::equals(const AbstractExeState&other) const +SparseAbstractState SparseAbstractState::globalES; +bool SparseAbstractState::equals(const SparseAbstractState&other) const { return *this == other; } -u32_t AbstractExeState::hash() const +u32_t SparseAbstractState::hash() const { - return AbstractESBase::hash(); + return AbstractState::hash(); } -AbstractExeState AbstractExeState::widening(const AbstractExeState& other) +SparseAbstractState SparseAbstractState::widening(const SparseAbstractState& other) { - AbstractExeState es = *this; + SparseAbstractState es = *this; for (auto it = es._varToAbsVal.begin(); it != es._varToAbsVal.end(); ++it) { auto key = it->first; @@ -289,9 +289,9 @@ AbstractExeState AbstractExeState::widening(const AbstractExeState& other) return es; } -AbstractExeState AbstractExeState::narrowing(const AbstractExeState& other) +SparseAbstractState SparseAbstractState::narrowing(const SparseAbstractState& other) { - AbstractExeState es = *this; + SparseAbstractState es = *this; for (auto it = es._varToAbsVal.begin(); it != es._varToAbsVal.end(); ++it) { auto key = it->first; @@ -311,32 +311,32 @@ AbstractExeState AbstractExeState::narrowing(const AbstractExeState& other) } /// domain widen with other, important! other widen this. -void AbstractExeState::widenWith(const AbstractExeState& other) +void SparseAbstractState::widenWith(const SparseAbstractState& other) { - AbstractESBase::widenWith(other); + AbstractState::widenWith(other); } /// domain join with other, important! other widen this. -void AbstractExeState::joinWith(const AbstractExeState& other) +void SparseAbstractState::joinWith(const SparseAbstractState& other) { - AbstractESBase::joinWith(other); + AbstractState::joinWith(other); } /// domain narrow with other, important! other widen this. -void AbstractExeState::narrowWith(const AbstractExeState& other) +void SparseAbstractState::narrowWith(const SparseAbstractState& other) { - AbstractESBase::narrowWith(other); + AbstractState::narrowWith(other); } /// domain meet with other, important! other widen this. -void AbstractExeState::meetWith(const AbstractExeState& other) +void SparseAbstractState::meetWith(const SparseAbstractState& other) { - AbstractESBase::meetWith(other); + AbstractState::meetWith(other); } /// Print values of all expressions -void AbstractExeState::printExprValues(std::ostream &oss) const +void SparseAbstractState::printExprValues(std::ostream &oss) const { oss << "-----------Var and Value-----------\n"; printTable(_varToAbsVal, oss); diff --git a/svf/lib/AE/Core/ExeState.cpp b/svf/lib/AE/Core/ExeState.cpp index 5f53335bc..7e1a98b0f 100644 --- a/svf/lib/AE/Core/ExeState.cpp +++ b/svf/lib/AE/Core/ExeState.cpp @@ -28,7 +28,7 @@ */ #include "AE/Core/ExeState.h" -#include "AE/Core/AbstractExeState.h" +#include "AE/Core/AbstractState.h" using namespace SVF; diff --git a/svf/lib/AE/Core/RelationSolver.cpp b/svf/lib/AE/Core/RelationSolver.cpp index 7f1f4b8ae..bb750103e 100644 --- a/svf/lib/AE/Core/RelationSolver.cpp +++ b/svf/lib/AE/Core/RelationSolver.cpp @@ -33,19 +33,19 @@ using namespace SVF; using namespace SVFUtil; -AbstractESBase RelationSolver::bilateral(const AbstractESBase&domain, const Z3Expr& phi, +AbstractState RelationSolver::bilateral(const AbstractState&domain, const Z3Expr& phi, u32_t descend_check) { /// init variables - AbstractESBase upper = domain.top(); - AbstractESBase lower = domain.bottom(); + AbstractState upper = domain.top(); + AbstractState lower = domain.bottom(); u32_t meets_in_a_row = 0; z3::solver solver = Z3Expr::getSolver(); z3::params p(Z3Expr::getContext()); /// TODO: add option for timeout p.set(":timeout", static_cast(600)); // in milliseconds solver.set(p); - AbstractESBase consequence; + AbstractState consequence; /// start processing while (lower != upper) @@ -85,9 +85,9 @@ AbstractESBase RelationSolver::bilateral(const AbstractESBase&domain, const Z3Ex } } solver.pop(); - AbstractESBase newLower = domain.bottom(); + AbstractState newLower = domain.bottom(); newLower.joinWith(lower); - AbstractESBase rhs = beta(solution, domain); + AbstractState rhs = beta(solution, domain); newLower.joinWith(rhs); lower = newLower; meets_in_a_row = 0; @@ -101,7 +101,7 @@ AbstractESBase RelationSolver::bilateral(const AbstractESBase&domain, const Z3Ex if (solver.reason_unknown() == "timeout") return upper; } - AbstractESBase newUpper = domain.top(); + AbstractState newUpper = domain.top(); newUpper.meetWith(upper); newUpper.meetWith(consequence); upper = newUpper; @@ -111,9 +111,9 @@ AbstractESBase RelationSolver::bilateral(const AbstractESBase&domain, const Z3Ex return upper; } -AbstractESBase RelationSolver::RSY(const AbstractESBase& domain, const Z3Expr& phi) +AbstractState RelationSolver::RSY(const AbstractState& domain, const Z3Expr& phi) { - AbstractESBase lower = domain.bottom(); + AbstractState lower = domain.bottom(); z3::solver& solver = Z3Expr::getSolver(); z3::params p(Z3Expr::getContext()); /// TODO: add option for timeout @@ -147,7 +147,7 @@ AbstractESBase RelationSolver::RSY(const AbstractESBase& domain, const Z3Expr& p } } solver.pop(); - AbstractESBase newLower = domain.bottom(); + AbstractState newLower = domain.bottom(); newLower.joinWith(lower); newLower.joinWith(beta(solution, domain)); lower = newLower; @@ -167,8 +167,8 @@ AbstractESBase RelationSolver::RSY(const AbstractESBase& domain, const Z3Expr& p return lower; } -AbstractESBase RelationSolver::abstract_consequence( - const AbstractESBase& lower, const AbstractESBase& upper, const AbstractESBase& domain) const +AbstractState RelationSolver::abstract_consequence( + const AbstractState& lower, const AbstractState& upper, const AbstractState& domain) const { /*Returns the "abstract consequence" of lower and upper. @@ -184,7 +184,7 @@ AbstractESBase RelationSolver::abstract_consequence( it != domain.getVarToVal().end(); ++it) /// for variable in self.variables: { - AbstractESBase proposed = domain.top(); /// proposed = self.top.copy() + AbstractState proposed = domain.top(); /// proposed = self.top.copy() proposed[it->first] = lower[it->first].getInterval(); /// proposed.set_interval(variable, lower.interval_of(variable)) /// proposed._locToItvVal @@ -196,7 +196,7 @@ AbstractESBase RelationSolver::abstract_consequence( return lower; /// return lower.copy() } -Z3Expr RelationSolver::gamma_hat(const AbstractESBase& exeState) const +Z3Expr RelationSolver::gamma_hat(const AbstractState& exeState) const { Z3Expr res(Z3Expr::getContext().bool_val(true)); for (auto& item : exeState.getVarToVal()) @@ -212,8 +212,8 @@ Z3Expr RelationSolver::gamma_hat(const AbstractESBase& exeState) const return res; } -Z3Expr RelationSolver::gamma_hat(const AbstractESBase& alpha, - const AbstractESBase& exeState) const +Z3Expr RelationSolver::gamma_hat(const AbstractState& alpha, + const AbstractState& exeState) const { Z3Expr res(Z3Expr::getContext().bool_val(true)); for (auto& item : exeState.getVarToVal()) @@ -230,7 +230,7 @@ Z3Expr RelationSolver::gamma_hat(const AbstractESBase& alpha, return res; } -Z3Expr RelationSolver::gamma_hat(u32_t id, const AbstractESBase& exeState) const +Z3Expr RelationSolver::gamma_hat(u32_t id, const AbstractState& exeState) const { auto it = exeState.getVarToVal().find(id); assert(it != exeState.getVarToVal().end() && "id not in varToVal?"); @@ -241,10 +241,10 @@ Z3Expr RelationSolver::gamma_hat(u32_t id, const AbstractESBase& exeState) const return res; } -AbstractESBase RelationSolver::beta(const Map& sigma, - const AbstractESBase& exeState) const +AbstractState RelationSolver::beta(const Map& sigma, + const AbstractState& exeState) const { - AbstractESBase res; + AbstractState res; for (const auto& item : exeState.getVarToVal()) { res[item.first] = IntervalValue( @@ -266,7 +266,7 @@ void RelationSolver::updateMap(Map& map, u32_t key, const } } -AbstractESBase RelationSolver::BS(const AbstractESBase& domain, const Z3Expr &phi) +AbstractState RelationSolver::BS(const AbstractState& domain, const Z3Expr &phi) { /// because key of _varToItvVal is u32_t, -key may out of range for int /// so we do key + bias for -key @@ -312,7 +312,7 @@ AbstractESBase RelationSolver::BS(const AbstractESBase& domain, const Z3Expr &ph /// optimize each object BoxedOptSolver(new_phi.simplify(), ret, low_values, high_values); /// fill in the return values - AbstractESBase retInv; + AbstractState retInv; for (const auto& item: ret) { if (item.first >= bias) diff --git a/svf/lib/AE/Svfexe/AbstractExecution.cpp b/svf/lib/AE/Svfexe/AbstractExecution.cpp index 0dbc2806f..71aeed9eb 100644 --- a/svf/lib/AE/Svfexe/AbstractExecution.cpp +++ b/svf/lib/AE/Svfexe/AbstractExecution.cpp @@ -162,7 +162,7 @@ void AbstractExecution::analyse() /// handle global node void AbstractExecution::handleGlobalNode() { - AbstractExeState es; + SparseAbstractState es; const ICFGNode* node = _icfg->getGlobalICFGNode(); _svfir2ExeState->setEs(es); // Global Node, we just need to handle addr, load, store, copy and gep @@ -181,22 +181,24 @@ bool AbstractExecution::hasInEdgesES(const ICFGNode *block) { if (isGlobalEntry(block)) { - _preES[block] = AbstractExeState(); + _preAbstractTrace[block] = SparseAbstractState(); return true; } // is common basic block else { - AbstractExeState es; + SparseAbstractState es; u32_t inEdgeNum = 0; for (auto& edge: block->getInEdges()) { - if (_postES.find(edge->getSrcNode()) != _postES.end()) + if (_postAbstractTrace.find(edge->getSrcNode()) != + _postAbstractTrace.end()) { const IntraCFGEdge *intraCfgEdge = SVFUtil::dyn_cast(edge); if (intraCfgEdge && intraCfgEdge->getCondition()) { - AbstractExeState tmpEs = _postES[edge->getSrcNode()]; + SparseAbstractState tmpEs = + _postAbstractTrace[edge->getSrcNode()]; if (hasBranchES(intraCfgEdge, tmpEs)) { es.joinWith(tmpEs); @@ -209,7 +211,7 @@ bool AbstractExecution::hasInEdgesES(const ICFGNode *block) } else { - es.joinWith(_postES[edge->getSrcNode()]); + es.joinWith(_postAbstractTrace[edge->getSrcNode()]); inEdgeNum++; } } @@ -224,7 +226,7 @@ bool AbstractExecution::hasInEdgesES(const ICFGNode *block) } else { - _preES[block] = es; + _preAbstractTrace[block] = es; return true; } } @@ -235,7 +237,7 @@ bool AbstractExecution::isFunEntry(const SVF::ICFGNode *block) { if (SVFUtil::isa(block)) { - if (_preES.find(block) != _preES.end()) + if (_preAbstractTrace.find(block) != _preAbstractTrace.end()) { return true; } @@ -256,9 +258,9 @@ bool AbstractExecution::isGlobalEntry(const SVF::ICFGNode *block) } bool AbstractExecution::hasCmpBranchES(const CmpStmt* cmpStmt, s64_t succ, - AbstractExeState& es) + SparseAbstractState& es) { - AbstractExeState new_es = es; + SparseAbstractState new_es = es; // get cmp stmt's op0, op1, and predicate NodeID op0 = cmpStmt->getOpVarID(0); NodeID op1 = cmpStmt->getOpVarID(1); @@ -487,9 +489,9 @@ bool AbstractExecution::hasCmpBranchES(const CmpStmt* cmpStmt, s64_t succ, } bool AbstractExecution::hasSwitchBranchES(const SVFVar* var, s64_t succ, - AbstractExeState& es) + SparseAbstractState& es) { - AbstractExeState new_es = es; + SparseAbstractState new_es = es; new_es.cpyItvToLocal(var->getId()); IntervalValue& switch_cond = new_es[var->getId()].getInterval(); s64_t value = succ; @@ -532,7 +534,7 @@ bool AbstractExecution::hasSwitchBranchES(const SVFVar* var, s64_t succ, } bool AbstractExecution::hasBranchES(const IntraCFGEdge* intraEdge, - AbstractExeState& es) + SparseAbstractState& es) { const SVFValue *cond = intraEdge->getCondition(); NodeID cmpID = _svfir->getValueNode(cond); @@ -571,7 +573,7 @@ void AbstractExecution::handleWTONode(const ICFGNode *node) { // Has ES on the in edges - Feasible block // Get execution state from in edges - _svfir2ExeState->setEs(_preES[node]); + _svfir2ExeState->setEs(_preAbstractTrace[node]); } std::deque worklist; @@ -583,8 +585,8 @@ void AbstractExecution::handleWTONode(const ICFGNode *node) handleICFGNode(curNode); } - _preES.erase(node); - _postES[node] = _svfir2ExeState->getEs(); + _preAbstractTrace.erase(node); + _postAbstractTrace[node] = _svfir2ExeState->getEs(); } void AbstractExecution::handleCallSite(const ICFGNode* node) @@ -652,7 +654,7 @@ void AbstractExecution::recursiveCallPass(const SVF::CallICFGNode *callNode) } } } - _postES[retNode] = _svfir2ExeState->getEs(); + _postAbstractTrace[retNode] = _svfir2ExeState->getEs(); } bool AbstractExecution::isDirectCall(const SVF::CallICFGNode *callNode) @@ -663,17 +665,17 @@ bool AbstractExecution::isDirectCall(const SVF::CallICFGNode *callNode) void AbstractExecution::directCallFunPass(const SVF::CallICFGNode *callNode) { const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite()); - AbstractExeState preES = _svfir2ExeState->getEs(); + SparseAbstractState preES = _svfir2ExeState->getEs(); _callSiteStack.push_back(callNode); - _postES[callNode] = _svfir2ExeState->getEs(); + _postAbstractTrace[callNode] = _svfir2ExeState->getEs(); handleFunc(callfun); _callSiteStack.pop_back(); // handle Ret node const RetICFGNode *retNode = callNode->getRetICFGNode(); // resume ES to callnode - _postES[retNode] = _postES[callNode]; + _postAbstractTrace[retNode] = _postAbstractTrace[callNode]; } bool AbstractExecution::isIndirectCall(const SVF::CallICFGNode *callNode) @@ -696,16 +698,16 @@ void AbstractExecution::indirectCallFunPass(const SVF::CallICFGNode *callNode) const SVFFunction *callfun = SVFUtil::dyn_cast(func_var->getValue()); if (callfun) { - AbstractExeState preES = _svfir2ExeState->getEs(); + SparseAbstractState preES = _svfir2ExeState->getEs(); _callSiteStack.push_back(callNode); - _postES[callNode] = _svfir2ExeState->getEs(); + _postAbstractTrace[callNode] = _svfir2ExeState->getEs(); handleFunc(callfun); _callSiteStack.pop_back(); // handle Ret node const RetICFGNode *retNode = callNode->getRetICFGNode(); - _postES[retNode] = _postES[callNode]; + _postAbstractTrace[retNode] = _postAbstractTrace[callNode]; } } @@ -740,7 +742,7 @@ void AbstractExecution::handleCycle(const ICFGWTOCycle *cycle) // No ES on the in edges - Infeasible block return; } - AbstractExeState pre_es = _preES[cycle->head()]; + SparseAbstractState pre_es = _preAbstractTrace[cycle->head()]; // set -widen-delay s32_t widen_delay = Options::WidenDelay(); bool incresing = true; @@ -751,11 +753,11 @@ void AbstractExecution::handleCycle(const ICFGWTOCycle *cycle) handleWTONode(cycle_head); if (i < widen_delay) { - if (i> 0 && pre_es >= _postES[cycle_head]) + if (i> 0 && pre_es >= _postAbstractTrace[cycle_head]) { break; } - pre_es = _postES[cycle_head]; + pre_es = _postAbstractTrace[cycle_head]; } else { @@ -798,45 +800,45 @@ void AbstractExecution::handleCycle(const ICFGWTOCycle *cycle) } bool AbstractExecution::widenFixpointPass(const ICFGNode* cycle_head, - AbstractExeState& pre_es) + SparseAbstractState& pre_es) { // increasing iterations - AbstractExeState new_pre_es = pre_es.widening(_postES[cycle_head]); - AbstractExeState new_pre_vaddr_es = new_pre_es; - _svfir2ExeState->widenAddrs(new_pre_es, _postES[cycle_head]); + SparseAbstractState new_pre_es = pre_es.widening(_postAbstractTrace[cycle_head]); + SparseAbstractState new_pre_vaddr_es = new_pre_es; + _svfir2ExeState->widenAddrs(new_pre_es, _postAbstractTrace[cycle_head]); if (pre_es >= new_pre_es) { // increasing iterations - fixpoint reached pre_es = new_pre_es; - _postES[cycle_head] = pre_es; + _postAbstractTrace[cycle_head] = pre_es; return true; } else { pre_es = new_pre_es; - _postES[cycle_head] = pre_es; + _postAbstractTrace[cycle_head] = pre_es; return false; } } -bool AbstractExecution::narrowFixpointPass(const SVF::ICFGNode *cycle_head, SVF::AbstractExeState&pre_es) +bool AbstractExecution::narrowFixpointPass(const SVF::ICFGNode *cycle_head, SVF::SparseAbstractState&pre_es) { // decreasing iterations - AbstractExeState new_pre_es = pre_es.narrowing(_postES[cycle_head]); - AbstractExeState new_pre_vaddr_es = new_pre_es; - _svfir2ExeState->narrowAddrs(new_pre_es, _postES[cycle_head]); + SparseAbstractState new_pre_es = pre_es.narrowing(_postAbstractTrace[cycle_head]); + SparseAbstractState new_pre_vaddr_es = new_pre_es; + _svfir2ExeState->narrowAddrs(new_pre_es, _postAbstractTrace[cycle_head]); if (new_pre_es >= pre_es) { // decreasing iterations - fixpoint reached pre_es = new_pre_es; - _postES[cycle_head] = pre_es; + _postAbstractTrace[cycle_head] = pre_es; return true; } else { pre_es = new_pre_es; - _postES[cycle_head] = pre_es; + _postAbstractTrace[cycle_head] = pre_es; return false; } } @@ -934,7 +936,7 @@ void AbstractExecution::SkipRecursiveCall(const CallICFGNode *callNode) { if (const RetPE *retPE = SVFUtil::dyn_cast(*retNode->getSVFStmts().begin())) { - AbstractExeState es; + SparseAbstractState es; if (!retPE->getLHSVar()->isPointer() && !retPE->getLHSVar()->isConstDataOrAggDataButNotNullPtr()) _svfir2ExeState->getEs()[retPE->getLHSVarID()] = IntervalValue::top(); } @@ -970,7 +972,7 @@ void AbstractExecution::SkipRecursiveFunc(const SVFFunction *func) { const SVFVar *rhsVar = store->getRHSVar(); u32_t lhs = store->getLHSVarID(); - AbstractExeState&curES = _svfir2ExeState->getEs(); + SparseAbstractState&curES = _svfir2ExeState->getEs(); if (curES.inVarToAddrsTable(lhs)) { if (!rhsVar->isPointer() && !rhsVar->isConstDataOrAggDataButNotNullPtr()) @@ -994,9 +996,9 @@ void AEStat::countStateSize() if (count == 0) { generalNumMap["Global_ES_Var_AVG_Num"] = - AbstractExeState::globalES.getVarToVal().size(); + SparseAbstractState::globalES.getVarToVal().size(); generalNumMap["Global_ES_Loc_AVG_Num"] = - AbstractExeState::globalES.getLocToVal().size(); + SparseAbstractState::globalES.getLocToVal().size(); generalNumMap["ES_Var_AVG_Num"] = 0; generalNumMap["ES_Loc_AVG_Num"] = 0; generalNumMap["ES_Var_Addr_AVG_Num"] = 0; @@ -1114,7 +1116,7 @@ void AbstractExecution::initExtFunMap() #define SSE_FUNC_PROCESS(LLVM_NAME ,FUNC_NAME) \ auto sse_##FUNC_NAME = [this](const CallSite &cs) { \ /* run real ext function */ \ - AbstractExeState&es = _svfir2ExeState->getEs(); \ + SparseAbstractState&es = _svfir2ExeState->getEs(); \ u32_t rhs_id = _svfir->getValueNode(cs.getArgument(0)); \ if (!es.inVarToValTable(rhs_id)) return; \ u32_t rhs = _svfir2ExeState->getEs()[rhs_id].getInterval().lb().getIntNumeral(); \ @@ -1149,7 +1151,7 @@ void AbstractExecution::initExtFunMap() const CallICFGNode* callNode = SVFUtil::dyn_cast(_svfir->getICFG()->getICFGNode(cs.getInstruction())); _checkpoints.erase(callNode); u32_t arg0 = _svfir->getValueNode(cs.getArgument(0)); - AbstractExeState&es = _svfir2ExeState->getEs(); + SparseAbstractState&es = _svfir2ExeState->getEs(); es[arg0].getInterval().meet_with(IntervalValue(1, 1)); if (es[arg0].getInterval().equals(IntervalValue(1, 1))) { @@ -1167,7 +1169,7 @@ void AbstractExecution::initExtFunMap() auto svf_print = [&](const CallSite &cs) { if (cs.arg_size() < 2) return; - AbstractExeState&es = _svfir2ExeState->getEs(); + SparseAbstractState&es = _svfir2ExeState->getEs(); u32_t num_id = _svfir->getValueNode(cs.getArgument(0)); std::string text = strRead(cs.getArgument(1)); assert(es.inVarToValTable(num_id) && "print() should pass integer"); @@ -1184,7 +1186,7 @@ void AbstractExecution::initExtFunMap() std::string AbstractExecution::strRead(const SVFValue* rhs) { // sse read string nodeID->string - AbstractExeState&es = _svfir2ExeState->getEs(); + SparseAbstractState&es = _svfir2ExeState->getEs(); std::string str0; for (u32_t index = 0; index < Options::MaxFieldLimit(); index++) @@ -1495,7 +1497,7 @@ AbstractValue AbstractExecution::traceMemoryAllocationSize(const SVFValue *value AbstractValue AbstractExecution::getStrlen(const SVF::SVFValue *strValue) { - AbstractExeState&es = _svfir2ExeState->getEs(); + SparseAbstractState&es = _svfir2ExeState->getEs(); AbstractValue dst_size = traceMemoryAllocationSize(strValue); u32_t len = 0; NodeID dstid = _svfir->getValueNode(strValue); @@ -1588,7 +1590,7 @@ void AbstractExecution::handleStrcat(const SVF::CallICFGNode *call) void AbstractExecution::handleMemcpy(const SVF::SVFValue *dst, const SVF::SVFValue *src, AbstractValue len, u32_t start_idx) { - AbstractExeState&es = _svfir2ExeState->getEs(); + SparseAbstractState&es = _svfir2ExeState->getEs(); u32_t dstId = _svfir->getValueNode(dst); // pts(dstId) = {objid} objbar objtypeinfo->getType(). u32_t srcId = _svfir->getValueNode(src); u32_t elemSize = 1; @@ -1663,7 +1665,7 @@ const SVFType* AbstractExecution::getPointeeElement(NodeID id) void AbstractExecution::handleMemset(const SVF::SVFValue *dst, AbstractValue elem, AbstractValue len) { - AbstractExeState&es = _svfir2ExeState->getEs(); + SparseAbstractState&es = _svfir2ExeState->getEs(); u32_t dstId = _svfir->getValueNode(dst); u32_t size = std::min((u32_t)Options::MaxFieldLimit(), (u32_t) len.lb().getIntNumeral()); u32_t elemSize = 1; diff --git a/svf/lib/AE/Svfexe/BufOverflowChecker.cpp b/svf/lib/AE/Svfexe/BufOverflowChecker.cpp index cd75a37dd..ef26a69c2 100644 --- a/svf/lib/AE/Svfexe/BufOverflowChecker.cpp +++ b/svf/lib/AE/Svfexe/BufOverflowChecker.cpp @@ -138,7 +138,7 @@ void BufOverflowChecker::initExtFunMap() { //scanf("%d", &data); if (cs.arg_size() < 2) return; - AbstractExeState&es = _svfir2ExeState->getEs(); + SparseAbstractState&es = _svfir2ExeState->getEs(); u32_t dst_id = _svfir->getValueNode(cs.getArgument(1)); if (!_svfir2ExeState->inVarToAddrsTable(dst_id)) { @@ -161,7 +161,7 @@ void BufOverflowChecker::initExtFunMap() { //fscanf(stdin, "%d", &data); if (cs.arg_size() < 3) return; - AbstractExeState&es = _svfir2ExeState->getEs(); + SparseAbstractState&es = _svfir2ExeState->getEs(); u32_t dst_id = _svfir->getValueNode(cs.getArgument(2)); if (!_svfir2ExeState->inVarToAddrsTable(dst_id)) { @@ -193,7 +193,7 @@ void BufOverflowChecker::initExtFunMap() auto sse_fread = [&](const CallSite &cs) { if (cs.arg_size() < 3) return; - AbstractExeState&es = _svfir2ExeState->getEs(); + SparseAbstractState&es = _svfir2ExeState->getEs(); u32_t block_count_id = _svfir->getValueNode(cs.getArgument(2)); u32_t block_size_id = _svfir->getValueNode(cs.getArgument(1)); AbstractValue block_count = es[block_count_id]; @@ -211,7 +211,7 @@ void BufOverflowChecker::initExtFunMap() auto sse_snprintf = [&](const CallSite &cs) { if (cs.arg_size() < 2) return; - AbstractExeState&es = _svfir2ExeState->getEs(); + SparseAbstractState&es = _svfir2ExeState->getEs(); u32_t size_id = _svfir->getValueNode(cs.getArgument(1)); u32_t dst_id = _svfir->getValueNode(cs.getArgument(0)); // get elem size of arg2 @@ -260,7 +260,7 @@ void BufOverflowChecker::initExtFunMap() // itoa(num, ch, 10); // num: int, ch: char*, 10 is decimal if (cs.arg_size() < 3) return; - AbstractExeState&es = _svfir2ExeState->getEs(); + SparseAbstractState&es = _svfir2ExeState->getEs(); u32_t num_id = _svfir->getValueNode(cs.getArgument(0)); u32_t num = (u32_t) es[num_id].getInterval().getNumeral(); @@ -275,7 +275,7 @@ void BufOverflowChecker::initExtFunMap() // check the arg size if (cs.arg_size() < 1) return; const SVFValue* strValue = cs.getArgument(0); - AbstractExeState&es = _svfir2ExeState->getEs(); + SparseAbstractState&es = _svfir2ExeState->getEs(); AbstractValue dst_size = getStrlen(strValue); u32_t elemSize = 1; if (strValue->getType()->isArrayTy()) @@ -299,7 +299,7 @@ void BufOverflowChecker::initExtFunMap() { // recv(sockfd, buf, len, flags); if (cs.arg_size() < 4) return; - AbstractExeState&es = _svfir2ExeState->getEs(); + SparseAbstractState&es = _svfir2ExeState->getEs(); u32_t len_id = _svfir->getValueNode(cs.getArgument(2)); AbstractValue len = es[len_id] - IntervalValue(1); u32_t lhsId = _svfir->getValueNode(cs.getInstruction()); @@ -314,7 +314,7 @@ void BufOverflowChecker::initExtFunMap() _checkpoints.erase(callNode); //void SAFE_BUFACCESS(void* data, int size); if (cs.arg_size() < 2) return; - AbstractExeState&es = _svfir2ExeState->getEs(); + SparseAbstractState&es = _svfir2ExeState->getEs(); u32_t size_id = _svfir->getValueNode(cs.getArgument(1)); AbstractValue val = es[size_id]; if (val.isBottom()) @@ -344,7 +344,7 @@ void BufOverflowChecker::initExtFunMap() _checkpoints.erase(callNode); //void UNSAFE_BUFACCESS(void* data, int size); if (cs.arg_size() < 2) return; - AbstractExeState&es = _svfir2ExeState->getEs(); + SparseAbstractState&es = _svfir2ExeState->getEs(); u32_t size_id = _svfir->getValueNode(cs.getArgument(1)); AbstractValue val = es[size_id]; if (val.isBottom()) diff --git a/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp b/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp index ffa078b9e..3a7c00e29 100644 --- a/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp +++ b/svf/lib/AE/Svfexe/SVFIR2ItvExeState.cpp @@ -271,7 +271,7 @@ AbstractValue SVFIR2ItvExeState::getFPTruncValue(const SVF::SVFVar* var, const S return _es[var->getId()].getInterval(); } -void SVFIR2ItvExeState::applySummary(AbstractExeState&es) +void SVFIR2ItvExeState::applySummary(SparseAbstractState&es) { for (const auto &item: es._varToAbsVal) { @@ -287,20 +287,20 @@ void SVFIR2ItvExeState::moveToGlobal() { for (const auto &it: _es._varToAbsVal) { - AbstractExeState::globalES._varToAbsVal.insert(it); + SparseAbstractState::globalES._varToAbsVal.insert(it); } for (const auto &it: _es._locToAbsVal) { - AbstractExeState::globalES._locToAbsVal.insert(it); + SparseAbstractState::globalES._locToAbsVal.insert(it); } _es._varToAbsVal.clear(); - AbstractExeState::globalES._varToAbsVal.erase(PAG::getPAG()->getBlkPtr()); + SparseAbstractState::globalES._varToAbsVal.erase(PAG::getPAG()->getBlkPtr()); _es._varToAbsVal[PAG::getPAG()->getBlkPtr()] = IntervalValue::top(); _es._locToAbsVal.clear(); } -void SVFIR2ItvExeState::widenAddrs(AbstractExeState&lhs, const AbstractExeState&rhs) +void SVFIR2ItvExeState::widenAddrs(SparseAbstractState&lhs, const SparseAbstractState&rhs) { for (const auto &rhsItem: rhs._varToAbsVal) { @@ -345,7 +345,7 @@ void SVFIR2ItvExeState::widenAddrs(AbstractExeState&lhs, const AbstractExeState& } } -void SVFIR2ItvExeState::narrowAddrs(AbstractExeState&lhs, const AbstractExeState&rhs) +void SVFIR2ItvExeState::narrowAddrs(SparseAbstractState&lhs, const SparseAbstractState&rhs) { for (const auto &rhsItem: rhs._varToAbsVal) { @@ -585,26 +585,26 @@ void SVFIR2ItvExeState::initObjVar(const ObjVar *objVar, u32_t varId) if (const SVFConstantInt *consInt = SVFUtil::dyn_cast(obj->getValue())) { s64_t numeral = consInt->getSExtValue(); - AbstractExeState::globalES[varId] = IntervalValue(numeral, numeral); + SparseAbstractState::globalES[varId] = IntervalValue(numeral, numeral); } else if (const SVFConstantFP* consFP = SVFUtil::dyn_cast(obj->getValue())) - AbstractExeState::globalES[varId] = IntervalValue(consFP->getFPValue(), consFP->getFPValue()); + SparseAbstractState::globalES[varId] = IntervalValue(consFP->getFPValue(), consFP->getFPValue()); else if (SVFUtil::isa(obj->getValue())) - AbstractExeState::globalES[varId] = IntervalValue(0, 0); + SparseAbstractState::globalES[varId] = IntervalValue(0, 0); else if (SVFUtil::isa(obj->getValue())) { - AbstractExeState::globalES[varId] = AddressValue(getVirtualMemAddress(varId)); + SparseAbstractState::globalES[varId] = AddressValue(getVirtualMemAddress(varId)); } else if (obj->isConstantArray() || obj->isConstantStruct()) - AbstractExeState::globalES[varId] = IntervalValue::top(); + SparseAbstractState::globalES[varId] = IntervalValue::top(); else - AbstractExeState::globalES[varId] = IntervalValue::top(); + SparseAbstractState::globalES[varId] = IntervalValue::top(); } else - AbstractExeState::globalES[varId] = AddressValue(getVirtualMemAddress(varId)); + SparseAbstractState::globalES[varId] = AddressValue(getVirtualMemAddress(varId)); } else - AbstractExeState::globalES[varId] = AddressValue(getVirtualMemAddress(varId)); + SparseAbstractState::globalES[varId] = AddressValue(getVirtualMemAddress(varId)); } void SVFIR2ItvExeState::initSVFVar(u32_t varId) @@ -633,16 +633,16 @@ void SVFIR2ItvExeState::translateAddr(const AddrStmt *addr) // if addr RHS is integerType(i8 i32 etc), value should be limited. if (addr->getRHSVar()->getType()->getKind() == SVFType::SVFIntegerTy) { - AbstractExeState::globalES[addr->getRHSVarID()].meet_with(getRangeLimitFromType(addr->getRHSVar()->getType())); + SparseAbstractState::globalES[addr->getRHSVarID()].meet_with(getRangeLimitFromType(addr->getRHSVar()->getType())); } - AbstractExeState::globalES[addr->getLHSVarID()] = - AbstractExeState::globalES[addr->getRHSVarID()]; + SparseAbstractState::globalES[addr->getLHSVarID()] = + SparseAbstractState::globalES[addr->getRHSVarID()]; } else if (inVarToAddrsTable(addr->getRHSVarID())) { - AbstractExeState::globalES[addr->getLHSVarID()] = - AbstractExeState::globalES[addr->getRHSVarID()]; + SparseAbstractState::globalES[addr->getLHSVarID()] = + SparseAbstractState::globalES[addr->getRHSVarID()]; } else { From 5609cc11b63f90876009417785f39c782be22cd6 Mon Sep 17 00:00:00 2001 From: bjjwwang Date: Thu, 4 Apr 2024 12:18:24 +1100 Subject: [PATCH 7/7] rename abstractInterpretation --- svf-llvm/tools/AE/ae.cpp | 2 +- ...ctExecution.h => AbstractInterpretation.h} | 17 ++-- svf/include/AE/Svfexe/BufOverflowChecker.h | 8 +- ...ecution.cpp => AbstractInterpretation.cpp} | 98 +++++++++---------- svf/lib/AE/Svfexe/BufOverflowChecker.cpp | 6 +- 5 files changed, 66 insertions(+), 65 deletions(-) rename svf/include/AE/Svfexe/{AbstractExecution.h => AbstractInterpretation.h} (96%) rename svf/lib/AE/Svfexe/{AbstractExecution.cpp => AbstractInterpretation.cpp} (94%) diff --git a/svf-llvm/tools/AE/ae.cpp b/svf-llvm/tools/AE/ae.cpp index 7339f2ee3..e25c7da4b 100644 --- a/svf-llvm/tools/AE/ae.cpp +++ b/svf-llvm/tools/AE/ae.cpp @@ -663,7 +663,7 @@ int main(int argc, char** argv) } else { - AbstractExecution ae; + AbstractInterpretation ae; ae.runOnModule(pag->getICFG()); } diff --git a/svf/include/AE/Svfexe/AbstractExecution.h b/svf/include/AE/Svfexe/AbstractInterpretation.h similarity index 96% rename from svf/include/AE/Svfexe/AbstractExecution.h rename to svf/include/AE/Svfexe/AbstractInterpretation.h index 067ed528b..7040b134c 100644 --- a/svf/include/AE/Svfexe/AbstractExecution.h +++ b/svf/include/AE/Svfexe/AbstractInterpretation.h @@ -1,4 +1,4 @@ -//===- AE.cpp -- Abstract Execution---------------------------------// +//===- AbstractInterpretation.h -- Abstract Execution----------// // // SVF: Static Value-Flow Analysis // @@ -35,7 +35,7 @@ namespace SVF { -class AbstractExecution; +class AbstractInterpretation; class AEStat; class AEAPI; class ExeState; @@ -53,7 +53,7 @@ class AEStat : public SVFStat { public: void countStateSize(); - AEStat(AbstractExecution* ae) : _ae(ae) + AEStat(AbstractInterpretation* ae) : _ae(ae) { startTime = getClk(true); } @@ -71,7 +71,7 @@ class AEStat : public SVFStat void reportBug(); public: - AbstractExecution* _ae; + AbstractInterpretation* _ae; s32_t count{0}; std::string memory_usage; std::string memUsage; @@ -104,7 +104,8 @@ class AEStat : public SVFStat } }; -class AbstractExecution +/// AbstractInterpretation is same as Abstract Execution +class AbstractInterpretation { friend class AEStat; friend class AEAPI; @@ -113,17 +114,17 @@ class AbstractExecution enum ExtAPIType { UNCLASSIFIED, MEMCPY, MEMSET, STRCPY, STRCAT }; typedef SCCDetection CallGraphSCC; /// Constructor - AbstractExecution(); + AbstractInterpretation(); virtual void runOnModule(ICFG* icfg); /// Destructor - virtual ~AbstractExecution(); + virtual ~AbstractInterpretation(); /// Program entry void analyse(); - static bool classof(const AbstractExecution* ae) + static bool classof(const AbstractInterpretation* ae) { return ae->getKind() == AEKind::AbstractExecution; } diff --git a/svf/include/AE/Svfexe/BufOverflowChecker.h b/svf/include/AE/Svfexe/BufOverflowChecker.h index 2615737bc..8b7fdc326 100644 --- a/svf/include/AE/Svfexe/BufOverflowChecker.h +++ b/svf/include/AE/Svfexe/BufOverflowChecker.h @@ -28,7 +28,7 @@ // Created by Jiawei Wang on 2024/1/12. // -#include "AE/Svfexe/AbstractExecution.h" +#include "AE/Svfexe/AbstractInterpretation.h" namespace SVF { @@ -100,17 +100,17 @@ struct BufOverflowException: public std::exception const SVFValue* _allocVar; }; -class BufOverflowChecker: public AbstractExecution +class BufOverflowChecker: public AbstractInterpretation { public: - BufOverflowChecker() : AbstractExecution() + BufOverflowChecker() : AbstractInterpretation() { initExtFunMap(); _kind = AEKind::BufOverflowChecker; initExtAPIBufOverflowCheckRules(); } - static bool classof(const AbstractExecution* ae) + static bool classof(const AbstractInterpretation* ae) { return ae->getKind() == AEKind::BufOverflowChecker; } diff --git a/svf/lib/AE/Svfexe/AbstractExecution.cpp b/svf/lib/AE/Svfexe/AbstractInterpretation.cpp similarity index 94% rename from svf/lib/AE/Svfexe/AbstractExecution.cpp rename to svf/lib/AE/Svfexe/AbstractInterpretation.cpp index 71aeed9eb..d2de42621 100644 --- a/svf/lib/AE/Svfexe/AbstractExecution.cpp +++ b/svf/lib/AE/Svfexe/AbstractInterpretation.cpp @@ -25,10 +25,10 @@ // Created by Jiawei Wang on 2024/1/10. // -#include "Util/WorkList.h" +#include "AE/Svfexe/AbstractInterpretation.h" #include "SVFIR/SVFIR.h" -#include "AE/Svfexe/AbstractExecution.h" #include "Util/Options.h" +#include "Util/WorkList.h" #include using namespace SVF; @@ -84,7 +84,7 @@ Map _switch_lhsrhs_predicate = }; -void AbstractExecution::runOnModule(ICFG *icfg) +void AbstractInterpretation::runOnModule(ICFG *icfg) { // 1. Start clock _stat->startClk(); @@ -120,13 +120,13 @@ void AbstractExecution::runOnModule(ICFG *icfg) _stat->reportBug(); } -AbstractExecution::AbstractExecution() +AbstractInterpretation::AbstractInterpretation() { _stat = new AEStat(this); initExtFunMap(); } /// Destructor -AbstractExecution::~AbstractExecution() +AbstractInterpretation::~AbstractInterpretation() { delete _stat; delete _svfir2ExeState; @@ -135,7 +135,7 @@ AbstractExecution::~AbstractExecution() } -void AbstractExecution::markRecursiveFuns() +void AbstractInterpretation::markRecursiveFuns() { // detect if callgraph has cycle CallGraphSCC* _callGraphScc = _ander->getCallGraphSCC(); @@ -149,7 +149,7 @@ void AbstractExecution::markRecursiveFuns() } /// Program entry -void AbstractExecution::analyse() +void AbstractInterpretation::analyse() { // handle Global ICFGNode of SVFModule handleGlobalNode(); @@ -160,7 +160,7 @@ void AbstractExecution::analyse() } /// handle global node -void AbstractExecution::handleGlobalNode() +void AbstractInterpretation::handleGlobalNode() { SparseAbstractState es; const ICFGNode* node = _icfg->getGlobalICFGNode(); @@ -177,7 +177,7 @@ void AbstractExecution::handleGlobalNode() /// get execution state by merging states of predecessor blocks /// Scenario 1: preblock -----(intraEdge)----> block, join the preES of inEdges /// Scenario 2: preblock -----(callEdge)----> block -bool AbstractExecution::hasInEdgesES(const ICFGNode *block) +bool AbstractInterpretation::hasInEdgesES(const ICFGNode *block) { if (isGlobalEntry(block)) { @@ -233,7 +233,7 @@ bool AbstractExecution::hasInEdgesES(const ICFGNode *block) assert(false && "implement this part"); } -bool AbstractExecution::isFunEntry(const SVF::ICFGNode *block) +bool AbstractInterpretation::isFunEntry(const SVF::ICFGNode *block) { if (SVFUtil::isa(block)) { @@ -245,7 +245,7 @@ bool AbstractExecution::isFunEntry(const SVF::ICFGNode *block) return false; } -bool AbstractExecution::isGlobalEntry(const SVF::ICFGNode *block) +bool AbstractInterpretation::isGlobalEntry(const SVF::ICFGNode *block) { for (auto *edge : _icfg->getGlobalICFGNode()->getOutEdges()) { @@ -257,7 +257,7 @@ bool AbstractExecution::isGlobalEntry(const SVF::ICFGNode *block) return false; } -bool AbstractExecution::hasCmpBranchES(const CmpStmt* cmpStmt, s64_t succ, +bool AbstractInterpretation::hasCmpBranchES(const CmpStmt* cmpStmt, s64_t succ, SparseAbstractState& es) { SparseAbstractState new_es = es; @@ -488,7 +488,7 @@ bool AbstractExecution::hasCmpBranchES(const CmpStmt* cmpStmt, s64_t succ, return true; } -bool AbstractExecution::hasSwitchBranchES(const SVFVar* var, s64_t succ, +bool AbstractInterpretation::hasSwitchBranchES(const SVFVar* var, s64_t succ, SparseAbstractState& es) { SparseAbstractState new_es = es; @@ -533,7 +533,7 @@ bool AbstractExecution::hasSwitchBranchES(const SVFVar* var, s64_t succ, return true; } -bool AbstractExecution::hasBranchES(const IntraCFGEdge* intraEdge, +bool AbstractInterpretation::hasBranchES(const IntraCFGEdge* intraEdge, SparseAbstractState& es) { const SVFValue *cond = intraEdge->getCondition(); @@ -560,7 +560,7 @@ bool AbstractExecution::hasBranchES(const IntraCFGEdge* intraEdge, return true; } /// handle instructions in svf basic blocks -void AbstractExecution::handleWTONode(const ICFGNode *node) +void AbstractInterpretation::handleWTONode(const ICFGNode *node) { _stat->getBlockTrace()++; // Get execution states from in edges @@ -589,7 +589,7 @@ void AbstractExecution::handleWTONode(const ICFGNode *node) _postAbstractTrace[node] = _svfir2ExeState->getEs(); } -void AbstractExecution::handleCallSite(const ICFGNode* node) +void AbstractInterpretation::handleCallSite(const ICFGNode* node) { if (const CallICFGNode* callNode = SVFUtil::dyn_cast(node)) { @@ -620,26 +620,26 @@ void AbstractExecution::handleCallSite(const ICFGNode* node) } } -bool AbstractExecution::isExtCall(const SVF::CallICFGNode *callNode) +bool AbstractInterpretation::isExtCall(const SVF::CallICFGNode *callNode) { const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite()); return SVFUtil::isExtCall(callfun); } -void AbstractExecution::extCallPass(const SVF::CallICFGNode *callNode) +void AbstractInterpretation::extCallPass(const SVF::CallICFGNode *callNode) { _callSiteStack.push_back(callNode); handleExtAPI(callNode); _callSiteStack.pop_back(); } -bool AbstractExecution::isRecursiveCall(const SVF::CallICFGNode *callNode) +bool AbstractInterpretation::isRecursiveCall(const SVF::CallICFGNode *callNode) { const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite()); return _recursiveFuns.find(callfun) != _recursiveFuns.end(); } -void AbstractExecution::recursiveCallPass(const SVF::CallICFGNode *callNode) +void AbstractInterpretation::recursiveCallPass(const SVF::CallICFGNode *callNode) { SkipRecursiveCall(callNode); const RetICFGNode *retNode = callNode->getRetICFGNode(); @@ -657,12 +657,12 @@ void AbstractExecution::recursiveCallPass(const SVF::CallICFGNode *callNode) _postAbstractTrace[retNode] = _svfir2ExeState->getEs(); } -bool AbstractExecution::isDirectCall(const SVF::CallICFGNode *callNode) +bool AbstractInterpretation::isDirectCall(const SVF::CallICFGNode *callNode) { const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite()); return _funcToWTO.find(callfun) != _funcToWTO.end(); } -void AbstractExecution::directCallFunPass(const SVF::CallICFGNode *callNode) +void AbstractInterpretation::directCallFunPass(const SVF::CallICFGNode *callNode) { const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite()); SparseAbstractState preES = _svfir2ExeState->getEs(); @@ -678,13 +678,13 @@ void AbstractExecution::directCallFunPass(const SVF::CallICFGNode *callNode) _postAbstractTrace[retNode] = _postAbstractTrace[callNode]; } -bool AbstractExecution::isIndirectCall(const SVF::CallICFGNode *callNode) +bool AbstractInterpretation::isIndirectCall(const SVF::CallICFGNode *callNode) { const auto callsiteMaps = _svfir->getIndirectCallsites(); return callsiteMaps.find(callNode) != callsiteMaps.end(); } -void AbstractExecution::indirectCallFunPass(const SVF::CallICFGNode *callNode) +void AbstractInterpretation::indirectCallFunPass(const SVF::CallICFGNode *callNode) { const auto callsiteMaps = _svfir->getIndirectCallsites(); NodeID call_id = callsiteMaps.at(callNode); @@ -713,7 +713,7 @@ void AbstractExecution::indirectCallFunPass(const SVF::CallICFGNode *callNode) -void AbstractExecution::handleICFGNode(const ICFGNode *curICFGNode) +void AbstractInterpretation::handleICFGNode(const ICFGNode *curICFGNode) { _stat->getICFGNodeTrace()++; // handle SVF Stmt @@ -734,7 +734,7 @@ void AbstractExecution::handleICFGNode(const ICFGNode *curICFGNode) } /// handle wto cycle (loop) -void AbstractExecution::handleCycle(const ICFGWTOCycle *cycle) +void AbstractInterpretation::handleCycle(const ICFGWTOCycle *cycle) { // Get execution states from in edges if (!hasInEdgesES(cycle->head())) @@ -799,7 +799,7 @@ void AbstractExecution::handleCycle(const ICFGWTOCycle *cycle) } } -bool AbstractExecution::widenFixpointPass(const ICFGNode* cycle_head, +bool AbstractInterpretation::widenFixpointPass(const ICFGNode* cycle_head, SparseAbstractState& pre_es) { // increasing iterations @@ -822,7 +822,7 @@ bool AbstractExecution::widenFixpointPass(const ICFGNode* cycle_head, } } -bool AbstractExecution::narrowFixpointPass(const SVF::ICFGNode *cycle_head, SVF::SparseAbstractState&pre_es) +bool AbstractInterpretation::narrowFixpointPass(const SVF::ICFGNode *cycle_head, SVF::SparseAbstractState&pre_es) { // decreasing iterations SparseAbstractState new_pre_es = pre_es.narrowing(_postAbstractTrace[cycle_head]); @@ -846,7 +846,7 @@ bool AbstractExecution::narrowFixpointPass(const SVF::ICFGNode *cycle_head, SVF: /// handle user defined function, ext function is not included. -void AbstractExecution::handleFunc(const SVFFunction *func) +void AbstractInterpretation::handleFunc(const SVFFunction *func) { _stat->getFunctionTrace()++; ICFGWTO* wto = _funcToWTO[func]; @@ -869,7 +869,7 @@ void AbstractExecution::handleFunc(const SVFFunction *func) } } -void AbstractExecution::handleSVFStatement(const SVFStmt *stmt) +void AbstractInterpretation::handleSVFStatement(const SVFStmt *stmt) { if (const AddrStmt *addr = SVFUtil::dyn_cast(stmt)) { @@ -928,7 +928,7 @@ void AbstractExecution::handleSVFStatement(const SVFStmt *stmt) } -void AbstractExecution::SkipRecursiveCall(const CallICFGNode *callNode) +void AbstractInterpretation::SkipRecursiveCall(const CallICFGNode *callNode) { const SVFFunction *callfun = SVFUtil::getCallee(callNode->getCallSite()); const RetICFGNode *retNode = callNode->getRetICFGNode(); @@ -955,7 +955,7 @@ void AbstractExecution::SkipRecursiveCall(const CallICFGNode *callNode) SkipRecursiveFunc(callfun); } -void AbstractExecution::SkipRecursiveFunc(const SVFFunction *func) +void AbstractInterpretation::SkipRecursiveFunc(const SVFFunction *func) { // handle Recursive Funcs, go throw every relevant funcs/blocks. // for every Call Argv, Ret , Global Vars, we make it as Top value @@ -1111,7 +1111,7 @@ void AEStat::reportBug() } } -void AbstractExecution::initExtFunMap() +void AbstractInterpretation::initExtFunMap() { #define SSE_FUNC_PROCESS(LLVM_NAME ,FUNC_NAME) \ auto sse_##FUNC_NAME = [this](const CallSite &cs) { \ @@ -1183,7 +1183,7 @@ void AbstractExecution::initExtFunMap() _checkpoint_names.insert("svf_assert"); }; -std::string AbstractExecution::strRead(const SVFValue* rhs) +std::string AbstractInterpretation::strRead(const SVFValue* rhs) { // sse read string nodeID->string SparseAbstractState&es = _svfir2ExeState->getEs(); @@ -1214,7 +1214,7 @@ std::string AbstractExecution::strRead(const SVFValue* rhs) return str0; } -void AbstractExecution::handleExtAPI(const CallICFGNode *call) +void AbstractInterpretation::handleExtAPI(const CallICFGNode *call) { const SVFFunction *fun = SVFUtil::getCallee(call->getCallSite()); assert(fun && "SVFFunction* is nullptr"); @@ -1280,7 +1280,7 @@ void AbstractExecution::handleExtAPI(const CallICFGNode *call) return; } -void AbstractExecution::collectCheckPoint() +void AbstractInterpretation::collectCheckPoint() { // traverse every ICFGNode for (auto it = _svfir->getICFG()->begin(); it != _svfir->getICFG()->end(); ++it) @@ -1299,7 +1299,7 @@ void AbstractExecution::collectCheckPoint() } } -void AbstractExecution::checkPointAllSet() +void AbstractInterpretation::checkPointAllSet() { if (_checkpoints.size() == 0) { @@ -1318,7 +1318,7 @@ void AbstractExecution::checkPointAllSet() } -void AbstractExecution::handleStrcpy(const CallICFGNode *call) +void AbstractInterpretation::handleStrcpy(const CallICFGNode *call) { // strcpy, __strcpy_chk, stpcpy , wcscpy, __wcscpy_chk // get the dst and src @@ -1330,7 +1330,7 @@ void AbstractExecution::handleStrcpy(const CallICFGNode *call) handleMemcpy(arg0Val, arg1Val, strLen,strLen.lb().getIntNumeral()); } -u32_t AbstractExecution::getAllocaInstByteSize(const AddrStmt *addr) +u32_t AbstractInterpretation::getAllocaInstByteSize(const AddrStmt *addr) { if (const ObjVar* objvar = SVFUtil::dyn_cast(addr->getRHSVar())) { @@ -1363,7 +1363,7 @@ u32_t AbstractExecution::getAllocaInstByteSize(const AddrStmt *addr) abort(); } -AbstractValue AbstractExecution::traceMemoryAllocationSize(const SVFValue *value) +AbstractValue AbstractInterpretation::traceMemoryAllocationSize(const SVFValue *value) { /// Usually called by a GepStmt overflow check, or external API (like memcpy) overflow check /// Defitions of Terms: @@ -1495,7 +1495,7 @@ AbstractValue AbstractExecution::traceMemoryAllocationSize(const SVFValue *value } -AbstractValue AbstractExecution::getStrlen(const SVF::SVFValue *strValue) +AbstractValue AbstractInterpretation::getStrlen(const SVF::SVFValue *strValue) { SparseAbstractState&es = _svfir2ExeState->getEs(); AbstractValue dst_size = traceMemoryAllocationSize(strValue); @@ -1552,7 +1552,7 @@ AbstractValue AbstractExecution::getStrlen(const SVF::SVFValue *strValue) } -void AbstractExecution::handleStrcat(const SVF::CallICFGNode *call) +void AbstractInterpretation::handleStrcat(const SVF::CallICFGNode *call) { // __strcat_chk, strcat, __wcscat_chk, wcscat, __strncat_chk, strncat, __wcsncat_chk, wcsncat // to check it is strcat group or strncat group @@ -1588,7 +1588,7 @@ void AbstractExecution::handleStrcat(const SVF::CallICFGNode *call) } } -void AbstractExecution::handleMemcpy(const SVF::SVFValue *dst, const SVF::SVFValue *src, AbstractValue len, u32_t start_idx) +void AbstractInterpretation::handleMemcpy(const SVF::SVFValue *dst, const SVF::SVFValue *src, AbstractValue len, u32_t start_idx) { SparseAbstractState&es = _svfir2ExeState->getEs(); u32_t dstId = _svfir->getValueNode(dst); // pts(dstId) = {objid} objbar objtypeinfo->getType(). @@ -1645,7 +1645,7 @@ void AbstractExecution::handleMemcpy(const SVF::SVFValue *dst, const SVF::SVFVal } } -const SVFType* AbstractExecution::getPointeeElement(NodeID id) +const SVFType* AbstractInterpretation::getPointeeElement(NodeID id) { if (_svfir2ExeState->inVarToAddrsTable(id)) { @@ -1663,7 +1663,7 @@ const SVFType* AbstractExecution::getPointeeElement(NodeID id) return nullptr; } -void AbstractExecution::handleMemset(const SVF::SVFValue *dst, AbstractValue elem, AbstractValue len) +void AbstractInterpretation::handleMemset(const SVF::SVFValue *dst, AbstractValue elem, AbstractValue len) { SparseAbstractState&es = _svfir2ExeState->getEs(); u32_t dstId = _svfir->getValueNode(dst); @@ -1718,7 +1718,7 @@ void AbstractExecution::handleMemset(const SVF::SVFValue *dst, AbstractValue ele -void AbstractExecution::AccessMemoryViaRetNode(const CallICFGNode *callnode, SVF::FILOWorkList& worklist, Set& visited) +void AbstractInterpretation::AccessMemoryViaRetNode(const CallICFGNode *callnode, SVF::FILOWorkList& worklist, Set& visited) { if (callnode->getRetICFGNode()->getSVFStmts().size() > 0) { @@ -1743,7 +1743,7 @@ void AbstractExecution::AccessMemoryViaRetNode(const CallICFGNode *callnode, SVF } } -void AbstractExecution::AccessMemoryViaCopyStmt(const CopyStmt *copy, SVF::FILOWorkList& worklist, Set& visited) +void AbstractInterpretation::AccessMemoryViaCopyStmt(const CopyStmt *copy, SVF::FILOWorkList& worklist, Set& visited) { if (!visited.count(copy->getRHSVar()->getValue())) { @@ -1752,7 +1752,7 @@ void AbstractExecution::AccessMemoryViaCopyStmt(const CopyStmt *copy, SVF::FILOW } } -void AbstractExecution::AccessMemoryViaLoadStmt(const LoadStmt *load, SVF::FILOWorkList& worklist, Set& visited) +void AbstractInterpretation::AccessMemoryViaLoadStmt(const LoadStmt *load, SVF::FILOWorkList& worklist, Set& visited) { if (_svfir2ExeState->inVarToAddrsTable(load->getLHSVarID())) { @@ -1772,7 +1772,7 @@ void AbstractExecution::AccessMemoryViaLoadStmt(const LoadStmt *load, SVF::FILOW } } -void AbstractExecution::AccessMemoryViaCallArgs(const SVF::SVFArgument *arg, +void AbstractInterpretation::AccessMemoryViaCallArgs(const SVF::SVFArgument *arg, SVF::FILOWorkList &worklist, Set &visited) { diff --git a/svf/lib/AE/Svfexe/BufOverflowChecker.cpp b/svf/lib/AE/Svfexe/BufOverflowChecker.cpp index ef26a69c2..70cf5e176 100644 --- a/svf/lib/AE/Svfexe/BufOverflowChecker.cpp +++ b/svf/lib/AE/Svfexe/BufOverflowChecker.cpp @@ -61,7 +61,7 @@ std::string IntervalToIntStr(const IntervalValue& inv) void BufOverflowChecker::handleSVFStatement(const SVFStmt *stmt) { - AbstractExecution::handleSVFStatement(stmt); + AbstractInterpretation::handleSVFStatement(stmt); // for gep stmt, add the gep stmt to the addrToGep map if (const GepStmt *gep = SVFUtil::dyn_cast(stmt)) { @@ -413,7 +413,7 @@ bool BufOverflowChecker::detectStrcat(const CallICFGNode *call) void BufOverflowChecker::handleExtAPI(const CallICFGNode *call) { - AbstractExecution::handleExtAPI(call); + AbstractInterpretation::handleExtAPI(call); const SVFFunction *fun = SVFUtil::getCallee(call->getCallSite()); assert(fun && "SVFFunction* is nullptr"); CallSite cs = SVFUtil::getSVFCallSite(call->getCallSite()); @@ -733,7 +733,7 @@ bool BufOverflowChecker::canSafelyAccessMemory(const SVFValue *value, const Abst void BufOverflowChecker::handleICFGNode(const SVF::ICFGNode *node) { - AbstractExecution::handleICFGNode(node); + AbstractInterpretation::handleICFGNode(node); detectBufOverflow(node); }