perf symbol: Add abi::__cxa_demangle C++ demangling support

Refactor C++ demangling out of symbol-elf into its own files similar
to other languages. Add abi::__cxa_demangle support. As the other
demanglers are not shippable with distributions, this brings back C++
demangling in a common case. It isn't perfect as the support for
optionally demangling arguments and modifiers isn't present.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andres Freund <andres@anarazel.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Martin Liška <mliska@suse.cz>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Pavithra Gurushankar <gpavithrasha@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Quentin Monnet <quentin@isovalent.com>
Cc: Roberto Sassu <roberto.sassu@huawei.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tiezhu Yang <yangtiezhu@loongson.cn>
Cc: Tom Rix <trix@redhat.com>
Cc: Yang Jihong <yangjihong1@huawei.com>
Cc: llvm@lists.linux.dev
Link: https://lore.kernel.org/r/20230311065753.3012826-2-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Ian Rogers 2023-03-10 22:57:49 -08:00 committed by Arnaldo Carvalho de Melo
parent 4c72e2b35a
commit 3b4e4efe88
5 changed files with 88 additions and 45 deletions

View File

@ -914,6 +914,7 @@ ifdef BUILD_NONDISTRO
endif endif
CFLAGS += -DHAVE_LIBBFD_SUPPORT CFLAGS += -DHAVE_LIBBFD_SUPPORT
CXXFLAGS += -DHAVE_LIBBFD_SUPPORT
ifeq ($(feature-libbfd-buildid), 1) ifeq ($(feature-libbfd-buildid), 1)
CFLAGS += -DHAVE_LIBBFD_BUILDID_SUPPORT CFLAGS += -DHAVE_LIBBFD_BUILDID_SUPPORT
else else
@ -921,26 +922,24 @@ ifdef BUILD_NONDISTRO
endif endif
endif endif
ifdef NO_DEMANGLE ifndef NO_DEMANGLE
CFLAGS += -DNO_DEMANGLE $(call feature_check,cxa-demangle)
else ifeq ($(feature-cxa-demangle), 1)
EXTLIBS += -lstdc++
CFLAGS += -DHAVE_CXA_DEMANGLE_SUPPORT
CXXFLAGS += -DHAVE_CXA_DEMANGLE_SUPPORT
endif
ifdef BUILD_NONDISTRO ifdef BUILD_NONDISTRO
ifeq ($(filter -liberty,$(EXTLIBS)),) ifeq ($(filter -liberty,$(EXTLIBS)),)
ifdef HAVE_CPLUS_DEMANGLE_SUPPORT $(call feature_check,cplus-demangle)
ifeq ($(feature-cplus-demangle), 1)
EXTLIBS += -liberty EXTLIBS += -liberty
else
$(call feature_check,cplus-demangle)
ifeq ($(feature-cplus-demangle), 1)
EXTLIBS += -liberty
endif
endif endif
endif endif
endif ifneq ($(filter -liberty,$(EXTLIBS)),)
CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT
ifneq ($(filter -liberty,$(EXTLIBS)),) CXXFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT
CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT endif
else
CFLAGS += -DNO_DEMANGLE
endif endif
endif endif

View File

@ -211,6 +211,7 @@ perf-$(CONFIG_ZSTD) += zstd.o
perf-$(CONFIG_LIBCAP) += cap.o perf-$(CONFIG_LIBCAP) += cap.o
perf-y += demangle-cxx.o
perf-y += demangle-ocaml.o perf-y += demangle-ocaml.o
perf-y += demangle-java.o perf-y += demangle-java.o
perf-y += demangle-rust.o perf-y += demangle-rust.o

View File

@ -0,0 +1,50 @@
// SPDX-License-Identifier: GPL-2.0
#include "demangle-cxx.h"
#include <stdlib.h>
#include <string.h>
#include <linux/compiler.h>
#ifdef HAVE_LIBBFD_SUPPORT
#define PACKAGE 'perf'
#include <bfd.h>
#endif
#ifdef HAVE_CXA_DEMANGLE_SUPPORT
#include <cxxabi.h>
#endif
#if defined(HAVE_LIBBFD_SUPPORT) || defined(HAVE_CPLUS_DEMANGLE_SUPPORT)
#ifndef DMGL_PARAMS
#define DMGL_PARAMS (1 << 0) /* Include function args */
#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
#endif
#endif
/*
* Demangle C++ function signature
*
* Note: caller is responsible for freeing demangled string
*/
extern "C"
char *cxx_demangle_sym(const char *str, bool params __maybe_unused,
bool modifiers __maybe_unused)
{
#ifdef HAVE_LIBBFD_SUPPORT
int flags = (params ? DMGL_PARAMS : 0) | (modifiers ? DMGL_ANSI : 0);
return bfd_demangle(NULL, str, flags);
#elif defined(HAVE_CPLUS_DEMANGLE_SUPPORT)
int flags = (params ? DMGL_PARAMS : 0) | (modifiers ? DMGL_ANSI : 0);
return cplus_demangle(str, flags);
#elif defined(HAVE_CXA_DEMANGLE_SUPPORT)
size_t len = strlen(str);
char *output = (char*)malloc(len);
int status;
output = abi::__cxa_demangle(str, output, &len, &status);
return output;
#else
return NULL;
#endif
}

