mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GP-3235 improved auto-assignment of VOID storage to void return type for
function
This commit is contained in:
parent
8dd584c9bc
commit
19c1e8ae5b
17 changed files with 119 additions and 86 deletions
|
@ -392,7 +392,10 @@ public class FunctionDB extends DatabaseObject implements Function {
|
|||
return;
|
||||
}
|
||||
type = type.clone(program.getDataTypeManager());
|
||||
if (storage.isValid() && (storage.size() != type.getLength())) {
|
||||
if (VoidDataType.isVoidDataType(type)) {
|
||||
storage = VariableStorage.VOID_STORAGE;
|
||||
}
|
||||
else if (storage.isValid() && (storage.size() != type.getLength())) {
|
||||
try {
|
||||
storage = VariableUtilities.resizeStorage(storage, type, true, this);
|
||||
}
|
||||
|
@ -811,13 +814,9 @@ public class FunctionDB extends DatabaseObject implements Function {
|
|||
}
|
||||
|
||||
dataTypes[0] = returnParam.getFormalDataType();
|
||||
DataType baseType = dataTypes[0];
|
||||
if (baseType instanceof TypeDef) {
|
||||
baseType = ((TypeDef) baseType).getBaseDataType();
|
||||
}
|
||||
returnParam
|
||||
.setDynamicStorage((baseType instanceof VoidDataType) ? VariableStorage.VOID_STORAGE
|
||||
: VariableStorage.UNASSIGNED_STORAGE);
|
||||
returnParam.setDynamicStorage(
|
||||
VoidDataType.isVoidDataType(dataTypes[0]) ? VariableStorage.VOID_STORAGE
|
||||
: VariableStorage.UNASSIGNED_STORAGE);
|
||||
|
||||
PrototypeModel callingConvention = getCallingConvention();
|
||||
if (callingConvention == null) {
|
||||
|
@ -913,12 +912,8 @@ public class FunctionDB extends DatabaseObject implements Function {
|
|||
ReturnParameterDB rtnParam = getReturn();
|
||||
if (rtnParam.getVariableStorage().isBadStorage()) {
|
||||
DataType dt = rtnParam.getDataType();
|
||||
DataType baseType = dt;
|
||||
if (baseType instanceof TypeDef) {
|
||||
baseType = ((TypeDef) baseType).getBaseDataType();
|
||||
}
|
||||
VariableStorage storage =
|
||||
(baseType instanceof VoidDataType) ? VariableStorage.VOID_STORAGE
|
||||
VoidDataType.isVoidDataType(dt) ? VariableStorage.VOID_STORAGE
|
||||
: VariableStorage.UNASSIGNED_STORAGE;
|
||||
rtnParam.setStorageAndDataType(storage, dt);
|
||||
}
|
||||
|
|
|
@ -22,10 +22,6 @@ import ghidra.program.model.listing.*;
|
|||
|
||||
class ParameterDB extends VariableDB implements Parameter {
|
||||
|
||||
/**
|
||||
* @param function
|
||||
* @param s
|
||||
*/
|
||||
ParameterDB(FunctionDB function, SymbolDB s) {
|
||||
super(function, s);
|
||||
}
|
||||
|
|
|
@ -28,16 +28,17 @@ public class ReturnParameterDB extends ParameterDB {
|
|||
|
||||
private DataType dataType;
|
||||
|
||||
/**
|
||||
* @param function
|
||||
* @param s
|
||||
*/
|
||||
ReturnParameterDB(FunctionDB function, DataType dt, VariableStorage storage) {
|
||||
super(function, null);
|
||||
this.dataType = dt;
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isVoidAllowed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return RETURN_NAME;
|
||||
|
@ -123,15 +124,10 @@ public class ReturnParameterDB extends ParameterDB {
|
|||
VariableStorage newStorage = VariableStorage.UNASSIGNED_STORAGE;
|
||||
boolean hasCustomVariableStorage = function.hasCustomVariableStorage();
|
||||
if (hasCustomVariableStorage) {
|
||||
DataType baseType = type;
|
||||
if (baseType instanceof TypeDef) {
|
||||
baseType = ((TypeDef) baseType).getBaseDataType();
|
||||
}
|
||||
try {
|
||||
newStorage =
|
||||
(baseType instanceof VoidDataType) ? VariableStorage.VOID_STORAGE
|
||||
: VariableUtilities.resizeStorage(getVariableStorage(), type,
|
||||
alignStack, function);
|
||||
newStorage = VoidDataType.isVoidDataType(type) ? VariableStorage.VOID_STORAGE
|
||||
: VariableUtilities.resizeStorage(getVariableStorage(), type,
|
||||
alignStack, function);
|
||||
VariableUtilities.checkStorage(newStorage, type, force);
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
|
|
|
@ -23,8 +23,8 @@ import ghidra.program.database.data.DataTypeUtilities;
|
|||
import ghidra.program.database.symbol.SymbolDB;
|
||||
import ghidra.program.database.symbol.VariableSymbolDB;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.AbstractFloatDataType;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.VoidDataType;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.pcode.Varnode;
|
||||
|
@ -53,12 +53,21 @@ public abstract class VariableDB implements Variable {
|
|||
this.functionMgr = function.getFunctionManager();
|
||||
}
|
||||
|
||||
protected boolean isVoidAllowed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
public final boolean isValid() {
|
||||
VariableStorage variableStorage = getVariableStorage();
|
||||
DataType dt = getDataType();
|
||||
return variableStorage.isValid() &&
|
||||
((dt instanceof AbstractFloatDataType) || variableStorage.size() == dt.getLength());
|
||||
if (VoidDataType.isVoidDataType(dt)) {
|
||||
return isVoidAllowed() && variableStorage.isVoidStorage();
|
||||
}
|
||||
if (dt.getLength() <= 0 || !variableStorage.isValid()) {
|
||||
return false;
|
||||
}
|
||||
return variableStorage.size() >= dt.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -93,4 +93,20 @@ public class VoidDataType extends BuiltIn {
|
|||
return null; // standard C name and type
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the specified {@link DataType} is a {@link VoidDataType} after
|
||||
* stripping away any {@link TypeDef}.
|
||||
* @param dt datatype to be tested
|
||||
* @return true if dt is a void type
|
||||
*/
|
||||
public static boolean isVoidDataType(DataType dt) {
|
||||
if (dt == null) {
|
||||
return false;
|
||||
}
|
||||
if (dt instanceof TypeDef t) {
|
||||
dt = t.getBaseDataType();
|
||||
}
|
||||
return dt instanceof VoidDataType;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -80,11 +80,7 @@ public class ParamListStandard implements ParamList {
|
|||
if (tp == null) {
|
||||
tp = DataType.DEFAULT;
|
||||
}
|
||||
DataType baseType = tp;
|
||||
if (baseType instanceof TypeDef) {
|
||||
baseType = ((TypeDef) baseType).getBaseDataType();
|
||||
}
|
||||
if (baseType instanceof VoidDataType) {
|
||||
if (VoidDataType.isVoidDataType(tp)) {
|
||||
return VariableStorage.VOID_STORAGE;
|
||||
}
|
||||
int sz = tp.getLength();
|
||||
|
|
|
@ -264,9 +264,13 @@ abstract class VariableImpl implements Variable {
|
|||
|
||||
@Override
|
||||
public final boolean isValid() {
|
||||
DataType dt = getDataType();
|
||||
return variableStorage.isValid() &&
|
||||
((dt instanceof AbstractFloatDataType) || variableStorage.size() == dt.getLength());
|
||||
if (VoidDataType.isVoidDataType(dataType)) {
|
||||
return isVoidAllowed() && variableStorage.isVoidStorage();
|
||||
}
|
||||
if (dataType.getLength() <= 0 || !variableStorage.isValid()) {
|
||||
return false;
|
||||
}
|
||||
return variableStorage.size() >= dataType.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -302,11 +306,7 @@ abstract class VariableImpl implements Variable {
|
|||
public void setDataType(DataType type, SourceType source) throws InvalidInputException {
|
||||
type =
|
||||
VariableUtilities.checkDataType(type, isVoidAllowed(), dataType.getLength(), program);
|
||||
DataType baseType = type;
|
||||
if (baseType instanceof TypeDef) {
|
||||
baseType = ((TypeDef) baseType).getBaseDataType();
|
||||
}
|
||||
variableStorage = (baseType instanceof VoidDataType) ? VariableStorage.VOID_STORAGE
|
||||
variableStorage = VoidDataType.isVoidDataType(type) ? VariableStorage.VOID_STORAGE
|
||||
: resizeStorage(variableStorage, type);
|
||||
dataType = type;
|
||||
}
|
||||
|
|
|
@ -372,6 +372,17 @@ public class VariableUtilities {
|
|||
*/
|
||||
public static VariableStorage resizeStorage(VariableStorage curStorage, DataType dataType,
|
||||
boolean alignStack, Function function) throws InvalidInputException {
|
||||
|
||||
if (dataType instanceof TypeDef td) {
|
||||
dataType = td.getBaseDataType();
|
||||
}
|
||||
if (dataType instanceof VoidDataType) {
|
||||
return VariableStorage.VOID_STORAGE;
|
||||
}
|
||||
if (dataType instanceof AbstractFloatDataType) {
|
||||
return curStorage; // do not constrain or attempt resize of float storage
|
||||
}
|
||||
|
||||
if (!curStorage.isValid()) {
|
||||
return curStorage;
|
||||
}
|
||||
|
@ -380,17 +391,11 @@ public class VariableUtilities {
|
|||
if (curSize == newSize) {
|
||||
return curStorage;
|
||||
}
|
||||
|
||||
if (curSize == 0 || curStorage.isUniqueStorage() || curStorage.isHashStorage()) {
|
||||
throw new InvalidInputException("Storage can't be resized: " + curStorage.toString());
|
||||
}
|
||||
|
||||
if (dataType instanceof TypeDef) {
|
||||
dataType = ((TypeDef) dataType).getBaseDataType();
|
||||
}
|
||||
if (dataType instanceof AbstractFloatDataType) {
|
||||
return curStorage; // do not constrain or attempt resize of float storage
|
||||
}
|
||||
|
||||
if (newSize > curSize) {
|
||||
return expandStorage(curStorage, newSize, dataType, alignStack, function);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue