GP-7291 - Gnu Demangler - Changed name of global initialization

functions
This commit is contained in:
dragonmacher
2026-09-17 17:47:24 -04:00
parent ebd54fcf52
commit c7600706cd
5 changed files with 51 additions and 17 deletions

View File

@@ -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);
}
}

View File

@@ -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) {

View File

@@ -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);
}
}

View File

@@ -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
//

View File

@@ -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 {