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