mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-11-01 23:04:54 +01: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 <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Albert Ou <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Alexandre Ghiti <[email protected]> Cc: Andrew Jones <[email protected]> Cc: Athira Rajeev <[email protected]> Cc: Dapeng Mi <[email protected]> Cc: Dmitrii Dolgov <[email protected]> Cc: Florian Fainelli <[email protected]> Cc: Howard Chu <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: James Clark <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: John Garry <[email protected]> Cc: Leo Yan <[email protected]> Cc: Li Guan <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Palmer Dabbelt <[email protected]> Cc: Paul Walmsley <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Shimin Guo <[email protected]> Cc: Thomas Richter <[email protected]> Cc: Tomas Glozar <[email protected]> Cc: Will Deacon <[email protected]> Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
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 */
|