mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-10-23 13:41:04 +00:00
GP-2311 Added hasNoDescend method to Varnode interface
This commit is contained in:
parent
c072972153
commit
60b9e00e2c
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user