Home | History | Annotate | Download | only in include
      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