mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-22 04:05:39 +00:00
GP-4859 RuleOrCompare
This commit is contained in:
parent
2ef83410be
commit
a31c4033a8
@ -50,6 +50,7 @@ src/decompile/datatests/noforloop_alias.xml||GHIDRA||||END|
|
||||
src/decompile/datatests/noforloop_globcall.xml||GHIDRA||||END|
|
||||
src/decompile/datatests/noforloop_iterused.xml||GHIDRA||||END|
|
||||
src/decompile/datatests/offsetarray.xml||GHIDRA||||END|
|
||||
src/decompile/datatests/orcompare.xml||GHIDRA||||END|
|
||||
src/decompile/datatests/packstructaccess.xml||GHIDRA||||END|
|
||||
src/decompile/datatests/partialmerge.xml||GHIDRA||||END|
|
||||
src/decompile/datatests/partialsplit.xml||GHIDRA||||END|
|
||||
|
@ -5518,7 +5518,6 @@ void ActionDatabase::universalAction(Architecture *conf)
|
||||
actprop->addRule( new RulePiece2Zext("analysis") );
|
||||
actprop->addRule( new RulePiece2Sext("analysis") );
|
||||
actprop->addRule( new RulePopcountBoolXor("analysis") );
|
||||
actprop->addRule( new RuleOrMultiBool("analysis") );
|
||||
actprop->addRule( new RuleXorSwap("analysis") );
|
||||
actprop->addRule( new RuleLzcountShiftBool("analysis") );
|
||||
actprop->addRule( new RuleFloatSign("analysis") );
|
||||
|
@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@ -1124,9 +1124,6 @@ int4 SplitVarnode::applyRuleIn(SplitVarnode &in,Funcdata &data)
|
||||
break;
|
||||
case CPUI_INT_OR:
|
||||
{
|
||||
Equal2Form equal2form;
|
||||
if (equal2form.applyRule(in,workop,workishi,data))
|
||||
return 1;
|
||||
LogicalForm logicalform;
|
||||
if (logicalform.applyRule(in,workop,workishi,data))
|
||||
return 1;
|
||||
@ -1134,9 +1131,6 @@ int4 SplitVarnode::applyRuleIn(SplitVarnode &in,Funcdata &data)
|
||||
break;
|
||||
case CPUI_INT_XOR:
|
||||
{
|
||||
Equal2Form equal2form;
|
||||
if (equal2form.applyRule(in,workop,workishi,data))
|
||||
return 1;
|
||||
LogicalForm logicalform;
|
||||
if (logicalform.applyRule(in,workop,workishi,data))
|
||||
return 1;
|
||||
@ -1151,6 +1145,9 @@ int4 SplitVarnode::applyRuleIn(SplitVarnode &in,Funcdata &data)
|
||||
Equal1Form equal1form;
|
||||
if (equal1form.applyRule(in,workop,workishi,data))
|
||||
return 1;
|
||||
Equal2Form equal2form;
|
||||
if (equal2form.applyRule(in,workop,workishi,data))
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case CPUI_INT_LESS:
|
||||
@ -1870,95 +1867,30 @@ bool Equal1Form::applyRule(SplitVarnode &i,PcodeOp *hop,bool workishi,Funcdata &
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Equal2Form::checkLoForm(void)
|
||||
|
||||
{ // Assuming we have equal <- or <- xor <- hi1, verify if we have the full equal form
|
||||
Varnode *orvnin = orop->getIn(1-orhislot);
|
||||
if (orvnin == lo1) { // lo2 is an implied 0
|
||||
loxor = (PcodeOp *)0;
|
||||
lo2 = (Varnode *)0;
|
||||
return true;
|
||||
}
|
||||
if (!orvnin->isWritten()) return false;
|
||||
loxor = orvnin->getDef();
|
||||
if (loxor->code() != CPUI_INT_XOR) return false;
|
||||
if (loxor->getIn(0) == lo1) {
|
||||
lo2 = loxor->getIn(1);
|
||||
return true;
|
||||
}
|
||||
else if (loxor->getIn(1) == lo1) {
|
||||
lo2 = loxor->getIn(0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Equal2Form::fillOutFromOr(Funcdata &data)
|
||||
|
||||
{ // We have filled in either or <- xor <- hi1, OR, or <- hi1
|
||||
// Now try to fill in the rest of the form
|
||||
Varnode *outvn = orop->getOut();
|
||||
list<PcodeOp *>::const_iterator iter,enditer;
|
||||
iter = outvn->beginDescend();
|
||||
enditer = outvn->endDescend();
|
||||
while(iter != enditer) {
|
||||
equalop = *iter;
|
||||
++iter;
|
||||
if ((equalop->code() != CPUI_INT_EQUAL)&&(equalop->code() != CPUI_INT_NOTEQUAL)) continue;
|
||||
if (!equalop->getIn(1)->isConstant()) continue;
|
||||
if (equalop->getIn(1)->getOffset() != 0) continue;
|
||||
|
||||
if (!checkLoForm()) continue;
|
||||
if (!replace(data)) continue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Equal2Form::replace(Funcdata &data)
|
||||
|
||||
{
|
||||
if ((hi2==(Varnode *)0)&&(lo2==(Varnode *)0)) {
|
||||
param2.initPartial(in.getSize(),0); // Double precis zero constant
|
||||
return SplitVarnode::prepareBoolOp(in,param2,equalop);
|
||||
}
|
||||
if ((hi2==(Varnode *)0)&&(lo2->isConstant())) {
|
||||
param2.initPartial(in.getSize(),lo2->getOffset());
|
||||
return SplitVarnode::prepareBoolOp(in,param2,equalop);
|
||||
}
|
||||
if ((lo2==(Varnode *)0)&&(hi2->isConstant())) {
|
||||
param2.initPartial(in.getSize(),hi2->getOffset() << 8*lo1->getSize());
|
||||
return SplitVarnode::prepareBoolOp(in,param2,equalop);
|
||||
}
|
||||
if (lo2 == (Varnode *)0) {
|
||||
// Equal to a zero extended and shifted var
|
||||
return false;
|
||||
}
|
||||
if (hi2 == (Varnode *)0) {
|
||||
// Equal to a zero extended var
|
||||
return false;
|
||||
}
|
||||
if (hi2->isConstant()&&lo2->isConstant()) {
|
||||
uintb val = hi2->getOffset();
|
||||
val <<= 8*lo1->getSize();
|
||||
val |= lo2->getOffset();
|
||||
param2.initPartial(in.getSize(),val);
|
||||
return SplitVarnode::prepareBoolOp(in,param2,equalop);
|
||||
return SplitVarnode::prepareBoolOp(in,param2,boolAndOr);
|
||||
}
|
||||
if (hi2->isConstant()||lo2->isConstant()) {
|
||||
// Some kind of mixed form
|
||||
return false;
|
||||
}
|
||||
param2.initPartial(in.getSize(),lo2,hi2);
|
||||
return SplitVarnode::prepareBoolOp(in,param2,equalop);
|
||||
return SplitVarnode::prepareBoolOp(in,param2,boolAndOr);
|
||||
}
|
||||
|
||||
// Given a known double precis input, look for double precision compares of the form
|
||||
// a == b, a != b
|
||||
//
|
||||
// We look for
|
||||
// res = ((hi1 ^ hi2) | (lo1 ^ lo2) == 0)
|
||||
// where hi2 or lo2 may be zero, and optimized out
|
||||
// res = (hi1 == hi2) && (lo1 == lo2) or
|
||||
// res = (hi1 != hi2) || (lo1 != lo2)
|
||||
bool Equal2Form::applyRule(SplitVarnode &i,PcodeOp *op,bool workishi,Funcdata &data)
|
||||
|
||||
{
|
||||
@ -1967,41 +1899,37 @@ bool Equal2Form::applyRule(SplitVarnode &i,PcodeOp *op,bool workishi,Funcdata &d
|
||||
in = i;
|
||||
hi1 = in.getHi();
|
||||
lo1 = in.getLo();
|
||||
|
||||
if (op->code() == CPUI_INT_OR) {
|
||||
orop = op;
|
||||
orhislot = op->getSlot(hi1);
|
||||
hixor = (PcodeOp *)0;
|
||||
hi2 = (Varnode *)0;
|
||||
if (fillOutFromOr(data)) {
|
||||
if (!param2.exceedsConstPrecision()) {
|
||||
SplitVarnode::replaceBoolOp(data,equalop,in,param2,equalop->code());
|
||||
return true;
|
||||
}
|
||||
OpCode eqCode = op->code();
|
||||
int4 hi1slot = op->getSlot(hi1);
|
||||
hi2 = op->getIn(1-hi1slot);
|
||||
Varnode *outvn = op->getOut();
|
||||
list<PcodeOp *>::const_iterator iter,enditer;
|
||||
iter = outvn->beginDescend();
|
||||
enditer = outvn->endDescend();
|
||||
while(iter != enditer) {
|
||||
boolAndOr = *iter;
|
||||
++iter;
|
||||
if (eqCode == CPUI_INT_EQUAL && boolAndOr->code() != CPUI_BOOL_AND) continue;
|
||||
if (eqCode == CPUI_INT_NOTEQUAL && boolAndOr->code() != CPUI_BOOL_OR) continue;
|
||||
int4 slot = boolAndOr->getSlot(outvn);
|
||||
Varnode *othervn = boolAndOr->getIn(1-slot);
|
||||
if (!othervn->isWritten()) continue;
|
||||
PcodeOp *equalLo = othervn->getDef();
|
||||
if (equalLo->code() != eqCode) continue;
|
||||
if (equalLo->getIn(0) == lo1) {
|
||||
lo2 = equalLo->getIn(1);
|
||||
}
|
||||
}
|
||||
else { // We see an XOR
|
||||
hixor = op;
|
||||
xorhislot = hixor->getSlot(hi1);
|
||||
hi2 = hixor->getIn(1-xorhislot);
|
||||
Varnode *vn = op->getOut();
|
||||
list<PcodeOp *>::const_iterator iter,enditer;
|
||||
iter = vn->beginDescend();
|
||||
enditer = vn->endDescend();
|
||||
while(iter != enditer) {
|
||||
orop = *iter;
|
||||
++iter;
|
||||
if (orop->code() != CPUI_INT_OR) continue;
|
||||
orhislot = orop->getSlot(vn);
|
||||
if (fillOutFromOr(data)) {
|
||||
if (!param2.exceedsConstPrecision()) {
|
||||
SplitVarnode::replaceBoolOp(data,equalop,in,param2,equalop->code());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (equalLo->getIn(1) == lo1) {
|
||||
lo2 = equalLo->getIn(0);
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
if (!replace(data)) continue;
|
||||
if (param2.exceedsConstPrecision()) continue;
|
||||
SplitVarnode::replaceBoolOp(data,boolAndOr,in,param2,eqCode);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@ -160,12 +160,8 @@ public:
|
||||
class Equal2Form {
|
||||
SplitVarnode in;
|
||||
Varnode *hi1,*hi2,*lo1,*lo2;
|
||||
PcodeOp *equalop,*orop;
|
||||
PcodeOp *hixor,*loxor;
|
||||
int4 orhislot,xorhislot;
|
||||
PcodeOp *boolAndOr;
|
||||
SplitVarnode param2;
|
||||
bool checkLoForm(void);
|
||||
bool fillOutFromOr(Funcdata &data);
|
||||
bool replace(Funcdata &data);
|
||||
public:
|
||||
bool applyRule(SplitVarnode &i,PcodeOp *op,bool workishi,Funcdata &data);
|
||||
|
@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@ -672,20 +672,33 @@ uintb PcodeOp::getNZMaskLocal(bool cliploop) const
|
||||
case CPUI_INT_MULT:
|
||||
val = getIn(0)->getNZMask();
|
||||
resmask = getIn(1)->getNZMask();
|
||||
sz1 = (size > sizeof(uintb)) ? 8*size-1 : mostsigbit_set(val);
|
||||
if (sz1 == -1)
|
||||
resmask = 0;
|
||||
if (size > sizeof(uintb)) {
|
||||
resmask = fullmask;
|
||||
}
|
||||
else {
|
||||
sz2 = (size > sizeof(uintb)) ? 8*size-1 : mostsigbit_set(resmask);
|
||||
if (sz2 == -1)
|
||||
sz1 = mostsigbit_set(val);
|
||||
sz2 = mostsigbit_set(resmask);
|
||||
if (sz1 == -1 || sz2 == -1) {
|
||||
resmask = 0;
|
||||
}
|
||||
else {
|
||||
if (sz1 + sz2 < 8*size-2)
|
||||
fullmask >>= (8*size-2-sz1-sz2);
|
||||
sz1 = leastsigbit_set(val);
|
||||
sz2 = leastsigbit_set(resmask);
|
||||
resmask = (~((uintb)0))<<(sz1+sz2);
|
||||
resmask &= fullmask;
|
||||
int4 l1 = leastsigbit_set(val);
|
||||
int4 l2 = leastsigbit_set(resmask);
|
||||
sa = l1 + l2;
|
||||
if (sa >= 8*size) {
|
||||
resmask = 0;
|
||||
}
|
||||
else {
|
||||
sz1 = sz1 - l1 + 1;
|
||||
sz2 = sz2 - l2 + 1;
|
||||
int4 total = sz1 + sz2;
|
||||
if (sz1 == 1 || sz2 == 1)
|
||||
total -= 1;
|
||||
resmask = fullmask;
|
||||
if (total < 8 * size)
|
||||
resmask >>= (8*size - total);
|
||||
resmask = (resmask << sa) & fullmask;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -10101,66 +10101,6 @@ Varnode *RulePopcountBoolXor::getBooleanResult(Varnode *vn,int4 bitPos,int4 &con
|
||||
}
|
||||
}
|
||||
|
||||
/// \class RuleOrMultiBool
|
||||
/// \brief Simplify boolean expressions that are combined through INT_OR
|
||||
///
|
||||
/// Convert expressions involving boolean values b1 and b2:
|
||||
/// - `(b1 << 6) | (b2 << 2) != 0 => b1 || b2
|
||||
void RuleOrMultiBool::getOpList(vector<uint4> &oplist) const
|
||||
|
||||
{
|
||||
oplist.push_back(CPUI_INT_OR);
|
||||
}
|
||||
|
||||
int4 RuleOrMultiBool::applyOp(PcodeOp *op,Funcdata &data)
|
||||
|
||||
{
|
||||
Varnode *outVn = op->getOut();
|
||||
list<PcodeOp *>::const_iterator iter;
|
||||
|
||||
if (popcount(outVn->getNZMask()) != 2) return 0;
|
||||
for(iter=outVn->beginDescend();iter!=outVn->endDescend();++iter) {
|
||||
PcodeOp *baseOp = *iter;
|
||||
OpCode opc = baseOp->code();
|
||||
// Result of INT_OR must be compared with zero
|
||||
if (opc != CPUI_INT_EQUAL && opc != CPUI_INT_NOTEQUAL) continue;
|
||||
Varnode *zerovn = baseOp->getIn(1);
|
||||
if (!zerovn->isConstant()) continue;
|
||||
if (zerovn->getOffset() != 0) continue;
|
||||
int4 pos0 = leastsigbit_set(outVn->getNZMask());
|
||||
int4 pos1 = mostsigbit_set(outVn->getNZMask());
|
||||
int4 constRes0,constRes1;
|
||||
Varnode *b1 = RulePopcountBoolXor::getBooleanResult(outVn, pos0, constRes0);
|
||||
if (b1 == (Varnode *)0 && constRes0 != 1) continue;
|
||||
Varnode *b2 = RulePopcountBoolXor::getBooleanResult(outVn, pos1, constRes1);
|
||||
if (b2 == (Varnode *)0 && constRes1 != 1) continue;
|
||||
if (b1 == (Varnode *)0 && b2 == (Varnode *)0) continue;
|
||||
|
||||
if (b1 == (Varnode *)0)
|
||||
b1 = data.newConstant(1, 1);
|
||||
if (b2 == (Varnode *)0)
|
||||
b2 = data.newConstant(1, 1);
|
||||
if (opc == CPUI_INT_EQUAL) {
|
||||
PcodeOp *newOp = data.newOp(2,baseOp->getAddr());
|
||||
Varnode *notIn = data.newUniqueOut(1, newOp);
|
||||
data.opSetOpcode(newOp, CPUI_BOOL_OR);
|
||||
data.opSetInput(newOp, b1, 0);
|
||||
data.opSetInput(newOp, b2, 1);
|
||||
data.opInsertBefore(newOp, baseOp);
|
||||
data.opRemoveInput(baseOp, 1);
|
||||
data.opSetInput(baseOp, notIn, 0);
|
||||
data.opSetOpcode(baseOp, CPUI_BOOL_NEGATE);
|
||||
}
|
||||
else {
|
||||
data.opSetOpcode(baseOp, CPUI_BOOL_OR);
|
||||
data.opSetInput(baseOp, b1, 0);
|
||||
data.opSetInput(baseOp, b2, 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// \brief Return \b true if concatenating with a SUBPIECE of the given Varnode is unusual
|
||||
///
|
||||
/// \param vn is the given Varnode
|
||||
@ -10550,53 +10490,65 @@ int4 RuleFloatSignCleanup::applyOp(PcodeOp *op,Funcdata &data)
|
||||
void RuleOrCompare::getOpList(vector<uint4> &oplist) const
|
||||
|
||||
{
|
||||
oplist.push_back(CPUI_INT_EQUAL);
|
||||
oplist.push_back(CPUI_INT_NOTEQUAL);
|
||||
oplist.push_back(CPUI_INT_OR);
|
||||
}
|
||||
|
||||
int4 RuleOrCompare::applyOp(PcodeOp *op,Funcdata &data)
|
||||
|
||||
{
|
||||
// make sure the comparison is against 0
|
||||
if (! op->getIn(1)->constantMatch(0)) return 0;
|
||||
Varnode *outvn = op->getOut();
|
||||
list<PcodeOp *>::const_iterator iter;
|
||||
bool hasCompares = false;
|
||||
for(iter=outvn->beginDescend();iter!=outvn->endDescend();++iter) {
|
||||
PcodeOp *compOp = *iter;
|
||||
OpCode opc = compOp->code();
|
||||
if (opc != CPUI_INT_EQUAL && opc != CPUI_INT_NOTEQUAL)
|
||||
return 0;
|
||||
if (!compOp->getIn(1)->constantMatch(0))
|
||||
return 0;
|
||||
hasCompares = true;
|
||||
}
|
||||
if (!hasCompares)
|
||||
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);
|
||||
Varnode* V = op->getIn(0);
|
||||
Varnode* W = 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);
|
||||
iter = outvn->beginDescend();
|
||||
while(iter!=outvn->endDescend()) {
|
||||
PcodeOp *equalOp = *iter;
|
||||
OpCode opc = equalOp->code();
|
||||
++iter; // Advance iterator immediately as equalOp gets modified
|
||||
// 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, equalOp->getAddr());
|
||||
data.opSetOpcode(eq_V, opc);
|
||||
data.opSetInput(eq_V, V, 0);
|
||||
data.opSetInput(eq_V, zero_V, 1);
|
||||
PcodeOp* eq_W = data.newOp(2, equalOp->getAddr());
|
||||
data.opSetOpcode(eq_W, opc);
|
||||
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);
|
||||
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);
|
||||
// make sure the comparisons' output is already defined
|
||||
data.opInsertBefore(eq_V, equalOp);
|
||||
data.opInsertBefore(eq_W, equalOp);
|
||||
|
||||
// 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);
|
||||
// change the original INT_EQUAL into a BOOL_AND, and INT_NOTEQUAL becomes BOOL_OR
|
||||
data.opSetOpcode(equalOp, opc == CPUI_INT_EQUAL ? CPUI_BOOL_AND : CPUI_BOOL_OR);
|
||||
data.opSetInput(equalOp, eq_V_out, 0);
|
||||
data.opSetInput(equalOp, eq_W_out, 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1598,17 +1598,6 @@ public:
|
||||
static Varnode *getBooleanResult(Varnode *vn,int4 bitPos,int4 &constRes);
|
||||
};
|
||||
|
||||
class RuleOrMultiBool : public Rule {
|
||||
public:
|
||||
RuleOrMultiBool(const string &g) : Rule( g, 0, "ormultibool") {} ///< Constructor
|
||||
virtual Rule *clone(const ActionGroupList &grouplist) const {
|
||||
if (!grouplist.contains(getGroup())) return (Rule *)0;
|
||||
return new RuleOrMultiBool(getGroup());
|
||||
}
|
||||
virtual void getOpList(vector<uint4> &oplist) const;
|
||||
virtual int4 applyOp(PcodeOp *op,Funcdata &data);
|
||||
};
|
||||
|
||||
class RulePiecePathology : public Rule {
|
||||
static bool isPathology(Varnode *vn,Funcdata &data);
|
||||
static int4 tracePathologyForward(PcodeOp *op,Funcdata &data);
|
||||
|
@ -0,0 +1,29 @@
|
||||
<decompilertest>
|
||||
<binaryimage arch="x86:LE:64:default:gcc">
|
||||
<bytechunk space="ram" offset="0x100000" readonly="true">
|
||||
f30f1efa83ff0a0f94c20fb6d201d283
|
||||
fe140f94c00fb6c0c1e007b901000000
|
||||
09c2740f833dd50f0000000f94c10fb6
|
||||
c901c989c8c3f30f1efa81fec8000000
|
||||
0f94c00fb6c0c1e00283ff640f94c10f
|
||||
b6c909c881fa2c0100000f94c20fb6d2
|
||||
c1e20409d07510833d920f000007ba02
|
||||
0000000f44c2c3b801000000c3
|
||||
</bytechunk>
|
||||
<symbol space="ram" offset="0x100000" name="comp2"/>
|
||||
<symbol space="ram" offset="0x100036" name="comp3"/>
|
||||
</binaryimage>
|
||||
<script>
|
||||
<com>parse line extern int4 comp2(int4 a,int4 b);</com>
|
||||
<com>parse line extern int4 comp3(int4 x,int4 y,int4 z);</com>
|
||||
<com>lo fu comp2</com>
|
||||
<com>dec</com>
|
||||
<com>print C</com>
|
||||
<com>lo fu comp3</com>
|
||||
<com>dec</com>
|
||||
<com>print C</com>
|
||||
<com>quit</com>
|
||||
</script>
|
||||
<stringmatch name="Compare INT_OR #1" min="1" max="1">if \(a == 10 \|\| b == 0x14\)</stringmatch>
|
||||
<stringmatch name="Compare INT_OR #2" min="1" max="1">if \(\(y != 200 && x != 100\) && z != 300\)</stringmatch>
|
||||
</decompilertest>
|
Loading…
Reference in New Issue
Block a user