1 | //===----------------------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | // |
8 | // Extensions to libunwind API. |
9 | // |
10 | //===----------------------------------------------------------------------===// |
11 | |
12 | #ifndef __LIBUNWIND_EXT__ |
13 | #define __LIBUNWIND_EXT__ |
14 | |
15 | #include "config.h" |
16 | #include <libunwind.h> |
17 | #include <unwind.h> |
18 | |
19 | #define UNW_STEP_SUCCESS 1 |
20 | #define UNW_STEP_END 0 |
21 | |
22 | #ifdef __cplusplus |
23 | extern "C" { |
24 | #endif |
25 | |
26 | extern int __unw_getcontext(unw_context_t *); |
27 | extern int __unw_init_local(unw_cursor_t *, unw_context_t *); |
28 | extern int __unw_step(unw_cursor_t *); |
29 | extern int __unw_get_reg(unw_cursor_t *, unw_regnum_t, unw_word_t *); |
30 | extern int __unw_get_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t *); |
31 | extern int __unw_set_reg(unw_cursor_t *, unw_regnum_t, unw_word_t); |
32 | extern int __unw_set_fpreg(unw_cursor_t *, unw_regnum_t, unw_fpreg_t); |
33 | extern int __unw_resume(unw_cursor_t *); |
34 | |
35 | #ifdef __arm__ |
36 | /* Save VFP registers in FSTMX format (instead of FSTMD). */ |
37 | extern void __unw_save_vfp_as_X(unw_cursor_t *); |
38 | #endif |
39 | |
40 | extern const char *__unw_regname(unw_cursor_t *, unw_regnum_t); |
41 | extern int __unw_get_proc_info(unw_cursor_t *, unw_proc_info_t *); |
42 | extern int __unw_is_fpreg(unw_cursor_t *, unw_regnum_t); |
43 | extern int __unw_is_signal_frame(unw_cursor_t *); |
44 | extern int __unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *); |
45 | |
46 | #if defined(_AIX) |
47 | extern uintptr_t __unw_get_data_rel_base(unw_cursor_t *); |
48 | #endif |
49 | |
50 | // SPI |
51 | extern void __unw_iterate_dwarf_unwind_cache(void (*func)( |
52 | unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)); |
53 | |
54 | // IPI |
55 | extern void __unw_add_dynamic_fde(unw_word_t fde); |
56 | extern void __unw_remove_dynamic_fde(unw_word_t fde); |
57 | |
58 | extern void __unw_add_dynamic_eh_frame_section(unw_word_t eh_frame_start); |
59 | extern void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start); |
60 | |
61 | #ifdef __APPLE__ |
62 | |
63 | // Holds a description of the object-format-header (if any) and unwind info |
64 | // sections for a given address: |
65 | // |
66 | // * dso_base should point to a header for the JIT'd object containing the |
67 | // given address. The header's type should match the format type that |
68 | // libunwind was compiled for (so a mach_header or mach_header_64 on Darwin). |
69 | // A value of zero indicates that no such header exists. |
70 | // |
71 | // * dwarf_section and dwarf_section_length hold the address range of a DWARF |
72 | // eh-frame section associated with the given address, if any. If the |
73 | // dwarf_section_length field is zero it indicates that no such section |
74 | // exists (and in this case dwarf_section should also be set to zero). |
75 | // |
76 | // * compact_unwind_section and compact_unwind_section_length hold the address |
77 | // range of a compact-unwind info section associated with the given address, |
78 | // if any. If the compact_unwind_section_length field is zero it indicates |
79 | // that no such section exists (and in this case compact_unwind_section |
80 | // should also be set to zero). |
81 | // |
82 | // See the unw_find_dynamic_unwind_sections type below for more details. |
83 | struct unw_dynamic_unwind_sections { |
84 | unw_word_t dso_base; |
85 | unw_word_t dwarf_section; |
86 | size_t dwarf_section_length; |
87 | unw_word_t compact_unwind_section; |
88 | size_t compact_unwind_section_length; |
89 | }; |
90 | |
91 | // Typedef for unwind-info lookup callbacks. Functions of this type can be |
92 | // registered and deregistered using __unw_add_find_dynamic_unwind_sections |
93 | // and __unw_remove_find_dynamic_unwind_sections respectively. |
94 | // |
95 | // An unwind-info lookup callback should return 1 to indicate that it found |
96 | // unwind-info for the given address, or 0 to indicate that it did not find |
97 | // unwind-info for the given address. If found, the callback should populate |
98 | // some or all of the fields of the info argument (which is guaranteed to be |
99 | // non-null with all fields zero-initialized): |
100 | typedef int (*unw_find_dynamic_unwind_sections)( |
101 | unw_word_t addr, struct unw_dynamic_unwind_sections *info); |
102 | |
103 | // Register a dynamic unwind-info lookup callback. If libunwind does not find |
104 | // unwind info for a given frame in the executable program or normal dynamic |
105 | // shared objects then it will call all registered dynamic lookup functions |
106 | // in registration order until either one of them returns true, or the end |
107 | // of the list is reached. This lookup will happen before libunwind searches |
108 | // any eh-frames registered via __register_frame or |
109 | // __unw_add_dynamic_eh_frame_section. |
110 | // |
111 | // Returns UNW_ESUCCESS for successful registrations. If the given callback |
112 | // has already been registered then UNW_EINVAL will be returned. If all |
113 | // available callback entries are in use then UNW_ENOMEM will be returned. |
114 | extern int __unw_add_find_dynamic_unwind_sections( |
115 | unw_find_dynamic_unwind_sections find_dynamic_unwind_sections); |
116 | |
117 | // Deregister a dynacim unwind-info lookup callback. |
118 | // |
119 | // Returns UNW_ESUCCESS for successful deregistrations. If the given callback |
120 | // has already been registered then UNW_EINVAL will be returned. |
121 | extern int __unw_remove_find_dynamic_unwind_sections( |
122 | unw_find_dynamic_unwind_sections find_dynamic_unwind_sections); |
123 | |
124 | #endif |
125 | |
126 | #if defined(_LIBUNWIND_ARM_EHABI) |
127 | extern const uint32_t* decode_eht_entry(const uint32_t*, size_t*, size_t*); |
128 | extern _Unwind_Reason_Code _Unwind_VRS_Interpret(_Unwind_Context *context, |
129 | const uint32_t *data, |
130 | size_t offset, size_t len); |
131 | #endif |
132 | |
133 | #ifdef __cplusplus |
134 | } |
135 | #endif |
136 | |
137 | #endif // __LIBUNWIND_EXT__ |
138 | |