mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GT-3214 corrected function parameter ordinal numbering when more than
one auto-parameter is present
This commit is contained in:
parent
0077735568
commit
5904b7d37d
2 changed files with 106 additions and 31 deletions
|
@ -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());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue