xref: /linux/tools/perf/util/unwind.h (revision 88b4275ff542510fa80c32c863571c71d60f8766)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __UNWIND_H
3 #define __UNWIND_H
4 
5 #include <stdint.h>
6 #include <linux/compiler.h>
7 #include <linux/types.h>
8 #include "map_symbol.h"
9 
10 struct maps;
11 struct option;
12 struct perf_sample;
13 struct thread;
14 
15 struct unwind_entry {
16 	struct map_symbol ms;
17 	u64		  ip;
18 };
19 
20 typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg);
21 
22 int unwind__configure(const char *var, const char *value, void *cb);
23 int unwind__option(const struct option *opt, const char *arg, int unset);
24 
25 /*
26  * When best_effort is set, don't report errors and fail silently. This could
27  * be expanded in the future to be more permissive about things other than
28  * error messages.
29  */
30 int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
31 			struct thread *thread,
32 			struct perf_sample *data, int max_stack,
33 			bool best_effort);
34 
35 #ifdef HAVE_LIBDW_SUPPORT
36 int libdw__get_entries(unwind_entry_cb_t cb, void *arg,
37 		       struct thread *thread,
38 		       struct perf_sample *data, int max_stack,
39 		       bool best_effort);
40 #else
41 #include "debug.h"
42 static inline int libdw__get_entries(unwind_entry_cb_t cb __maybe_unused, void *arg __maybe_unused,
43 				     struct thread *thread __maybe_unused,
44 				     struct perf_sample *data __maybe_unused,
45 				     int max_stack __maybe_unused,
46 				     bool best_effort __maybe_unused)
47 {
48 	pr_warning_once("Error: libdw dwarf unwinding not built into perf\n");
49 	return 0;
50 }
51 #endif
52 
53 #ifdef HAVE_LIBUNWIND_SUPPORT
54 /* libunwind specific */
55 int libunwind__get_entries(unwind_entry_cb_t cb, void *arg,
56 			   struct thread *thread,
57 			   struct perf_sample *data, int max_stack,
58 			   bool best_effort);
59 int unwind__prepare_access(struct maps *maps, uint16_t e_machine);
60 void unwind__flush_access(struct maps *maps);
61 void unwind__finish_access(struct maps *maps);
62 #else
63 #include "debug.h"
64 static inline int libunwind__get_entries(unwind_entry_cb_t cb __maybe_unused,
65 					 void *arg __maybe_unused,
66 					 struct thread *thread __maybe_unused,
67 					 struct perf_sample *data __maybe_unused,
68 					 int max_stack __maybe_unused,
69 					 bool best_effort __maybe_unused)
70 {
71 	pr_warning_once("Error: libunwind dwarf unwinding not built into perf\n");
72 	return 0;
73 }
74 
75 static inline int unwind__prepare_access(struct maps *maps __maybe_unused,
76 					 uint16_t e_machine __maybe_unused)
77 {
78 	return 0;
79 }
80 
81 static inline void unwind__flush_access(struct maps *maps __maybe_unused) {}
82 static inline void unwind__finish_access(struct maps *maps __maybe_unused) {}
83 #endif
84 
85 #endif /* __UNWIND_H */
86