mirror of
https://github.com/NationalSecurityAgency/ghidra
synced 2024-08-28 05:20:21 +00:00
GP-2545 Check for unknown prototype models when committing
This commit is contained in:
parent
a438a1e1ea
commit
badc9370c1
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue