[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250122062332.577009-9-irogers@google.com>
Date: Tue, 21 Jan 2025 22:23:23 -0800
From: Ian Rogers <irogers@...gle.com>
To: Peter Zijlstra <peterz@...radead.org>, Ingo Molnar <mingo@...hat.com>,
Arnaldo Carvalho de Melo <acme@...nel.org>, Namhyung Kim <namhyung@...nel.org>,
Mark Rutland <mark.rutland@....com>,
Alexander Shishkin <alexander.shishkin@...ux.intel.com>, Jiri Olsa <jolsa@...nel.org>,
Ian Rogers <irogers@...gle.com>, Adrian Hunter <adrian.hunter@...el.com>,
Kan Liang <kan.liang@...ux.intel.com>, Nathan Chancellor <nathan@...nel.org>,
Nick Desaulniers <ndesaulniers@...gle.com>, Bill Wendling <morbo@...gle.com>,
Justin Stitt <justinstitt@...gle.com>, Aditya Gupta <adityag@...ux.ibm.com>,
"Steinar H. Gunderson" <sesse@...gle.com>, Charlie Jenkins <charlie@...osinc.com>,
Changbin Du <changbin.du@...wei.com>, "Masami Hiramatsu (Google)" <mhiramat@...nel.org>,
James Clark <james.clark@...aro.org>, Kajol Jain <kjain@...ux.ibm.com>,
Athira Rajeev <atrajeev@...ux.vnet.ibm.com>, Li Huafei <lihuafei1@...wei.com>,
Dmitry Vyukov <dvyukov@...gle.com>, Andi Kleen <ak@...ux.intel.com>,
Chaitanya S Prakash <chaitanyas.prakash@....com>, linux-kernel@...r.kernel.org,
linux-perf-users@...r.kernel.org, llvm@...ts.linux.dev,
Song Liu <song@...nel.org>, bpf@...r.kernel.org
Subject: [PATCH v2 08/17] perf llvm: Mangle libperf-llvm.so function names
For a function like llvm_addr2line having the libperf-llvm.so exported
symbol named llvm_addr2line meant that the perf llvm_addr2line could
sometimes erroneously be returned. This led to infinite recursion and
eventual stack overflow. To avoid this conflict add a new
BUILDING_PERF_LLVMSO when libperf-llvm.so is being built and use it to
alter the behavior of MANGLE_PERF_LLVM_API, a macro that prefixes the
name when libperf-llvm.so is being built. The prefixed named avoids
the name collision.
Signed-off-by: Ian Rogers <irogers@...gle.com>
---
tools/perf/Makefile.perf | 3 ++-
tools/perf/util/llvm-c-helpers.cpp | 29 ++++++++++++++++++-----------
tools/perf/util/llvm-c-helpers.h | 24 ++++++++++++++++--------
3 files changed, 36 insertions(+), 20 deletions(-)
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index eae77f6af59d..a2886abd4f02 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -1026,7 +1026,8 @@ $(LIBSYMBOL)-clean:
$(Q)$(RM) -r -- $(LIBSYMBOL_OUTPUT)
ifdef LIBLLVM_DYNAMIC
-LIBPERF_LLVM_CXXFLAGS := $(call filter-out,-DHAVE_LIBLLVM_DYNAMIC,$(CXXFLAGS)) -DHAVE_LIBLLVM_SUPPORT
+LIBPERF_LLVM_CXXFLAGS := $(call filter-out,-DHAVE_LIBLLVM_DYNAMIC,$(CXXFLAGS))
+LIBPERF_LLVM_CXXFLAGS += -DHAVE_LIBLLVM_SUPPORT -DBUILDING_PERF_LLVMSO
LIBPERF_LLVM_LIBS = -L$(shell $(LLVM_CONFIG) --libdir) $(LIBLLVM) -lstdc++
$(OUTPUT)$(LIBPERF_LLVM): util/llvm-c-helpers.cpp
diff --git a/tools/perf/util/llvm-c-helpers.cpp b/tools/perf/util/llvm-c-helpers.cpp
index 5a6f76e6b705..8cea380be5c2 100644
--- a/tools/perf/util/llvm-c-helpers.cpp
+++ b/tools/perf/util/llvm-c-helpers.cpp
@@ -99,10 +99,12 @@ static int extract_file_and_line(const DILineInfo &line_info, char **file,
#endif
extern "C"
-int llvm_addr2line(const char *dso_name __maybe_unused, u64 addr __maybe_unused,
- char **file __maybe_unused, unsigned int *line __maybe_unused,
- bool unwind_inlines __maybe_unused,
- llvm_a2l_frame **inline_frames __maybe_unused)
+int MANGLE_PERF_LLVM_API(llvm_addr2line)(const char *dso_name __maybe_unused,
+ u64 addr __maybe_unused,
+ char **file __maybe_unused,
+ unsigned int *line __maybe_unused,
+ bool unwind_inlines __maybe_unused,
+ llvm_a2l_frame **inline_frames __maybe_unused)
{
#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC)
LLVMSymbolizer *symbolizer = get_symbolizer();
@@ -177,7 +179,8 @@ int llvm_addr2line(const char *dso_name __maybe_unused, u64 addr __maybe_unused,
if (!handle)
return 0;
- fn = reinterpret_cast<decltype(fn)>(dlsym(handle, "llvm_addr2line"));
+ fn = reinterpret_cast<decltype(fn)>(
+ dlsym(handle, MANGLE_PERF_LLVM_API_STR(llvm_addr2line)));
if (!fn)
pr_debug("dlsym failed for llvm_addr2line\n");
fn_init = true;
@@ -215,8 +218,9 @@ make_symbol_relative_string(struct dso *dso, const char *sym_name,
#endif
extern "C"
-char *llvm_name_for_code(struct dso *dso __maybe_unused, const char *dso_name __maybe_unused,
- u64 addr __maybe_unused)
+char *MANGLE_PERF_LLVM_API(llvm_name_for_code)(struct dso *dso __maybe_unused,
+ const char *dso_name __maybe_unused,
+ u64 addr __maybe_unused)
{
#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC)
LLVMSymbolizer *symbolizer = get_symbolizer();
@@ -242,7 +246,8 @@ char *llvm_name_for_code(struct dso *dso __maybe_unused, const char *dso_name __
if (!handle)
return NULL;
- fn = reinterpret_cast<decltype(fn)>(dlsym(handle, "llvm_name_for_code"));
+ fn = reinterpret_cast<decltype(fn)>(
+ dlsym(handle, MANGLE_PERF_LLVM_API_STR(llvm_name_for_code)));
if (!fn)
pr_debug("dlsym failed for llvm_name_for_code\n");
fn_init = true;
@@ -256,8 +261,9 @@ char *llvm_name_for_code(struct dso *dso __maybe_unused, const char *dso_name __
}
extern "C"
-char *llvm_name_for_data(struct dso *dso __maybe_unused, const char *dso_name __maybe_unused,
- u64 addr __maybe_unused)
+char *MANGLE_PERF_LLVM_API(llvm_name_for_data)(struct dso *dso __maybe_unused,
+ const char *dso_name __maybe_unused,
+ u64 addr __maybe_unused)
{
#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC)
LLVMSymbolizer *symbolizer = get_symbolizer();
@@ -283,7 +289,8 @@ char *llvm_name_for_data(struct dso *dso __maybe_unused, const char *dso_name __
if (!handle)
return NULL;
- fn = reinterpret_cast<decltype(fn)>(dlsym(handle, "llvm_name_for_data"));
+ fn = reinterpret_cast<decltype(fn)>(
+ dlsym(handle, MANGLE_PERF_LLVM_API_STR(llvm_name_for_data)));
if (!fn)
pr_debug("dlsym failed for llvm_name_for_data\n");
fn_init = true;
diff --git a/tools/perf/util/llvm-c-helpers.h b/tools/perf/util/llvm-c-helpers.h
index d2b99637a28a..cfcfd540cdae 100644
--- a/tools/perf/util/llvm-c-helpers.h
+++ b/tools/perf/util/llvm-c-helpers.h
@@ -13,6 +13,14 @@
extern "C" {
#endif
+/* Support name mangling so that libperf_llvm.so's names don't match those in perf. */
+#ifdef BUILDING_PERF_LLVMSO
+#define MANGLE_PERF_LLVM_API(x) PERF_LLVM_SO_ ## x
+#else
+#define MANGLE_PERF_LLVM_API(x) x
+#endif
+#define MANGLE_PERF_LLVM_API_STR(x) "PERF_LLVM_SO_" #x
+
struct dso;
struct llvm_a2l_frame {
@@ -37,12 +45,12 @@ struct llvm_a2l_frame {
* a newly allocated array with that length. The caller is then responsible
* for freeing both the strings and the array itself.
*/
-int llvm_addr2line(const char* dso_name,
- u64 addr,
- char** file,
- unsigned int* line,
- bool unwind_inlines,
- struct llvm_a2l_frame** inline_frames);
+int MANGLE_PERF_LLVM_API(llvm_addr2line)(const char *dso_name,
+ u64 addr,
+ char **file,
+ unsigned int *line,
+ bool unwind_inlines,
+ struct llvm_a2l_frame **inline_frames);
/*
* Simple symbolizers for addresses; will convert something like
@@ -50,8 +58,8 @@ int llvm_addr2line(const char* dso_name,
*
* The returned value must be freed by the caller, with free().
*/
-char *llvm_name_for_code(struct dso *dso, const char *dso_name, u64 addr);
-char *llvm_name_for_data(struct dso *dso, const char *dso_name, u64 addr);
+char *MANGLE_PERF_LLVM_API(llvm_name_for_code)(struct dso *dso, const char *dso_name, u64 addr);
+char *MANGLE_PERF_LLVM_API(llvm_name_for_data)(struct dso *dso, const char *dso_name, u64 addr);
#ifdef __cplusplus
}
--
2.48.0.rc2.279.g1de40edade-goog
Powered by blists - more mailing lists