mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
GP-4139 Improve demanglers function signature source type applied.
Renamed rustcall to __rustcall. Minor fix to legacy rust demangling for namespaces.
This commit is contained in:
parent
ed46dde304
commit
d4c854ddbc
18 changed files with 140 additions and 103 deletions
|
@ -145,15 +145,6 @@ public class RustDemanglerAnalyzer extends AbstractDemanglerAnalyzer {
|
|||
try {
|
||||
if (demangled instanceof DemangledFunction defunc) {
|
||||
defunc.applyTo(program, address, options, monitor);
|
||||
Function func = program.getFunctionManager().getFunctionAt(address);
|
||||
if (func != null) {
|
||||
// if has no return type and no parameters, don't trust that it is void and unlock
|
||||
// the signature so the decompiler can figure it out
|
||||
if (defunc.getReturnType() == null && defunc.getParameters().size() == 0) {
|
||||
func.setSignatureSource(SourceType.DEFAULT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package ghidra.app.plugin.core.analysis.rust.demangler;
|
||||
|
||||
import ghidra.app.util.demangler.*;
|
||||
import ghidra.program.model.lang.CompilerSpec;
|
||||
import ghidra.program.model.listing.Program;
|
||||
|
||||
/**
|
||||
|
@ -68,8 +69,9 @@ public class RustDemangler implements Demangler {
|
|||
RustDemanglerParser parser = new RustDemanglerParser();
|
||||
DemangledObject demangledObject = parser.parse(mangled, demangled);
|
||||
|
||||
if (options.applyCallingConvention() && demangledObject instanceof DemangledFunction) {
|
||||
((DemangledFunction) demangledObject).setCallingConvention("rustcall");
|
||||
if (options.applyCallingConvention() &&
|
||||
demangledObject instanceof DemangledFunction demangledFunction) {
|
||||
demangledFunction.setCallingConvention(CompilerSpec.CALLING_CONVENTION_rustcall);
|
||||
}
|
||||
|
||||
return demangledObject;
|
||||
|
|
|
@ -73,6 +73,9 @@ public class RustDemanglerLegacy {
|
|||
element = element.replace("$RP$", ")");
|
||||
element = element.replace("$C$", ",");
|
||||
|
||||
// Ghidra uses :: between namespace names
|
||||
element = element.replace("..", "::");
|
||||
|
||||
int k = 0;
|
||||
while (k < element.length()) {
|
||||
if (element.charAt(k) == '$') {
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.stream.Collectors;
|
|||
import generic.json.Json;
|
||||
import ghidra.app.util.SymbolPathParser;
|
||||
import ghidra.app.util.demangler.*;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
|
||||
/** Parses a demangled rust string */
|
||||
public class RustDemanglerParser {
|
||||
|
@ -67,10 +68,12 @@ public class RustDemanglerParser {
|
|||
|
||||
private DemangledObject parseNext(String demangled) {
|
||||
String nameString = removeBadSpaces(demangled).trim();
|
||||
DemangledFunction variable =
|
||||
DemangledFunction demangledFunction =
|
||||
new DemangledFunction(mangledSource, demangledSource, (String) null);
|
||||
setNameAndNamespace(variable, nameString);
|
||||
return variable;
|
||||
setNameAndNamespace(demangledFunction, nameString);
|
||||
// Restrict to applying name, namespace and calling-convention
|
||||
demangledFunction.setSignatureSourceType(SourceType.DEFAULT);
|
||||
return demangledFunction;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,8 +36,7 @@ public class DataTypeNamingUtil {
|
|||
* @throws IllegalArgumentException if generated name contains unsupported characters
|
||||
*/
|
||||
public static String setMangledAnonymousFunctionName(
|
||||
FunctionDefinitionDataType functionDefinition)
|
||||
throws IllegalArgumentException {
|
||||
FunctionDefinitionDataType functionDefinition) throws IllegalArgumentException {
|
||||
|
||||
DataType returnType = functionDefinition.getReturnType();
|
||||
ParameterDefinition[] parameters = functionDefinition.getArguments();
|
||||
|
@ -49,7 +48,7 @@ public class DataTypeNamingUtil {
|
|||
}
|
||||
|
||||
String convention = functionDefinition.getCallingConventionName();
|
||||
if (convention != null && !Function.UNKNOWN_CALLING_CONVENTION_STRING.equals(convention)) {
|
||||
if (!Function.UNKNOWN_CALLING_CONVENTION_STRING.equals(convention)) {
|
||||
sb.append("_").append(convention);
|
||||
}
|
||||
|
||||
|
|
|
@ -294,7 +294,7 @@ public class ToolTipUtils {
|
|||
if (callingConvention.equals(Function.DEFAULT_CALLING_CONVENTION_STRING)) {
|
||||
callingConvention = function.getCallingConvention().getName();
|
||||
}
|
||||
if (!callingConvention.equals(Function.UNKNOWN_CALLING_CONVENTION_STRING)) {
|
||||
if (!Function.UNKNOWN_CALLING_CONVENTION_STRING.equals(callingConvention)) {
|
||||
String ccHtml = friendlyEncodeHTML(callingConvention);
|
||||
if (function.hasUnknownCallingConventionName()) {
|
||||
ccHtml = colorString(Color.RED, ccHtml);
|
||||
|
|
|
@ -24,9 +24,11 @@ import ghidra.app.cmd.function.*;
|
|||
import ghidra.app.util.NamespaceUtils;
|
||||
import ghidra.app.util.PseudoDisassembler;
|
||||
import ghidra.program.database.data.DataTypeUtilities;
|
||||
import ghidra.program.database.data.ProgramBasedDataTypeManagerDB;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.lang.CompilerSpec;
|
||||
import ghidra.program.model.lang.PrototypeModel;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.symbol.*;
|
||||
|
@ -55,6 +57,7 @@ public class DemangledFunction extends DemangledObject {
|
|||
protected List<DemangledDataType> parameters = new ArrayList<>();
|
||||
protected DemangledTemplate template;
|
||||
protected boolean isOverloadedOperator = false;
|
||||
protected SourceType signatureSourceType = SourceType.ANALYSIS;
|
||||
|
||||
/** Special constructor where it has a templated type before the parameter list */
|
||||
private String templatedConstructorType;
|
||||
|
@ -67,11 +70,43 @@ public class DemangledFunction extends DemangledObject {
|
|||
private boolean isTypeCast;
|
||||
private String throwAttribute;
|
||||
|
||||
/**
|
||||
* Create a {@link DemangledFunction} instance which is marked with a
|
||||
* signature {@link SourceType} of {@link SourceType#ANALYSIS} which will be used
|
||||
* when function signatures are applied to a program. This source type may be changed
|
||||
* if needed using {@link #setSignatureSourceType(SourceType)}.
|
||||
* The function name and namespace is always applied using a symbol source
|
||||
* of {@link SourceType#ANALYSIS}.
|
||||
* @param mangled original mangled symbol name
|
||||
* @param originalDemangled demangled function signature generally used when generating comments
|
||||
* @param name demangled function name
|
||||
*/
|
||||
public DemangledFunction(String mangled, String originalDemangled, String name) {
|
||||
super(mangled, originalDemangled);
|
||||
setName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set signature {@link SourceType} of {@link SourceType#ANALYSIS} which will be used
|
||||
* when function signatures are applied to a program. Specifying {@link SourceType#DEFAULT}
|
||||
* will prevent function return and parameters from being applied but will still apply
|
||||
* calling convention name if specified.
|
||||
* @param signatureSourceType signature source type
|
||||
*/
|
||||
public void setSignatureSourceType(SourceType signatureSourceType) {
|
||||
this.signatureSourceType = signatureSourceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the signature source type which is used when applying the function signature
|
||||
* to a program. A value of {@link SourceType#DEFAULT} indicates that
|
||||
* function return and parameters should not be applied.
|
||||
* @return signature source type
|
||||
*/
|
||||
public SourceType getSignatureSourceType() {
|
||||
return signatureSourceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the function return type.
|
||||
* @param returnType the function return type
|
||||
|
@ -433,6 +468,22 @@ public class DemangledFunction extends DemangledObject {
|
|||
return true;
|
||||
}
|
||||
|
||||
boolean hasCallingConvention = !CompilerSpec.isUnknownCallingConvention(callingConvention);
|
||||
if (hasCallingConvention) {
|
||||
// Ensure that calling convention name exists and can be used
|
||||
ProgramBasedDataTypeManagerDB dtm =
|
||||
(ProgramBasedDataTypeManagerDB) program.getDataTypeManager();
|
||||
dtm.getCallingConventionID(callingConvention, false);
|
||||
}
|
||||
|
||||
if (signatureSourceType == SourceType.DEFAULT) {
|
||||
// Only apply calling convention if specified with DEFAULT source
|
||||
if (hasCallingConvention) {
|
||||
function.setCallingConvention(callingConvention);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Structure classStructure =
|
||||
maybeUpdateCallingConventionAndCreateClass(program, function, options);
|
||||
|
||||
|
@ -454,7 +505,7 @@ public class DemangledFunction extends DemangledObject {
|
|||
}
|
||||
|
||||
ApplyFunctionSignatureCmd cmd = new ApplyFunctionSignatureCmd(function.getEntryPoint(),
|
||||
signature, SourceType.IMPORTED, true, false, DataTypeConflictHandler.DEFAULT_HANDLER,
|
||||
signature, signatureSourceType, true, false, DataTypeConflictHandler.DEFAULT_HANDLER,
|
||||
FunctionRenameOption.RENAME_IF_DEFAULT);
|
||||
cmd.applyTo(program);
|
||||
|
||||
|
|
|
@ -363,6 +363,18 @@ public abstract class DemangledObject implements Demangled {
|
|||
this.errorMessage = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply this demangled object detail to the specified program.
|
||||
* <br>
|
||||
* NOTE: An open Program transaction must be established prior to invoking this method.
|
||||
*
|
||||
* @param program program to which demangled data should be applied.
|
||||
* @param address address which corresponds to this demangled object
|
||||
* @param options options which control how demangled data is applied
|
||||
* @param monitor task monitor
|
||||
* @return true if successfully applied, else false
|
||||
* @throws Exception if an error occurs during the apply operation
|
||||
*/
|
||||
public boolean applyTo(Program program, Address address, DemanglerOptions options,
|
||||
TaskMonitor monitor) throws Exception {
|
||||
return applyPlateCommentOnly(program, address);
|
||||
|
|
|
@ -22,8 +22,12 @@ import org.junit.Test;
|
|||
import ghidra.app.plugin.core.analysis.rust.demangler.RustDemangler;
|
||||
import ghidra.app.util.demangler.DemangledException;
|
||||
import ghidra.app.util.demangler.DemangledObject;
|
||||
import ghidra.program.model.lang.CompilerSpec;
|
||||
|
||||
public class RustDemanglerLegacyTest {
|
||||
|
||||
private static final String RUSTCALL = CompilerSpec.CALLING_CONVENTION_rustcall;
|
||||
|
||||
private static String[] symbols =
|
||||
{ "_ZN43_$LT$char$u20$as$u20$core..fmt..Display$GT$3fmt17h31c4c24bbd08aa24E",
|
||||
"_ZN4core6option13expect_failed17h09b982639336e7eaE",
|
||||
|
@ -32,13 +36,13 @@ public class RustDemanglerLegacyTest {
|
|||
"_ZN5alloc5alloc18handle_alloc_error8rt_error17h4b79f8a717741b7cE",
|
||||
"_ZN3std6thread7current17h20e47a880e55afd5E", };
|
||||
|
||||
private static String[] names = { "rustcall _<char_as_core..fmt..Display>::fmt(void)",
|
||||
"rustcall core::option::expect_failed(void)",
|
||||
"rustcall core::fmt::Formatter::debug_lower_hex(void)",
|
||||
"rustcall std::path::Components::as_path(void)",
|
||||
"rustcall alloc::alloc::handle_alloc_error::rt_error(void)",
|
||||
"rustcall std::thread::current(void)",
|
||||
"rustcall gimli::read::abbrev::Attributes::new(void)" };
|
||||
private static String[] names = { RUSTCALL + " _<char_as_core::fmt::Display>::fmt(void)",
|
||||
RUSTCALL + " core::option::expect_failed(void)",
|
||||
RUSTCALL + " core::fmt::Formatter::debug_lower_hex(void)",
|
||||
RUSTCALL + " std::path::Components::as_path(void)",
|
||||
RUSTCALL + " alloc::alloc::handle_alloc_error::rt_error(void)",
|
||||
RUSTCALL + " std::thread::current(void)",
|
||||
RUSTCALL + " gimli::read::abbrev::Attributes::new(void)" };
|
||||
|
||||
@Test
|
||||
public void demangle() {
|
||||
|
|
|
@ -27,6 +27,7 @@ import ghidra.app.util.importer.MessageLog;
|
|||
import ghidra.framework.options.Options;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.lang.CompilerSpec;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.symbol.Namespace;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
|
@ -206,8 +207,7 @@ public class DecompilerCallConventionAnalyzer extends AbstractAnalyzer {
|
|||
|
||||
// must be an unknown signature
|
||||
String callingConventionName = function.getCallingConventionName();
|
||||
|
||||
if (!callingConventionName.equals(Function.UNKNOWN_CALLING_CONVENTION_STRING)) {
|
||||
if (!CompilerSpec.isUnknownCallingConvention(callingConventionName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.util.Iterator;
|
|||
|
||||
import ghidra.app.util.demangler.*;
|
||||
import ghidra.program.model.lang.CompilerSpec;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import mdemangler.datatype.MDDataType;
|
||||
import mdemangler.datatype.MDVarArgsType;
|
||||
import mdemangler.datatype.complex.*;
|
||||
|
@ -216,6 +217,7 @@ public class MDMangGhidra extends MDMang {
|
|||
else {
|
||||
DemangledFunction function =
|
||||
new DemangledFunction(mangledSource, demangledSource, objectCPP.getName());
|
||||
function.setSignatureSourceType(SourceType.IMPORTED);
|
||||
function.setNamespace(processNamespace(objectCPP.getQualification()));
|
||||
resultObject = function;
|
||||
objectResult = processFunction((MDFunctionInfo) typeinfo, function);
|
||||
|
|
|
@ -15,68 +15,24 @@
|
|||
*/
|
||||
package ghidra.feature.vt.api.stringable;
|
||||
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.CALLING_CONVENTION;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.CALL_FIXUP;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_CALLING_CONVENTION;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_CALL_FIXUP;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_FUNCTION_RETURN_TYPE;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_FUNCTION_SIGNATURE;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_HIGHEST_NAME_PRIORITY;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_INLINE;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_NO_RETURN;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_PARAMETER_COMMENTS;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_PARAMETER_DATA_TYPES;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_PARAMETER_NAMES;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_PARAMETER_NAMES_REPLACE_IF_SAME_PRIORITY;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.DEFAULT_OPTION_FOR_VAR_ARGS;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.FUNCTION_RETURN_TYPE;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.INLINE;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.NO_RETURN;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.PARAMETER_COMMENTS;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.PARAMETER_NAMES_REPLACE_IF_SAME_PRIORITY;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.VAR_ARGS;
|
||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.feature.vt.api.util.Stringable;
|
||||
import ghidra.feature.vt.api.util.VersionTrackingApplyException;
|
||||
import ghidra.feature.vt.gui.util.VTMatchApplyChoices;
|
||||
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.CallingConventionChoices;
|
||||
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.CommentChoices;
|
||||
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.FunctionSignatureChoices;
|
||||
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.HighestSourcePriorityChoices;
|
||||
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.ParameterDataTypeChoices;
|
||||
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.ReplaceChoices;
|
||||
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.*;
|
||||
import ghidra.feature.vt.gui.util.VTOptionDefines;
|
||||
import ghidra.framework.options.ToolOptions;
|
||||
import ghidra.program.database.data.DataTypeUtilities;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.DataTypeManager;
|
||||
import ghidra.program.model.data.Pointer;
|
||||
import ghidra.program.model.data.PointerDataType;
|
||||
import ghidra.program.model.data.Undefined;
|
||||
import ghidra.program.model.lang.CompilerSpec;
|
||||
import ghidra.program.model.lang.Language;
|
||||
import ghidra.program.model.lang.PrototypeModel;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.listing.Function.FunctionUpdateType;
|
||||
import ghidra.program.model.listing.FunctionSignature;
|
||||
import ghidra.program.model.listing.Parameter;
|
||||
import ghidra.program.model.listing.ParameterImpl;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.listing.ReturnParameterImpl;
|
||||
import ghidra.program.model.listing.VariableStorage;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.model.symbol.SymbolTable;
|
||||
import ghidra.program.model.symbol.SymbolUtilities;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.util.FunctionUtility;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.StringUtilities;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
|
||||
|
@ -544,9 +500,8 @@ public class FunctionSignatureStringable extends Stringable {
|
|||
public boolean applyFunctionSignature(Function toFunction, ToolOptions markupOptions,
|
||||
boolean forceApply) throws VersionTrackingApplyException {
|
||||
|
||||
VTMatchApplyChoices.FunctionSignatureChoices functionSignatureChoice =
|
||||
markupOptions.getEnum(VTOptionDefines.FUNCTION_SIGNATURE,
|
||||
DEFAULT_OPTION_FOR_FUNCTION_SIGNATURE);
|
||||
VTMatchApplyChoices.FunctionSignatureChoices functionSignatureChoice = markupOptions
|
||||
.getEnum(VTOptionDefines.FUNCTION_SIGNATURE, DEFAULT_OPTION_FOR_FUNCTION_SIGNATURE);
|
||||
|
||||
int toParamCount = toFunction.getParameterCount();
|
||||
|
||||
|
@ -586,10 +541,11 @@ public class FunctionSignatureStringable extends Stringable {
|
|||
List<Parameter> newParams =
|
||||
getParameters(toFunction, markupOptions, forceApply, useCustomStorage);
|
||||
|
||||
toFunction.updateFunction(conventionName, returnParam, newParams,
|
||||
useCustomStorage ? FunctionUpdateType.CUSTOM_STORAGE
|
||||
: FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,
|
||||
true, signatureSource);
|
||||
toFunction
|
||||
.updateFunction(conventionName, returnParam, newParams,
|
||||
useCustomStorage ? FunctionUpdateType.CUSTOM_STORAGE
|
||||
: FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,
|
||||
true, signatureSource);
|
||||
if (forceApply) {
|
||||
// must force signatureSource if precedence has been lowered
|
||||
// TODO: Should any manual change in function signature force source to be USER_DEFINED instead ??
|
||||
|
@ -723,8 +679,8 @@ public class FunctionSignatureStringable extends Stringable {
|
|||
}
|
||||
|
||||
private String getCallingConvention(Function toFunction, ToolOptions markupOptions) {
|
||||
boolean isFromUnknownCallingConvention = ((callingConventionName == null) ||
|
||||
callingConventionName.equals(Function.UNKNOWN_CALLING_CONVENTION_STRING));
|
||||
boolean isFromUnknownCallingConvention =
|
||||
CompilerSpec.isUnknownCallingConvention(callingConventionName);
|
||||
CallingConventionChoices callingConventionChoice =
|
||||
markupOptions.getEnum(CALLING_CONVENTION, DEFAULT_OPTION_FOR_CALLING_CONVENTION);
|
||||
String toCallingConventionName = toFunction.getCallingConventionName();
|
||||
|
@ -854,8 +810,8 @@ public class FunctionSignatureStringable extends Stringable {
|
|||
throws VersionTrackingApplyException {
|
||||
|
||||
// See what options the user has specified when applying parameter names.
|
||||
VTMatchApplyChoices.SourcePriorityChoices parameterNamesChoice = markupOptions.getEnum(
|
||||
VTOptionDefines.PARAMETER_NAMES, DEFAULT_OPTION_FOR_PARAMETER_NAMES);
|
||||
VTMatchApplyChoices.SourcePriorityChoices parameterNamesChoice = markupOptions
|
||||
.getEnum(VTOptionDefines.PARAMETER_NAMES, DEFAULT_OPTION_FOR_PARAMETER_NAMES);
|
||||
VTMatchApplyChoices.HighestSourcePriorityChoices highestPriorityChoice =
|
||||
markupOptions.getEnum(VTOptionDefines.HIGHEST_NAME_PRIORITY,
|
||||
DEFAULT_OPTION_FOR_HIGHEST_NAME_PRIORITY);
|
||||
|
|
|
@ -67,8 +67,8 @@ class CallingConventionDBAdapterV0 extends CallingConventionDBAdapter {
|
|||
String tableName = tablePrefix + CALLING_CONVENTION_TABLE_NAME;
|
||||
if (create) {
|
||||
// No additional indexed fields.
|
||||
callingConventionTable = handle.createTable(tableName,
|
||||
V0_CALLING_CONVENTION_SCHEMA, new int[] {});
|
||||
callingConventionTable =
|
||||
handle.createTable(tableName, V0_CALLING_CONVENTION_SCHEMA, new int[] {});
|
||||
}
|
||||
else {
|
||||
callingConventionTable = handle.getTable(tableName);
|
||||
|
@ -138,7 +138,7 @@ class CallingConventionDBAdapterV0 extends CallingConventionDBAdapter {
|
|||
|
||||
@Override
|
||||
byte getCallingConventionId(String name, Consumer<String> conventionAdded) throws IOException {
|
||||
if (name == null || name.equals(CompilerSpec.CALLING_CONVENTION_unknown)) {
|
||||
if (CompilerSpec.isUnknownCallingConvention(name)) {
|
||||
return UNKNOWN_CALLING_CONVENTION_ID;
|
||||
}
|
||||
else if (name.equals(CompilerSpec.CALLING_CONVENTION_default)) {
|
||||
|
|
|
@ -4008,7 +4008,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
|||
public byte getCallingConventionID(String name, boolean restrictive)
|
||||
throws InvalidInputException, IOException {
|
||||
|
||||
if (name == null || CompilerSpec.CALLING_CONVENTION_unknown.equals(name)) {
|
||||
if (CompilerSpec.isUnknownCallingConvention(name)) {
|
||||
return UNKNOWN_CALLING_CONVENTION_ID;
|
||||
}
|
||||
if (CompilerSpec.CALLING_CONVENTION_default.equals(name)) {
|
||||
|
|
|
@ -178,8 +178,7 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
|||
@Override
|
||||
public void setCallingConvention(String conventionName) throws InvalidInputException {
|
||||
|
||||
if (conventionName == null ||
|
||||
CompilerSpec.CALLING_CONVENTION_unknown.equals(conventionName)) {
|
||||
if (CompilerSpec.isUnknownCallingConvention(conventionName)) {
|
||||
this.callingConventionName = CompilerSpec.CALLING_CONVENTION_unknown;
|
||||
return;
|
||||
}
|
||||
|
@ -365,8 +364,7 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
|||
if ((signature.getName().equals(this.name)) && (compareComment(signature)) &&
|
||||
(DataTypeUtilities.isSameOrEquivalentDataType(signature.getReturnType(),
|
||||
this.returnType)) &&
|
||||
(hasVarArgs == signature.hasVarArgs()) &&
|
||||
(hasNoReturn == signature.hasNoReturn()) &&
|
||||
(hasVarArgs == signature.hasVarArgs()) && (hasNoReturn == signature.hasNoReturn()) &&
|
||||
callingConventionName.equals(signature.getCallingConventionName())) {
|
||||
ParameterDefinition[] args = signature.getArguments();
|
||||
if (args.length == this.params.length) {
|
||||
|
|
|
@ -1089,7 +1089,7 @@ public class BasicCompilerSpec implements CompilerSpec {
|
|||
|
||||
@Override
|
||||
public PrototypeModel matchConvention(String conventionName) {
|
||||
if (conventionName == null || CALLING_CONVENTION_unknown.equals(conventionName) ||
|
||||
if (CompilerSpec.isUnknownCallingConvention(conventionName) ||
|
||||
CALLING_CONVENTION_default.equals(conventionName)) {
|
||||
return defaultModel;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ package ghidra.program.model.lang;
|
|||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.data.DataOrganization;
|
||||
|
@ -48,6 +50,7 @@ public interface CompilerSpec {
|
|||
public final static String CALLING_CONVENTION_stdcall = "__stdcall";
|
||||
public final static String CALLING_CONVENTION_fastcall = "__fastcall";
|
||||
public final static String CALLING_CONVENTION_vectorcall = "__vectorcall";
|
||||
public final static String CALLING_CONVENTION_rustcall = "__rustcall";
|
||||
|
||||
/**
|
||||
* Labels for PrototypeModels that are used by default for various analysis/evaluation
|
||||
|
@ -59,6 +62,19 @@ public interface CompilerSpec {
|
|||
EVAL_CALLED // A PrototypeModel used to evaluate a "called" function
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the specified calling convention name is treated as the unknown calling
|
||||
* convention (blank or {code "unknown"}). Other unrecognized names will return false.
|
||||
* This static method does not assume any specific compiler specification.
|
||||
*
|
||||
* @param callingConventionName calling convention name or null
|
||||
* @return true if specified name is blank or {code "unknown"}
|
||||
*/
|
||||
public static boolean isUnknownCallingConvention(String callingConventionName) {
|
||||
return StringUtils.isBlank(callingConventionName) ||
|
||||
CompilerSpec.CALLING_CONVENTION_unknown.equals(callingConventionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Language this compiler spec is based on. Note that
|
||||
* compiler specs may be reused across multiple languages in the
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<prototype name="rustcall" extrapop="8" stackshift="8">
|
||||
<prototype name="__rustcall" extrapop="8" stackshift="8">
|
||||
<input pointermax="8">
|
||||
<pentry minsize="4" maxsize="8" metatype="float">
|
||||
<register name="XMM0_Qa"/>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue