GP-4234 Corrected custom storage transitions when indirect-void-storage

applies.
This commit is contained in:
ghidra1 2024-01-12 15:08:24 -05:00
parent a299648f5c
commit 97edcc0d36
3 changed files with 57 additions and 51 deletions

View File

@ -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());

View File

@ -815,8 +815,8 @@ public class FunctionDB extends DatabaseObject implements Function {
dataTypes[0] = returnParam.getFormalDataType();
returnParam.setDynamicStorage(
VoidDataType.isVoidDataType(dataTypes[0]) ? VariableStorage.VOID_STORAGE
: VariableStorage.UNASSIGNED_STORAGE);
VoidDataType.isVoidDataType(dataTypes[0]) ? VariableStorage.VOID_STORAGE
: VariableStorage.UNASSIGNED_STORAGE);
PrototypeModel callingConvention = getCallingConvention();
if (callingConvention == null) {
@ -1300,7 +1300,6 @@ public class FunctionDB extends DatabaseObject implements Function {
source);
}
/**
* Increment updateInProgressCount indicating that an update operation is in progress and
* that any attempted refresh should be deferred. The updateRefreshReqd flag will be set
@ -1363,8 +1362,9 @@ public class FunctionDB extends DatabaseObject implements Function {
newParams = new ArrayList<Variable>(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 +2255,7 @@ public class FunctionDB extends DatabaseObject implements Function {
return false;
}
private static int findExplicitReturnStorageParameter(List<? extends Variable> params) {
private static int findExplicitReturnStoragePtrParameter(List<? extends Variable> 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 +2265,54 @@ public class FunctionDB extends DatabaseObject implements Function {
return -1;
}
private static boolean removeExplicitReturnStorageParameter(List<? extends Variable> params) {
int paramIndex = findExplicitReturnStorageParameter(params);
private static DataType removeExplicitReturnStoragePtrParameter(
List<? extends Variable> 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 +2334,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);
}
}

View File

@ -270,6 +270,9 @@ public class VariableStorage implements Comparable<VariableStorage> {
if (getClass().equals(VariableStorage.class)) {
return this; // only reuse if simple VariableStorage instance
}
if (isVoidStorage()) {
return VOID_STORAGE;
}
if (isUnassignedStorage()) {
return UNASSIGNED_STORAGE;
}