1*53ee8cc1Swenshuai.xi /* Exception handling and frame unwind runtime interface routines.
2*53ee8cc1Swenshuai.xi Copyright (C) 2001, 2003, 2004, 2006 Free Software Foundation, Inc.
3*53ee8cc1Swenshuai.xi
4*53ee8cc1Swenshuai.xi This file is part of GCC.
5*53ee8cc1Swenshuai.xi
6*53ee8cc1Swenshuai.xi GCC is free software; you can redistribute it and/or modify it
7*53ee8cc1Swenshuai.xi under the terms of the GNU General Public License as published by
8*53ee8cc1Swenshuai.xi the Free Software Foundation; either version 2, or (at your option)
9*53ee8cc1Swenshuai.xi any later version.
10*53ee8cc1Swenshuai.xi
11*53ee8cc1Swenshuai.xi GCC is distributed in the hope that it will be useful, but WITHOUT
12*53ee8cc1Swenshuai.xi ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13*53ee8cc1Swenshuai.xi or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14*53ee8cc1Swenshuai.xi License for more details.
15*53ee8cc1Swenshuai.xi
16*53ee8cc1Swenshuai.xi You should have received a copy of the GNU General Public License
17*53ee8cc1Swenshuai.xi along with GCC; see the file COPYING. If not, write to the Free
18*53ee8cc1Swenshuai.xi Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19*53ee8cc1Swenshuai.xi 02110-1301, USA. */
20*53ee8cc1Swenshuai.xi
21*53ee8cc1Swenshuai.xi /* As a special exception, if you include this header file into source
22*53ee8cc1Swenshuai.xi files compiled by GCC, this header file does not by itself cause
23*53ee8cc1Swenshuai.xi the resulting executable to be covered by the GNU General Public
24*53ee8cc1Swenshuai.xi License. This exception does not however invalidate any other
25*53ee8cc1Swenshuai.xi reasons why the executable file might be covered by the GNU General
26*53ee8cc1Swenshuai.xi Public License. */
27*53ee8cc1Swenshuai.xi
28*53ee8cc1Swenshuai.xi /* This is derived from the C++ ABI for IA-64. Where we diverge
29*53ee8cc1Swenshuai.xi for cross-architecture compatibility are noted with "@@@". */
30*53ee8cc1Swenshuai.xi
31*53ee8cc1Swenshuai.xi #ifndef _UNWIND_H
32*53ee8cc1Swenshuai.xi #define _UNWIND_H
33*53ee8cc1Swenshuai.xi
34*53ee8cc1Swenshuai.xi #ifndef HIDE_EXPORTS
35*53ee8cc1Swenshuai.xi #pragma GCC visibility push(default)
36*53ee8cc1Swenshuai.xi #endif
37*53ee8cc1Swenshuai.xi
38*53ee8cc1Swenshuai.xi #ifdef __cplusplus
39*53ee8cc1Swenshuai.xi extern "C" {
40*53ee8cc1Swenshuai.xi #endif
41*53ee8cc1Swenshuai.xi
42*53ee8cc1Swenshuai.xi /* Level 1: Base ABI */
43*53ee8cc1Swenshuai.xi
44*53ee8cc1Swenshuai.xi /* @@@ The IA-64 ABI uses uint64 throughout. Most places this is
45*53ee8cc1Swenshuai.xi inefficient for 32-bit and smaller machines. */
46*53ee8cc1Swenshuai.xi typedef unsigned _Unwind_Word __attribute__((__mode__(__unwind_word__)));
47*53ee8cc1Swenshuai.xi typedef signed _Unwind_Sword __attribute__((__mode__(__unwind_word__)));
48*53ee8cc1Swenshuai.xi #if defined(__ia64__) && defined(__hpux__)
49*53ee8cc1Swenshuai.xi typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__)));
50*53ee8cc1Swenshuai.xi #else
51*53ee8cc1Swenshuai.xi typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
52*53ee8cc1Swenshuai.xi #endif
53*53ee8cc1Swenshuai.xi typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__)));
54*53ee8cc1Swenshuai.xi
55*53ee8cc1Swenshuai.xi /* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and
56*53ee8cc1Swenshuai.xi consumer of an exception. We'll go along with this for now even on
57*53ee8cc1Swenshuai.xi 32-bit machines. We'll need to provide some other option for
58*53ee8cc1Swenshuai.xi 16-bit machines and for machines with > 8 bits per byte. */
59*53ee8cc1Swenshuai.xi typedef unsigned _Unwind_Exception_Class __attribute__((__mode__(__DI__)));
60*53ee8cc1Swenshuai.xi
61*53ee8cc1Swenshuai.xi /* The unwind interface uses reason codes in several contexts to
62*53ee8cc1Swenshuai.xi identify the reasons for failures or other actions. */
63*53ee8cc1Swenshuai.xi typedef enum
64*53ee8cc1Swenshuai.xi {
65*53ee8cc1Swenshuai.xi _URC_NO_REASON = 0,
66*53ee8cc1Swenshuai.xi _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
67*53ee8cc1Swenshuai.xi _URC_FATAL_PHASE2_ERROR = 2,
68*53ee8cc1Swenshuai.xi _URC_FATAL_PHASE1_ERROR = 3,
69*53ee8cc1Swenshuai.xi _URC_NORMAL_STOP = 4,
70*53ee8cc1Swenshuai.xi _URC_END_OF_STACK = 5,
71*53ee8cc1Swenshuai.xi _URC_HANDLER_FOUND = 6,
72*53ee8cc1Swenshuai.xi _URC_INSTALL_CONTEXT = 7,
73*53ee8cc1Swenshuai.xi _URC_CONTINUE_UNWIND = 8
74*53ee8cc1Swenshuai.xi } _Unwind_Reason_Code;
75*53ee8cc1Swenshuai.xi
76*53ee8cc1Swenshuai.xi
77*53ee8cc1Swenshuai.xi /* The unwind interface uses a pointer to an exception header object
78*53ee8cc1Swenshuai.xi as its representation of an exception being thrown. In general, the
79*53ee8cc1Swenshuai.xi full representation of an exception object is language- and
80*53ee8cc1Swenshuai.xi implementation-specific, but it will be prefixed by a header
81*53ee8cc1Swenshuai.xi understood by the unwind interface. */
82*53ee8cc1Swenshuai.xi
83*53ee8cc1Swenshuai.xi struct _Unwind_Exception;
84*53ee8cc1Swenshuai.xi
85*53ee8cc1Swenshuai.xi typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code,
86*53ee8cc1Swenshuai.xi struct _Unwind_Exception *);
87*53ee8cc1Swenshuai.xi
88*53ee8cc1Swenshuai.xi struct _Unwind_Exception
89*53ee8cc1Swenshuai.xi {
90*53ee8cc1Swenshuai.xi _Unwind_Exception_Class exception_class;
91*53ee8cc1Swenshuai.xi _Unwind_Exception_Cleanup_Fn exception_cleanup;
92*53ee8cc1Swenshuai.xi _Unwind_Word private_1;
93*53ee8cc1Swenshuai.xi _Unwind_Word private_2;
94*53ee8cc1Swenshuai.xi
95*53ee8cc1Swenshuai.xi /* @@@ The IA-64 ABI says that this structure must be double-word aligned.
96*53ee8cc1Swenshuai.xi Taking that literally does not make much sense generically. Instead we
97*53ee8cc1Swenshuai.xi provide the maximum alignment required by any type for the machine. */
98*53ee8cc1Swenshuai.xi } __attribute__((__aligned__));
99*53ee8cc1Swenshuai.xi
100*53ee8cc1Swenshuai.xi
101*53ee8cc1Swenshuai.xi /* The ACTIONS argument to the personality routine is a bitwise OR of one
102*53ee8cc1Swenshuai.xi or more of the following constants. */
103*53ee8cc1Swenshuai.xi typedef int _Unwind_Action;
104*53ee8cc1Swenshuai.xi
105*53ee8cc1Swenshuai.xi #define _UA_SEARCH_PHASE 1
106*53ee8cc1Swenshuai.xi #define _UA_CLEANUP_PHASE 2
107*53ee8cc1Swenshuai.xi #define _UA_HANDLER_FRAME 4
108*53ee8cc1Swenshuai.xi #define _UA_FORCE_UNWIND 8
109*53ee8cc1Swenshuai.xi #define _UA_END_OF_STACK 16
110*53ee8cc1Swenshuai.xi
111*53ee8cc1Swenshuai.xi /* The target can override this macro to define any back-end-specific
112*53ee8cc1Swenshuai.xi attributes required for the lowest-level stack frame. */
113*53ee8cc1Swenshuai.xi #ifndef LIBGCC2_UNWIND_ATTRIBUTE
114*53ee8cc1Swenshuai.xi #define LIBGCC2_UNWIND_ATTRIBUTE
115*53ee8cc1Swenshuai.xi #endif
116*53ee8cc1Swenshuai.xi
117*53ee8cc1Swenshuai.xi /* This is an opaque type used to refer to a system-specific data
118*53ee8cc1Swenshuai.xi structure used by the system unwinder. This context is created and
119*53ee8cc1Swenshuai.xi destroyed by the system, and passed to the personality routine
120*53ee8cc1Swenshuai.xi during unwinding. */
121*53ee8cc1Swenshuai.xi struct _Unwind_Context;
122*53ee8cc1Swenshuai.xi
123*53ee8cc1Swenshuai.xi /* Raise an exception, passing along the given exception object. */
124*53ee8cc1Swenshuai.xi extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
125*53ee8cc1Swenshuai.xi _Unwind_RaiseException (struct _Unwind_Exception *);
126*53ee8cc1Swenshuai.xi
127*53ee8cc1Swenshuai.xi /* Raise an exception for forced unwinding. */
128*53ee8cc1Swenshuai.xi
129*53ee8cc1Swenshuai.xi typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
130*53ee8cc1Swenshuai.xi (int, _Unwind_Action, _Unwind_Exception_Class,
131*53ee8cc1Swenshuai.xi struct _Unwind_Exception *, struct _Unwind_Context *, void *);
132*53ee8cc1Swenshuai.xi
133*53ee8cc1Swenshuai.xi extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
134*53ee8cc1Swenshuai.xi _Unwind_ForcedUnwind (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
135*53ee8cc1Swenshuai.xi
136*53ee8cc1Swenshuai.xi /* Helper to invoke the exception_cleanup routine. */
137*53ee8cc1Swenshuai.xi extern void _Unwind_DeleteException (struct _Unwind_Exception *);
138*53ee8cc1Swenshuai.xi
139*53ee8cc1Swenshuai.xi /* Resume propagation of an existing exception. This is used after
140*53ee8cc1Swenshuai.xi e.g. executing cleanup code, and not to implement rethrowing. */
141*53ee8cc1Swenshuai.xi extern void LIBGCC2_UNWIND_ATTRIBUTE
142*53ee8cc1Swenshuai.xi _Unwind_Resume (struct _Unwind_Exception *);
143*53ee8cc1Swenshuai.xi
144*53ee8cc1Swenshuai.xi /* @@@ Resume propagation of a FORCE_UNWIND exception, or to rethrow
145*53ee8cc1Swenshuai.xi a normal exception that was handled. */
146*53ee8cc1Swenshuai.xi extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
147*53ee8cc1Swenshuai.xi _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *);
148*53ee8cc1Swenshuai.xi
149*53ee8cc1Swenshuai.xi /* @@@ Use unwind data to perform a stack backtrace. The trace callback
150*53ee8cc1Swenshuai.xi is called for every stack frame in the call chain, but no cleanup
151*53ee8cc1Swenshuai.xi actions are performed. */
152*53ee8cc1Swenshuai.xi typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)
153*53ee8cc1Swenshuai.xi (struct _Unwind_Context *, void *);
154*53ee8cc1Swenshuai.xi
155*53ee8cc1Swenshuai.xi extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
156*53ee8cc1Swenshuai.xi _Unwind_Backtrace (_Unwind_Trace_Fn, void *);
157*53ee8cc1Swenshuai.xi
158*53ee8cc1Swenshuai.xi /* These functions are used for communicating information about the unwind
159*53ee8cc1Swenshuai.xi context (i.e. the unwind descriptors and the user register state) between
160*53ee8cc1Swenshuai.xi the unwind library and the personality routine and landing pad. Only
161*53ee8cc1Swenshuai.xi selected registers may be manipulated. */
162*53ee8cc1Swenshuai.xi
163*53ee8cc1Swenshuai.xi extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int);
164*53ee8cc1Swenshuai.xi extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word);
165*53ee8cc1Swenshuai.xi
166*53ee8cc1Swenshuai.xi extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *);
167*53ee8cc1Swenshuai.xi extern _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *, int *);
168*53ee8cc1Swenshuai.xi extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr);
169*53ee8cc1Swenshuai.xi
170*53ee8cc1Swenshuai.xi /* @@@ Retrieve the CFA of the given context. */
171*53ee8cc1Swenshuai.xi extern _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *);
172*53ee8cc1Swenshuai.xi
173*53ee8cc1Swenshuai.xi extern void *_Unwind_GetLanguageSpecificData (struct _Unwind_Context *);
174*53ee8cc1Swenshuai.xi
175*53ee8cc1Swenshuai.xi extern _Unwind_Ptr _Unwind_GetRegionStart (struct _Unwind_Context *);
176*53ee8cc1Swenshuai.xi
177*53ee8cc1Swenshuai.xi
178*53ee8cc1Swenshuai.xi /* The personality routine is the function in the C++ (or other language)
179*53ee8cc1Swenshuai.xi runtime library which serves as an interface between the system unwind
180*53ee8cc1Swenshuai.xi library and language-specific exception handling semantics. It is
181*53ee8cc1Swenshuai.xi specific to the code fragment described by an unwind info block, and
182*53ee8cc1Swenshuai.xi it is always referenced via the pointer in the unwind info block, and
183*53ee8cc1Swenshuai.xi hence it has no ABI-specified name.
184*53ee8cc1Swenshuai.xi
185*53ee8cc1Swenshuai.xi Note that this implies that two different C++ implementations can
186*53ee8cc1Swenshuai.xi use different names, and have different contents in the language
187*53ee8cc1Swenshuai.xi specific data area. Moreover, that the language specific data
188*53ee8cc1Swenshuai.xi area contains no version info because name of the function invoked
189*53ee8cc1Swenshuai.xi provides more effective versioning by detecting at link time the
190*53ee8cc1Swenshuai.xi lack of code to handle the different data format. */
191*53ee8cc1Swenshuai.xi
192*53ee8cc1Swenshuai.xi typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)
193*53ee8cc1Swenshuai.xi (int, _Unwind_Action, _Unwind_Exception_Class,
194*53ee8cc1Swenshuai.xi struct _Unwind_Exception *, struct _Unwind_Context *);
195*53ee8cc1Swenshuai.xi
196*53ee8cc1Swenshuai.xi /* @@@ The following alternate entry points are for setjmp/longjmp
197*53ee8cc1Swenshuai.xi based unwinding. */
198*53ee8cc1Swenshuai.xi
199*53ee8cc1Swenshuai.xi struct SjLj_Function_Context;
200*53ee8cc1Swenshuai.xi extern void _Unwind_SjLj_Register (struct SjLj_Function_Context *);
201*53ee8cc1Swenshuai.xi extern void _Unwind_SjLj_Unregister (struct SjLj_Function_Context *);
202*53ee8cc1Swenshuai.xi
203*53ee8cc1Swenshuai.xi extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
204*53ee8cc1Swenshuai.xi _Unwind_SjLj_RaiseException (struct _Unwind_Exception *);
205*53ee8cc1Swenshuai.xi extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
206*53ee8cc1Swenshuai.xi _Unwind_SjLj_ForcedUnwind (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
207*53ee8cc1Swenshuai.xi extern void LIBGCC2_UNWIND_ATTRIBUTE
208*53ee8cc1Swenshuai.xi _Unwind_SjLj_Resume (struct _Unwind_Exception *);
209*53ee8cc1Swenshuai.xi extern _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
210*53ee8cc1Swenshuai.xi _Unwind_SjLj_Resume_or_Rethrow (struct _Unwind_Exception *);
211*53ee8cc1Swenshuai.xi
212*53ee8cc1Swenshuai.xi /* @@@ The following provide access to the base addresses for text
213*53ee8cc1Swenshuai.xi and data-relative addressing in the LDSA. In order to stay link
214*53ee8cc1Swenshuai.xi compatible with the standard ABI for IA-64, we inline these. */
215*53ee8cc1Swenshuai.xi
216*53ee8cc1Swenshuai.xi #ifdef __ia64__
217*53ee8cc1Swenshuai.xi #include <stdlib.h>
218*53ee8cc1Swenshuai.xi
219*53ee8cc1Swenshuai.xi static inline _Unwind_Ptr
_Unwind_GetDataRelBase(struct _Unwind_Context * _C)220*53ee8cc1Swenshuai.xi _Unwind_GetDataRelBase (struct _Unwind_Context *_C)
221*53ee8cc1Swenshuai.xi {
222*53ee8cc1Swenshuai.xi /* The GP is stored in R1. */
223*53ee8cc1Swenshuai.xi return _Unwind_GetGR (_C, 1);
224*53ee8cc1Swenshuai.xi }
225*53ee8cc1Swenshuai.xi
226*53ee8cc1Swenshuai.xi static inline _Unwind_Ptr
_Unwind_GetTextRelBase(struct _Unwind_Context * _C)227*53ee8cc1Swenshuai.xi _Unwind_GetTextRelBase (struct _Unwind_Context *_C __attribute__ ((__unused__)))
228*53ee8cc1Swenshuai.xi {
229*53ee8cc1Swenshuai.xi abort ();
230*53ee8cc1Swenshuai.xi return 0;
231*53ee8cc1Swenshuai.xi }
232*53ee8cc1Swenshuai.xi
233*53ee8cc1Swenshuai.xi /* @@@ Retrieve the Backing Store Pointer of the given context. */
234*53ee8cc1Swenshuai.xi extern _Unwind_Word _Unwind_GetBSP (struct _Unwind_Context *);
235*53ee8cc1Swenshuai.xi #else
236*53ee8cc1Swenshuai.xi extern _Unwind_Ptr _Unwind_GetDataRelBase (struct _Unwind_Context *);
237*53ee8cc1Swenshuai.xi extern _Unwind_Ptr _Unwind_GetTextRelBase (struct _Unwind_Context *);
238*53ee8cc1Swenshuai.xi #endif
239*53ee8cc1Swenshuai.xi
240*53ee8cc1Swenshuai.xi /* @@@ Given an address, return the entry point of the function that
241*53ee8cc1Swenshuai.xi contains it. */
242*53ee8cc1Swenshuai.xi extern void * _Unwind_FindEnclosingFunction (void *pc);
243*53ee8cc1Swenshuai.xi
244*53ee8cc1Swenshuai.xi #ifndef __SIZEOF_LONG__
245*53ee8cc1Swenshuai.xi #error "__SIZEOF_LONG__ macro not defined"
246*53ee8cc1Swenshuai.xi #endif
247*53ee8cc1Swenshuai.xi
248*53ee8cc1Swenshuai.xi #ifndef __SIZEOF_POINTER__
249*53ee8cc1Swenshuai.xi #error "__SIZEOF_POINTER__ macro not defined"
250*53ee8cc1Swenshuai.xi #endif
251*53ee8cc1Swenshuai.xi
252*53ee8cc1Swenshuai.xi
253*53ee8cc1Swenshuai.xi /* leb128 type numbers have a potentially unlimited size.
254*53ee8cc1Swenshuai.xi The target of the following definitions of _sleb128_t and _uleb128_t
255*53ee8cc1Swenshuai.xi is to have efficient data types large enough to hold the leb128 type
256*53ee8cc1Swenshuai.xi numbers used in the unwind code.
257*53ee8cc1Swenshuai.xi Mostly these types will simply be defined to long and unsigned long
258*53ee8cc1Swenshuai.xi except when a unsigned long data type on the target machine is not
259*53ee8cc1Swenshuai.xi capable of storing a pointer. */
260*53ee8cc1Swenshuai.xi
261*53ee8cc1Swenshuai.xi #if __SIZEOF_LONG__ >= __SIZEOF_POINTER__
262*53ee8cc1Swenshuai.xi typedef long _sleb128_t;
263*53ee8cc1Swenshuai.xi typedef unsigned long _uleb128_t;
264*53ee8cc1Swenshuai.xi #elif __SIZEOF_LONG_LONG__ >= __SIZEOF_POINTER__
265*53ee8cc1Swenshuai.xi typedef long long _sleb128_t;
266*53ee8cc1Swenshuai.xi typedef unsigned long long _uleb128_t;
267*53ee8cc1Swenshuai.xi #else
268*53ee8cc1Swenshuai.xi # error "What type shall we use for _sleb128_t?"
269*53ee8cc1Swenshuai.xi #endif
270*53ee8cc1Swenshuai.xi
271*53ee8cc1Swenshuai.xi #ifdef __cplusplus
272*53ee8cc1Swenshuai.xi }
273*53ee8cc1Swenshuai.xi #endif
274*53ee8cc1Swenshuai.xi
275*53ee8cc1Swenshuai.xi #ifndef HIDE_EXPORTS
276*53ee8cc1Swenshuai.xi #pragma GCC visibility pop
277*53ee8cc1Swenshuai.xi #endif
278*53ee8cc1Swenshuai.xi
279*53ee8cc1Swenshuai.xi #endif /* unwind.h */
280