mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-09-20 09:31:47 +00:00
Merge branch
'GP-0_caheckman_PR-6578_LukeSerne_decomp-rule-int-or-zero-compare' into GP-4859_RuleOrCompare
This commit is contained in:
commit
2ef83410be
|
@ -5522,6 +5522,7 @@ void ActionDatabase::universalAction(Architecture *conf)
|
|||
actprop->addRule( new RuleXorSwap("analysis") );
|
||||
actprop->addRule( new RuleLzcountShiftBool("analysis") );
|
||||
actprop->addRule( new RuleFloatSign("analysis") );
|
||||
actprop->addRule( new RuleOrCompare("analysis") );
|
||||
actprop->addRule( new RuleSubvarAnd("subvar") );
|
||||
actprop->addRule( new RuleSubvarSubpiece("subvar") );
|
||||
actprop->addRule( new RuleSplitFlow("subvar") );
|
||||
|
|
|
@ -10542,4 +10542,63 @@ int4 RuleFloatSignCleanup::applyOp(PcodeOp *op,Funcdata &data)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/// \class RuleOrCompare
|
||||
/// \brief Simplify INT_OR in comparisons with 0.
|
||||
///
|
||||
/// `(V | W) == 0` => '(V == 0) && (W == 0)'
|
||||
/// `(V | W) != 0` => '(V != 0) || (W != 0)'
|
||||
void RuleOrCompare::getOpList(vector<uint4> &oplist) const
|
||||
|
||||
{
|
||||
oplist.push_back(CPUI_INT_EQUAL);
|
||||
oplist.push_back(CPUI_INT_NOTEQUAL);
|
||||
}
|
||||
|
||||
int4 RuleOrCompare::applyOp(PcodeOp *op,Funcdata &data)
|
||||
|
||||
{
|
||||
// make sure the comparison is against 0
|
||||
if (! op->getIn(1)->constantMatch(0)) return 0;
|
||||
|
||||
// make sure the other operand is an INT_OR
|
||||
PcodeOp *or_op = op->getIn(0)->getDef();
|
||||
if (or_op == (PcodeOp *)0) return 0;
|
||||
if (or_op->code() != CPUI_INT_OR) return 0;
|
||||
|
||||
Varnode* V = or_op->getIn(0);
|
||||
Varnode* W = or_op->getIn(1);
|
||||
|
||||
// make sure V and W are in SSA form
|
||||
if (V->isFree()) return 0;
|
||||
if (W->isFree()) return 0;
|
||||
|
||||
// construct the new segment:
|
||||
// if the original condition was INT_EQUAL: BOOL_AND(INT_EQUAL(V, 0:|V|), INT_EQUAL(W, 0:|W|))
|
||||
// if the original condition was INT_NOTEQUAL: BOOL_OR(INT_NOTEQUAL(V, 0:|V|), INT_NOTEQUAL(W, 0:|W|))
|
||||
Varnode* zero_V = data.newConstant(V->getSize(), 0);
|
||||
Varnode* zero_W = data.newConstant(W->getSize(), 0);
|
||||
PcodeOp* eq_V = data.newOp(2, op->getAddr());
|
||||
data.opSetOpcode(eq_V, op->code());
|
||||
data.opSetInput(eq_V, V, 0);
|
||||
data.opSetInput(eq_V, zero_V, 1);
|
||||
PcodeOp* eq_W = data.newOp(2, op->getAddr());
|
||||
data.opSetOpcode(eq_W, op->code());
|
||||
data.opSetInput(eq_W, W, 0);
|
||||
data.opSetInput(eq_W, zero_W, 1);
|
||||
|
||||
Varnode* eq_V_out = data.newUniqueOut(1, eq_V);
|
||||
Varnode* eq_W_out = data.newUniqueOut(1, eq_W);
|
||||
|
||||
// make sure the comparisons' output is already defined
|
||||
data.opInsertBefore(eq_V, op);
|
||||
data.opInsertBefore(eq_W, op);
|
||||
|
||||
// change the original INT_EQUAL into a BOOL_AND, and INT_NOTEQUAL becomes BOOL_OR
|
||||
data.opSetOpcode(op, op->code() == CPUI_INT_EQUAL ? CPUI_BOOL_AND : CPUI_BOOL_OR);
|
||||
data.opSetInput(op, eq_V_out, 0);
|
||||
data.opSetInput(op, eq_W_out, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // End namespace ghidra
|
||||
|
|
|
@ -1666,5 +1666,16 @@ public:
|
|||
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
|
||||
};
|
||||
|
||||
class RuleOrCompare : public Rule {
|
||||
public:
|
||||
RuleOrCompare(const string &g) : Rule( g, 0, "orcompare") {} ///< Constructor
|
||||
virtual Rule *clone(const ActionGroupList &grouplist) const {
|
||||
if (!grouplist.contains(getGroup())) return (Rule *)0;
|
||||
return new RuleOrCompare(getGroup());
|
||||
}
|
||||
virtual void getOpList(vector<uint4> &oplist) const;
|
||||
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
|
||||
};
|
||||
|
||||
} // End namespace ghidra
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue
Block a user