mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
Merge remote-tracking branch 'origin/GP-7291-dragonmacher-gnu-demangler-global-init-function'
This commit is contained in:
@@ -17,6 +17,7 @@ package ghidra.app.util.demangler;
|
|||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import generic.json.Json;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
|
|
||||||
@@ -77,4 +78,8 @@ public class MangledContext {
|
|||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Json.toString(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,12 +120,13 @@ public class GnuDemangler implements Demangler {
|
|||||||
DemangledObject demangledObject =
|
DemangledObject demangledObject =
|
||||||
parse(originalMangled, process, demangled, options);
|
parse(originalMangled, process, demangled, options);
|
||||||
if (demangledObject == null) {
|
if (demangledObject == null) {
|
||||||
return demangledObject;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globalPrefix != null) {
|
if (globalPrefix != null) {
|
||||||
|
String prefix = translateGlobalPrefix(globalPrefix);
|
||||||
DemangledFunction dfunc = new DemangledFunction(originalMangled, demangled,
|
DemangledFunction dfunc = new DemangledFunction(originalMangled, demangled,
|
||||||
globalPrefix + demangledObject.getName());
|
prefix + demangledObject.getName());
|
||||||
dfunc.setNamespace(demangledObject.getNamespace());
|
dfunc.setNamespace(demangledObject.getNamespace());
|
||||||
demangledObject = dfunc;
|
demangledObject = dfunc;
|
||||||
}
|
}
|
||||||
@@ -152,6 +153,17 @@ public class GnuDemangler implements Demangler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String translateGlobalPrefix(String globalPrefix) {
|
||||||
|
|
||||||
|
return switch (globalPrefix) {
|
||||||
|
case "_GLOBAL__sub_I_" -> "global_init_constructor_";
|
||||||
|
case "_GLOBAL__sub_D_" -> "global_destructor_";
|
||||||
|
// case "_GLOBAL__N_" // anonymous namespace; only seen inside mangled text
|
||||||
|
// case "_GLOBAL__sub_G__" // debugging info; not seen in the wild
|
||||||
|
default -> globalPrefix;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private GnuDemanglerOptions getGnuOptions(DemanglerOptions options) {
|
private GnuDemanglerOptions getGnuOptions(DemanglerOptions options) {
|
||||||
|
|
||||||
if (options instanceof GnuDemanglerOptions) {
|
if (options instanceof GnuDemanglerOptions) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.app.util.demangler.gnu;
|
package ghidra.app.util.demangler.gnu;
|
||||||
|
|
||||||
|
import generic.json.Json;
|
||||||
import ghidra.app.util.demangler.DemanglerOptions;
|
import ghidra.app.util.demangler.DemanglerOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,7 +84,7 @@ public class GnuDemanglerOptions extends DemanglerOptions {
|
|||||||
public GnuDemanglerOptions(GnuDemanglerFormat format, boolean isDeprecated) {
|
public GnuDemanglerOptions(GnuDemanglerFormat format, boolean isDeprecated) {
|
||||||
this(format, isDeprecated, GnuDemanglerOptions.DEFAULT_TIMEOUT_SECONDS);
|
this(format, isDeprecated, GnuDemanglerOptions.DEFAULT_TIMEOUT_SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor to specify the format to use, whether to prefer the deprecated format when
|
* Constructor to specify the format to use, whether to prefer the deprecated format when
|
||||||
* both deprecated and modern are available, and the timeout
|
* both deprecated and modern are available, and the timeout
|
||||||
@@ -219,16 +220,6 @@ public class GnuDemanglerOptions extends DemanglerOptions {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
//@formatter:off
|
return Json.toString(this);
|
||||||
return "{\n" +
|
|
||||||
"\tdoDisassembly: " + doDisassembly() + ",\n" +
|
|
||||||
"\tapplySignature: " + applySignature() + ",\n" +
|
|
||||||
"\tuseStandardReplacements: " + useStandardReplacements + ",\n" +
|
|
||||||
"\tdemangleOnlyKnownPatterns: " + demangleOnlyKnownPatterns() + ",\n" +
|
|
||||||
"\ttimeout (sec): " + timeout + ",\n" +
|
|
||||||
"\tdemanglerName: " + getDemanglerName() + ",\n" +
|
|
||||||
"\tdemanglerApplicationArguments: " + getDemanglerApplicationArguments() + ",\n" +
|
|
||||||
"}";
|
|
||||||
//@formatter:on
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1410,7 +1410,7 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
|
|||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Mangled: _ZN12_GLOBAL__N_120decode_charset_iconvEPKc
|
// Mangled: _ZNK17GCC_IndicationPDUcvRK31GCC_ApplicationInvokeIndicationEv
|
||||||
//
|
//
|
||||||
// Demangled: GCC_IndicationPDU::operator GCC_ApplicationInvokeIndication const&() const
|
// Demangled: GCC_IndicationPDU::operator GCC_ApplicationInvokeIndication const&() const
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -150,7 +150,9 @@ public class GnuDemanglerTest extends AbstractGenericTest {
|
|||||||
|
|
||||||
GnuDemanglerOptions options = new GnuDemanglerOptions();
|
GnuDemanglerOptions options = new GnuDemanglerOptions();
|
||||||
options.setUseStandardReplacements(true);
|
options.setUseStandardReplacements(true);
|
||||||
DemangledFunction dobj = (DemangledFunction) demangler.demangle(mangled, options);
|
MangledContext context = new MangledContext(program, options, mangled, null);
|
||||||
|
|
||||||
|
DemangledFunction dobj = (DemangledFunction) demangler.demangle(context);
|
||||||
assertNotNull(dobj);
|
assertNotNull(dobj);
|
||||||
|
|
||||||
String signature = dobj.getSignature();
|
String signature = dobj.getSignature();
|
||||||
@@ -172,7 +174,8 @@ public class GnuDemanglerTest extends AbstractGenericTest {
|
|||||||
// Now disable demangled string replacement
|
// Now disable demangled string replacement
|
||||||
//
|
//
|
||||||
options.setUseStandardReplacements(false);
|
options.setUseStandardReplacements(false);
|
||||||
dobj = (DemangledFunction) demangler.demangle(mangled, options);
|
context = new MangledContext(program, options, mangled, null);
|
||||||
|
dobj = (DemangledFunction) demangler.demangle(context);
|
||||||
assertNotNull(dobj);
|
assertNotNull(dobj);
|
||||||
|
|
||||||
String fullSignature = dobj.getSignature();
|
String fullSignature = dobj.getSignature();
|
||||||
@@ -233,6 +236,29 @@ public class GnuDemanglerTest extends AbstractGenericTest {
|
|||||||
assertTrue(d.isPointer());
|
assertTrue(d.isPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGlobalInitializationFunction() throws Exception {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Mangled: _GLOBAL__sub_I__ZN6ghidra8ATTRIB_AE
|
||||||
|
|
||||||
|
We parse this as a DemangledVariable. We then us the '_GLOBAL__sub_I_' prefix as
|
||||||
|
a signal that the symbol represents a global initialization constructor. We then
|
||||||
|
convert the variable to a DemangledFunction.
|
||||||
|
|
||||||
|
Signature: ghidra::global_init_constructor_ATTRIB_A(void)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
String mangled = "_GLOBAL__sub_I__ZN6ghidra8ATTRIB_AE";
|
||||||
|
|
||||||
|
GnuDemangler demangler = new GnuDemangler();
|
||||||
|
DemangledFunction obj = (DemangledFunction) demangler.demangle(mangled);
|
||||||
|
|
||||||
|
String signature = obj.getSignature();
|
||||||
|
assertEquals("ghidra::global_init_constructor_ATTRIB_A(void)", signature);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDemangleTypeInfoName() throws Exception {
|
public void testDemangleTypeInfoName() throws Exception {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user