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 AddressSpace space;
@ -609,7 +610,7 @@ public class FunctionDBTest extends AbstractGhidraHeadedIntegrationTest implemen
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());
if (!p1.getDataType().isEquivalent(p2.getDataType())) {
Assert.fail("Expected " + p1.getDataType().getName() + " but parameter has type " +
@ -816,15 +817,15 @@ public class FunctionDBTest extends AbstractGhidraHeadedIntegrationTest implemen
assertEquals("__stdcall", f.getCallingConventionName());
Parameter return1 = f.getReturn();
assertParameters(returnVar, return1, true);
assertParameter(returnVar, return1, true);
assertEquals("r6:4", return1.getVariableStorage().toString());
Parameter[] parameters = f.getParameters();
assertEquals(3, parameters.length);
assertParameters(p1, parameters[0], true);
assertParameters(p2, parameters[1], true);
assertParameters(p3, parameters[2], true);
assertParameter(p1, parameters[0], true);
assertParameter(p2, parameters[1], true);
assertParameter(p3, parameters[2], true);
}
@ -835,38 +836,104 @@ public class FunctionDBTest extends AbstractGhidraHeadedIntegrationTest implemen
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),
VariableStorage.UNASSIGNED_STORAGE, program);
ParameterImpl p1 =
new ParameterImpl(Function.RETURN_PTR_PARAM_NAME, new PointerDataType(bigStruct),
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")),
program);
ParameterImpl p3 = new ParameterImpl("m3", ByteDataType.dataType,
ParameterImpl p4 = new ParameterImpl("m3", ByteDataType.dataType,
new VariableStorage(program, program.getRegister("r9")), program);
f.updateFunction("__stdcall", returnVar, FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,
true, SourceType.USER_DEFINED, p1, p2, p3);
// function updated with auto parameters
f.updateFunction("__thiscall", returnVar, FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,
true, SourceType.USER_DEFINED, p1, p2, p3, p4);
assertTrue(!f.hasCustomVariableStorage());
assertEquals("__stdcall", f.getCallingConventionName());
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(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());
assertParameters(p2, parameters[1], false);
assertEquals("Stack[0x0]:8", parameters[1].getVariableStorage().toString());
assertParameters(p3, parameters[2], false);
assertEquals("r11:1", parameters[2].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());
}
@ -908,13 +975,13 @@ public class FunctionDBTest extends AbstractGhidraHeadedIntegrationTest implemen
ParameterImpl thisParam = new ParameterImpl(Function.THIS_PARAM_NAME,
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());
assertParameters(thisParam, parameters[1], false);
assertParameter(thisParam, parameters[1], false);
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());
assertParameters(p3, parameters[3], false);
assertParameter(p3, parameters[3], false);
assertEquals("r10:1", parameters[3].getVariableStorage().toString());
// try again with DB params
@ -933,13 +1000,17 @@ public class FunctionDBTest extends AbstractGhidraHeadedIntegrationTest implemen
parameters = f.getParameters();
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());
assertParameters(thisParam, parameters[1], false);
assertParameter(thisParam, parameters[1], false);
assertEquals(1, parameters[1].getOrdinal());
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());
assertParameters(p3, parameters[3], false);
assertParameter(p3, parameters[3], false);
assertEquals(3, parameters[3].getOrdinal());
assertEquals("r10:1", parameters[3].getVariableStorage().toString());
// try again with DB params and custom storage
@ -951,19 +1022,23 @@ public class FunctionDBTest extends AbstractGhidraHeadedIntegrationTest implemen
assertEquals("__thiscall", f.getCallingConventionName());
return1 = f.getReturn();
assertParameters(returnVar, return1, false);
assertParameter(returnVar, return1, false);
assertEquals("r12:4", return1.getVariableStorage().toString());
parameters = f.getParameters();
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());
assertParameters(thisParam, parameters[1], false);
assertParameter(thisParam, parameters[1], false);
assertEquals(1, parameters[1].getOrdinal());
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());
assertParameters(p3, parameters[3], false);
assertParameter(p3, parameters[3], false);
assertEquals(3, parameters[3].getOrdinal());
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,
returnParam.getFormalDataType(), storage);
try {
autoParams.add(new AutoParameterImpl(dt, autoIndex, storage, this));
autoParams.add(new AutoParameterImpl(dt, autoIndex++, storage, this));
}
catch (InvalidInputException e) {
Msg.error(this,