From 34535a85632b1c8c5fc6f1831ef7a12bc7e740cb Mon Sep 17 00:00:00 2001 From: dragonmacher <48328597+dragonmacher@users.noreply.github.com> Date: Tue, 10 Nov 2020 17:10:28 -0500 Subject: [PATCH] GP-272 - Gnu Demangler - fixed demangler failure function parameter that is a member pointer --- .../demangler/gnu/GnuDemanglerParser.java | 29 ++++++++++++++ .../demangler/GnuDemanglerParserTest.java | 40 ++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) 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 ba73d25e34..c04666bf1c 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 @@ -682,6 +682,11 @@ public class GnuDemanglerParser { DemangledDataType ddt = createTypeInNamespace(fullDatatype); String datatype = ddt.getDemangledName(); + + if ("*".equals(datatype)) { + return createMemberPointer(fullDatatype); + } + boolean finishedName = false; for (int i = 0; i < datatype.length(); ++i) { char ch = datatype.charAt(i); @@ -853,6 +858,30 @@ public class GnuDemanglerParser { return ddt; } + private DemangledDataType createMemberPointer(String datatype) { + // this is temp code we expect to update as more samples arrive + + // example: NS1::Type1 NS1::ParenType::* + + String typeWithoutPointer = datatype.substring(0, datatype.length() - 3); + int space = typeWithoutPointer.indexOf(' '); + DemangledDataType ddt; + if (space != -1) { + String type = typeWithoutPointer.substring(0, space); + ddt = createTypeInNamespace(type); + + String parentType = typeWithoutPointer.substring(space + 1); + DemangledDataType parentDdt = createTypeInNamespace(parentType); + ddt.setNamespace(parentDdt); + } + else { + ddt = createTypeInNamespace(typeWithoutPointer); + } + + ddt.incrementPointerLevels(); + return ddt; + } + private boolean isDataTypeNameCharacter(char ch) { /* 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 81cda031b9..9ebc143f9f 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 @@ -1502,11 +1502,49 @@ public class GnuDemanglerParserTest extends AbstractGenericTest { signature); } + @Test + public void testFunctionParameterWithMemberPointer() throws Exception { + + // + // Mangled: __ZN7WebCore22FontSelectionAlgorithm16filterCapabilityEPbMS0_KFNS0_14DistanceResultENS_25FontSelectionCapabilitiesEEMS3_NS_18FontSelectionRangeE + // + // Demangled: WebCore::FontSelectionAlgorithm::filterCapability(bool*, WebCore::FontSelectionAlgorithm::DistanceResult (WebCore::FontSelectionAlgorithm::*)(WebCore::FontSelectionCapabilities) const, WebCore::FontSelectionRange WebCore::FontSelectionCapabilities::*) + // + // + // WebCore::FontSelectionAlgorithm::filterCapability + // ( + // bool*, + // WebCore::FontSelectionAlgorithm::DistanceResult (WebCore::FontSelectionAlgorithm::*)(WebCore::FontSelectionCapabilities) const, + // WebCore::FontSelectionRange WebCore::FontSelectionCapabilities::* + // ) + // + // This demangled string introduces a new construct: + // + // FontSelectionRange FontSelectionCapabilities::* + // + // where the type is 'FontSelectionRange' which is a member of 'FontSelectionCapabilities' + // + DemangledObject object = parser.parse( + "__ZN7WebCore22FontSelectionAlgorithm16filterCapabilityEPbMS0_KFNS0_14DistanceResultENS_25FontSelectionCapabilitiesEEMS3_NS_18FontSelectionRangeE", + "WebCore::FontSelectionAlgorithm::filterCapability(bool*, WebCore::FontSelectionAlgorithm::DistanceResult (WebCore::FontSelectionAlgorithm::*)(WebCore::FontSelectionCapabilities) const, WebCore::FontSelectionRange WebCore::FontSelectionCapabilities::*)"); + + assertNotNull(object); + assertType(object, DemangledFunction.class); + + String name = "filterCapability"; + assertName(object, name, "WebCore", "FontSelectionAlgorithm"); + + String signature = object.getSignature(false); + assertEquals( + "undefined WebCore::FontSelectionAlgorithm::filterCapability(bool *,WebCore::FontSelectionAlgorithm::DistanceResult ()(WebCore::FontSelectionCapabilities) const,WebCore::FontSelectionCapabilities::FontSelectionRange *)", + signature); + } + @Test public void testFunctionWithVarargsRvalueParameter() throws Exception { // __ZN3WTF15__visit_helper2ILl1ELm1EJEE7__visitINS_7VisitorIZNKS_17TextBreakIterator9followingEjEUlRKT_E_JEEEJRKNS_7VariantIJNS_20TextBreakIteratorICUENS_19TextBreakIteratorCFEEEEEEENS_27__multi_visitor_return_typeIS5_JDpT0_EE6__typeERS5_DpOSH_ - + // // // this demangled string introduces a new construct: //