Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Ian Rogers and committed by
Arnaldo Carvalho de Melo
3b4e4efe 4c72e2b3

+88 -45
+14 -15
tools/perf/Makefile.config
··· 914 914 endif 915 915 916 916 CFLAGS += -DHAVE_LIBBFD_SUPPORT 917 + CXXFLAGS += -DHAVE_LIBBFD_SUPPORT 917 918 ifeq ($(feature-libbfd-buildid), 1) 918 919 CFLAGS += -DHAVE_LIBBFD_BUILDID_SUPPORT 919 920 else ··· 922 921 endif 923 922 endif 924 923 925 - ifdef NO_DEMANGLE 926 - CFLAGS += -DNO_DEMANGLE 927 - else 924 + ifndef NO_DEMANGLE 925 + $(call feature_check,cxa-demangle) 926 + ifeq ($(feature-cxa-demangle), 1) 927 + EXTLIBS += -lstdc++ 928 + CFLAGS += -DHAVE_CXA_DEMANGLE_SUPPORT 929 + CXXFLAGS += -DHAVE_CXA_DEMANGLE_SUPPORT 930 + endif 928 931 ifdef BUILD_NONDISTRO 929 932 ifeq ($(filter -liberty,$(EXTLIBS)),) 930 - ifdef HAVE_CPLUS_DEMANGLE_SUPPORT 933 + $(call feature_check,cplus-demangle) 934 + ifeq ($(feature-cplus-demangle), 1) 931 935 EXTLIBS += -liberty 932 - else 933 - $(call feature_check,cplus-demangle) 934 - ifeq ($(feature-cplus-demangle), 1) 935 - EXTLIBS += -liberty 936 - endif 937 936 endif 938 937 endif 939 - endif 940 - 941 - ifneq ($(filter -liberty,$(EXTLIBS)),) 942 - CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT 943 - else 944 - CFLAGS += -DNO_DEMANGLE 938 + ifneq ($(filter -liberty,$(EXTLIBS)),) 939 + CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT 940 + CXXFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT 941 + endif 945 942 endif 946 943 endif 947 944
+1
tools/perf/util/Build
··· 211 211 212 212 perf-$(CONFIG_LIBCAP) += cap.o 213 213 214 + perf-y += demangle-cxx.o 214 215 perf-y += demangle-ocaml.o 215 216 perf-y += demangle-java.o 216 217 perf-y += demangle-rust.o
+50
tools/perf/util/demangle-cxx.cpp
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include "demangle-cxx.h" 3 + #include <stdlib.h> 4 + #include <string.h> 5 + #include <linux/compiler.h> 6 + 7 + #ifdef HAVE_LIBBFD_SUPPORT 8 + #define PACKAGE 'perf' 9 + #include <bfd.h> 10 + #endif 11 + 12 + #ifdef HAVE_CXA_DEMANGLE_SUPPORT 13 + #include <cxxabi.h> 14 + #endif 15 + 16 + #if defined(HAVE_LIBBFD_SUPPORT) || defined(HAVE_CPLUS_DEMANGLE_SUPPORT) 17 + #ifndef DMGL_PARAMS 18 + #define DMGL_PARAMS (1 << 0) /* Include function args */ 19 + #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ 20 + #endif 21 + #endif 22 + 23 + /* 24 + * Demangle C++ function signature 25 + * 26 + * Note: caller is responsible for freeing demangled string 27 + */ 28 + extern "C" 29 + char *cxx_demangle_sym(const char *str, bool params __maybe_unused, 30 + bool modifiers __maybe_unused) 31 + { 32 + #ifdef HAVE_LIBBFD_SUPPORT 33 + int flags = (params ? DMGL_PARAMS : 0) | (modifiers ? DMGL_ANSI : 0); 34 + 35 + return bfd_demangle(NULL, str, flags); 36 + #elif defined(HAVE_CPLUS_DEMANGLE_SUPPORT) 37 + int flags = (params ? DMGL_PARAMS : 0) | (modifiers ? DMGL_ANSI : 0); 38 + 39 + return cplus_demangle(str, flags); 40 + #elif defined(HAVE_CXA_DEMANGLE_SUPPORT) 41 + size_t len = strlen(str); 42 + char *output = (char*)malloc(len); 43 + int status; 44 + 45 + output = abi::__cxa_demangle(str, output, &len, &status); 46 + return output; 47 + #else 48 + return NULL; 49 + #endif 50 + }
+16
tools/perf/util/demangle-cxx.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __PERF_DEMANGLE_CXX 3 + #define __PERF_DEMANGLE_CXX 1 4 + 5 + #ifdef __cplusplus 6 + extern "C" { 7 + #endif 8 + 9 + char *cxx_demangle_sym(const char *str, bool params, bool modifiers); 10 + 11 + #ifdef __cplusplus 12 + } 13 + #endif 14 + 15 + 16 + #endif /* __PERF_DEMANGLE_CXX */
+7 -30
tools/perf/util/symbol-elf.c
··· 12 12 #include "maps.h" 13 13 #include "symbol.h" 14 14 #include "symsrc.h" 15 + #include "demangle-cxx.h" 15 16 #include "demangle-ocaml.h" 16 17 #include "demangle-java.h" 17 18 #include "demangle-rust.h" ··· 25 24 #include <linux/zalloc.h> 26 25 #include <symbol/kallsyms.h> 27 26 #include <internal/lib.h> 27 + 28 + #ifdef HAVE_LIBBFD_SUPPORT 29 + #define PACKAGE 'perf' 30 + #include <bfd.h> 31 + #endif 28 32 29 33 #ifndef EM_AARCH64 30 34 #define EM_AARCH64 183 /* ARM 64 bit */ ··· 51 45 52 46 typedef Elf64_Nhdr GElf_Nhdr; 53 47 54 - #ifndef DMGL_PARAMS 55 - #define DMGL_NO_OPTS 0 /* For readability... */ 56 - #define DMGL_PARAMS (1 << 0) /* Include function args */ 57 - #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ 58 - #endif 59 - 60 - #ifdef HAVE_LIBBFD_SUPPORT 61 - #define PACKAGE 'perf' 62 - #include <bfd.h> 63 - #else 64 - #ifdef HAVE_CPLUS_DEMANGLE_SUPPORT 65 - extern char *cplus_demangle(const char *, int); 66 - 67 - static inline char *bfd_demangle(void __maybe_unused *v, const char *c, int i) 68 - { 69 - return cplus_demangle(c, i); 70 - } 71 - #else 72 - #ifdef NO_DEMANGLE 73 - static inline char *bfd_demangle(void __maybe_unused *v, 74 - const char __maybe_unused *c, 75 - int __maybe_unused i) 76 - { 77 - return NULL; 78 - } 79 - #endif 80 - #endif 81 - #endif 82 48 83 49 #ifndef HAVE_ELF_GETPHDRNUM_SUPPORT 84 50 static int elf_getphdrnum(Elf *elf, size_t *dst) ··· 273 295 274 296 static char *demangle_sym(struct dso *dso, int kmodule, const char *elf_name) 275 297 { 276 - int demangle_flags = verbose > 0 ? (DMGL_PARAMS | DMGL_ANSI) : DMGL_NO_OPTS; 277 298 char *demangled = NULL; 278 299 279 300 /* ··· 283 306 if (!want_demangle(dso->kernel || kmodule)) 284 307 return demangled; 285 308 286 - demangled = bfd_demangle(NULL, elf_name, demangle_flags); 309 + demangled = cxx_demangle_sym(elf_name, verbose > 0, verbose > 0); 287 310 if (demangled == NULL) { 288 311 demangled = ocaml_demangle_sym(elf_name); 289 312 if (demangled == NULL) {