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