GT-3214 corrected function parameter ordinal numbering when more than

one auto-parameter is present
This commit is contained in:
ghidra1 2019-10-03 13:42:45 -04:00
parent 0077735568
commit 5904b7d37d
2 changed files with 106 additions and 31 deletions

View file

@ -45,7 +45,8 @@ import ghidra.util.task.TaskMonitorAdapter;
/** /**
* *
*/ */
public class FunctionDBTest extends AbstractGhidraHeadedIntegrationTest implements DomainObjectListener { public class FunctionDBTest extends AbstractGhidraHeadedIntegrationTest
implements DomainObjectListener {
private ProgramDB program; private ProgramDB program;
private AddressSpace space; private AddressSpace space;
@ -609,7 +610,7 @@ public class FunctionDBTest extends AbstractGhidraHeadedIntegrationTest implemen
return f; return f;
} }
private void assertParameters(Parameter p1, Parameter p2, boolean checkStorage) { private void assertParameter(Parameter p1, Parameter p2, boolean checkStorage) {
assertEquals(p1.getName(), p2.getName()); assertEquals(p1.getName(), p2.getName());
if (!p1.getDataType().isEquivalent(p2.getDataType())) { if (!p1.getDataType().isEquivalent(p2.getDataType())) {
Assert.fail("Expected " + p1.getDataType().getName() + " but parameter has type " + Assert.fail("Expected " + p1.getDataType().getName() + " but parameter has type " +
@ -816,15 +817,15 @@ public class FunctionDBTest extends AbstractGhidraHeadedIntegrationTest implemen
assertEquals("__stdcall", f.getCallingConventionName()); assertEquals("__stdcall", f.getCallingConventionName());
Parameter return1 = f.getReturn(); Parameter return1 = f.getReturn();
assertParameters(returnVar, return1, true); assertParameter(returnVar, return1, true);
assertEquals("r6:4", return1.getVariableStorage().toString()); assertEquals("r6:4", return1.getVariableStorage().toString());
Parameter[] parameters = f.getParameters(); Parameter[] parameters = f.getParameters();
assertEquals(3, parameters.length); assertEquals(3, parameters.length);
assertParameters(p1, parameters[0], true); assertParameter(p1, parameters[0], true);
assertParameters(p2, parameters[1], true); assertParameter(p2, parameters[1], true);
assertParameters(p3, parameters[2], true); assertParameter(p3, parameters[2], true);
} }
@ -835,38 +836,104 @@ public class FunctionDBTest extends AbstractGhidraHeadedIntegrationTest implemen
Structure bigStruct = new StructureDataType("bigStruct", 20); Structure bigStruct = new StructureDataType("bigStruct", 20);
ReturnParameterImpl returnVar =
new ReturnParameterImpl(bigStruct, VariableStorage.UNASSIGNED_STORAGE, program);
ParameterImpl p1 =
new ParameterImpl(Function.RETURN_PTR_PARAM_NAME, new PointerDataType(bigStruct),
new VariableStorage(program, program.getRegister("r7")), program);
Structure classStruct = VariableUtilities.findOrCreateClassStruct(f);
ParameterImpl p2 =
new ParameterImpl(Function.THIS_PARAM_NAME, new PointerDataType(classStruct),
new VariableStorage(program, program.getRegister("r8")), program);
ParameterImpl p3 = new ParameterImpl("m2", LongLongDataType.dataType,
new VariableStorage(program, program.getRegister("r12"), program.getRegister("r11")),
program);
ParameterImpl p4 = new ParameterImpl("m3", ByteDataType.dataType,
new VariableStorage(program, program.getRegister("r9")), program);
// function updated with formal signature
f.updateFunction("__thiscall", returnVar, FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,
true, SourceType.USER_DEFINED, p3, p4);
assertTrue(!f.hasCustomVariableStorage());
assertEquals("__thiscall", f.getCallingConventionName());
Parameter return1 = f.getReturn();
assertTrue(return1.isForcedIndirect());
assertTrue(bigStruct.isEquivalent(return1.getFormalDataType()));
assertTrue(returnVar.getDataType().isEquivalent(returnVar.getDataType()));
assertEquals("r12:4 (ptr)", return1.getVariableStorage().toString());
Parameter[] parameters = f.getParameters();
assertEquals(4, parameters.length);
assertParameter(p1, parameters[0], false);
assertEquals(0, parameters[0].getOrdinal());
assertEquals("r12:4 (auto)", parameters[0].getVariableStorage().toString());
assertParameter(p2, parameters[1], false);
assertEquals(1, parameters[1].getOrdinal());
assertEquals("r11:4 (auto)", parameters[1].getVariableStorage().toString());
assertParameter(p3, parameters[2], false);
assertEquals(2, parameters[2].getOrdinal());
assertEquals("Stack[0x0]:8", parameters[2].getVariableStorage().toString());
assertParameter(p4, parameters[3], false);
assertEquals(3, parameters[3].getOrdinal());
assertEquals("r10:1", parameters[3].getVariableStorage().toString());
}
@Test
public void testUpdateFunctionDynamicStorage1() throws Exception {
Function f = createTestFunction();
Structure bigStruct = new StructureDataType("bigStruct", 20);
ReturnParameterImpl returnVar = new ReturnParameterImpl(new PointerDataType(bigStruct), ReturnParameterImpl returnVar = new ReturnParameterImpl(new PointerDataType(bigStruct),
VariableStorage.UNASSIGNED_STORAGE, program); VariableStorage.UNASSIGNED_STORAGE, program);
ParameterImpl p1 = ParameterImpl p1 =
new ParameterImpl(Function.RETURN_PTR_PARAM_NAME, new PointerDataType(bigStruct), new ParameterImpl(Function.RETURN_PTR_PARAM_NAME, new PointerDataType(bigStruct),
new VariableStorage(program, program.getRegister("r7")), program); new VariableStorage(program, program.getRegister("r7")), program);
ParameterImpl p2 = new ParameterImpl("m2", LongLongDataType.dataType, Structure classStruct = VariableUtilities.findOrCreateClassStruct(f);
ParameterImpl p2 =
new ParameterImpl(Function.THIS_PARAM_NAME, new PointerDataType(classStruct),
new VariableStorage(program, program.getRegister("r8")), program);
ParameterImpl p3 = new ParameterImpl("m2", LongLongDataType.dataType,
new VariableStorage(program, program.getRegister("r12"), program.getRegister("r11")), new VariableStorage(program, program.getRegister("r12"), program.getRegister("r11")),
program); program);
ParameterImpl p3 = new ParameterImpl("m3", ByteDataType.dataType, ParameterImpl p4 = new ParameterImpl("m3", ByteDataType.dataType,
new VariableStorage(program, program.getRegister("r9")), program); new VariableStorage(program, program.getRegister("r9")), program);
f.updateFunction("__stdcall", returnVar, FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS, // function updated with auto parameters
true, SourceType.USER_DEFINED, p1, p2, p3); f.updateFunction("__thiscall", returnVar, FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,
true, SourceType.USER_DEFINED, p1, p2, p3, p4);
assertTrue(!f.hasCustomVariableStorage()); assertTrue(!f.hasCustomVariableStorage());
assertEquals("__stdcall", f.getCallingConventionName()); assertEquals("__thiscall", f.getCallingConventionName());
Parameter return1 = f.getReturn(); Parameter return1 = f.getReturn();
assertTrue(return1.isForcedIndirect());
assertTrue(bigStruct.isEquivalent(return1.getFormalDataType())); assertTrue(bigStruct.isEquivalent(return1.getFormalDataType()));
assertTrue(returnVar.getDataType().isEquivalent(returnVar.getDataType())); assertTrue(returnVar.getDataType().isEquivalent(returnVar.getDataType()));
assertEquals("r12:4 (ptr)", return1.getVariableStorage().toString()); assertEquals("r12:4 (ptr)", return1.getVariableStorage().toString());
Parameter[] parameters = f.getParameters(); Parameter[] parameters = f.getParameters();
assertEquals(3, parameters.length); assertEquals(4, parameters.length);
assertParameters(p1, parameters[0], false); assertParameter(p1, parameters[0], false);
assertEquals(0, parameters[0].getOrdinal());
assertEquals("r12:4 (auto)", parameters[0].getVariableStorage().toString()); assertEquals("r12:4 (auto)", parameters[0].getVariableStorage().toString());
assertParameters(p2, parameters[1], false); assertParameter(p2, parameters[1], false);
assertEquals("Stack[0x0]:8", parameters[1].getVariableStorage().toString()); assertEquals(1, parameters[1].getOrdinal());
assertParameters(p3, parameters[2], false); assertEquals("r11:4 (auto)", parameters[1].getVariableStorage().toString());
assertEquals("r11:1", parameters[2].getVariableStorage().toString()); assertParameter(p3, parameters[2], false);
assertEquals(2, parameters[2].getOrdinal());
assertEquals("Stack[0x0]:8", parameters[2].getVariableStorage().toString());
assertParameter(p4, parameters[3], false);
assertEquals(3, parameters[3].getOrdinal());
assertEquals("r10:1", parameters[3].getVariableStorage().toString());
} }
@ -908,13 +975,13 @@ public class FunctionDBTest extends AbstractGhidraHeadedIntegrationTest implemen
ParameterImpl thisParam = new ParameterImpl(Function.THIS_PARAM_NAME, ParameterImpl thisParam = new ParameterImpl(Function.THIS_PARAM_NAME,
new PointerDataType(classStruct), VariableStorage.UNASSIGNED_STORAGE, program); new PointerDataType(classStruct), VariableStorage.UNASSIGNED_STORAGE, program);
assertParameters(p1, parameters[0], false); assertParameter(p1, parameters[0], false);
assertEquals("r12:4 (auto)", parameters[0].getVariableStorage().toString()); assertEquals("r12:4 (auto)", parameters[0].getVariableStorage().toString());
assertParameters(thisParam, parameters[1], false); assertParameter(thisParam, parameters[1], false);
assertEquals("r11:4 (auto)", parameters[1].getVariableStorage().toString()); assertEquals("r11:4 (auto)", parameters[1].getVariableStorage().toString());
assertParameters(p2, parameters[2], false); assertParameter(p2, parameters[2], false);
assertEquals("Stack[0x0]:8", parameters[2].getVariableStorage().toString()); assertEquals("Stack[0x0]:8", parameters[2].getVariableStorage().toString());
assertParameters(p3, parameters[3], false); assertParameter(p3, parameters[3], false);
assertEquals("r10:1", parameters[3].getVariableStorage().toString()); assertEquals("r10:1", parameters[3].getVariableStorage().toString());
// try again with DB params // try again with DB params
@ -933,13 +1000,17 @@ public class FunctionDBTest extends AbstractGhidraHeadedIntegrationTest implemen
parameters = f.getParameters(); parameters = f.getParameters();
assertEquals(4, parameters.length); assertEquals(4, parameters.length);
assertParameters(p1, parameters[0], false); assertParameter(p1, parameters[0], false);
assertEquals(0, parameters[0].getOrdinal());
assertEquals("r12:4 (auto)", parameters[0].getVariableStorage().toString()); assertEquals("r12:4 (auto)", parameters[0].getVariableStorage().toString());
assertParameters(thisParam, parameters[1], false); assertParameter(thisParam, parameters[1], false);
assertEquals(1, parameters[1].getOrdinal());
assertEquals("r11:4 (auto)", parameters[1].getVariableStorage().toString()); assertEquals("r11:4 (auto)", parameters[1].getVariableStorage().toString());
assertParameters(p2, parameters[2], false); assertParameter(p2, parameters[2], false);
assertEquals(2, parameters[2].getOrdinal());
assertEquals("Stack[0x0]:8", parameters[2].getVariableStorage().toString()); assertEquals("Stack[0x0]:8", parameters[2].getVariableStorage().toString());
assertParameters(p3, parameters[3], false); assertParameter(p3, parameters[3], false);
assertEquals(3, parameters[3].getOrdinal());
assertEquals("r10:1", parameters[3].getVariableStorage().toString()); assertEquals("r10:1", parameters[3].getVariableStorage().toString());
// try again with DB params and custom storage // try again with DB params and custom storage
@ -951,19 +1022,23 @@ public class FunctionDBTest extends AbstractGhidraHeadedIntegrationTest implemen
assertEquals("__thiscall", f.getCallingConventionName()); assertEquals("__thiscall", f.getCallingConventionName());
return1 = f.getReturn(); return1 = f.getReturn();
assertParameters(returnVar, return1, false); assertParameter(returnVar, return1, false);
assertEquals("r12:4", return1.getVariableStorage().toString()); assertEquals("r12:4", return1.getVariableStorage().toString());
parameters = f.getParameters(); parameters = f.getParameters();
assertEquals(4, parameters.length); assertEquals(4, parameters.length);
assertParameters(p1, parameters[0], false); assertParameter(p1, parameters[0], false);
assertEquals(0, parameters[0].getOrdinal());
assertEquals("r12:4", parameters[0].getVariableStorage().toString()); assertEquals("r12:4", parameters[0].getVariableStorage().toString());
assertParameters(thisParam, parameters[1], false); assertParameter(thisParam, parameters[1], false);
assertEquals(1, parameters[1].getOrdinal());
assertEquals("r11:4", parameters[1].getVariableStorage().toString()); assertEquals("r11:4", parameters[1].getVariableStorage().toString());
assertParameters(p2, parameters[2], false); assertParameter(p2, parameters[2], false);
assertEquals(2, parameters[2].getOrdinal());
assertEquals("Stack[0x0]:8", parameters[2].getVariableStorage().toString()); assertEquals("Stack[0x0]:8", parameters[2].getVariableStorage().toString());
assertParameters(p3, parameters[3], false); assertParameter(p3, parameters[3], false);
assertEquals(3, parameters[3].getOrdinal());
assertEquals("r10:1", parameters[3].getVariableStorage().toString()); assertEquals("r10:1", parameters[3].getVariableStorage().toString());
} }

View file

@ -826,7 +826,7 @@ public class FunctionDB extends DatabaseObject implements Function {
DataType dt = VariableUtilities.getAutoDataType(this, DataType dt = VariableUtilities.getAutoDataType(this,
returnParam.getFormalDataType(), storage); returnParam.getFormalDataType(), storage);
try { try {
autoParams.add(new AutoParameterImpl(dt, autoIndex, storage, this)); autoParams.add(new AutoParameterImpl(dt, autoIndex++, storage, this));
} }
catch (InvalidInputException e) { catch (InvalidInputException e) {
Msg.error(this, Msg.error(this,