fix for stale LoadGuard segfault

This commit is contained in:
caheckman 2019-06-17 12:26:55 -04:00
parent e5c7b58305
commit cb5ac78c08
3 changed files with 31 additions and 13 deletions

View File

@ -992,12 +992,19 @@ void Heritage::guardLoads(uint4 flags,const Address &addr,int4 size,vector<Varno
list<LoadGuard>::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<LoadGuard>::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();

View File

@ -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

View File

@ -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> &loadGuard( fd.getLoadGuards() );
for(list<LoadGuard>::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();