View File

@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __PERF_DEMANGLE_CXX
#define __PERF_DEMANGLE_CXX 1
#ifdef __cplusplus
extern "C" {
#endif
char *cxx_demangle_sym(const char *str, bool params, bool modifiers);
#ifdef __cplusplus
}
#endif
#endif /* __PERF_DEMANGLE_CXX */

View File

@ -12,6 +12,7 @@
#include "maps.h" #include "maps.h"
#include "symbol.h" #include "symbol.h"
#include "symsrc.h" #include "symsrc.h"
#include "demangle-cxx.h"
#include "demangle-ocaml.h" #include "demangle-ocaml.h"
#include "demangle-java.h" #include "demangle-java.h"
#include "demangle-rust.h" #include "demangle-rust.h"
@ -25,6 +26,11 @@
#include <symbol/kallsyms.h> #include <symbol/kallsyms.h>
#include <internal/lib.h> #include <internal/lib.h>
#ifdef HAVE_LIBBFD_SUPPORT
#define PACKAGE 'perf'
#include <bfd.h>
#endif
#ifndef EM_AARCH64 #ifndef EM_AARCH64
#define EM_AARCH64 183 /* ARM 64 bit */ #define EM_AARCH64 183 /* ARM 64 bit */
#endif #endif
@ -45,34 +51,6 @@
typedef Elf64_Nhdr GElf_Nhdr; typedef Elf64_Nhdr GElf_Nhdr;
#ifndef DMGL_PARAMS
#define DMGL_NO_OPTS 0 /* For readability... */
#define DMGL_PARAMS (1 << 0) /* Include function args */
#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
#endif
#ifdef HAVE_LIBBFD_SUPPORT
#define PACKAGE 'perf'
#include <bfd.h>
#else
#ifdef HAVE_CPLUS_DEMANGLE_SUPPORT
extern char *cplus_demangle(const char *, int);
static inline char *bfd_demangle(void __maybe_unused *v, const char *c, int i)
{
return cplus_demangle(c, i);
}
#else
#ifdef NO_DEMANGLE
static inline char *bfd_demangle(void __maybe_unused *v,
const char __maybe_unused *c,
int __maybe_unused i)
{
return NULL;
}
#endif
#endif
#endif
#ifndef HAVE_ELF_GETPHDRNUM_SUPPORT #ifndef HAVE_ELF_GETPHDRNUM_SUPPORT
static int elf_getphdrnum(Elf *elf, size_t *dst) static int elf_getphdrnum(Elf *elf, size_t *dst)
@ -295,7 +273,6 @@ static bool want_demangle(bool is_kernel_sym)
static char *demangle_sym(struct dso *dso, int kmodule, const char *elf_name) static char *demangle_sym(struct dso *dso, int kmodule, const char *elf_name)
{ {
int demangle_flags = verbose > 0 ? (DMGL_PARAMS | DMGL_ANSI) : DMGL_NO_OPTS;
char *demangled = NULL; char *demangled = NULL;
/* /*
@ -306,7 +283,7 @@ static char *demangle_sym(struct dso *dso, int kmodule, const char *elf_name)
if (!want_demangle(dso->kernel || kmodule)) if (!want_demangle(dso->kernel || kmodule))
return demangled; return demangled;
demangled = bfd_demangle(NULL, elf_name, demangle_flags); demangled = cxx_demangle_sym(elf_name, verbose > 0, verbose > 0);
if (demangled == NULL) { if (demangled == NULL) {
demangled = ocaml_demangle_sym(elf_name); demangled = ocaml_demangle_sym(elf_name);
if (demangled == NULL) { if (demangled == NULL) {