diff options
| author | Mason Reed <mason@vector35.com> | 2025-04-26 20:47:22 -0400 |
|---|---|---|
| committer | Mason Reed <mason@vector35.com> | 2025-04-26 20:47:22 -0400 |
| commit | 51903e9ca5f269979b84ddcc7f5019b492d8b9ff (patch) | |
| tree | 8e2c199a9ed3525fbca5cf493af5e07b057e1e93 /plugins/rtti | |
| parent | 671a0e4ffa70e76f2cc1f4614d8ceaad52bb8bae (diff) | |
Demangle more types in Itanium RTTI
Diffstat (limited to 'plugins/rtti')
| -rw-r--r-- | plugins/rtti/rtti.cpp | 32 |
1 files changed, 21 insertions, 11 deletions
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<std::string> RTTI::DemangleNameGNU3(BinaryView* view, bool allowMa QualifiedName demangledName = {}; Ref<Type> 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 (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(), mangledName, outType, demangledName, true)) + 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<std::string> 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; |
