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