vex_libunwind_sys/
lib.rs

1//! Bindings to the low-level `unw_*` LLVM libunwind APIs which are an interface
2//! defined by the HP libunwind project.
3#![allow(non_camel_case_types, missing_docs)]
4#![no_std]
5
6#[cfg(not(all(
7    target_arch = "arm",
8    target_endian = "little",
9    target_pointer_width = "32"
10)))]
11compile_error!("vex-libunwind-sys only supports running in an armv7a environment.");
12
13use core::ffi::{c_char, c_int, c_void};
14
15pub type uw_error_t = c_int;
16
17/// Error codes.
18pub mod error {
19    use core::ffi::c_int;
20    /// No error.
21    pub const UNW_ESUCCESS: c_int = 0;
22    /// Unspecified (general) error.
23    pub const UNW_EUNSPEC: c_int = -6540;
24    /// Out of memory.
25    pub const UNW_ENOMEM: c_int = -6541;
26    /// Bad register number.
27    pub const UNW_EBADREG: c_int = -6542;
28    /// Attempt to write read-only register.
29    pub const UNW_EREADONLYREG: c_int = -6543;
30    /// Stop unwinding.
31    pub const UNW_ESTOPUNWIND: c_int = -6544;
32    /// Invalid IP.
33    pub const UNW_EINVALIDIP: c_int = -6545;
34    /// Bad frame.
35    pub const UNW_EBADFRAME: c_int = -6546;
36    /// Unsupported operation or bad value.
37    pub const UNW_EINVAL: c_int = -6547;
38    /// Unwind info has unsupported version.
39    pub const UNW_EBADVERSION: c_int = -6548;
40    /// No unwind info found.
41    pub const UNW_ENOINFO: c_int = -6549;
42}
43
44/// Architecture-specific context size
45#[cfg(target_arch = "arm")]
46pub const CONTEXT_SIZE: usize = 42;
47/// Architecture-specific cursor size
48#[cfg(target_arch = "arm")]
49pub const CURSOR_SIZE: usize = 49;
50
51/// The step was successful.
52pub const UNW_STEP_SUCCESS: c_int = 1;
53/// There are no more stack frames.
54pub const UNW_STEP_END: c_int = 0;
55
56#[repr(C)]
57#[derive(Copy, Clone)]
58pub struct unw_context_t {
59    _data: [u64; CONTEXT_SIZE],
60}
61
62#[repr(C)]
63#[derive(Copy, Clone)]
64pub struct unw_cursor_t {
65    _data: [u64; CURSOR_SIZE],
66}
67
68pub type unw_addr_space_t = *mut c_void;
69
70pub type unw_regnum_t = c_int;
71pub type unw_word_t = usize;
72pub type unw_fpreg_t = u64;
73
74#[repr(C)]
75#[derive(Debug, Copy, Clone)]
76pub struct unw_proc_info_t {
77    /// Start address of function
78    pub start_ip: unw_word_t,
79    /// Address after end of function
80    pub end_ip: unw_word_t,
81    /// Address of language specific data area or zero if not used
82    pub lsda: unw_word_t,
83    /// Personality routine, or zero if not used
84    pub handler: unw_word_t,
85    /// Not used
86    pub gp: unw_word_t,
87    /// Not used
88    pub flags: unw_word_t,
89    /// Compact unwind encoding, or zero if none
90    pub format: u32,
91    /// Size of DWARF unwind info, or zero if none
92    pub unwind_info_size: u32,
93    /// Address of DWARF unwind info, or zero
94    pub unwind_info: unw_word_t,
95    /// mach_header of mach-o image containing func
96    pub extra: unw_word_t,
97}
98
99#[link(name = "unwind")]
100unsafe extern "C" {
101    pub fn unw_getcontext(ctx: *mut unw_context_t) -> c_int;
102
103    pub fn unw_init_local(cur: *mut unw_cursor_t, ctx: *mut unw_context_t) -> c_int;
104
105    pub fn unw_step(cur: *mut unw_cursor_t) -> c_int;
106
107    pub fn unw_get_reg(cur: *mut unw_cursor_t, reg: unw_regnum_t, val: *mut unw_word_t) -> c_int;
108
109    pub fn unw_get_fpreg(cur: *mut unw_cursor_t, reg: unw_regnum_t, val: *mut unw_fpreg_t)
110        -> c_int;
111
112    pub fn unw_set_reg(cur: *mut unw_cursor_t, reg: unw_regnum_t, val: unw_word_t) -> c_int;
113
114    pub fn unw_set_fpreg(cur: *mut unw_cursor_t, reg: unw_regnum_t, val: unw_fpreg_t) -> c_int;
115
116    #[cfg(target_arch = "arm")]
117    // Save VFP registers in FSTMX format (instead of FSTMD).
118    pub fn unw_save_vfp_as_X(cur: *mut unw_cursor_t);
119
120    pub fn unw_regname(cur: *mut unw_cursor_t, reg: unw_regnum_t) -> *const c_char;
121
122    pub fn unw_get_proc_info(cur: *mut unw_cursor_t, info: *mut unw_proc_info_t) -> c_int;
123
124    pub fn unw_is_fpreg(cur: *mut unw_cursor_t, reg: unw_regnum_t) -> c_int;
125
126    pub fn unw_is_signal_frame(cur: *mut unw_cursor_t) -> c_int;
127
128    pub fn unw_get_proc_name(
129        cur: *mut unw_cursor_t,
130        buf: *mut c_char,
131        len: usize,
132        offp: *mut unw_word_t,
133    ) -> c_int;
134
135    pub static mut unw_local_addr_space: unw_addr_space_t;
136}
137
138#[link(name = "unwind")]
139unsafe extern "C-unwind" {
140    pub fn unw_resume(cur: *mut unw_cursor_t) -> c_int;
141}
142
143pub mod registers {
144    use super::unw_regnum_t;
145
146    /// Instruction pointer
147    pub const UNW_REG_IP: unw_regnum_t = -1;
148    /// Stack pointer
149    pub const UNW_REG_SP: unw_regnum_t = -2;
150
151    // 32-bit ARM registers. Numbers match DWARF for ARM spec #3.1 Table 1.
152    // Naming scheme uses recommendations given in Note 4 for VFP-v2 and VFP-v3.
153    // In this scheme, even though the 64-bit floating point registers D0-D31
154    // overlap physically with the 32-bit floating pointer registers S0-S31,
155    // they are given a non-overlapping range of register numbers.
156    //
157    // Commented out ranges are not preserved during unwinding.
158    pub const UNW_ARM_R0: unw_regnum_t = 0;
159    pub const UNW_ARM_R1: unw_regnum_t = 1;
160    pub const UNW_ARM_R2: unw_regnum_t = 2;
161    pub const UNW_ARM_R3: unw_regnum_t = 3;
162    pub const UNW_ARM_R4: unw_regnum_t = 4;
163    pub const UNW_ARM_R5: unw_regnum_t = 5;
164    pub const UNW_ARM_R6: unw_regnum_t = 6;
165    pub const UNW_ARM_R7: unw_regnum_t = 7;
166    pub const UNW_ARM_R8: unw_regnum_t = 8;
167    pub const UNW_ARM_R9: unw_regnum_t = 9;
168    pub const UNW_ARM_R10: unw_regnum_t = 10;
169    pub const UNW_ARM_R11: unw_regnum_t = 11;
170    pub const UNW_ARM_R12: unw_regnum_t = 12;
171    pub const UNW_ARM_SP: unw_regnum_t = 13; // Logical alias for UNW_REG_SP
172    pub const UNW_ARM_R13: unw_regnum_t = 13;
173    pub const UNW_ARM_LR: unw_regnum_t = 14;
174    pub const UNW_ARM_R14: unw_regnum_t = 14;
175    pub const UNW_ARM_IP: unw_regnum_t = 15; // Logical alias for UNW_REG_IP
176    pub const UNW_ARM_R15: unw_regnum_t = 15;
177    // 16-63 -- OBSOLETE. Used in VFP1 to represent both S0-S31 and D0-D31.
178    pub const UNW_ARM_S0: unw_regnum_t = 64;
179    pub const UNW_ARM_S1: unw_regnum_t = 65;
180    pub const UNW_ARM_S2: unw_regnum_t = 66;
181    pub const UNW_ARM_S3: unw_regnum_t = 67;
182    pub const UNW_ARM_S4: unw_regnum_t = 68;
183    pub const UNW_ARM_S5: unw_regnum_t = 69;
184    pub const UNW_ARM_S6: unw_regnum_t = 70;
185    pub const UNW_ARM_S7: unw_regnum_t = 71;
186    pub const UNW_ARM_S8: unw_regnum_t = 72;
187    pub const UNW_ARM_S9: unw_regnum_t = 73;
188    pub const UNW_ARM_S10: unw_regnum_t = 74;
189    pub const UNW_ARM_S11: unw_regnum_t = 75;
190    pub const UNW_ARM_S12: unw_regnum_t = 76;
191    pub const UNW_ARM_S13: unw_regnum_t = 77;
192    pub const UNW_ARM_S14: unw_regnum_t = 78;
193    pub const UNW_ARM_S15: unw_regnum_t = 79;
194    pub const UNW_ARM_S16: unw_regnum_t = 80;
195    pub const UNW_ARM_S17: unw_regnum_t = 81;
196    pub const UNW_ARM_S18: unw_regnum_t = 82;
197    pub const UNW_ARM_S19: unw_regnum_t = 83;
198    pub const UNW_ARM_S20: unw_regnum_t = 84;
199    pub const UNW_ARM_S21: unw_regnum_t = 85;
200    pub const UNW_ARM_S22: unw_regnum_t = 86;
201    pub const UNW_ARM_S23: unw_regnum_t = 87;
202    pub const UNW_ARM_S24: unw_regnum_t = 88;
203    pub const UNW_ARM_S25: unw_regnum_t = 89;
204    pub const UNW_ARM_S26: unw_regnum_t = 90;
205    pub const UNW_ARM_S27: unw_regnum_t = 91;
206    pub const UNW_ARM_S28: unw_regnum_t = 92;
207    pub const UNW_ARM_S29: unw_regnum_t = 93;
208    pub const UNW_ARM_S30: unw_regnum_t = 94;
209    pub const UNW_ARM_S31: unw_regnum_t = 95;
210    //  96-103 -- OBSOLETE. F0-F7. Used by the FPA system. Superseded by VFP.
211    // 104-111 -- wCGR0-wCGR7, ACC0-ACC7 (Intel wireless MMX)
212    pub const UNW_ARM_WR0: unw_regnum_t = 112;
213    pub const UNW_ARM_WR1: unw_regnum_t = 113;
214    pub const UNW_ARM_WR2: unw_regnum_t = 114;
215    pub const UNW_ARM_WR3: unw_regnum_t = 115;
216    pub const UNW_ARM_WR4: unw_regnum_t = 116;
217    pub const UNW_ARM_WR5: unw_regnum_t = 117;
218    pub const UNW_ARM_WR6: unw_regnum_t = 118;
219    pub const UNW_ARM_WR7: unw_regnum_t = 119;
220    pub const UNW_ARM_WR8: unw_regnum_t = 120;
221    pub const UNW_ARM_WR9: unw_regnum_t = 121;
222    pub const UNW_ARM_WR10: unw_regnum_t = 122;
223    pub const UNW_ARM_WR11: unw_regnum_t = 123;
224    pub const UNW_ARM_WR12: unw_regnum_t = 124;
225    pub const UNW_ARM_WR13: unw_regnum_t = 125;
226    pub const UNW_ARM_WR14: unw_regnum_t = 126;
227    pub const UNW_ARM_WR15: unw_regnum_t = 127;
228    // 128-133 -- SPSR, SPSR_{FIQ|IRQ|ABT|UND|SVC}
229    // 134-143 -- Reserved
230    // 144-150 -- R8_USR-R14_USR
231    // 151-157 -- R8_FIQ-R14_FIQ
232    // 158-159 -- R13_IRQ-R14_IRQ
233    // 160-161 -- R13_ABT-R14_ABT
234    // 162-163 -- R13_UND-R14_UND
235    // 164-165 -- R13_SVC-R14_SVC
236    // 166-191 -- Reserved
237    pub const UNW_ARM_WC0: unw_regnum_t = 192;
238    pub const UNW_ARM_WC1: unw_regnum_t = 193;
239    pub const UNW_ARM_WC2: unw_regnum_t = 194;
240    pub const UNW_ARM_WC3: unw_regnum_t = 195;
241    // 196-199 -- wC4-wC7 (Intel wireless MMX control)
242    // 200-255 -- Reserved
243    pub const UNW_ARM_D0: unw_regnum_t = 256;
244    pub const UNW_ARM_D1: unw_regnum_t = 257;
245    pub const UNW_ARM_D2: unw_regnum_t = 258;
246    pub const UNW_ARM_D3: unw_regnum_t = 259;
247    pub const UNW_ARM_D4: unw_regnum_t = 260;
248    pub const UNW_ARM_D5: unw_regnum_t = 261;
249    pub const UNW_ARM_D6: unw_regnum_t = 262;
250    pub const UNW_ARM_D7: unw_regnum_t = 263;
251    pub const UNW_ARM_D8: unw_regnum_t = 264;
252    pub const UNW_ARM_D9: unw_regnum_t = 265;
253    pub const UNW_ARM_D10: unw_regnum_t = 266;
254    pub const UNW_ARM_D11: unw_regnum_t = 267;
255    pub const UNW_ARM_D12: unw_regnum_t = 268;
256    pub const UNW_ARM_D13: unw_regnum_t = 269;
257    pub const UNW_ARM_D14: unw_regnum_t = 270;
258    pub const UNW_ARM_D15: unw_regnum_t = 271;
259    pub const UNW_ARM_D16: unw_regnum_t = 272;
260    pub const UNW_ARM_D17: unw_regnum_t = 273;
261    pub const UNW_ARM_D18: unw_regnum_t = 274;
262    pub const UNW_ARM_D19: unw_regnum_t = 275;
263    pub const UNW_ARM_D20: unw_regnum_t = 276;
264    pub const UNW_ARM_D21: unw_regnum_t = 277;
265    pub const UNW_ARM_D22: unw_regnum_t = 278;
266    pub const UNW_ARM_D23: unw_regnum_t = 279;
267    pub const UNW_ARM_D24: unw_regnum_t = 280;
268    pub const UNW_ARM_D25: unw_regnum_t = 281;
269    pub const UNW_ARM_D26: unw_regnum_t = 282;
270    pub const UNW_ARM_D27: unw_regnum_t = 283;
271    pub const UNW_ARM_D28: unw_regnum_t = 284;
272    pub const UNW_ARM_D29: unw_regnum_t = 285;
273    pub const UNW_ARM_D30: unw_regnum_t = 286;
274    pub const UNW_ARM_D31: unw_regnum_t = 287;
275    // 288-319 -- Reserved for VFP/Neon
276    // 320-8191 -- Reserved
277    // 8192-16383 -- Unspecified vendor co-processor register.
278}