mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-08-09 06:14:34 +02:00
Local unwinding only works on the machine libunwind is built for, rather than cross platform, the APIs for remote and local unwinding are similar but types like unw_word_t depend on the included header. Place the architecture specific code into the appropriate libunwind-<arch>.c file. Put generic code in unwind-libunwind.c and use libunwind-arch to choose the correct implementation based on the thread's e_machine. Structuring the code this way avoids including the unwind-libunwind-local.c for each architecture of remote unwinding. Data is moved into the struct unwind_info to simplify the architecture and generic code, trying to keep as much code as possible generic. Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Albert Ou <aou@eecs.berkeley.edu> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Alexandre Ghiti <alex@ghiti.fr> Cc: Andrew Jones <andrew.jones@oss.qualcomm.com> Cc: Athira Rajeev <atrajeev@linux.ibm.com> Cc: Dapeng Mi <dapeng1.mi@linux.intel.com> Cc: Dmitrii Dolgov <9erthalion6@gmail.com> Cc: Florian Fainelli <florian.fainelli@broadcom.com> Cc: Howard Chu <howardchu95@gmail.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: John Garry <john.g.garry@oracle.com> Cc: Leo Yan <leo.yan@linux.dev> Cc: Li Guan <guanli.oerv@isrc.iscas.ac.cn> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Palmer Dabbelt <palmer@dabbelt.com> Cc: Paul Walmsley <pjw@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Shimin Guo <shimin.guo@skydio.com> Cc: Thomas Richter <tmricht@linux.ibm.com> Cc: Tomas Glozar <tglozar@redhat.com> Cc: Will Deacon <will@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
86 lines
2.5 KiB
C
86 lines
2.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef __UNWIND_H
|
|
#define __UNWIND_H
|
|
|
|
#include <stdint.h>
|
|
#include <linux/compiler.h>
|
|
#include <linux/types.h>
|
|
#include "map_symbol.h"
|
|
|
|
struct maps;
|
|
struct option;
|
|
struct perf_sample;
|
|
struct thread;
|
|
|
|
struct unwind_entry {
|
|
struct map_symbol ms;
|
|
u64 ip;
|
|
};
|
|
|
|
typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg);
|
|
|
|
int unwind__configure(const char *var, const char *value, void *cb);
|
|
int unwind__option(const struct option *opt, const char *arg, int unset);
|
|
|
|
/*
|
|
* When best_effort is set, don't report errors and fail silently. This could
|
|
* be expanded in the future to be more permissive about things other than
|
|
* error messages.
|
|
*/
|
|
int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
|
|
struct thread *thread,
|
|
struct perf_sample *data, int max_stack,
|
|
bool best_effort);
|
|
|
|
#ifdef HAVE_LIBDW_SUPPORT
|
|
int libdw__get_entries(unwind_entry_cb_t cb, void *arg,
|
|
struct thread *thread,
|
|
struct perf_sample *data, int max_stack,
|
|
bool best_effort);
|
|
#else
|
|
#include "debug.h"
|
|
static inline int libdw__get_entries(unwind_entry_cb_t cb __maybe_unused, void *arg __maybe_unused,
|
|
struct thread *thread __maybe_unused,
|
|
struct perf_sample *data __maybe_unused,
|
|
int max_stack __maybe_unused,
|
|
bool best_effort __maybe_unused)
|
|
{
|
|
pr_warning_once("Error: libdw dwarf unwinding not built into perf\n");
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#ifdef HAVE_LIBUNWIND_SUPPORT
|
|
/* libunwind specific */
|
|
int libunwind__get_entries(unwind_entry_cb_t cb, void *arg,
|
|
struct thread *thread,
|
|
struct perf_sample *data, int max_stack,
|
|
bool best_effort);
|
|
int unwind__prepare_access(struct maps *maps, uint16_t e_machine);
|
|
void unwind__flush_access(struct maps *maps);
|
|
void unwind__finish_access(struct maps *maps);
|
|
#else
|
|
#include "debug.h"
|
|
static inline int libunwind__get_entries(unwind_entry_cb_t cb __maybe_unused,
|
|
void *arg __maybe_unused,
|
|
struct thread *thread __maybe_unused,
|
|
struct perf_sample *data __maybe_unused,
|
|
int max_stack __maybe_unused,
|
|
bool best_effort __maybe_unused)
|
|
{
|
|
pr_warning_once("Error: libunwind dwarf unwinding not built into perf\n");
|
|
return 0;
|
|
}
|
|
|
|
static inline int unwind__prepare_access(struct maps *maps __maybe_unused,
|
|
uint16_t e_machine __maybe_unused)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline void unwind__flush_access(struct maps *maps __maybe_unused) {}
|
|
static inline void unwind__finish_access(struct maps *maps __maybe_unused) {}
|
|
#endif
|
|
|
|
#endif /* __UNWIND_H */
|