1122715Sbde/* Header file for the ARM EABI unwinder 2122715Sbde Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 3122715Sbde Contributed by Paul Brook 4122715Sbde 5122715Sbde This file is free software; you can redistribute it and/or modify it 685909Simp under the terms of the GNU General Public License as published by the 788893Simp Free Software Foundation; either version 2, or (at your option) any 888893Simp later version. 988969Simp 1085909Simp In addition to the permissions in the GNU General Public License, the 11115572Sphk Free Software Foundation gives you unlimited permission to link the 12115572Sphk compiled version of this file into combinations with other programs, 13115572Sphk and to distribute those combinations without any restriction coming 14115572Sphk from the use of this file. (The General Public License restrictions 15124108Simp do apply in other respects; for example, they cover modification of 16115572Sphk the file, and distribution when not linked into a combine 17111211Sru executable.) 1885909Simp 19111802Sru This file is distributed in the hope that it will be useful, but 20111802Sru WITHOUT ANY WARRANTY; without even the implied warranty of 21111211Sru MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22111211Sru General Public License for more details. 23111211Sru 24111211Sru You should have received a copy of the GNU General Public License 25111802Sru along with this program; see the file COPYING. If not, write to 26111802Sru the Free Software Foundation, 51 Franklin Street, Fifth Floor, 27111211Sru Boston, MA 02110-1301, USA. */ 28111211Sru 2985909Simp/* Language-independent unwinder header public defines. This contains both 30137596Simp ABI defined objects, and GNU support routines. */ 31147155Simp 32151732Sru#ifndef UNWIND_ARM_H 33137596Simp#define UNWIND_ARM_H 34147011Smux 35142424Simp#define __ARM_EABI_UNWINDER__ 1 36142413Simp 37137596Simp#ifdef __cplusplus 38147011Smuxextern "C" { 39137596Simp#endif 40137596Simp typedef unsigned _Unwind_Word __attribute__((__mode__(__word__))); 41137596Simp typedef signed _Unwind_Sword __attribute__((__mode__(__word__))); 42137596Simp typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__))); 43111211Sru typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__))); 44111211Sru typedef _Unwind_Word _uw; 45111211Sru typedef unsigned _uw64 __attribute__((mode(__DI__))); 46111211Sru typedef unsigned _uw16 __attribute__((mode(__HI__))); 47155427Sru typedef unsigned _uw8 __attribute__((mode(__QI__))); 48111802Sru 49111802Sru typedef enum 50111766Sru { 51111211Sru _URC_OK = 0, /* operation completed successfully */ 52111766Sru _URC_FOREIGN_EXCEPTION_CAUGHT = 1, 53111766Sru _URC_END_OF_STACK = 5, 54111211Sru _URC_HANDLER_FOUND = 6, 55111211Sru _URC_INSTALL_CONTEXT = 7, 56111211Sru _URC_CONTINUE_UNWIND = 8, 57111211Sru _URC_FAILURE = 9 /* unspecified failure of some kind */ 58111211Sru } 59111211Sru _Unwind_Reason_Code; 60111211Sru 61111211Sru typedef enum 62151636Simp { 63151636Simp _US_VIRTUAL_UNWIND_FRAME = 0, 64151636Simp _US_UNWIND_FRAME_STARTING = 1, 65151636Simp _US_UNWIND_FRAME_RESUME = 2, 66151750Sru _US_ACTION_MASK = 3, 67151750Sru _US_FORCE_UNWIND = 8, 68151731Sru _US_END_OF_STACK = 16 69151750Sru } 70151731Sru _Unwind_State; 71151646Sru 72151646Sru /* Provided only for for compatibility with existing code. */ 73116252Sgrog typedef int _Unwind_Action; 74123965Sbde#define _UA_SEARCH_PHASE 1 75116252Sgrog#define _UA_CLEANUP_PHASE 2 76123965Sbde#define _UA_HANDLER_FRAME 4 77123965Sbde#define _UA_FORCE_UNWIND 8 78135611Sphk#define _UA_END_OF_STACK 16 79124776Sru#define _URC_NO_REASON _URC_OK 80116252Sgrog 81123965Sbde typedef struct _Unwind_Control_Block _Unwind_Control_Block; 8285909Simp typedef struct _Unwind_Context _Unwind_Context; 83124776Sru typedef _uw _Unwind_EHT_Header; 8485909Simp 85151636Simp 8685909Simp /* UCB: */ 8785909Simp 8885909Simp struct _Unwind_Control_Block 89125775Sru { 90125775Sru unsigned exception_class __attribute__((__mode__(__DI__))); 91125775Sru void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block *); 9285909Simp /* Unwinder cache, private fields for the unwinder's use */ 93159560Scognet struct 94159560Scognet { 95159560Scognet _uw reserved1; /* Forced unwind stop fn, 0 if not forced */ 96159560Scognet _uw reserved2; /* Personality routine address */ 97159560Scognet _uw reserved3; /* Saved callsite address */ 98159560Scognet _uw reserved4; /* Forced unwind stop arg */ 99159560Scognet _uw reserved5; 100159560Scognet } 101159560Scognet unwinder_cache; 10285909Simp /* Propagation barrier cache (valid after phase 1): */ 103116691Sru struct 104131129Simp { 10585909Simp _uw sp; 10685909Simp _uw bitpattern[5]; 107116341Smarkm } 108116341Smarkm barrier_cache; 10985909Simp /* Cleanup cache (preserved over cleanup): */ 110102082Sbde struct 111102082Sbde { 112102082Sbde _uw bitpattern[4]; 113102082Sbde } 11485909Simp cleanup_cache; 11595844Sobrien /* Pr cache (for pr's benefit): */ 11685909Simp struct 11785909Simp { 11885909Simp _uw fnstart; /* function start address */ 11985909Simp _Unwind_EHT_Header *ehtp; /* pointer to EHT entry header word */ 120151750Sru _uw additional; /* additional data */ 121151731Sru _uw reserved1; 122145416Sru } 123123965Sbde pr_cache; 124163332Sru long long int :0; /* Force alignment to 8-byte boundary */ 12585909Simp }; 126116341Smarkm 127123965Sbde /* Virtual Register Set*/ 128123965Sbde 12992491Smarkm typedef enum 13085909Simp { 13185909Simp _UVRSC_CORE = 0, /* integer register */ 13285909Simp _UVRSC_VFP = 1, /* vfp */ 13385909Simp _UVRSC_FPA = 2, /* fpa */ 13485909Simp _UVRSC_WMMXD = 3, /* Intel WMMX data register */ 135161283Sdes _UVRSC_WMMXC = 4 /* Intel WMMX control register */ 136123966Sbde } 13785909Simp _Unwind_VRS_RegClass; 13885909Simp 139123965Sbde typedef enum 14085909Simp { 14185909Simp _UVRSD_UINT32 = 0, 14285909Simp _UVRSD_VFPX = 1, 143127306Sobrien _UVRSD_FPAX = 2, 14485909Simp _UVRSD_UINT64 = 3, 14585909Simp _UVRSD_FLOAT = 4, 146123985Sbde _UVRSD_DOUBLE = 5 14785909Simp } 14885909Simp _Unwind_VRS_DataRepresentation; 14985909Simp 150145403Sru typedef enum 151102073Sbde { 15291104Sjake _UVRSR_OK = 0, 153152964Sru _UVRSR_NOT_IMPLEMENTED = 1, 154152964Sru _UVRSR_FAILED = 2 155152964Sru } 156163332Sru _Unwind_VRS_Result; 15785909Simp 158131210Simp /* Frame unwinding state. */ 159102073Sbde typedef struct 160111684Sru { 161102073Sbde /* The current word (bytes packed msb first). */ 16285909Simp _uw data; 16385909Simp /* Pointer to the next word of data. */ 16485909Simp _uw *next; 165152964Sru /* The number of bytes left in this word. */ 166152964Sru _uw8 bytes_left; 167152964Sru /* The number of words pointed to by ptr. */ 168152964Sru _uw8 words_left; 169152964Sru } 170152964Sru __gnu_unwind_state; 171152964Sru 172152964Sru typedef _Unwind_Reason_Code (*personality_routine) (_Unwind_State, 173152964Sru _Unwind_Control_Block *, _Unwind_Context *); 174152964Sru 175152964Sru _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *, _Unwind_VRS_RegClass, 176152964Sru _uw, _Unwind_VRS_DataRepresentation, 177152964Sru void *); 178152964Sru 179152964Sru _Unwind_VRS_Result _Unwind_VRS_Get(_Unwind_Context *, _Unwind_VRS_RegClass, 180152964Sru _uw, _Unwind_VRS_DataRepresentation, 181152964Sru void *); 182152964Sru 183152964Sru _Unwind_VRS_Result _Unwind_VRS_Pop(_Unwind_Context *, _Unwind_VRS_RegClass, 184152964Sru _uw, _Unwind_VRS_DataRepresentation); 185152964Sru 186152964Sru 187163332Sru /* Support functions for the PR. */ 18885909Simp#define _Unwind_Exception _Unwind_Control_Block 189163332Sru typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__))); 19085909Simp 19185909Simp void * _Unwind_GetLanguageSpecificData (_Unwind_Context *); 19285909Simp _Unwind_Ptr _Unwind_GetRegionStart (_Unwind_Context *); 193123965Sbde 19491046Sluigi /* These two should never be used. */ 195123965Sbde _Unwind_Ptr _Unwind_GetDataRelBase (_Unwind_Context *); 196123965Sbde _Unwind_Ptr _Unwind_GetTextRelBase (_Unwind_Context *); 19785909Simp 19885909Simp /* Interface functions: */ 19985909Simp _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Control_Block *ucbp); 20085909Simp void __attribute__((noreturn)) _Unwind_Resume(_Unwind_Control_Block *ucbp); 20185909Simp _Unwind_Reason_Code _Unwind_Resume_or_Rethrow (_Unwind_Control_Block *ucbp); 20285909Simp 203127246Smarcel typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) 204151731Sru (int, _Unwind_Action, _Unwind_Exception_Class, 20585909Simp _Unwind_Control_Block *, struct _Unwind_Context *, void *); 20685909Simp _Unwind_Reason_Code _Unwind_ForcedUnwind (_Unwind_Control_Block *, 20785909Simp _Unwind_Stop_Fn, void *); 20885909Simp /* @@@ Use unwind data to perform a stack backtrace. The trace callback 20985909Simp is called for every stack frame in the call chain, but no cleanup 210145623Sru actions are performed. */ 21185909Simp typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (_Unwind_Context *, void *); 21285909Simp _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, 21385909Simp void*); 21485909Simp 21585909Simp _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *); 21685909Simp void _Unwind_Complete(_Unwind_Control_Block *ucbp); 21785909Simp void _Unwind_DeleteException (_Unwind_Exception *); 21885909Simp 219118633Sru _Unwind_Reason_Code __gnu_unwind_frame (_Unwind_Control_Block *, 22085909Simp _Unwind_Context *); 22185909Simp _Unwind_Reason_Code __gnu_unwind_execute (_Unwind_Context *, 22285909Simp __gnu_unwind_state *); 223151731Sru 224151636Simp /* Decode an R_ARM_TARGET2 relocation. */ 225151750Sru static inline _Unwind_Word 226151636Simp _Unwind_decode_target2 (_Unwind_Word ptr) 22785909Simp { 22895356Sru _Unwind_Word tmp; 22985909Simp 230151731Sru tmp = *(_Unwind_Word *) ptr; 231151636Simp /* Zero values are always NULL. */ 232151750Sru if (!tmp) 233151636Simp return 0; 23485909Simp 235144293Sphk#if defined(linux) || defined(__NetBSD__) || defined(__FreeBSD__) 23685909Simp /* Pc-relative indirect. */ 23785909Simp tmp += ptr; 238144293Sphk tmp = *(_Unwind_Word *) tmp; 239116341Smarkm#elif defined(__symbian__) 240116341Smarkm /* Absolute pointer. Nothing more to do. */ 24185909Simp#else 242135371Sru /* Pc-relative pointer. */ 24385909Simp tmp += ptr; 24491512Sobrien#endif 24591512Sobrien return tmp; 24685909Simp } 24791512Sobrien 24891512Sobrien static inline _Unwind_Word 249138290Sphk _Unwind_GetGR (_Unwind_Context *context, int regno) 250138290Sphk { 25185909Simp _uw val; 252116691Sru _Unwind_VRS_Get (context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val); 253116691Sru return val; 25485909Simp } 255111686Sru 256#ifndef __FreeBSD__ 257 /* Return the address of the instruction, not the actual IP value. */ 258#define _Unwind_GetIP(context) \ 259 (_Unwind_GetGR (context, 15) & ~(_Unwind_Word)1) 260 261#define _Unwind_GetIPInfo(context, ip_before_insn) \ 262 (*ip_before_insn = 0, _Unwind_GetGR (context, 15) & ~(_Unwind_Word)1) 263#else 264 _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *); 265 _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *, int *); 266#endif 267 268 static inline void 269 _Unwind_SetGR (_Unwind_Context *context, int regno, _Unwind_Word val) 270 { 271 _Unwind_VRS_Set (context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val); 272 } 273 274 /* The dwarf unwinder doesn't understand arm/thumb state. We assume the 275 landing pad uses the same instruction set as the call site. */ 276#define _Unwind_SetIP(context, val) \ 277 _Unwind_SetGR (context, 15, val | (_Unwind_GetGR (context, 15) & 1)) 278 279#ifdef __cplusplus 280} /* extern "C" */ 281#endif 282 283#endif /* defined UNWIND_ARM_H */ 284