1 /* 2 * Copyright 2010-2011 PathScale, Inc. All rights reserved. 3 * Copyright 2021 David Chisnall. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS 16 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 17 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <stdlib.h> 29 #include <dlfcn.h> 30 #include <stdio.h> 31 #include <string.h> 32 #include <stdint.h> 33 #include <pthread.h> 34 #include "typeinfo.h" 35 #include "dwarf_eh.h" 36 #include "atomic.h" 37 #include "cxxabi.h" 38 39 #pragma weak pthread_key_create 40 #pragma weak pthread_setspecific 41 #pragma weak pthread_getspecific 42 #pragma weak pthread_once 43 #ifdef LIBCXXRT_WEAK_LOCKS 44 #pragma weak pthread_mutex_lock 45 #define pthread_mutex_lock(mtx) do {\ 46 if (pthread_mutex_lock) pthread_mutex_lock(mtx);\ 47 } while(0) 48 #pragma weak pthread_mutex_unlock 49 #define pthread_mutex_unlock(mtx) do {\ 50 if (pthread_mutex_unlock) pthread_mutex_unlock(mtx);\ 51 } while(0) 52 #pragma weak pthread_cond_signal 53 #define pthread_cond_signal(cv) do {\ 54 if (pthread_cond_signal) pthread_cond_signal(cv);\ 55 } while(0) 56 #pragma weak pthread_cond_wait 57 #define pthread_cond_wait(cv, mtx) do {\ 58 if (pthread_cond_wait) pthread_cond_wait(cv, mtx);\ 59 } while(0) 60 #endif 61 62 using namespace ABI_NAMESPACE; 63 64 /** 65 * Saves the result of the landing pad that we have found. For ARM, this is 66 * stored in the generic unwind structure, while on other platforms it is 67 * stored in the C++ exception. 68 */ 69 static void saveLandingPad(struct _Unwind_Context *context, 70 struct _Unwind_Exception *ucb, 71 struct __cxa_exception *ex, 72 int selector, 73 dw_eh_ptr_t landingPad) 74 { 75 #if defined(__arm__) && !defined(__ARM_DWARF_EH__) 76 // On ARM, we store the saved exception in the generic part of the structure 77 ucb->barrier_cache.sp = _Unwind_GetGR(context, 13); 78 ucb->barrier_cache.bitpattern[1] = static_cast<uint32_t>(selector); 79 ucb->barrier_cache.bitpattern[3] = reinterpret_cast<uint32_t>(landingPad); 80 #endif 81 // Cache the results for the phase 2 unwind, if we found a handler 82 // and this is not a foreign exception. 83 if (ex) 84 { 85 ex->handlerSwitchValue = selector; 86 ex->catchTemp = landingPad; 87 } 88 } 89 90 /** 91 * Loads the saved landing pad. Returns 1 on success, 0 on failure. 92 */ 93 static int loadLandingPad(struct _Unwind_Context *context, 94 struct _Unwind_Exception *ucb, 95 struct __cxa_exception *ex, 96 unsigned long *selector, 97 dw_eh_ptr_t *landingPad) 98 { 99 #if defined(__arm__) && !defined(__ARM_DWARF_EH__) 100 *selector = ucb->barrier_cache.bitpattern[1]; 101 *landingPad = reinterpret_cast<dw_eh_ptr_t>(ucb->barrier_cache.bitpattern[3]); 102 return 1; 103 #else 104 if (ex) 105 { 106 *selector = ex->handlerSwitchValue; 107 *landingPad = reinterpret_cast<dw_eh_ptr_t>(ex->catchTemp); 108 return 0; 109 } 110 return 0; 111 #endif 112 } 113 114 static inline _Unwind_Reason_Code continueUnwinding(struct _Unwind_Exception *ex, 115 struct _Unwind_Context *context) 116 { 117 #if defined(__arm__) && !defined(__ARM_DWARF_EH__) 118 if (__gnu_unwind_frame(ex, context) != _URC_OK) { return _URC_FAILURE; } 119 #endif 120 return _URC_CONTINUE_UNWIND; 121 } 122 123 124 extern "C" void __cxa_free_exception(void *thrown_exception); 125 extern "C" void __cxa_free_dependent_exception(void *thrown_exception); 126 extern "C" void* __dynamic_cast(const void *sub, 127 const __class_type_info *src, 128 const __class_type_info *dst, 129 ptrdiff_t src2dst_offset); 130 131 /** 132 * The type of a handler that has been found. 133 */ 134 typedef enum 135 { 136 /** No handler. */ 137 handler_none, 138 /** 139 * A cleanup - the exception will propagate through this frame, but code 140 * must be run when this happens. 141 */ 142 handler_cleanup, 143 /** 144 * A catch statement. The exception will not propagate past this frame 145 * (without an explicit rethrow). 146 */ 147 handler_catch 148 } handler_type; 149 150 /** 151 * Per-thread info required by the runtime. We store a single structure 152 * pointer in thread-local storage, because this tends to be a scarce resource 153 * and it's impolite to steal all of it and not leave any for the rest of the 154 * program. 155 * 156 * Instances of this structure are allocated lazily - at most one per thread - 157 * and are destroyed on thread termination. 158 */ 159 struct __cxa_thread_info 160 { 161 /** The termination handler for this thread. */ 162 terminate_handler terminateHandler; 163 /** The unexpected exception handler for this thread. */ 164 unexpected_handler unexpectedHandler; 165 /** 166 * The number of emergency buffers held by this thread. This is 0 in 167 * normal operation - the emergency buffers are only used when malloc() 168 * fails to return memory for allocating an exception. Threads are not 169 * permitted to hold more than 4 emergency buffers (as per recommendation 170 * in ABI spec [3.3.1]). 171 */ 172 int emergencyBuffersHeld; 173 /** 174 * The exception currently running in a cleanup. 175 */ 176 _Unwind_Exception *currentCleanup; 177 /** 178 * Our state with respect to foreign exceptions. Usually none, set to 179 * caught if we have just caught an exception and rethrown if we are 180 * rethrowing it. 181 */ 182 enum 183 { 184 none, 185 caught, 186 rethrown 187 } foreign_exception_state; 188 /** 189 * The public part of this structure, accessible from outside of this 190 * module. 191 */ 192 __cxa_eh_globals globals; 193 }; 194 /** 195 * Dependent exception. This 196 */ 197 struct __cxa_dependent_exception 198 { 199 #if __LP64__ 200 void *reserve; 201 void *primaryException; 202 #endif 203 std::type_info *exceptionType; 204 void (*exceptionDestructor) (void *); 205 unexpected_handler unexpectedHandler; 206 terminate_handler terminateHandler; 207 __cxa_exception *nextException; 208 int handlerCount; 209 #if defined(__arm__) && !defined(__ARM_DWARF_EH__) 210 _Unwind_Exception *nextCleanup; 211 int cleanupCount; 212 #endif 213 int handlerSwitchValue; 214 const char *actionRecord; 215 const char *languageSpecificData; 216 void *catchTemp; 217 void *adjustedPtr; 218 #if !__LP64__ 219 void *primaryException; 220 #endif 221 _Unwind_Exception unwindHeader; 222 }; 223 static_assert(sizeof(__cxa_exception) == sizeof(__cxa_dependent_exception), 224 "__cxa_exception and __cxa_dependent_exception should have the same size"); 225 static_assert(offsetof(__cxa_exception, referenceCount) == 226 offsetof(__cxa_dependent_exception, primaryException), 227 "referenceCount and primaryException should have the same offset"); 228 static_assert(offsetof(__cxa_exception, unwindHeader) == 229 offsetof(__cxa_dependent_exception, unwindHeader), 230 "unwindHeader fields should have the same offset"); 231 static_assert(offsetof(__cxa_dependent_exception, unwindHeader) == 232 offsetof(__cxa_dependent_exception, adjustedPtr) + 8, 233 "there should be no padding before unwindHeader"); 234 235 236 namespace std 237 { 238 void unexpected(); 239 class exception 240 { 241 public: 242 virtual ~exception() throw(); 243 virtual const char* what() const throw(); 244 }; 245 246 } 247 248 /** 249 * Class of exceptions to distinguish between this and other exception types. 250 * 251 * The first four characters are the vendor ID. Currently, we use GNUC, 252 * because we aim for ABI-compatibility with the GNU implementation, and 253 * various checks may test for equality of the class, which is incorrect. 254 */ 255 static const uint64_t exception_class = 256 EXCEPTION_CLASS('G', 'N', 'U', 'C', 'C', '+', '+', '\0'); 257 /** 258 * Class used for dependent exceptions. 259 */ 260 static const uint64_t dependent_exception_class = 261 EXCEPTION_CLASS('G', 'N', 'U', 'C', 'C', '+', '+', '\x01'); 262 /** 263 * The low four bytes of the exception class, indicating that we conform to the 264 * Itanium C++ ABI. This is currently unused, but should be used in the future 265 * if we change our exception class, to allow this library and libsupc++ to be 266 * linked to the same executable and both to interoperate. 267 */ 268 static const uint32_t abi_exception_class = 269 GENERIC_EXCEPTION_CLASS('C', '+', '+', '\0'); 270 271 static bool isCXXException(uint64_t cls) 272 { 273 return (cls == exception_class) || (cls == dependent_exception_class); 274 } 275 276 static bool isDependentException(uint64_t cls) 277 { 278 return cls == dependent_exception_class; 279 } 280 281 static __cxa_exception *exceptionFromPointer(void *ex) 282 { 283 return reinterpret_cast<__cxa_exception*>(static_cast<char*>(ex) - 284 offsetof(struct __cxa_exception, unwindHeader)); 285 } 286 static __cxa_exception *realExceptionFromException(__cxa_exception *ex) 287 { 288 if (!isDependentException(ex->unwindHeader.exception_class)) { return ex; } 289 return reinterpret_cast<__cxa_exception*>((reinterpret_cast<__cxa_dependent_exception*>(ex))->primaryException)-1; 290 } 291 292 293 namespace std 294 { 295 // Forward declaration of standard library terminate() function used to 296 // abort execution. 297 void terminate(void); 298 } 299 300 using namespace ABI_NAMESPACE; 301 302 303 304 /** The global termination handler. */ 305 static atomic<terminate_handler> terminateHandler = abort; 306 /** The global unexpected exception handler. */ 307 static atomic<unexpected_handler> unexpectedHandler = std::terminate; 308 309 /** Key used for thread-local data. */ 310 static pthread_key_t eh_key; 311 312 313 /** 314 * Cleanup function, allowing foreign exception handlers to correctly destroy 315 * this exception if they catch it. 316 */ 317 static void exception_cleanup(_Unwind_Reason_Code reason, 318 struct _Unwind_Exception *ex) 319 { 320 // Exception layout: 321 // [__cxa_exception [_Unwind_Exception]] [exception object] 322 // 323 // __cxa_free_exception expects a pointer to the exception object 324 __cxa_free_exception(static_cast<void*>(ex + 1)); 325 } 326 static void dependent_exception_cleanup(_Unwind_Reason_Code reason, 327 struct _Unwind_Exception *ex) 328 { 329 330 __cxa_free_dependent_exception(static_cast<void*>(ex + 1)); 331 } 332 333 /** 334 * Recursively walk a list of exceptions and delete them all in post-order. 335 */ 336 static void free_exception_list(__cxa_exception *ex) 337 { 338 if (0 != ex->nextException) 339 { 340 free_exception_list(ex->nextException); 341 } 342 // __cxa_free_exception() expects to be passed the thrown object, which 343 // immediately follows the exception, not the exception itself 344 __cxa_free_exception(ex+1); 345 } 346 347 /** 348 * Cleanup function called when a thread exists to make certain that all of the 349 * per-thread data is deleted. 350 */ 351 static void thread_cleanup(void* thread_info) 352 { 353 __cxa_thread_info *info = static_cast<__cxa_thread_info*>(thread_info); 354 if (info->globals.caughtExceptions) 355 { 356 // If this is a foreign exception, ask it to clean itself up. 357 if (info->foreign_exception_state != __cxa_thread_info::none) 358 { 359 _Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(info->globals.caughtExceptions); 360 if (e->exception_cleanup) 361 e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e); 362 } 363 else 364 { 365 free_exception_list(info->globals.caughtExceptions); 366 } 367 } 368 free(thread_info); 369 } 370 371 372 /** 373 * Once control used to protect the key creation. 374 */ 375 static pthread_once_t once_control = PTHREAD_ONCE_INIT; 376 377 /** 378 * We may not be linked against a full pthread implementation. If we're not, 379 * then we need to fake the thread-local storage by storing 'thread-local' 380 * things in a global. 381 */ 382 static bool fakeTLS; 383 /** 384 * Thread-local storage for a single-threaded program. 385 */ 386 static __cxa_thread_info singleThreadInfo; 387 /** 388 * Initialise eh_key. 389 */ 390 static void init_key(void) 391 { 392 if ((0 == pthread_key_create) || 393 (0 == pthread_setspecific) || 394 (0 == pthread_getspecific)) 395 { 396 fakeTLS = true; 397 return; 398 } 399 pthread_key_create(&eh_key, thread_cleanup); 400 pthread_setspecific(eh_key, reinterpret_cast<void *>(0x42)); 401 fakeTLS = (pthread_getspecific(eh_key) != reinterpret_cast<void *>(0x42)); 402 pthread_setspecific(eh_key, 0); 403 } 404 405 /** 406 * Returns the thread info structure, creating it if it is not already created. 407 */ 408 static __cxa_thread_info *thread_info() 409 { 410 if ((0 == pthread_once) || pthread_once(&once_control, init_key)) 411 { 412 fakeTLS = true; 413 } 414 if (fakeTLS) { return &singleThreadInfo; } 415 __cxa_thread_info *info = static_cast<__cxa_thread_info*>(pthread_getspecific(eh_key)); 416 if (0 == info) 417 { 418 info = static_cast<__cxa_thread_info*>(calloc(1, sizeof(__cxa_thread_info))); 419 pthread_setspecific(eh_key, info); 420 } 421 return info; 422 } 423 /** 424 * Fast version of thread_info(). May fail if thread_info() is not called on 425 * this thread at least once already. 426 */ 427 static __cxa_thread_info *thread_info_fast() 428 { 429 if (fakeTLS) { return &singleThreadInfo; } 430 return static_cast<__cxa_thread_info*>(pthread_getspecific(eh_key)); 431 } 432 /** 433 * ABI function returning the __cxa_eh_globals structure. 434 */ 435 extern "C" __cxa_eh_globals *ABI_NAMESPACE::__cxa_get_globals(void) 436 { 437 return &(thread_info()->globals); 438 } 439 /** 440 * Version of __cxa_get_globals() assuming that __cxa_get_globals() has already 441 * been called at least once by this thread. 442 */ 443 extern "C" __cxa_eh_globals *ABI_NAMESPACE::__cxa_get_globals_fast(void) 444 { 445 return &(thread_info_fast()->globals); 446 } 447 448 /** 449 * An emergency allocation reserved for when malloc fails. This is treated as 450 * 16 buffers of 1KB each. 451 */ 452 static char emergency_buffer[16384]; 453 /** 454 * Flag indicating whether each buffer is allocated. 455 */ 456 static bool buffer_allocated[16]; 457 /** 458 * Lock used to protect emergency allocation. 459 */ 460 static pthread_mutex_t emergency_malloc_lock = PTHREAD_MUTEX_INITIALIZER; 461 /** 462 * Condition variable used to wait when two threads are both trying to use the 463 * emergency malloc() buffer at once. 464 */ 465 static pthread_cond_t emergency_malloc_wait = PTHREAD_COND_INITIALIZER; 466 467 /** 468 * Allocates size bytes from the emergency allocation mechanism, if possible. 469 * This function will fail if size is over 1KB or if this thread already has 4 470 * emergency buffers. If all emergency buffers are allocated, it will sleep 471 * until one becomes available. 472 */ 473 static char *emergency_malloc(size_t size) 474 { 475 if (size > 1024) { return 0; } 476 477 __cxa_thread_info *info = thread_info(); 478 // Only 4 emergency buffers allowed per thread! 479 if (info->emergencyBuffersHeld > 3) { return 0; } 480 481 pthread_mutex_lock(&emergency_malloc_lock); 482 int buffer = -1; 483 while (buffer < 0) 484 { 485 // While we were sleeping on the lock, another thread might have free'd 486 // enough memory for us to use, so try the allocation again - no point 487 // using the emergency buffer if there is some real memory that we can 488 // use... 489 void *m = calloc(1, size); 490 if (0 != m) 491 { 492 pthread_mutex_unlock(&emergency_malloc_lock); 493 return static_cast<char*>(m); 494 } 495 for (int i=0 ; i<16 ; i++) 496 { 497 if (!buffer_allocated[i]) 498 { 499 buffer = i; 500 buffer_allocated[i] = true; 501 break; 502 } 503 } 504 // If there still isn't a buffer available, then sleep on the condition 505 // variable. This will be signalled when another thread releases one 506 // of the emergency buffers. 507 if (buffer < 0) 508 { 509 pthread_cond_wait(&emergency_malloc_wait, &emergency_malloc_lock); 510 } 511 } 512 pthread_mutex_unlock(&emergency_malloc_lock); 513 info->emergencyBuffersHeld++; 514 return emergency_buffer + (1024 * buffer); 515 } 516 517 /** 518 * Frees a buffer returned by emergency_malloc(). 519 * 520 * Note: Neither this nor emergency_malloc() is particularly efficient. This 521 * should not matter, because neither will be called in normal operation - they 522 * are only used when the program runs out of memory, which should not happen 523 * often. 524 */ 525 static void emergency_malloc_free(char *ptr) 526 { 527 int buffer = -1; 528 // Find the buffer corresponding to this pointer. 529 for (int i=0 ; i<16 ; i++) 530 { 531 if (ptr == static_cast<void*>(emergency_buffer + (1024 * i))) 532 { 533 buffer = i; 534 break; 535 } 536 } 537 assert(buffer >= 0 && 538 "Trying to free something that is not an emergency buffer!"); 539 // emergency_malloc() is expected to return 0-initialized data. We don't 540 // zero the buffer when allocating it, because the static buffers will 541 // begin life containing 0 values. 542 memset(ptr, 0, 1024); 543 // Signal the condition variable to wake up any threads that are blocking 544 // waiting for some space in the emergency buffer 545 pthread_mutex_lock(&emergency_malloc_lock); 546 // In theory, we don't need to do this with the lock held. In practice, 547 // our array of bools will probably be updated using 32-bit or 64-bit 548 // memory operations, so this update may clobber adjacent values. 549 buffer_allocated[buffer] = false; 550 pthread_cond_signal(&emergency_malloc_wait); 551 pthread_mutex_unlock(&emergency_malloc_lock); 552 } 553 554 static char *alloc_or_die(size_t size) 555 { 556 char *buffer = static_cast<char*>(calloc(1, size)); 557 558 // If calloc() doesn't want to give us any memory, try using an emergency 559 // buffer. 560 if (0 == buffer) 561 { 562 buffer = emergency_malloc(size); 563 // This is only reached if the allocation is greater than 1KB, and 564 // anyone throwing objects that big really should know better. 565 if (0 == buffer) 566 { 567 fprintf(stderr, "Out of memory attempting to allocate exception\n"); 568 std::terminate(); 569 } 570 } 571 return buffer; 572 } 573 static void free_exception(char *e) 574 { 575 // If this allocation is within the address range of the emergency buffer, 576 // don't call free() because it was not allocated with malloc() 577 if ((e >= emergency_buffer) && 578 (e < (emergency_buffer + sizeof(emergency_buffer)))) 579 { 580 emergency_malloc_free(e); 581 } 582 else 583 { 584 free(e); 585 } 586 } 587 588 /** 589 * Allocates an exception structure. Returns a pointer to the space that can 590 * be used to store an object of thrown_size bytes. This function will use an 591 * emergency buffer if malloc() fails, and may block if there are no such 592 * buffers available. 593 */ 594 extern "C" void *__cxa_allocate_exception(size_t thrown_size) 595 { 596 size_t size = thrown_size + sizeof(__cxa_exception); 597 char *buffer = alloc_or_die(size); 598 return buffer+sizeof(__cxa_exception); 599 } 600 601 extern "C" void *__cxa_allocate_dependent_exception(void) 602 { 603 size_t size = sizeof(__cxa_dependent_exception); 604 char *buffer = alloc_or_die(size); 605 return buffer+sizeof(__cxa_dependent_exception); 606 } 607 608 /** 609 * __cxa_free_exception() is called when an exception was thrown in between 610 * calling __cxa_allocate_exception() and actually throwing the exception. 611 * This happens when the object's copy constructor throws an exception. 612 * 613 * In this implementation, it is also called by __cxa_end_catch() and during 614 * thread cleanup. 615 */ 616 extern "C" void __cxa_free_exception(void *thrown_exception) 617 { 618 __cxa_exception *ex = reinterpret_cast<__cxa_exception*>(thrown_exception) - 1; 619 // Free the object that was thrown, calling its destructor 620 if (0 != ex->exceptionDestructor) 621 { 622 try 623 { 624 ex->exceptionDestructor(thrown_exception); 625 } 626 catch(...) 627 { 628 // FIXME: Check that this is really what the spec says to do. 629 std::terminate(); 630 } 631 } 632 633 free_exception(reinterpret_cast<char*>(ex)); 634 } 635 636 static void releaseException(__cxa_exception *exception) 637 { 638 if (isDependentException(exception->unwindHeader.exception_class)) 639 { 640 __cxa_free_dependent_exception(exception+1); 641 return; 642 } 643 if (__sync_sub_and_fetch(&exception->referenceCount, 1) == 0) 644 { 645 // __cxa_free_exception() expects to be passed the thrown object, 646 // which immediately follows the exception, not the exception 647 // itself 648 __cxa_free_exception(exception+1); 649 } 650 } 651 652 void __cxa_free_dependent_exception(void *thrown_exception) 653 { 654 __cxa_dependent_exception *ex = reinterpret_cast<__cxa_dependent_exception*>(thrown_exception) - 1; 655 assert(isDependentException(ex->unwindHeader.exception_class)); 656 if (ex->primaryException) 657 { 658 releaseException(realExceptionFromException(reinterpret_cast<__cxa_exception*>(ex))); 659 } 660 free_exception(reinterpret_cast<char*>(ex)); 661 } 662 663 /** 664 * Callback function used with _Unwind_Backtrace(). 665 * 666 * Prints a stack trace. Used only for debugging help. 667 * 668 * Note: As of FreeBSD 8.1, dladd() still doesn't work properly, so this only 669 * correctly prints function names from public, relocatable, symbols. 670 */ 671 static _Unwind_Reason_Code trace(struct _Unwind_Context *context, void *c) 672 { 673 Dl_info myinfo; 674 int mylookup = 675 dladdr(reinterpret_cast<void *>(__cxa_current_exception_type), &myinfo); 676 void *ip = reinterpret_cast<void*>(_Unwind_GetIP(context)); 677 Dl_info info; 678 if (dladdr(ip, &info) != 0) 679 { 680 if (mylookup == 0 || strcmp(info.dli_fname, myinfo.dli_fname) != 0) 681 { 682 printf("%p:%s() in %s\n", ip, info.dli_sname, info.dli_fname); 683 } 684 } 685 return _URC_CONTINUE_UNWIND; 686 } 687 688 /** 689 * Report a failure that occurred when attempting to throw an exception. 690 * 691 * If the failure happened by falling off the end of the stack without finding 692 * a handler, prints a back trace before aborting. 693 */ 694 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) 695 extern "C" void *__cxa_begin_catch(void *e) throw(); 696 #else 697 extern "C" void *__cxa_begin_catch(void *e); 698 #endif 699 static void report_failure(_Unwind_Reason_Code err, __cxa_exception *thrown_exception) 700 { 701 switch (err) 702 { 703 default: break; 704 case _URC_FATAL_PHASE1_ERROR: 705 fprintf(stderr, "Fatal error during phase 1 unwinding\n"); 706 break; 707 #if !defined(__arm__) || defined(__ARM_DWARF_EH__) 708 case _URC_FATAL_PHASE2_ERROR: 709 fprintf(stderr, "Fatal error during phase 2 unwinding\n"); 710 break; 711 #endif 712 case _URC_END_OF_STACK: 713 __cxa_begin_catch (&(thrown_exception->unwindHeader)); 714 std::terminate(); 715 fprintf(stderr, "Terminating due to uncaught exception %p", 716 static_cast<void*>(thrown_exception)); 717 thrown_exception = realExceptionFromException(thrown_exception); 718 static const __class_type_info *e_ti = 719 static_cast<const __class_type_info*>(&typeid(std::exception)); 720 const __class_type_info *throw_ti = 721 dynamic_cast<const __class_type_info*>(thrown_exception->exceptionType); 722 if (throw_ti) 723 { 724 std::exception *e = 725 static_cast<std::exception*>(e_ti->cast_to(static_cast<void*>(thrown_exception+1), 726 throw_ti)); 727 if (e) 728 { 729 fprintf(stderr, " '%s'", e->what()); 730 } 731 } 732 733 size_t bufferSize = 128; 734 char *demangled = static_cast<char*>(malloc(bufferSize)); 735 const char *mangled = thrown_exception->exceptionType->name(); 736 int status; 737 demangled = __cxa_demangle(mangled, demangled, &bufferSize, &status); 738 fprintf(stderr, " of type %s\n", 739 status == 0 ? demangled : mangled); 740 if (status == 0) { free(demangled); } 741 // Print a back trace if no handler is found. 742 // TODO: Make this optional 743 #ifndef __arm__ 744 _Unwind_Backtrace(trace, 0); 745 #endif 746 747 // Just abort. No need to call std::terminate for the second time 748 abort(); 749 break; 750 } 751 std::terminate(); 752 } 753 754 static void throw_exception(__cxa_exception *ex) 755 { 756 __cxa_thread_info *info = thread_info(); 757 ex->unexpectedHandler = info->unexpectedHandler; 758 if (0 == ex->unexpectedHandler) 759 { 760 ex->unexpectedHandler = unexpectedHandler.load(); 761 } 762 ex->terminateHandler = info->terminateHandler; 763 if (0 == ex->terminateHandler) 764 { 765 ex->terminateHandler = terminateHandler.load(); 766 } 767 info->globals.uncaughtExceptions++; 768 769 _Unwind_Reason_Code err = _Unwind_RaiseException(&ex->unwindHeader); 770 // The _Unwind_RaiseException() function should not return, it should 771 // unwind the stack past this function. If it does return, then something 772 // has gone wrong. 773 report_failure(err, ex); 774 } 775 776 777 /** 778 * ABI function for throwing an exception. Takes the object to be thrown (the 779 * pointer returned by __cxa_allocate_exception()), the type info for the 780 * pointee, and the destructor (if there is one) as arguments. 781 */ 782 extern "C" void __cxa_throw(void *thrown_exception, 783 std::type_info *tinfo, 784 void(*dest)(void*)) 785 { 786 __cxa_exception *ex = reinterpret_cast<__cxa_exception*>(thrown_exception) - 1; 787 788 ex->referenceCount = 1; 789 ex->exceptionType = tinfo; 790 791 ex->exceptionDestructor = dest; 792 793 ex->unwindHeader.exception_class = exception_class; 794 ex->unwindHeader.exception_cleanup = exception_cleanup; 795 796 throw_exception(ex); 797 } 798 799 extern "C" void __cxa_rethrow_primary_exception(void* thrown_exception) 800 { 801 if (NULL == thrown_exception) { return; } 802 803 __cxa_exception *original = exceptionFromPointer(thrown_exception); 804 __cxa_dependent_exception *ex = reinterpret_cast<__cxa_dependent_exception*>(__cxa_allocate_dependent_exception())-1; 805 806 ex->primaryException = thrown_exception; 807 __cxa_increment_exception_refcount(thrown_exception); 808 809 ex->exceptionType = original->exceptionType; 810 ex->unwindHeader.exception_class = dependent_exception_class; 811 ex->unwindHeader.exception_cleanup = dependent_exception_cleanup; 812 813 throw_exception(reinterpret_cast<__cxa_exception*>(ex)); 814 } 815 816 extern "C" void *__cxa_current_primary_exception(void) 817 { 818 __cxa_eh_globals* globals = __cxa_get_globals(); 819 __cxa_exception *ex = globals->caughtExceptions; 820 821 if (0 == ex) { return NULL; } 822 ex = realExceptionFromException(ex); 823 __sync_fetch_and_add(&ex->referenceCount, 1); 824 return ex + 1; 825 } 826 827 extern "C" void __cxa_increment_exception_refcount(void* thrown_exception) 828 { 829 if (NULL == thrown_exception) { return; } 830 __cxa_exception *ex = static_cast<__cxa_exception*>(thrown_exception) - 1; 831 if (isDependentException(ex->unwindHeader.exception_class)) { return; } 832 __sync_fetch_and_add(&ex->referenceCount, 1); 833 } 834 extern "C" void __cxa_decrement_exception_refcount(void* thrown_exception) 835 { 836 if (NULL == thrown_exception) { return; } 837 __cxa_exception *ex = static_cast<__cxa_exception*>(thrown_exception) - 1; 838 releaseException(ex); 839 } 840 841 /** 842 * ABI function. Rethrows the current exception. Does not remove the 843 * exception from the stack or decrement its handler count - the compiler is 844 * expected to set the landing pad for this function to the end of the catch 845 * block, and then call _Unwind_Resume() to continue unwinding once 846 * __cxa_end_catch() has been called and any cleanup code has been run. 847 */ 848 extern "C" void __cxa_rethrow() 849 { 850 __cxa_thread_info *ti = thread_info(); 851 __cxa_eh_globals *globals = &ti->globals; 852 // Note: We don't remove this from the caught list here, because 853 // __cxa_end_catch will be called when we unwind out of the try block. We 854 // could probably make this faster by providing an alternative rethrow 855 // function and ensuring that all cleanup code is run before calling it, so 856 // we can skip the top stack frame when unwinding. 857 __cxa_exception *ex = globals->caughtExceptions; 858 859 if (0 == ex) 860 { 861 fprintf(stderr, 862 "Attempting to rethrow an exception that doesn't exist!\n"); 863 std::terminate(); 864 } 865 866 if (ti->foreign_exception_state != __cxa_thread_info::none) 867 { 868 ti->foreign_exception_state = __cxa_thread_info::rethrown; 869 _Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(ex); 870 _Unwind_Reason_Code err = _Unwind_Resume_or_Rethrow(e); 871 report_failure(err, ex); 872 return; 873 } 874 875 assert(ex->handlerCount > 0 && "Rethrowing uncaught exception!"); 876 877 // `globals->uncaughtExceptions` was decremented by `__cxa_begin_catch`. 878 // It's normally incremented by `throw_exception`, but this path invokes 879 // `_Unwind_Resume_or_Rethrow` directly to rethrow the exception. 880 // This path is only reachable if we're rethrowing a C++ exception - 881 // foreign exceptions don't adjust any of this state. 882 globals->uncaughtExceptions++; 883 884 // ex->handlerCount will be decremented in __cxa_end_catch in enclosing 885 // catch block 886 887 // Make handler count negative. This will tell __cxa_end_catch that 888 // exception was rethrown and exception object should not be destroyed 889 // when handler count become zero 890 ex->handlerCount = -ex->handlerCount; 891 892 // Continue unwinding the stack with this exception. This should unwind to 893 // the place in the caller where __cxa_end_catch() is called. The caller 894 // will then run cleanup code and bounce the exception back with 895 // _Unwind_Resume(). 896 _Unwind_Reason_Code err = _Unwind_Resume_or_Rethrow(&ex->unwindHeader); 897 report_failure(err, ex); 898 } 899 900 /** 901 * Returns the type_info object corresponding to the filter. 902 */ 903 static std::type_info *get_type_info_entry(_Unwind_Context *context, 904 dwarf_eh_lsda *lsda, 905 int filter) 906 { 907 // Get the address of the record in the table. 908 dw_eh_ptr_t record = lsda->type_table - 909 dwarf_size_of_fixed_size_field(lsda->type_table_encoding)*filter; 910 //record -= 4; 911 dw_eh_ptr_t start = record; 912 // Read the value, but it's probably an indirect reference... 913 int64_t offset = read_value(lsda->type_table_encoding, &record); 914 915 // (If the entry is 0, don't try to dereference it. That would be bad.) 916 if (offset == 0) { return 0; } 917 918 // ...so we need to resolve it 919 return reinterpret_cast<std::type_info*>(resolve_indirect_value(context, 920 lsda->type_table_encoding, offset, start)); 921 } 922 923 924 925 /** 926 * Checks the type signature found in a handler against the type of the thrown 927 * object. If ex is 0 then it is assumed to be a foreign exception and only 928 * matches cleanups. 929 */ 930 static bool check_type_signature(__cxa_exception *ex, 931 const std::type_info *type, 932 void *&adjustedPtr) 933 { 934 void *exception_ptr = static_cast<void*>(ex+1); 935 const std::type_info *ex_type = ex ? ex->exceptionType : 0; 936 937 bool is_ptr = ex ? ex_type->__is_pointer_p() : false; 938 if (is_ptr) 939 { 940 exception_ptr = *static_cast<void**>(exception_ptr); 941 } 942 // Always match a catchall, even with a foreign exception 943 // 944 // Note: A 0 here is a catchall, not a cleanup, so we return true to 945 // indicate that we found a catch. 946 if (0 == type) 947 { 948 if (ex) 949 { 950 adjustedPtr = exception_ptr; 951 } 952 return true; 953 } 954 955 if (0 == ex) { return false; } 956 957 // If the types are the same, no casting is needed. 958 if (*type == *ex_type) 959 { 960 adjustedPtr = exception_ptr; 961 return true; 962 } 963 964 965 if (type->__do_catch(ex_type, &exception_ptr, 1)) 966 { 967 adjustedPtr = exception_ptr; 968 return true; 969 } 970 971 return false; 972 } 973 /** 974 * Checks whether the exception matches the type specifiers in this action 975 * record. If the exception only matches cleanups, then this returns false. 976 * If it matches a catch (including a catchall) then it returns true. 977 * 978 * The selector argument is used to return the selector that is passed in the 979 * second exception register when installing the context. 980 */ 981 static handler_type check_action_record(_Unwind_Context *context, 982 dwarf_eh_lsda *lsda, 983 dw_eh_ptr_t action_record, 984 __cxa_exception *ex, 985 unsigned long *selector, 986 void *&adjustedPtr) 987 { 988 if (!action_record) { return handler_cleanup; } 989 handler_type found = handler_none; 990 while (action_record) 991 { 992 int filter = read_sleb128(&action_record); 993 dw_eh_ptr_t action_record_offset_base = action_record; 994 int displacement = read_sleb128(&action_record); 995 action_record = displacement ? 996 action_record_offset_base + displacement : 0; 997 // We only check handler types for C++ exceptions - foreign exceptions 998 // are only allowed for cleanups and catchalls. 999 if (filter > 0) 1000 { 1001 std::type_info *handler_type = get_type_info_entry(context, lsda, filter); 1002 if (check_type_signature(ex, handler_type, adjustedPtr)) 1003 { 1004 *selector = filter; 1005 return handler_catch; 1006 } 1007 } 1008 else if (filter < 0 && 0 != ex) 1009 { 1010 bool matched = false; 1011 *selector = filter; 1012 #if defined(__arm__) && !defined(__ARM_DWARF_EH__) 1013 filter++; 1014 std::type_info *handler_type = get_type_info_entry(context, lsda, filter--); 1015 while (handler_type) 1016 { 1017 if (check_type_signature(ex, handler_type, adjustedPtr)) 1018 { 1019 matched = true; 1020 break; 1021 } 1022 handler_type = get_type_info_entry(context, lsda, filter--); 1023 } 1024 #else 1025 unsigned char *type_index = reinterpret_cast<unsigned char*>(lsda->type_table) - filter - 1; 1026 while (*type_index) 1027 { 1028 std::type_info *handler_type = get_type_info_entry(context, lsda, *(type_index++)); 1029 // If the exception spec matches a permitted throw type for 1030 // this function, don't report a handler - we are allowed to 1031 // propagate this exception out. 1032 if (check_type_signature(ex, handler_type, adjustedPtr)) 1033 { 1034 matched = true; 1035 break; 1036 } 1037 } 1038 #endif 1039 if (matched) { continue; } 1040 // If we don't find an allowed exception spec, we need to install 1041 // the context for this action. The landing pad will then call the 1042 // unexpected exception function. Treat this as a catch 1043 return handler_catch; 1044 } 1045 else if (filter == 0) 1046 { 1047 *selector = filter; 1048 found = handler_cleanup; 1049 } 1050 } 1051 return found; 1052 } 1053 1054 static void pushCleanupException(_Unwind_Exception *exceptionObject, 1055 __cxa_exception *ex) 1056 { 1057 #if defined(__arm__) && !defined(__ARM_DWARF_EH__) 1058 __cxa_thread_info *info = thread_info_fast(); 1059 if (ex) 1060 { 1061 ex->cleanupCount++; 1062 if (ex->cleanupCount > 1) 1063 { 1064 assert(exceptionObject == info->currentCleanup); 1065 return; 1066 } 1067 ex->nextCleanup = info->currentCleanup; 1068 } 1069 info->currentCleanup = exceptionObject; 1070 #endif 1071 } 1072 1073 /** 1074 * The exception personality function. This is referenced in the unwinding 1075 * DWARF metadata and is called by the unwind library for each C++ stack frame 1076 * containing catch or cleanup code. 1077 */ 1078 extern "C" 1079 BEGIN_PERSONALITY_FUNCTION(__gxx_personality_v0) 1080 // This personality function is for version 1 of the ABI. If you use it 1081 // with a future version of the ABI, it won't know what to do, so it 1082 // reports a fatal error and give up before it breaks anything. 1083 if (1 != version) 1084 { 1085 return _URC_FATAL_PHASE1_ERROR; 1086 } 1087 __cxa_exception *ex = 0; 1088 __cxa_exception *realEx = 0; 1089 1090 // If this exception is throw by something else then we can't make any 1091 // assumptions about its layout beyond the fields declared in 1092 // _Unwind_Exception. 1093 bool foreignException = !isCXXException(exceptionClass); 1094 1095 // If this isn't a foreign exception, then we have a C++ exception structure 1096 if (!foreignException) 1097 { 1098 ex = exceptionFromPointer(exceptionObject); 1099 realEx = realExceptionFromException(ex); 1100 } 1101 1102 #if defined(__arm__) && !defined(__ARM_DWARF_EH__) 1103 unsigned char *lsda_addr = 1104 static_cast<unsigned char*>(_Unwind_GetLanguageSpecificData(context)); 1105 #else 1106 unsigned char *lsda_addr = 1107 reinterpret_cast<unsigned char*>(static_cast<uintptr_t>(_Unwind_GetLanguageSpecificData(context))); 1108 #endif 1109 1110 // No LSDA implies no landing pads - try the next frame 1111 if (0 == lsda_addr) { return continueUnwinding(exceptionObject, context); } 1112 1113 // These two variables define how the exception will be handled. 1114 dwarf_eh_action action = {0}; 1115 unsigned long selector = 0; 1116 1117 // During the search phase, we do a complete lookup. If we return 1118 // _URC_HANDLER_FOUND, then the phase 2 unwind will call this function with 1119 // a _UA_HANDLER_FRAME action, telling us to install the handler frame. If 1120 // we return _URC_CONTINUE_UNWIND, we may be called again later with a 1121 // _UA_CLEANUP_PHASE action for this frame. 1122 // 1123 // The point of the two-stage unwind allows us to entirely avoid any stack 1124 // unwinding if there is no handler. If there are just cleanups found, 1125 // then we can just panic call an abort function. 1126 // 1127 // Matching a handler is much more expensive than matching a cleanup, 1128 // because we don't need to bother doing type comparisons (or looking at 1129 // the type table at all) for a cleanup. This means that there is no need 1130 // to cache the result of finding a cleanup, because it's (quite) quick to 1131 // look it up again from the action table. 1132 if (actions & _UA_SEARCH_PHASE) 1133 { 1134 struct dwarf_eh_lsda lsda = parse_lsda(context, lsda_addr); 1135 1136 if (!dwarf_eh_find_callsite(context, &lsda, &action)) 1137 { 1138 // EH range not found. This happens if exception is thrown and not 1139 // caught inside a cleanup (destructor). We should call 1140 // terminate() in this case. The catchTemp (landing pad) field of 1141 // exception object will contain null when personality function is 1142 // called with _UA_HANDLER_FRAME action for phase 2 unwinding. 1143 return _URC_HANDLER_FOUND; 1144 } 1145 1146 handler_type found_handler = check_action_record(context, &lsda, 1147 action.action_record, realEx, &selector, ex->adjustedPtr); 1148 // If there's no action record, we've only found a cleanup, so keep 1149 // searching for something real 1150 if (found_handler == handler_catch) 1151 { 1152 // Cache the results for the phase 2 unwind, if we found a handler 1153 // and this is not a foreign exception. 1154 if (ex) 1155 { 1156 saveLandingPad(context, exceptionObject, ex, selector, action.landing_pad); 1157 ex->languageSpecificData = reinterpret_cast<const char*>(lsda_addr); 1158 ex->actionRecord = reinterpret_cast<const char*>(action.action_record); 1159 // ex->adjustedPtr is set when finding the action record. 1160 } 1161 return _URC_HANDLER_FOUND; 1162 } 1163 return continueUnwinding(exceptionObject, context); 1164 } 1165 1166 1167 // If this is a foreign exception, we didn't have anywhere to cache the 1168 // lookup stuff, so we need to do it again. If this is either a forced 1169 // unwind, a foreign exception, or a cleanup, then we just install the 1170 // context for a cleanup. 1171 if (!(actions & _UA_HANDLER_FRAME)) 1172 { 1173 // cleanup 1174 struct dwarf_eh_lsda lsda = parse_lsda(context, lsda_addr); 1175 dwarf_eh_find_callsite(context, &lsda, &action); 1176 if (0 == action.landing_pad) { return continueUnwinding(exceptionObject, context); } 1177 handler_type found_handler = check_action_record(context, &lsda, 1178 action.action_record, realEx, &selector, ex->adjustedPtr); 1179 // Ignore handlers this time. 1180 if (found_handler != handler_cleanup) { return continueUnwinding(exceptionObject, context); } 1181 pushCleanupException(exceptionObject, ex); 1182 } 1183 else if (foreignException) 1184 { 1185 struct dwarf_eh_lsda lsda = parse_lsda(context, lsda_addr); 1186 dwarf_eh_find_callsite(context, &lsda, &action); 1187 check_action_record(context, &lsda, action.action_record, realEx, 1188 &selector, ex->adjustedPtr); 1189 } 1190 else if (ex->catchTemp == 0) 1191 { 1192 // Uncaught exception in cleanup, calling terminate 1193 std::terminate(); 1194 } 1195 else 1196 { 1197 // Restore the saved info if we saved some last time. 1198 loadLandingPad(context, exceptionObject, ex, &selector, &action.landing_pad); 1199 ex->catchTemp = 0; 1200 ex->handlerSwitchValue = 0; 1201 } 1202 1203 1204 _Unwind_SetIP(context, reinterpret_cast<unsigned long>(action.landing_pad)); 1205 _Unwind_SetGR(context, __builtin_eh_return_data_regno(0), 1206 reinterpret_cast<unsigned long>(exceptionObject)); 1207 _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), selector); 1208 1209 return _URC_INSTALL_CONTEXT; 1210 } 1211 1212 /** 1213 * ABI function called when entering a catch statement. The argument is the 1214 * pointer passed out of the personality function. This is always the start of 1215 * the _Unwind_Exception object. The return value for this function is the 1216 * pointer to the caught exception, which is either the adjusted pointer (for 1217 * C++ exceptions) of the unadjusted pointer (for foreign exceptions). 1218 */ 1219 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) 1220 extern "C" void *__cxa_begin_catch(void *e) throw() 1221 #else 1222 extern "C" void *__cxa_begin_catch(void *e) 1223 #endif 1224 { 1225 // We can't call the fast version here, because if the first exception that 1226 // we see is a foreign exception then we won't have called it yet. 1227 __cxa_thread_info *ti = thread_info(); 1228 __cxa_eh_globals *globals = &ti->globals; 1229 _Unwind_Exception *exceptionObject = static_cast<_Unwind_Exception*>(e); 1230 1231 if (isCXXException(exceptionObject->exception_class)) 1232 { 1233 // Only exceptions thrown with a C++ exception throwing function will 1234 // increment this, so don't decrement it here. 1235 globals->uncaughtExceptions--; 1236 __cxa_exception *ex = exceptionFromPointer(exceptionObject); 1237 1238 if (ex->handlerCount == 0) 1239 { 1240 // Add this to the front of the list of exceptions being handled 1241 // and increment its handler count so that it won't be deleted 1242 // prematurely. 1243 ex->nextException = globals->caughtExceptions; 1244 globals->caughtExceptions = ex; 1245 } 1246 1247 if (ex->handlerCount < 0) 1248 { 1249 // Rethrown exception is catched before end of catch block. 1250 // Clear the rethrow flag (make value positive) - we are allowed 1251 // to delete this exception at the end of the catch block, as long 1252 // as it isn't thrown again later. 1253 1254 // Code pattern: 1255 // 1256 // try { 1257 // throw x; 1258 // } 1259 // catch() { 1260 // try { 1261 // throw; 1262 // } 1263 // catch() { 1264 // __cxa_begin_catch() <- we are here 1265 // } 1266 // } 1267 ex->handlerCount = -ex->handlerCount + 1; 1268 } 1269 else 1270 { 1271 ex->handlerCount++; 1272 } 1273 ti->foreign_exception_state = __cxa_thread_info::none; 1274 1275 return ex->adjustedPtr; 1276 } 1277 else 1278 { 1279 // If this is a foreign exception, then we need to be able to 1280 // store it. We can't chain foreign exceptions, so we give up 1281 // if there are already some outstanding ones. 1282 if (globals->caughtExceptions != 0) 1283 { 1284 std::terminate(); 1285 } 1286 globals->caughtExceptions = reinterpret_cast<__cxa_exception*>(exceptionObject); 1287 ti->foreign_exception_state = __cxa_thread_info::caught; 1288 } 1289 // exceptionObject is the pointer to the _Unwind_Exception within the 1290 // __cxa_exception. The throw object is after this 1291 return (reinterpret_cast<char*>(exceptionObject) + sizeof(_Unwind_Exception)); 1292 } 1293 1294 1295 1296 /** 1297 * ABI function called when exiting a catch block. This will free the current 1298 * exception if it is no longer referenced in other catch blocks. 1299 */ 1300 extern "C" void __cxa_end_catch() 1301 { 1302 // We can call the fast version here because the slow version is called in 1303 // __cxa_throw(), which must have been called before we end a catch block 1304 __cxa_thread_info *ti = thread_info_fast(); 1305 __cxa_eh_globals *globals = &ti->globals; 1306 __cxa_exception *ex = globals->caughtExceptions; 1307 1308 assert(0 != ex && "Ending catch when no exception is on the stack!"); 1309 1310 if (ti->foreign_exception_state != __cxa_thread_info::none) 1311 { 1312 if (ti->foreign_exception_state != __cxa_thread_info::rethrown) 1313 { 1314 _Unwind_Exception *e = reinterpret_cast<_Unwind_Exception*>(ti->globals.caughtExceptions); 1315 if (e->exception_cleanup) 1316 e->exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, e); 1317 } 1318 globals->caughtExceptions = 0; 1319 ti->foreign_exception_state = __cxa_thread_info::none; 1320 return; 1321 } 1322 1323 bool deleteException = true; 1324 1325 if (ex->handlerCount < 0) 1326 { 1327 // exception was rethrown. Exception should not be deleted even if 1328 // handlerCount become zero. 1329 // Code pattern: 1330 // try { 1331 // throw x; 1332 // } 1333 // catch() { 1334 // { 1335 // throw; 1336 // } 1337 // cleanup { 1338 // __cxa_end_catch(); <- we are here 1339 // } 1340 // } 1341 // 1342 1343 ex->handlerCount++; 1344 deleteException = false; 1345 } 1346 else 1347 { 1348 ex->handlerCount--; 1349 } 1350 1351 if (ex->handlerCount == 0) 1352 { 1353 globals->caughtExceptions = ex->nextException; 1354 if (deleteException) 1355 { 1356 releaseException(ex); 1357 } 1358 } 1359 } 1360 1361 /** 1362 * ABI function. Returns the type of the current exception. 1363 */ 1364 extern "C" std::type_info *__cxa_current_exception_type() 1365 { 1366 __cxa_eh_globals *globals = __cxa_get_globals(); 1367 __cxa_exception *ex = globals->caughtExceptions; 1368 return ex ? ex->exceptionType : 0; 1369 } 1370 1371 /** 1372 * Cleanup, ensures that `__cxa_end_catch` is called to balance an explicit 1373 * `__cxa_begin_catch` call. 1374 */ 1375 static void end_catch(char *) 1376 { 1377 __cxa_end_catch(); 1378 } 1379 /** 1380 * ABI function, called when an exception specification is violated. 1381 * 1382 * This function does not return. 1383 */ 1384 extern "C" void __cxa_call_unexpected(void*exception) 1385 { 1386 _Unwind_Exception *exceptionObject = static_cast<_Unwind_Exception*>(exception); 1387 // Wrap the call to the unexpected handler in calls to `__cxa_begin_catch` 1388 // and `__cxa_end_catch` so that we correctly update exception counts if 1389 // the unexpected handler throws an exception. 1390 __cxa_begin_catch(exceptionObject); 1391 __attribute__((cleanup(end_catch))) 1392 char unused; 1393 if (exceptionObject->exception_class == exception_class) 1394 { 1395 __cxa_exception *ex = exceptionFromPointer(exceptionObject); 1396 if (ex->unexpectedHandler) 1397 { 1398 ex->unexpectedHandler(); 1399 // Should not be reached. 1400 abort(); 1401 } 1402 } 1403 std::unexpected(); 1404 // Should not be reached. 1405 abort(); 1406 } 1407 1408 /** 1409 * ABI function, returns the adjusted pointer to the exception object. 1410 */ 1411 extern "C" void *__cxa_get_exception_ptr(void *exceptionObject) 1412 { 1413 return exceptionFromPointer(exceptionObject)->adjustedPtr; 1414 } 1415 1416 /** 1417 * As an extension, we provide the ability for the unexpected and terminate 1418 * handlers to be thread-local. We default to the standards-compliant 1419 * behaviour where they are global. 1420 */ 1421 static bool thread_local_handlers = false; 1422 1423 1424 namespace pathscale 1425 { 1426 /** 1427 * Sets whether unexpected and terminate handlers should be thread-local. 1428 */ 1429 void set_use_thread_local_handlers(bool flag) throw() 1430 { 1431 thread_local_handlers = flag; 1432 } 1433 /** 1434 * Sets a thread-local unexpected handler. 1435 */ 1436 unexpected_handler set_unexpected(unexpected_handler f) throw() 1437 { 1438 static __cxa_thread_info *info = thread_info(); 1439 unexpected_handler old = info->unexpectedHandler; 1440 info->unexpectedHandler = f; 1441 return old; 1442 } 1443 /** 1444 * Sets a thread-local terminate handler. 1445 */ 1446 terminate_handler set_terminate(terminate_handler f) throw() 1447 { 1448 static __cxa_thread_info *info = thread_info(); 1449 terminate_handler old = info->terminateHandler; 1450 info->terminateHandler = f; 1451 return old; 1452 } 1453 } 1454 1455 namespace std 1456 { 1457 /** 1458 * Sets the function that will be called when an exception specification is 1459 * violated. 1460 */ 1461 unexpected_handler set_unexpected(unexpected_handler f) throw() 1462 { 1463 if (thread_local_handlers) { return pathscale::set_unexpected(f); } 1464 1465 return unexpectedHandler.exchange(f); 1466 } 1467 /** 1468 * Sets the function that is called to terminate the program. 1469 */ 1470 terminate_handler set_terminate(terminate_handler f) throw() 1471 { 1472 if (thread_local_handlers) { return pathscale::set_terminate(f); } 1473 1474 return terminateHandler.exchange(f); 1475 } 1476 /** 1477 * Terminates the program, calling a custom terminate implementation if 1478 * required. 1479 */ 1480 void terminate() 1481 { 1482 static __cxa_thread_info *info = thread_info(); 1483 if (0 != info && 0 != info->terminateHandler) 1484 { 1485 info->terminateHandler(); 1486 // Should not be reached - a terminate handler is not expected to 1487 // return. 1488 abort(); 1489 } 1490 terminateHandler.load()(); 1491 } 1492 /** 1493 * Called when an unexpected exception is encountered (i.e. an exception 1494 * violates an exception specification). This calls abort() unless a 1495 * custom handler has been set.. 1496 */ 1497 void unexpected() 1498 { 1499 static __cxa_thread_info *info = thread_info(); 1500 if (0 != info && 0 != info->unexpectedHandler) 1501 { 1502 info->unexpectedHandler(); 1503 // Should not be reached - a terminate handler is not expected to 1504 // return. 1505 abort(); 1506 } 1507 unexpectedHandler.load()(); 1508 } 1509 /** 1510 * Returns whether there are any exceptions currently being thrown that 1511 * have not been caught. This can occur inside a nested catch statement. 1512 */ 1513 bool uncaught_exception() throw() 1514 { 1515 __cxa_thread_info *info = thread_info(); 1516 return info->globals.uncaughtExceptions != 0; 1517 } 1518 /** 1519 * Returns the number of exceptions currently being thrown that have not 1520 * been caught. This can occur inside a nested catch statement. 1521 */ 1522 int uncaught_exceptions() throw() 1523 { 1524 __cxa_thread_info *info = thread_info(); 1525 return info->globals.uncaughtExceptions; 1526 } 1527 /** 1528 * Returns the current unexpected handler. 1529 */ 1530 unexpected_handler get_unexpected() throw() 1531 { 1532 __cxa_thread_info *info = thread_info(); 1533 if (info->unexpectedHandler) 1534 { 1535 return info->unexpectedHandler; 1536 } 1537 return unexpectedHandler.load(); 1538 } 1539 /** 1540 * Returns the current terminate handler. 1541 */ 1542 terminate_handler get_terminate() throw() 1543 { 1544 __cxa_thread_info *info = thread_info(); 1545 if (info->terminateHandler) 1546 { 1547 return info->terminateHandler; 1548 } 1549 return terminateHandler.load(); 1550 } 1551 } 1552 #if defined(__arm__) && !defined(__ARM_DWARF_EH__) 1553 extern "C" _Unwind_Exception *__cxa_get_cleanup(void) 1554 { 1555 __cxa_thread_info *info = thread_info_fast(); 1556 _Unwind_Exception *exceptionObject = info->currentCleanup; 1557 if (isCXXException(exceptionObject->exception_class)) 1558 { 1559 __cxa_exception *ex = exceptionFromPointer(exceptionObject); 1560 ex->cleanupCount--; 1561 if (ex->cleanupCount == 0) 1562 { 1563 info->currentCleanup = ex->nextCleanup; 1564 ex->nextCleanup = 0; 1565 } 1566 } 1567 else 1568 { 1569 info->currentCleanup = 0; 1570 } 1571 return exceptionObject; 1572 } 1573 1574 asm ( 1575 ".pushsection .text.__cxa_end_cleanup \n" 1576 ".global __cxa_end_cleanup \n" 1577 ".type __cxa_end_cleanup, \"function\" \n" 1578 "__cxa_end_cleanup: \n" 1579 " push {r1, r2, r3, r4} \n" 1580 " bl __cxa_get_cleanup \n" 1581 " push {r1, r2, r3, r4} \n" 1582 " b _Unwind_Resume \n" 1583 " bl abort \n" 1584 ".popsection \n" 1585 ); 1586 #endif 1587