diff --git a/Ghidra/Features/GnuDemangler/data/default.gnu.demangler.replacements.txt b/Ghidra/Features/GnuDemangler/data/default.gnu.demangler.replacements.txt index c14eb6d242..96b23f3d81 100644 --- a/Ghidra/Features/GnuDemangler/data/default.gnu.demangler.replacements.txt +++ b/Ghidra/Features/GnuDemangler/data/default.gnu.demangler.replacements.txt @@ -28,14 +28,14 @@ // // -// Note: these have been disabled. Some binaries have a class namespace with the same name in more -// than one namespace that may include these values. In that case, if we drop these values, then -// instead of 2 distinct namespaces, we will have only 1, which is incorrect. If we decide that +// Note: some of these have been disabled. Some binaries have a class namespace with the same name +// in more than one namespace that may include these values. In that case, if we drop these values, +// then instead of 2 distinct namespaces, we will have only 1, which is incorrect. If we decide that // these values are not desired, then we will have to figure out a way to create 2 distinct // namespaces after we apply the simplification. // // current tests show this is a non-leading mangled namespace placeholder -//"" ::__1 +"" ::__1 // current tests show this is a non-leading mangled namespace placeholder //"" ::__cxx11 diff --git a/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerParser.java b/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerParser.java index bdc59032e7..5af4da0d8a 100644 --- a/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerParser.java +++ b/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerParser.java @@ -1550,17 +1550,16 @@ public class GnuDemanglerParser { for (ResourceFile file : files) { List lines = getReplacementLines(file); for (String line : lines) { - GnuDemanglerReplacement replacement = parseReplacement(line, file); - if (replacement != null) { - results.add(replacement); - } + parseReplacement(line, file, results); } } return results; } - private static GnuDemanglerReplacement parseReplacement(String line, ResourceFile file) { + private static void parseReplacement(String line, ResourceFile file, + List results) { + for (int i = 0; i < line.length(); i++) { char c = line.charAt(i); if (Character.isWhitespace(c)) { @@ -1572,13 +1571,35 @@ public class GnuDemanglerParser { } String find = line.substring(i).trim(); - return new GnuDemanglerReplacement(find, replace, file); + results.add(new GnuDemanglerReplacement(find, replace, file)); + + // + // We have disabled some global text replacements. Instead of globally replacing + // them, we will update each replacement to handle the special case when it starts + // at the beginning of the replacement. + // + createAlternateReplacement("std::__cxx11::", find, replace, file, results); + createAlternateReplacement("__gnu_cxx::", find, replace, file, results); + + return; } } Msg.warn(GnuDemanglerParser.class, "Malformed replacement line. No spaces found: " + line + ". In file: " + file); - return null; + } + + private static void createAlternateReplacement(String alternate, String find, String replace, + ResourceFile file, List results) { + + if (!(find.startsWith("std::") && replace.startsWith("std::"))) { + return; + } + + String altFind = find.replaceFirst("std::", alternate); + String altReplace = replace.replaceFirst("std::", alternate); + results.add(new GnuDemanglerReplacement(altFind, altReplace, file)); + } private static List getReplacementLines(ResourceFile file) { diff --git a/Ghidra/Features/GnuDemangler/src/test/java/ghidra/app/util/demangler/GnuDemanglerParserTest.java b/Ghidra/Features/GnuDemangler/src/test/java/ghidra/app/util/demangler/GnuDemanglerParserTest.java index 1dae049b18..5974df1858 100644 --- a/Ghidra/Features/GnuDemangler/src/test/java/ghidra/app/util/demangler/GnuDemanglerParserTest.java +++ b/Ghidra/Features/GnuDemangler/src/test/java/ghidra/app/util/demangler/GnuDemanglerParserTest.java @@ -197,15 +197,15 @@ public class GnuDemanglerParserTest extends AbstractGenericTest { List parameters = function.getParameters(); assertEquals( - "__insertion_sort<__normal_iterator*,std::vector,std::allocator>>>,bool(*)(std::pairconst&,std::pairconst&)>", + "__insertion_sort<__gnu_cxx::__normal_iterator*,std::vector,std::allocator>>>,bool(*)(std::pairconst&,std::pairconst&)>", function.getName()); assertEquals("std", function.getNamespace().getName()); assertEquals( - "__normal_iterator *,std::vector,std::allocator>>>", + "__gnu_cxx::__normal_iterator *,std::vector,std::allocator>>>", parameters.get(0).toString()); assertEquals( - "__normal_iterator *,std::vector,std::allocator>>>", + "__gnu_cxx::__normal_iterator *,std::vector,std::allocator>>>", parameters.get(1).toString()); assertEquals( "bool (*)(std::pair const &,std::pair const &)", @@ -1112,7 +1112,7 @@ public class GnuDemanglerParserTest extends AbstractGenericTest { String signature = object.getSignature(false); assertEquals( - "std::string std::_Bind::operator()(void)", + "std::__cxx11::string std::_Bind::operator()(void)", signature); } @@ -1145,7 +1145,7 @@ public class GnuDemanglerParserTest extends AbstractGenericTest { String signature = object.getSignature(false); assertEquals( - "std::string gsl::to_string(gsl::basic_string_span)", + "std::__cxx11::string gsl::to_string(gsl::basic_string_span)", signature); } @@ -1630,7 +1630,7 @@ public class GnuDemanglerParserTest extends AbstractGenericTest { "vector,std::allocator>>"); assertEquals( - "undefined std::vector,std::allocator>>::_M_insert_aux(__normal_iterator *,std::vector,std::allocator>>>,boost::function const &)", + "undefined std::vector,std::allocator>>::_M_insert_aux(__gnu_cxx::__normal_iterator *,std::vector,std::allocator>>>,boost::function const &)", object.getSignature(false)); } @@ -1770,7 +1770,7 @@ public class GnuDemanglerParserTest extends AbstractGenericTest { String signature = object.getSignature(false); assertEquals("undefined " + - "__stoa(long(*)(char_const*,char**,int),char_const*,char_const*,unsigned_long*,int)" + + "__gnu_cxx::__stoa(long(*)(char_const*,char**,int),char_const*,char_const*,unsigned_long*,int)" + "::_Save_errno::_Save_errno(void)", signature); } 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 d879f51270..2214781c7c 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 @@ -154,14 +154,14 @@ public class GnuDemanglerTest extends AbstractGenericTest { assertNotNull(dobj); String signature = dobj.getSignature(); - assertEquals("undefined Greeter::greet(std::string)", signature); + assertEquals("undefined Greeter::greet(std::__cxx11::string)", signature); DemangledParameter demangledParameter = dobj.getParameters().get(0); DemangledDataType type = demangledParameter.getType(); DataType dt = type.getDataType(program.getDataTypeManager()); assertTrue(dt.isNotYetDefined()); //@formatter:off - assertEquals("/Demangler/std/string\n" + + assertEquals("/Demangler/std/__cxx11/string\n" + "pack(disabled)\n" + "Structure string {\n" + "}\n" +