Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef __UNWIND_H
0003 #define __UNWIND_H
0004 
0005 #include <linux/compiler.h>
0006 #include <linux/types.h>
0007 #include "util/map_symbol.h"
0008 
0009 struct maps;
0010 struct perf_sample;
0011 struct thread;
0012 
0013 struct unwind_entry {
0014     struct map_symbol ms;
0015     u64       ip;
0016 };
0017 
0018 typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg);
0019 
0020 struct unwind_libunwind_ops {
0021     int (*prepare_access)(struct maps *maps);
0022     void (*flush_access)(struct maps *maps);
0023     void (*finish_access)(struct maps *maps);
0024     int (*get_entries)(unwind_entry_cb_t cb, void *arg,
0025                struct thread *thread,
0026                struct perf_sample *data, int max_stack, bool best_effort);
0027 };
0028 
0029 #ifdef HAVE_DWARF_UNWIND_SUPPORT
0030 /*
0031  * When best_effort is set, don't report errors and fail silently. This could
0032  * be expanded in the future to be more permissive about things other than
0033  * error messages.
0034  */
0035 int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
0036             struct thread *thread,
0037             struct perf_sample *data, int max_stack,
0038             bool best_effort);
0039 /* libunwind specific */
0040 #ifdef HAVE_LIBUNWIND_SUPPORT
0041 #ifndef LIBUNWIND__ARCH_REG_ID
0042 #define LIBUNWIND__ARCH_REG_ID(regnum) libunwind__arch_reg_id(regnum)
0043 #endif
0044 
0045 #ifndef LIBUNWIND__ARCH_REG_SP
0046 #define LIBUNWIND__ARCH_REG_SP PERF_REG_SP
0047 #endif
0048 
0049 #ifndef LIBUNWIND__ARCH_REG_IP
0050 #define LIBUNWIND__ARCH_REG_IP PERF_REG_IP
0051 #endif
0052 
0053 int LIBUNWIND__ARCH_REG_ID(int regnum);
0054 int unwind__prepare_access(struct maps *maps, struct map *map, bool *initialized);
0055 void unwind__flush_access(struct maps *maps);
0056 void unwind__finish_access(struct maps *maps);
0057 #else
0058 static inline int unwind__prepare_access(struct maps *maps __maybe_unused,
0059                      struct map *map __maybe_unused,
0060                      bool *initialized __maybe_unused)
0061 {
0062     return 0;
0063 }
0064 
0065 static inline void unwind__flush_access(struct maps *maps __maybe_unused) {}
0066 static inline void unwind__finish_access(struct maps *maps __maybe_unused) {}
0067 #endif
0068 #else
0069 static inline int
0070 unwind__get_entries(unwind_entry_cb_t cb __maybe_unused,
0071             void *arg __maybe_unused,
0072             struct thread *thread __maybe_unused,
0073             struct perf_sample *data __maybe_unused,
0074             int max_stack __maybe_unused,
0075             bool best_effort __maybe_unused)
0076 {
0077     return 0;
0078 }
0079 
0080 static inline int unwind__prepare_access(struct maps *maps __maybe_unused,
0081                      struct map *map __maybe_unused,
0082                      bool *initialized __maybe_unused)
0083 {
0084     return 0;
0085 }
0086 
0087 static inline void unwind__flush_access(struct maps *maps __maybe_unused) {}
0088 static inline void unwind__finish_access(struct maps *maps __maybe_unused) {}
0089 #endif /* HAVE_DWARF_UNWIND_SUPPORT */
0090 #endif /* __UNWIND_H */