GP-2545 Check for unknown prototype models when committing

This commit is contained in:
caheckman 2022-09-15 19:17:18 -04:00
parent a438a1e1ea
commit badc9370c1

View file

@ -19,6 +19,7 @@ import java.util.*;
import ghidra.program.model.address.*;
import ghidra.program.model.data.*;
import ghidra.program.model.lang.PrototypeModel;
import ghidra.program.model.lang.Register;
import ghidra.program.model.listing.*;
import ghidra.program.model.listing.Function.FunctionUpdateType;
@ -39,6 +40,38 @@ public class HighFunctionDBUtil {
public static final String AUTO_CAT = "/auto_proto"; // Category for auto generated prototypes
/**
* Return the appropriate model name for committing to the database with the given HighFunction.
* Generally this just returns the model name attached to the HighFunction, but if the "unknown"
* model is associated with the function, or if the model doesn't exist, the decompiler
* was using the "default" model internally, so this is the more appropriate model to commit.
* Its possible for this routine to return null, if the architecture has no default model.
* @param highFunction is the given HighFunction
* @return the model name to commit
*/
private static String getPrototypeModelForCommit(HighFunction highFunction) {
FunctionPrototype prototype = highFunction.getFunctionPrototype();
String modelName = (prototype != null) ? prototype.getModelName() : null;
if (modelName != null) {
if (modelName.equals(Function.UNKNOWN_CALLING_CONVENTION_STRING)) {
modelName = null;
}
else {
if (null == highFunction.getCompilerSpec().getCallingConvention(modelName)) {
modelName = null;
}
}
}
if (modelName == null) {
// Currently the decompiler uses the default convention to model an unknown convention
PrototypeModel model = highFunction.getCompilerSpec().getDefaultCallingConvention();
if (model != null) {
modelName = model.getName();
}
}
return modelName;
}
/**
* Commit the decompiler's version of the function return data-type to the database.
* The decompiler's version of the prototype model is committed as well
@ -51,7 +84,7 @@ public class HighFunctionDBUtil {
// Change calling convention if needed
Function function = highFunction.getFunction();
String convention = function.getCallingConventionName();
String modelName = highFunction.getFunctionPrototype().getModelName();
String modelName = getPrototypeModelForCommit(highFunction);
if (modelName != null && !modelName.equals(convention)) {
function.setCallingConvention(modelName);
}
@ -84,8 +117,7 @@ public class HighFunctionDBUtil {
List<Parameter> params = getParameters(highFunction, useDataTypes);
FunctionPrototype functionPrototype = highFunction.getFunctionPrototype();
String modelName = (functionPrototype != null) ? functionPrototype.getModelName() : null;
String modelName = getPrototypeModelForCommit(highFunction);
commitParamsToDatabase(function, modelName, params,
highFunction.getFunctionPrototype().isVarArg(), true, source);
}