diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.cc index c7abdf43dd..38a6b211a4 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.cc @@ -992,12 +992,19 @@ void Heritage::guardLoads(uint4 flags,const Address &addr,int4 size,vector::iterator iter; if ((flags & Varnode::addrtied)==0) return; // If not address tied, don't consider for index alias - for(iter=loadGuard.begin();iter!=loadGuard.end();++iter) { + iter = loadGuard.begin(); + while(iter!=loadGuard.end()) { LoadGuard &guardRec(*iter); + if (!guardRec.isValid()) { + list::iterator copyIter = iter; + ++iter; + loadGuard.erase(copyIter); + continue; + } + ++iter; if (guardRec.spc != addr.getSpace()) continue; if (addr.getOffset() < guardRec.minimumOffset) continue; if (addr.getOffset() > guardRec.maximumOffset) continue; - if (guardRec.op->isDead()) continue; copyop = fd->newOp(1,guardRec.op->getAddr()); Varnode *vn = fd->newVarnodeOut(size,addr,copyop); vn->setActiveHeritage(); diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.hh b/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.hh index 8fef13bd01..eb0f58cd7b 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.hh +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/heritage.hh @@ -126,6 +126,7 @@ public: uintb getMaximum(void) const { return maximumOffset; } ///< Get maximum offset of the guarded range int4 getStep(void) const { return step; } ///< Get the calculated step associated with the range (or 0) bool isRangeLocked(void) const { return (analysisState == 2); } ///< Return \b true if the range is fully determined + bool isValid(void) const { return (!op->isDead() && op->code() == CPUI_LOAD); } ///< Return \b true if the record still describes an active LOAD }; /// \brief Manage the construction of Static Single Assignment (SSA) form diff --git a/Ghidra/Features/Decompiler/src/decompile/cpp/varmap.cc b/Ghidra/Features/Decompiler/src/decompile/cpp/varmap.cc index 9dc10e4f90..a52ac0c98d 100644 --- a/Ghidra/Features/Decompiler/src/decompile/cpp/varmap.cc +++ b/Ghidra/Features/Decompiler/src/decompile/cpp/varmap.cc @@ -143,18 +143,28 @@ bool RangeHint::absorb(RangeHint *b) if (rangeType != RangeHint::open) return false; if (highind < 0) return false; if (b->rangeType == RangeHint::endpoint) return false; // Don't merge with bounding range - Datatype *settype = type; + Datatype *settype = type; // Assume we will keep this data-type if (settype->getSize() != b->type->getSize()) return false; - if (settype->getMetatype() == TYPE_UNKNOWN) - settype = b->type; - else if (b->type->getMetatype() == TYPE_UNKNOWN) { + if (settype != b->type) { + Datatype *aTestType = type; + Datatype *bTestType = b->type; + while(aTestType->getMetatype() == TYPE_PTR) { + if (bTestType->getMetatype() != TYPE_PTR) + break; + aTestType = ((TypePointer *)aTestType)->getPtrTo(); + bTestType = ((TypePointer *)bTestType)->getPtrTo(); + } + if (aTestType->getMetatype() == TYPE_UNKNOWN) + settype = b->type; + else if (bTestType->getMetatype() == TYPE_UNKNOWN) { + } + else if (aTestType->getMetatype() == TYPE_INT && bTestType->getMetatype() == TYPE_UINT) { + } + else if (aTestType->getMetatype() == TYPE_UINT && bTestType->getMetatype() == TYPE_INT) { + } + else if (aTestType != bTestType) // If they are both not unknown, they must be the same + return false; } - else if (settype->getMetatype() == TYPE_INT && b->type->getMetatype() == TYPE_UINT) { - } - else if (settype->getMetatype() == TYPE_UINT && b->type->getMetatype() == TYPE_INT) { - } - else if (settype != b->type) // If they are both not unknown, they must be the same - return false; if ((flags & Varnode::typelock)!=0) return false; if ((b->flags & Varnode::typelock)!=0) return false; if (flags != b->flags) return false; @@ -911,7 +921,7 @@ void MapState::gatherOpen(const Funcdata &fd) const list &loadGuard( fd.getLoadGuards() ); for(list::const_iterator iter=loadGuard.begin();iter!=loadGuard.end();++iter) { const LoadGuard &guard( *iter ); - if (guard.getOp()->isDead()) continue; + if (!guard.isValid()) continue; int4 step = guard.getStep(); if (step == 0) continue; // No definitive sign of array access Datatype *ct = guard.getOp()->getIn(1)->getType();