mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-1647 equivalence check
This commit is contained in:
parent
4830d035b3
commit
4bfade4cd8
23 changed files with 409 additions and 380 deletions
|
@ -86,7 +86,7 @@ public class DecompInterface {
|
|||
// Last warning messages from the decompiler
|
||||
// or other error message
|
||||
protected String decompileMessage;
|
||||
protected BasicCompilerSpec compilerSpec;
|
||||
protected CompilerSpec compilerSpec;
|
||||
protected DecompileProcess decompProcess;
|
||||
protected DecompileCallback decompCallback;
|
||||
private DecompileDebug debug;
|
||||
|
@ -221,7 +221,9 @@ public class DecompInterface {
|
|||
(SleighLanguageDescription) pcodelanguage.getLanguageDescription();
|
||||
ResourceFile pspecfile = sleighdescription.getSpecFile();
|
||||
String pspecxml = fileToString(pspecfile);
|
||||
String cspecxml = compilerSpec.getXMLString();
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
compilerSpec.saveXml(buffer);
|
||||
String cspecxml = buffer.toString();
|
||||
|
||||
decompCallback.setNativeMessage(null);
|
||||
decompProcess.registerProgram(decompCallback, pspecxml, cspecxml, tspec, coretypes);
|
||||
|
@ -313,7 +315,7 @@ public class DecompInterface {
|
|||
"Language has unsupported compiler spec: " + spec.getClass().getName();
|
||||
return false;
|
||||
}
|
||||
compilerSpec = (BasicCompilerSpec) spec;
|
||||
compilerSpec = spec;
|
||||
|
||||
dtmanage = new PcodeDataTypeManager(prog);
|
||||
try {
|
||||
|
|
|
@ -42,4 +42,22 @@ public interface BitFieldPacking {
|
|||
* a zero-length bit-field
|
||||
*/
|
||||
int getZeroLengthBoundary();
|
||||
|
||||
/**
|
||||
* Determine if this BitFieldPacking is equivalent to another specified instance
|
||||
* @param obj is the other instance
|
||||
* @return true if they are equivalent
|
||||
*/
|
||||
public default boolean isEquivalent(BitFieldPacking obj) {
|
||||
if (isTypeAlignmentEnabled() != obj.isTypeAlignmentEnabled()) {
|
||||
return false;
|
||||
}
|
||||
if (useMSConvention() != obj.useMSConvention()) {
|
||||
return false;
|
||||
}
|
||||
if (getZeroLengthBoundary() != obj.getZeroLengthBoundary()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,24 +118,4 @@ public class BitFieldPackingImpl implements BitFieldPacking {
|
|||
}
|
||||
parser.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
BitFieldPackingImpl op2 = (BitFieldPackingImpl) obj;
|
||||
if (typeAlignmentEnabled != op2.typeAlignmentEnabled) {
|
||||
return false;
|
||||
}
|
||||
if (useMSConvention != op2.useMSConvention) {
|
||||
return false;
|
||||
}
|
||||
if (zeroLengthBoundary != op2.zeroLengthBoundary) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (typeAlignmentEnabled ? 1 : 13) + (useMSConvention ? 5 : 27) + zeroLengthBoundary;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,4 +172,69 @@ public interface DataOrganization {
|
|||
// * @return the aligned offset for the data type
|
||||
// */
|
||||
// int getAlignmentOffset(int minimumOffset, DataType dataType, int dtSize);
|
||||
|
||||
/**
|
||||
* Determine if this DataOrganization is equivalent to another specific instance
|
||||
* @param obj is the other instance
|
||||
* @return true if they are equivalent
|
||||
*/
|
||||
public default boolean isEquivalent(DataOrganization obj) {
|
||||
if (getAbsoluteMaxAlignment() != obj.getAbsoluteMaxAlignment()) {
|
||||
return false;
|
||||
}
|
||||
if (isBigEndian() != obj.isBigEndian()) {
|
||||
return false;
|
||||
}
|
||||
if (!getBitFieldPacking().isEquivalent(obj.getBitFieldPacking())) {
|
||||
return false;
|
||||
}
|
||||
if (getCharSize() != obj.getCharSize() || getWideCharSize() != obj.getWideCharSize()) {
|
||||
return false;
|
||||
}
|
||||
if (getDefaultAlignment() != obj.getDefaultAlignment()) {
|
||||
return false;
|
||||
}
|
||||
if (getDefaultPointerAlignment() != obj.getDefaultPointerAlignment()) {
|
||||
return false;
|
||||
}
|
||||
if (getDoubleSize() != obj.getDoubleSize() || getFloatSize() != obj.getFloatSize()) {
|
||||
return false;
|
||||
}
|
||||
if (getIntegerSize() != obj.getIntegerSize() ||
|
||||
getLongLongSize() != obj.getLongLongSize()) {
|
||||
return false;
|
||||
}
|
||||
if (getShortSize() != obj.getShortSize()) {
|
||||
return false;
|
||||
}
|
||||
if (getLongSize() != obj.getLongSize() || getLongDoubleSize() != obj.getLongDoubleSize()) {
|
||||
return false;
|
||||
}
|
||||
if (isSignedChar() != obj.isSignedChar()) {
|
||||
return false;
|
||||
}
|
||||
if (getMachineAlignment() != obj.getMachineAlignment()) {
|
||||
return false;
|
||||
}
|
||||
if (getPointerSize() != obj.getPointerSize() ||
|
||||
getPointerShift() != obj.getPointerShift()) {
|
||||
return false;
|
||||
}
|
||||
int[] keys = getSizes();
|
||||
int[] op2keys = obj.getSizes();
|
||||
if (keys.length != op2keys.length) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
for (int k : keys) {
|
||||
if (getSizeAlignment(k) != obj.getSizeAlignment(k)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NoValueException ex) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ package ghidra.program.model.data;
|
|||
import java.util.*;
|
||||
|
||||
import ghidra.program.model.lang.Language;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.xml.SpecXmlUtils;
|
||||
import ghidra.xml.XmlElement;
|
||||
|
@ -736,85 +735,4 @@ public class DataOrganizationImpl implements DataOrganization {
|
|||
parser.end();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
DataOrganizationImpl op2 = (DataOrganizationImpl) obj;
|
||||
if (absoluteMaxAlignment != op2.absoluteMaxAlignment) {
|
||||
return false;
|
||||
}
|
||||
if (bigEndian != op2.bigEndian) {
|
||||
return false;
|
||||
}
|
||||
if (!bitFieldPacking.equals(op2.bitFieldPacking)) {
|
||||
return false;
|
||||
}
|
||||
if (charSize != op2.charSize || wideCharSize != op2.wideCharSize) {
|
||||
return false;
|
||||
}
|
||||
if (defaultAlignment != op2.defaultAlignment) {
|
||||
return false;
|
||||
}
|
||||
if (defaultPointerAlignment != op2.defaultPointerAlignment) {
|
||||
return false;
|
||||
}
|
||||
if (doubleSize != op2.doubleSize || floatSize != op2.floatSize) {
|
||||
return false;
|
||||
}
|
||||
if (integerSize != op2.integerSize || longLongSize != op2.longLongSize) {
|
||||
return false;
|
||||
}
|
||||
if (shortSize != op2.shortSize) {
|
||||
return false;
|
||||
}
|
||||
if (longSize != op2.longSize || longDoubleSize != op2.longDoubleSize) {
|
||||
return false;
|
||||
}
|
||||
if (isSignedChar != op2.isSignedChar) {
|
||||
return false;
|
||||
}
|
||||
if (machineAlignment != op2.machineAlignment) {
|
||||
return false;
|
||||
}
|
||||
if (pointerSize != op2.pointerSize || pointerShift != op2.pointerShift) {
|
||||
return false;
|
||||
}
|
||||
Set<Integer> keys = sizeAlignmentMap.keySet();
|
||||
Set<Integer> op2keys = op2.sizeAlignmentMap.keySet();
|
||||
if (keys.size() != op2keys.size()) {
|
||||
return false;
|
||||
}
|
||||
for (int k : keys) {
|
||||
if (!SystemUtilities.isEqual(sizeAlignmentMap.get(k), op2.sizeAlignmentMap.get(k))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = bitFieldPacking.hashCode();
|
||||
hash = 79 * hash + absoluteMaxAlignment;
|
||||
hash = 79 * hash + (bigEndian ? 27 : 13);
|
||||
hash = 79 * hash + charSize;
|
||||
hash = 79 * hash + defaultAlignment;
|
||||
hash = 79 * hash + defaultPointerAlignment;
|
||||
hash = 79 * hash + doubleSize;
|
||||
hash = 79 * hash + floatSize;
|
||||
hash = 79 * hash + integerSize;
|
||||
hash = 79 * hash + (isSignedChar ? 1 : 3);
|
||||
hash = 79 * hash + longDoubleSize;
|
||||
hash = 79 * hash + longLongSize;
|
||||
hash = 79 * hash + longSize;
|
||||
hash = 79 * hash + machineAlignment;
|
||||
hash = 79 * hash + pointerShift;
|
||||
hash = 79 * hash + pointerSize;
|
||||
hash = 79 * hash + shortSize;
|
||||
hash = 79 * hash + wideCharSize;
|
||||
for (int k : sizeAlignmentMap.keySet()) {
|
||||
hash = 79 * hash + sizeAlignmentMap.get(k);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -302,16 +302,6 @@ public class BasicCompilerSpec implements CompilerSpec {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to marshal this entire object, via saveXml, into a String object.
|
||||
* @return a String containing this entire spec as an XML document.
|
||||
*/
|
||||
public String getXMLString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
saveXml(buffer);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyContextSettings(DefaultProgramContext programContext) {
|
||||
for (ContextSetting cs : ctxsetting) {
|
||||
|
@ -512,11 +502,7 @@ public class BasicCompilerSpec implements CompilerSpec {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marshal this entire specification to an XML stream. An XML document is written with
|
||||
* root tag \<compiler_spec>.
|
||||
* @param buffer is the XML stream
|
||||
*/
|
||||
@Override
|
||||
public void saveXml(StringBuilder buffer) {
|
||||
buffer.append("<compiler_spec>\n");
|
||||
saveProperties(buffer);
|
||||
|
@ -1125,111 +1111,114 @@ public class BasicCompilerSpec implements CompilerSpec {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
BasicCompilerSpec op2 = (BasicCompilerSpec) obj;
|
||||
if (aggressiveTrim != op2.aggressiveTrim || copiedThisModel != op2.copiedThisModel) {
|
||||
public boolean isEquivalent(CompilerSpec obj) {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
if (!dataOrganization.equals(op2.dataOrganization)) {
|
||||
BasicCompilerSpec other = (BasicCompilerSpec) obj;
|
||||
if (aggressiveTrim != other.aggressiveTrim || copiedThisModel != other.copiedThisModel) {
|
||||
return false;
|
||||
}
|
||||
if (!ctxsetting.equals(op2.ctxsetting)) {
|
||||
if (!dataOrganization.isEquivalent(other.dataOrganization)) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isEqual(deadCodeDelay, op2.deadCodeDelay)) {
|
||||
if (ctxsetting.size() != other.ctxsetting.size()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < ctxsetting.size(); ++i) {
|
||||
if (!ctxsetting.get(i).isEquivalent(other.ctxsetting.get(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!SystemUtilities.isEqual(deadCodeDelay, other.deadCodeDelay)) {
|
||||
return false;
|
||||
}
|
||||
if (defaultModel != null) {
|
||||
if (op2.defaultModel == null) {
|
||||
if (other.defaultModel == null) {
|
||||
return false;
|
||||
}
|
||||
if (!defaultModel.name.equals(op2.defaultModel.name)) {
|
||||
if (!defaultModel.name.equals(other.defaultModel.name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (op2.defaultModel != null) {
|
||||
else if (other.defaultModel != null) {
|
||||
return false;
|
||||
}
|
||||
if (evalCalledModel != null) {
|
||||
if (op2.evalCalledModel == null) {
|
||||
if (other.evalCalledModel == null) {
|
||||
return false;
|
||||
}
|
||||
if (!evalCalledModel.name.equals(op2.evalCalledModel.name)) {
|
||||
if (!evalCalledModel.name.equals(other.evalCalledModel.name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (op2.evalCalledModel != null) {
|
||||
else if (other.evalCalledModel != null) {
|
||||
return false;
|
||||
}
|
||||
if (evalCurrentModel != null) {
|
||||
if (op2.evalCurrentModel == null) {
|
||||
if (other.evalCurrentModel == null) {
|
||||
return false;
|
||||
}
|
||||
if (!evalCurrentModel.name.equals(op2.evalCurrentModel.name)) {
|
||||
if (!evalCurrentModel.name.equals(other.evalCurrentModel.name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (op2.evalCurrentModel != null) {
|
||||
else if (other.evalCurrentModel != null) {
|
||||
return false;
|
||||
}
|
||||
if (allmodels.length != op2.allmodels.length) {
|
||||
if (allmodels.length != other.allmodels.length) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isArrayEqual(allmodels, op2.allmodels)) {
|
||||
for (int i = 0; i < allmodels.length; ++i) {
|
||||
if (!allmodels[i].isEquivalent(other.allmodels[i])) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isEqual(extraRanges, op2.extraRanges)) {
|
||||
}
|
||||
if (!SystemUtilities.isEqual(extraRanges, other.extraRanges)) {
|
||||
return false;
|
||||
}
|
||||
if (funcPtrAlign != op2.funcPtrAlign) {
|
||||
if (funcPtrAlign != other.funcPtrAlign) {
|
||||
return false;
|
||||
}
|
||||
if (!globalSet.equals(op2.globalSet)) {
|
||||
if (!globalSet.equals(other.globalSet)) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isEqual(inferPtrBounds, op2.inferPtrBounds)) {
|
||||
if (!SystemUtilities.isEqual(inferPtrBounds, other.inferPtrBounds)) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isEqual(noHighPtr, op2.noHighPtr)) {
|
||||
if (!SystemUtilities.isEqual(noHighPtr, other.noHighPtr)) {
|
||||
return false;
|
||||
}
|
||||
if (!pcodeInject.equals(op2.pcodeInject)) {
|
||||
if (!pcodeInject.isEquivalent(other.pcodeInject)) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isEqual(preferSplit, op2.preferSplit)) {
|
||||
if (!SystemUtilities.isEqual(preferSplit, other.preferSplit)) {
|
||||
return false;
|
||||
}
|
||||
if (!properties.equals(op2.properties)) {
|
||||
if (!properties.equals(other.properties)) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isEqual(readOnlySet, op2.readOnlySet)) {
|
||||
if (!SystemUtilities.isEqual(readOnlySet, other.readOnlySet)) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isEqual(returnAddress, op2.returnAddress)) {
|
||||
if (!SystemUtilities.isEqual(returnAddress, other.returnAddress)) {
|
||||
return false;
|
||||
}
|
||||
if (reverseJustifyStack != op2.reverseJustifyStack) {
|
||||
if (reverseJustifyStack != other.reverseJustifyStack) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isEqual(spaceBases, op2.spaceBases)) {
|
||||
if (!SystemUtilities.isEqual(spaceBases, other.spaceBases)) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isEqual(stackBaseSpace, op2.stackBaseSpace)) {
|
||||
if (!SystemUtilities.isEqual(stackBaseSpace, other.stackBaseSpace)) {
|
||||
return false;
|
||||
}
|
||||
if (stackGrowsNegative != op2.stackGrowsNegative) {
|
||||
if (stackGrowsNegative != other.stackGrowsNegative) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isEqual(stackPointer, op2.stackPointer)) {
|
||||
if (!SystemUtilities.isEqual(stackPointer, other.stackPointer)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = language.getLanguageID().hashCode();
|
||||
hash = 79 * description.getCompilerSpecID().hashCode() + hash;
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -237,4 +237,18 @@ public interface CompilerSpec {
|
|||
* @return read-only set of property keys
|
||||
*/
|
||||
public Set<String> getPropertyKeys();
|
||||
|
||||
/**
|
||||
* Marshal this entire specification to an XML stream. An XML document is written with
|
||||
* root tag \<compiler_spec>.
|
||||
* @param buffer is the XML stream
|
||||
*/
|
||||
public void saveXml(StringBuilder buffer);
|
||||
|
||||
/**
|
||||
* Determine if this CompilerSpec is equivalent to another specified instance
|
||||
* @param obj is the other instance
|
||||
* @return true if they are equivalent
|
||||
*/
|
||||
public boolean isEquivalent(CompilerSpec obj);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ import ghidra.xml.*;
|
|||
* Class for context configuration information as
|
||||
* part of the compiler configuration (CompilerSpec)
|
||||
*/
|
||||
public class ContextSetting {
|
||||
public final class ContextSetting {
|
||||
private Register register; // Register being set in default context
|
||||
private BigInteger value; // value being set in default context
|
||||
private Address startAddr; // Beginning address of context
|
||||
|
@ -108,33 +108,27 @@ public class ContextSetting {
|
|||
buffer.append("/>\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
ContextSetting op2 = (ContextSetting) obj;
|
||||
if (!startAddr.equals(op2.startAddr)) {
|
||||
/**
|
||||
* Determine if this ContextSetting is equivalent to another specified instance
|
||||
* @param obj is the other instance
|
||||
* @return true if they are equivalent
|
||||
*/
|
||||
public boolean isEquivalent(ContextSetting obj) {
|
||||
if (!startAddr.equals(obj.startAddr)) {
|
||||
return false;
|
||||
}
|
||||
if (!endAddr.equals(op2.endAddr)) {
|
||||
if (!endAddr.equals(obj.endAddr)) {
|
||||
return false;
|
||||
}
|
||||
if (!register.equals(op2.register)) {
|
||||
if (!register.equals(obj.register)) {
|
||||
return false;
|
||||
}
|
||||
if (!value.equals(op2.value)) {
|
||||
if (!value.equals(obj.value)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = startAddr.hashCode();
|
||||
hash = 79 * hash + endAddr.hashCode();
|
||||
hash = 79 * hash + register.hashCode();
|
||||
hash = 79 * hash + value.hashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
public static void parseContextSet(List<ContextSetting> resList, XmlPullParser parser,
|
||||
CompilerSpec cspec) throws XmlParseException {
|
||||
XmlElement el = parser.start();
|
||||
|
|
|
@ -62,25 +62,20 @@ public interface InjectPayload {
|
|||
index = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
InjectParameter op2 = (InjectParameter) obj;
|
||||
if (index != op2.index || size != op2.size) {
|
||||
/**
|
||||
* Determine if this InjectParameter and another instance are equivalent
|
||||
* @param obj is the other instance
|
||||
* @return true if they are equivalent
|
||||
*/
|
||||
public boolean isEquivalent(InjectParameter obj) {
|
||||
if (!name.equals(obj.name)) {
|
||||
return false;
|
||||
}
|
||||
if (!name.equals(op2.name)) {
|
||||
if (index != obj.index || size != obj.size) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = name.hashCode();
|
||||
hash = 79 * hash + index;
|
||||
hash = 79 * hash + size;
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,4 +155,12 @@ public interface InjectPayload {
|
|||
* @throws XmlParseException for badly formed XML
|
||||
*/
|
||||
public void restoreXml(XmlPullParser parser, SleighLanguage language) throws XmlParseException;
|
||||
|
||||
/**
|
||||
* Determine if this InjectPayload and another instance are equivalent
|
||||
* (have the same name and generate the same p-code)
|
||||
* @param obj is the other payload
|
||||
* @return true if they are equivalent
|
||||
*/
|
||||
public boolean isEquivalent(InjectPayload obj);
|
||||
}
|
||||
|
|
|
@ -102,21 +102,14 @@ public class InjectPayloadCallfixup extends InjectPayloadSleigh {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean isEquivalent(InjectPayload obj) {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
InjectPayloadCallfixup op2 = (InjectPayloadCallfixup) obj;
|
||||
if (!targetSymbolNames.equals(op2.targetSymbolNames)) {
|
||||
return false;
|
||||
}
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 13;
|
||||
for (String target : targetSymbolNames) {
|
||||
hash = 79 * hash + target.hashCode();
|
||||
}
|
||||
hash = 79 * hash + super.hashCode();
|
||||
return hash;
|
||||
return super.isEquivalent(obj);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,4 +45,16 @@ public class InjectPayloadJumpAssist extends InjectPayloadSleigh {
|
|||
}
|
||||
super.restoreXml(parser, language);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEquivalent(InjectPayload obj) {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
InjectPayloadJumpAssist op2 = (InjectPayloadJumpAssist) obj;
|
||||
if (!baseName.equals(op2.baseName)) {
|
||||
return false;
|
||||
}
|
||||
return super.isEquivalent(obj);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,7 +103,10 @@ public class InjectPayloadSegment extends InjectPayloadSleigh {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean isEquivalent(InjectPayload obj) {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
InjectPayloadSegment op2 = (InjectPayloadSegment) obj;
|
||||
if (constResolveOffset != op2.constResolveOffset) {
|
||||
return false;
|
||||
|
@ -120,18 +123,6 @@ public class InjectPayloadSegment extends InjectPayloadSleigh {
|
|||
if (supportsFarPointer != op2.supportsFarPointer) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = space.hashCode();
|
||||
if (constResolveSpace != null) {
|
||||
hash = 79 * hash + constResolveSpace.hashCode();
|
||||
}
|
||||
hash = 79 * hash + Long.hashCode(constResolveOffset);
|
||||
hash = 79 * hash + constResolveSize;
|
||||
hash = 79 * hash + (supportsFarPointer ? 1 : 13);
|
||||
return hash;
|
||||
return super.isEquivalent(obj);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import ghidra.program.model.listing.Program;
|
|||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.pcode.PcodeOp;
|
||||
import ghidra.program.model.pcode.Varnode;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import ghidra.util.xml.SpecXmlUtils;
|
||||
import ghidra.xml.*;
|
||||
|
||||
|
@ -395,17 +394,30 @@ public class InjectPayloadSleigh implements InjectPayload {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean isEquivalent(InjectPayload obj) {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
InjectPayloadSleigh op2 = (InjectPayloadSleigh) obj;
|
||||
if (!name.equals(op2.name)) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isArrayEqual(inputlist, op2.inputlist)) {
|
||||
if (inputlist.length != op2.inputlist.length) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isArrayEqual(output, op2.output)) {
|
||||
for (int i = 0; i < inputlist.length; ++i) {
|
||||
if (!inputlist[i].isEquivalent(op2.inputlist[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (output.length != op2.output.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < output.length; ++i) {
|
||||
if (!output[i].isEquivalent(op2.output[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (incidentalCopy != op2.incidentalCopy) {
|
||||
return false;
|
||||
}
|
||||
|
@ -423,22 +435,6 @@ public class InjectPayloadSleigh implements InjectPayload {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = (incidentalCopy ? 1 : 13);
|
||||
hash = 79 * hash + name.hashCode();
|
||||
hash = 79 * hash + type;
|
||||
hash = 79 * hash + subType;
|
||||
hash = 79 * hash + paramShift;
|
||||
for (InjectParameter param : inputlist) {
|
||||
hash = 79 * hash + param.hashCode();
|
||||
}
|
||||
for (InjectParameter param : output) {
|
||||
hash = 79 * hash + param.hashCode();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a dummy p-code sequence to use in place of a normal parsed payload.
|
||||
* A ConstructTpl is built out of Varnode and PcodeOp templates that can
|
||||
|
|
|
@ -494,50 +494,33 @@ public class ParamEntry {
|
|||
parser.end(el);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
ParamEntry op2 = (ParamEntry) obj;
|
||||
if (!spaceid.equals(op2.spaceid) || addressbase != op2.addressbase) {
|
||||
/**
|
||||
* Determine if this ParamEntry is equivalent to another instance
|
||||
* @param obj is the other instance
|
||||
* @return true if they are equivalent
|
||||
*/
|
||||
public boolean isEquivalent(ParamEntry obj) {
|
||||
if (!spaceid.equals(obj.spaceid) || addressbase != obj.addressbase) {
|
||||
return false;
|
||||
}
|
||||
if (size != op2.size || minsize != op2.minsize || alignment != op2.alignment) {
|
||||
if (size != obj.size || minsize != obj.minsize || alignment != obj.alignment) {
|
||||
return false;
|
||||
}
|
||||
if (type != op2.type || flags != op2.flags) {
|
||||
if (type != obj.type || flags != obj.flags) {
|
||||
return false;
|
||||
}
|
||||
if (numslots != op2.numslots) {
|
||||
if (numslots != obj.numslots) {
|
||||
return false;
|
||||
}
|
||||
if (group != op2.group || groupsize != op2.groupsize) {
|
||||
if (group != obj.group || groupsize != obj.groupsize) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isArrayEqual(joinrec, op2.joinrec)) {
|
||||
if (!SystemUtilities.isArrayEqual(joinrec, obj.joinrec)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = spaceid.hashCode();
|
||||
hash = 79 * hash + Long.hashCode(addressbase);
|
||||
hash = 79 * hash + alignment;
|
||||
hash = 79 * hash + flags;
|
||||
hash = 79 * hash + group;
|
||||
hash = 79 * hash + groupsize;
|
||||
hash = 79 * hash + minsize;
|
||||
hash = 79 * hash + numslots;
|
||||
hash = 79 * hash + size;
|
||||
hash = 79 * hash + type;
|
||||
if (joinrec != null) {
|
||||
for (Varnode vn : joinrec) {
|
||||
hash = 79 * hash + vn.hashCode();
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsigned less-than operation
|
||||
* @param a is the first operand
|
||||
|
|
|
@ -79,4 +79,11 @@ public interface ParamList {
|
|||
public boolean possibleParamWithSlot(Address loc, int size, WithSlotRec res);
|
||||
|
||||
public boolean isThisBeforeRetPointer();
|
||||
|
||||
/**
|
||||
* Determine if this ParmList is equivalent to another instance
|
||||
* @param obj is the other instance
|
||||
* @return true if they are equivalent
|
||||
*/
|
||||
public boolean isEquivalent(ParamList obj);
|
||||
}
|
||||
|
|
|
@ -381,11 +381,19 @@ public class ParamListStandard implements ParamList {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
ParamListStandard op2 = (ParamListStandard) obj;
|
||||
if (!SystemUtilities.isArrayEqual(entry, op2.entry)) {
|
||||
public boolean isEquivalent(ParamList obj) {
|
||||
if (this.getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ParamListStandard op2 = (ParamListStandard) obj;
|
||||
if (entry.length != op2.entry.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < entry.length; ++i) {
|
||||
if (!entry[i].isEquivalent(op2.entry[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (numgroup != op2.numgroup || pointermax != op2.pointermax) {
|
||||
return false;
|
||||
}
|
||||
|
@ -398,20 +406,6 @@ public class ParamListStandard implements ParamList {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = numgroup;
|
||||
hash = 79 * hash + pointermax;
|
||||
hash = 79 * hash + (thisbeforeret ? 27 : 19);
|
||||
for (ParamEntry param : entry) {
|
||||
hash = 79 * hash + param.hashCode();
|
||||
}
|
||||
if (spacebase == null) {
|
||||
hash = 79 * hash + spacebase.hashCode();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isThisBeforeRetPointer() {
|
||||
return thisbeforeret;
|
||||
|
|
|
@ -25,7 +25,6 @@ import ghidra.program.model.lang.InjectPayload.InjectParameter;
|
|||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.sleigh.grammar.Location;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import ghidra.xml.XmlParseException;
|
||||
import ghidra.xml.XmlPullParser;
|
||||
|
||||
|
@ -423,59 +422,93 @@ public class PcodeInjectLibrary {
|
|||
return uniqueBase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
PcodeInjectLibrary op2 = (PcodeInjectLibrary) obj;
|
||||
/**
|
||||
* Compare that this and the other library contain all equivalent payloads
|
||||
* @param obj is the other library
|
||||
* @return true if all payloads are equivalent
|
||||
*/
|
||||
public boolean isEquivalent(PcodeInjectLibrary obj) {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
// Cannot compare uniqueBase as one side may not have parsed p-code
|
||||
// if (uniqueBase != op2.uniqueBase) {
|
||||
// return false;
|
||||
// }
|
||||
if (!callFixupMap.equals(op2.callFixupMap)) {
|
||||
if (callFixupMap.size() != obj.callFixupMap.size()) {
|
||||
return false;
|
||||
}
|
||||
if (!callMechFixupMap.equals(op2.callMechFixupMap)) {
|
||||
for (Entry<String, InjectPayload> entry : callFixupMap.entrySet()) {
|
||||
InjectPayload op2payload = obj.callFixupMap.get(entry.getKey());
|
||||
if (!entry.getValue().isEquivalent(op2payload)) {
|
||||
return false;
|
||||
}
|
||||
if (!callOtherFixupMap.equals(op2.callOtherFixupMap)) {
|
||||
}
|
||||
if (callMechFixupMap.size() != obj.callMechFixupMap.size()) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isArrayEqual(callOtherOverride, op2.callOtherOverride)) {
|
||||
for (Entry<String, InjectPayload> entry : callMechFixupMap.entrySet()) {
|
||||
InjectPayload op2payload = obj.callMechFixupMap.get(entry.getKey());
|
||||
if (!entry.getValue().isEquivalent(op2payload)) {
|
||||
return false;
|
||||
}
|
||||
if (!exePcodeMap.equals(op2.exePcodeMap)) {
|
||||
}
|
||||
if (callOtherFixupMap.size() != obj.callOtherFixupMap.size()) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isArrayEqual(programPayload, op2.programPayload)) {
|
||||
for (Entry<String, InjectPayload> entry : callOtherFixupMap.entrySet()) {
|
||||
InjectPayload op2payload = obj.callOtherFixupMap.get(entry.getKey());
|
||||
if (entry.getValue() != null && op2payload != null) {
|
||||
if (!entry.getValue().isEquivalent(op2payload)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (entry.getValue() != null || op2payload != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (callOtherOverride != null && obj.callOtherOverride != null) {
|
||||
if (callOtherOverride.length != obj.callOtherOverride.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < callOtherOverride.length; ++i) {
|
||||
if (!callOtherOverride[i].isEquivalent(obj.callOtherOverride[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (callOtherOverride == null && obj.callOtherOverride == null) {
|
||||
// continue
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (exePcodeMap.size() != obj.exePcodeMap.size()) {
|
||||
return false;
|
||||
}
|
||||
for (Entry<String, InjectPayload> entry : exePcodeMap.entrySet()) {
|
||||
InjectPayload op2payload = obj.exePcodeMap.get(entry.getKey());
|
||||
if (!entry.getValue().isEquivalent(op2payload)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (programPayload != null && obj.programPayload != null) {
|
||||
if (programPayload.length != obj.programPayload.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < programPayload.length; ++i) {
|
||||
if (!programPayload[i].isEquivalent(obj.programPayload[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (programPayload == null && obj.programPayload == null) {
|
||||
// continue
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 111;
|
||||
for (InjectPayload payload : callFixupMap.values()) {
|
||||
hash = 79 * hash + payload.hashCode();
|
||||
}
|
||||
for (InjectPayload payload : callMechFixupMap.values()) {
|
||||
hash = 79 * hash + payload.hashCode();
|
||||
}
|
||||
for (InjectPayload payload : callOtherFixupMap.values()) {
|
||||
hash = 79 * hash + payload.hashCode();
|
||||
}
|
||||
for (InjectPayload payload : exePcodeMap.values()) {
|
||||
hash = 79 * hash + payload.hashCode();
|
||||
}
|
||||
if (programPayload != null) {
|
||||
for (InjectPayloadSleigh payload : programPayload) {
|
||||
hash = 79 * hash + payload.hashCode();
|
||||
}
|
||||
}
|
||||
if (callOtherOverride != null) {
|
||||
for (InjectPayload payload : callOtherOverride) {
|
||||
hash = 79 * hash + payload.hashCode();
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -617,59 +617,60 @@ public class PrototypeModel {
|
|||
return inputParams.getPotentialRegisterStorage(prog);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
PrototypeModel op2 = (PrototypeModel) obj;
|
||||
if (!name.equals(op2.name)) {
|
||||
/**
|
||||
* Determine if this PrototypeModel is equivalent to another instance
|
||||
* @param obj is the other instance
|
||||
* @return true if they are equivalent
|
||||
*/
|
||||
public boolean isEquivalent(PrototypeModel obj) {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
if (extrapop != op2.extrapop || stackshift != op2.stackshift) {
|
||||
if (!name.equals(obj.name)) {
|
||||
return false;
|
||||
}
|
||||
if (genericCallingConvention != op2.genericCallingConvention) {
|
||||
if (extrapop != obj.extrapop || stackshift != obj.stackshift) {
|
||||
return false;
|
||||
}
|
||||
if (hasThis != op2.hasThis || isConstruct != op2.isConstruct) {
|
||||
if (genericCallingConvention != obj.genericCallingConvention) {
|
||||
return false;
|
||||
}
|
||||
if (hasUponEntry != op2.hasUponEntry || hasUponReturn != op2.hasUponReturn) {
|
||||
if (hasThis != obj.hasThis || isConstruct != obj.isConstruct) {
|
||||
return false;
|
||||
}
|
||||
if (inputListType != op2.inputListType) {
|
||||
if (hasUponEntry != obj.hasUponEntry || hasUponReturn != obj.hasUponReturn) {
|
||||
return false;
|
||||
}
|
||||
if (!inputParams.equals(op2.inputParams)) {
|
||||
if (inputListType != obj.inputListType) {
|
||||
return false;
|
||||
}
|
||||
if (!outputParams.equals(op2.outputParams)) {
|
||||
if (!inputParams.isEquivalent(obj.inputParams)) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isArrayEqual(unaffected, op2.unaffected)) {
|
||||
if (!outputParams.isEquivalent(obj.outputParams)) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isArrayEqual(killedbycall, op2.killedbycall)) {
|
||||
if (!SystemUtilities.isArrayEqual(unaffected, obj.unaffected)) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isArrayEqual(likelytrash, op2.likelytrash)) {
|
||||
if (!SystemUtilities.isArrayEqual(killedbycall, obj.killedbycall)) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isEqual(localRange, op2.localRange)) {
|
||||
if (!SystemUtilities.isArrayEqual(likelytrash, obj.likelytrash)) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isEqual(paramRange, op2.paramRange)) {
|
||||
if (!SystemUtilities.isEqual(localRange, obj.localRange)) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isArrayEqual(returnaddress, op2.returnaddress)) {
|
||||
if (!SystemUtilities.isEqual(paramRange, obj.paramRange)) {
|
||||
return false;
|
||||
}
|
||||
if (!SystemUtilities.isArrayEqual(returnaddress, obj.returnaddress)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName();
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.util.*;
|
|||
import ghidra.app.plugin.processors.sleigh.SleighException;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Parameter;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import ghidra.util.xml.SpecXmlUtils;
|
||||
import ghidra.xml.*;
|
||||
|
||||
|
@ -215,20 +214,19 @@ public class PrototypeModelMerged extends PrototypeModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
PrototypeModelMerged op2 = (PrototypeModelMerged) obj;
|
||||
if (!name.equals(op2.name)) {
|
||||
public boolean isEquivalent(PrototypeModel obj) {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
return SystemUtilities.isArrayEqual(modellist, op2.modellist);
|
||||
PrototypeModelMerged op2 = (PrototypeModelMerged) obj;
|
||||
if (modellist.length != op2.modellist.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = name.hashCode();
|
||||
for (PrototypeModel model : modellist) {
|
||||
hash = 79 * hash + model.hashCode();
|
||||
}
|
||||
return hash;
|
||||
for (int i = 0; i < modellist.length; ++i) {
|
||||
if (!modellist[i].getName().equals(op2.modellist[i].getName())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -679,4 +679,14 @@ class TemporaryCompilerSpec implements CompilerSpec {
|
|||
public PcodeInjectLibrary getPcodeInjectLibrary() {
|
||||
return newCompilerSpec.getPcodeInjectLibrary();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveXml(StringBuilder buffer) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEquivalent(CompilerSpec obj) {
|
||||
return (this == obj);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -201,12 +201,17 @@ public class InjectPayloadDexParameters implements InjectPayload {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return (obj instanceof InjectPayloadDexParameters); // All instances are equal
|
||||
public boolean isEquivalent(InjectPayload obj) {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 123474219; // All instances are equal
|
||||
InjectPayloadDexParameters op2 = (InjectPayloadDexParameters) obj;
|
||||
if (!name.equals(op2.name)) {
|
||||
return false;
|
||||
}
|
||||
if (!sourceName.equals(op2.sourceName)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import ghidra.app.plugin.processors.sleigh.SleighLanguage;
|
|||
import ghidra.javaclass.format.ClassFileAnalysisState;
|
||||
import ghidra.javaclass.format.ClassFileJava;
|
||||
import ghidra.javaclass.format.constantpool.AbstractConstantPoolInfoJava;
|
||||
import ghidra.program.model.lang.InjectPayload;
|
||||
import ghidra.program.model.lang.InjectPayloadCallother;
|
||||
import ghidra.program.model.listing.Program;
|
||||
|
||||
|
@ -51,4 +52,16 @@ public abstract class InjectPayloadJava extends InjectPayloadCallother {
|
|||
ClassFileJava classFile = analysisState.getClassFile();
|
||||
return classFile.getConstantPool();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEquivalent(InjectPayload obj) {
|
||||
if (this.getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
InjectPayloadJava op2 = (InjectPayloadJava) obj;
|
||||
if (uniqueBase != op2.uniqueBase) {
|
||||
return false;
|
||||
}
|
||||
return super.isEquivalent(obj);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,6 +110,15 @@ public class InjectPayloadJavaParameters implements InjectPayload {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveXml(StringBuilder buffer) {
|
||||
// Provide a minimal tag so decompiler can call-back
|
||||
buffer.append("<pcode");
|
||||
SpecXmlUtils.encodeStringAttribute(buffer, "inject", "uponentry");
|
||||
SpecXmlUtils.encodeBooleanAttribute(buffer, "dynamic", true);
|
||||
buffer.append("/>\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject(InjectContext context, PcodeEmit emit) {
|
||||
//not used
|
||||
|
@ -203,15 +212,6 @@ public class InjectPayloadJavaParameters implements InjectPayload {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveXml(StringBuilder buffer) {
|
||||
// Provide a minimal tag so decompiler can call-back
|
||||
buffer.append("<pcode");
|
||||
SpecXmlUtils.encodeStringAttribute(buffer, "inject", "uponentry");
|
||||
SpecXmlUtils.encodeBooleanAttribute(buffer, "dynamic", true);
|
||||
buffer.append("/>\n");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreXml(XmlPullParser parser, SleighLanguage language) throws XmlParseException {
|
||||
XmlElement el = parser.start();
|
||||
|
@ -227,12 +227,22 @@ public class InjectPayloadJavaParameters implements InjectPayload {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return (obj instanceof InjectPayloadJavaParameters); // All instances are equal
|
||||
public boolean isEquivalent(InjectPayload obj) {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 123474217; // All instances are equal
|
||||
InjectPayloadJavaParameters op2 = (InjectPayloadJavaParameters) obj;
|
||||
if (!name.equals(op2.name)) {
|
||||
return false;
|
||||
}
|
||||
if (!sourceName.equals(op2.sourceName)) {
|
||||
return false;
|
||||
}
|
||||
// Compare temp4 to determine if the uniqBase passed in was equivalent.
|
||||
// Otherwise we don't need to compare the other internal Varnodes
|
||||
if (!temp4.equals(op2.temp4)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue