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