diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/demangler/DemangledObject.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/demangler/DemangledObject.java index 0534c05a6c..0173aa710d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/demangler/DemangledObject.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/demangler/DemangledObject.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. @@ -45,38 +45,38 @@ public abstract class DemangledObject implements Demangled { The following names probably need to be refactored. Until then, this is how the following fields are used. - mangled - + mangled - Source: The original mangled string as seen in the program Usage: Can be used to see if a program symbol has already been demangled - originalDemangled - + originalDemangled - Source: The raw demangled string returned from the demangler Usage: for display - demangledName - - Source: The name as created by the parser which may transform or even replace the + demangledName - + Source: The name as created by the parser which may transform or even replace the string returned from the demangler Usage: for display - name - - Source: This is derived from the 'demangledName' This is updated to be suitable - for use as a symbol name. This may be null while building, but is - expected to be non-null when applyTo() is called - Usage: The name that will be applied when applyTo() is called. + name - + Source: This is derived from the 'demangledName' This is updated to be suitable + for use as a symbol name. This may be null while building, but is + expected to be non-null when applyTo() is called + Usage: The name that will be applied when applyTo() is called. - Future: These variables should be refactored and renamed to be clearer and more cohesive, - something like: + Future: These variables should be refactored and renamed to be clearer and more cohesive, + something like: mangled rawDemangled escapedDemangled - symbolName + symbolName */ protected final String mangled; // original mangled string - protected final String originalDemangled; // raw demangled string + protected String originalDemangled; // raw demangled string private String demangledName; // updated demangled string private String name; // version of demangled name suitable for symbols @@ -240,6 +240,17 @@ public abstract class DemangledObject implements Demangled { return originalDemangled; } + /** + * Sets the original demangled string. This is useful for clients that reuse constructed + * demangled objects for special case constructs. + *
+ * Note: this method is not on the interface
+ * @param originalDemangled the new original demangled string
+ */
+ public void setOriginalDemangled(String originalDemangled) {
+ this.originalDemangled = originalDemangled;
+ }
+
@Override
public Demangled getNamespace() {
return namespace;
@@ -364,7 +375,7 @@ public abstract class DemangledObject implements Demangled {
}
/**
- * Apply this demangled object detail to the specified program.
+ * Apply this demangled object detail to the specified program.
*
* NOTE: An open Program transaction must be established prior to invoking this method.
*
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 7fef606dc6..ae13dcb1a8 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.
@@ -271,6 +271,19 @@ public class GnuDemanglerParser {
private static final Pattern DESCRIPTIVE_PREFIX_PATTERN =
Pattern.compile("((.+ )(for|to) )(.+)");
+ /*
+ * Sample: global constructors keyed to cyg_libc_stdio_altout
+ *
+ * Pattern: global (constructors|destructors) keyed to text
+ *
+ * Parts:
+ * -global (constructors|destructors) keyed to (group 1)
+ * -text (group 3)
+ *
+ */
+ private static final Pattern GLOBAL_CTOR_DTOR_FOR_PATTERN =
+ Pattern.compile("(global (constructors|destructors) keyed to )(.+)");
+
/**
* The c 'decltype' keyword pattern
*/
@@ -446,6 +459,13 @@ public class GnuDemanglerParser {
return new ArrayHandler(demangled, prefix, type);
}
+ Matcher globalCtorMatcher = GLOBAL_CTOR_DTOR_FOR_PATTERN.matcher(demangled);
+ if (globalCtorMatcher.matches()) {
+ prefix = globalCtorMatcher.group(1);
+ type = globalCtorMatcher.group(3);
+ return new GlobalCtorDtorHandler(demangled, prefix, type);
+ }
+
return new ItemInNamespaceHandler(demangled, prefix, type);
}
@@ -1524,13 +1544,11 @@ public class GnuDemanglerParser {
ItemInNamespaceHandler(String demangled) {
super(demangled);
- this.demangled = demangled;
this.type = demangled;
}
ItemInNamespaceHandler(String demangled, String prefix, String item) {
super(demangled);
- this.demangled = demangled;
this.prefix = prefix;
this.type = item;
}
@@ -1542,6 +1560,40 @@ public class GnuDemanglerParser {
}
}
+ private class GlobalCtorDtorHandler extends SpecialPrefixHandler {
+
+ GlobalCtorDtorHandler(String demangled, String prefix, String item) {
+ super(demangled);
+ this.prefix = prefix;
+ this.type = item;
+ }
+
+ @Override
+ DemangledObject doBuild(Demangled namespace) {
+
+ //
+ // Since we are for constructors/destructors, assume each item is function
+ //
+ String functionName = type;
+ if (!functionName.contains("(")) {
+ // add parens so the type will be parsed as a function
+ functionName += "()";
+ }
+
+ DemangledObject demangledFunction = parseFunctionOrVariable(functionName);
+ demangledFunction.setOriginalDemangled(demangled);
+
+ // e.g., global.constructors.keyed.to.functionName
+ String parsedFunctionName = demangledFunction.getName();
+ String prefixNoSpaces = prefix.replaceAll("\s", "\\.");
+ String fullName = prefixNoSpaces + parsedFunctionName;
+
+ demangledFunction.setName(fullName);
+ demangledFunction.setBackupPlateComment(demangled);
+ return demangledFunction;
+ }
+ }
+
private class ArrayHandler extends SpecialPrefixHandler {
private String arrayType;
@@ -1576,9 +1628,8 @@ public class GnuDemanglerParser {
//
if ("char".equals(arrayType) && type.contains("StringLiteral")) {
// treat a char[] as a string
- DemangledString ds =
- new DemangledString(variable.getMangledString(), demangled, type, type,
- -1 /*unknown length*/, false);
+ DemangledString ds = new DemangledString(variable.getMangledString(), demangled,
+ type, type, -1 /*unknown length*/, false);
ds.setSpecialPrefix(prefix);
return ds;
}
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 4ea5c01bfa..4657cdf013 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
@@ -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.
@@ -1025,7 +1025,7 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
String demangled = process.demangle(mangled);
/*
- typeinfo for
+ typeinfo for
std::__ndk1::__function::__func<
dummy::it::other::Namespace::function(float)::$_2::operator()(dummy::it::other::Namespace*) const::{lambda(dummy::it::other::Namespace*)#1},
std::__ndk1::allocator