mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-02 08:08:10 +08:00
Merge remote-tracking branch 'origin/GP-2956_SubpieceZext'
This commit is contained in:
@@ -4019,6 +4019,10 @@ int4 RuleStoreVarnode::applyOp(PcodeOp *op,Funcdata &data)
|
|||||||
/// This is in keeping with the philosophy to push SUBPIECE back earlier in the expression.
|
/// This is in keeping with the philosophy to push SUBPIECE back earlier in the expression.
|
||||||
/// The original SUBPIECE is changed into the INT_ZEXT, but the original INT_ZEXT is
|
/// The original SUBPIECE is changed into the INT_ZEXT, but the original INT_ZEXT is
|
||||||
/// not changed, a new SUBPIECE is created.
|
/// not changed, a new SUBPIECE is created.
|
||||||
|
/// There are corner cases, if the SUBPIECE doesn't hit extended bits or is ultimately unnecessary.
|
||||||
|
/// - `sub(zext(V),c) => sub(V,C)`
|
||||||
|
/// - `sub(zext(V),0) => zext(V)`
|
||||||
|
///
|
||||||
/// This rule also works with INT_SEXT.
|
/// This rule also works with INT_SEXT.
|
||||||
void RuleSubExtComm::getOpList(vector<uint4> &oplist) const
|
void RuleSubExtComm::getOpList(vector<uint4> &oplist) const
|
||||||
|
|
||||||
@@ -4029,24 +4033,37 @@ void RuleSubExtComm::getOpList(vector<uint4> &oplist) const
|
|||||||
int4 RuleSubExtComm::applyOp(PcodeOp *op,Funcdata &data)
|
int4 RuleSubExtComm::applyOp(PcodeOp *op,Funcdata &data)
|
||||||
|
|
||||||
{
|
{
|
||||||
int4 subcut = (int4)op->getIn(1)->getOffset();
|
|
||||||
Varnode *base = op->getIn(0);
|
Varnode *base = op->getIn(0);
|
||||||
// Make sure subpiece preserves most sig bytes
|
|
||||||
if (op->getOut()->getSize()+subcut != base->getSize()) return 0;
|
|
||||||
if (!base->isWritten()) return 0;
|
if (!base->isWritten()) return 0;
|
||||||
PcodeOp *extop = base->getDef();
|
PcodeOp *extop = base->getDef();
|
||||||
if ((extop->code()!=CPUI_INT_ZEXT)&&(extop->code()!=CPUI_INT_SEXT))
|
if ((extop->code()!=CPUI_INT_ZEXT)&&(extop->code()!=CPUI_INT_SEXT))
|
||||||
return 0;
|
return 0;
|
||||||
Varnode *invn = extop->getIn(0);
|
Varnode *invn = extop->getIn(0);
|
||||||
if (invn->isFree()) return 0;
|
if (invn->isFree()) return 0;
|
||||||
|
int4 subcut = (int4)op->getIn(1)->getOffset();
|
||||||
|
if (op->getOut()->getSize() + subcut <= invn->getSize()) {
|
||||||
|
// SUBPIECE doesn't hit the extended bits at all
|
||||||
|
data.opSetInput(op,invn,0);
|
||||||
|
if (invn->getSize() == op->getOut()->getSize()) {
|
||||||
|
data.opRemoveInput(op, 1);
|
||||||
|
data.opSetOpcode(op, CPUI_COPY);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (subcut >= invn->getSize()) return 0;
|
if (subcut >= invn->getSize()) return 0;
|
||||||
|
|
||||||
PcodeOp *newop = data.newOp(2,op->getAddr());
|
Varnode *newvn;
|
||||||
data.opSetOpcode(newop,CPUI_SUBPIECE);
|
if (subcut != 0) {
|
||||||
Varnode *newvn = data.newUniqueOut(invn->getSize()-subcut,newop);
|
PcodeOp *newop = data.newOp(2,op->getAddr());
|
||||||
data.opSetInput(newop,data.newConstant(op->getIn(1)->getSize(),(uintb)subcut),1);
|
data.opSetOpcode(newop,CPUI_SUBPIECE);
|
||||||
data.opSetInput(newop,invn,0);
|
newvn = data.newUniqueOut(invn->getSize()-subcut,newop);
|
||||||
data.opInsertBefore(newop,op);
|
data.opSetInput(newop,data.newConstant(op->getIn(1)->getSize(),(uintb)subcut),1);
|
||||||
|
data.opSetInput(newop,invn,0);
|
||||||
|
data.opInsertBefore(newop,op);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
newvn = invn;
|
||||||
|
|
||||||
data.opRemoveInput(op,1);
|
data.opRemoveInput(op,1);
|
||||||
data.opSetOpcode(op,extop->code());
|
data.opSetOpcode(op,extop->code());
|
||||||
@@ -4626,6 +4643,8 @@ int4 RuleSubZext::applyOp(PcodeOp *op,Funcdata &data)
|
|||||||
basevn = subop->getIn(0);
|
basevn = subop->getIn(0);
|
||||||
if (basevn->isFree()) return 0;
|
if (basevn->isFree()) return 0;
|
||||||
if (basevn->getSize() != op->getOut()->getSize()) return 0; // Truncating then extending to same size
|
if (basevn->getSize() != op->getOut()->getSize()) return 0; // Truncating then extending to same size
|
||||||
|
if (basevn->getSize() > sizeof(uintb))
|
||||||
|
return 0;
|
||||||
if (subop->getIn(1)->getOffset() != 0) { // If truncating from middle
|
if (subop->getIn(1)->getOffset() != 0) { // If truncating from middle
|
||||||
if (subvn->loneDescend() != op) return 0; // and there is no other use of the truncated value
|
if (subvn->loneDescend() != op) return 0; // and there is no other use of the truncated value
|
||||||
Varnode *newvn = data.newUnique(basevn->getSize(),(Datatype *)0);
|
Varnode *newvn = data.newUnique(basevn->getSize(),(Datatype *)0);
|
||||||
|
|||||||
Reference in New Issue
Block a user