mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
overflow checks, take into account LOAD size
This commit is contained in:
parent
cb5ac78c08
commit
2a73bca9ac
4 changed files with 39 additions and 11 deletions
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
int4 outSize = guard.getOp()->getOut()->getSize();
|
||||||
if (ct->getSize() > step || (step % ct->getSize()) != 0)
|
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;
|
continue;
|
||||||
// Since ct's size divides the step and we want to preserve the arrayness
|
// Since the LOAD size divides the step and we want to preserve the arrayness
|
||||||
// we pretend we have an array of ct's size
|
// we pretend we have an array of LOAD's size
|
||||||
step = ct->getSize();
|
step = outSize;
|
||||||
}
|
}
|
||||||
}
|
if (ct->getSize() != step) { // Make sure data-type matches our step size
|
||||||
else {
|
|
||||||
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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue