Merge remote-tracking branch 'origin/patch'

This commit is contained in:
Ryan Kurtz 2022-12-08 13:58:37 -05:00
commit 93df150b21
3 changed files with 40 additions and 14 deletions

View file

@ -276,8 +276,8 @@ public abstract class ConvertConstantAction extends AbstractDecompilerAction {
Msg.error(this, "Symbol does not have matching entry in equate table"); Msg.error(this, "Symbol does not have matching entry in equate table");
return null; return null;
} }
task = new ConvertConstantTask(context, equateName, convertAddr, convertVn, convertHash, task = new ConvertConstantTask(context, equateName, convertAddr, convertVn,
convertIndex); convertIsSigned, convertHash, convertIndex);
} }
else { else {
PcodeOp op = convertVn.getLoneDescend(); PcodeOp op = convertVn.getLoneDescend();
@ -285,8 +285,8 @@ public abstract class ConvertConstantAction extends AbstractDecompilerAction {
DynamicHash dynamicHash = new DynamicHash(convertVn, 0); DynamicHash dynamicHash = new DynamicHash(convertVn, 0);
convertHash = dynamicHash.getHash(); convertHash = dynamicHash.getHash();
task = new ConvertConstantTask(context, equateName, convertAddr, convertVn, convertHash, task = new ConvertConstantTask(context, equateName, convertAddr, convertVn,
-1); convertIsSigned, convertHash, -1);
try { try {
ScalarMatch scalarMatch = findScalarMatch(context.getProgram(), convertAddr, ScalarMatch scalarMatch = findScalarMatch(context.getProgram(), convertAddr,
convertVn, TaskMonitor.DUMMY); convertVn, TaskMonitor.DUMMY);
@ -296,14 +296,14 @@ public abstract class ConvertConstantAction extends AbstractDecompilerAction {
if (size == 0) { if (size == 0) {
size = 1; size = 1;
} }
value = ConvertConstantTask.signExtendValue(convertIsSigned, value, size);
String altName = getEquateName(value, size, convertIsSigned, null); String altName = getEquateName(value, size, convertIsSigned, null);
if (altName == null) { if (altName == null) {
altName = equateName; altName = equateName;
} }
// Don't create a named equate if the varnode and the instruction operand differ // Don't create a named equate if the varnode and the instruction operand differ
// as the name was selected specifically for the varnode // as the name was selected specifically for the varnode
if (convertType != EquateSymbol.FORMAT_DEFAULT || if (convertType != EquateSymbol.FORMAT_DEFAULT || value == task.getValue()) {
value == convertVn.getOffset()) {
task.setAlternate(altName, scalarMatch.refAddr, scalarMatch.opIndex, value); task.setAlternate(altName, scalarMatch.refAddr, scalarMatch.opIndex, value);
} }
} }

View file

@ -41,9 +41,10 @@ import utility.function.Callback;
public class ConvertConstantTask implements Callback { public class ConvertConstantTask implements Callback {
private DecompilerActionContext context; private DecompilerActionContext context;
private Program program; private Program program;
private long equateValue; // Primary value of the equate
private int equateSize; // The number of bytes in the Varnode constant being equated
private Address convertAddress; // The primary address of the Equate private Address convertAddress; // The primary address of the Equate
private String convertName; // The primary name to use in the Equate table private String convertName; // The primary name to use in the Equate table
private Varnode convertVn; // The Varnode holding the constant value being equated
private long convertHash; // A dynamic hash locating the constant Varnode in data-flow private long convertHash; // A dynamic hash locating the constant Varnode in data-flow
private int convertIndex; // The scalar index associated with the primary Equate (or -1) private int convertIndex; // The scalar index associated with the primary Equate (or -1)
private boolean convertSigned; private boolean convertSigned;
@ -54,7 +55,8 @@ public class ConvertConstantTask implements Callback {
private long altValue; // Alternate value private long altValue; // Alternate value
public ConvertConstantTask(Varnode vn, boolean isSigned) { public ConvertConstantTask(Varnode vn, boolean isSigned) {
convertVn = vn; equateValue = signExtendValue(isSigned, vn.getOffset(), vn.getSize());
equateSize = vn.getSize();
convertSigned = isSigned; convertSigned = isSigned;
} }
@ -64,20 +66,41 @@ public class ConvertConstantTask implements Callback {
* @param name is the primary Equate name * @param name is the primary Equate name
* @param addr is the primary address of the Equate * @param addr is the primary address of the Equate
* @param vn is the constant Varnode being equated * @param vn is the constant Varnode being equated
* @param isSigned is true if the equate value is considered signed
* @param hash is the dynamic hash * @param hash is the dynamic hash
* @param index is the operand index if the Equate is known to label an instruction operand * @param index is the operand index if the Equate is known to label an instruction operand
*/ */
public ConvertConstantTask(DecompilerActionContext context, String name, Address addr, public ConvertConstantTask(DecompilerActionContext context, String name, Address addr,
Varnode vn, long hash, int index) { Varnode vn, boolean isSigned, long hash, int index) {
this.context = context; this.context = context;
program = context.getProgram(); program = context.getProgram();
convertName = name; convertName = name;
convertAddress = addr; convertAddress = addr;
convertVn = vn; equateValue = signExtendValue(isSigned, vn.getOffset(), vn.getSize());
equateSize = vn.getSize();
convertSigned = isSigned;
convertHash = hash; convertHash = hash;
convertIndex = index; convertIndex = index;
} }
/**
* Negative equates must be sign extended to 64-bits to be properly stored in the table.
* Compute the proper 64-bit value of a constant given its signedness and the number
* of bytes used to store the constant.
* @param isSigned is true if the equate is considered signed
* @param value is the (unsigned) form of the constant
* @param size is the number of bytes used to store the constant
* @return the 64-bit extended value
*/
public static long signExtendValue(boolean isSigned, long value, int size) {
if (isSigned && size < 8) {
int sa = (8 /* sizeof(long) */ - size) * 8 /* bits per byte */;
value <<= sa;
value >>= sa;
}
return value;
}
/** /**
* Establish an alternate Equate to try before falling back on the primary Equate * Establish an alternate Equate to try before falling back on the primary Equate
* @param name is the alternate name of the Equate * @param name is the alternate name of the Equate
@ -96,14 +119,14 @@ public class ConvertConstantTask implements Callback {
* @return the primary value being equated * @return the primary value being equated
*/ */
public long getValue() { public long getValue() {
return convertVn.getOffset(); return equateValue;
} }
/** /**
* @return the size of constant (Varnode) being equated * @return the size of constant (Varnode) being equated
*/ */
public int getSize() { public int getSize() {
return convertVn.getSize(); return equateSize;
} }
/** /**
@ -168,14 +191,14 @@ public class ConvertConstantTask implements Callback {
EquateTable equateTable = program.getEquateTable(); EquateTable equateTable = program.getEquateTable();
Equate equate = equateTable.getEquate(convertName); Equate equate = equateTable.getEquate(convertName);
if (equate != null && equate.getValue() != convertVn.getOffset()) { if (equate != null && equate.getValue() != equateValue) {
String msg = "Equate named " + convertName + " already exists with value of " + String msg = "Equate named " + convertName + " already exists with value of " +
equate.getValue() + "."; equate.getValue() + ".";
throw new DuplicateNameException(msg); throw new DuplicateNameException(msg);
} }
if (equate == null) { if (equate == null) {
equate = equateTable.createEquate(convertName, convertVn.getOffset()); equate = equateTable.createEquate(convertName, equateValue);
} }
// Add reference to existing equate // Add reference to existing equate

View file

@ -218,6 +218,9 @@ public class EquateTest extends AbstractDecompilerTest {
// Make sure the named equate applies to the negative number in the decompiler window // Make sure the named equate applies to the negative number in the decompiler window
// NOT the positive variant in the listing // NOT the positive variant in the listing
verifyMatch("MYMINUS", "MYMINUS", 0x1002862, false); verifyMatch("MYMINUS", "MYMINUS", 0x1002862, false);
Equate equate = program.getEquateTable().getEquate("MYMINUS");
// Table value should be sign-extended version of original scalar
assertEquals(equate.getValue(), 0xffffffffffffffc8L);
} }
@Test @Test