From 740affe799c6a77e22ce3a3a5a9e58f19b0f2a4c Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 23 May 2026 14:58:32 +0000 Subject: [PATCH] Demangle C++ symbols in the symbol table Add a dependency-free Itanium C++ demangler (abi::__cxa_demangle, available in both libstdc++ and libc++) and show a "Demangled" row next to each C++-mangled symbol in the symbol table. Mach-O's extra leading underscore is stripped before demangling; non-C++ names (C, ObjC, Swift) are left untouched. https://claude.ai/code/session_013kBiVXftgoEsyGVyrvfGok --- src/libmoex/base/demangle/Demangle.h | 39 +++++++++++++++++++ .../viewnode/views/SymbolTableViewNode.cpp | 9 ++++- 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/libmoex/base/demangle/Demangle.h diff --git a/src/libmoex/base/demangle/Demangle.h b/src/libmoex/base/demangle/Demangle.h new file mode 100644 index 0000000..f9901ac --- /dev/null +++ b/src/libmoex/base/demangle/Demangle.h @@ -0,0 +1,39 @@ +// +// Created by everettjf +// Copyright © 2017 everettjf. All rights reserved. +// +// C++ (Itanium) symbol demangling via the C++ runtime. No extra dependency: +// abi::__cxa_demangle ships with both libstdc++ and libc++. +#ifndef MOEX_DEMANGLE_H +#define MOEX_DEMANGLE_H + +#include +#include +#include + +namespace moex { namespace demangle { + +// Returns the demangled C++ name, or an empty string if the input is not an +// Itanium-mangled C++ symbol. Mach-O symbols carry an extra leading underscore +// (e.g. `__Z3fooi`), which is stripped before demangling. +inline std::string DemangleCxx(const std::string &name) { + const char *m = name.c_str(); + if (name.size() > 1 && name[0] == '_') { + m = name.c_str() + 1; + } + if (!(m[0] == '_' && m[1] == 'Z')) { + return std::string(); + } + int status = 0; + char *demangled = abi::__cxa_demangle(m, nullptr, nullptr, &status); + std::string out; + if (status == 0 && demangled != nullptr) { + out = demangled; + } + std::free(demangled); + return out; +} + +}} // namespace moex::demangle + +#endif // MOEX_DEMANGLE_H diff --git a/src/libmoex/viewnode/views/SymbolTableViewNode.cpp b/src/libmoex/viewnode/views/SymbolTableViewNode.cpp index 107816e..3eddb08 100644 --- a/src/libmoex/viewnode/views/SymbolTableViewNode.cpp +++ b/src/libmoex/viewnode/views/SymbolTableViewNode.cpp @@ -3,6 +3,7 @@ // #include "SymbolTableViewNode.h" +#include "libmoex/base/demangle/Demangle.h" MOEX_NAMESPACE_BEGIN @@ -16,7 +17,13 @@ void SymbolTableViewNode::InitViewDatas() { return; for(auto & item : seg->nlists_ref()){ - t->AddRow(item->n_strx(),"String Table Index",seg->GetStringByStrX(item->n_strx())); + const std::string name = seg->GetStringByStrX(item->n_strx()); + t->AddRow(item->n_strx(),"String Table Index",name); + + const std::string demangled = moex::demangle::DemangleCxx(name); + if(!demangled.empty()){ + t->AddRow(item->n_strx(),"Demangled",demangled); + } t->AddRow(item->n_type(),"Type",AsShortHexString((uint32_t )item->n_type())); // foreach