mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-22 20:22:44 +00:00
GP-4234 Corrected custom storage transitions when indirect-void-storage
applies.
This commit is contained in:
parent
a299648f5c
commit
97edcc0d36
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user