1 // -*- C++ -*- Exception handling and frame unwind runtime interface routines. 2 // Copyright (C) 2001-2018 Free Software Foundation, Inc. 3 // 4 // This file is part of GCC. 5 // 6 // GCC is free software; you can redistribute it and/or modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 // 11 // GCC is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 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/>. 24 25 // This is derived from the C++ ABI for IA-64. Where we diverge 26 // for cross-architecture compatibility are noted with "@@@". 27 28 #ifndef _UNWIND_CXX_H 29 #define _UNWIND_CXX_H 1 30 31 // Level 2: C++ ABI 32 33 #include <typeinfo> 34 #include <exception> 35 #include <cstddef> 36 #include "unwind.h" 37 #include <bits/atomic_word.h> 38 #include <cxxabi.h> 39 40 #ifdef _GLIBCXX_HAVE_SYS_SDT_H 41 #include <sys/sdt.h> 42 /* We only want to use stap probes starting with v3. Earlier versions 43 added too much startup cost. */ 44 #if defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3 45 #define PROBE2(name, arg1, arg2) STAP_PROBE2 (libstdcxx, name, arg1, arg2) 46 #endif 47 #endif 48 49 #ifndef PROBE2 50 #define PROBE2(name, arg1, arg2) 51 #endif 52 53 #pragma GCC visibility push(default) 54 55 namespace __cxxabiv1 56 { 57 58 // A primary C++ exception object consists of a header, which is a wrapper 59 // around an unwind object header with additional C++ specific information, 60 // followed by the exception object itself. 61 62 struct __cxa_exception 63 { 64 // Manage the exception object itself. 65 std::type_info *exceptionType; 66 void (_GLIBCXX_CDTOR_CALLABI *exceptionDestructor)(void *); 67 68 // The C++ standard has entertaining rules wrt calling set_terminate 69 // and set_unexpected in the middle of the exception cleanup process. 70 std::unexpected_handler unexpectedHandler; 71 std::terminate_handler terminateHandler; 72 73 // The caught exception stack threads through here. 74 __cxa_exception *nextException; 75 76 // How many nested handlers have caught this exception. A negated 77 // value is a signal that this object has been rethrown. 78 int handlerCount; 79 80 #ifdef __ARM_EABI_UNWINDER__ 81 // Stack of exceptions in cleanups. 82 __cxa_exception* nextPropagatingException; 83 84 // The number of active cleanup handlers for this exception. 85 int propagationCount; 86 #else 87 // Cache parsed handler data from the personality routine Phase 1 88 // for Phase 2 and __cxa_call_unexpected. 89 int handlerSwitchValue; 90 const unsigned char *actionRecord; 91 const unsigned char *languageSpecificData; 92 _Unwind_Ptr catchTemp; 93 void *adjustedPtr; 94 #endif 95 96 // The generic exception header. Must be last. 97 _Unwind_Exception unwindHeader; 98 }; 99 100 struct __cxa_refcounted_exception 101 { 102 // Manage this header. 103 _Atomic_word referenceCount; 104 // __cxa_exception must be last, and no padding can be after it. 105 __cxa_exception exc; 106 }; 107 108 // A dependent C++ exception object consists of a wrapper around an unwind 109 // object header with additional C++ specific information, containing a pointer 110 // to a primary exception object. 111 112 struct __cxa_dependent_exception 113 { 114 // The primary exception this thing depends on. 115 void *primaryException; 116 117 // Unused member to get similar layout to __cxa_exception, otherwise the 118 // alignment requirements of _Unwind_Exception would require padding bytes 119 // before the unwindHeader member. 120 void (_GLIBCXX_CDTOR_CALLABI *__padding)(void *); 121 122 // The C++ standard has entertaining rules wrt calling set_terminate 123 // and set_unexpected in the middle of the exception cleanup process. 124 std::unexpected_handler unexpectedHandler; 125 std::terminate_handler terminateHandler; 126 127 // The caught exception stack threads through here. 128 __cxa_exception *nextException; 129 130 // How many nested handlers have caught this exception. A negated 131 // value is a signal that this object has been rethrown. 132 int handlerCount; 133 134 #ifdef __ARM_EABI_UNWINDER__ 135 // Stack of exceptions in cleanups. 136 __cxa_exception* nextPropagatingException; 137 138 // The number of active cleanup handlers for this exception. 139 int propagationCount; 140 #else 141 // Cache parsed handler data from the personality routine Phase 1 142 // for Phase 2 and __cxa_call_unexpected. 143 int handlerSwitchValue; 144 const unsigned char *actionRecord; 145 const unsigned char *languageSpecificData; 146 _Unwind_Ptr catchTemp; 147 void *adjustedPtr; 148 #endif 149 150 // The generic exception header. Must be last. 151 _Unwind_Exception unwindHeader; 152 }; 153 154 // Each thread in a C++ program has access to a __cxa_eh_globals object. 155 struct __cxa_eh_globals 156 { 157 __cxa_exception *caughtExceptions; 158 unsigned int uncaughtExceptions; 159 #ifdef __ARM_EABI_UNWINDER__ 160 __cxa_exception* propagatingExceptions; 161 #endif 162 }; 163 164 // @@@ These are not directly specified by the IA-64 C++ ABI. 165 166 // Handles re-checking the exception specification if unexpectedHandler 167 // throws, and if bad_exception needs to be thrown. Called from the 168 // compiler. 169 extern "C" void __cxa_call_unexpected (void *) __attribute__((__noreturn__)); 170 extern "C" void __cxa_call_terminate (_Unwind_Exception*) throw () 171 __attribute__((__noreturn__)); 172 173 #ifdef __ARM_EABI_UNWINDER__ 174 // Arm EABI specified routines. 175 typedef enum { 176 ctm_failed = 0, 177 ctm_succeeded = 1, 178 ctm_succeeded_with_ptr_to_base = 2 179 } __cxa_type_match_result; 180 extern "C" __cxa_type_match_result __cxa_type_match(_Unwind_Exception*, 181 const std::type_info*, 182 bool, void**); 183 extern "C" bool __cxa_begin_cleanup (_Unwind_Exception*); 184 extern "C" void __cxa_end_cleanup (void); 185 #endif 186 187 // Handles cleanup from transactional memory restart. 188 extern "C" void __cxa_tm_cleanup (void *, void *, unsigned int) throw(); 189 190 // Invokes given handler, dying appropriately if the user handler was 191 // so inconsiderate as to return. 192 extern void __terminate(std::terminate_handler) throw () 193 __attribute__((__noreturn__)); 194 extern void __unexpected(std::unexpected_handler) 195 __attribute__((__noreturn__)); 196 197 // The current installed user handlers. 198 extern std::terminate_handler __terminate_handler; 199 extern std::unexpected_handler __unexpected_handler; 200 201 // These are explicitly GNU C++ specific. 202 203 // Acquire the C++ exception header from the C++ object. 204 static inline __cxa_exception * 205 __get_exception_header_from_obj (void *ptr) 206 { 207 return reinterpret_cast<__cxa_exception *>(ptr) - 1; 208 } 209 210 // Acquire the C++ exception header from the generic exception header. 211 static inline __cxa_exception * 212 __get_exception_header_from_ue (_Unwind_Exception *exc) 213 { 214 return reinterpret_cast<__cxa_exception *>(exc + 1) - 1; 215 } 216 217 // Acquire the C++ refcounted exception header from the C++ object. 218 static inline __cxa_refcounted_exception * 219 __get_refcounted_exception_header_from_obj (void *ptr) 220 { 221 return reinterpret_cast<__cxa_refcounted_exception *>(ptr) - 1; 222 } 223 224 // Acquire the C++ refcounted exception header from the generic exception 225 // header. 226 static inline __cxa_refcounted_exception * 227 __get_refcounted_exception_header_from_ue (_Unwind_Exception *exc) 228 { 229 return reinterpret_cast<__cxa_refcounted_exception *>(exc + 1) - 1; 230 } 231 232 static inline __cxa_dependent_exception * 233 __get_dependent_exception_from_ue (_Unwind_Exception *exc) 234 { 235 return reinterpret_cast<__cxa_dependent_exception *>(exc + 1) - 1; 236 } 237 238 #ifdef __ARM_EABI_UNWINDER__ 239 static inline bool 240 __is_gxx_exception_class(_Unwind_Exception_Class c) 241 { 242 // TODO: Take advantage of the fact that c will always be word aligned. 243 return c[0] == 'G' 244 && c[1] == 'N' 245 && c[2] == 'U' 246 && c[3] == 'C' 247 && c[4] == 'C' 248 && c[5] == '+' 249 && c[6] == '+' 250 && (c[7] == '\0' || c[7] == '\x01'); 251 } 252 253 // Only checks for primary or dependent, but not that it is a C++ exception at 254 // all. 255 static inline bool 256 __is_dependent_exception(_Unwind_Exception_Class c) 257 { 258 return c[7] == '\x01'; 259 } 260 261 static inline void 262 __GXX_INIT_PRIMARY_EXCEPTION_CLASS(_Unwind_Exception_Class c) 263 { 264 c[0] = 'G'; 265 c[1] = 'N'; 266 c[2] = 'U'; 267 c[3] = 'C'; 268 c[4] = 'C'; 269 c[5] = '+'; 270 c[6] = '+'; 271 c[7] = '\0'; 272 } 273 274 static inline void 275 __GXX_INIT_DEPENDENT_EXCEPTION_CLASS(_Unwind_Exception_Class c) 276 { 277 c[0] = 'G'; 278 c[1] = 'N'; 279 c[2] = 'U'; 280 c[3] = 'C'; 281 c[4] = 'C'; 282 c[5] = '+'; 283 c[6] = '+'; 284 c[7] = '\x01'; 285 } 286 287 static inline bool 288 __is_gxx_forced_unwind_class(_Unwind_Exception_Class c) 289 { 290 return c[0] == 'G' 291 && c[1] == 'N' 292 && c[2] == 'U' 293 && c[3] == 'C' 294 && c[4] == 'F' 295 && c[5] == 'O' 296 && c[6] == 'R' 297 && c[7] == '\0'; 298 } 299 300 static inline void 301 __GXX_INIT_FORCED_UNWIND_CLASS(_Unwind_Exception_Class c) 302 { 303 c[0] = 'G'; 304 c[1] = 'N'; 305 c[2] = 'U'; 306 c[3] = 'C'; 307 c[4] = 'F'; 308 c[5] = 'O'; 309 c[6] = 'R'; 310 c[7] = '\0'; 311 } 312 313 static inline void* 314 __gxx_caught_object(_Unwind_Exception* eo) 315 { 316 return (void*)eo->barrier_cache.bitpattern[0]; 317 } 318 #else // !__ARM_EABI_UNWINDER__ 319 // This is the primary exception class we report -- "GNUCC++\0". 320 const _Unwind_Exception_Class __gxx_primary_exception_class 321 = ((((((((_Unwind_Exception_Class) 'G' 322 << 8 | (_Unwind_Exception_Class) 'N') 323 << 8 | (_Unwind_Exception_Class) 'U') 324 << 8 | (_Unwind_Exception_Class) 'C') 325 << 8 | (_Unwind_Exception_Class) 'C') 326 << 8 | (_Unwind_Exception_Class) '+') 327 << 8 | (_Unwind_Exception_Class) '+') 328 << 8 | (_Unwind_Exception_Class) '\0'); 329 330 // This is the dependent (from std::rethrow_exception) exception class we report 331 // "GNUCC++\x01" 332 const _Unwind_Exception_Class __gxx_dependent_exception_class 333 = ((((((((_Unwind_Exception_Class) 'G' 334 << 8 | (_Unwind_Exception_Class) 'N') 335 << 8 | (_Unwind_Exception_Class) 'U') 336 << 8 | (_Unwind_Exception_Class) 'C') 337 << 8 | (_Unwind_Exception_Class) 'C') 338 << 8 | (_Unwind_Exception_Class) '+') 339 << 8 | (_Unwind_Exception_Class) '+') 340 << 8 | (_Unwind_Exception_Class) '\x01'); 341 342 static inline bool 343 __is_gxx_exception_class(_Unwind_Exception_Class c) 344 { 345 return c == __gxx_primary_exception_class 346 || c == __gxx_dependent_exception_class; 347 } 348 349 // Only checks for primary or dependent, but not that it is a C++ exception at 350 // all. 351 static inline bool 352 __is_dependent_exception(_Unwind_Exception_Class c) 353 { 354 return (c & 1); 355 } 356 357 #define __GXX_INIT_PRIMARY_EXCEPTION_CLASS(c) c = __gxx_primary_exception_class 358 #define __GXX_INIT_DEPENDENT_EXCEPTION_CLASS(c) \ 359 c = __gxx_dependent_exception_class 360 361 // GNU C++ personality routine, Version 0. 362 extern "C" _Unwind_Reason_Code __gxx_personality_v0 363 (int, _Unwind_Action, _Unwind_Exception_Class, 364 struct _Unwind_Exception *, struct _Unwind_Context *); 365 366 // GNU C++ sjlj personality routine, Version 0. 367 extern "C" _Unwind_Reason_Code __gxx_personality_sj0 368 (int, _Unwind_Action, _Unwind_Exception_Class, 369 struct _Unwind_Exception *, struct _Unwind_Context *); 370 371 static inline void* 372 __gxx_caught_object(_Unwind_Exception* eo) 373 { 374 // Bad as it looks, this actually works for dependent exceptions too. 375 __cxa_exception* header = __get_exception_header_from_ue (eo); 376 return header->adjustedPtr; 377 } 378 #endif // !__ARM_EABI_UNWINDER__ 379 380 static inline void* 381 __get_object_from_ue(_Unwind_Exception* eo) throw() 382 { 383 return __is_dependent_exception (eo->exception_class) ? 384 __get_dependent_exception_from_ue (eo)->primaryException : 385 eo + 1; 386 } 387 388 static inline void * 389 __get_object_from_ambiguous_exception(__cxa_exception *p_or_d) throw() 390 { 391 return __get_object_from_ue (&p_or_d->unwindHeader); 392 } 393 394 395 } /* namespace __cxxabiv1 */ 396 397 #pragma GCC visibility pop 398 399 #endif // _UNWIND_CXX_H 400