Merge remote-tracking branch

'origin/GP-2612_PrototypeModel_return_address' (Closes #4611)
This commit is contained in:
Ryan Kurtz 2022-10-24 13:04:16 -04:00
commit daa2342aa4
4 changed files with 27 additions and 6 deletions

View file

@ -154,6 +154,8 @@ public class SpecExtensionTest extends AbstractDecompilerTest {
program.endTransaction(id1, true); program.endTransaction(id1, true);
PrototypeModel myproto = cspec.getCallingConvention("myproto"); PrototypeModel myproto = cspec.getCallingConvention("myproto");
assertNotNull(myproto); assertNotNull(myproto);
assertNotNull(myproto.getReturnAddress());
assertArrayEquals(defaultModel.getReturnAddress(), myproto.getReturnAddress());
int id = program.startTransaction("test extension install"); int id = program.startTransaction("test extension install");
Address addr = program.getAddressFactory().getDefaultAddressSpace().getAddress(0x100112c); Address addr = program.getAddressFactory().getDefaultAddressSpace().getAddress(0x100112c);

View file

@ -136,6 +136,7 @@ public class ProgramCompilerSpec extends BasicCompilerSpec {
continue; continue;
} }
markPrototypeAsExtension(model); markPrototypeAsExtension(model);
setDefaultReturnAddressIfNeeded(model);
finalList.add(model); finalList.add(model);
usermodels.put(model.getName(), model); usermodels.put(model.getName(), model);
} }

View file

@ -77,7 +77,7 @@ public class BasicCompilerSpec implements CompilerSpec {
private List<Varnode> preferSplit; // List of registers the decompiler prefers to split private List<Varnode> preferSplit; // List of registers the decompiler prefers to split
private AddressSet noHighPtr; // Memory regions the decompiler treats as not addressable private AddressSet noHighPtr; // Memory regions the decompiler treats as not addressable
private AddressSet readOnlySet; // (Additional) memory ranges the decompiler treats as read-only private AddressSet readOnlySet; // (Additional) memory ranges the decompiler treats as read-only
private Varnode returnAddress; // Register/memory where decompiler expects return address to be stored protected Varnode returnAddress; // Register/memory where decompiler expects return address to be stored
private int funcPtrAlign; // Alignment of function pointers, 0=no alignment (default) private int funcPtrAlign; // Alignment of function pointers, 0=no alignment (default)
private List<Pair<AddressSpace, Integer>> deadCodeDelay; private List<Pair<AddressSpace, Integer>> deadCodeDelay;
private List<AddressRange> inferPtrBounds; // Restrictions on where decompiler can infer pointers private List<AddressRange> inferPtrBounds; // Restrictions on where decompiler can infer pointers
@ -1066,6 +1066,7 @@ public class BasicCompilerSpec implements CompilerSpec {
model = new PrototypeModel(); model = new PrototypeModel();
model.restoreXml(parser, this); model.restoreXml(parser, this);
} }
setDefaultReturnAddressIfNeeded(model);
modelList.add(model); modelList.add(model);
return model; return model;
} }
@ -1169,6 +1170,19 @@ public class BasicCompilerSpec implements CompilerSpec {
model.isExtension = true; model.isExtension = true;
} }
/**
* Sets the {@code returnaddress} of {@code model} to the {@code returnAddress}
* of {@code this} if the model does not have a return address set.
* @param model prototype
*/
protected void setDefaultReturnAddressIfNeeded(PrototypeModel model) {
if (model.getReturnAddress() == null) {
Varnode[] retAddr =
(returnAddress == null) ? new Varnode[0] : new Varnode[] { returnAddress };
model.setReturnAddress(retAddr);
}
}
@Override @Override
public boolean isEquivalent(CompilerSpec obj) { public boolean isEquivalent(CompilerSpec obj) {
if (getClass() != obj.getClass()) { if (getClass() != obj.getClass()) {

View file

@ -156,9 +156,6 @@ public class PrototypeModel {
* @return list of registers/memory used to store the return address * @return list of registers/memory used to store the return address
*/ */
public Varnode[] getReturnAddress() { public Varnode[] getReturnAddress() {
if (returnaddress == null) {
returnaddress = new Varnode[0];
}
return returnaddress; return returnaddress;
} }
@ -444,8 +441,7 @@ public class PrototypeModel {
encoder.writeSignedInteger(ATTRIB_STACKSHIFT, stackshift); encoder.writeSignedInteger(ATTRIB_STACKSHIFT, stackshift);
GenericCallingConvention nameType = GenericCallingConvention.guessFromName(name); GenericCallingConvention nameType = GenericCallingConvention.guessFromName(name);
if (nameType != genericCallingConvention) { if (nameType != genericCallingConvention) {
encoder.writeString(ATTRIB_TYPE, encoder.writeString(ATTRIB_TYPE, genericCallingConvention.getDeclarationName());
genericCallingConvention.getDeclarationName());
} }
if (hasThis) { if (hasThis) {
encoder.writeBool(ATTRIB_HASTHIS, true); encoder.writeBool(ATTRIB_HASTHIS, true);
@ -794,4 +790,12 @@ public class PrototypeModel {
public String toString() { public String toString() {
return getName(); return getName();
} }
/**
* Set the return address
* @param returnaddress return address
*/
protected void setReturnAddress(Varnode[] returnaddress) {
this.returnaddress = returnaddress;
}
} }