GP-4898 - more Demangler changes: interface, individual demanglers, tests

This commit is contained in:
ghizard 2024-09-26 13:58:46 -04:00
parent 9e5c6fecf2
commit c51f65c376
7 changed files with 64 additions and 61 deletions

View File

@ -39,13 +39,6 @@ public class RustDemangler implements Demangler {
return RustUtilities.isRustProgram(program); 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 @Override
public DemangledObject demangle(MangledContext context) { public DemangledObject demangle(MangledContext context) {
DemanglerOptions options = context.getOptions(); DemanglerOptions options = context.getOptions();

View File

@ -37,40 +37,47 @@ public interface Demangler extends ExtensionPoint {
* default options ({@link #createDefaultOptions()}. * default options ({@link #createDefaultOptions()}.
* *
* @param mangled the mangled string * @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 * @throws DemangledException if the string cannot be demangled
*/ */
public default DemangledObject demangle(String mangled) throws DemangledException { public default DemangledObject demangle(String mangled) throws DemangledException {
MangledContext mangledContext = createMangledContext(mangled, null, null, null); MangledContext mangledContext = createMangledContext(mangled, null, null, null);
DemangledObject demangledObject = demangle(mangledContext);
if (demangledObject != null && demangledObject.getMangledContext() == null) {
demangledObject.setMangledContext(mangledContext);
}
return demangle(mangledContext); return demangle(mangledContext);
} }
/** /**
* Deprecated. Use {@link #demangle(String)} or
* {@link #demangle(MangledContext)}.
*
* Attempts to demangle the given string using the given options * Attempts to demangle the given string using the given options
* *
* @param mangled the mangled string * @param mangled the mangled string
* @param options the options * @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 * @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) @Deprecated(since = "11.3", forRemoval = true)
public DemangledObject demangle(String mangled, DemanglerOptions options) public default DemangledObject demangle(String mangled, DemanglerOptions options)
throws DemangledException; 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 * @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 * @throws DemangledException if the string cannot be demangled
*/ */
public default DemangledObject demangle(MangledContext context) throws DemangledException { public DemangledObject demangle(MangledContext context) throws DemangledException;
return demangle(context.getMangled(), context.getOptions());
}
/** /**
* Creates default options for this particular demangler * Creates default options for this particular demangler

View File

@ -65,14 +65,6 @@ public class GnuDemangler implements Demangler {
return false; 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 @Override
public DemangledObject demangle(MangledContext mangledContext) public DemangledObject demangle(MangledContext mangledContext)
throws DemangledException { throws DemangledException {

View File

@ -23,8 +23,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import generic.test.AbstractGenericTest; import generic.test.AbstractGenericTest;
import ghidra.app.util.demangler.DemangledException; import ghidra.app.util.demangler.*;
import ghidra.app.util.demangler.DemangledObject;
import ghidra.program.database.ProgramDB; import ghidra.program.database.ProgramDB;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.TerminatedStringDataType; import ghidra.program.model.data.TerminatedStringDataType;
@ -78,7 +77,9 @@ public class GnuDemanglerTest extends AbstractGenericTest {
GnuDemanglerOptions options = new GnuDemanglerOptions(); GnuDemanglerOptions options = new GnuDemanglerOptions();
options.setDemangleOnlyKnownPatterns(false); options.setDemangleOnlyKnownPatterns(false);
try { 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"); fail("Demangle should have failed attempting to demangle a non-mangled string");
} }
catch (DemangledException e) { catch (DemangledException e) {
@ -89,7 +90,7 @@ public class GnuDemanglerTest extends AbstractGenericTest {
@Test @Test
public void testUseStandardReplacements() throws Exception { public void testUseStandardReplacements() throws Exception {
// //
// Mangled: _ZTv0_n24_NSt19basic_ostringstreamIcSt11char_traitsIcE14pool_allocatorIcEED0Ev // Mangled: _ZTv0_n24_NSt19basic_ostringstreamIcSt11char_traitsIcE14pool_allocatorIcEED0Ev
// //
// Demangled: virtual thunk to std::basic_ostringstream<char, std::char_traits<char>, pool_allocator<char> >::~basic_ostringstream() // Demangled: virtual thunk to std::basic_ostringstream<char, std::char_traits<char>, pool_allocator<char> >::~basic_ostringstream()
@ -104,7 +105,9 @@ public class GnuDemanglerTest extends AbstractGenericTest {
GnuDemanglerOptions options = new GnuDemanglerOptions(); GnuDemanglerOptions options = new GnuDemanglerOptions();
options.setUseStandardReplacements(true); options.setUseStandardReplacements(true);
DemangledObject dobj = demangler.demangle(mangled, options); MangledContext mangledContext =
demangler.createMangledContext(mangled, options, program, null);
DemangledObject dobj = demangler.demangle(mangledContext);
assertNotNull(dobj); assertNotNull(dobj);
String signature = dobj.getSignature(); String signature = dobj.getSignature();
@ -114,9 +117,9 @@ public class GnuDemanglerTest extends AbstractGenericTest {
// //
// Now disable demangled string replacement // Now disable demangled string replacement
// //
options.setUseStandardReplacements(false); options.setUseStandardReplacements(false); // options are still in context
dobj = demangler.demangle(mangled, options); dobj = demangler.demangle(mangledContext);
assertNotNull(dobj); assertNotNull(dobj);
String fullSignature = dobj.getSignature(); String fullSignature = dobj.getSignature();
@ -224,7 +227,9 @@ public class GnuDemanglerTest extends AbstractGenericTest {
demangler.canDemangle(program);// this perform initialization demangler.canDemangle(program);// this perform initialization
GnuDemanglerOptions options = new GnuDemanglerOptions(GnuDemanglerFormat.EDG); 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); assertNull(result);
} }
@ -239,7 +244,9 @@ public class GnuDemanglerTest extends AbstractGenericTest {
GnuDemanglerOptions options = new GnuDemanglerOptions(GnuDemanglerFormat.AUTO, true); GnuDemanglerOptions options = new GnuDemanglerOptions(GnuDemanglerFormat.AUTO, true);
options.setDemangleOnlyKnownPatterns(false); options.setDemangleOnlyKnownPatterns(false);
DemangledObject result = demangler.demangle(mangled, options); MangledContext mangledContext =
demangler.createMangledContext(mangled, options, program, null);
DemangledObject result = demangler.demangle(mangledContext);
assertNotNull(result); assertNotNull(result);
assertEquals("undefined MyFunction::~MyFunction(void)", result.getSignature(false)); assertEquals("undefined MyFunction::~MyFunction(void)", result.getSignature(false));
} }
@ -257,7 +264,9 @@ public class GnuDemanglerTest extends AbstractGenericTest {
GnuDemanglerOptions options = new GnuDemanglerOptions(GnuDemanglerFormat.AUTO, true); GnuDemanglerOptions options = new GnuDemanglerOptions(GnuDemanglerFormat.AUTO, true);
options.setDemangleOnlyKnownPatterns(false); options.setDemangleOnlyKnownPatterns(false);
DemangledObject result = demangler.demangle(mangled, options); MangledContext mangledContext =
demangler.createMangledContext(mangled, options, program, null);
DemangledObject result = demangler.demangle(mangledContext);
assertNotNull(result); assertNotNull(result);
assertEquals("undefined TTextPanel::scroll(unsigned char,short,int)", assertEquals("undefined TTextPanel::scroll(unsigned char,short,int)",
result.getSignature(false)); result.getSignature(false));

View File

@ -48,14 +48,6 @@ public class MicrosoftDemangler implements Demangler {
executableFormat.indexOf(MSCoffLoader.MSCOFF_NAME) != -1); 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 @Override
public DemangledObject demangle(MangledContext context) throws DemangledException { public DemangledObject demangle(MangledContext context) throws DemangledException {
if (!(context instanceof MicrosoftMangledContext mContext)) { if (!(context instanceof MicrosoftMangledContext mContext)) {

View File

@ -89,21 +89,26 @@ public class SwiftDemangler implements Demangler {
} }
@Override @Override
@Deprecated(since = "11.3", forRemoval = true) public DemangledObject demangle(MangledContext context) throws DemangledException {
public DemangledObject demangle(String mangled, DemanglerOptions op) throws DemangledException { SwiftDemanglerOptions options = getSwiftDemanglerOptions(context.getOptions());
SwiftDemanglerOptions options = getSwiftDemanglerOptions(op); String mangled = context.getMangled();
Demangled demangled = getDemangled(mangled, options); Demangled demangled = getDemangled(mangled, options);
DemangledObject demangledObject;
if (demangled instanceof DemangledFunction func) { if (demangled instanceof DemangledFunction func) {
return func; demangledObject = func;
} }
else if (demangled instanceof DemangledLabel label) { else if (demangled instanceof DemangledLabel label) {
return label; demangledObject = label;
} }
else if (demangled instanceof DemangledUnknown unknown) { else if (demangled instanceof DemangledUnknown unknown) {
return new DemangledLabel(mangled, unknown.getOriginalDemangled(), demangledObject = new DemangledLabel(mangled, unknown.getOriginalDemangled(),
options.getUnsupportedPrefix() + unknown.getOriginalDemangled()); options.getUnsupportedPrefix() + unknown.getOriginalDemangled());
} }
return null; else {
return null;
}
demangledObject.setMangledContext(context);
return demangledObject;
} }
/** /**

View File

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -21,8 +21,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import ghidra.app.cmd.label.DemanglerCmd; import ghidra.app.cmd.label.DemanglerCmd;
import ghidra.app.util.demangler.DemangledException; import ghidra.app.util.demangler.*;
import ghidra.app.util.demangler.DemangledObject;
import ghidra.program.database.ProgramDB; import ghidra.program.database.ProgramDB;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.test.AbstractGhidraHeadlessIntegrationTest; import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
@ -62,7 +61,9 @@ public class GnuDemanglerIntegrationTest extends AbstractGhidraHeadlessIntegrati
GnuDemanglerOptions options = new GnuDemanglerOptions(); GnuDemanglerOptions options = new GnuDemanglerOptions();
options.setDemangleOnlyKnownPatterns(false); options.setDemangleOnlyKnownPatterns(false);
options = options.withDemanglerFormat(GnuDemanglerFormat.AUTO, true); 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); assertNotNull(result);
assertEquals("undefined MyNamespace::MyFunction($ParamNamespace::paramName *)", assertEquals("undefined MyNamespace::MyFunction($ParamNamespace::paramName *)",
result.getSignature(false)); result.getSignature(false));
@ -87,7 +88,9 @@ public class GnuDemanglerIntegrationTest extends AbstractGhidraHeadlessIntegrati
GnuDemanglerOptions options = new GnuDemanglerOptions(); GnuDemanglerOptions options = new GnuDemanglerOptions();
options.setDemangleOnlyKnownPatterns(false); options.setDemangleOnlyKnownPatterns(false);
options = options.withDemanglerFormat(GnuDemanglerFormat.AUTO, true); 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); assertNotNull(result);
assertEquals("undefined SoloGimbalEKF::{unnamed_type#1}::SoloGimbalEKF(void)", assertEquals("undefined SoloGimbalEKF::{unnamed_type#1}::SoloGimbalEKF(void)",
result.getSignature(false)); result.getSignature(false));
@ -117,7 +120,9 @@ public class GnuDemanglerIntegrationTest extends AbstractGhidraHeadlessIntegrati
GnuDemanglerOptions options = new GnuDemanglerOptions(); GnuDemanglerOptions options = new GnuDemanglerOptions();
options.setDemangleOnlyKnownPatterns(false); options.setDemangleOnlyKnownPatterns(false);
options = options.withDemanglerFormat(GnuDemanglerFormat.AUTO, true); 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); assertNotNull(result);
assertEquals( 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 &)", "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 &)",