mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GP-4871 Don't ignore signed to unsigned integer casts for
FLOAT_INT2FLOAT
This commit is contained in:
parent
a4d97ff872
commit
e5969a613c
16 changed files with 408 additions and 16 deletions
|
@ -330,6 +330,41 @@ bool SubvariableFlow::trySwitchPull(PcodeOp *op,ReplaceVarnode *rvn)
|
|||
return true;
|
||||
}
|
||||
|
||||
/// \brief Determine if the subgraph variable flows naturally into a terminal FLOAT_INT2FLOAT operation
|
||||
///
|
||||
/// The original data-flow must pad the logical value with zero bits, making the conversion to
|
||||
/// floating-point unsigned. A PatchRecord is created that preserves the FLOAT_INT2FLOAT but inserts an
|
||||
/// additional INT_ZEXT operation to preserve the unsigned nature of the conversion.
|
||||
/// \param op is the FLOAT_INT2FLOAT conversion operation
|
||||
/// \param rvn is the logical value flowing into the conversion
|
||||
bool SubvariableFlow::tryInt2FloatPull(PcodeOp *op,ReplaceVarnode *rvn)
|
||||
|
||||
{
|
||||
if ((rvn->mask & 1) == 0) return false; // Logical value must be justified
|
||||
if ((rvn->vn->getNZMask()&~rvn->mask)!=0)
|
||||
return false; // Everything outside the logical value must be zero
|
||||
if (rvn->vn->getSize() == flowsize)
|
||||
return false; // There must be some (zero) extension
|
||||
bool pullModification = true;
|
||||
if (rvn->vn->isWritten() && rvn->vn->getDef()->code() == CPUI_INT_ZEXT) {
|
||||
if (rvn->vn->getSize() == TypeOpFloatInt2Float::preferredZextSize(flowsize)) {
|
||||
if (rvn->vn->loneDescend() == op) {
|
||||
pullModification = false; // This patch does not count as a modification
|
||||
// The INT_ZEXT -> FLOAT_INT2FLOAT has the correct form and does not need to be modified.
|
||||
// We indicate this by NOT incrementing pullcount, so there has to be at least one other
|
||||
// terminal patch in order for doTrace() to return true.
|
||||
}
|
||||
}
|
||||
}
|
||||
patchlist.emplace_back();
|
||||
patchlist.back().type = PatchRecord::int2float_patch;
|
||||
patchlist.back().patchOp = op;
|
||||
patchlist.back().in1 = rvn;
|
||||
if (pullModification)
|
||||
pullcount += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Try to trace the logical variable through descendant Varnodes
|
||||
/// creating new nodes in the logical subgraph and updating the worklist.
|
||||
/// \param rvn is the given subgraph variable to trace
|
||||
|
@ -586,6 +621,10 @@ bool SubvariableFlow::traceForward(ReplaceVarnode *rvn)
|
|||
if (rvn->mask != 1) return false;
|
||||
addBooleanPatch(op,rvn,slot);
|
||||
break;
|
||||
case CPUI_FLOAT_INT2FLOAT:
|
||||
if (!tryInt2FloatPull(op, rvn)) return false;
|
||||
hcount += 1;
|
||||
break;
|
||||
case CPUI_CBRANCH:
|
||||
if ((bitsize != 1)||(slot != 1)) return false;
|
||||
if (rvn->mask != 1) return false;
|
||||
|
@ -1451,6 +1490,18 @@ void SubvariableFlow::doReplacement(void)
|
|||
}
|
||||
case PatchRecord::push_patch:
|
||||
break; // Shouldn't see these here, handled earlier
|
||||
case PatchRecord::int2float_patch:
|
||||
{
|
||||
PcodeOp *zextOp = fd->newOp(1, pullop->getAddr());
|
||||
fd->opSetOpcode(zextOp, CPUI_INT_ZEXT);
|
||||
Varnode *invn = getReplaceVarnode((*piter).in1);
|
||||
fd->opSetInput(zextOp,invn,0);
|
||||
int4 sizeout = TypeOpFloatInt2Float::preferredZextSize(invn->getSize());
|
||||
Varnode *outvn = fd->newUniqueOut(sizeout, zextOp);
|
||||
fd->opInsertBefore(zextOp, pullop);
|
||||
fd->opSetInput(pullop, outvn, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue