mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
GP-4300 Full extended division in optimized division rules
This commit is contained in:
parent
c63be6d2c3
commit
4bbbba3e5a
17 changed files with 821 additions and 228 deletions
|
@ -780,37 +780,55 @@ void Varnode::printRawHeritage(ostream &s,int4 depth) const
|
|||
s << endl;
|
||||
}
|
||||
|
||||
/// If \b this is a constant, or is extended (INT_ZEXT,INT_SEXT) from a constant,
|
||||
/// the \e value of the constant is passed back and a non-negative integer is returned, either:
|
||||
/// - 0 for a normal constant Varnode
|
||||
/// - 1 for a zero extension (INT_ZEXT) of a normal constant
|
||||
/// - 2 for a sign extension (INT_SEXT) of a normal constant
|
||||
/// \param val is a reference to the constant value that is passed back
|
||||
/// \return the extension code (or -1 if \b this cannot be interpreted as a constant)
|
||||
int4 Varnode::isConstantExtended(uintb &val) const
|
||||
/// If \b this is a constant, or is extended (INT_ZEXT,INT_SEXT,PIECE) from a constant,
|
||||
/// the \e value of the constant (currently up to 128 bits) is passed back and \b true is returned.
|
||||
/// \param val will hold the 128-bit constant value
|
||||
/// \return \b true if a constant was recovered
|
||||
bool Varnode::isConstantExtended(uint8 *val) const
|
||||
|
||||
{
|
||||
if (isConstant()) {
|
||||
val = getOffset();
|
||||
return 0;
|
||||
val[0] = getOffset();
|
||||
val[1] = 0;
|
||||
return true;
|
||||
}
|
||||
if (!isWritten()) return -1;
|
||||
if (!isWritten() || size <= 8) return false;
|
||||
if (size > 16) return false; // Currently only up to 128-bit values
|
||||
OpCode opc = def->code();
|
||||
if (opc == CPUI_INT_ZEXT) {
|
||||
Varnode *vn0 = def->getIn(0);
|
||||
if (vn0->isConstant()) {
|
||||
val = vn0->getOffset();
|
||||
return 1;
|
||||
val[0] = vn0->getOffset();
|
||||
val[1] = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (opc == CPUI_INT_SEXT) {
|
||||
Varnode *vn0 = def->getIn(0);
|
||||
if (vn0->isConstant()) {
|
||||
val = vn0->getOffset();
|
||||
return 2;
|
||||
val[0] = vn0->getOffset();
|
||||
if (vn0->getSize() < 8)
|
||||
val[0] = sign_extend(val[0], vn0->getSize(), size);
|
||||
val[1] = (signbit_negative(val[0], 8)) ? 0xffffffffffffffffL : 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
else if (opc == CPUI_PIECE) {
|
||||
Varnode *vnlo = def->getIn(1);
|
||||
if (vnlo->isConstant()) {
|
||||
val[0] = vnlo->getOffset();
|
||||
Varnode *vnhi = def->getIn(0);
|
||||
if (vnhi->isConstant()) {
|
||||
val[1] = vnhi->getOffset();
|
||||
if (vnlo->getSize() == 8)
|
||||
return true;
|
||||
val[0] |= val[1] << 8*vnlo->getSize();
|
||||
val[1] >>= 8*(8-vnlo->getSize());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Make an initial determination of the Datatype of this Varnode. If a Datatype is already
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue