overflow checks, take into account LOAD size

This commit is contained in:
caheckman 2019-06-17 23:47:05 -04:00
parent cb5ac78c08
commit 2a73bca9ac
4 changed files with 39 additions and 11 deletions

View file

@ -642,8 +642,10 @@ void LoadGuard::finalizeRange(const ValueSetRead &valueSet)
step = range.getStep(); step = range.getStep();
minimumOffset = range.getMin(); minimumOffset = range.getMin();
maximumOffset = (range.getEnd() - 1) & range.getMask(); // NOTE: Don't subtract a whole step maximumOffset = (range.getEnd() - 1) & range.getMask(); // NOTE: Don't subtract a whole step
if (maximumOffset < minimumOffset) // Values extend into what is usually stack parameters if (maximumOffset < minimumOffset) { // Values extend into what is usually stack parameters
maximumOffset = spc->getHighest(); maximumOffset = spc->getHighest();
analysisState = 1; // Remove the lock as we have likely overflowed
}
} }
if (minimumOffset > spc->getHighest()) if (minimumOffset > spc->getHighest())
minimumOffset = spc->getHighest(); minimumOffset = spc->getHighest();

View file

@ -2565,3 +2565,21 @@ void ValueSetSolver::solve(int4 max,Widener &widener)
for(riter=readNodes.begin();riter!=readNodes.end();++riter) for(riter=readNodes.begin();riter!=readNodes.end();++riter)
(*riter).second.compute(); // Calculate any follow-on value sets (*riter).second.compute(); // Calculate any follow-on value sets
} }
#ifdef CPUI_DEBUG
void ValueSetSolver::dumpValueSets(ostream &s) const
{
list<ValueSet>::const_iterator iter;
for(iter=valueNodes.begin();iter!=valueNodes.end();++iter) {
(*iter).printRaw(s);
s << endl;
}
map<SeqNum,ValueSetRead>::const_iterator riter;
for(riter=readNodes.begin();riter!=readNodes.end();++riter) {
(*riter).second.printRaw(s);
s << endl;
}
}
#endif

View file

@ -319,6 +319,9 @@ public:
map<SeqNum,ValueSetRead>::const_iterator beginValueSetReads(void) const { return readNodes.begin(); } ///< Start of ValueSetReads map<SeqNum,ValueSetRead>::const_iterator beginValueSetReads(void) const { return readNodes.begin(); } ///< Start of ValueSetReads
map<SeqNum,ValueSetRead>::const_iterator endValueSetReads(void) const { return readNodes.end(); } ///< End of ValueSetReads map<SeqNum,ValueSetRead>::const_iterator endValueSetReads(void) const { return readNodes.end(); } ///< End of ValueSetReads
const ValueSetRead &getValueSetRead(const SeqNum &seq) { return (*readNodes.find(seq)).second; } ///< Get ValueSetRead by SeqNum const ValueSetRead &getValueSetRead(const SeqNum &seq) { return (*readNodes.find(seq)).second; } ///< Get ValueSetRead by SeqNum
#ifdef CPUI_DEBUG
void dumpValueSets(ostream &s) const;
#endif
}; };
/// \param op2 is the range to compare \b this to /// \param op2 is the range to compare \b this to

View file

@ -258,10 +258,14 @@ bool RangeHint::merge(RangeHint *b,AddrSpace *space,TypeFactory *typeFactory)
return overlapProblems; // Discard b entirely in favor of a return overlapProblems; // Discard b entirely in favor of a
} }
// Concede confusion about types, set unknown type rather than a or b's type // Concede confusion about types, set unknown type rather than a or b's type
rangeType = RangeHint::fixed;
size = space->wrapOffset(end-start); size = space->wrapOffset(end-start);
if (size != 1 && size != 2 && size != 4 && size != 8) {
size = 1;
rangeType = RangeHint::open;
}
type = typeFactory->getBase(size,TYPE_UNKNOWN); type = typeFactory->getBase(size,TYPE_UNKNOWN);
flags = 0; flags = 0;
rangeType = RangeHint::fixed;
highind = -1; highind = -1;
return overlapProblems; return overlapProblems;
} }
@ -929,16 +933,17 @@ void MapState::gatherOpen(const Funcdata &fd)
ct = ((TypePointer *) ct)->getPtrTo(); ct = ((TypePointer *) ct)->getPtrTo();
while (ct->getMetatype() == TYPE_ARRAY) while (ct->getMetatype() == TYPE_ARRAY)
ct = ((TypeArray *) ct)->getBase(); ct = ((TypeArray *) ct)->getBase();
if (ct->getSize() != step) {
// Datatype doesn't match step: field in array of structures or something more unusual
if (ct->getSize() > step || (step % ct->getSize()) != 0)
continue;
// Since ct's size divides the step and we want to preserve the arrayness
// we pretend we have an array of ct's size
step = ct->getSize();
}
} }
else { int4 outSize = guard.getOp()->getOut()->getSize();
if (outSize != step) {
// LOAD size doesn't match step: field in array of structures or something more unusual
if (outSize > step || (step % outSize) != 0)
continue;
// Since the LOAD size divides the step and we want to preserve the arrayness
// we pretend we have an array of LOAD's size
step = outSize;
}
if (ct->getSize() != step) { // Make sure data-type matches our step size
if (step > 8) if (step > 8)
continue; // Don't manufacture primitives bigger than 8-bytes continue; // Don't manufacture primitives bigger than 8-bytes
ct = fd.getArch()->types->getBase(step, TYPE_UNKNOWN); ct = fd.getArch()->types->getBase(step, TYPE_UNKNOWN);