libsysprof: Support demangling rust symbols using the v0 scheme

This doesn't add support for the legacy symbol mangling scheme which is
currently the default pending support in tools for the v0 symbol
mangling scheme. The legacy symbol mangling scheme is similar enough to
C++'s symbol mangling scheme that demangling them using the C++
demangler generally produces readable symbols. The v0 scheme is entirely
custom and due to backreferences and encoding all generic arguments not
very readable when mangled, so supporting it is more important than
supporting the legacy scheme.
This commit is contained in:
bjorn3
2023-08-31 19:40:46 +02:00
parent 501e35803a
commit 3994635a2a
5 changed files with 1309 additions and 2 deletions

View File

@ -27,6 +27,7 @@
#include "demangle.h"
#include "elfparser.h"
#include "rust-demangle.h"
typedef struct Section Section;
@ -484,7 +485,15 @@ elf_parser_free (ElfParser *parser)
gchar *
elf_demangle (const char *name)
{
gchar *demangled = sysprof_cplus_demangle (name);
/* Try demangling as rust symbol first as legacy rust symbols can demangle as C++ symbols too
* but will only get partially demangled in that case.
*/
gchar *demangled = sysprof_rust_demangle (name, 0);
if (demangled)
return demangled;
demangled = sysprof_cplus_demangle (name);
if (demangled)
return demangled;

View File

@ -1,5 +1,6 @@
libelfparser_sources = [
'demangle.cpp',
'rust-demangle.c',
'elfparser.c',
]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
/*
Imported from https://github.com/LykenSol/rust-demangle.c commit eed29f57732ddb2be434ec89f8ede9b695e5e157
Modifications from upstream:
* Add sysprof_ prefix to exported symbols and mark them as hidden
* Add pragma once
* Use glib begin/end decls
*/
#pragma once
#include <glib.h>
G_BEGIN_DECLS
#include <stdbool.h>
#include <stddef.h>
#define RUST_DEMANGLE_FLAG_VERBOSE 1
G_GNUC_INTERNAL
bool sysprof_rust_demangle_with_callback(
const char *mangled, int flags,
void (*callback)(const char *data, size_t len, void *opaque), void *opaque
);
G_GNUC_INTERNAL
char *sysprof_rust_demangle(const char *mangled, int flags);
G_END_DECLS

View File

@ -434,7 +434,7 @@ sysprof_elf_get_symbol_at_address_internal (SysprofElf *self,
name = elf_parser_get_sym_name (self->parser, symbol);
if (name != NULL && name[0] == '_' && name[1] == 'Z')
if (name != NULL && name[0] == '_' && ((name[1] == 'Z') || (name[1] == 'R')))
ret = elf_demangle (name);
else
ret = g_strdup (name);