From 3095568c7fc0b02ecc528d7b0d1d9b75f930b54f Mon Sep 17 00:00:00 2001 From: bjjwwang Date: Thu, 23 May 2024 13:00:57 +1000 Subject: [PATCH 1/8] refactor APIs in AbstractState/Value --- svf/include/AE/Core/AbstractState.h | 6 +- svf/include/AE/Core/AbstractValue.h | 55 ++---- svf/include/AE/Core/AddressValue.h | 4 +- svf/include/AE/Core/RelExeState.h | 2 + svf/include/AE/Svfexe/SVFIR2AbsState.h | 15 +- svf/lib/AE/Svfexe/AbstractInterpretation.cpp | 19 +- svf/lib/AE/Svfexe/SVFIR2AbsState.cpp | 186 ++++++++----------- 7 files changed, 119 insertions(+), 168 deletions(-) diff --git a/svf/include/AE/Core/AbstractState.h b/svf/include/AE/Core/AbstractState.h index 8829eddc9..b281997a9 100644 --- a/svf/include/AE/Core/AbstractState.h +++ b/svf/include/AE/Core/AbstractState.h @@ -80,6 +80,8 @@ class AbstractState /// The physical address starts with 0x7f...... + idx static inline u32_t getVirtualMemAddress(u32_t idx) { + if (idx == 0) + assert(false && "idx cannot be 0"); return AddressValue::getVirtualMemAddress(idx); } @@ -224,7 +226,7 @@ class AbstractState } /// whether the memory address stores memory addresses - inline bool inLocToAddrsTable(u32_t id) const + inline bool inAddrToAddrsTable(u32_t id) const { if (_addrToAbsVal.find(id)!= _addrToAbsVal.end()) { @@ -237,7 +239,7 @@ class AbstractState } /// whether the memory address stores abstract value - inline virtual bool inLocToValTable(u32_t id) const + inline virtual bool inAddrToValTable(u32_t id) const { if (_addrToAbsVal.find(id) != _addrToAbsVal.end()) { diff --git a/svf/include/AE/Core/AbstractValue.h b/svf/include/AE/Core/AbstractValue.h index 292cfa649..764485438 100644 --- a/svf/include/AE/Core/AbstractValue.h +++ b/svf/include/AE/Core/AbstractValue.h @@ -39,7 +39,7 @@ class AbstractValue }; DataType type; IntervalValue interval; - AddressValue addr; + AddressValue addrs; AbstractValue() : type(IntervalType) { @@ -53,7 +53,7 @@ class AbstractValue interval = IntervalValue::top(); break; case AddressType: - addr = AddressValue(); + addrs = AddressValue(); break; case UnknownType: break; @@ -68,7 +68,7 @@ class AbstractValue interval = other.interval; break; case AddressType: - addr = other.addr; + addrs = other.addrs; break; case UnknownType: break; @@ -101,7 +101,7 @@ class AbstractValue interval = other.interval; break; case AddressType: - addr = other.addr; + addrs = other.addrs; break; case UnknownType: break; @@ -118,7 +118,7 @@ class AbstractValue interval = other.interval; break; case AddressType: - addr = other.addr; + addrs = other.addrs; break; case UnknownType: break; @@ -136,38 +136,13 @@ class AbstractValue AbstractValue& operator=(const AddressValue& other) { type = AddressType; - addr = other; + addrs = other; 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; - } - - AbstractValue operator!=(const AbstractValue& other) const - { - 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) {} + AbstractValue(const AddressValue& addr) : type(AddressType), addrs(addr) {} IntervalValue& getInterval() { @@ -175,26 +150,22 @@ class AbstractValue { interval = IntervalValue::top(); } - assert(isInterval() && "Attempting to retrieve an AbstractValue that is not an Interval!"); return interval; } const IntervalValue getInterval() const { - assert(isInterval() && "Attempting to retrieve an AbstractValue that is not an Interval!"); return interval; } AddressValue& getAddrs() { - assert(isAddr() && "Attempting to retrieve an AbstractValue that is not an Address!"); - return addr; + return addrs; } const AddressValue getAddrs() const { - assert(isAddr() && "Attempting to retrieve an AbstractValue that is not an Address!"); - return addr; + return addrs; } ~AbstractValue() {}; @@ -211,7 +182,7 @@ class AbstractValue } if (isAddr()) { - return addr.equals(rhs.addr); + return addrs.equals(rhs.addrs); } return false; } @@ -233,7 +204,7 @@ class AbstractValue } if (isAddr() && other.isAddr()) { - addr.join_with(other.addr); + addrs.join_with(other.addrs); } return; } @@ -250,7 +221,7 @@ class AbstractValue } if (isAddr() && other.isAddr()) { - addr.meet_with(other.addr); + addrs.meet_with(other.addrs); } return; } @@ -281,7 +252,7 @@ class AbstractValue } else if (isAddr()) { - return addr.toString(); + return addrs.toString(); } return ""; } diff --git a/svf/include/AE/Core/AddressValue.h b/svf/include/AE/Core/AddressValue.h index eead17b80..94be8ac7b 100644 --- a/svf/include/AE/Core/AddressValue.h +++ b/svf/include/AE/Core/AddressValue.h @@ -211,13 +211,15 @@ class AddressValue /// The physical address starts with 0x7f...... + idx static inline u32_t getVirtualMemAddress(u32_t idx) { + if (idx == 0) + assert(false && "idx cannot be 0"); return AddressMask + idx; } /// Check bit value of val start with 0x7F000000, filter by 0xFF000000 static inline bool isVirtualMemAddress(u32_t val) { - return (val & 0xff000000) == AddressMask; + return (val & 0xff000000) == AddressMask && val != AddressMask + 0; } /// Return the internal index if idx is an address otherwise return the value of idx diff --git a/svf/include/AE/Core/RelExeState.h b/svf/include/AE/Core/RelExeState.h index f97e80777..e43c1f035 100644 --- a/svf/include/AE/Core/RelExeState.h +++ b/svf/include/AE/Core/RelExeState.h @@ -175,6 +175,8 @@ class RelExeState /// Check bit value of val start with 0x7F000000, filter by 0xFF000000 static inline bool isVirtualMemAddress(u32_t val) { + if (val == 0) + assert(false && "val cannot be 0"); return AddressValue::isVirtualMemAddress(val); } diff --git a/svf/include/AE/Svfexe/SVFIR2AbsState.h b/svf/include/AE/Svfexe/SVFIR2AbsState.h index 6664c890d..adca71ad3 100644 --- a/svf/include/AE/Svfexe/SVFIR2AbsState.h +++ b/svf/include/AE/Svfexe/SVFIR2AbsState.h @@ -109,6 +109,15 @@ class SVFIR2AbsState return globalNulladdrs; } + inline bool inVarTable(const AbstractState& es, u32_t id) const + { + return es.inVarToValTable(id) || es.inVarToAddrsTable(id); + } + + inline bool inAddrTable(const AbstractState& es, u32_t id) const + { + return es.inAddrToValTable(id) || es.inAddrToAddrsTable(id); + } /// whether the variable is in varToVal table inline bool inVarToValTable(const AbstractState& es, u32_t id) const @@ -126,13 +135,13 @@ class SVFIR2AbsState /// whether the memory address stores a interval value inline bool inLocToValTable(const AbstractState& es, u32_t id) const { - return es.inLocToValTable(id); + return es.inAddrToValTable(id); } /// whether the memory address stores memory addresses inline bool inLocToAddrsTable(const AbstractState& es, u32_t id) const { - return es.inLocToAddrsTable(id); + return es.inAddrToAddrsTable(id); } void handleAddr(AbstractState& es, const AddrStmt *addr); @@ -166,6 +175,8 @@ class SVFIR2AbsState /// The physical address starts with 0x7f...... + idx static inline u32_t getVirtualMemAddress(u32_t idx) { + if (idx == 0) + assert(false && "idx cannot be 0"); return AbstractState::getVirtualMemAddress(idx); } diff --git a/svf/lib/AE/Svfexe/AbstractInterpretation.cpp b/svf/lib/AE/Svfexe/AbstractInterpretation.cpp index 03d387578..1cd19499b 100644 --- a/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +++ b/svf/lib/AE/Svfexe/AbstractInterpretation.cpp @@ -166,6 +166,7 @@ void AbstractInterpretation::handleGlobalNode() AbstractState as; const ICFGNode* node = _icfg->getGlobalICFGNode(); _postAbsTrace[node] = _preAbsTrace[node]; + _postAbsTrace[node][0] = AddressValue(); // Global Node, we just need to handle addr, load, store, copy and gep for (const SVFStmt *stmt: node->getSVFStmts()) { @@ -345,7 +346,7 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s for (const auto &addr: addrs) { NodeID objId = new_es.getInternalID(addr); - if (new_es.inLocToValTable(objId)) + if (new_es.inAddrToValTable(objId)) { new_es.load(addr).meet_with(rhs); } @@ -367,7 +368,7 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s for (const auto &addr: addrs) { NodeID objId = new_es.getInternalID(addr); - if (new_es.inLocToValTable(objId)) + if (new_es.inAddrToValTable(objId)) { new_es.load(addr).meet_with( IntervalValue(rhs.lb() + 1, IntervalValue::plus_infinity())); @@ -385,7 +386,7 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s for (const auto &addr: addrs) { NodeID objId = new_es.getInternalID(addr); - if (new_es.inLocToValTable(objId)) + if (new_es.inAddrToValTable(objId)) { new_es.load(addr).meet_with( IntervalValue(rhs.lb(), IntervalValue::plus_infinity())); @@ -404,7 +405,7 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s for (const auto &addr: addrs) { NodeID objId = new_es.getInternalID(addr); - if (new_es.inLocToValTable(objId)) + if (new_es.inAddrToValTable(objId)) { new_es.load(addr).meet_with( IntervalValue(IntervalValue::minus_infinity(), rhs.ub() - 1)); @@ -423,7 +424,7 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s for (const auto &addr: addrs) { NodeID objId = new_es.getInternalID(addr); - if (new_es.inLocToValTable(objId)) + if (new_es.inAddrToValTable(objId)) { new_es.load(addr).meet_with( IntervalValue(IntervalValue::minus_infinity(), rhs.ub())); @@ -475,7 +476,7 @@ bool AbstractInterpretation::isSwitchBranchFeasible(const SVFVar* var, s64_t suc for (const auto &addr: addrs) { NodeID objId = new_es.getInternalID(addr); - if (new_es.inLocToValTable(objId)) + if (new_es.inAddrToValTable(objId)) { new_es.load(addr).meet_with(switch_cond); } @@ -1591,11 +1592,11 @@ void AbstractInterpretation::handleMemcpy(AbstractState& as, const SVF::SVFValue for (const auto &src: expr_src.getAddrs()) { u32_t objId = AbstractState::getInternalID(src); - if (as.inLocToValTable(objId)) + if (as.inAddrToValTable(objId)) { as.store(dst, as.load(src)); } - else if (as.inLocToAddrsTable(objId)) + else if (as.inAddrToAddrsTable(objId)) { as.store(dst, as.load(src)); } @@ -1661,7 +1662,7 @@ void AbstractInterpretation::handleMemset(AbstractState& as, const SVF::SVFValue for (const auto &addr: lhs_gep.getAddrs()) { u32_t objId = AbstractState::getInternalID(addr); - if (as.inLocToValTable(objId)) + if (as.inAddrToValTable(objId)) { AbstractValue tmp = as.load(addr); tmp.join_with(elem); diff --git a/svf/lib/AE/Svfexe/SVFIR2AbsState.cpp b/svf/lib/AE/Svfexe/SVFIR2AbsState.cpp index 59e075545..c03ed8066 100644 --- a/svf/lib/AE/Svfexe/SVFIR2AbsState.cpp +++ b/svf/lib/AE/Svfexe/SVFIR2AbsState.cpp @@ -359,7 +359,6 @@ void SVFIR2AbsState::narrowAddrs(AbstractState& es, AbstractState&lhs, const Abs AbstractValue SVFIR2AbsState::getGepObjAddress(AbstractState& es, u32_t pointer, APOffset offset) { - assert(!getAddrs(es, pointer).getAddrs().empty()); AbstractValue addrs = getAddrs(es, pointer); AddressValue ret = AddressValue(); for (const auto &addr: addrs.getAddrs()) @@ -750,7 +749,6 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp) { IntervalValue resVal; AbstractValue &lhs = getAddrs(es, op0), &rhs = getAddrs(es, op1); - assert(!lhs.getAddrs().empty() && !rhs.getAddrs().empty() && "empty address?"); auto predicate = cmp->getPredicate(); switch (predicate) { @@ -758,20 +756,12 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp) case CmpStmt::FCMP_OEQ: case CmpStmt::FCMP_UEQ: { - if (lhs.getAddrs().size() == 1 && rhs.getAddrs().size() == 1) - { - resVal = IntervalValue(lhs.equals(rhs)); - } - else - { - if (lhs.getAddrs().hasIntersect(rhs.getAddrs())) - { - resVal = IntervalValue::top(); - } - else - { - resVal = IntervalValue(0); - } + if (lhs.getAddrs().hasIntersect(rhs.getAddrs())) { + resVal = IntervalValue(0, 1); + } else if (lhs.getAddrs().empty() && rhs.getAddrs().empty()) { + resVal = IntervalValue(1, 1); + } else { + resVal = IntervalValue(0, 0); } break; } @@ -779,20 +769,12 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp) case CmpStmt::FCMP_ONE: case CmpStmt::FCMP_UNE: { - if (lhs.getAddrs().size() == 1 && rhs.getAddrs().size() == 1) - { - resVal = IntervalValue(!lhs.equals(rhs)); - } - else - { - if (lhs.getAddrs().hasIntersect(rhs.getAddrs())) - { - resVal = IntervalValue::top(); - } - else - { - resVal = IntervalValue(1); - } + if (lhs.getAddrs().hasIntersect(rhs.getAddrs())) { + resVal = IntervalValue(0, 1); + } else if (lhs.getAddrs().empty() && rhs.getAddrs().empty()) { + resVal = IntervalValue(0, 0); + } else { + resVal = IntervalValue(1, 1); } break; } @@ -807,7 +789,7 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp) } else { - resVal = IntervalValue::top(); + resVal = IntervalValue(0, 1); } break; } @@ -822,7 +804,7 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp) } else { - resVal = IntervalValue::top(); + resVal = IntervalValue(0, 1); } break; } @@ -837,7 +819,7 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp) } else { - resVal = IntervalValue::top(); + resVal = IntervalValue(0, 1); } break; } @@ -852,7 +834,7 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp) } else { - resVal = IntervalValue::top(); + resVal = IntervalValue(0, 1); } break; } @@ -878,7 +860,6 @@ void SVFIR2AbsState::handleLoad(AbstractState& es, const LoadStmt *load) if (inVarToAddrsTable(es, rhs)) { AbstractValue &addrs = getAddrs(es, rhs); - assert(!addrs.getAddrs().empty()); AbstractValue rhsVal(AbstractValue::UnknownType); // interval::bottom Address::bottom // AbstractValue absRhs for (const auto &addr: addrs.getAddrs()) @@ -887,7 +868,7 @@ void SVFIR2AbsState::handleLoad(AbstractState& es, const LoadStmt *load) // absRhs.join_with // es.load() u32_t objId = getInternalID(addr); - if (inLocToValTable(es, objId) || inLocToAddrsTable(es, objId)) + if (inAddrTable(es, objId)) { rhsVal.join_with(es.load(addr)); } @@ -903,17 +884,8 @@ void SVFIR2AbsState::handleStore(AbstractState& es, const StoreStmt *store) u32_t lhs = store->getLHSVarID(); if (inVarToAddrsTable(es, lhs)) { - //es.store() - assert(!getAddrs(es, lhs).getAddrs().empty()); - AbstractValue &addrs = es[lhs]; - for (const auto &addr: addrs.getAddrs()) + if (inVarTable(es, rhs)) { - es.store(addr, es[rhs]); - } - - if (inVarToValTable(es, rhs) || inVarToAddrsTable(es, rhs)) - { - assert(!getAddrs(es, lhs).getAddrs().empty()); for (const auto &addr: es[lhs].getAddrs()) { es.store(addr, es[rhs]); @@ -926,81 +898,74 @@ void SVFIR2AbsState::handleCopy(AbstractState& es, const CopyStmt *copy) { u32_t lhs = copy->getLHSVarID(); u32_t rhs = copy->getRHSVarID(); - if (PAG::getPAG()->isBlkPtr(lhs)) - { - es[lhs] = IntervalValue::top(); - } - else + + if (inVarToValTable(es, rhs)) { - if (inVarToValTable(es, rhs)) + if (copy->getCopyKind() == CopyStmt::COPYVAL) { - if (copy->getCopyKind() == CopyStmt::COPYVAL) + es[lhs] = es[rhs]; + } + else if (copy->getCopyKind() == CopyStmt::ZEXT) + { + es[lhs] = getZExtValue(es, copy->getRHSVar()); + } + else if (copy->getCopyKind() == CopyStmt::SEXT) + { + es[lhs] = getSExtValue(es, copy->getRHSVar()); + } + else if (copy->getCopyKind() == CopyStmt::FPTOSI) + { + es[lhs] = getFPToSIntValue(es, copy->getRHSVar()); + } + else if (copy->getCopyKind() == CopyStmt::FPTOUI) + { + es[lhs] = getFPToUIntValue(es, copy->getRHSVar()); + } + else if (copy->getCopyKind() == CopyStmt::SITOFP) + { + es[lhs] = getSIntToFPValue(es, copy->getRHSVar()); + } + else if (copy->getCopyKind() == CopyStmt::UITOFP) + { + es[lhs] = getUIntToFPValue(es, copy->getRHSVar()); + } + else if (copy->getCopyKind() == CopyStmt::TRUNC) + { + es[lhs] = getTruncValue(es, copy->getRHSVar(), copy->getLHSVar()->getType()); + } + else if (copy->getCopyKind() == CopyStmt::FPTRUNC) + { + es[lhs] = getFPTruncValue(es, copy->getRHSVar(), copy->getLHSVar()->getType()); + } + else if (copy->getCopyKind() == CopyStmt::INTTOPTR) + { + //insert nullptr + } + else if (copy->getCopyKind() == CopyStmt::PTRTOINT) + { + es[lhs] = IntervalValue::top(); + } + else if (copy->getCopyKind() == CopyStmt::BITCAST) + { + if (es[rhs].isAddr()) { es[lhs] = es[rhs]; } - else if (copy->getCopyKind() == CopyStmt::ZEXT) - { - es[lhs] = getZExtValue(es, copy->getRHSVar()); - } - else if (copy->getCopyKind() == CopyStmt::SEXT) - { - es[lhs] = getSExtValue(es, copy->getRHSVar()); - } - else if (copy->getCopyKind() == CopyStmt::FPTOSI) - { - es[lhs] = getFPToSIntValue(es, copy->getRHSVar()); - } - else if (copy->getCopyKind() == CopyStmt::FPTOUI) - { - es[lhs] = getFPToUIntValue(es, copy->getRHSVar()); - } - else if (copy->getCopyKind() == CopyStmt::SITOFP) - { - es[lhs] = getSIntToFPValue(es, copy->getRHSVar()); - } - else if (copy->getCopyKind() == CopyStmt::UITOFP) - { - es[lhs] = getUIntToFPValue(es, copy->getRHSVar()); - } - else if (copy->getCopyKind() == CopyStmt::TRUNC) - { - es[lhs] = getTruncValue(es, copy->getRHSVar(), copy->getLHSVar()->getType()); - } - else if (copy->getCopyKind() == CopyStmt::FPTRUNC) - { - es[lhs] = getFPTruncValue(es, copy->getRHSVar(), copy->getLHSVar()->getType()); - } - else if (copy->getCopyKind() == CopyStmt::INTTOPTR) - { - es.getAddrs(lhs).getAddrs().insert(getVirtualMemAddress(0)); //insert nullptr - } - else if (copy->getCopyKind() == CopyStmt::PTRTOINT) - { - es[lhs] = IntervalValue::top(); - } - else if (copy->getCopyKind() == CopyStmt::BITCAST) - { - if (es[rhs].isAddr()) - { - es[lhs] = es[rhs]; - } - else - { - // do nothing - } - } else { - assert(false && "undefined copy kind"); - abort(); + // do nothing } } - else if (inVarToAddrsTable(es, rhs)) + else { - assert(!getAddrs(es, rhs).getAddrs().empty()); - es[lhs] = es[rhs]; + assert(false && "undefined copy kind"); + abort(); } } + else if (inVarToAddrsTable(es, rhs)) + { + es[lhs] = es[rhs]; + } } void SVFIR2AbsState::handleGep(AbstractState& es, const GepStmt *gep) @@ -1009,7 +974,6 @@ void SVFIR2AbsState::handleGep(AbstractState& es, const GepStmt *gep) u32_t lhs = gep->getLHSVarID(); if (!inVarToAddrsTable(es, rhs)) return; AbstractValue &rhsVal = es[rhs]; - assert(!rhsVal.getAddrs().empty()); IntervalValue offsetPair = getElementIndex(es, gep); if (!isVirtualMemAddress(*rhsVal.getAddrs().begin())) return; @@ -1049,8 +1013,6 @@ void SVFIR2AbsState::handleSelect(AbstractState& es, const SelectStmt *select) { if (es[cond].getInterval().is_numeral()) { - assert(!getAddrs(es, fval).getAddrs().empty()); - assert(!getAddrs(es, tval).getAddrs().empty()); es.getAddrs(res) = es[cond].getInterval().is_zero() ? getAddrs(es, fval) : getAddrs(es, tval); } } From 643c19cf86a94c62f18e7ab756df4a248b7f048f Mon Sep 17 00:00:00 2001 From: bjjwwang Date: Thu, 23 May 2024 14:29:32 +1000 Subject: [PATCH 2/8] refactor APIs in AbstractState/Value --- svf/include/AE/Core/AbstractState.h | 3 +-- svf/include/AE/Core/AddressValue.h | 3 +-- svf/include/AE/Svfexe/SVFIR2AbsState.h | 3 +-- svf/lib/AE/Svfexe/SVFIR2AbsState.cpp | 5 ----- 4 files changed, 3 insertions(+), 11 deletions(-) diff --git a/svf/include/AE/Core/AbstractState.h b/svf/include/AE/Core/AbstractState.h index b281997a9..5ed32e7fd 100644 --- a/svf/include/AE/Core/AbstractState.h +++ b/svf/include/AE/Core/AbstractState.h @@ -80,8 +80,7 @@ class AbstractState /// The physical address starts with 0x7f...... + idx static inline u32_t getVirtualMemAddress(u32_t idx) { - if (idx == 0) - assert(false && "idx cannot be 0"); + assert(idx != 0 && "idx cannot be 0"); return AddressValue::getVirtualMemAddress(idx); } diff --git a/svf/include/AE/Core/AddressValue.h b/svf/include/AE/Core/AddressValue.h index 94be8ac7b..5ddfaa7f3 100644 --- a/svf/include/AE/Core/AddressValue.h +++ b/svf/include/AE/Core/AddressValue.h @@ -211,8 +211,7 @@ class AddressValue /// The physical address starts with 0x7f...... + idx static inline u32_t getVirtualMemAddress(u32_t idx) { - if (idx == 0) - assert(false && "idx cannot be 0"); + assert(idx != 0 && "idx cannot be 0"); return AddressMask + idx; } diff --git a/svf/include/AE/Svfexe/SVFIR2AbsState.h b/svf/include/AE/Svfexe/SVFIR2AbsState.h index adca71ad3..84bb9223c 100644 --- a/svf/include/AE/Svfexe/SVFIR2AbsState.h +++ b/svf/include/AE/Svfexe/SVFIR2AbsState.h @@ -175,8 +175,7 @@ class SVFIR2AbsState /// The physical address starts with 0x7f...... + idx static inline u32_t getVirtualMemAddress(u32_t idx) { - if (idx == 0) - assert(false && "idx cannot be 0"); + assert(idx != 0 && "idx cannot be 0"); return AbstractState::getVirtualMemAddress(idx); } diff --git a/svf/lib/AE/Svfexe/SVFIR2AbsState.cpp b/svf/lib/AE/Svfexe/SVFIR2AbsState.cpp index c03ed8066..b1e576049 100644 --- a/svf/lib/AE/Svfexe/SVFIR2AbsState.cpp +++ b/svf/lib/AE/Svfexe/SVFIR2AbsState.cpp @@ -364,11 +364,6 @@ AbstractValue SVFIR2AbsState::getGepObjAddress(AbstractState& es, u32_t pointer, for (const auto &addr: addrs.getAddrs()) { s64_t baseObj = getInternalID(addr); - if (baseObj == 0) - { - ret.insert(getVirtualMemAddress(0)); - continue; - } assert(SVFUtil::isa(_svfir->getGNode(baseObj)) && "Fail to get the base object address!"); NodeID gepObj = _svfir->getGepObjVar(baseObj, offset); initSVFVar(es, gepObj); From 807010d0778056cc14a874644ca7603b2d7fac58 Mon Sep 17 00:00:00 2001 From: bjjwwang Date: Thu, 23 May 2024 15:03:51 +1000 Subject: [PATCH 3/8] add comments to idx 0 --- svf/include/AE/Core/AbstractState.h | 1 + svf/include/AE/Core/AddressValue.h | 1 + svf/include/AE/Svfexe/SVFIR2AbsState.h | 1 + 3 files changed, 3 insertions(+) diff --git a/svf/include/AE/Core/AbstractState.h b/svf/include/AE/Core/AbstractState.h index 5ed32e7fd..510e3a760 100644 --- a/svf/include/AE/Core/AbstractState.h +++ b/svf/include/AE/Core/AbstractState.h @@ -80,6 +80,7 @@ class AbstractState /// The physical address starts with 0x7f...... + idx static inline u32_t getVirtualMemAddress(u32_t idx) { + // 0 is the null address, should not be used as a virtual address assert(idx != 0 && "idx cannot be 0"); return AddressValue::getVirtualMemAddress(idx); } diff --git a/svf/include/AE/Core/AddressValue.h b/svf/include/AE/Core/AddressValue.h index 5ddfaa7f3..e5c20f3b1 100644 --- a/svf/include/AE/Core/AddressValue.h +++ b/svf/include/AE/Core/AddressValue.h @@ -211,6 +211,7 @@ class AddressValue /// The physical address starts with 0x7f...... + idx static inline u32_t getVirtualMemAddress(u32_t idx) { + // 0 is the null address, should not be used as a virtual address assert(idx != 0 && "idx cannot be 0"); return AddressMask + idx; } diff --git a/svf/include/AE/Svfexe/SVFIR2AbsState.h b/svf/include/AE/Svfexe/SVFIR2AbsState.h index 84bb9223c..d2b04ce07 100644 --- a/svf/include/AE/Svfexe/SVFIR2AbsState.h +++ b/svf/include/AE/Svfexe/SVFIR2AbsState.h @@ -175,6 +175,7 @@ class SVFIR2AbsState /// The physical address starts with 0x7f...... + idx static inline u32_t getVirtualMemAddress(u32_t idx) { + // 0 is the null address, should not be used as a virtual address assert(idx != 0 && "idx cannot be 0"); return AbstractState::getVirtualMemAddress(idx); } From b911c7ad8eca991e7f4cb9b1a84dfa477b3f8452 Mon Sep 17 00:00:00 2001 From: bjjwwang Date: Thu, 23 May 2024 15:06:48 +1000 Subject: [PATCH 4/8] add comments to idx 0 --- svf/include/AE/Core/AbstractState.h | 2 +- svf/include/AE/Core/AddressValue.h | 2 +- svf/include/AE/Svfexe/SVFIR2AbsState.h | 2 +- svf/lib/AE/Svfexe/AbstractInterpretation.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/svf/include/AE/Core/AbstractState.h b/svf/include/AE/Core/AbstractState.h index 510e3a760..088dad934 100644 --- a/svf/include/AE/Core/AbstractState.h +++ b/svf/include/AE/Core/AbstractState.h @@ -81,7 +81,7 @@ class AbstractState static inline u32_t getVirtualMemAddress(u32_t idx) { // 0 is the null address, should not be used as a virtual address - assert(idx != 0 && "idx cannot be 0"); + assert(idx != 0 && "idx cannot be 0 because 0 represents null pointer"); return AddressValue::getVirtualMemAddress(idx); } diff --git a/svf/include/AE/Core/AddressValue.h b/svf/include/AE/Core/AddressValue.h index e5c20f3b1..e2eab05d3 100644 --- a/svf/include/AE/Core/AddressValue.h +++ b/svf/include/AE/Core/AddressValue.h @@ -212,7 +212,7 @@ class AddressValue static inline u32_t getVirtualMemAddress(u32_t idx) { // 0 is the null address, should not be used as a virtual address - assert(idx != 0 && "idx cannot be 0"); + assert(idx != 0 && "idx cannot be 0 because 0 represents null pointer"); return AddressMask + idx; } diff --git a/svf/include/AE/Svfexe/SVFIR2AbsState.h b/svf/include/AE/Svfexe/SVFIR2AbsState.h index d2b04ce07..4ef165cef 100644 --- a/svf/include/AE/Svfexe/SVFIR2AbsState.h +++ b/svf/include/AE/Svfexe/SVFIR2AbsState.h @@ -176,7 +176,7 @@ class SVFIR2AbsState static inline u32_t getVirtualMemAddress(u32_t idx) { // 0 is the null address, should not be used as a virtual address - assert(idx != 0 && "idx cannot be 0"); + assert(idx != 0 && "idx cannot be 0 because 0 represents null pointer"); return AbstractState::getVirtualMemAddress(idx); } diff --git a/svf/lib/AE/Svfexe/AbstractInterpretation.cpp b/svf/lib/AE/Svfexe/AbstractInterpretation.cpp index 1cd19499b..ab75420f5 100644 --- a/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +++ b/svf/lib/AE/Svfexe/AbstractInterpretation.cpp @@ -166,7 +166,7 @@ void AbstractInterpretation::handleGlobalNode() AbstractState as; const ICFGNode* node = _icfg->getGlobalICFGNode(); _postAbsTrace[node] = _preAbsTrace[node]; - _postAbsTrace[node][0] = AddressValue(); + _postAbsTrace[node][SymbolTableInfo::NullPtr] = AddressValue(); // Global Node, we just need to handle addr, load, store, copy and gep for (const SVFStmt *stmt: node->getSVFStmts()) { From a5b118a48da637fe5d7e108b78c1f3c3220956f8 Mon Sep 17 00:00:00 2001 From: bjjwwang Date: Thu, 23 May 2024 15:08:02 +1000 Subject: [PATCH 5/8] add comments to idx 0 --- svf/include/AE/Core/AbstractState.h | 2 +- svf/include/AE/Core/AddressValue.h | 2 +- svf/include/AE/Svfexe/SVFIR2AbsState.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/svf/include/AE/Core/AbstractState.h b/svf/include/AE/Core/AbstractState.h index 088dad934..f3b31ca2e 100644 --- a/svf/include/AE/Core/AbstractState.h +++ b/svf/include/AE/Core/AbstractState.h @@ -81,7 +81,7 @@ class AbstractState static inline u32_t getVirtualMemAddress(u32_t idx) { // 0 is the null address, should not be used as a virtual address - assert(idx != 0 && "idx cannot be 0 because 0 represents null pointer"); + assert(idx != 0 && "because 0 represents null pointer"); return AddressValue::getVirtualMemAddress(idx); } diff --git a/svf/include/AE/Core/AddressValue.h b/svf/include/AE/Core/AddressValue.h index e2eab05d3..dae9c3417 100644 --- a/svf/include/AE/Core/AddressValue.h +++ b/svf/include/AE/Core/AddressValue.h @@ -212,7 +212,7 @@ class AddressValue static inline u32_t getVirtualMemAddress(u32_t idx) { // 0 is the null address, should not be used as a virtual address - assert(idx != 0 && "idx cannot be 0 because 0 represents null pointer"); + assert(idx != 0 && "because 0 represents null pointer"); return AddressMask + idx; } diff --git a/svf/include/AE/Svfexe/SVFIR2AbsState.h b/svf/include/AE/Svfexe/SVFIR2AbsState.h index 4ef165cef..e1a632836 100644 --- a/svf/include/AE/Svfexe/SVFIR2AbsState.h +++ b/svf/include/AE/Svfexe/SVFIR2AbsState.h @@ -176,7 +176,7 @@ class SVFIR2AbsState static inline u32_t getVirtualMemAddress(u32_t idx) { // 0 is the null address, should not be used as a virtual address - assert(idx != 0 && "idx cannot be 0 because 0 represents null pointer"); + assert(idx != 0 && "because 0 represents null pointer"); return AbstractState::getVirtualMemAddress(idx); } From 0b20524b152b1a86727964f4ace4bfa82f0e3870 Mon Sep 17 00:00:00 2001 From: bjjwwang Date: Thu, 23 May 2024 15:11:21 +1000 Subject: [PATCH 6/8] remove redundant assert --- svf/include/AE/Core/AbstractState.h | 2 -- svf/include/AE/Svfexe/SVFIR2AbsState.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/svf/include/AE/Core/AbstractState.h b/svf/include/AE/Core/AbstractState.h index f3b31ca2e..983ea375d 100644 --- a/svf/include/AE/Core/AbstractState.h +++ b/svf/include/AE/Core/AbstractState.h @@ -80,8 +80,6 @@ class AbstractState /// The physical address starts with 0x7f...... + idx static inline u32_t getVirtualMemAddress(u32_t idx) { - // 0 is the null address, should not be used as a virtual address - assert(idx != 0 && "because 0 represents null pointer"); return AddressValue::getVirtualMemAddress(idx); } diff --git a/svf/include/AE/Svfexe/SVFIR2AbsState.h b/svf/include/AE/Svfexe/SVFIR2AbsState.h index e1a632836..6bb7f5e9d 100644 --- a/svf/include/AE/Svfexe/SVFIR2AbsState.h +++ b/svf/include/AE/Svfexe/SVFIR2AbsState.h @@ -175,8 +175,6 @@ class SVFIR2AbsState /// The physical address starts with 0x7f...... + idx static inline u32_t getVirtualMemAddress(u32_t idx) { - // 0 is the null address, should not be used as a virtual address - assert(idx != 0 && "because 0 represents null pointer"); return AbstractState::getVirtualMemAddress(idx); } From e49f7a3e7c6da7b94d2db7f1464465f24df600af Mon Sep 17 00:00:00 2001 From: bjjwwang Date: Thu, 23 May 2024 15:12:50 +1000 Subject: [PATCH 7/8] remove redundant assert --- svf/include/AE/Core/AddressValue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svf/include/AE/Core/AddressValue.h b/svf/include/AE/Core/AddressValue.h index dae9c3417..3fb4ab49c 100644 --- a/svf/include/AE/Core/AddressValue.h +++ b/svf/include/AE/Core/AddressValue.h @@ -212,7 +212,7 @@ class AddressValue static inline u32_t getVirtualMemAddress(u32_t idx) { // 0 is the null address, should not be used as a virtual address - assert(idx != 0 && "because 0 represents null pointer"); + assert(idx != 0 && "idx can’t be 0 because it represents a nullptr"); return AddressMask + idx; } From ec9f5368ef63328c6f85921f160577505e9dd10b Mon Sep 17 00:00:00 2001 From: bjjwwang Date: Thu, 23 May 2024 15:47:07 +1000 Subject: [PATCH 8/8] stage1: refactor SVFIR2AbsState --- svf/include/AE/Svfexe/SVFIR2AbsState.h | 4 +- svf/lib/AE/Svfexe/SVFIR2AbsState.cpp | 275 +++++++++++-------------- 2 files changed, 127 insertions(+), 152 deletions(-) diff --git a/svf/include/AE/Svfexe/SVFIR2AbsState.h b/svf/include/AE/Svfexe/SVFIR2AbsState.h index 6bb7f5e9d..e15b2ad78 100644 --- a/svf/include/AE/Svfexe/SVFIR2AbsState.h +++ b/svf/include/AE/Svfexe/SVFIR2AbsState.h @@ -96,10 +96,8 @@ class SVFIR2AbsState /// Init ObjVar - void initObjVar(AbstractState& es, const ObjVar *objVar, u32_t varId); + void initObjVar(AbstractState& as, const ObjVar* var); - /// Init SVFVar - void initSVFVar(AbstractState& es, u32_t varId); inline AbstractValue &getAddrs(AbstractState& es, u32_t id) { diff --git a/svf/lib/AE/Svfexe/SVFIR2AbsState.cpp b/svf/lib/AE/Svfexe/SVFIR2AbsState.cpp index b1e576049..b49a2dec8 100644 --- a/svf/lib/AE/Svfexe/SVFIR2AbsState.cpp +++ b/svf/lib/AE/Svfexe/SVFIR2AbsState.cpp @@ -108,35 +108,35 @@ AbstractValue SVFIR2AbsState::getRangeLimitFromType(const SVFType* type) } } -AbstractValue SVFIR2AbsState::getZExtValue(const AbstractState& es, const SVFVar* var) +AbstractValue SVFIR2AbsState::getZExtValue(const AbstractState& as, const SVFVar* var) { const SVFType* type = var->getType(); if (SVFUtil::isa(type)) { u32_t bits = type->getByteSize() * 8; - if (es[var->getId()].getInterval().is_numeral()) + if (as[var->getId()].getInterval().is_numeral()) { if (bits == 8) { - int8_t signed_i8_value = es[var->getId()].getInterval().getIntNumeral(); + int8_t signed_i8_value = as[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()].getInterval().getIntNumeral(); + s16_t signed_i16_value = as[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()].getInterval().getIntNumeral(); + s32_t signed_i32_value = as[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()].getInterval().getIntNumeral(); + s64_t signed_i64_value = as[var->getId()].getInterval().getIntNumeral(); return IntervalValue((s64_t)signed_i64_value, (s64_t)signed_i64_value); // we only support i64 at most } @@ -153,18 +153,18 @@ AbstractValue SVFIR2AbsState::getZExtValue(const AbstractState& es, const SVFVar return IntervalValue::top(); // TODO: may have better solution } -AbstractValue SVFIR2AbsState::getSExtValue(const AbstractState& es, const SVFVar* var) +AbstractValue SVFIR2AbsState::getSExtValue(const AbstractState& as, const SVFVar* var) { - return es[var->getId()].getInterval(); + return as[var->getId()].getInterval(); } -AbstractValue SVFIR2AbsState::getFPToSIntValue(const AbstractState& es, const SVF::SVFVar* var) +AbstractValue SVFIR2AbsState::getFPToSIntValue(const AbstractState& as, const SVF::SVFVar* var) { - if (es[var->getId()].getInterval().is_real()) + if (as[var->getId()].getInterval().is_real()) { // get the float value of ub and lb - double float_lb = es[var->getId()].getInterval().lb().getRealNumeral(); - double float_ub = es[var->getId()].getInterval().ub().getRealNumeral(); + double float_lb = as[var->getId()].getInterval().lb().getRealNumeral(); + double float_ub = as[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); @@ -172,17 +172,17 @@ AbstractValue SVFIR2AbsState::getFPToSIntValue(const AbstractState& es, const SV } else { - return getSExtValue(es, var); + return getSExtValue(as, var); } } -AbstractValue SVFIR2AbsState::getFPToUIntValue(const AbstractState& es, const SVF::SVFVar* var) +AbstractValue SVFIR2AbsState::getFPToUIntValue(const AbstractState& as, const SVF::SVFVar* var) { - if (es[var->getId()].getInterval().is_real()) + if (as[var->getId()].getInterval().is_real()) { // get the float value of ub and lb - double float_lb = es[var->getId()].getInterval().lb().getRealNumeral(); - double float_ub = es[var->getId()].getInterval().ub().getRealNumeral(); + double float_lb = as[var->getId()].getInterval().lb().getRealNumeral(); + double float_ub = as[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); @@ -190,37 +190,37 @@ AbstractValue SVFIR2AbsState::getFPToUIntValue(const AbstractState& es, const SV } else { - return getZExtValue(es, var); + return getZExtValue(as, var); } } -AbstractValue SVFIR2AbsState::getSIntToFPValue(const AbstractState& es, const SVF::SVFVar* var) +AbstractValue SVFIR2AbsState::getSIntToFPValue(const AbstractState& as, const SVF::SVFVar* var) { // get the sint value of ub and lb - s64_t sint_lb = es[var->getId()].getInterval().lb().getIntNumeral(); - s64_t sint_ub = es[var->getId()].getInterval().ub().getIntNumeral(); + s64_t sint_lb = as[var->getId()].getInterval().lb().getIntNumeral(); + s64_t sint_ub = as[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); } -AbstractValue SVFIR2AbsState::getUIntToFPValue(const AbstractState& es, const SVF::SVFVar* var) +AbstractValue SVFIR2AbsState::getUIntToFPValue(const AbstractState& as, const SVF::SVFVar* var) { // get the uint value of ub and lb - u64_t uint_lb = es[var->getId()].getInterval().lb().getIntNumeral(); - u64_t uint_ub = es[var->getId()].getInterval().ub().getIntNumeral(); + u64_t uint_lb = as[var->getId()].getInterval().lb().getIntNumeral(); + u64_t uint_ub = as[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); } -AbstractValue SVFIR2AbsState::getTruncValue(const AbstractState& es, const SVF::SVFVar* var, const SVFType* dstType) +AbstractValue SVFIR2AbsState::getTruncValue(const AbstractState& as, const SVF::SVFVar* var, const SVFType* dstType) { // get the value of ub and lb - s64_t int_lb = es[var->getId()].getInterval().lb().getIntNumeral(); - s64_t int_ub = es[var->getId()].getInterval().ub().getIntNumeral(); + s64_t int_lb = as[var->getId()].getInterval().lb().getIntNumeral(); + s64_t int_ub = as[var->getId()].getInterval().ub().getIntNumeral(); // get dst type u32_t dst_bits = dstType->getByteSize() * 8; if (dst_bits == 8) @@ -265,13 +265,13 @@ AbstractValue SVFIR2AbsState::getTruncValue(const AbstractState& es, const SVF:: } } -AbstractValue SVFIR2AbsState::getFPTruncValue(const AbstractState& es, const SVF::SVFVar* var, const SVFType* dstType) +AbstractValue SVFIR2AbsState::getFPTruncValue(const AbstractState& as, const SVF::SVFVar* var, const SVFType* dstType) { // TODO: now we do not really handle fptrunc - return es[var->getId()].getInterval(); + return as[var->getId()].getInterval(); } -void SVFIR2AbsState::widenAddrs(AbstractState& es, AbstractState&lhs, const AbstractState&rhs) +void SVFIR2AbsState::widenAddrs(AbstractState& as, AbstractState&lhs, const AbstractState&rhs) { for (const auto &rhsItem: rhs._varToAbsVal) { @@ -286,7 +286,7 @@ void SVFIR2AbsState::widenAddrs(AbstractState& es, AbstractState&lhs, const Abst { for (s32_t i = 0; i < (s32_t) Options::MaxFieldLimit(); i++) { - lhsIter->second.join_with(getGepObjAddress(es, getInternalID(addr), i)); + lhsIter->second.join_with(getGepObjAddress(as, getInternalID(addr), i)); } } } @@ -308,7 +308,7 @@ void SVFIR2AbsState::widenAddrs(AbstractState& es, AbstractState&lhs, const Abst i++) { lhsIter->second.join_with( - getGepObjAddress(es, getInternalID(addr), i)); + getGepObjAddress(as, getInternalID(addr), i)); } } } @@ -317,7 +317,7 @@ void SVFIR2AbsState::widenAddrs(AbstractState& es, AbstractState&lhs, const Abst } } -void SVFIR2AbsState::narrowAddrs(AbstractState& es, AbstractState&lhs, const AbstractState&rhs) +void SVFIR2AbsState::narrowAddrs(AbstractState& as, AbstractState&lhs, const AbstractState&rhs) { for (const auto &rhsItem: rhs._varToAbsVal) { @@ -357,17 +357,17 @@ void SVFIR2AbsState::narrowAddrs(AbstractState& es, AbstractState&lhs, const Abs } } -AbstractValue SVFIR2AbsState::getGepObjAddress(AbstractState& es, u32_t pointer, APOffset offset) +AbstractValue SVFIR2AbsState::getGepObjAddress(AbstractState& as, u32_t pointer, APOffset offset) { - AbstractValue addrs = getAddrs(es, pointer); + AbstractValue addrs = getAddrs(as, pointer); AddressValue ret = AddressValue(); for (const auto &addr: addrs.getAddrs()) { s64_t baseObj = getInternalID(addr); assert(SVFUtil::isa(_svfir->getGNode(baseObj)) && "Fail to get the base object address!"); NodeID gepObj = _svfir->getGepObjVar(baseObj, offset); - initSVFVar(es, gepObj); - ret.insert(getVirtualMemAddress(gepObj)); + as[gepObj] = AddressValue(AbstractState::getVirtualMemAddress(gepObj)); + ret.insert(AbstractState::getVirtualMemAddress(gepObj)); } return ret; } @@ -394,7 +394,7 @@ AbstractValue SVFIR2AbsState::getGepObjAddress(AbstractState& es, u32_t pointer, * Therefore the final byteoffset is [8+4*var1.lb(), 8+4*var1.ub()] * */ -IntervalValue SVFIR2AbsState::getByteOffset(const AbstractState& es, const GepStmt *gep) +IntervalValue SVFIR2AbsState::getByteOffset(const AbstractState& as, const GepStmt *gep) { if (gep->isConstantOffset()) return IntervalValue((s64_t)gep->accumulateConstantByteOffset()); @@ -425,7 +425,7 @@ IntervalValue SVFIR2AbsState::getByteOffset(const AbstractState& es, const GepSt else { u32_t idx = _svfir->getValueNode(idxOperandVar->getValue()); - IntervalValue idxVal = es[idx].getInterval(); + IntervalValue idxVal = as[idx].getInterval(); if (idxVal.isBottom()) res = res + IntervalValue(0, 0); else @@ -464,7 +464,7 @@ IntervalValue SVFIR2AbsState::getByteOffset(const AbstractState& es, const GepSt * * @return A pair of APOffset values representing the offset range. */ -IntervalValue SVFIR2AbsState::getElementIndex(const AbstractState& es, const GepStmt *gep) +IntervalValue SVFIR2AbsState::getElementIndex(const AbstractState& as, const GepStmt *gep) { if (gep->isConstantOffset()) return IntervalValue((s64_t)gep->accumulateConstantOffset()); @@ -484,7 +484,7 @@ IntervalValue SVFIR2AbsState::getElementIndex(const AbstractState& es, const Gep idxLb = idxUb = constInt->getSExtValue(); else { - IntervalValue idxItv = es[_svfir->getValueNode(value)].getInterval(); + IntervalValue idxItv = as[_svfir->getValueNode(value)].getInterval(); if (idxItv.isBottom()) idxLb = idxUb = 0; else @@ -534,81 +534,58 @@ IntervalValue SVFIR2AbsState::getElementIndex(const AbstractState& es, const Gep } -/*! - * Init Z3Expr for ObjVar - * @param objVar - * @param valExprIdToCondValPairMap - */ -void SVFIR2AbsState::initObjVar(AbstractState& es, const ObjVar *objVar, u32_t varId) -{ - - if (objVar->hasValue()) +void SVFIR2AbsState::initObjVar(AbstractState& as, const ObjVar* var) { + NodeID varId = var->getId(); + if (var->hasValue()) { - const MemObj *obj = objVar->getMemObj(); + const MemObj *obj = var->getMemObj(); /// constant data if (obj->isConstDataOrConstGlobal() || obj->isConstantArray() || obj->isConstantStruct()) { if (const SVFConstantInt *consInt = SVFUtil::dyn_cast(obj->getValue())) { s64_t numeral = consInt->getSExtValue(); - es[varId] = IntervalValue(numeral, numeral); + as[varId] = IntervalValue(numeral, numeral); } else if (const SVFConstantFP* consFP = SVFUtil::dyn_cast(obj->getValue())) - es[varId] = IntervalValue(consFP->getFPValue(), consFP->getFPValue()); + as[varId] = IntervalValue(consFP->getFPValue(), consFP->getFPValue()); else if (SVFUtil::isa(obj->getValue())) - es[varId] = IntervalValue(0, 0); + as[varId] = IntervalValue(0, 0); else if (SVFUtil::isa(obj->getValue())) { - es[varId] = AddressValue(getVirtualMemAddress(varId)); + as[varId] = AddressValue(getVirtualMemAddress(varId)); } else if (obj->isConstantArray() || obj->isConstantStruct()) - es[varId] = IntervalValue::top(); + as[varId] = IntervalValue::top(); else - es[varId] = IntervalValue::top(); + as[varId] = IntervalValue::top(); } else - es[varId] = AddressValue(getVirtualMemAddress(varId)); - } - else - es[varId] = AddressValue(getVirtualMemAddress(varId)); -} - -void SVFIR2AbsState::initSVFVar(AbstractState& es, u32_t varId) -{ - if (inVarToValTable(es, varId) || es.inVarToAddrsTable(varId)) return; - SVFIR *svfir = PAG::getPAG(); - SVFVar *svfVar = svfir->getGNode(varId); - // write objvar into cache instead of exestate - if (const ObjVar *objVar = dyn_cast(svfVar)) - { - initObjVar(es, objVar, varId); - return; + as[varId] = AddressValue(getVirtualMemAddress(varId)); } else - { - assert(false && "not an obj var?"); - } + as[varId] = AddressValue(getVirtualMemAddress(varId)); } -void SVFIR2AbsState::handleAddr(AbstractState& es, const AddrStmt *addr) +void SVFIR2AbsState::handleAddr(AbstractState& as, const AddrStmt *addr) { - initSVFVar(es, addr->getRHSVarID()); - if (inVarToValTable(es, addr->getRHSVarID())) + initObjVar(as, SVFUtil::cast(addr->getRHSVar())); + if (inVarToValTable(as, addr->getRHSVarID())) { // if addr RHS is integerType(i8 i32 etc), value should be limited. if (addr->getRHSVar()->getType()->getKind() == SVFType::SVFIntegerTy) { - es[addr->getRHSVarID()].meet_with(getRangeLimitFromType(addr->getRHSVar()->getType())); + as[addr->getRHSVarID()].meet_with(getRangeLimitFromType(addr->getRHSVar()->getType())); } - es[addr->getLHSVarID()] = es[addr->getRHSVarID()]; + as[addr->getLHSVarID()] = as[addr->getRHSVarID()]; } - else if (inVarToAddrsTable(es, addr->getRHSVarID())) + else if (inVarToAddrsTable(as, addr->getRHSVarID())) { - es[addr->getLHSVarID()] = - es[addr->getRHSVarID()]; + as[addr->getLHSVarID()] = + as[addr->getRHSVarID()]; } else { @@ -617,16 +594,16 @@ void SVFIR2AbsState::handleAddr(AbstractState& es, const AddrStmt *addr) } -void SVFIR2AbsState::handleBinary(AbstractState& es, const BinaryOPStmt *binary) +void SVFIR2AbsState::handleBinary(AbstractState& as, const BinaryOPStmt *binary) { u32_t op0 = binary->getOpVarID(0); u32_t op1 = binary->getOpVarID(1); u32_t res = binary->getResID(); - if (!inVarToValTable(es, op0)) es[op0] = IntervalValue::top(); - if (!inVarToValTable(es, op1)) es[op1] = IntervalValue::top(); - if (inVarToValTable(es, op0) && inVarToValTable(es, op1)) + if (!inVarToValTable(as, op0)) as[op0] = IntervalValue::top(); + if (!inVarToValTable(as, op1)) as[op1] = IntervalValue::top(); + if (inVarToValTable(as, op0) && inVarToValTable(as, op1)) { - IntervalValue &lhs = es[op0].getInterval(), &rhs = es[op1].getInterval(); + IntervalValue &lhs = as[op0].getInterval(), &rhs = as[op1].getInterval(); IntervalValue resVal; switch (binary->getOpcode()) { @@ -675,19 +652,19 @@ void SVFIR2AbsState::handleBinary(AbstractState& es, const BinaryOPStmt *binary) assert(false && "undefined binary: "); } } - es[res] = resVal; + as[res] = resVal; } } -void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp) +void SVFIR2AbsState::handleCmp(AbstractState& as, const CmpStmt *cmp) { u32_t op0 = cmp->getOpVarID(0); u32_t op1 = cmp->getOpVarID(1); u32_t res = cmp->getResID(); - if (inVarToValTable(es, op0) && inVarToValTable(es, op1)) + if (inVarToValTable(as, op0) && inVarToValTable(as, op1)) { IntervalValue resVal; - IntervalValue &lhs = es[op0].getInterval(), &rhs = es[op1].getInterval(); + IntervalValue &lhs = as[op0].getInterval(), &rhs = as[op1].getInterval(); //AbstractValue auto predicate = cmp->getPredicate(); switch (predicate) @@ -738,12 +715,12 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp) assert(false && "undefined compare: "); } } - es[res] = resVal; + as[res] = resVal; } - else if (inVarToAddrsTable(es, op0) && inVarToAddrsTable(es, op1)) + else if (inVarToAddrsTable(as, op0) && inVarToAddrsTable(as, op1)) { IntervalValue resVal; - AbstractValue &lhs = getAddrs(es, op0), &rhs = getAddrs(es, op1); + AbstractValue &lhs = getAddrs(as, op0), &rhs = getAddrs(as, op1); auto predicate = cmp->getPredicate(); switch (predicate) { @@ -844,93 +821,93 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp) assert(false && "undefined compare: "); } } - es[res] = resVal; + as[res] = resVal; } } -void SVFIR2AbsState::handleLoad(AbstractState& es, const LoadStmt *load) +void SVFIR2AbsState::handleLoad(AbstractState& as, const LoadStmt *load) { u32_t rhs = load->getRHSVarID(); u32_t lhs = load->getLHSVarID(); - if (inVarToAddrsTable(es, rhs)) + if (inVarToAddrsTable(as, rhs)) { - AbstractValue &addrs = getAddrs(es, rhs); + AbstractValue &addrs = getAddrs(as, rhs); AbstractValue rhsVal(AbstractValue::UnknownType); // interval::bottom Address::bottom // AbstractValue absRhs for (const auto &addr: addrs.getAddrs()) { // inLocToAbsVal() // absRhs.join_with - // es.load() + // as.load() u32_t objId = getInternalID(addr); - if (inAddrTable(es, objId)) + if (inAddrTable(as, objId)) { - rhsVal.join_with(es.load(addr)); + rhsVal.join_with(as.load(addr)); } } if (!rhsVal.isUnknown()) - es[lhs] = rhsVal; + as[lhs] = rhsVal; } } -void SVFIR2AbsState::handleStore(AbstractState& es, const StoreStmt *store) +void SVFIR2AbsState::handleStore(AbstractState& as, const StoreStmt *store) { u32_t rhs = store->getRHSVarID(); u32_t lhs = store->getLHSVarID(); - if (inVarToAddrsTable(es, lhs)) + if (inVarToAddrsTable(as, lhs)) { - if (inVarTable(es, rhs)) + if (inVarTable(as, rhs)) { - for (const auto &addr: es[lhs].getAddrs()) + for (const auto &addr: as[lhs].getAddrs()) { - es.store(addr, es[rhs]); + as.store(addr, as[rhs]); } } } } -void SVFIR2AbsState::handleCopy(AbstractState& es, const CopyStmt *copy) +void SVFIR2AbsState::handleCopy(AbstractState& as, const CopyStmt *copy) { u32_t lhs = copy->getLHSVarID(); u32_t rhs = copy->getRHSVarID(); - if (inVarToValTable(es, rhs)) + if (inVarToValTable(as, rhs)) { if (copy->getCopyKind() == CopyStmt::COPYVAL) { - es[lhs] = es[rhs]; + as[lhs] = as[rhs]; } else if (copy->getCopyKind() == CopyStmt::ZEXT) { - es[lhs] = getZExtValue(es, copy->getRHSVar()); + as[lhs] = getZExtValue(as, copy->getRHSVar()); } else if (copy->getCopyKind() == CopyStmt::SEXT) { - es[lhs] = getSExtValue(es, copy->getRHSVar()); + as[lhs] = getSExtValue(as, copy->getRHSVar()); } else if (copy->getCopyKind() == CopyStmt::FPTOSI) { - es[lhs] = getFPToSIntValue(es, copy->getRHSVar()); + as[lhs] = getFPToSIntValue(as, copy->getRHSVar()); } else if (copy->getCopyKind() == CopyStmt::FPTOUI) { - es[lhs] = getFPToUIntValue(es, copy->getRHSVar()); + as[lhs] = getFPToUIntValue(as, copy->getRHSVar()); } else if (copy->getCopyKind() == CopyStmt::SITOFP) { - es[lhs] = getSIntToFPValue(es, copy->getRHSVar()); + as[lhs] = getSIntToFPValue(as, copy->getRHSVar()); } else if (copy->getCopyKind() == CopyStmt::UITOFP) { - es[lhs] = getUIntToFPValue(es, copy->getRHSVar()); + as[lhs] = getUIntToFPValue(as, copy->getRHSVar()); } else if (copy->getCopyKind() == CopyStmt::TRUNC) { - es[lhs] = getTruncValue(es, copy->getRHSVar(), copy->getLHSVar()->getType()); + as[lhs] = getTruncValue(as, copy->getRHSVar(), copy->getLHSVar()->getType()); } else if (copy->getCopyKind() == CopyStmt::FPTRUNC) { - es[lhs] = getFPTruncValue(es, copy->getRHSVar(), copy->getLHSVar()->getType()); + as[lhs] = getFPTruncValue(as, copy->getRHSVar(), copy->getLHSVar()->getType()); } else if (copy->getCopyKind() == CopyStmt::INTTOPTR) { @@ -938,13 +915,13 @@ void SVFIR2AbsState::handleCopy(AbstractState& es, const CopyStmt *copy) } else if (copy->getCopyKind() == CopyStmt::PTRTOINT) { - es[lhs] = IntervalValue::top(); + as[lhs] = IntervalValue::top(); } else if (copy->getCopyKind() == CopyStmt::BITCAST) { - if (es[rhs].isAddr()) + if (as[rhs].isAddr()) { - es[lhs] = es[rhs]; + as[lhs] = as[rhs]; } else { @@ -957,19 +934,19 @@ void SVFIR2AbsState::handleCopy(AbstractState& es, const CopyStmt *copy) abort(); } } - else if (inVarToAddrsTable(es, rhs)) + else if (inVarToAddrsTable(as, rhs)) { - es[lhs] = es[rhs]; + as[lhs] = as[rhs]; } } -void SVFIR2AbsState::handleGep(AbstractState& es, const GepStmt *gep) +void SVFIR2AbsState::handleGep(AbstractState& as, const GepStmt *gep) { u32_t rhs = gep->getRHSVarID(); u32_t lhs = gep->getLHSVarID(); - if (!inVarToAddrsTable(es, rhs)) return; - AbstractValue &rhsVal = es[rhs]; - IntervalValue offsetPair = getElementIndex(es, gep); + if (!inVarToAddrsTable(as, rhs)) return; + AbstractValue &rhsVal = as[rhs]; + IntervalValue offsetPair = getElementIndex(as, gep); if (!isVirtualMemAddress(*rhsVal.getAddrs().begin())) return; else @@ -980,40 +957,40 @@ void SVFIR2AbsState::handleGep(AbstractState& es, const GepStmt *gep) APOffset ub = offsetPair.ub().getIntNumeral() < Options::MaxFieldLimit()? offsetPair.ub().getIntNumeral(): Options::MaxFieldLimit(); for (APOffset i = lb; i <= ub; i++) - gepAddrs.join_with(getGepObjAddress(es, rhs, i)); + gepAddrs.join_with(getGepObjAddress(as, rhs, i)); if (!rhsVal.isUnknown()) - es[lhs] = gepAddrs; + as[lhs] = gepAddrs; return; } } -void SVFIR2AbsState::handleSelect(AbstractState& es, const SelectStmt *select) +void SVFIR2AbsState::handleSelect(AbstractState& as, const SelectStmt *select) { u32_t res = select->getResID(); u32_t tval = select->getTrueValue()->getId(); u32_t fval = select->getFalseValue()->getId(); u32_t cond = select->getCondition()->getId(); - if (inVarToValTable(es, tval) && inVarToValTable(es, fval) && inVarToValTable(es, cond)) + if (inVarToValTable(as, tval) && inVarToValTable(as, fval) && inVarToValTable(as, cond)) { - if (es[cond].getInterval().is_numeral()) + if (as[cond].getInterval().is_numeral()) { - es[res] = es[cond].getInterval().is_zero() ? es[fval] : es[tval]; + as[res] = as[cond].getInterval().is_zero() ? as[fval] : as[tval]; } else { - es[res] = es[cond]; + as[res] = as[cond]; } } - else if (inVarToAddrsTable(es, tval) && inVarToAddrsTable(es, fval) && inVarToValTable(es, cond)) + else if (inVarToAddrsTable(as, tval) && inVarToAddrsTable(as, fval) && inVarToValTable(as, cond)) { - if (es[cond].getInterval().is_numeral()) + if (as[cond].getInterval().is_numeral()) { - es.getAddrs(res) = es[cond].getInterval().is_zero() ? getAddrs(es, fval) : getAddrs(es, tval); + as.getAddrs(res) = as[cond].getInterval().is_zero() ? getAddrs(as, fval) : getAddrs(as, tval); } } } -void SVFIR2AbsState::handlePhi(AbstractState& es, const PhiStmt *phi) +void SVFIR2AbsState::handlePhi(AbstractState& as, const PhiStmt *phi) { u32_t res = phi->getResID(); AbstractValue rhs(AbstractValue::UnknownType); @@ -1021,32 +998,32 @@ void SVFIR2AbsState::handlePhi(AbstractState& es, const PhiStmt *phi) { NodeID curId = phi->getOpVarID(i); - if (inVarToValTable(es, curId) || inVarToAddrsTable(es, curId)) + if (inVarToValTable(as, curId) || inVarToAddrsTable(as, curId)) { - rhs.join_with(es[curId]); + rhs.join_with(as[curId]); } } if (!rhs.isUnknown()) - es[res] = rhs; + as[res] = rhs; } -void SVFIR2AbsState::handleCall(AbstractState& es, const CallPE *callPE) +void SVFIR2AbsState::handleCall(AbstractState& as, const CallPE *callPE) { NodeID lhs = callPE->getLHSVarID(); NodeID rhs = callPE->getRHSVarID(); - if (inVarToValTable(es, rhs) || inVarToAddrsTable(es, rhs)) + if (inVarToValTable(as, rhs) || inVarToAddrsTable(as, rhs)) { - es[lhs] = es[rhs]; + as[lhs] = as[rhs]; } } -void SVFIR2AbsState::handleRet(AbstractState& es, const RetPE *retPE) +void SVFIR2AbsState::handleRet(AbstractState& as, const RetPE *retPE) { NodeID lhs = retPE->getLHSVarID(); NodeID rhs = retPE->getRHSVarID(); - if (inVarToValTable(es, rhs) || inVarToAddrsTable(es, rhs)) + if (inVarToValTable(as, rhs) || inVarToAddrsTable(as, rhs)) { - es[lhs] = es[rhs]; + as[lhs] = as[rhs]; } }