mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
GP-7291 - Gnu Demangler - Changed name of global initialization
functions
This commit is contained in:
@@ -17,6 +17,7 @@ package ghidra.app.util.demangler;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import generic.json.Json;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
|
||||
@@ -77,4 +78,8 @@ public class MangledContext {
|
||||
return address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Json.toString(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,12 +120,13 @@ public class GnuDemangler implements Demangler {
|
||||
DemangledObject demangledObject =
|
||||
parse(originalMangled, process, demangled, options);
|
||||
if (demangledObject == null) {
|
||||
return demangledObject;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (globalPrefix != null) {
|
||||
String prefix = translateGlobalPrefix(globalPrefix);
|
||||
DemangledFunction dfunc = new DemangledFunction(originalMangled, demangled,
|
||||
globalPrefix + demangledObject.getName());
|
||||
prefix + demangledObject.getName());
|
||||
dfunc.setNamespace(demangledObject.getNamespace());
|
||||
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) {
|
||||
|
||||
if (options instanceof GnuDemanglerOptions) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package ghidra.app.util.demangler.gnu;
|
||||
|
||||
import generic.json.Json;
|
||||
import ghidra.app.util.demangler.DemanglerOptions;
|
||||
|
||||
/**
|
||||
@@ -83,7 +84,7 @@ public class GnuDemanglerOptions extends DemanglerOptions {
|
||||
public GnuDemanglerOptions(GnuDemanglerFormat format, boolean isDeprecated) {
|
||||
this(format, isDeprecated, GnuDemanglerOptions.DEFAULT_TIMEOUT_SECONDS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor to specify the format to use, whether to prefer the deprecated format when
|
||||
* both deprecated and modern are available, and the timeout
|
||||
@@ -219,16 +220,6 @@ public class GnuDemanglerOptions extends DemanglerOptions {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
//@formatter:off
|
||||
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
|
||||
return Json.toString(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
//
|
||||
|
||||
@@ -150,7 +150,9 @@ public class GnuDemanglerTest extends AbstractGenericTest {
|
||||
|
||||
GnuDemanglerOptions options = new GnuDemanglerOptions();
|
||||
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);
|
||||
|
||||
String signature = dobj.getSignature();
|
||||
@@ -172,7 +174,8 @@ public class GnuDemanglerTest extends AbstractGenericTest {
|
||||
// Now disable demangled string replacement
|
||||
//
|
||||
options.setUseStandardReplacements(false);
|
||||
dobj = (DemangledFunction) demangler.demangle(mangled, options);
|
||||
context = new MangledContext(program, options, mangled, null);
|
||||
dobj = (DemangledFunction) demangler.demangle(context);
|
||||
assertNotNull(dobj);
|
||||
|
||||
String fullSignature = dobj.getSignature();
|
||||
@@ -233,6 +236,29 @@ public class GnuDemanglerTest extends AbstractGenericTest {
|
||||
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
|
||||
public void testDemangleTypeInfoName() throws Exception {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user