unwind.inc revision 1.1 1 1.1 mrg /* Exception handling and frame unwind runtime interface routines. -*- C -*-
2 1.1 mrg Copyright (C) 2001-2013 Free Software Foundation, Inc.
3 1.1 mrg
4 1.1 mrg This file is part of GCC.
5 1.1 mrg
6 1.1 mrg GCC is free software; you can redistribute it and/or modify it
7 1.1 mrg under the terms of the GNU General Public License as published by
8 1.1 mrg the Free Software Foundation; either version 3, or (at your option)
9 1.1 mrg any later version.
10 1.1 mrg
11 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT
12 1.1 mrg ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 1.1 mrg License for more details.
15 1.1 mrg
16 1.1 mrg Under Section 7 of GPL version 3, you are granted additional
17 1.1 mrg permissions described in the GCC Runtime Library Exception, version
18 1.1 mrg 3.1, as published by the Free Software Foundation.
19 1.1 mrg
20 1.1 mrg You should have received a copy of the GNU General Public License and
21 1.1 mrg a copy of the GCC Runtime Library Exception along with this program;
22 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 1.1 mrg <http://www.gnu.org/licenses/>. */
24 1.1 mrg
25 1.1 mrg /* This is derived from the C++ ABI for IA-64. Where we diverge
26 1.1 mrg for cross-architecture compatibility are noted with "@@@".
27 1.1 mrg This file is included from unwind-dw2.c, unwind-sjlj.c or
28 1.1 mrg unwind-ia64.c. */
29 1.1 mrg
30 1.1 mrg /* Subroutine of _Unwind_RaiseException also invoked from _Unwind_Resume.
31 1.1 mrg
32 1.1 mrg Unwind the stack calling the personality routine to find both the
33 1.1 mrg exception handler and intermediary cleanup code. We'll only locate
34 1.1 mrg the first such frame here. Cleanup code will call back into
35 1.1 mrg _Unwind_Resume and we'll continue Phase 2 there. */
36 1.1 mrg
37 1.1 mrg static _Unwind_Reason_Code
38 1.1 mrg _Unwind_RaiseException_Phase2(struct _Unwind_Exception *exc,
39 1.1 mrg struct _Unwind_Context *context)
40 1.1 mrg {
41 1.1 mrg _Unwind_Reason_Code code;
42 1.1 mrg
43 1.1 mrg while (1)
44 1.1 mrg {
45 1.1 mrg _Unwind_FrameState fs;
46 1.1 mrg int match_handler;
47 1.1 mrg
48 1.1 mrg code = uw_frame_state_for (context, &fs);
49 1.1 mrg
50 1.1 mrg /* Identify when we've reached the designated handler context. */
51 1.1 mrg match_handler = (uw_identify_context (context) == exc->private_2
52 1.1 mrg ? _UA_HANDLER_FRAME : 0);
53 1.1 mrg
54 1.1 mrg if (code != _URC_NO_REASON)
55 1.1 mrg /* Some error encountered. Usually the unwinder doesn't
56 1.1 mrg diagnose these and merely crashes. */
57 1.1 mrg return _URC_FATAL_PHASE2_ERROR;
58 1.1 mrg
59 1.1 mrg /* Unwind successful. Run the personality routine, if any. */
60 1.1 mrg if (fs.personality)
61 1.1 mrg {
62 1.1 mrg code = (*fs.personality) (1, _UA_CLEANUP_PHASE | match_handler,
63 1.1 mrg exc->exception_class, exc, context);
64 1.1 mrg if (code == _URC_INSTALL_CONTEXT)
65 1.1 mrg break;
66 1.1 mrg if (code != _URC_CONTINUE_UNWIND)
67 1.1 mrg return _URC_FATAL_PHASE2_ERROR;
68 1.1 mrg }
69 1.1 mrg
70 1.1 mrg /* Don't let us unwind past the handler context. */
71 1.1 mrg gcc_assert (!match_handler);
72 1.1 mrg
73 1.1 mrg uw_update_context (context, &fs);
74 1.1 mrg }
75 1.1 mrg
76 1.1 mrg return code;
77 1.1 mrg }
78 1.1 mrg
79 1.1 mrg /* Raise an exception, passing along the given exception object. */
80 1.1 mrg
81 1.1 mrg _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
82 1.1 mrg _Unwind_RaiseException(struct _Unwind_Exception *exc)
83 1.1 mrg {
84 1.1 mrg struct _Unwind_Context this_context, cur_context;
85 1.1 mrg _Unwind_Reason_Code code;
86 1.1 mrg
87 1.1 mrg /* Set up this_context to describe the current stack frame. */
88 1.1 mrg uw_init_context (&this_context);
89 1.1 mrg cur_context = this_context;
90 1.1 mrg
91 1.1 mrg /* Phase 1: Search. Unwind the stack, calling the personality routine
92 1.1 mrg with the _UA_SEARCH_PHASE flag set. Do not modify the stack yet. */
93 1.1 mrg while (1)
94 1.1 mrg {
95 1.1 mrg _Unwind_FrameState fs;
96 1.1 mrg
97 1.1 mrg /* Set up fs to describe the FDE for the caller of cur_context. The
98 1.1 mrg first time through the loop, that means __cxa_throw. */
99 1.1 mrg code = uw_frame_state_for (&cur_context, &fs);
100 1.1 mrg
101 1.1 mrg if (code == _URC_END_OF_STACK)
102 1.1 mrg /* Hit end of stack with no handler found. */
103 1.1 mrg return _URC_END_OF_STACK;
104 1.1 mrg
105 1.1 mrg if (code != _URC_NO_REASON)
106 1.1 mrg /* Some error encountered. Usually the unwinder doesn't
107 1.1 mrg diagnose these and merely crashes. */
108 1.1 mrg return _URC_FATAL_PHASE1_ERROR;
109 1.1 mrg
110 1.1 mrg /* Unwind successful. Run the personality routine, if any. */
111 1.1 mrg if (fs.personality)
112 1.1 mrg {
113 1.1 mrg code = (*fs.personality) (1, _UA_SEARCH_PHASE, exc->exception_class,
114 1.1 mrg exc, &cur_context);
115 1.1 mrg if (code == _URC_HANDLER_FOUND)
116 1.1 mrg break;
117 1.1 mrg else if (code != _URC_CONTINUE_UNWIND)
118 1.1 mrg return _URC_FATAL_PHASE1_ERROR;
119 1.1 mrg }
120 1.1 mrg
121 1.1 mrg /* Update cur_context to describe the same frame as fs. */
122 1.1 mrg uw_update_context (&cur_context, &fs);
123 1.1 mrg }
124 1.1 mrg
125 1.1 mrg /* Indicate to _Unwind_Resume and associated subroutines that this
126 1.1 mrg is not a forced unwind. Further, note where we found a handler. */
127 1.1 mrg exc->private_1 = 0;
128 1.1 mrg exc->private_2 = uw_identify_context (&cur_context);
129 1.1 mrg
130 1.1 mrg cur_context = this_context;
131 1.1 mrg code = _Unwind_RaiseException_Phase2 (exc, &cur_context);
132 1.1 mrg if (code != _URC_INSTALL_CONTEXT)
133 1.1 mrg return code;
134 1.1 mrg
135 1.1 mrg uw_install_context (&this_context, &cur_context);
136 1.1 mrg }
137 1.1 mrg
138 1.1 mrg
139 1.1 mrg /* Subroutine of _Unwind_ForcedUnwind also invoked from _Unwind_Resume. */
140 1.1 mrg
141 1.1 mrg static _Unwind_Reason_Code
142 1.1 mrg _Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc,
143 1.1 mrg struct _Unwind_Context *context)
144 1.1 mrg {
145 1.1 mrg _Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) (_Unwind_Ptr) exc->private_1;
146 1.1 mrg void *stop_argument = (void *) (_Unwind_Ptr) exc->private_2;
147 1.1 mrg _Unwind_Reason_Code code, stop_code;
148 1.1 mrg
149 1.1 mrg while (1)
150 1.1 mrg {
151 1.1 mrg _Unwind_FrameState fs;
152 1.1 mrg int action;
153 1.1 mrg
154 1.1 mrg /* Set up fs to describe the FDE for the caller of cur_context. */
155 1.1 mrg code = uw_frame_state_for (context, &fs);
156 1.1 mrg if (code != _URC_NO_REASON && code != _URC_END_OF_STACK)
157 1.1 mrg return _URC_FATAL_PHASE2_ERROR;
158 1.1 mrg
159 1.1 mrg /* Unwind successful. */
160 1.1 mrg action = _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE;
161 1.1 mrg if (code == _URC_END_OF_STACK)
162 1.1 mrg action |= _UA_END_OF_STACK;
163 1.1 mrg stop_code = (*stop) (1, action, exc->exception_class, exc,
164 1.1 mrg context, stop_argument);
165 1.1 mrg if (stop_code != _URC_NO_REASON)
166 1.1 mrg return _URC_FATAL_PHASE2_ERROR;
167 1.1 mrg
168 1.1 mrg /* Stop didn't want to do anything. Invoke the personality
169 1.1 mrg handler, if applicable, to run cleanups. */
170 1.1 mrg if (code == _URC_END_OF_STACK)
171 1.1 mrg break;
172 1.1 mrg
173 1.1 mrg if (fs.personality)
174 1.1 mrg {
175 1.1 mrg code = (*fs.personality) (1, _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE,
176 1.1 mrg exc->exception_class, exc, context);
177 1.1 mrg if (code == _URC_INSTALL_CONTEXT)
178 1.1 mrg break;
179 1.1 mrg if (code != _URC_CONTINUE_UNWIND)
180 1.1 mrg return _URC_FATAL_PHASE2_ERROR;
181 1.1 mrg }
182 1.1 mrg
183 1.1 mrg /* Update cur_context to describe the same frame as fs, and discard
184 1.1 mrg the previous context if necessary. */
185 1.1 mrg uw_advance_context (context, &fs);
186 1.1 mrg }
187 1.1 mrg
188 1.1 mrg return code;
189 1.1 mrg }
190 1.1 mrg
191 1.1 mrg
192 1.1 mrg /* Raise an exception for forced unwinding. */
193 1.1 mrg
194 1.1 mrg _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
195 1.1 mrg _Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
196 1.1 mrg _Unwind_Stop_Fn stop, void * stop_argument)
197 1.1 mrg {
198 1.1 mrg struct _Unwind_Context this_context, cur_context;
199 1.1 mrg _Unwind_Reason_Code code;
200 1.1 mrg
201 1.1 mrg uw_init_context (&this_context);
202 1.1 mrg cur_context = this_context;
203 1.1 mrg
204 1.1 mrg exc->private_1 = (_Unwind_Ptr) stop;
205 1.1 mrg exc->private_2 = (_Unwind_Ptr) stop_argument;
206 1.1 mrg
207 1.1 mrg code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
208 1.1 mrg if (code != _URC_INSTALL_CONTEXT)
209 1.1 mrg return code;
210 1.1 mrg
211 1.1 mrg uw_install_context (&this_context, &cur_context);
212 1.1 mrg }
213 1.1 mrg
214 1.1 mrg
215 1.1 mrg /* Resume propagation of an existing exception. This is used after
216 1.1 mrg e.g. executing cleanup code, and not to implement rethrowing. */
217 1.1 mrg
218 1.1 mrg void LIBGCC2_UNWIND_ATTRIBUTE
219 1.1 mrg _Unwind_Resume (struct _Unwind_Exception *exc)
220 1.1 mrg {
221 1.1 mrg struct _Unwind_Context this_context, cur_context;
222 1.1 mrg _Unwind_Reason_Code code;
223 1.1 mrg
224 1.1 mrg uw_init_context (&this_context);
225 1.1 mrg cur_context = this_context;
226 1.1 mrg
227 1.1 mrg /* Choose between continuing to process _Unwind_RaiseException
228 1.1 mrg or _Unwind_ForcedUnwind. */
229 1.1 mrg if (exc->private_1 == 0)
230 1.1 mrg code = _Unwind_RaiseException_Phase2 (exc, &cur_context);
231 1.1 mrg else
232 1.1 mrg code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
233 1.1 mrg
234 1.1 mrg gcc_assert (code == _URC_INSTALL_CONTEXT);
235 1.1 mrg
236 1.1 mrg uw_install_context (&this_context, &cur_context);
237 1.1 mrg }
238 1.1 mrg
239 1.1 mrg
240 1.1 mrg /* Resume propagation of an FORCE_UNWIND exception, or to rethrow
241 1.1 mrg a normal exception that was handled. */
242 1.1 mrg
243 1.1 mrg _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
244 1.1 mrg _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
245 1.1 mrg {
246 1.1 mrg struct _Unwind_Context this_context, cur_context;
247 1.1 mrg _Unwind_Reason_Code code;
248 1.1 mrg
249 1.1 mrg /* Choose between continuing to process _Unwind_RaiseException
250 1.1 mrg or _Unwind_ForcedUnwind. */
251 1.1 mrg if (exc->private_1 == 0)
252 1.1 mrg return _Unwind_RaiseException (exc);
253 1.1 mrg
254 1.1 mrg uw_init_context (&this_context);
255 1.1 mrg cur_context = this_context;
256 1.1 mrg
257 1.1 mrg code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
258 1.1 mrg
259 1.1 mrg gcc_assert (code == _URC_INSTALL_CONTEXT);
260 1.1 mrg
261 1.1 mrg uw_install_context (&this_context, &cur_context);
262 1.1 mrg }
263 1.1 mrg
264 1.1 mrg
265 1.1 mrg /* A convenience function that calls the exception_cleanup field. */
266 1.1 mrg
267 1.1 mrg void
268 1.1 mrg _Unwind_DeleteException (struct _Unwind_Exception *exc)
269 1.1 mrg {
270 1.1 mrg if (exc->exception_cleanup)
271 1.1 mrg (*exc->exception_cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exc);
272 1.1 mrg }
273 1.1 mrg
274 1.1 mrg
275 1.1 mrg /* Perform stack backtrace through unwind data. */
276 1.1 mrg
277 1.1 mrg _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
278 1.1 mrg _Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument)
279 1.1 mrg {
280 1.1 mrg struct _Unwind_Context context;
281 1.1 mrg _Unwind_Reason_Code code;
282 1.1 mrg
283 1.1 mrg uw_init_context (&context);
284 1.1 mrg
285 1.1 mrg while (1)
286 1.1 mrg {
287 1.1 mrg _Unwind_FrameState fs;
288 1.1 mrg
289 1.1 mrg /* Set up fs to describe the FDE for the caller of context. */
290 1.1 mrg code = uw_frame_state_for (&context, &fs);
291 1.1 mrg if (code != _URC_NO_REASON && code != _URC_END_OF_STACK)
292 1.1 mrg return _URC_FATAL_PHASE1_ERROR;
293 1.1 mrg
294 1.1 mrg /* Call trace function. */
295 1.1 mrg if ((*trace) (&context, trace_argument) != _URC_NO_REASON)
296 1.1 mrg return _URC_FATAL_PHASE1_ERROR;
297 1.1 mrg
298 1.1 mrg /* We're done at end of stack. */
299 1.1 mrg if (code == _URC_END_OF_STACK)
300 1.1 mrg break;
301 1.1 mrg
302 1.1 mrg /* Update context to describe the same frame as fs. */
303 1.1 mrg uw_update_context (&context, &fs);
304 1.1 mrg }
305 1.1 mrg
306 1.1 mrg return code;
307 1.1 mrg }
308