mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
fix for stale LoadGuard segfault
This commit is contained in:
parent
e5c7b58305
commit
cb5ac78c08
3 changed files with 31 additions and 13 deletions
|
@ -992,12 +992,19 @@ void Heritage::guardLoads(uint4 flags,const Address &addr,int4 size,vector<Varno
|
||||||
list<LoadGuard>::iterator iter;
|
list<LoadGuard>::iterator iter;
|
||||||
|
|
||||||
if ((flags & Varnode::addrtied)==0) return; // If not address tied, don't consider for index alias
|
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);
|
LoadGuard &guardRec(*iter);
|
||||||
|
if (!guardRec.isValid()) {
|
||||||
|
list<LoadGuard>::iterator copyIter = iter;
|
||||||
|
++iter;
|
||||||
|
loadGuard.erase(copyIter);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++iter;
|
||||||
if (guardRec.spc != addr.getSpace()) continue;
|
if (guardRec.spc != addr.getSpace()) continue;
|
||||||
if (addr.getOffset() < guardRec.minimumOffset) continue;
|
if (addr.getOffset() < guardRec.minimumOffset) continue;
|
||||||
if (addr.getOffset() > guardRec.maximumOffset) continue;
|
if (addr.getOffset() > guardRec.maximumOffset) continue;
|
||||||
if (guardRec.op->isDead()) continue;
|
|
||||||
copyop = fd->newOp(1,guardRec.op->getAddr());
|
copyop = fd->newOp(1,guardRec.op->getAddr());
|
||||||
Varnode *vn = fd->newVarnodeOut(size,addr,copyop);
|
Varnode *vn = fd->newVarnodeOut(size,addr,copyop);
|
||||||
vn->setActiveHeritage();
|
vn->setActiveHeritage();
|
||||||
|
|
|
@ -126,6 +126,7 @@ public:
|
||||||
uintb getMaximum(void) const { return maximumOffset; } ///< Get maximum offset of the guarded range
|
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)
|
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 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
|
/// \brief Manage the construction of Static Single Assignment (SSA) form
|
||||||
|
|
|
@ -143,18 +143,28 @@ bool RangeHint::absorb(RangeHint *b)
|
||||||
if (rangeType != RangeHint::open) return false;
|
if (rangeType != RangeHint::open) return false;
|
||||||
if (highind < 0) return false;
|
if (highind < 0) return false;
|
||||||
if (b->rangeType == RangeHint::endpoint) return false; // Don't merge with bounding range
|
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->getSize() != b->type->getSize()) return false;
|
||||||
if (settype->getMetatype() == TYPE_UNKNOWN)
|
if (settype != b->type) {
|
||||||
settype = b->type;
|
Datatype *aTestType = type;
|
||||||
else if (b->type->getMetatype() == TYPE_UNKNOWN) {
|
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 ((flags & Varnode::typelock)!=0) return false;
|
||||||
if ((b->flags & Varnode::typelock)!=0) return false;
|
if ((b->flags & Varnode::typelock)!=0) return false;
|
||||||
if (flags != b->flags) return false;
|
if (flags != b->flags) return false;
|
||||||
|
@ -911,7 +921,7 @@ void MapState::gatherOpen(const Funcdata &fd)
|
||||||
const list<LoadGuard> &loadGuard( fd.getLoadGuards() );
|
const list<LoadGuard> &loadGuard( fd.getLoadGuards() );
|
||||||
for(list<LoadGuard>::const_iterator iter=loadGuard.begin();iter!=loadGuard.end();++iter) {
|
for(list<LoadGuard>::const_iterator iter=loadGuard.begin();iter!=loadGuard.end();++iter) {
|
||||||
const LoadGuard &guard( *iter );
|
const LoadGuard &guard( *iter );
|
||||||
if (guard.getOp()->isDead()) continue;
|
if (!guard.isValid()) continue;
|
||||||
int4 step = guard.getStep();
|
int4 step = guard.getStep();
|
||||||
if (step == 0) continue; // No definitive sign of array access
|
if (step == 0) continue; // No definitive sign of array access
|
||||||
Datatype *ct = guard.getOp()->getIn(1)->getType();
|
Datatype *ct = guard.getOp()->getIn(1)->getType();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue