Skip to content

Commit

Permalink
demumble swift symbols as well
Browse files Browse the repository at this point in the history
  • Loading branch information
nico committed Aug 5, 2024
1 parent 21ad9a0 commit b300620
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
32 changes: 31 additions & 1 deletion demumble.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <algorithm>

#include "llvm/Demangle/Demangle.h"
#include "swift/Demangling/Demangle.h"

const char kDemumbleVersion[] = "1.2.3.git";

Expand Down Expand Up @@ -33,6 +34,14 @@ static void print_demangled(const char* format, std::string_view s,
} else if (char* ms = llvm::microsoftDemangle(s, n_used, NULL)) {
printf(format, ms, (int)s.size(), s.data());
free(ms);
} else if (swift::Demangle::isSwiftSymbol(s)) {
swift::Demangle::DemangleOptions options;
options.SynthesizeSugarOnTypes = true;
std::string swift = swift::Demangle::demangleSymbolAsString(s, options);
if (swift == s)
printf("%.*s", (int)s.size(), s.data()); // Not a mangled name
else
printf(format, swift.c_str(), (int)s.size(), s.data());
} else {
printf("%.*s", (int)s.size(), s.data());
}
Expand All @@ -49,6 +58,12 @@ static bool is_mangle_char_rust(char c) {
(c >= '0' && c <= '9') || c == '_';
}

static bool is_mangle_char_swift(char c) {
// https://github.com/swiftlang/swift/blob/main/docs/ABI/Mangling.rst
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') || c == '_' || c == '$';
}

static bool is_mangle_char_win(char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') || strchr("?_@$", c);
Expand All @@ -68,6 +83,18 @@ static bool is_plausible_rust_prefix(char* s) {
return s[0] == '_' && s[1] == 'R';
}

static bool is_plausible_swift_prefix(char* s) {
// https://github.com/swiftlang/swift/blob/main/docs/ABI/Mangling.rst
// But also swift/test/Demangle/Inputs/manglings.txt, which has
// _Tt, _TF etc as prefix.

// FIXME: This is missing prefix `@__swiftmacro_`.
return
(s[0] == '$' && s[1] == 's') ||
(s[0] == '_' && s[1] == 'T') ||
(s[0] == '$' && s[1] == 'S');
}

static char buf[8192];
int main(int argc, char* argv[]) {
enum { kPrintAll, kPrintMatching } print_mode = kPrintAll;
Expand Down Expand Up @@ -119,7 +146,7 @@ int main(int argc, char* argv[]) {
char* end = cur + strlen(cur);

while (cur != end) {
size_t offset_to_possible_symbol = strcspn(cur, "_?");
size_t offset_to_possible_symbol = strcspn(cur, "_?$");
if (print_mode == kPrintAll)
printf("%.*s", static_cast<int>(offset_to_possible_symbol), cur);
else if (need_separator)
Expand All @@ -139,6 +166,9 @@ int main(int argc, char* argv[]) {
else if (is_plausible_rust_prefix(cur))
while (cur + n_sym != end && is_mangle_char_rust(cur[n_sym]))
++n_sym;
else if (is_plausible_swift_prefix(cur))
while (cur + n_sym != end && is_mangle_char_swift(cur[n_sym]))
++n_sym;
else {
if (print_mode == kPrintAll)
printf("_");
Expand Down
4 changes: 4 additions & 0 deletions demumble_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
'std::mem::align_of::<f64>\nmylib::foo::bar\n'),
('demumble < _RINvNtC3std3mem8align_ofdE _RNvNvC5mylib3foo3bar',
'std::mem::align_of::<f64>\nmylib::foo::bar\n'),
('demumble _TtP3foo3bar_', 'foo.bar\n'),
('demumble < _TtP3foo3bar_', 'foo.bar\n'),
('demumble $sSS5countSivg', 'Swift.String.count.getter : Swift.Int\n'),
('demumble < $sSS5countSivg', 'Swift.String.count.getter : Swift.Int\n'),
('demumble ?Fxi@@YAHP6AHH@Z@Z', 'int __cdecl Fxi(int (__cdecl *)(int))\n'),
('demumble ??0S@@QEAA@$$QEAU0@@Z', 'public: __cdecl S::S(struct S &&)\n'),
('demumble ??_C@_02PCEFGMJL@hi?$AA@', '"hi"\n'),
Expand Down

0 comments on commit b300620

Please sign in to comment.