GP-2311 Added hasNoDescend method to Varnode interface

This commit is contained in:
caheckman 2023-09-06 22:20:06 +00:00
parent c072972153
commit 60b9e00e2c
4 changed files with 78 additions and 26 deletions

View File

@ -1266,7 +1266,7 @@ Datatype *TypeOpIntSub::getOutputToken(const PcodeOp *op,CastStrategy *castStrat
TypeOpIntCarry::TypeOpIntCarry(TypeFactory *t)
: TypeOpFunc(t,CPUI_INT_CARRY,"CARRY",TYPE_BOOL,TYPE_UINT)
{
opflags = PcodeOp::binary;
opflags = PcodeOp::binary | PcodeOp::commutative;
addlflags = arithmetic_op;
behave = new OpBehaviorIntCarry();
}
@ -1282,7 +1282,7 @@ string TypeOpIntCarry::getOperatorName(const PcodeOp *op) const
TypeOpIntScarry::TypeOpIntScarry(TypeFactory *t)
: TypeOpFunc(t,CPUI_INT_SCARRY,"SCARRY",TYPE_BOOL,TYPE_INT)
{
opflags = PcodeOp::binary;
opflags = PcodeOp::binary | PcodeOp::commutative;
behave = new OpBehaviorIntScarry();
}

View File

@ -293,6 +293,15 @@ public class PcodeOp {
return (output != null);
}
/**
* Return true if the PcodeOp is commutative.
* If true, the operation has exactly two inputs that can be switched without affecting the output.
* @return true if the operation is commutative
*/
public final boolean isCommutative() {
return isCommutative(opcode);
}
/**
* @return the sequence number this pcode is within some number of pcode
*/
@ -715,4 +724,33 @@ public class PcodeOp {
}
return i.intValue();
}
/**
* Return true if the given opcode represents a commutative operation.
* If true, the operation has exactly two inputs that can be switched without affecting the output.
* @param opcode is the opcode
* @return true if the operation is commutative
*/
public static boolean isCommutative(int opcode) {
switch (opcode) {
case PcodeOp.INT_EQUAL:
case PcodeOp.INT_NOTEQUAL:
case PcodeOp.INT_ADD:
case PcodeOp.INT_XOR:
case PcodeOp.INT_AND:
case PcodeOp.INT_OR:
case PcodeOp.INT_MULT:
case PcodeOp.BOOL_XOR:
case PcodeOp.BOOL_AND:
case PcodeOp.BOOL_OR:
case PcodeOp.FLOAT_EQUAL:
case PcodeOp.FLOAT_NOTEQUAL:
case PcodeOp.FLOAT_ADD:
case PcodeOp.FLOAT_MULT:
case PcodeOp.INT_CARRY:
case PcodeOp.INT_SCARRY:
return true;
}
return false;
}
}

View File

@ -304,6 +304,13 @@ public class Varnode {
return null;
}
/**
* @return false if the Varnode has a PcodeOp reading it that is part of function data-flow
*/
public boolean hasNoDescend() {
return true;
}
/**
* @return the high level variable this varnode represents
*/

View File

@ -21,9 +21,7 @@
*/
package ghidra.program.model.pcode;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.*;
import ghidra.program.model.address.Address;
@ -93,18 +91,18 @@ public class VarnodeAST extends Varnode {
public Iterator<PcodeOp> getDescendants() {
return descend.iterator();
}
@Override
public PcodeOp getLoneDescend() {
Iterator<PcodeOp> iter = getDescendants();
if (!iter.hasNext()) {
return null; // If there are no descendants return null
if (descend.size() != 1) {
return null;
}
PcodeOp op = iter.next();
if (iter.hasNext()) {
return null; // If there is more than one descendant return null
}
return op;
return descend.peekFirst();
}
@Override
public boolean hasNoDescend() {
return descend.isEmpty();
}
@Override
@ -194,10 +192,11 @@ public class VarnodeAST extends Varnode {
ListIterator<PcodeOp> iter = vn.descend.listIterator();
while (iter.hasNext()) {
PcodeOp op = iter.next();
if (op.getOutput() == this)
if (op.getOutput() == this) {
continue; // Cannot be input to your own definition
}
int num = op.getNumInputs();
for (int i = 0; i < num; ++i)
for (int i = 0; i < num; ++i) {
// Find reference to vn
if (op.getInput(i) == vn) {
vn.removeDescendant(op);
@ -206,6 +205,7 @@ public class VarnodeAST extends Varnode {
op.setInput(this, i);
break;
}
}
}
}
@ -217,28 +217,35 @@ public class VarnodeAST extends Varnode {
@Override
public boolean equals(Object o) {
if (o == this)
if (o == this) {
return true;
if (!(o instanceof VarnodeAST))
}
if (!(o instanceof VarnodeAST)) {
return false;
}
VarnodeAST vn = (VarnodeAST) o;
if (getOffset() != vn.getOffset() || getSize() != vn.getSize() ||
getSpace() != vn.getSpace())
return false;
if (isFree()) {
if (vn.isFree())
return (uniqId == vn.uniqId);
getSpace() != vn.getSpace()) {
return false;
}
else if (vn.isFree())
if (isFree()) {
if (vn.isFree()) {
return (uniqId == vn.uniqId);
}
return false;
if (isInput() != vn.isInput())
}
else if (vn.isFree()) {
return false;
}
if (isInput() != vn.isInput()) {
return false;
}
if (def != null) {
PcodeOp vnDef = vn.getDef();
if (vnDef == null)
if (vnDef == null) {
return false;
}
return (def.getSeqnum().equals(vnDef.getSeqnum()));
}
return true;