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 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());
|
||||
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue