From 51903e9ca5f269979b84ddcc7f5019b492d8b9ff Mon Sep 17 00:00:00 2001 From: Mason Reed Date: Sat, 26 Apr 2025 20:47:22 -0400 Subject: Demangle more types in Itanium RTTI --- plugins/rtti/rtti.cpp | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'plugins/rtti/rtti.cpp') diff --git a/plugins/rtti/rtti.cpp b/plugins/rtti/rtti.cpp index f0cde410..3f6abe94 100644 --- a/plugins/rtti/rtti.cpp +++ b/plugins/rtti/rtti.cpp @@ -19,18 +19,30 @@ std::optional RTTI::DemangleNameGNU3(BinaryView* view, bool allowMa QualifiedName demangledName = {}; Ref outType = {}; - // TODO: This is disabled because most of the uses of this were making the problem worse by demangling - // TODO: To a very generic string that dozens of classes would then look like. We likely need to add some extra - // TODO: sauce to the demangler to pickup strings like: - // TODO: REAL: PackageListGui::PackageListGui(Filesystem::Path&&, PackageListGui::UnderSubheader, bool)::$_1[0x0] - // TODO: OURS: PackageListGui::PackageListGui - // TODO: OURS MANGLED: ZN14PackageListGuiC1EON10Filesystem4PathENS_14UnderSubheaderEbE3$_1 + std::string adjustedMangledName = mangledName; // For some reason some of the names that start with ZN are not prefixed by `_`. - // if (mangled.find("ZN") == 0) - // mangled = "_" + mangled; - - if (!DemangleGNU3(view->GetDefaultArchitecture(), mangledName, outType, demangledName, true)) + if (adjustedMangledName.find("ZN") == 0) + adjustedMangledName = "_" + adjustedMangledName; + // Sometimes some std types will have a * prefixed, IDK what it means, but we need to remove it to demangle. + if (adjustedMangledName.find("*N") == 0) + adjustedMangledName = adjustedMangledName.substr(1); + // All types at this point should have a _Z prefix, if not, we likely need to just call the demangler directly, as this + // function is specific to dealing with mangled _type_ names. + if (adjustedMangledName.find("_Z") != 0) + adjustedMangledName = "_Z" + adjustedMangledName; + + if (!DemangleGNU3(view->GetDefaultArchitecture(), adjustedMangledName, outType, demangledName, true)) return allowMangled ? std::optional(mangledName) : std::nullopt; + + // Because we might have a generic name such as "PackageListGui::PackageListGui" returned, we must attempt to + // stringify the returned type IF its function type and then append that to the end of the demangled name. + // REAL: PackageListGui::PackageListGui(Filesystem::Path&&, PackageListGui::UnderSubheader, bool)::$_1[0x0] + // MANGLED: ZN14PackageListGuiC1EON10Filesystem4PathENS_14UnderSubheaderEbE3$_1 + // GENERIC DEMANGLED: PackageListGui::PackageListGui + // UPDATED DEMANGLED: PackageListGui::PackageListGui(Filesystem::Path&&, PackageListGui::UnderSubheader, bool) + if (outType && outType->IsFunction()) + demangledName.push_back(outType->GetStringAfterName(view->GetDefaultPlatform())); + return demangledName.GetString(); } @@ -38,8 +50,6 @@ std::optional RTTI::DemangleNameGNU3(BinaryView* view, bool allowMa std::string RemoveItaniumPrefix(std::string &name) { // Remove numerical prefixes. - // TODO: We might want to use the numbers for figuring out the class info. - // TODO: NSt6locale5facetE is not demangled. N and St seem to be prefixes. while (!name.empty() && std::isdigit(name[0])) name = name.substr(1); return name; -- cgit v1.3.1