From c51f65c37669921a984de1c36cd709a91ffda2a3 Mon Sep 17 00:00:00 2001 From: ghizard <50744617+ghizard@users.noreply.github.com> Date: Thu, 26 Sep 2024 13:58:46 -0400 Subject: [PATCH] GP-4898 - more Demangler changes: interface, individual demanglers, tests --- .../rust/demangler/RustDemangler.java | 7 ---- .../ghidra/app/util/demangler/Demangler.java | 33 +++++++++++-------- .../app/util/demangler/gnu/GnuDemangler.java | 8 ----- .../util/demangler/gnu/GnuDemanglerTest.java | 31 ++++++++++------- .../microsoft/MicrosoftDemangler.java | 8 ----- .../util/demangler/swift/SwiftDemangler.java | 19 +++++++---- .../gnu/GnuDemanglerIntegrationTest.java | 19 +++++++---- 7 files changed, 64 insertions(+), 61 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/rust/demangler/RustDemangler.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/rust/demangler/RustDemangler.java index 4031ca6281..927af23101 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/rust/demangler/RustDemangler.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/rust/demangler/RustDemangler.java @@ -39,13 +39,6 @@ public class RustDemangler implements Demangler { return RustUtilities.isRustProgram(program); } - @Override - @Deprecated(since = "11.3", forRemoval = true) - public DemangledObject demangle(String mangled, DemanglerOptions options) { - MangledContext mangledContext = createMangledContext(mangled, options, null, null); - return demangle(mangledContext); - } - @Override public DemangledObject demangle(MangledContext context) { DemanglerOptions options = context.getOptions(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/demangler/Demangler.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/demangler/Demangler.java index e2204baa6b..714f6c23a2 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/demangler/Demangler.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/demangler/Demangler.java @@ -37,40 +37,47 @@ public interface Demangler extends ExtensionPoint { * default options ({@link #createDefaultOptions()}. * * @param mangled the mangled string - * @return the result + * @return the result; {@code null} is possible if the mangled string is not supported * @throws DemangledException if the string cannot be demangled */ public default DemangledObject demangle(String mangled) throws DemangledException { MangledContext mangledContext = createMangledContext(mangled, null, null, null); + DemangledObject demangledObject = demangle(mangledContext); + if (demangledObject != null && demangledObject.getMangledContext() == null) { + demangledObject.setMangledContext(mangledContext); + } return demangle(mangledContext); } /** - * Deprecated. Use {@link #demangle(String)} or - * {@link #demangle(MangledContext)}. - * * Attempts to demangle the given string using the given options * * @param mangled the mangled string * @param options the options - * @return the result + * @return the result; {@code null} is possible if the mangled string is not supported * @throws DemangledException if the string cannot be demangled - * @deprecated see above + * @deprecated Use {@link #demangle(String)} or {@link #demangle(MangledContext)}. */ @Deprecated(since = "11.3", forRemoval = true) - public DemangledObject demangle(String mangled, DemanglerOptions options) - throws DemangledException; + public default DemangledObject demangle(String mangled, DemanglerOptions options) + throws DemangledException { + MangledContext mangledContext = createMangledContext(mangled, options, null, null); + DemangledObject demangledObject = demangle(mangledContext); + if (demangledObject != null && demangledObject.getMangledContext() == null) { + demangledObject.setMangledContext(mangledContext); + } + return demangle(mangledContext); + } /** - * Attempts to demangle the string of the mangled context + * Attempts to demangle the string of the mangled context and sets the mangled context on + * the {@link DemangledObject} * * @param context the mangled context - * @return the result + * @return the result; {@code null} is possible if the mangled string is not supported * @throws DemangledException if the string cannot be demangled */ - public default DemangledObject demangle(MangledContext context) throws DemangledException { - return demangle(context.getMangled(), context.getOptions()); - } + public DemangledObject demangle(MangledContext context) throws DemangledException; /** * Creates default options for this particular demangler 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 4b6557ab0a..4c051e89f2 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 @@ -65,14 +65,6 @@ public class GnuDemangler implements Demangler { return false; } - @Override - @Deprecated(since = "11.3", forRemoval = true) - public DemangledObject demangle(String mangled, DemanglerOptions demanglerOptions) - throws DemangledException { - MangledContext mangledContext = createMangledContext(mangled, demanglerOptions, null, null); - return demangle(mangledContext); - } - @Override public DemangledObject demangle(MangledContext mangledContext) throws DemangledException { diff --git a/Ghidra/Features/GnuDemangler/src/test/java/ghidra/app/util/demangler/gnu/GnuDemanglerTest.java b/Ghidra/Features/GnuDemangler/src/test/java/ghidra/app/util/demangler/gnu/GnuDemanglerTest.java index e8458bee39..9fd5aceee8 100644 --- a/Ghidra/Features/GnuDemangler/src/test/java/ghidra/app/util/demangler/gnu/GnuDemanglerTest.java +++ b/Ghidra/Features/GnuDemangler/src/test/java/ghidra/app/util/demangler/gnu/GnuDemanglerTest.java @@ -23,8 +23,7 @@ import org.junit.Before; import org.junit.Test; import generic.test.AbstractGenericTest; -import ghidra.app.util.demangler.DemangledException; -import ghidra.app.util.demangler.DemangledObject; +import ghidra.app.util.demangler.*; import ghidra.program.database.ProgramDB; import ghidra.program.model.address.Address; import ghidra.program.model.data.TerminatedStringDataType; @@ -78,7 +77,9 @@ public class GnuDemanglerTest extends AbstractGenericTest { GnuDemanglerOptions options = new GnuDemanglerOptions(); options.setDemangleOnlyKnownPatterns(false); try { - demangler.demangle(mangled, options); + MangledContext mangledContext = + demangler.createMangledContext(mangled, options, program, null); + demangler.demangle(mangledContext); fail("Demangle should have failed attempting to demangle a non-mangled string"); } catch (DemangledException e) { @@ -89,7 +90,7 @@ public class GnuDemanglerTest extends AbstractGenericTest { @Test public void testUseStandardReplacements() throws Exception { - // + // // Mangled: _ZTv0_n24_NSt19basic_ostringstreamIcSt11char_traitsIcE14pool_allocatorIcEED0Ev // // Demangled: virtual thunk to std::basic_ostringstream, pool_allocator >::~basic_ostringstream() @@ -104,7 +105,9 @@ public class GnuDemanglerTest extends AbstractGenericTest { GnuDemanglerOptions options = new GnuDemanglerOptions(); options.setUseStandardReplacements(true); - DemangledObject dobj = demangler.demangle(mangled, options); + MangledContext mangledContext = + demangler.createMangledContext(mangled, options, program, null); + DemangledObject dobj = demangler.demangle(mangledContext); assertNotNull(dobj); String signature = dobj.getSignature(); @@ -114,9 +117,9 @@ public class GnuDemanglerTest extends AbstractGenericTest { // // Now disable demangled string replacement - // - options.setUseStandardReplacements(false); - dobj = demangler.demangle(mangled, options); + // + options.setUseStandardReplacements(false); // options are still in context + dobj = demangler.demangle(mangledContext); assertNotNull(dobj); String fullSignature = dobj.getSignature(); @@ -224,7 +227,9 @@ public class GnuDemanglerTest extends AbstractGenericTest { demangler.canDemangle(program);// this perform initialization GnuDemanglerOptions options = new GnuDemanglerOptions(GnuDemanglerFormat.EDG); - DemangledObject result = demangler.demangle(mangled, options); + MangledContext mangledContext = + demangler.createMangledContext(mangled, options, program, null); + DemangledObject result = demangler.demangle(mangledContext); assertNull(result); } @@ -239,7 +244,9 @@ public class GnuDemanglerTest extends AbstractGenericTest { GnuDemanglerOptions options = new GnuDemanglerOptions(GnuDemanglerFormat.AUTO, true); options.setDemangleOnlyKnownPatterns(false); - DemangledObject result = demangler.demangle(mangled, options); + MangledContext mangledContext = + demangler.createMangledContext(mangled, options, program, null); + DemangledObject result = demangler.demangle(mangledContext); assertNotNull(result); assertEquals("undefined MyFunction::~MyFunction(void)", result.getSignature(false)); } @@ -257,7 +264,9 @@ public class GnuDemanglerTest extends AbstractGenericTest { GnuDemanglerOptions options = new GnuDemanglerOptions(GnuDemanglerFormat.AUTO, true); options.setDemangleOnlyKnownPatterns(false); - DemangledObject result = demangler.demangle(mangled, options); + MangledContext mangledContext = + demangler.createMangledContext(mangled, options, program, null); + DemangledObject result = demangler.demangle(mangledContext); assertNotNull(result); assertEquals("undefined TTextPanel::scroll(unsigned char,short,int)", result.getSignature(false)); diff --git a/Ghidra/Features/MicrosoftDemangler/src/main/java/ghidra/app/util/demangler/microsoft/MicrosoftDemangler.java b/Ghidra/Features/MicrosoftDemangler/src/main/java/ghidra/app/util/demangler/microsoft/MicrosoftDemangler.java index 4ba4ff5b6a..60d7fed401 100644 --- a/Ghidra/Features/MicrosoftDemangler/src/main/java/ghidra/app/util/demangler/microsoft/MicrosoftDemangler.java +++ b/Ghidra/Features/MicrosoftDemangler/src/main/java/ghidra/app/util/demangler/microsoft/MicrosoftDemangler.java @@ -48,14 +48,6 @@ public class MicrosoftDemangler implements Demangler { executableFormat.indexOf(MSCoffLoader.MSCOFF_NAME) != -1); } - @Override - @Deprecated(since = "11.3", forRemoval = true) - public DemangledObject demangle(String mangled, DemanglerOptions options) - throws DemangledException { - MangledContext mangledContext = new MangledContext(null, options, mangled, null); - return demangle(mangledContext); - } - @Override public DemangledObject demangle(MangledContext context) throws DemangledException { if (!(context instanceof MicrosoftMangledContext mContext)) { diff --git a/Ghidra/Features/SwiftDemangler/src/main/java/ghidra/app/util/demangler/swift/SwiftDemangler.java b/Ghidra/Features/SwiftDemangler/src/main/java/ghidra/app/util/demangler/swift/SwiftDemangler.java index c53a237539..5d74cc09bc 100644 --- a/Ghidra/Features/SwiftDemangler/src/main/java/ghidra/app/util/demangler/swift/SwiftDemangler.java +++ b/Ghidra/Features/SwiftDemangler/src/main/java/ghidra/app/util/demangler/swift/SwiftDemangler.java @@ -89,21 +89,26 @@ public class SwiftDemangler implements Demangler { } @Override - @Deprecated(since = "11.3", forRemoval = true) - public DemangledObject demangle(String mangled, DemanglerOptions op) throws DemangledException { - SwiftDemanglerOptions options = getSwiftDemanglerOptions(op); + public DemangledObject demangle(MangledContext context) throws DemangledException { + SwiftDemanglerOptions options = getSwiftDemanglerOptions(context.getOptions()); + String mangled = context.getMangled(); Demangled demangled = getDemangled(mangled, options); + DemangledObject demangledObject; if (demangled instanceof DemangledFunction func) { - return func; + demangledObject = func; } else if (demangled instanceof DemangledLabel label) { - return label; + demangledObject = label; } else if (demangled instanceof DemangledUnknown unknown) { - return new DemangledLabel(mangled, unknown.getOriginalDemangled(), + demangledObject = new DemangledLabel(mangled, unknown.getOriginalDemangled(), options.getUnsupportedPrefix() + unknown.getOriginalDemangled()); } - return null; + else { + return null; + } + demangledObject.setMangledContext(context); + return demangledObject; } /** diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/app/util/demangler/gnu/GnuDemanglerIntegrationTest.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/app/util/demangler/gnu/GnuDemanglerIntegrationTest.java index 541e381de2..6290691bf4 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/app/util/demangler/gnu/GnuDemanglerIntegrationTest.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/app/util/demangler/gnu/GnuDemanglerIntegrationTest.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. @@ -21,8 +21,7 @@ import org.junit.Before; import org.junit.Test; import ghidra.app.cmd.label.DemanglerCmd; -import ghidra.app.util.demangler.DemangledException; -import ghidra.app.util.demangler.DemangledObject; +import ghidra.app.util.demangler.*; import ghidra.program.database.ProgramDB; import ghidra.program.model.address.Address; import ghidra.test.AbstractGhidraHeadlessIntegrationTest; @@ -62,7 +61,9 @@ public class GnuDemanglerIntegrationTest extends AbstractGhidraHeadlessIntegrati GnuDemanglerOptions options = new GnuDemanglerOptions(); options.setDemangleOnlyKnownPatterns(false); options = options.withDemanglerFormat(GnuDemanglerFormat.AUTO, true); - DemangledObject result = demangler.demangle(mangled, options); + MangledContext mangledContext = + demangler.createMangledContext(mangled, options, program, null); + DemangledObject result = demangler.demangle(mangledContext); assertNotNull(result); assertEquals("undefined MyNamespace::MyFunction($ParamNamespace::paramName *)", result.getSignature(false)); @@ -87,7 +88,9 @@ public class GnuDemanglerIntegrationTest extends AbstractGhidraHeadlessIntegrati GnuDemanglerOptions options = new GnuDemanglerOptions(); options.setDemangleOnlyKnownPatterns(false); options = options.withDemanglerFormat(GnuDemanglerFormat.AUTO, true); - DemangledObject result = demangler.demangle(mangled, options); + MangledContext mangledContext = + demangler.createMangledContext(mangled, options, program, null); + DemangledObject result = demangler.demangle(mangledContext); assertNotNull(result); assertEquals("undefined SoloGimbalEKF::{unnamed_type#1}::SoloGimbalEKF(void)", result.getSignature(false)); @@ -117,7 +120,9 @@ public class GnuDemanglerIntegrationTest extends AbstractGhidraHeadlessIntegrati GnuDemanglerOptions options = new GnuDemanglerOptions(); options.setDemangleOnlyKnownPatterns(false); options = options.withDemanglerFormat(GnuDemanglerFormat.AUTO, true); - DemangledObject result = demangler.demangle(mangled, options); + MangledContext mangledContext = + demangler.createMangledContext(mangled, options, program, null); + DemangledObject result = demangler.demangle(mangledContext); assertNotNull(result); assertEquals( "int JSC::Structure::add<(JSC::Structure::ShouldPin)1,JSC::JSObject::prepareToPutDirectWithoutTransition(JSC::VM&,JSC::PropertyName,unsigned_int,unsigned_int,JSC::Structure*)::{lambda(JSC::GCSafeConcurrentJSLocker_const&,int,int)#1}>(JSC::VM &,JSC::PropertyName,unsigned int,JSC::JSObject::prepareToPutDirectWithoutTransition(JSC::VM&,JSC::PropertyName,unsigned_int,unsigned_int,JSC::Structure*)::{lambda(JSC::GCSafeConcurrentJSLocker const&, int, int)#1} const &)",