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 #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 49 typedef uint32_t unw_word_t; 50 typedef int32_t unw_sword_t; 51 52 typedef long double unw_tdep_fpreg_t; 53 54 typedef 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 } 243 arm_regnum_t; 244 245 #define UNW_TDEP_NUM_EH_REGS 2 /* FIXME for ARM. */ 246 247 typedef 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 } 254 unw_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. */ 259 typedef struct unw_tdep_context 260 { 261 unsigned long regs[16]; 262 } 263 unw_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 290 typedef struct 291 { 292 /* no arm-specific auxiliary proc-info */ 293 /* ANDROID support update. */ 294 char __reserved; 295 /* End of ANDROID update. */ 296 } 297 unw_tdep_proc_info_t; 298 299 #include "libunwind-common.h" 300 301 #define unw_tdep_is_fpreg UNW_ARCH_OBJ(is_fpreg) 302 extern int unw_tdep_is_fpreg (int); 303 304 #if defined(__cplusplus) || defined(c_plusplus) 305 } 306 #endif 307 308 #endif /* LIBUNWIND_H */ 309