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