unwind.inc revision 1.10 1 1.1 mrg /* Exception handling and frame unwind runtime interface routines. -*- C -*-
2 1.10 mrg Copyright (C) 2001-2022 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.7 mrg struct _Unwind_Context *context,
40 1.7 mrg unsigned long *frames_p)
41 1.1 mrg {
42 1.1 mrg _Unwind_Reason_Code code;
43 1.7 mrg unsigned long frames = 1;
44 1.1 mrg
45 1.1 mrg while (1)
46 1.1 mrg {
47 1.1 mrg _Unwind_FrameState fs;
48 1.1 mrg int match_handler;
49 1.1 mrg
50 1.1 mrg code = uw_frame_state_for (context, &fs);
51 1.1 mrg
52 1.1 mrg /* Identify when we've reached the designated handler context. */
53 1.1 mrg match_handler = (uw_identify_context (context) == exc->private_2
54 1.1 mrg ? _UA_HANDLER_FRAME : 0);
55 1.1 mrg
56 1.1 mrg if (code != _URC_NO_REASON)
57 1.1 mrg /* Some error encountered. Usually the unwinder doesn't
58 1.1 mrg diagnose these and merely crashes. */
59 1.1 mrg return _URC_FATAL_PHASE2_ERROR;
60 1.1 mrg
61 1.1 mrg /* Unwind successful. Run the personality routine, if any. */
62 1.1 mrg if (fs.personality)
63 1.1 mrg {
64 1.1 mrg code = (*fs.personality) (1, _UA_CLEANUP_PHASE | match_handler,
65 1.1 mrg exc->exception_class, exc, context);
66 1.1 mrg if (code == _URC_INSTALL_CONTEXT)
67 1.1 mrg break;
68 1.1 mrg if (code != _URC_CONTINUE_UNWIND)
69 1.1 mrg return _URC_FATAL_PHASE2_ERROR;
70 1.1 mrg }
71 1.1 mrg
72 1.1 mrg /* Don't let us unwind past the handler context. */
73 1.1 mrg gcc_assert (!match_handler);
74 1.1 mrg
75 1.1 mrg uw_update_context (context, &fs);
76 1.7 mrg _Unwind_Frames_Increment (context, frames);
77 1.1 mrg }
78 1.1 mrg
79 1.7 mrg *frames_p = frames;
80 1.1 mrg return code;
81 1.1 mrg }
82 1.1 mrg
83 1.1 mrg /* Raise an exception, passing along the given exception object. */
84 1.1 mrg
85 1.1 mrg _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
86 1.1 mrg _Unwind_RaiseException(struct _Unwind_Exception *exc)
87 1.1 mrg {
88 1.1 mrg struct _Unwind_Context this_context, cur_context;
89 1.1 mrg _Unwind_Reason_Code code;
90 1.7 mrg unsigned long frames;
91 1.1 mrg
92 1.1 mrg /* Set up this_context to describe the current stack frame. */
93 1.1 mrg uw_init_context (&this_context);
94 1.1 mrg cur_context = this_context;
95 1.1 mrg
96 1.1 mrg /* Phase 1: Search. Unwind the stack, calling the personality routine
97 1.1 mrg with the _UA_SEARCH_PHASE flag set. Do not modify the stack yet. */
98 1.1 mrg while (1)
99 1.1 mrg {
100 1.1 mrg _Unwind_FrameState fs;
101 1.1 mrg
102 1.1 mrg /* Set up fs to describe the FDE for the caller of cur_context. The
103 1.1 mrg first time through the loop, that means __cxa_throw. */
104 1.1 mrg code = uw_frame_state_for (&cur_context, &fs);
105 1.1 mrg
106 1.1 mrg if (code == _URC_END_OF_STACK)
107 1.1 mrg /* Hit end of stack with no handler found. */
108 1.1 mrg return _URC_END_OF_STACK;
109 1.1 mrg
110 1.1 mrg if (code != _URC_NO_REASON)
111 1.1 mrg /* Some error encountered. Usually the unwinder doesn't
112 1.1 mrg diagnose these and merely crashes. */
113 1.1 mrg return _URC_FATAL_PHASE1_ERROR;
114 1.1 mrg
115 1.1 mrg /* Unwind successful. Run the personality routine, if any. */
116 1.1 mrg if (fs.personality)
117 1.1 mrg {
118 1.1 mrg code = (*fs.personality) (1, _UA_SEARCH_PHASE, exc->exception_class,
119 1.1 mrg exc, &cur_context);
120 1.1 mrg if (code == _URC_HANDLER_FOUND)
121 1.1 mrg break;
122 1.1 mrg else if (code != _URC_CONTINUE_UNWIND)
123 1.1 mrg return _URC_FATAL_PHASE1_ERROR;
124 1.1 mrg }
125 1.1 mrg
126 1.1 mrg /* Update cur_context to describe the same frame as fs. */
127 1.1 mrg uw_update_context (&cur_context, &fs);
128 1.1 mrg }
129 1.1 mrg
130 1.1 mrg /* Indicate to _Unwind_Resume and associated subroutines that this
131 1.1 mrg is not a forced unwind. Further, note where we found a handler. */
132 1.1 mrg exc->private_1 = 0;
133 1.1 mrg exc->private_2 = uw_identify_context (&cur_context);
134 1.1 mrg
135 1.1 mrg cur_context = this_context;
136 1.7 mrg code = _Unwind_RaiseException_Phase2 (exc, &cur_context, &frames);
137 1.1 mrg if (code != _URC_INSTALL_CONTEXT)
138 1.1 mrg return code;
139 1.1 mrg
140 1.7 mrg uw_install_context (&this_context, &cur_context, frames);
141 1.1 mrg }
142 1.1 mrg
143 1.1 mrg
144 1.1 mrg /* Subroutine of _Unwind_ForcedUnwind also invoked from _Unwind_Resume. */
145 1.1 mrg
146 1.1 mrg static _Unwind_Reason_Code
147 1.1 mrg _Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc,
148 1.7 mrg struct _Unwind_Context *context,
149 1.7 mrg unsigned long *frames_p)
150 1.1 mrg {
151 1.1 mrg _Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) (_Unwind_Ptr) exc->private_1;
152 1.1 mrg void *stop_argument = (void *) (_Unwind_Ptr) exc->private_2;
153 1.1 mrg _Unwind_Reason_Code code, stop_code;
154 1.7 mrg unsigned long frames = 1;
155 1.1 mrg
156 1.1 mrg while (1)
157 1.1 mrg {
158 1.1 mrg _Unwind_FrameState fs;
159 1.1 mrg int action;
160 1.1 mrg
161 1.1 mrg /* Set up fs to describe the FDE for the caller of cur_context. */
162 1.1 mrg code = uw_frame_state_for (context, &fs);
163 1.10 mrg if (code != _URC_NO_REASON && code != _URC_END_OF_STACK
164 1.10 mrg && code != _URC_NORMAL_STOP)
165 1.1 mrg return _URC_FATAL_PHASE2_ERROR;
166 1.1 mrg
167 1.1 mrg /* Unwind successful. */
168 1.1 mrg action = _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE;
169 1.10 mrg if (code == _URC_END_OF_STACK || code == _URC_NORMAL_STOP)
170 1.1 mrg action |= _UA_END_OF_STACK;
171 1.1 mrg stop_code = (*stop) (1, action, exc->exception_class, exc,
172 1.1 mrg context, stop_argument);
173 1.1 mrg if (stop_code != _URC_NO_REASON)
174 1.1 mrg return _URC_FATAL_PHASE2_ERROR;
175 1.1 mrg
176 1.1 mrg /* Stop didn't want to do anything. Invoke the personality
177 1.1 mrg handler, if applicable, to run cleanups. */
178 1.1 mrg if (code == _URC_END_OF_STACK)
179 1.1 mrg break;
180 1.1 mrg
181 1.1 mrg if (fs.personality)
182 1.1 mrg {
183 1.1 mrg code = (*fs.personality) (1, _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE,
184 1.1 mrg exc->exception_class, exc, context);
185 1.1 mrg if (code == _URC_INSTALL_CONTEXT)
186 1.1 mrg break;
187 1.1 mrg if (code != _URC_CONTINUE_UNWIND)
188 1.1 mrg return _URC_FATAL_PHASE2_ERROR;
189 1.1 mrg }
190 1.1 mrg
191 1.1 mrg /* Update cur_context to describe the same frame as fs, and discard
192 1.1 mrg the previous context if necessary. */
193 1.1 mrg uw_advance_context (context, &fs);
194 1.7 mrg _Unwind_Frames_Increment (context, frames);
195 1.1 mrg }
196 1.1 mrg
197 1.7 mrg *frames_p = frames;
198 1.1 mrg return code;
199 1.1 mrg }
200 1.1 mrg
201 1.1 mrg
202 1.1 mrg /* Raise an exception for forced unwinding. */
203 1.1 mrg
204 1.1 mrg _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
205 1.1 mrg _Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
206 1.1 mrg _Unwind_Stop_Fn stop, void * stop_argument)
207 1.1 mrg {
208 1.1 mrg struct _Unwind_Context this_context, cur_context;
209 1.1 mrg _Unwind_Reason_Code code;
210 1.7 mrg unsigned long frames;
211 1.1 mrg
212 1.1 mrg uw_init_context (&this_context);
213 1.1 mrg cur_context = this_context;
214 1.1 mrg
215 1.1 mrg exc->private_1 = (_Unwind_Ptr) stop;
216 1.1 mrg exc->private_2 = (_Unwind_Ptr) stop_argument;
217 1.1 mrg
218 1.7 mrg code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context, &frames);
219 1.1 mrg if (code != _URC_INSTALL_CONTEXT)
220 1.1 mrg return code;
221 1.1 mrg
222 1.7 mrg uw_install_context (&this_context, &cur_context, frames);
223 1.1 mrg }
224 1.1 mrg
225 1.1 mrg
226 1.1 mrg /* Resume propagation of an existing exception. This is used after
227 1.1 mrg e.g. executing cleanup code, and not to implement rethrowing. */
228 1.1 mrg
229 1.1 mrg void LIBGCC2_UNWIND_ATTRIBUTE
230 1.1 mrg _Unwind_Resume (struct _Unwind_Exception *exc)
231 1.1 mrg {
232 1.1 mrg struct _Unwind_Context this_context, cur_context;
233 1.1 mrg _Unwind_Reason_Code code;
234 1.7 mrg unsigned long frames;
235 1.1 mrg
236 1.1 mrg uw_init_context (&this_context);
237 1.1 mrg cur_context = this_context;
238 1.1 mrg
239 1.1 mrg /* Choose between continuing to process _Unwind_RaiseException
240 1.1 mrg or _Unwind_ForcedUnwind. */
241 1.1 mrg if (exc->private_1 == 0)
242 1.7 mrg code = _Unwind_RaiseException_Phase2 (exc, &cur_context, &frames);
243 1.1 mrg else
244 1.7 mrg code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context, &frames);
245 1.1 mrg
246 1.1 mrg gcc_assert (code == _URC_INSTALL_CONTEXT);
247 1.1 mrg
248 1.7 mrg uw_install_context (&this_context, &cur_context, frames);
249 1.1 mrg }
250 1.1 mrg
251 1.1 mrg
252 1.1 mrg /* Resume propagation of an FORCE_UNWIND exception, or to rethrow
253 1.1 mrg a normal exception that was handled. */
254 1.1 mrg
255 1.1 mrg _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
256 1.1 mrg _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
257 1.1 mrg {
258 1.1 mrg struct _Unwind_Context this_context, cur_context;
259 1.1 mrg _Unwind_Reason_Code code;
260 1.7 mrg unsigned long frames;
261 1.1 mrg
262 1.1 mrg /* Choose between continuing to process _Unwind_RaiseException
263 1.1 mrg or _Unwind_ForcedUnwind. */
264 1.1 mrg if (exc->private_1 == 0)
265 1.1 mrg return _Unwind_RaiseException (exc);
266 1.1 mrg
267 1.1 mrg uw_init_context (&this_context);
268 1.1 mrg cur_context = this_context;
269 1.1 mrg
270 1.7 mrg code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context, &frames);
271 1.1 mrg
272 1.1 mrg gcc_assert (code == _URC_INSTALL_CONTEXT);
273 1.1 mrg
274 1.7 mrg uw_install_context (&this_context, &cur_context, frames);
275 1.1 mrg }
276 1.1 mrg
277 1.1 mrg
278 1.1 mrg /* A convenience function that calls the exception_cleanup field. */
279 1.1 mrg
280 1.1 mrg void
281 1.1 mrg _Unwind_DeleteException (struct _Unwind_Exception *exc)
282 1.1 mrg {
283 1.1 mrg if (exc->exception_cleanup)
284 1.1 mrg (*exc->exception_cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exc);
285 1.1 mrg }
286 1.1 mrg
287 1.1 mrg
288 1.1 mrg /* Perform stack backtrace through unwind data. */
289 1.1 mrg
290 1.1 mrg _Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
291 1.1 mrg _Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument)
292 1.1 mrg {
293 1.1 mrg struct _Unwind_Context context;
294 1.1 mrg _Unwind_Reason_Code code;
295 1.1 mrg
296 1.1 mrg uw_init_context (&context);
297 1.1 mrg
298 1.1 mrg while (1)
299 1.1 mrg {
300 1.1 mrg _Unwind_FrameState fs;
301 1.1 mrg
302 1.1 mrg /* Set up fs to describe the FDE for the caller of context. */
303 1.1 mrg code = uw_frame_state_for (&context, &fs);
304 1.10 mrg if (code != _URC_NO_REASON && code != _URC_END_OF_STACK
305 1.10 mrg && code != _URC_NORMAL_STOP)
306 1.1 mrg return _URC_FATAL_PHASE1_ERROR;
307 1.1 mrg
308 1.1 mrg /* Call trace function. */
309 1.1 mrg if ((*trace) (&context, trace_argument) != _URC_NO_REASON)
310 1.1 mrg return _URC_FATAL_PHASE1_ERROR;
311 1.1 mrg
312 1.10 mrg #ifdef MD_BACKCHAIN_FALLBACK
313 1.10 mrg /* Do a backchain if there is no DWARF data. */
314 1.10 mrg if (code == _URC_NORMAL_STOP)
315 1.10 mrg {
316 1.10 mrg MD_BACKCHAIN_FALLBACK(&context, trace_argument);
317 1.10 mrg break;
318 1.10 mrg }
319 1.10 mrg #endif
320 1.10 mrg
321 1.10 mrg /* We're done at end of stack. */
322 1.1 mrg if (code == _URC_END_OF_STACK)
323 1.1 mrg break;
324 1.1 mrg
325 1.1 mrg /* Update context to describe the same frame as fs. */
326 1.1 mrg uw_update_context (&context, &fs);
327 1.1 mrg }
328 1.1 mrg
329 1.1 mrg return code;
330 1.1 mrg }
331