1 /* GDC -- D front-end for GCC
2    Copyright (C) 2004 David Friedman
3    
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8  
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13  
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18 
19 /* GNU/GCC unwind interface declarations for D.  This must match
20    unwind-generic.h */
21 
22 module rt.compiler.gdc.gcc.unwind;
23 
24 private import rt.compiler.gdc.gcc.builtins;
25 private import tango.stdc.stdlib; // for abort
26 
27 /* This is derived from the C++ ABI for IA-64.  Where we diverge
28    for cross-architecture compatibility are noted with "@@@".  */
29 
30 extern (C):
31 
32 /* Level 1: Base ABI  */
33 
34 /* @@@ The IA-64 ABI uses uint64 throughout.  Most places this is
35    inefficient for 32-bit and smaller machines.  */
36 
37 // %% These were typedefs, then made alias -- there are some
38 // extra casts now
39 
40 alias __builtin_machine_uint _Unwind_Word;
41 alias __builtin_machine_int  _Unwind_Sword;
42 alias __builtin_pointer_uint _Unwind_Internal_Ptr;
43 
44 version (IA64) {
45     version (HPUX) {
46         alias __builtin_machine_uint _Unwind_Ptr;
47     } else {
48         alias __builtin_pointer_uint _Unwind_Ptr;
49     }
50 } else {
51     alias __builtin_pointer_uint _Unwind_Ptr;
52 }
53 
54 
55 /* @@@ The IA-64 ABI uses a 64-bit word to identify the producer and
56    consumer of an exception.  We'll go along with this for now even on
57    32-bit machines.  We'll need to provide some other option for
58    16-bit machines and for machines with > 8 bits per byte.  */
59 alias ulong _Unwind_Exception_Class;
60 
61 /* The unwind interface uses reason codes in several contexts to
62    identify the reasons for failures or other actions.  */
63 enum
64 {
65   _URC_NO_REASON = 0,
66   _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
67   _URC_FATAL_PHASE2_ERROR = 2,
68   _URC_FATAL_PHASE1_ERROR = 3,
69   _URC_NORMAL_STOP = 4,
70   _URC_END_OF_STACK = 5,
71   _URC_HANDLER_FOUND = 6,
72   _URC_INSTALL_CONTEXT = 7,
73   _URC_CONTINUE_UNWIND = 8
74 }
75 alias uint _Unwind_Reason_Code;
76 
77 
78 /* The unwind interface uses a pointer to an exception header object
79    as its representation of an exception being thrown. In general, the
80    full representation of an exception object is language- and
81    implementation-specific, but it will be prefixed by a header
82    understood by the unwind interface.  */
83 
84 extern(C) typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code,
85                                               _Unwind_Exception *);
86 
87 align struct _Unwind_Exception // D Note: this may not be "maxium alignment required by any type"?
88 {
89   _Unwind_Exception_Class exception_class;
90   _Unwind_Exception_Cleanup_Fn exception_cleanup;
91   _Unwind_Word private_1;
92   _Unwind_Word private_2;
93 
94   /* @@@ The IA-64 ABI says that this structure must be double-word aligned.
95      Taking that literally does not make much sense generically.  Instead we
96      provide the maximum alignment required by any type for the machine.  */
97 }
98 
99 
100 /* The ACTIONS argument to the personality routine is a bitwise OR of one
101    or more of the following constants.  */
102 typedef int _Unwind_Action;
103 
104 enum
105 {
106     _UA_SEARCH_PHASE  = 1,
107     _UA_CLEANUP_PHASE = 2,
108     _UA_HANDLER_FRAME = 4,
109     _UA_FORCE_UNWIND  = 8,
110     _UA_END_OF_STACK  = 16
111 }
112 
113 /* This is an opaque type used to refer to a system-specific data
114    structure used by the system unwinder. This context is created and
115    destroyed by the system, and passed to the personality routine
116    during unwinding.  */
117 struct _Unwind_Context;
118 
119 /* Raise an exception, passing along the given exception object.  */
120 _Unwind_Reason_Code _Unwind_RaiseException (_Unwind_Exception *);
121 
122 /* Raise an exception for forced unwinding.  */
123 
124 extern(C) typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
125      (int, _Unwind_Action, _Unwind_Exception_Class,
126       _Unwind_Exception *, _Unwind_Context *, void *);
127 
128 _Unwind_Reason_Code _Unwind_ForcedUnwind (_Unwind_Exception *,
129                                                  _Unwind_Stop_Fn,
130                                                  void *);
131 
132 /* Helper to invoke the exception_cleanup routine.  */
133 void _Unwind_DeleteException (_Unwind_Exception *);
134 
135 /* Resume propagation of an existing exception.  This is used after
136    e.g. executing cleanup code, and not to implement rethrowing.  */
137 void _Unwind_Resume (_Unwind_Exception *);
138 
139 /* @@@ Resume propagation of an FORCE_UNWIND exception, or to rethrow
140    a normal exception that was handled.  */
141 _Unwind_Reason_Code _Unwind_Resume_or_Rethrow (_Unwind_Exception *);
142 
143 /* @@@ Use unwind data to perform a stack backtrace.  The trace callback
144    is called for every stack frame in the call chain, but no cleanup
145    actions are performed.  */
146 extern(C) typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)
147      (_Unwind_Context *, void *);
148 
149 _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *);
150 
151 /* These functions are used for communicating information about the unwind
152    context (i.e. the unwind descriptors and the user register state) between
153    the unwind library and the personality routine and landing pad.  Only
154    selected registers maybe manipulated.  */
155 
156 _Unwind_Word _Unwind_GetGR (_Unwind_Context *, int);
157 void _Unwind_SetGR (_Unwind_Context *, int, _Unwind_Word);
158 
159 _Unwind_Ptr _Unwind_GetIP (_Unwind_Context *);
160 void _Unwind_SetIP (_Unwind_Context *, _Unwind_Ptr);
161 
162 /* @@@ Retrieve the CFA of the given context.  */
163 _Unwind_Word _Unwind_GetCFA (_Unwind_Context *);
164 
165 void *_Unwind_GetLanguageSpecificData (_Unwind_Context *);
166 
167 _Unwind_Ptr _Unwind_GetRegionStart (_Unwind_Context *);
168 
169 
170 /* The personality routine is the function in the C++ (or other language)
171    runtime library which serves as an interface between the system unwind
172    library and language-specific exception handling semantics.  It is
173    specific to the code fragment described by an unwind info block, and
174    it is always referenced via the pointer in the unwind info block, and
175    hence it has no ABI-specified name.
176 
177    Note that this implies that two different C++ implementations can
178    use different names, and have different contents in the language
179    specific data area.  Moreover, that the language specific data
180    area contains no version info because name of the function invoked
181    provides more effective versioning by detecting at link time the
182    lack of code to handle the different data format.  */
183 
184 extern(C) typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)
185      (int, _Unwind_Action, _Unwind_Exception_Class,
186       _Unwind_Exception *, _Unwind_Context *);
187 
188 /* @@@ The following alternate entry points are for setjmp/longjmp
189    based unwinding.  */
190 
191 struct SjLj_Function_Context;
192 extern void _Unwind_SjLj_Register (SjLj_Function_Context *);
193 extern void _Unwind_SjLj_Unregister (SjLj_Function_Context *);
194 
195 _Unwind_Reason_Code _Unwind_SjLj_RaiseException
196      (_Unwind_Exception *);
197 _Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind
198      (_Unwind_Exception *, _Unwind_Stop_Fn, void *);
199 void _Unwind_SjLj_Resume (_Unwind_Exception *);
200 _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow (_Unwind_Exception *);
201 
202 /* @@@ The following provide access to the base addresses for text
203    and data-relative addressing in the LDSA.  In order to stay link
204    compatible with the standard ABI for IA-64, we inline these.  */
205 
206 version (IA64) {
207 _Unwind_Ptr
208 _Unwind_GetDataRelBase (_Unwind_Context *_C)
209 {
210   /* The GP is stored in R1.  */
211   return _Unwind_GetGR (_C, 1);
212 }
213 
214 _Unwind_Ptr
215 _Unwind_GetTextRelBase (_Unwind_Context *)
216 {
217   abort ();
218   return 0;
219 }
220 
221 /* @@@ Retrieve the Backing Store Pointer of the given context.  */
222 _Unwind_Word _Unwind_GetBSP (_Unwind_Context *);
223 } else {
224 _Unwind_Ptr _Unwind_GetDataRelBase (_Unwind_Context *);
225 _Unwind_Ptr _Unwind_GetTextRelBase (_Unwind_Context *);
226 }
227 
228 /* @@@ Given an address, return the entry point of the function that
229    contains it.  */
230 extern void * _Unwind_FindEnclosingFunction (void *pc);