summaryrefslogtreecommitdiff
path: root/plugins/rtti
diff options
context:
space:
mode:
authorMason Reed <mason@vector35.com>2025-04-26 20:47:22 -0400
committerMason Reed <mason@vector35.com>2025-04-26 20:47:22 -0400
commit51903e9ca5f269979b84ddcc7f5019b492d8b9ff (patch)
tree8e2c199a9ed3525fbca5cf493af5e07b057e1e93 /plugins/rtti
parent671a0e4ffa70e76f2cc1f4614d8ceaad52bb8bae (diff)
Demangle more types in Itanium RTTI
Diffstat (limited to 'plugins/rtti')
-rw-r--r--plugins/rtti/rtti.cpp32
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;