diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index c4ae70c643b9..ac8a206acf87 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -914,6 +914,7 @@ ifdef BUILD_NONDISTRO endif CFLAGS += -DHAVE_LIBBFD_SUPPORT + CXXFLAGS += -DHAVE_LIBBFD_SUPPORT ifeq ($(feature-libbfd-buildid), 1) CFLAGS += -DHAVE_LIBBFD_BUILDID_SUPPORT else @@ -921,26 +922,24 @@ ifdef BUILD_NONDISTRO endif endif -ifdef NO_DEMANGLE - CFLAGS += -DNO_DEMANGLE -else +ifndef NO_DEMANGLE + $(call feature_check,cxa-demangle) + ifeq ($(feature-cxa-demangle), 1) + EXTLIBS += -lstdc++ + CFLAGS += -DHAVE_CXA_DEMANGLE_SUPPORT + CXXFLAGS += -DHAVE_CXA_DEMANGLE_SUPPORT + endif ifdef BUILD_NONDISTRO ifeq ($(filter -liberty,$(EXTLIBS)),) - ifdef HAVE_CPLUS_DEMANGLE_SUPPORT + $(call feature_check,cplus-demangle) + ifeq ($(feature-cplus-demangle), 1) EXTLIBS += -liberty - else - $(call feature_check,cplus-demangle) - ifeq ($(feature-cplus-demangle), 1) - EXTLIBS += -liberty - endif endif endif - endif - - ifneq ($(filter -liberty,$(EXTLIBS)),) - CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT - else - CFLAGS += -DNO_DEMANGLE + ifneq ($(filter -liberty,$(EXTLIBS)),) + CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT + CXXFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT + endif endif endif diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 918b501f9bd8..8607575183a9 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -211,6 +211,7 @@ perf-$(CONFIG_ZSTD) += zstd.o perf-$(CONFIG_LIBCAP) += cap.o +perf-y += demangle-cxx.o perf-y += demangle-ocaml.o perf-y += demangle-java.o perf-y += demangle-rust.o diff --git a/tools/perf/util/demangle-cxx.cpp b/tools/perf/util/demangle-cxx.cpp new file mode 100644 index 000000000000..8708bcafd370 --- /dev/null +++ b/tools/perf/util/demangle-cxx.cpp @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "demangle-cxx.h" +#include +#include +#include + +#ifdef HAVE_LIBBFD_SUPPORT +#define PACKAGE 'perf' +#include +#endif + +#ifdef HAVE_CXA_DEMANGLE_SUPPORT +#include +#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 +} diff --git a/tools/perf/util/demangle-cxx.h b/tools/perf/util/demangle-cxx.h new file mode 100644 index 000000000000..26b5b66c0b4e --- /dev/null +++ b/tools/perf/util/demangle-cxx.h @@ -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 */ diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 41882ae8452e..c0a2de42c51b 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -12,6 +12,7 @@ #include "maps.h" #include "symbol.h" #include "symsrc.h" +#include "demangle-cxx.h" #include "demangle-ocaml.h" #include "demangle-java.h" #include "demangle-rust.h" @@ -25,6 +26,11 @@ #include #include +#ifdef HAVE_LIBBFD_SUPPORT +#define PACKAGE 'perf' +#include +#endif + #ifndef EM_AARCH64 #define EM_AARCH64 183 /* ARM 64 bit */ #endif @@ -45,34 +51,6 @@ 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 -#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 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) { - int demangle_flags = verbose > 0 ? (DMGL_PARAMS | DMGL_ANSI) : DMGL_NO_OPTS; 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)) return demangled; - demangled = bfd_demangle(NULL, elf_name, demangle_flags); + demangled = cxx_demangle_sym(elf_name, verbose > 0, verbose > 0); if (demangled == NULL) { demangled = ocaml_demangle_sym(elf_name); if (demangled == NULL) {