Commit 3b4e4efe authored by Ian Rogers's avatar Ian Rogers Committed by Arnaldo Carvalho de Melo
Browse files

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: default avatarIan 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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 4c72e2b3
Loading
Loading
Loading
Loading
+14 −15
Original line number Diff line number Diff line
@@ -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
        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
      CXXFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT
    endif
  endif
endif

+1 −0
Original line number Diff line number Diff line
@@ -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
+50 −0
Original line number Diff line number Diff line
// 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
}
+16 −0
Original line number Diff line number Diff line
/* 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 */
+7 −30
Original line number Diff line number Diff line
@@ -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 <symbol/kallsyms.h>
#include <internal/lib.h>

#ifdef HAVE_LIBBFD_SUPPORT
#define PACKAGE 'perf'
#include <bfd.h>
#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 <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
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) {