1169689Skan/* Header file for the ARM EABI unwinder 2169689Skan Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 3169689Skan Contributed by Paul Brook 4169689Skan 5169689Skan This file is free software; you can redistribute it and/or modify it 6169689Skan under the terms of the GNU General Public License as published by the 7169689Skan Free Software Foundation; either version 2, or (at your option) any 8169689Skan later version. 9169689Skan 10169689Skan In addition to the permissions in the GNU General Public License, the 11169689Skan Free Software Foundation gives you unlimited permission to link the 12169689Skan compiled version of this file into combinations with other programs, 13169689Skan and to distribute those combinations without any restriction coming 14169689Skan from the use of this file. (The General Public License restrictions 15169689Skan do apply in other respects; for example, they cover modification of 16169689Skan the file, and distribution when not linked into a combine 17169689Skan executable.) 18169689Skan 19169689Skan This file is distributed in the hope that it will be useful, but 20169689Skan WITHOUT ANY WARRANTY; without even the implied warranty of 21169689Skan MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22169689Skan General Public License for more details. 23169689Skan 24169689Skan You should have received a copy of the GNU General Public License 25169689Skan along with this program; see the file COPYING. If not, write to 26169689Skan the Free Software Foundation, 51 Franklin Street, Fifth Floor, 27169689Skan Boston, MA 02110-1301, USA. */ 28169689Skan 29169689Skan/* Language-independent unwinder header public defines. This contains both 30169689Skan ABI defined objects, and GNU support routines. */ 31169689Skan 32169689Skan#ifndef UNWIND_ARM_H 33169689Skan#define UNWIND_ARM_H 34169689Skan 35169689Skan#define __ARM_EABI_UNWINDER__ 1 36169689Skan 37169689Skan#ifdef __cplusplus 38169689Skanextern "C" { 39169689Skan#endif 40169689Skan typedef unsigned _Unwind_Word __attribute__((__mode__(__word__))); 41169689Skan typedef signed _Unwind_Sword __attribute__((__mode__(__word__))); 42169689Skan typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__))); 43169689Skan typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__))); 44169689Skan typedef _Unwind_Word _uw; 45169689Skan typedef unsigned _uw64 __attribute__((mode(__DI__))); 46169689Skan typedef unsigned _uw16 __attribute__((mode(__HI__))); 47169689Skan typedef unsigned _uw8 __attribute__((mode(__QI__))); 48169689Skan 49169689Skan typedef enum 50169689Skan { 51169689Skan _URC_OK = 0, /* operation completed successfully */ 52169689Skan _URC_FOREIGN_EXCEPTION_CAUGHT = 1, 53169689Skan _URC_END_OF_STACK = 5, 54169689Skan _URC_HANDLER_FOUND = 6, 55169689Skan _URC_INSTALL_CONTEXT = 7, 56169689Skan _URC_CONTINUE_UNWIND = 8, 57169689Skan _URC_FAILURE = 9 /* unspecified failure of some kind */ 58169689Skan } 59169689Skan _Unwind_Reason_Code; 60169689Skan 61169689Skan typedef enum 62169689Skan { 63169689Skan _US_VIRTUAL_UNWIND_FRAME = 0, 64169689Skan _US_UNWIND_FRAME_STARTING = 1, 65169689Skan _US_UNWIND_FRAME_RESUME = 2, 66169689Skan _US_ACTION_MASK = 3, 67169689Skan _US_FORCE_UNWIND = 8, 68169689Skan _US_END_OF_STACK = 16 69169689Skan } 70169689Skan _Unwind_State; 71169689Skan 72169689Skan /* Provided only for for compatibility with existing code. */ 73169689Skan typedef int _Unwind_Action; 74169689Skan#define _UA_SEARCH_PHASE 1 75169689Skan#define _UA_CLEANUP_PHASE 2 76169689Skan#define _UA_HANDLER_FRAME 4 77169689Skan#define _UA_FORCE_UNWIND 8 78169689Skan#define _UA_END_OF_STACK 16 79169689Skan#define _URC_NO_REASON _URC_OK 80169689Skan 81169689Skan typedef struct _Unwind_Control_Block _Unwind_Control_Block; 82169689Skan typedef struct _Unwind_Context _Unwind_Context; 83169689Skan typedef _uw _Unwind_EHT_Header; 84169689Skan 85169689Skan 86169689Skan /* UCB: */ 87169689Skan 88169689Skan struct _Unwind_Control_Block 89169689Skan { 90246314Sandrew unsigned exception_class __attribute__((__mode__(__DI__))); 91169689Skan void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block *); 92169689Skan /* Unwinder cache, private fields for the unwinder's use */ 93169689Skan struct 94169689Skan { 95169689Skan _uw reserved1; /* Forced unwind stop fn, 0 if not forced */ 96169689Skan _uw reserved2; /* Personality routine address */ 97169689Skan _uw reserved3; /* Saved callsite address */ 98169689Skan _uw reserved4; /* Forced unwind stop arg */ 99169689Skan _uw reserved5; 100169689Skan } 101169689Skan unwinder_cache; 102169689Skan /* Propagation barrier cache (valid after phase 1): */ 103169689Skan struct 104169689Skan { 105169689Skan _uw sp; 106169689Skan _uw bitpattern[5]; 107169689Skan } 108169689Skan barrier_cache; 109169689Skan /* Cleanup cache (preserved over cleanup): */ 110169689Skan struct 111169689Skan { 112169689Skan _uw bitpattern[4]; 113169689Skan } 114169689Skan cleanup_cache; 115169689Skan /* Pr cache (for pr's benefit): */ 116169689Skan struct 117169689Skan { 118169689Skan _uw fnstart; /* function start address */ 119169689Skan _Unwind_EHT_Header *ehtp; /* pointer to EHT entry header word */ 120169689Skan _uw additional; /* additional data */ 121169689Skan _uw reserved1; 122169689Skan } 123169689Skan pr_cache; 124169689Skan long long int :0; /* Force alignment to 8-byte boundary */ 125169689Skan }; 126169689Skan 127169689Skan /* Virtual Register Set*/ 128169689Skan 129169689Skan typedef enum 130169689Skan { 131169689Skan _UVRSC_CORE = 0, /* integer register */ 132169689Skan _UVRSC_VFP = 1, /* vfp */ 133169689Skan _UVRSC_FPA = 2, /* fpa */ 134169689Skan _UVRSC_WMMXD = 3, /* Intel WMMX data register */ 135169689Skan _UVRSC_WMMXC = 4 /* Intel WMMX control register */ 136169689Skan } 137169689Skan _Unwind_VRS_RegClass; 138169689Skan 139169689Skan typedef enum 140169689Skan { 141169689Skan _UVRSD_UINT32 = 0, 142169689Skan _UVRSD_VFPX = 1, 143169689Skan _UVRSD_FPAX = 2, 144169689Skan _UVRSD_UINT64 = 3, 145169689Skan _UVRSD_FLOAT = 4, 146169689Skan _UVRSD_DOUBLE = 5 147169689Skan } 148169689Skan _Unwind_VRS_DataRepresentation; 149169689Skan 150169689Skan typedef enum 151169689Skan { 152169689Skan _UVRSR_OK = 0, 153169689Skan _UVRSR_NOT_IMPLEMENTED = 1, 154169689Skan _UVRSR_FAILED = 2 155169689Skan } 156169689Skan _Unwind_VRS_Result; 157169689Skan 158169689Skan /* Frame unwinding state. */ 159169689Skan typedef struct 160169689Skan { 161169689Skan /* The current word (bytes packed msb first). */ 162169689Skan _uw data; 163169689Skan /* Pointer to the next word of data. */ 164169689Skan _uw *next; 165169689Skan /* The number of bytes left in this word. */ 166169689Skan _uw8 bytes_left; 167169689Skan /* The number of words pointed to by ptr. */ 168169689Skan _uw8 words_left; 169169689Skan } 170169689Skan __gnu_unwind_state; 171169689Skan 172169689Skan typedef _Unwind_Reason_Code (*personality_routine) (_Unwind_State, 173169689Skan _Unwind_Control_Block *, _Unwind_Context *); 174169689Skan 175169689Skan _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *, _Unwind_VRS_RegClass, 176169689Skan _uw, _Unwind_VRS_DataRepresentation, 177169689Skan void *); 178169689Skan 179169689Skan _Unwind_VRS_Result _Unwind_VRS_Get(_Unwind_Context *, _Unwind_VRS_RegClass, 180169689Skan _uw, _Unwind_VRS_DataRepresentation, 181169689Skan void *); 182169689Skan 183169689Skan _Unwind_VRS_Result _Unwind_VRS_Pop(_Unwind_Context *, _Unwind_VRS_RegClass, 184169689Skan _uw, _Unwind_VRS_DataRepresentation); 185169689Skan 186169689Skan 187169689Skan /* Support functions for the PR. */ 188169689Skan#define _Unwind_Exception _Unwind_Control_Block 189246314Sandrew typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__))); 190169689Skan 191169689Skan void * _Unwind_GetLanguageSpecificData (_Unwind_Context *); 192169689Skan _Unwind_Ptr _Unwind_GetRegionStart (_Unwind_Context *); 193169689Skan 194169689Skan /* These two should never be used. */ 195169689Skan _Unwind_Ptr _Unwind_GetDataRelBase (_Unwind_Context *); 196169689Skan _Unwind_Ptr _Unwind_GetTextRelBase (_Unwind_Context *); 197169689Skan 198169689Skan /* Interface functions: */ 199169689Skan _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Control_Block *ucbp); 200169689Skan void __attribute__((noreturn)) _Unwind_Resume(_Unwind_Control_Block *ucbp); 201169689Skan _Unwind_Reason_Code _Unwind_Resume_or_Rethrow (_Unwind_Control_Block *ucbp); 202169689Skan 203169689Skan typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) 204169689Skan (int, _Unwind_Action, _Unwind_Exception_Class, 205169689Skan _Unwind_Control_Block *, struct _Unwind_Context *, void *); 206169689Skan _Unwind_Reason_Code _Unwind_ForcedUnwind (_Unwind_Control_Block *, 207169689Skan _Unwind_Stop_Fn, void *); 208255095Sandrew /* @@@ Use unwind data to perform a stack backtrace. The trace callback 209255095Sandrew is called for every stack frame in the call chain, but no cleanup 210255095Sandrew actions are performed. */ 211255095Sandrew typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (_Unwind_Context *, void *); 212255095Sandrew _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, 213255095Sandrew void*); 214255095Sandrew 215169689Skan _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *); 216169689Skan void _Unwind_Complete(_Unwind_Control_Block *ucbp); 217169689Skan void _Unwind_DeleteException (_Unwind_Exception *); 218169689Skan 219169689Skan _Unwind_Reason_Code __gnu_unwind_frame (_Unwind_Control_Block *, 220169689Skan _Unwind_Context *); 221169689Skan _Unwind_Reason_Code __gnu_unwind_execute (_Unwind_Context *, 222169689Skan __gnu_unwind_state *); 223169689Skan 224169689Skan /* Decode an R_ARM_TARGET2 relocation. */ 225169689Skan static inline _Unwind_Word 226169689Skan _Unwind_decode_target2 (_Unwind_Word ptr) 227169689Skan { 228169689Skan _Unwind_Word tmp; 229169689Skan 230169689Skan tmp = *(_Unwind_Word *) ptr; 231169689Skan /* Zero values are always NULL. */ 232169689Skan if (!tmp) 233169689Skan return 0; 234169689Skan 235169689Skan#if defined(linux) || defined(__NetBSD__) 236169689Skan /* Pc-relative indirect. */ 237169689Skan tmp += ptr; 238169689Skan tmp = *(_Unwind_Word *) tmp; 239169689Skan#elif defined(__symbian__) 240169689Skan /* Absolute pointer. Nothing more to do. */ 241169689Skan#else 242169689Skan /* Pc-relative pointer. */ 243169689Skan tmp += ptr; 244169689Skan#endif 245169689Skan return tmp; 246169689Skan } 247169689Skan 248169689Skan static inline _Unwind_Word 249169689Skan _Unwind_GetGR (_Unwind_Context *context, int regno) 250169689Skan { 251169689Skan _uw val; 252169689Skan _Unwind_VRS_Get (context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val); 253169689Skan return val; 254169689Skan } 255169689Skan 256255096Sandrew#ifndef __FreeBSD__ 257169689Skan /* Return the address of the instruction, not the actual IP value. */ 258169689Skan#define _Unwind_GetIP(context) \ 259169689Skan (_Unwind_GetGR (context, 15) & ~(_Unwind_Word)1) 260169689Skan 261169689Skan#define _Unwind_GetIPInfo(context, ip_before_insn) \ 262169689Skan (*ip_before_insn = 0, _Unwind_GetGR (context, 15) & ~(_Unwind_Word)1) 263255096Sandrew#else 264255096Sandrew _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *); 265255096Sandrew _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *, int *); 266255096Sandrew#endif 267169689Skan 268169689Skan static inline void 269169689Skan _Unwind_SetGR (_Unwind_Context *context, int regno, _Unwind_Word val) 270169689Skan { 271169689Skan _Unwind_VRS_Set (context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val); 272169689Skan } 273169689Skan 274169689Skan /* The dwarf unwinder doesn't understand arm/thumb state. We assume the 275169689Skan landing pad uses the same instruction set as the call site. */ 276169689Skan#define _Unwind_SetIP(context, val) \ 277169689Skan _Unwind_SetGR (context, 15, val | (_Unwind_GetGR (context, 15) & 1)) 278169689Skan 279169689Skan#ifdef __cplusplus 280169689Skan} /* extern "C" */ 281169689Skan#endif 282169689Skan 283169689Skan#endif /* defined UNWIND_ARM_H */ 284