diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/FunctionEditorModel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/FunctionEditorModel.java index a5e078bc95..f4d63443d4 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/FunctionEditorModel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/editor/FunctionEditorModel.java @@ -588,6 +588,9 @@ public class FunctionEditorModel { VariableStorage returnStorage = returnInfo.getStorage(); if (returnStorage.isForcedIndirect()) { DataType returnType = returnInfo.getDataType(); + if (returnStorage.isVoidStorage()) { + returnType = VoidDataType.dataType; + } returnInfo.setFormalDataType(returnType); returnInfo.setStorage(returnStorage.clone(program)); signatureTransformed = true; @@ -650,8 +653,8 @@ public class FunctionEditorModel { try { if (autoParamCount < oldAutoCount) { if (oldParams.get(autoParamCount) - .getStorage() - .getAutoParameterType() != storage.getAutoParameterType()) { + .getStorage() + .getAutoParameterType() != storage.getAutoParameterType()) { adjustSelectionForRowRemoved(i); } } @@ -901,25 +904,18 @@ public class FunctionEditorModel { return -1; } - private boolean removeExplicitReturnStoragePtrParameter() { + private DataType removeExplicitReturnStoragePtrParameter() { int index = findExplicitReturnStoragePtrParameter(); if (index >= 0) { - parameters.remove(index); // remove explicit '__return_storage_ptr__' parameter + // remove explicit '__return_storage_ptr__' parameter - should always be a pointer + ParamInfo returnStoragePtrParameter = parameters.remove(index); + DataType dt = returnStoragePtrParameter.getDataType(); adjustSelectionForRowRemoved(index); - return true; - } - return false; - } - - private void revertIndirectParameter(ParamInfo param) { - if (allowCustomStorage) { - throw new AssertException(); // auto-storage mode only - } - DataType dt = param.getDataType(); - if (dt instanceof Pointer) { - param.setFormalDataType(((Pointer) dt).getDataType()); - param.setStorage(VariableStorage.UNASSIGNED_STORAGE); + if (dt instanceof Pointer ptr) { + return ptr.getDataType(); + } } + return null; } /** @@ -933,8 +929,10 @@ public class FunctionEditorModel { allowCustomStorage = b; if (!allowCustomStorage) { removeExplicitThisParameter(); - if (removeExplicitReturnStoragePtrParameter()) { - revertIndirectParameter(returnInfo); + DataType returnDt = removeExplicitReturnStoragePtrParameter(); + if (returnDt != null) { + returnInfo.setFormalDataType(returnDt); + returnInfo.setStorage(VariableStorage.UNASSIGNED_STORAGE); } updateParameterAndReturnStorage(); } @@ -1093,7 +1091,7 @@ public class FunctionEditorModel { } public void setFunctionData(FunctionDefinitionDataType functionDefinition) { - + name = functionDefinition.getName(); setCallingConventionName(functionDefinition.getCallingConventionName()); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/function/FunctionDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/function/FunctionDB.java index 5d23713fbd..3e47b12837 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/function/FunctionDB.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/function/FunctionDB.java @@ -1364,8 +1364,9 @@ public class FunctionDB extends DatabaseObject implements Function { newParams = new ArrayList(newParams); // copy for edit boolean thisParamRemoved = removeExplicitThisParameter(newParams, callingConvention); - if (removeExplicitReturnStorageParameter(newParams)) { - returnVar = revertIndirectParameter(returnVar, true); + DataType dt = removeExplicitReturnStoragePtrParameter(newParams); + if (dt != null) { + returnVar = revertIndirectParameter(returnVar, dt, true); } if (returnVar instanceof Parameter) { returnType = ((Parameter) returnVar).getFormalDataType(); @@ -2255,7 +2256,7 @@ public class FunctionDB extends DatabaseObject implements Function { return false; } - private static int findExplicitReturnStorageParameter(List params) { + private static int findExplicitReturnStoragePtrParameter(List params) { for (int i = 0; i < params.size(); i++) { Variable p = params.get(i); if (RETURN_PTR_PARAM_NAME.equals(p.getName()) && (p.getDataType() instanceof Pointer)) { @@ -2265,50 +2266,54 @@ public class FunctionDB extends DatabaseObject implements Function { return -1; } - private static boolean removeExplicitReturnStorageParameter(List params) { - int paramIndex = findExplicitReturnStorageParameter(params); + private static DataType removeExplicitReturnStoragePtrParameter( + List params) { + int paramIndex = findExplicitReturnStoragePtrParameter(params); if (paramIndex >= 0) { - params.remove(paramIndex); // remove return storage parameter - return true; + Variable returnStoragePtrParameter = params.remove(paramIndex); // remove return storage parameter + DataType dt = returnStoragePtrParameter.getDataType(); + if (dt instanceof Pointer ptr) { + return ptr.getDataType(); + } } - return false; + return null; } - private boolean removeExplicitReturnStorageParameter() { - int paramIndex = findExplicitReturnStorageParameter(params); + private DataType removeExplicitReturnStoragePtrParameter() { + int paramIndex = findExplicitReturnStoragePtrParameter(params); if (paramIndex >= 0) { + ParameterDB returnStoragePtrParameter = params.get(paramIndex); + DataType dt = returnStoragePtrParameter.getDataType(); removeParameter(paramIndex); // remove return storage parameter - return true; + if (dt instanceof Pointer ptr) { + return ptr.getDataType(); + } } - return false; + return null; } /** * Strip indirect pointer data type from a parameter. * @param param parameter to be examined and optionally modified + * @param dt return datatype to be applied * @param create if true the specified param will not be affected and a new parameter * instance will be returned if strip performed, otherwise orginal param will be changed * if possible and returned. * @return parameter with pointer stripped or original param if pointer not used. * Returned parameter will have unassigned storage if affected. */ - private static Variable revertIndirectParameter(Variable param, boolean create) { - DataType dt = param.getDataType(); - if (dt instanceof Pointer) { - try { - dt = ((Pointer) dt).getDataType(); - if (create) { - param = new ParameterImpl(param.getName(), dt, param.getProgram()); - } - else { - param.setDataType(dt, VariableStorage.UNASSIGNED_STORAGE, false, - param.getSource()); - } + private static Variable revertIndirectParameter(Variable param, DataType dt, boolean create) { + try { + if (create) { + param = new ParameterImpl(param.getName(), dt, param.getProgram()); } - catch (InvalidInputException e) { - throw new AssertException(e); // unexpected + else { + param.setDataType(dt, VariableStorage.UNASSIGNED_STORAGE, false, param.getSource()); } } + catch (InvalidInputException e) { + throw new AssertException(e); // unexpected + } return param; } @@ -2330,8 +2335,9 @@ public class FunctionDB extends DatabaseObject implements Function { if (!hasCustomVariableStorage) { // remove explicit 'this' param and return storage use if switching to dynamic storage removeExplicitThisParameter(); - if (removeExplicitReturnStorageParameter()) { - revertIndirectParameter(returnParam, false); + DataType returnDt = removeExplicitReturnStoragePtrParameter(); + if (returnDt != null) { + revertIndirectParameter(returnParam, returnDt, false); } } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/VariableStorage.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/VariableStorage.java index e52d9e638a..732c1f0a8d 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/VariableStorage.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/VariableStorage.java @@ -270,6 +270,9 @@ public class VariableStorage implements Comparable { if (getClass().equals(VariableStorage.class)) { return this; // only reuse if simple VariableStorage instance } + if (isVoidStorage()) { + return VOID_STORAGE; + } if (isUnassignedStorage()) { return UNASSIGNED_STORAGE; }