diff --git a/Ghidra/Features/Base/src/main/help/help/topics/AutoAnalysisPlugin/AutoAnalysis.htm b/Ghidra/Features/Base/src/main/help/help/topics/AutoAnalysisPlugin/AutoAnalysis.htm index 0662dd0d6c..fd3e5dc315 100644 --- a/Ghidra/Features/Base/src/main/help/help/topics/AutoAnalysisPlugin/AutoAnalysis.htm +++ b/Ghidra/Features/Base/src/main/help/help/topics/AutoAnalysisPlugin/AutoAnalysis.htm @@ -386,10 +386,7 @@ Use Deprecated Demangler - By default, GCC symbols will be demangled using the most up-to-date demangler that Ghidra contains (version 2.33.1 as of this writing). Turning this - option on will also invoke the now deprecated previous version of the demangler - (version 2.24) if the preferred demangler cannot demangle a given symbol. - This option only has an effect when the demangler format is available in both - the deprecated and modern demanglers. + option on will invoke the now deprecated version of the demangler (version 2.24).
Support for older demangling styles was removed in c++filt (v2.32).
@@ -402,10 +399,15 @@
The available programs are:
demangler_gnu_v2_33_1demangler_gnu_v2_24
+ <GHIDRA_INSTALL_DIR>/GPL/DemanglerGnu/os/<OS>/
+ demangler_gnu_v2_33_1
+ <GHIDRA_INSTALL_DIR>/GPL/DemanglerGnu/os/<OS>/
+ demangler_gnu_v2_24
When using an external GNU demangler,
please understand the risks associated with using that version of the
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/demangler/DemanglerOptions.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/demangler/DemanglerOptions.java
index e185f044f7..64fd4ffb85 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/demangler/DemanglerOptions.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/demangler/DemanglerOptions.java
@@ -16,7 +16,7 @@
package ghidra.app.util.demangler;
/**
- * A simple class to contain the various settings for demangling.
+ * A simple class to contain the various settings for demangling
*/
public class DemanglerOptions {
@@ -35,47 +35,47 @@ public class DemanglerOptions {
}
/**
- * Checks if the apply signature option is currently set.
- *
- * @return true if set to apply function signatures that are demangled.
+ * Checks if the apply signature option is currently set
+ *
+ * @return true if set to apply function signatures that are demangled
*/
public boolean applySignature() {
return applySignature;
}
/**
- * Set the option to apply function signatures that are demangled.
- *
- * @param applySignature true to apply function signatures that are demangled.
+ * Set the option to apply function signatures that are demangled
+ *
+ * @param applySignature true to apply function signatures that are demangled
*/
public void setApplySignature(boolean applySignature) {
this.applySignature = applySignature;
}
/**
- * Checks if the option to perform disassembly for known data structures (like functions) when
- * demangling is set.
- *
- * @return true if the option is set.
+ * Checks if the option to perform disassembly for known data structures (like functions) when
+ * demangling is set
+ *
+ * @return true if the option is set
*/
public boolean doDisassembly() {
return doDisassembly;
}
/**
- * Sets the option to perform disassembly for known data structures (like functions) when
- * demangling.
- *
- * @param doDisassembly true to perform disassembly when demangling.
+ * Sets the option to perform disassembly for known data structures (like functions) when
+ * demangling
+ *
+ * @param doDisassembly true to perform disassembly when demangling
*/
public void setDoDisassembly(boolean doDisassembly) {
this.doDisassembly = doDisassembly;
}
/**
- * Checks if the option to only demangle known mangled patterns is set.
- *
- * @return true if only known mangled patterns will be demangled.
+ * Checks if the option to only demangle known mangled patterns is set
+ *
+ * @return true if only known mangled patterns will be demangled
*/
public boolean demangleOnlyKnownPatterns() {
return demangleOnlyKnownPatterns;
@@ -83,10 +83,15 @@ public class DemanglerOptions {
/**
* Sets the option to only demangle known mangled patterns. Setting this to false causes
- * all symbols to be demangled, which may result in some symbols getting demangled that were not
- * actually mangled symbols.
- *
- * @param demangleOnlyKnownPatterns true to only demangle known mangled patterns.
+ * most symbols to be demangled, which may result in some symbols getting demangled that were
+ * not actually mangled symbols.
+ *
+ *
Generally, a demangler will report an error if a symbol fails to demangle. Hence, + * clients can use this flag to prevent such errors, signalling to the demangler to only + * attempt those symbols that have a known start pattern. If the known start pattern list + * becomes comprehensive, then this flag can go away. + * + * @param demangleOnlyKnownPatterns true to only demangle known mangled patterns */ public void setDemangleOnlyKnownPatterns(boolean demangleOnlyKnownPatterns) { this.demangleOnlyKnownPatterns = demangleOnlyKnownPatterns; diff --git a/Ghidra/Features/GnuDemangler/ghidra_scripts/DemangleElfWithOptionScript.java b/Ghidra/Features/GnuDemangler/ghidra_scripts/DemangleElfWithOptionScript.java index c4e4988054..82dc4981c7 100644 --- a/Ghidra/Features/GnuDemangler/ghidra_scripts/DemangleElfWithOptionScript.java +++ b/Ghidra/Features/GnuDemangler/ghidra_scripts/DemangleElfWithOptionScript.java @@ -21,8 +21,7 @@ //@category Examples.Demangler import ghidra.app.script.GhidraScript; import ghidra.app.util.demangler.DemangledObject; -import ghidra.app.util.demangler.gnu.GnuDemangler; -import ghidra.app.util.demangler.gnu.GnuDemanglerOptions; +import ghidra.app.util.demangler.gnu.*; import ghidra.program.model.symbol.Symbol; public class DemangleElfWithOptionScript extends GhidraScript { @@ -33,8 +32,8 @@ public class DemangleElfWithOptionScript extends GhidraScript { GnuDemangler demangler = new GnuDemangler(); if (!demangler.canDemangle(currentProgram)) { String executableFormat = currentProgram.getExecutableFormat(); - println("Cannot use the elf demangling options for executable format: " + - executableFormat); + println( + "Cannot use the elf demangling options for executable format: " + executableFormat); return; } @@ -49,14 +48,12 @@ public class DemangleElfWithOptionScript extends GhidraScript { String mangled = symbol.getName(); - GnuDemanglerOptions options = new GnuDemanglerOptions(); + GnuDemanglerOptions options = new GnuDemanglerOptions(GnuDemanglerFormat.AUTO, false); options.setDoDisassembly(false); - options.setDemanglerApplicationArguments("-s auto"); /* // for older formats use the deprecated demangler - options.setDemanglerName(GnuDemanglerOptions.GNU_DEMANGLER_V2_24); - options.setDemanglerApplicationArguments("-s arm"); + options = options.withDemanglerFormat(GnuDemanglerFormat.ARM, true); */ DemangledObject demangledObject = demangler.demangle(mangled, options); diff --git a/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/plugin/core/analysis/GnuDemanglerAnalyzer.java b/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/plugin/core/analysis/GnuDemanglerAnalyzer.java index 2068b1a7ff..015811016b 100644 --- a/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/plugin/core/analysis/GnuDemanglerAnalyzer.java +++ b/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/plugin/core/analysis/GnuDemanglerAnalyzer.java @@ -19,6 +19,7 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Arrays; +import docking.options.editor.BooleanEditor; import ghidra.app.util.demangler.*; import ghidra.app.util.demangler.gnu.*; import ghidra.app.util.importer.MessageLog; @@ -26,10 +27,8 @@ import ghidra.framework.options.*; import ghidra.program.model.listing.Program; import ghidra.util.HelpLocation; -import docking.options.editor.BooleanEditor; - /** - * A version of the demangler analyzer to handle GNU GCC symbols + * A version of the demangler analyzer to handle GNU GCC symbols */ public class GnuDemanglerAnalyzer extends AbstractDemanglerAnalyzer { @@ -87,12 +86,12 @@ public class GnuDemanglerAnalyzer extends AbstractDemanglerAnalyzer { options.registerOption(OPTION_NAME_DEMANGLE_USE_KNOWN_PATTERNS, demangleOnlyKnownPatterns, help, OPTION_DESCRIPTION_USE_KNOWN_PATTERNS); - + options.registerOption(OPTION_NAME_USE_DEPRECATED_DEMANGLER, OptionType.BOOLEAN_TYPE, useDeprecatedDemangler, help, OPTION_DESCRIPTION_DEPRECATED_DEMANGLER, editor); - - options.registerOption(OPTION_NAME_DEMANGLER_FORMAT, OptionType.ENUM_TYPE, - demanglerFormat, help, OPTION_DESCRIPTION_DEMANGLER_FORMAT, formatEditor); + + options.registerOption(OPTION_NAME_DEMANGLER_FORMAT, OptionType.ENUM_TYPE, demanglerFormat, + help, OPTION_DESCRIPTION_DEMANGLER_FORMAT, formatEditor); } @Override @@ -102,7 +101,7 @@ public class GnuDemanglerAnalyzer extends AbstractDemanglerAnalyzer { options.getBoolean(OPTION_NAME_DEMANGLE_USE_KNOWN_PATTERNS, demangleOnlyKnownPatterns); demanglerFormat = options.getEnum(OPTION_NAME_DEMANGLER_FORMAT, GnuDemanglerFormat.AUTO); useDeprecatedDemangler = - options.getBoolean(OPTION_NAME_USE_DEPRECATED_DEMANGLER, useDeprecatedDemangler); + options.getBoolean(OPTION_NAME_USE_DEPRECATED_DEMANGLER, useDeprecatedDemangler); } @Override @@ -118,7 +117,7 @@ public class GnuDemanglerAnalyzer extends AbstractDemanglerAnalyzer { @Override protected DemangledObject doDemangle(String mangled, DemanglerOptions demanglerOtions, MessageLog log) throws DemangledException { - return demangler.demangle(mangled, (GnuDemanglerOptions) demanglerOtions); + return demangler.demangle(mangled, demanglerOtions); } private static class FormatEditor extends EnumEditor implements PropertyChangeListener { @@ -145,16 +144,16 @@ public class GnuDemanglerAnalyzer extends AbstractDemanglerAnalyzer { @Override public GnuDemanglerFormat[] getEnums() { return Arrays.stream(GnuDemanglerFormat.values()) - .filter(this::filter) - .toArray(GnuDemanglerFormat[]::new); + .filter(this::filter) + .toArray(GnuDemanglerFormat[]::new); } @Override public String[] getTags() { return Arrays.stream(GnuDemanglerFormat.values()) - .filter(this::filter) - .map(GnuDemanglerFormat::name) - .toArray(String[]::new); + .filter(this::filter) + .map(GnuDemanglerFormat::name) + .toArray(String[]::new); } @Override @@ -164,7 +163,8 @@ public class GnuDemanglerAnalyzer extends AbstractDemanglerAnalyzer { if (format.isAvailable(isDeprecatedDemangler())) { setValue(format); selector.setFormat(format); - } else { + } + else { setValue(GnuDemanglerFormat.AUTO); } } @@ -178,18 +178,16 @@ public class GnuDemanglerAnalyzer extends AbstractDemanglerAnalyzer { } } - @SuppressWarnings("serial") private static class FormatSelector extends PropertySelector { public FormatSelector(FormatEditor fe) { super(fe); } - @SuppressWarnings("unchecked") void reset(String[] tags) { removeAllItems(); - for (int i = 0; i < tags.length; i++) { - addItem(tags[i]); + for (String tag : tags) { + addItem(tag); } } @@ -200,6 +198,6 @@ public class GnuDemanglerAnalyzer extends AbstractDemanglerAnalyzer { void setFormat(GnuDemanglerFormat format) { setSelectedItem(format.name()); } - + } } diff --git a/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemangler.java b/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemangler.java index b91bb4c0bf..9513e94f05 100644 --- a/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemangler.java +++ b/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemangler.java @@ -106,16 +106,14 @@ public class GnuDemangler implements Demangler { } boolean onlyKnownPatterns = options.demangleOnlyKnownPatterns(); - DemangledObject demangledObject = - parse(mangled, process, demangled, onlyKnownPatterns); + DemangledObject demangledObject = parse(mangled, process, demangled, onlyKnownPatterns); if (demangledObject == null) { return demangledObject; } if (globalPrefix != null) { - DemangledFunction dfunc = - new DemangledFunction(originalMangled, demangled, - globalPrefix + demangledObject.getName()); + DemangledFunction dfunc = new DemangledFunction(originalMangled, demangled, + globalPrefix + demangledObject.getName()); dfunc.setNamespace(demangledObject.getNamespace()); demangledObject = dfunc; } @@ -163,6 +161,19 @@ public class GnuDemangler implements Demangler { applicationOptions); } + /** + * Determines if the given mangled string should not be demangled. There are a couple + * patterns that will always be skipped. + * If {@link GnuDemanglerOptions#demangleOnlyKnownPatterns()} is true, then only mangled + * symbols matching a list of known start patters will not be skipped. + * + *
This demangler class will default to demangling most patterns, since we do not yet
+ * have a comprehensive list of known start patterns.
+ *
+ * @param mangled the mangled string
+ * @param options the options
+ * @return true if the string should not be demangled
+ */
private boolean skip(String mangled, GnuDemanglerOptions options) {
// Ignore versioned symbols which are generally duplicated at the same address
@@ -179,36 +190,29 @@ public class GnuDemangler implements Demangler {
return false; // let it go through
}
- // TODO provide some checks specific to the other formats
- GnuDemanglerFormat format = options.getDemanglerFormat();
- if (format == GnuDemanglerFormat.AUTO) {
+ // This is the current list of known demangler start patterns. Add to this list if we
+ // find any other known GNU start patterns.
+ if (mangled.startsWith("_Z")) {
return false;
}
- if (format == GnuDemanglerFormat.GNUV3) {
- // add to this list if we find any other known GNU start patterns
- if (mangled.startsWith("_Z")) {
- return false;
- }
- if (mangled.startsWith("__Z")) {
- return false;
- }
- if (mangled.startsWith("h__")) {
- return false; // not sure about this one
- }
- if (mangled.startsWith("?")) {
- return false; // not sure about this one
- }
- if (isGnu2Or3Pattern(mangled)) {
- return false;
- }
+ if (mangled.startsWith("__Z")) {
+ return false;
+ }
+ if (mangled.startsWith("h__")) {
+ return false; // not sure about this one
+ }
+ if (mangled.startsWith("?")) {
+ return false; // not sure about this one
+ }
+ if (isGnu2Or3Pattern(mangled)) {
+ return false;
}
return true;
}
private DemangledObject parse(String mangled, GnuDemanglerNativeProcess process,
- String demangled,
- boolean demangleOnlyKnownPatterns) {
+ String demangled, boolean demangleOnlyKnownPatterns) {
if (demangleOnlyKnownPatterns && !isKnownMangledString(mangled, demangled)) {
return null;
@@ -224,7 +228,7 @@ public class GnuDemangler implements Demangler {
// We get requests to demangle strings that are not mangled. For newer mangled strings
// we know how to avoid that. However, older mangled strings can be of many forms. To
// detect whether a string is mangled, we have to resort to examining the output of
- // the demangler.
+ // the demangler.
//
// check for the case where good strings have '__' in them (which is valid GNU2 mangling)
diff --git a/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerFormat.java b/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerFormat.java
index 9f3ffb7de3..38b442e8aa 100644
--- a/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerFormat.java
+++ b/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerFormat.java
@@ -19,71 +19,74 @@ package ghidra.app.util.demangler.gnu;
* Enum representation of the available GnuDemangler formats
*/
public enum GnuDemanglerFormat {
- // OLD: none,auto,gnu,lucid,arm,hp,edg,gnu-v3,java,gnat
- // NEW: none,auto,gnu-v3,java,gnat,dlang,rust
- /** Automatic mangling format detection */
- AUTO("", 0),
- /** GNUv2 mangling format */
- GNU("gnu", -1),
- /** lucid mangling format */
- LUCID("lucid", -1),
- /** arm mangling format */
- ARM("arm", -1),
- /** hp mangling format */
- HP("hp", -1),
- /** mangling format used by the Edison Design Group (EDG) compiler */
- EDG("edg", -1),
- /** GNUv3 mangling format */
- GNUV3("gnu-v3", 0),
- /** Java mangling format */
- JAVA("java", 0),
- /** GNAT Ada compiler mangling format */
- GNAT("gnat", 0),
- /** D mangling format */
- DLANG("dlang", 1),
- /** Rust mangling format */
- RUST("rust", 1);
+ // OLD: none,auto,gnu,lucid,arm,hp,edg,gnu-v3,java,gnat
+ // NEW: none,auto,gnu-v3,java,gnat,dlang,rust
+ /** Automatic mangling format detection */
+ AUTO("", Version.ALL),
+ /** GNUv2 mangling format */
+ GNU("gnu", Version.DEPRECATED),
+ /** lucid mangling format */
+ LUCID("lucid", Version.DEPRECATED),
+ /** arm mangling format */
+ ARM("arm", Version.DEPRECATED),
+ /** hp mangling format */
+ HP("hp", Version.DEPRECATED),
+ /** mangling format used by the Edison Design Group (EDG) compiler */
+ EDG("edg", Version.DEPRECATED),
+ /** GNUv3 mangling format */
+ GNUV3("gnu-v3", Version.ALL),
+ /** Java mangling format */
+ JAVA("java", Version.ALL),
+ /** GNAT Ada compiler mangling format */
+ GNAT("gnat", Version.ALL),
+ /** D mangling format */
+ DLANG("dlang", Version.MODERN),
+ /** Rust mangling format */
+ RUST("rust", Version.MODERN);
- /** the format option string */
- private final String format;
- /** private sentinal. deprecated = -1, both = 0, new = 1 */
- private final byte version;
+ /** the format option string used by the native demangler */
+ private final String format;
+ private final Version version;
- private GnuDemanglerFormat(String format, int version) {
- this.format = format;
- this.version = (byte) version;
- }
+ private GnuDemanglerFormat(String format, Version version) {
+ this.format = format;
+ this.version = version;
+ }
- /**
- * Checks if this format is available in the deprecated gnu demangler
- * @return true if this format is available in the deprecated gnu demangler
- */
- public boolean isDeprecatedFormat() {
- return version <= 0;
- }
+ /**
+ * Checks if this format is available in the deprecated gnu demangler
+ * @return true if this format is available in the deprecated gnu demangler
+ */
+ public boolean isDeprecatedFormat() {
+ return version == Version.DEPRECATED || version == Version.ALL;
+ }
- /**
- * Checks if this format is available in a modern version of the gnu demangler
- * @return true if this format is available in a modern version of the gnu demangler.
- */
- public boolean isModernFormat() {
- return version >= 0;
- }
-
- /**
- * Checks if this format is available for the specified demangler
- * @param isDeprecated true for the deprecated demangler, false for the modern demangler.
- * @return true if the format is available
- */
- public boolean isAvailable(boolean isDeprecated) {
- return isDeprecated ? isDeprecatedFormat() : isModernFormat();
- }
+ /**
+ * Checks if this format is available in a modern version of the gnu demangler
+ * @return true if this format is available in a modern version of the gnu demangler
+ */
+ public boolean isModernFormat() {
+ return version == Version.MODERN || version == Version.ALL;
+ }
- /**
- * Gets the format option to be passed to the demangler via the -s option
- * @return the format option to be passed to the demangler
- */
- public String getFormat() {
- return format;
- }
+ /**
+ * Checks if this format is available for the specified demangler
+ * @param isDeprecated true for the deprecated demangler, false for the modern demangler
+ * @return true if the format is available
+ */
+ public boolean isAvailable(boolean isDeprecated) {
+ return isDeprecated ? isDeprecatedFormat() : isModernFormat();
+ }
+
+ /**
+ * Gets the format option to be passed to the demangler via the -s option
+ * @return the format option to be passed to the demangler
+ */
+ public String getFormat() {
+ return format;
+ }
+
+ private enum Version {
+ DEPRECATED, MODERN, ALL
+ }
}
diff --git a/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerOptions.java b/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerOptions.java
index 5e045ec836..7ba4275019 100644
--- a/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerOptions.java
+++ b/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerOptions.java
@@ -46,26 +46,45 @@ public class GnuDemanglerOptions extends DemanglerOptions {
private final GnuDemanglerFormat format;
private final boolean isDeprecated;
+ /**
+ * Default constructor to use the modern demangler with auto-detect for the format. This
+ * constructor will limit demangling to only known symbols.
+ */
public GnuDemanglerOptions() {
- // use default values
this(GnuDemanglerFormat.AUTO);
}
+ /**
+ * Constructor to specify a particular format
+ *
+ * @param format signals to use the given format
+ */
public GnuDemanglerOptions(GnuDemanglerFormat format) {
- this.format = format;
- // default to the "new" demangler if the format is available in both
- this.isDeprecated = !format.isModernFormat();
+ this(format, !format.isModernFormat());
}
+ /**
+ * Constructor to specify the format to use and whether to prefer the deprecated format when
+ * both deprecated and modern are available
+ *
+ * @param format the format
+ * @param isDeprecated true if the format is not available in the modern demangler
+ * @throws IllegalArgumentException if the given format is not available in the deprecated
+ * demangler
+ */
public GnuDemanglerOptions(GnuDemanglerFormat format, boolean isDeprecated) {
this.format = format;
this.isDeprecated = isDeprecated;
if (!format.isAvailable(isDeprecated)) {
throw new IllegalArgumentException(
- format.name() + " is not available in the "+getDemanglerName());
+ format.name() + " is not available in the " + getDemanglerName());
}
}
+ /**
+ * Copy constructor to create a version of this class from a more generic set of options
+ * @param copy the options to copy
+ */
public GnuDemanglerOptions(DemanglerOptions copy) {
super(copy);
@@ -73,7 +92,8 @@ public class GnuDemanglerOptions extends DemanglerOptions {
GnuDemanglerOptions gCopy = (GnuDemanglerOptions) copy;
format = gCopy.format;
isDeprecated = gCopy.isDeprecated;
- } else {
+ }
+ else {
format = GnuDemanglerFormat.AUTO;
isDeprecated = false;
}
@@ -87,7 +107,7 @@ public class GnuDemanglerOptions extends DemanglerOptions {
}
/**
- * Returns the external demangler executable name to be used for demangling. The
+ * Returns the external demangler executable name to be used for demangling. The
* default value is {@link #GNU_DEMANGLER_DEFAULT}.
* @return the name
*/
@@ -96,24 +116,25 @@ public class GnuDemanglerOptions extends DemanglerOptions {
}
/**
- * A convenience method to copy the state of this options object, changing the
- * demangler executable name and demangler format to the specified values.
- * @param format the demangling format to use
- * @param isDeprecated true to use the deprecated gnu demangler, else false
+ * A convenience method to copy the state of this options object, changing the
+ * demangler executable name and demangler format to the specified values
+ *
+ * @param demanglerFormat the demangling format to use
+ * @param useDeprecated true to use the deprecated gnu demangler, else false
* @return the new options
* @throws IllegalArgumentException if the current format is not available in the
* selected demangler.
*/
- public GnuDemanglerOptions withDemanglerFormat(GnuDemanglerFormat format, boolean isDeprecated)
- throws IllegalArgumentException {
- if (this.format == format && this.isDeprecated == isDeprecated) {
+ public GnuDemanglerOptions withDemanglerFormat(GnuDemanglerFormat demanglerFormat,
+ boolean useDeprecated) throws IllegalArgumentException {
+ if (this.format == demanglerFormat && this.isDeprecated == useDeprecated) {
return this;
}
- if (format.isAvailable(isDeprecated)) {
- return new GnuDemanglerOptions(this, format, isDeprecated);
+ if (demanglerFormat.isAvailable(useDeprecated)) {
+ return new GnuDemanglerOptions(this, demanglerFormat, useDeprecated);
}
throw new IllegalArgumentException(
- format.name() + " is not available in the "+getDemanglerName());
+ demanglerFormat.name() + " is not available in the " + getDemanglerName());
}
/**
diff --git a/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerParser.java b/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerParser.java
index 632cc2c92c..6fb5416236 100644
--- a/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerParser.java
+++ b/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerParser.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -896,9 +896,9 @@ public class GnuDemanglerParser {
/*
Note: really, this should just be checking a list of known disallowed characters,
which is something like:
-
+
<,>,(,),&,*,[,]
-
+
It seems like the current code below is unnecessarily restrictive
*/
@@ -1187,9 +1187,9 @@ public class GnuDemanglerParser {
/*
Examples:
-
+
NS1::Function<>()::StructureName::StructureConstructor()
-
+
*/
String nameString = removeBadSpaces(demangled).trim();
@@ -1353,7 +1353,7 @@ public class GnuDemanglerParser {
DemangledObject doBuild(Demangled namespace) {
DemangledString demangledString = new DemangledString(mangledSource, demangledSource,
"typeinfo-name", type, -1/*unknown length*/, false);
- demangledString.setSpecialPrefix("typeinfo name for ");
+ demangledString.setSpecialPrefix(TYPEINFO_NAME_FOR);
String namespaceString = removeBadSpaces(type);
setNamespace(demangledString, namespaceString);
return demangledString;
@@ -1372,13 +1372,13 @@ public class GnuDemanglerParser {
Samples:
prefix: construction vtable for
name: construction-vtable
-
+
prefix: vtable for
name: vtable
-
+
prefix: typeinfo name for
name: typeinfo-name
-
+
prefix: covariant return thunk
name: covariant-return
*/
diff --git a/Ghidra/Features/GnuDemangler/src/test/java/ghidra/app/plugin/core/analysis/GnuDemanglerAnalyzerTest.java b/Ghidra/Features/GnuDemangler/src/test/java/ghidra/app/plugin/core/analysis/GnuDemanglerAnalyzerTest.java
index 193359b5e3..e4af5e2e22 100644
--- a/Ghidra/Features/GnuDemangler/src/test/java/ghidra/app/plugin/core/analysis/GnuDemanglerAnalyzerTest.java
+++ b/Ghidra/Features/GnuDemangler/src/test/java/ghidra/app/plugin/core/analysis/GnuDemanglerAnalyzerTest.java
@@ -17,12 +17,16 @@ package ghidra.app.plugin.core.analysis;
import static org.junit.Assert.*;
+import java.util.Arrays;
+
import org.junit.Before;
import org.junit.Test;
+import docking.options.editor.BooleanEditor;
import ghidra.app.cmd.label.AddLabelCmd;
import ghidra.app.util.demangler.gnu.GnuDemanglerFormat;
import ghidra.app.util.importer.MessageLog;
+import ghidra.framework.options.EnumEditor;
import ghidra.framework.options.Options;
import ghidra.program.database.ProgramBuilder;
import ghidra.program.database.ProgramDB;
@@ -104,6 +108,24 @@ public class GnuDemanglerAnalyzerTest extends AbstractGhidraHeadlessIntegrationT
assertDemangled(addr, "__dt");
}
+ @Test
+ public void testMangledString_WithArguments_Valid() {
+
+ //
+ // The below demangles to std::io::Read::read_to_end
+ //
+ String mangled = "_ZN3std2io4Read11read_to_end17hb85a0f6802e14499E";
+
+ Address addr = addr("0x110");
+ createSymbol(addr, mangled);
+
+ setFormat(GnuDemanglerFormat.RUST);
+
+ analyze();
+
+ assertDemangled(addr, "read_to_end");
+ }
+
@Test
public void testMangledString_WithArguments_ValidButWrongFormat() {
@@ -123,26 +145,13 @@ public class GnuDemanglerAnalyzerTest extends AbstractGhidraHeadlessIntegrationT
}
@Test
- public void testUseDeprecatedOptionRemoval_WithDeprecatedFormat() {
- setFormat(GnuDemanglerFormat.GNU);
- Options options = program.getOptions("Analyzers");
- assertFalse(options.contains(GnuDemanglerAnalyzer.OPTION_NAME_USE_DEPRECATED_DEMANGLER));
- }
+ public void testUseDeprecatedOptionUpdatesAvailableFormats() {
- @Test
- public void testUseDeprecatedOptionRemoval_WithRecentFormat() {
- setFormat(GnuDemanglerFormat.RUST);
- Options options = program.getOptions("Analyzers");
- assertFalse(options.contains(GnuDemanglerAnalyzer.OPTION_NAME_USE_DEPRECATED_DEMANGLER));
- }
+ setOption_UseDeprecatedDemangler(false);
+ assertFormatAvailable(GnuDemanglerFormat.RUST, true);
- @Test
- public void testUseDeprecatedOptionAddition() {
- // remove it first
- testUseDeprecatedOptionRemoval_WithDeprecatedFormat();
- setFormat(GnuDemanglerFormat.AUTO);
- Options options = program.getOptions("Analyzers");
- assertTrue(options.contains(GnuDemanglerAnalyzer.OPTION_NAME_USE_DEPRECATED_DEMANGLER));
+ setOption_UseDeprecatedDemangler(true);
+ assertFormatAvailable(GnuDemanglerFormat.RUST, false);
}
// things missed:
@@ -151,7 +160,7 @@ public class GnuDemanglerAnalyzerTest extends AbstractGhidraHeadlessIntegrationT
//==================================================================================================
// Private Methods
-//==================================================================================================
+//==================================================================================================
private void analyze() {
tx(program, () -> analyzer.added(program, program.getMemory(), TaskMonitor.DUMMY, log));
@@ -181,6 +190,32 @@ public class GnuDemanglerAnalyzerTest extends AbstractGhidraHeadlessIntegrationT
fail("Unable to find demangled symbol '" + name + "'");
}
+ private void assertFormatAvailable(GnuDemanglerFormat format, boolean isAvailable) {
+
+ Options options = program.getOptions("Analyzers");
+ Options analyzerOptions = options.getOptions(analyzer.getName());
+
+ EnumEditor enumEditor =
+ (EnumEditor) runSwing(() -> analyzerOptions.getPropertyEditor("Demangler Format"));
+ assertNotNull(enumEditor);
+
+ Enum>[] values = enumEditor.getEnums();
+ for (Enum> enum1 : values) {
+ if (format.equals(enum1)) {
+ if (isAvailable) {
+ return;
+ }
+ fail("Found bad enum in list of choices: " + format + ".\nFound: " +
+ Arrays.toString(values));
+ }
+ }
+
+ if (isAvailable) {
+ fail("Did not find enum in list of choices: " + format + ".\nInstead found: " +
+ Arrays.toString(values));
+ }
+ }
+
private void setOption(String optionName, boolean doUse) {
String fullOptionName = analyzer.getName() + Options.DELIMITER_STRING + optionName;
@@ -199,6 +234,18 @@ public class GnuDemanglerAnalyzerTest extends AbstractGhidraHeadlessIntegrationT
fail("Could not find option '" + optionName + "'");
}
+ private void setOption_UseDeprecatedDemangler(boolean use) {
+
+ Options options = program.getOptions("Analyzers");
+ Options analyzerOptions = options.getOptions(analyzer.getName());
+
+ BooleanEditor enumEditor = (BooleanEditor) runSwing(
+ () -> analyzerOptions.getPropertyEditor("Use Deprecated Demangler"));
+ assertNotNull(enumEditor);
+
+ runSwing(() -> enumEditor.setValue(use));
+ }
+
private void setFormat(GnuDemanglerFormat format) {
String optionName = GnuDemanglerAnalyzer.OPTION_NAME_DEMANGLER_FORMAT;
diff --git a/Ghidra/Features/GnuDemangler/src/test/java/ghidra/app/util/demangler/GnuDemanglerParserTest.java b/Ghidra/Features/GnuDemangler/src/test/java/ghidra/app/util/demangler/GnuDemanglerParserTest.java
index 4aaf0fd0a0..17d5ae7b65 100644
--- a/Ghidra/Features/GnuDemangler/src/test/java/ghidra/app/util/demangler/GnuDemanglerParserTest.java
+++ b/Ghidra/Features/GnuDemangler/src/test/java/ghidra/app/util/demangler/GnuDemanglerParserTest.java
@@ -32,8 +32,8 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
@Before
public void setUp() throws Exception {
- process = GnuDemanglerNativeProcess.getDemanglerNativeProcess(
- GnuDemanglerOptions.GNU_DEMANGLER_V2_33_1);
+ process = GnuDemanglerNativeProcess
+ .getDemanglerNativeProcess(GnuDemanglerOptions.GNU_DEMANGLER_V2_33_1);
parser = new GnuDemanglerParser();
}
@@ -111,8 +111,8 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
public void testFunctionPointers() throws Exception {
String mangled = "__t6XpsMap2ZlZP14CORBA_TypeCodePFRCl_UlUlUlf";
- process = GnuDemanglerNativeProcess.getDemanglerNativeProcess(
- GnuDemanglerOptions.GNU_DEMANGLER_V2_24);
+ process = GnuDemanglerNativeProcess
+ .getDemanglerNativeProcess(GnuDemanglerOptions.GNU_DEMANGLER_V2_24);
String demangled = process.demangle(mangled);
@@ -564,8 +564,8 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
String mangled = "CalcPortExposedRect__13LScrollerViewCFR4Rectb";
// use an older demangler; the current demangler cannot handle this string
- process = GnuDemanglerNativeProcess.getDemanglerNativeProcess(
- GnuDemanglerOptions.GNU_DEMANGLER_V2_24);
+ process = GnuDemanglerNativeProcess
+ .getDemanglerNativeProcess(GnuDemanglerOptions.GNU_DEMANGLER_V2_24);
String demangled = process.demangle(mangled);
@@ -589,8 +589,8 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
String mangled = "__dt__Q26MsoDAL9VertFrameFv";
// use an older demangler; the current demangler cannot handle this string
- process = GnuDemanglerNativeProcess.getDemanglerNativeProcess(
- GnuDemanglerOptions.GNU_DEMANGLER_V2_24);
+ process = GnuDemanglerNativeProcess
+ .getDemanglerNativeProcess(GnuDemanglerOptions.GNU_DEMANGLER_V2_24);
String demangled = process.demangle(mangled);
@@ -630,8 +630,8 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
String mangled = "GetColWidths__13CDataRendererCFRA7_s";
// use an older demangler; the current demangler cannot handle this string
- process = GnuDemanglerNativeProcess.getDemanglerNativeProcess(
- GnuDemanglerOptions.GNU_DEMANGLER_V2_24);
+ process = GnuDemanglerNativeProcess
+ .getDemanglerNativeProcess(GnuDemanglerOptions.GNU_DEMANGLER_V2_24);
String demangled = process.demangle(mangled);
@@ -655,8 +655,8 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
String mangled = "GetColWidths__13CDataRendererCFPA7_s";
// use an older demangler; the current demangler cannot handle this string
- process = GnuDemanglerNativeProcess.getDemanglerNativeProcess(
- GnuDemanglerOptions.GNU_DEMANGLER_V2_24);
+ process = GnuDemanglerNativeProcess
+ .getDemanglerNativeProcess(GnuDemanglerOptions.GNU_DEMANGLER_V2_24);
String demangled = process.demangle(mangled);
@@ -709,13 +709,13 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
// This is testing a bug where we were 'off by one' when the array pointer syntax was
// followed by another parameter.
//
- // The below demangles to _gmStage2(SECTION_INFO *, int *, int (*)[12], int, short const *)
+ // The below demangles to _gmStage2(SECTION_INFO *, int *, int (*)[12], int, short const *)
//
String mangled = "_gmStage2__FP12SECTION_INFOPiPA12_iiPCs";
// use an older demangler; the current demangler cannot handle this string
- process = GnuDemanglerNativeProcess.getDemanglerNativeProcess(
- GnuDemanglerOptions.GNU_DEMANGLER_V2_24);
+ process = GnuDemanglerNativeProcess
+ .getDemanglerNativeProcess(GnuDemanglerOptions.GNU_DEMANGLER_V2_24);
String demangled = process.demangle(mangled);
@@ -749,8 +749,8 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
String mangled = "__ct__Q24CStr6BufferFR4CStrUl";
// use an older demangler; the current demangler cannot handle this string
- process = GnuDemanglerNativeProcess.getDemanglerNativeProcess(
- GnuDemanglerOptions.GNU_DEMANGLER_V2_24);
+ process = GnuDemanglerNativeProcess
+ .getDemanglerNativeProcess(GnuDemanglerOptions.GNU_DEMANGLER_V2_24);
String demangled = process.demangle(mangled);
@@ -887,16 +887,14 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
@Test
public void testOverloadedShiftOperatorTemplated_LeftShift() {
- String raw =
- "std::basic_ostream