1/* libunwind - a platform-independent unwind library
2   Copyright (C) 2008 CodeSourcery
3
4This file is part of libunwind.
5
6Permission is hereby granted, free of charge, to any person obtaining
7a copy of this software and associated documentation files (the
8"Software"), to deal in the Software without restriction, including
9without limitation the rights to use, copy, modify, merge, publish,
10distribute, sublicense, and/or sell copies of the Software, and to
11permit persons to whom the Software is furnished to do so, subject to
12the following conditions:
13
14The above copyright notice and this permission notice shall be
15included in all copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
24
25#ifndef LIBUNWIND_H
26#define LIBUNWIND_H
27
28#if defined(__cplusplus) || defined(c_plusplus)
29extern "C" {
30#endif
31
32#include <inttypes.h>
33#include <stddef.h>
34
35#define UNW_TARGET	arm
36#define UNW_TARGET_ARM	1
37
38#define _U_TDEP_QP_TRUE	0	/* see libunwind-dynamic.h  */
39
40/* This needs to be big enough to accommodate "struct cursor", while
41   leaving some slack for future expansion.  Changing this value will
42   require recompiling all users of this library.  Stack allocation is
43   relatively cheap and unwind-state copying is relatively rare, so we
44   want to err on making it rather too big than too small.  */
45
46/* FIXME for ARM. Too big?  What do other things use for similar tasks?  */
47#define UNW_TDEP_CURSOR_LEN	4096
48
49typedef uint32_t unw_word_t;
50typedef int32_t unw_sword_t;
51
52typedef long double unw_tdep_fpreg_t;
53
54typedef enum
55  {
56    UNW_ARM_R0,
57    UNW_ARM_R1,
58    UNW_ARM_R2,
59    UNW_ARM_R3,
60    UNW_ARM_R4,
61    UNW_ARM_R5,
62    UNW_ARM_R6,
63    UNW_ARM_R7,
64    UNW_ARM_R8,
65    UNW_ARM_R9,
66    UNW_ARM_R10,
67    UNW_ARM_R11,
68    UNW_ARM_R12,
69    UNW_ARM_R13,
70    UNW_ARM_R14,
71    UNW_ARM_R15,
72
73    /* VFPv2 s0-s31 (obsolescent numberings).  */
74    UNW_ARM_S0 = 64,
75    UNW_ARM_S1,
76    UNW_ARM_S2,
77    UNW_ARM_S3,
78    UNW_ARM_S4,
79    UNW_ARM_S5,
80    UNW_ARM_S6,
81    UNW_ARM_S7,
82    UNW_ARM_S8,
83    UNW_ARM_S9,
84    UNW_ARM_S10,
85    UNW_ARM_S11,
86    UNW_ARM_S12,
87    UNW_ARM_S13,
88    UNW_ARM_S14,
89    UNW_ARM_S15,
90    UNW_ARM_S16,
91    UNW_ARM_S17,
92    UNW_ARM_S18,
93    UNW_ARM_S19,
94    UNW_ARM_S20,
95    UNW_ARM_S21,
96    UNW_ARM_S22,
97    UNW_ARM_S23,
98    UNW_ARM_S24,
99    UNW_ARM_S25,
100    UNW_ARM_S26,
101    UNW_ARM_S27,
102    UNW_ARM_S28,
103    UNW_ARM_S29,
104    UNW_ARM_S30,
105    UNW_ARM_S31,
106
107    /* FPA register numberings.  */
108    UNW_ARM_F0 = 96,
109    UNW_ARM_F1,
110    UNW_ARM_F2,
111    UNW_ARM_F3,
112    UNW_ARM_F4,
113    UNW_ARM_F5,
114    UNW_ARM_F6,
115    UNW_ARM_F7,
116
117    /* iWMMXt GR register numberings.  */
118    UNW_ARM_wCGR0 = 104,
119    UNW_ARM_wCGR1,
120    UNW_ARM_wCGR2,
121    UNW_ARM_wCGR3,
122    UNW_ARM_wCGR4,
123    UNW_ARM_wCGR5,
124    UNW_ARM_wCGR6,
125    UNW_ARM_wCGR7,
126
127    /* iWMMXt register numberings.  */
128    UNW_ARM_wR0 = 112,
129    UNW_ARM_wR1,
130    UNW_ARM_wR2,
131    UNW_ARM_wR3,
132    UNW_ARM_wR4,
133    UNW_ARM_wR5,
134    UNW_ARM_wR6,
135    UNW_ARM_wR7,
136    UNW_ARM_wR8,
137    UNW_ARM_wR9,
138    UNW_ARM_wR10,
139    UNW_ARM_wR11,
140    UNW_ARM_wR12,
141    UNW_ARM_wR13,
142    UNW_ARM_wR14,
143    UNW_ARM_wR15,
144
145    /* Two-byte encodings from here on.  */
146
147    /* SPSR.  */
148    UNW_ARM_SPSR = 128,
149    UNW_ARM_SPSR_FIQ,
150    UNW_ARM_SPSR_IRQ,
151    UNW_ARM_SPSR_ABT,
152    UNW_ARM_SPSR_UND,
153    UNW_ARM_SPSR_SVC,
154
155    /* User mode registers.  */
156    UNW_ARM_R8_USR = 144,
157    UNW_ARM_R9_USR,
158    UNW_ARM_R10_USR,
159    UNW_ARM_R11_USR,
160    UNW_ARM_R12_USR,
161    UNW_ARM_R13_USR,
162    UNW_ARM_R14_USR,
163
164    /* FIQ registers.  */
165    UNW_ARM_R8_FIQ = 151,
166    UNW_ARM_R9_FIQ,
167    UNW_ARM_R10_FIQ,
168    UNW_ARM_R11_FIQ,
169    UNW_ARM_R12_FIQ,
170    UNW_ARM_R13_FIQ,
171    UNW_ARM_R14_FIQ,
172
173    /* IRQ registers.  */
174    UNW_ARM_R13_IRQ = 158,
175    UNW_ARM_R14_IRQ,
176
177    /* ABT registers.  */
178    UNW_ARM_R13_ABT = 160,
179    UNW_ARM_R14_ABT,
180
181    /* UND registers.  */
182    UNW_ARM_R13_UND = 162,
183    UNW_ARM_R14_UND,
184
185    /* SVC registers.  */
186    UNW_ARM_R13_SVC = 164,
187    UNW_ARM_R14_SVC,
188
189    /* iWMMXt control registers.  */
190    UNW_ARM_wC0 = 192,
191    UNW_ARM_wC1,
192    UNW_ARM_wC2,
193    UNW_ARM_wC3,
194    UNW_ARM_wC4,
195    UNW_ARM_wC5,
196    UNW_ARM_wC6,
197    UNW_ARM_wC7,
198
199    /* VFPv3/Neon 64-bit registers.  */
200    UNW_ARM_D0 = 256,
201    UNW_ARM_D1,
202    UNW_ARM_D2,
203    UNW_ARM_D3,
204    UNW_ARM_D4,
205    UNW_ARM_D5,
206    UNW_ARM_D6,
207    UNW_ARM_D7,
208    UNW_ARM_D8,
209    UNW_ARM_D9,
210    UNW_ARM_D10,
211    UNW_ARM_D11,
212    UNW_ARM_D12,
213    UNW_ARM_D13,
214    UNW_ARM_D14,
215    UNW_ARM_D15,
216    UNW_ARM_D16,
217    UNW_ARM_D17,
218    UNW_ARM_D18,
219    UNW_ARM_D19,
220    UNW_ARM_D20,
221    UNW_ARM_D21,
222    UNW_ARM_D22,
223    UNW_ARM_D23,
224    UNW_ARM_D24,
225    UNW_ARM_D25,
226    UNW_ARM_D26,
227    UNW_ARM_D27,
228    UNW_ARM_D28,
229    UNW_ARM_D29,
230    UNW_ARM_D30,
231    UNW_ARM_D31,
232
233    /* For ARM, the CFA is the value of SP (r13) at the call site in the
234       previous frame.  */
235    UNW_ARM_CFA,
236
237    UNW_TDEP_LAST_REG = UNW_ARM_D31,
238
239    UNW_TDEP_IP = UNW_ARM_R14,  /* A little white lie.  */
240    UNW_TDEP_SP = UNW_ARM_R13,
241    UNW_TDEP_EH = UNW_ARM_R0   /* FIXME.  */
242  }
243arm_regnum_t;
244
245#define UNW_TDEP_NUM_EH_REGS	2	/* FIXME for ARM.  */
246
247typedef struct unw_tdep_save_loc
248  {
249    /* Additional target-dependent info on a save location.  */
250    /* ANDROID support update. */
251    char __reserved;
252    /* End of ANDROID update. */
253  }
254unw_tdep_save_loc_t;
255
256/* On ARM, we define our own unw_tdep_context instead of using ucontext_t.
257   This allows us to support systems that don't support getcontext and
258   therefore do not define ucontext_t.  */
259typedef struct unw_tdep_context
260  {
261    unsigned long regs[16];
262  }
263unw_tdep_context_t;
264
265/* There is no getcontext() on ARM.  Use a stub version which only saves GP
266   registers.  FIXME: Not ideal, may not be sufficient for all libunwind
267   use cases.  Stores pc+8, which is only approximately correct, really.  */
268#ifndef __thumb__
269#define unw_tdep_getcontext(uc) (({					\
270  unw_tdep_context_t *unw_ctx = (uc);					\
271  register unsigned long *unw_base asm ("r0") = unw_ctx->regs;		\
272  __asm__ __volatile__ (						\
273    "stmia %[base], {r0-r15}"						\
274    : : [base] "r" (unw_base) : "memory");				\
275  }), 0)
276#else /* __thumb__ */
277#define unw_tdep_getcontext(uc) (({					\
278  unw_tdep_context_t *unw_ctx = (uc);					\
279  register unsigned long *unw_base asm ("r0") = unw_ctx->regs;		\
280  __asm__ __volatile__ (						\
281    ".align 2\nbx pc\nnop\n.code 32\n"					\
282    "stmia %[base], {r0-r15}\n"						\
283    "orr %[base], pc, #1\nbx %[base]"					\
284    : [base] "+r" (unw_base) : : "memory", "cc");			\
285  }), 0)
286#endif
287
288#include "libunwind-dynamic.h"
289
290typedef struct
291  {
292    /* no arm-specific auxiliary proc-info */
293    /* ANDROID support update. */
294    char __reserved;
295    /* End of ANDROID update. */
296  }
297unw_tdep_proc_info_t;
298
299#include "libunwind-common.h"
300
301#define unw_tdep_is_fpreg		UNW_ARCH_OBJ(is_fpreg)
302extern int unw_tdep_is_fpreg (int);
303
304#if defined(__cplusplus) || defined(c_plusplus)
305}
306#endif
307
308#endif /* LIBUNWIND_H */
309