1 //===------------------------- cxa_exception.cpp --------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 // 9 // This file implements the "Exception Handling APIs" 10 // http://mentorembedded.github.io/cxx-abi/abi-eh.html 11 // http://www.intel.com/design/itanium/downloads/245358.htm 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include <assert.h> 16 #include <stdlib.h> 17 #include <typeinfo> 18 19 #include "config.h" 20 #include "cxa_exception.hpp" 21 #include "cxa_handlers.hpp" 22 #include "private_typeinfo.h" 23 #include "unwind.h" 24 25 #if LIBCXXABI_ARM_EHABI 26 #include "Unwind/libunwind_ext.h" 27 #endif 28 29 /* 30 Exception Header Layout: 31 32 +---------------------------+-----------------------------+---------------+ 33 | __cxa_exception | _Unwind_Exception CLNGC++\0 | thrown object | 34 +---------------------------+-----------------------------+---------------+ 35 ^ 36 | 37 +-------------------------------------------------------+ 38 | 39 +---------------------------+-----------------------------+ 40 | __cxa_dependent_exception | _Unwind_Exception CLNGC++\1 | 41 +---------------------------+-----------------------------+ 42 43 Exception Handling Table Layout: 44 45 +-----------------+--------+ 46 | lpStartEncoding | (char) | 47 +---------+-------+--------+---------------+-----------------------+ 48 | lpStart | (encoded with lpStartEncoding) | defaults to funcStart | 49 +---------+-----+--------+-----------------+---------------+-------+ 50 | ttypeEncoding | (char) | Encoding of the type_info table | 51 +---------------+-+------+----+----------------------------+----------------+ 52 | classInfoOffset | (ULEB128) | Offset to type_info table, defaults to null | 53 +-----------------++--------+-+----------------------------+----------------+ 54 | callSiteEncoding | (char) | Encoding for Call Site Table | 55 +------------------+--+-----+-----+------------------------+--------------------------+ 56 | callSiteTableLength | (ULEB128) | Call Site Table length, used to find Action table | 57 +---------------------+-----------+---------------------------------------------------+ 58 #ifndef __USING_SJLJ_EXCEPTIONS__ 59 +---------------------+-----------+------------------------------------------------+ 60 | Beginning of Call Site Table The current ip lies within the | 61 | ... (start, length) range of one of these | 62 | call sites. There may be action needed. | 63 | +-------------+---------------------------------+------------------------------+ | 64 | | start | (encoded with callSiteEncoding) | offset relative to funcStart | | 65 | | length | (encoded with callSiteEncoding) | length of code fragment | | 66 | | landingPad | (encoded with callSiteEncoding) | offset relative to lpStart | | 67 | | actionEntry | (ULEB128) | Action Table Index 1-based | | 68 | | | | actionEntry == 0 -> cleanup | | 69 | +-------------+---------------------------------+------------------------------+ | 70 | ... | 71 +----------------------------------------------------------------------------------+ 72 #else // __USING_SJLJ_EXCEPTIONS__ 73 +---------------------+-----------+------------------------------------------------+ 74 | Beginning of Call Site Table The current ip is a 1-based index into | 75 | ... this table. Or it is -1 meaning no | 76 | action is needed. Or it is 0 meaning | 77 | terminate. | 78 | +-------------+---------------------------------+------------------------------+ | 79 | | landingPad | (ULEB128) | offset relative to lpStart | | 80 | | actionEntry | (ULEB128) | Action Table Index 1-based | | 81 | | | | actionEntry == 0 -> cleanup | | 82 | +-------------+---------------------------------+------------------------------+ | 83 | ... | 84 +----------------------------------------------------------------------------------+ 85 #endif // __USING_SJLJ_EXCEPTIONS__ 86 +---------------------------------------------------------------------+ 87 | Beginning of Action Table ttypeIndex == 0 : cleanup | 88 | ... ttypeIndex > 0 : catch | 89 | ttypeIndex < 0 : exception spec | 90 | +--------------+-----------+--------------------------------------+ | 91 | | ttypeIndex | (SLEB128) | Index into type_info Table (1-based) | | 92 | | actionOffset | (SLEB128) | Offset into next Action Table entry | | 93 | +--------------+-----------+--------------------------------------+ | 94 | ... | 95 +---------------------------------------------------------------------+-----------------+ 96 | type_info Table, but classInfoOffset does *not* point here! | 97 | +----------------+------------------------------------------------+-----------------+ | 98 | | Nth type_info* | Encoded with ttypeEncoding, 0 means catch(...) | ttypeIndex == N | | 99 | +----------------+------------------------------------------------+-----------------+ | 100 | ... | 101 | +----------------+------------------------------------------------+-----------------+ | 102 | | 1st type_info* | Encoded with ttypeEncoding, 0 means catch(...) | ttypeIndex == 1 | | 103 | +----------------+------------------------------------------------+-----------------+ | 104 | +---------------------------------------+-----------+------------------------------+ | 105 | | 1st ttypeIndex for 1st exception spec | (ULEB128) | classInfoOffset points here! | | 106 | | ... | (ULEB128) | | | 107 | | Mth ttypeIndex for 1st exception spec | (ULEB128) | | | 108 | | 0 | (ULEB128) | | | 109 | +---------------------------------------+------------------------------------------+ | 110 | ... | 111 | +---------------------------------------+------------------------------------------+ | 112 | | 0 | (ULEB128) | throw() | | 113 | +---------------------------------------+------------------------------------------+ | 114 | ... | 115 | +---------------------------------------+------------------------------------------+ | 116 | | 1st ttypeIndex for Nth exception spec | (ULEB128) | | | 117 | | ... | (ULEB128) | | | 118 | | Mth ttypeIndex for Nth exception spec | (ULEB128) | | | 119 | | 0 | (ULEB128) | | | 120 | +---------------------------------------+------------------------------------------+ | 121 +---------------------------------------------------------------------------------------+ 122 123 Notes: 124 125 * ttypeIndex in the Action Table, and in the exception spec table, is an index, 126 not a byte count, if positive. It is a negative index offset of 127 classInfoOffset and the sizeof entry depends on ttypeEncoding. 128 But if ttypeIndex is negative, it is a positive 1-based byte offset into the 129 type_info Table. 130 And if ttypeIndex is zero, it refers to a catch (...). 131 132 * landingPad can be 0, this implies there is nothing to be done. 133 134 * landingPad != 0 and actionEntry == 0 implies a cleanup needs to be done 135 @landingPad. 136 137 * A cleanup can also be found under landingPad != 0 and actionEntry != 0 in 138 the Action Table with ttypeIndex == 0. 139 */ 140 141 namespace __cxxabiv1 142 { 143 144 extern "C" 145 { 146 147 // private API 148 149 // Heavily borrowed from llvm/examples/ExceptionDemo/ExceptionDemo.cpp 150 151 // DWARF Constants 152 enum 153 { 154 DW_EH_PE_absptr = 0x00, 155 DW_EH_PE_uleb128 = 0x01, 156 DW_EH_PE_udata2 = 0x02, 157 DW_EH_PE_udata4 = 0x03, 158 DW_EH_PE_udata8 = 0x04, 159 DW_EH_PE_sleb128 = 0x09, 160 DW_EH_PE_sdata2 = 0x0A, 161 DW_EH_PE_sdata4 = 0x0B, 162 DW_EH_PE_sdata8 = 0x0C, 163 DW_EH_PE_pcrel = 0x10, 164 DW_EH_PE_textrel = 0x20, 165 DW_EH_PE_datarel = 0x30, 166 DW_EH_PE_funcrel = 0x40, 167 DW_EH_PE_aligned = 0x50, 168 DW_EH_PE_indirect = 0x80, 169 DW_EH_PE_omit = 0xFF 170 }; 171 172 /// Read a uleb128 encoded value and advance pointer 173 /// See Variable Length Data Appendix C in: 174 /// @link http://dwarfstd.org/Dwarf4.pdf @unlink 175 /// @param data reference variable holding memory pointer to decode from 176 /// @returns decoded value 177 static 178 uintptr_t 179 readULEB128(const uint8_t** data) 180 { 181 uintptr_t result = 0; 182 uintptr_t shift = 0; 183 unsigned char byte; 184 const uint8_t *p = *data; 185 do 186 { 187 byte = *p++; 188 result |= static_cast<uintptr_t>(byte & 0x7F) << shift; 189 shift += 7; 190 } while (byte & 0x80); 191 *data = p; 192 return result; 193 } 194 195 /// Read a sleb128 encoded value and advance pointer 196 /// See Variable Length Data Appendix C in: 197 /// @link http://dwarfstd.org/Dwarf4.pdf @unlink 198 /// @param data reference variable holding memory pointer to decode from 199 /// @returns decoded value 200 static 201 intptr_t 202 readSLEB128(const uint8_t** data) 203 { 204 uintptr_t result = 0; 205 uintptr_t shift = 0; 206 unsigned char byte; 207 const uint8_t *p = *data; 208 do 209 { 210 byte = *p++; 211 result |= static_cast<uintptr_t>(byte & 0x7F) << shift; 212 shift += 7; 213 } while (byte & 0x80); 214 *data = p; 215 if ((byte & 0x40) && (shift < (sizeof(result) << 3))) 216 result |= static_cast<uintptr_t>(~0) << shift; 217 return static_cast<intptr_t>(result); 218 } 219 220 /// Read a pointer encoded value and advance pointer 221 /// See Variable Length Data in: 222 /// @link http://dwarfstd.org/Dwarf3.pdf @unlink 223 /// @param data reference variable holding memory pointer to decode from 224 /// @param encoding dwarf encoding type 225 /// @returns decoded value 226 static 227 uintptr_t 228 readEncodedPointer(const uint8_t** data, uint8_t encoding) 229 { 230 uintptr_t result = 0; 231 if (encoding == DW_EH_PE_omit) 232 return result; 233 const uint8_t* p = *data; 234 // first get value 235 switch (encoding & 0x0F) 236 { 237 case DW_EH_PE_absptr: 238 result = *((uintptr_t*)p); 239 p += sizeof(uintptr_t); 240 break; 241 case DW_EH_PE_uleb128: 242 result = readULEB128(&p); 243 break; 244 case DW_EH_PE_sleb128: 245 result = static_cast<uintptr_t>(readSLEB128(&p)); 246 break; 247 case DW_EH_PE_udata2: 248 result = *((uint16_t*)p); 249 p += sizeof(uint16_t); 250 break; 251 case DW_EH_PE_udata4: 252 result = *((uint32_t*)p); 253 p += sizeof(uint32_t); 254 break; 255 case DW_EH_PE_udata8: 256 result = static_cast<uintptr_t>(*((uint64_t*)p)); 257 p += sizeof(uint64_t); 258 break; 259 case DW_EH_PE_sdata2: 260 result = static_cast<uintptr_t>(*((int16_t*)p)); 261 p += sizeof(int16_t); 262 break; 263 case DW_EH_PE_sdata4: 264 result = static_cast<uintptr_t>(*((int32_t*)p)); 265 p += sizeof(int32_t); 266 break; 267 case DW_EH_PE_sdata8: 268 result = static_cast<uintptr_t>(*((int64_t*)p)); 269 p += sizeof(int64_t); 270 break; 271 default: 272 // not supported 273 abort(); 274 break; 275 } 276 // then add relative offset 277 switch (encoding & 0x70) 278 { 279 case DW_EH_PE_absptr: 280 // do nothing 281 break; 282 case DW_EH_PE_pcrel: 283 if (result) 284 result += (uintptr_t)(*data); 285 break; 286 case DW_EH_PE_textrel: 287 case DW_EH_PE_datarel: 288 case DW_EH_PE_funcrel: 289 case DW_EH_PE_aligned: 290 default: 291 // not supported 292 abort(); 293 break; 294 } 295 // then apply indirection 296 if (result && (encoding & DW_EH_PE_indirect)) 297 result = *((uintptr_t*)result); 298 *data = p; 299 return result; 300 } 301 302 static 303 void 304 call_terminate(bool native_exception, _Unwind_Exception* unwind_exception) 305 { 306 __cxa_begin_catch(unwind_exception); 307 if (native_exception) 308 { 309 // Use the stored terminate_handler if possible 310 __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; 311 std::__terminate(exception_header->terminateHandler); 312 } 313 std::terminate(); 314 } 315 316 #if LIBCXXABI_ARM_EHABI 317 static const void* read_target2_value(const void* ptr) 318 { 319 uintptr_t offset = *reinterpret_cast<const uintptr_t*>(ptr); 320 if (!offset) 321 return 0; 322 // "ARM EABI provides a TARGET2 relocation to describe these typeinfo 323 // pointers. The reason being it allows their precise semantics to be 324 // deferred to the linker. For bare-metal they turn into absolute 325 // relocations. For linux they turn into GOT-REL relocations." 326 // https://gcc.gnu.org/ml/gcc-patches/2009-08/msg00264.html 327 #if LIBCXXABI_BAREMETAL 328 return reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(ptr) + 329 offset); 330 #else 331 return *reinterpret_cast<const void **>(reinterpret_cast<uintptr_t>(ptr) + 332 offset); 333 #endif 334 } 335 336 static const __shim_type_info* 337 get_shim_type_info(uint64_t ttypeIndex, const uint8_t* classInfo, 338 uint8_t ttypeEncoding, bool native_exception, 339 _Unwind_Exception* unwind_exception) 340 { 341 if (classInfo == 0) 342 { 343 // this should not happen. Indicates corrupted eh_table. 344 call_terminate(native_exception, unwind_exception); 345 } 346 347 assert(ttypeEncoding == DW_EH_PE_absptr && "Unexpected TTypeEncoding"); 348 (void)ttypeEncoding; 349 350 const uint8_t* ttypePtr = classInfo - ttypeIndex * sizeof(uintptr_t); 351 return reinterpret_cast<const __shim_type_info *>( 352 read_target2_value(ttypePtr)); 353 } 354 #else // !LIBCXXABI_ARM_EHABI 355 static 356 const __shim_type_info* 357 get_shim_type_info(uint64_t ttypeIndex, const uint8_t* classInfo, 358 uint8_t ttypeEncoding, bool native_exception, 359 _Unwind_Exception* unwind_exception) 360 { 361 if (classInfo == 0) 362 { 363 // this should not happen. Indicates corrupted eh_table. 364 call_terminate(native_exception, unwind_exception); 365 } 366 switch (ttypeEncoding & 0x0F) 367 { 368 case DW_EH_PE_absptr: 369 ttypeIndex *= sizeof(void*); 370 break; 371 case DW_EH_PE_udata2: 372 case DW_EH_PE_sdata2: 373 ttypeIndex *= 2; 374 break; 375 case DW_EH_PE_udata4: 376 case DW_EH_PE_sdata4: 377 ttypeIndex *= 4; 378 break; 379 case DW_EH_PE_udata8: 380 case DW_EH_PE_sdata8: 381 ttypeIndex *= 8; 382 break; 383 default: 384 // this should not happen. Indicates corrupted eh_table. 385 call_terminate(native_exception, unwind_exception); 386 } 387 classInfo -= ttypeIndex; 388 return (const __shim_type_info*)readEncodedPointer(&classInfo, ttypeEncoding); 389 } 390 #endif // !LIBCXXABI_ARM_EHABI 391 392 /* 393 This is checking a thrown exception type, excpType, against a possibly empty 394 list of catchType's which make up an exception spec. 395 396 An exception spec acts like a catch handler, but in reverse. This "catch 397 handler" will catch an excpType if and only if none of the catchType's in 398 the list will catch a excpType. If any catchType in the list can catch an 399 excpType, then this exception spec does not catch the excpType. 400 */ 401 #if LIBCXXABI_ARM_EHABI 402 static 403 bool 404 exception_spec_can_catch(int64_t specIndex, const uint8_t* classInfo, 405 uint8_t ttypeEncoding, const __shim_type_info* excpType, 406 void* adjustedPtr, _Unwind_Exception* unwind_exception) 407 { 408 if (classInfo == 0) 409 { 410 // this should not happen. Indicates corrupted eh_table. 411 call_terminate(false, unwind_exception); 412 } 413 414 assert(ttypeEncoding == DW_EH_PE_absptr && "Unexpected TTypeEncoding"); 415 (void)ttypeEncoding; 416 417 // specIndex is negative of 1-based byte offset into classInfo; 418 specIndex = -specIndex; 419 --specIndex; 420 const void** temp = reinterpret_cast<const void**>( 421 reinterpret_cast<uintptr_t>(classInfo) + 422 static_cast<uintptr_t>(specIndex) * sizeof(uintptr_t)); 423 // If any type in the spec list can catch excpType, return false, else return true 424 // adjustments to adjustedPtr are ignored. 425 while (true) 426 { 427 // ARM EHABI exception specification table (filter table) consists of 428 // several pointers which will directly point to the type info object 429 // (instead of ttypeIndex). The table will be terminated with 0. 430 const void** ttypePtr = temp++; 431 if (*ttypePtr == 0) 432 break; 433 // We can get the __shim_type_info simply by performing a 434 // R_ARM_TARGET2 relocation, and cast the result to __shim_type_info. 435 const __shim_type_info* catchType = 436 static_cast<const __shim_type_info*>(read_target2_value(ttypePtr)); 437 void* tempPtr = adjustedPtr; 438 if (catchType->can_catch(excpType, tempPtr)) 439 return false; 440 } 441 return true; 442 } 443 #else 444 static 445 bool 446 exception_spec_can_catch(int64_t specIndex, const uint8_t* classInfo, 447 uint8_t ttypeEncoding, const __shim_type_info* excpType, 448 void* adjustedPtr, _Unwind_Exception* unwind_exception) 449 { 450 if (classInfo == 0) 451 { 452 // this should not happen. Indicates corrupted eh_table. 453 call_terminate(false, unwind_exception); 454 } 455 // specIndex is negative of 1-based byte offset into classInfo; 456 specIndex = -specIndex; 457 --specIndex; 458 const uint8_t* temp = classInfo + specIndex; 459 // If any type in the spec list can catch excpType, return false, else return true 460 // adjustments to adjustedPtr are ignored. 461 while (true) 462 { 463 uint64_t ttypeIndex = readULEB128(&temp); 464 if (ttypeIndex == 0) 465 break; 466 const __shim_type_info* catchType = get_shim_type_info(ttypeIndex, 467 classInfo, 468 ttypeEncoding, 469 true, 470 unwind_exception); 471 void* tempPtr = adjustedPtr; 472 if (catchType->can_catch(excpType, tempPtr)) 473 return false; 474 } 475 return true; 476 } 477 #endif 478 479 static 480 void* 481 get_thrown_object_ptr(_Unwind_Exception* unwind_exception) 482 { 483 // Even for foreign exceptions, the exception object is *probably* at unwind_exception + 1 484 // Regardless, this library is prohibited from touching a foreign exception 485 void* adjustedPtr = unwind_exception + 1; 486 if (unwind_exception->exception_class == kOurDependentExceptionClass) 487 adjustedPtr = ((__cxa_dependent_exception*)adjustedPtr - 1)->primaryException; 488 return adjustedPtr; 489 } 490 491 namespace 492 { 493 494 struct scan_results 495 { 496 int64_t ttypeIndex; // > 0 catch handler, < 0 exception spec handler, == 0 a cleanup 497 const uint8_t* actionRecord; // Currently unused. Retained to ease future maintenance. 498 const uint8_t* languageSpecificData; // Needed only for __cxa_call_unexpected 499 uintptr_t landingPad; // null -> nothing found, else something found 500 void* adjustedPtr; // Used in cxa_exception.cpp 501 _Unwind_Reason_Code reason; // One of _URC_FATAL_PHASE1_ERROR, 502 // _URC_FATAL_PHASE2_ERROR, 503 // _URC_CONTINUE_UNWIND, 504 // _URC_HANDLER_FOUND 505 }; 506 507 } // unnamed namespace 508 509 static 510 void 511 set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context, 512 const scan_results& results) 513 { 514 _Unwind_SetGR(context, __builtin_eh_return_data_regno(0), 515 reinterpret_cast<uintptr_t>(unwind_exception)); 516 _Unwind_SetGR(context, __builtin_eh_return_data_regno(1), 517 static_cast<uintptr_t>(results.ttypeIndex)); 518 _Unwind_SetIP(context, results.landingPad); 519 } 520 521 /* 522 There are 3 types of scans needed: 523 524 1. Scan for handler with native or foreign exception. If handler found, 525 save state and return _URC_HANDLER_FOUND, else return _URC_CONTINUE_UNWIND. 526 May also report an error on invalid input. 527 May terminate for invalid exception table. 528 _UA_SEARCH_PHASE 529 530 2. Scan for handler with foreign exception. Must return _URC_HANDLER_FOUND, 531 or call terminate. 532 _UA_CLEANUP_PHASE && _UA_HANDLER_FRAME && !native_exception 533 534 3. Scan for cleanups. If a handler is found and this isn't forced unwind, 535 then terminate, otherwise ignore the handler and keep looking for cleanup. 536 If a cleanup is found, return _URC_HANDLER_FOUND, else return _URC_CONTINUE_UNWIND. 537 May also report an error on invalid input. 538 May terminate for invalid exception table. 539 _UA_CLEANUP_PHASE && !_UA_HANDLER_FRAME 540 */ 541 542 static void scan_eh_tab(scan_results &results, _Unwind_Action actions, 543 bool native_exception, 544 _Unwind_Exception *unwind_exception, 545 _Unwind_Context *context) { 546 // Initialize results to found nothing but an error 547 results.ttypeIndex = 0; 548 results.actionRecord = 0; 549 results.languageSpecificData = 0; 550 results.landingPad = 0; 551 results.adjustedPtr = 0; 552 results.reason = _URC_FATAL_PHASE1_ERROR; 553 // Check for consistent actions 554 if (actions & _UA_SEARCH_PHASE) 555 { 556 // Do Phase 1 557 if (actions & (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME | _UA_FORCE_UNWIND)) 558 { 559 // None of these flags should be set during Phase 1 560 // Client error 561 results.reason = _URC_FATAL_PHASE1_ERROR; 562 return; 563 } 564 } 565 else if (actions & _UA_CLEANUP_PHASE) 566 { 567 if ((actions & _UA_HANDLER_FRAME) && (actions & _UA_FORCE_UNWIND)) 568 { 569 // _UA_HANDLER_FRAME should only be set if phase 1 found a handler. 570 // If _UA_FORCE_UNWIND is set, phase 1 shouldn't have happened. 571 // Client error 572 results.reason = _URC_FATAL_PHASE2_ERROR; 573 return; 574 } 575 } 576 else // Neither _UA_SEARCH_PHASE nor _UA_CLEANUP_PHASE is set 577 { 578 // One of these should be set. 579 // Client error 580 results.reason = _URC_FATAL_PHASE1_ERROR; 581 return; 582 } 583 // Start scan by getting exception table address 584 const uint8_t *lsda = (const uint8_t *)_Unwind_GetLanguageSpecificData(context); 585 if (lsda == 0) 586 { 587 // There is no exception table 588 results.reason = _URC_CONTINUE_UNWIND; 589 return; 590 } 591 results.languageSpecificData = lsda; 592 // Get the current instruction pointer and offset it before next 593 // instruction in the current frame which threw the exception. 594 uintptr_t ip = _Unwind_GetIP(context) - 1; 595 // Get beginning current frame's code (as defined by the 596 // emitted dwarf code) 597 uintptr_t funcStart = _Unwind_GetRegionStart(context); 598 #ifdef __USING_SJLJ_EXCEPTIONS__ 599 if (ip == uintptr_t(-1)) 600 { 601 // no action 602 results.reason = _URC_CONTINUE_UNWIND; 603 return; 604 } 605 else if (ip == 0) 606 call_terminate(native_exception, unwind_exception); 607 // ip is 1-based index into call site table 608 #else // !__USING_SJLJ_EXCEPTIONS__ 609 uintptr_t ipOffset = ip - funcStart; 610 #endif // !defined(_USING_SLJL_EXCEPTIONS__) 611 const uint8_t* classInfo = NULL; 612 // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding 613 // dwarf emission 614 // Parse LSDA header. 615 uint8_t lpStartEncoding = *lsda++; 616 const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding); 617 if (lpStart == 0) 618 lpStart = (const uint8_t*)funcStart; 619 uint8_t ttypeEncoding = *lsda++; 620 if (ttypeEncoding != DW_EH_PE_omit) 621 { 622 // Calculate type info locations in emitted dwarf code which 623 // were flagged by type info arguments to llvm.eh.selector 624 // intrinsic 625 uintptr_t classInfoOffset = readULEB128(&lsda); 626 classInfo = lsda + classInfoOffset; 627 } 628 // Walk call-site table looking for range that 629 // includes current PC. 630 uint8_t callSiteEncoding = *lsda++; 631 #ifdef __USING_SJLJ_EXCEPTIONS__ 632 (void)callSiteEncoding; // When using SjLj exceptions, callSiteEncoding is never used 633 #endif 634 uint32_t callSiteTableLength = static_cast<uint32_t>(readULEB128(&lsda)); 635 const uint8_t* callSiteTableStart = lsda; 636 const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength; 637 const uint8_t* actionTableStart = callSiteTableEnd; 638 const uint8_t* callSitePtr = callSiteTableStart; 639 while (callSitePtr < callSiteTableEnd) 640 { 641 // There is one entry per call site. 642 #ifndef __USING_SJLJ_EXCEPTIONS__ 643 // The call sites are non-overlapping in [start, start+length) 644 // The call sites are ordered in increasing value of start 645 uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding); 646 uintptr_t length = readEncodedPointer(&callSitePtr, callSiteEncoding); 647 uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding); 648 uintptr_t actionEntry = readULEB128(&callSitePtr); 649 if ((start <= ipOffset) && (ipOffset < (start + length))) 650 #else // __USING_SJLJ_EXCEPTIONS__ 651 // ip is 1-based index into this table 652 uintptr_t landingPad = readULEB128(&callSitePtr); 653 uintptr_t actionEntry = readULEB128(&callSitePtr); 654 if (--ip == 0) 655 #endif // __USING_SJLJ_EXCEPTIONS__ 656 { 657 // Found the call site containing ip. 658 #ifndef __USING_SJLJ_EXCEPTIONS__ 659 if (landingPad == 0) 660 { 661 // No handler here 662 results.reason = _URC_CONTINUE_UNWIND; 663 return; 664 } 665 landingPad = (uintptr_t)lpStart + landingPad; 666 #else // __USING_SJLJ_EXCEPTIONS__ 667 ++landingPad; 668 #endif // __USING_SJLJ_EXCEPTIONS__ 669 if (actionEntry == 0) 670 { 671 // Found a cleanup 672 // If this is a type 1 or type 2 search, there are no handlers 673 // If this is a type 3 search, you want to install the cleanup. 674 if ((actions & _UA_CLEANUP_PHASE) && !(actions & _UA_HANDLER_FRAME)) 675 { 676 results.ttypeIndex = 0; // Redundant but clarifying 677 results.landingPad = landingPad; 678 results.reason = _URC_HANDLER_FOUND; 679 return; 680 } 681 // No handler here 682 results.reason = _URC_CONTINUE_UNWIND; 683 return; 684 } 685 // Convert 1-based byte offset into 686 const uint8_t* action = actionTableStart + (actionEntry - 1); 687 // Scan action entries until you find a matching handler, cleanup, or the end of action list 688 while (true) 689 { 690 const uint8_t* actionRecord = action; 691 int64_t ttypeIndex = readSLEB128(&action); 692 if (ttypeIndex > 0) 693 { 694 // Found a catch, does it actually catch? 695 // First check for catch (...) 696 const __shim_type_info* catchType = 697 get_shim_type_info(static_cast<uint64_t>(ttypeIndex), 698 classInfo, ttypeEncoding, 699 native_exception, unwind_exception); 700 if (catchType == 0) 701 { 702 // Found catch (...) catches everything, including foreign exceptions 703 // If this is a type 1 search save state and return _URC_HANDLER_FOUND 704 // If this is a type 2 search save state and return _URC_HANDLER_FOUND 705 // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1! 706 // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan 707 if ((actions & _UA_SEARCH_PHASE) || (actions & _UA_HANDLER_FRAME)) 708 { 709 // Save state and return _URC_HANDLER_FOUND 710 results.ttypeIndex = ttypeIndex; 711 results.actionRecord = actionRecord; 712 results.landingPad = landingPad; 713 results.adjustedPtr = get_thrown_object_ptr(unwind_exception); 714 results.reason = _URC_HANDLER_FOUND; 715 return; 716 } 717 else if (!(actions & _UA_FORCE_UNWIND)) 718 { 719 // It looks like the exception table has changed 720 // on us. Likely stack corruption! 721 call_terminate(native_exception, unwind_exception); 722 } 723 } 724 // Else this is a catch (T) clause and will never 725 // catch a foreign exception 726 else if (native_exception) 727 { 728 __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; 729 void* adjustedPtr = get_thrown_object_ptr(unwind_exception); 730 const __shim_type_info* excpType = 731 static_cast<const __shim_type_info*>(exception_header->exceptionType); 732 if (adjustedPtr == 0 || excpType == 0) 733 { 734 // Something very bad happened 735 call_terminate(native_exception, unwind_exception); 736 } 737 if (catchType->can_catch(excpType, adjustedPtr)) 738 { 739 // Found a matching handler 740 // If this is a type 1 search save state and return _URC_HANDLER_FOUND 741 // If this is a type 3 search and !_UA_FORCE_UNWIND, we should have found this in phase 1! 742 // If this is a type 3 search and _UA_FORCE_UNWIND, ignore handler and continue scan 743 if (actions & _UA_SEARCH_PHASE) 744 { 745 // Save state and return _URC_HANDLER_FOUND 746 results.ttypeIndex = ttypeIndex; 747 results.actionRecord = actionRecord; 748 results.landingPad = landingPad; 749 results.adjustedPtr = adjustedPtr; 750 results.reason = _URC_HANDLER_FOUND; 751 return; 752 } 753 else if (!(actions & _UA_FORCE_UNWIND)) 754 { 755 // It looks like the exception table has changed 756 // on us. Likely stack corruption! 757 call_terminate(native_exception, unwind_exception); 758 } 759 } 760 } 761 // Scan next action ... 762 } 763 else if (ttypeIndex < 0) 764 { 765 // Found an exception spec. If this is a foreign exception, 766 // it is always caught. 767 if (native_exception) 768 { 769 // Does the exception spec catch this native exception? 770 __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; 771 void* adjustedPtr = get_thrown_object_ptr(unwind_exception); 772 const __shim_type_info* excpType = 773 static_cast<const __shim_type_info*>(exception_header->exceptionType); 774 if (adjustedPtr == 0 || excpType == 0) 775 { 776 // Something very bad happened 777 call_terminate(native_exception, unwind_exception); 778 } 779 if (exception_spec_can_catch(ttypeIndex, classInfo, 780 ttypeEncoding, excpType, 781 adjustedPtr, unwind_exception)) 782 { 783 // native exception caught by exception spec 784 // If this is a type 1 search, save state and return _URC_HANDLER_FOUND 785 // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1! 786 // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan 787 if (actions & _UA_SEARCH_PHASE) 788 { 789 // Save state and return _URC_HANDLER_FOUND 790 results.ttypeIndex = ttypeIndex; 791 results.actionRecord = actionRecord; 792 results.landingPad = landingPad; 793 results.adjustedPtr = adjustedPtr; 794 results.reason = _URC_HANDLER_FOUND; 795 return; 796 } 797 else if (!(actions & _UA_FORCE_UNWIND)) 798 { 799 // It looks like the exception table has changed 800 // on us. Likely stack corruption! 801 call_terminate(native_exception, unwind_exception); 802 } 803 } 804 } 805 else 806 { 807 // foreign exception caught by exception spec 808 // If this is a type 1 search, save state and return _URC_HANDLER_FOUND 809 // If this is a type 2 search, save state and return _URC_HANDLER_FOUND 810 // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1! 811 // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan 812 if ((actions & _UA_SEARCH_PHASE) || (actions & _UA_HANDLER_FRAME)) 813 { 814 // Save state and return _URC_HANDLER_FOUND 815 results.ttypeIndex = ttypeIndex; 816 results.actionRecord = actionRecord; 817 results.landingPad = landingPad; 818 results.adjustedPtr = get_thrown_object_ptr(unwind_exception); 819 results.reason = _URC_HANDLER_FOUND; 820 return; 821 } 822 else if (!(actions & _UA_FORCE_UNWIND)) 823 { 824 // It looks like the exception table has changed 825 // on us. Likely stack corruption! 826 call_terminate(native_exception, unwind_exception); 827 } 828 } 829 // Scan next action ... 830 } 831 else // ttypeIndex == 0 832 { 833 // Found a cleanup 834 // If this is a type 1 search, ignore it and continue scan 835 // If this is a type 2 search, ignore it and continue scan 836 // If this is a type 3 search, save state and return _URC_HANDLER_FOUND 837 if ((actions & _UA_CLEANUP_PHASE) && !(actions & _UA_HANDLER_FRAME)) 838 { 839 // Save state and return _URC_HANDLER_FOUND 840 results.ttypeIndex = ttypeIndex; 841 results.actionRecord = actionRecord; 842 results.landingPad = landingPad; 843 results.adjustedPtr = get_thrown_object_ptr(unwind_exception); 844 results.reason = _URC_HANDLER_FOUND; 845 return; 846 } 847 } 848 const uint8_t* temp = action; 849 int64_t actionOffset = readSLEB128(&temp); 850 if (actionOffset == 0) 851 { 852 // End of action list, no matching handler or cleanup found 853 results.reason = _URC_CONTINUE_UNWIND; 854 return; 855 } 856 // Go to next action 857 action += actionOffset; 858 } // there is no break out of this loop, only return 859 } 860 #ifndef __USING_SJLJ_EXCEPTIONS__ 861 else if (ipOffset < start) 862 { 863 // There is no call site for this ip 864 // Something bad has happened. We should never get here. 865 // Possible stack corruption. 866 call_terminate(native_exception, unwind_exception); 867 } 868 #endif // !__USING_SJLJ_EXCEPTIONS__ 869 } // there might be some tricky cases which break out of this loop 870 871 // It is possible that no eh table entry specify how to handle 872 // this exception. By spec, terminate it immediately. 873 call_terminate(native_exception, unwind_exception); 874 } 875 876 // public API 877 878 /* 879 The personality function branches on actions like so: 880 881 _UA_SEARCH_PHASE 882 883 If _UA_CLEANUP_PHASE or _UA_HANDLER_FRAME or _UA_FORCE_UNWIND there's 884 an error from above, return _URC_FATAL_PHASE1_ERROR. 885 886 Scan for anything that could stop unwinding: 887 888 1. A catch clause that will catch this exception 889 (will never catch foreign). 890 2. A catch (...) (will always catch foreign). 891 3. An exception spec that will catch this exception 892 (will always catch foreign). 893 If a handler is found 894 If not foreign 895 Save state in header 896 return _URC_HANDLER_FOUND 897 Else a handler not found 898 return _URC_CONTINUE_UNWIND 899 900 _UA_CLEANUP_PHASE 901 902 If _UA_HANDLER_FRAME 903 If _UA_FORCE_UNWIND 904 How did this happen? return _URC_FATAL_PHASE2_ERROR 905 If foreign 906 Do _UA_SEARCH_PHASE to recover state 907 else 908 Recover state from header 909 Transfer control to landing pad. return _URC_INSTALL_CONTEXT 910 911 Else 912 913 This branch handles both normal C++ non-catching handlers (cleanups) 914 and forced unwinding. 915 Scan for anything that can not stop unwinding: 916 917 1. A cleanup. 918 919 If a cleanup is found 920 transfer control to it. return _URC_INSTALL_CONTEXT 921 Else a cleanup is not found: return _URC_CONTINUE_UNWIND 922 */ 923 924 #if !LIBCXXABI_ARM_EHABI 925 _Unwind_Reason_Code 926 #ifdef __USING_SJLJ_EXCEPTIONS__ 927 __gxx_personality_sj0 928 #else 929 __gxx_personality_v0 930 #endif 931 (int version, _Unwind_Action actions, uint64_t exceptionClass, 932 _Unwind_Exception* unwind_exception, _Unwind_Context* context) 933 { 934 if (version != 1 || unwind_exception == 0 || context == 0) 935 return _URC_FATAL_PHASE1_ERROR; 936 937 bool native_exception = (exceptionClass & get_vendor_and_language) == 938 (kOurExceptionClass & get_vendor_and_language); 939 scan_results results; 940 if (actions & _UA_SEARCH_PHASE) 941 { 942 // Phase 1 search: All we're looking for in phase 1 is a handler that 943 // halts unwinding 944 scan_eh_tab(results, actions, native_exception, unwind_exception, context); 945 if (results.reason == _URC_HANDLER_FOUND) 946 { 947 // Found one. Can we cache the results somewhere to optimize phase 2? 948 if (native_exception) 949 { 950 __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; 951 exception_header->handlerSwitchValue = static_cast<int>(results.ttypeIndex); 952 exception_header->actionRecord = results.actionRecord; 953 exception_header->languageSpecificData = results.languageSpecificData; 954 exception_header->catchTemp = reinterpret_cast<void*>(results.landingPad); 955 exception_header->adjustedPtr = results.adjustedPtr; 956 } 957 return _URC_HANDLER_FOUND; 958 } 959 // Did not find a catching-handler. Return the results of the scan 960 // (normally _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE1_ERROR 961 // if we were called improperly). 962 return results.reason; 963 } 964 if (actions & _UA_CLEANUP_PHASE) 965 { 966 // Phase 2 search: 967 // Did we find a catching handler in phase 1? 968 if (actions & _UA_HANDLER_FRAME) 969 { 970 // Yes, phase 1 said we have a catching handler here. 971 // Did we cache the results of the scan? 972 if (native_exception) 973 { 974 // Yes, reload the results from the cache. 975 __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; 976 results.ttypeIndex = exception_header->handlerSwitchValue; 977 results.actionRecord = exception_header->actionRecord; 978 results.languageSpecificData = exception_header->languageSpecificData; 979 results.landingPad = reinterpret_cast<uintptr_t>(exception_header->catchTemp); 980 results.adjustedPtr = exception_header->adjustedPtr; 981 } 982 else 983 { 984 // No, do the scan again to reload the results. 985 scan_eh_tab(results, actions, native_exception, unwind_exception, context); 986 // Phase 1 told us we would find a handler. Now in Phase 2 we 987 // didn't find a handler. The eh table should not be changing! 988 if (results.reason != _URC_HANDLER_FOUND) 989 call_terminate(native_exception, unwind_exception); 990 } 991 // Jump to the handler 992 set_registers(unwind_exception, context, results); 993 return _URC_INSTALL_CONTEXT; 994 } 995 // Either we didn't do a phase 1 search (due to forced unwinding), or 996 // phase 1 reported no catching-handlers. 997 // Search for a (non-catching) cleanup 998 scan_eh_tab(results, actions, native_exception, unwind_exception, context); 999 if (results.reason == _URC_HANDLER_FOUND) 1000 { 1001 // Found a non-catching handler. Jump to it: 1002 set_registers(unwind_exception, context, results); 1003 return _URC_INSTALL_CONTEXT; 1004 } 1005 // Did not find a cleanup. Return the results of the scan 1006 // (normally _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE2_ERROR 1007 // if we were called improperly). 1008 return results.reason; 1009 } 1010 // We were called improperly: neither a phase 1 or phase 2 search 1011 return _URC_FATAL_PHASE1_ERROR; 1012 } 1013 #else 1014 1015 #if !LIBCXXABI_USE_LLVM_UNWINDER 1016 extern "C" _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception*, _Unwind_Context*); 1017 #endif 1018 1019 // Helper function to unwind one frame. 1020 // ARM EHABI 7.3 and 7.4: If the personality function returns _URC_CONTINUE_UNWIND, the 1021 // personality routine should update the virtual register set (VRS) according to the 1022 // corresponding frame unwinding instructions (ARM EHABI 9.3.) 1023 static _Unwind_Reason_Code continue_unwind(_Unwind_Exception* unwind_exception, 1024 _Unwind_Context* context) 1025 { 1026 #if LIBCXXABI_USE_LLVM_UNWINDER 1027 // ARM EHABI # 6.2, # 9.2 1028 // 1029 // +---- ehtp 1030 // v 1031 // +--------------------------------------+ 1032 // | +--------+--------+--------+-------+ | 1033 // | |0| prel31 to __gxx_personality_v0 | | 1034 // | +--------+--------+--------+-------+ | 1035 // | | N | unwind opcodes | | <-- unwind_opcodes 1036 // | +--------+--------+--------+-------+ | 1037 // | | Word 2 unwind opcodes | | 1038 // | +--------+--------+--------+-------+ | 1039 // | ... | 1040 // | +--------+--------+--------+-------+ | 1041 // | | Word N unwind opcodes | | 1042 // | +--------+--------+--------+-------+ | 1043 // | | LSDA | | <-- lsda 1044 // | | ... | | 1045 // | +--------+--------+--------+-------+ | 1046 // +--------------------------------------+ 1047 1048 uint32_t *unwind_opcodes = unwind_exception->pr_cache.ehtp + 1; 1049 size_t opcode_words = ((*unwind_opcodes >> 24) & 0xff) + 1; 1050 if (_Unwind_VRS_Interpret(context, unwind_opcodes, 1, opcode_words * 4) != 1051 _URC_CONTINUE_UNWIND) 1052 return _URC_FAILURE; 1053 #else 1054 if (__gnu_unwind_frame(unwind_exception, context) != _URC_OK) 1055 return _URC_FAILURE; 1056 #endif 1057 return _URC_CONTINUE_UNWIND; 1058 } 1059 1060 // ARM register names 1061 #if !LIBCXXABI_USE_LLVM_UNWINDER 1062 static const uint32_t REG_UCB = 12; // Register to save _Unwind_Control_Block 1063 #endif 1064 static const uint32_t REG_SP = 13; 1065 1066 static void save_results_to_barrier_cache(_Unwind_Exception* unwind_exception, 1067 const scan_results& results) 1068 { 1069 unwind_exception->barrier_cache.bitpattern[0] = (uint32_t)results.adjustedPtr; 1070 unwind_exception->barrier_cache.bitpattern[1] = (uint32_t)results.actionRecord; 1071 unwind_exception->barrier_cache.bitpattern[2] = (uint32_t)results.languageSpecificData; 1072 unwind_exception->barrier_cache.bitpattern[3] = (uint32_t)results.landingPad; 1073 unwind_exception->barrier_cache.bitpattern[4] = (uint32_t)results.ttypeIndex; 1074 } 1075 1076 static void load_results_from_barrier_cache(scan_results& results, 1077 const _Unwind_Exception* unwind_exception) 1078 { 1079 results.adjustedPtr = (void*)unwind_exception->barrier_cache.bitpattern[0]; 1080 results.actionRecord = (const uint8_t*)unwind_exception->barrier_cache.bitpattern[1]; 1081 results.languageSpecificData = (const uint8_t*)unwind_exception->barrier_cache.bitpattern[2]; 1082 results.landingPad = (uintptr_t)unwind_exception->barrier_cache.bitpattern[3]; 1083 results.ttypeIndex = (int64_t)(int32_t)unwind_exception->barrier_cache.bitpattern[4]; 1084 } 1085 1086 extern "C" _Unwind_Reason_Code 1087 __gxx_personality_v0(_Unwind_State state, 1088 _Unwind_Exception* unwind_exception, 1089 _Unwind_Context* context) 1090 { 1091 if (unwind_exception == 0 || context == 0) 1092 return _URC_FATAL_PHASE1_ERROR; 1093 1094 bool native_exception = (unwind_exception->exception_class & get_vendor_and_language) == 1095 (kOurExceptionClass & get_vendor_and_language); 1096 1097 #if !LIBCXXABI_USE_LLVM_UNWINDER 1098 // Copy the address of _Unwind_Control_Block to r12 so that 1099 // _Unwind_GetLanguageSpecificData() and _Unwind_GetRegionStart() can 1100 // return correct address. 1101 _Unwind_SetGR(context, REG_UCB, reinterpret_cast<uint32_t>(unwind_exception)); 1102 #endif 1103 1104 // Check the undocumented force unwinding behavior 1105 bool is_force_unwinding = state & _US_FORCE_UNWIND; 1106 state &= ~_US_FORCE_UNWIND; 1107 1108 scan_results results; 1109 switch (state) { 1110 case _US_VIRTUAL_UNWIND_FRAME: 1111 if (is_force_unwinding) 1112 return continue_unwind(unwind_exception, context); 1113 1114 // Phase 1 search: All we're looking for in phase 1 is a handler that halts unwinding 1115 scan_eh_tab(results, _UA_SEARCH_PHASE, native_exception, unwind_exception, context); 1116 if (results.reason == _URC_HANDLER_FOUND) 1117 { 1118 unwind_exception->barrier_cache.sp = _Unwind_GetGR(context, REG_SP); 1119 if (native_exception) 1120 save_results_to_barrier_cache(unwind_exception, results); 1121 return _URC_HANDLER_FOUND; 1122 } 1123 // Did not find the catch handler 1124 if (results.reason == _URC_CONTINUE_UNWIND) 1125 return continue_unwind(unwind_exception, context); 1126 return results.reason; 1127 1128 case _US_UNWIND_FRAME_STARTING: 1129 // TODO: Support force unwinding in the phase 2 search. 1130 // NOTE: In order to call the cleanup functions, _Unwind_ForcedUnwind() 1131 // will call this personality function with (_US_FORCE_UNWIND | 1132 // _US_UNWIND_FRAME_STARTING). 1133 1134 // Phase 2 search 1135 if (unwind_exception->barrier_cache.sp == _Unwind_GetGR(context, REG_SP)) 1136 { 1137 // Found a catching handler in phase 1 1138 if (native_exception) 1139 { 1140 // Load the result from the native exception barrier cache. 1141 load_results_from_barrier_cache(results, unwind_exception); 1142 results.reason = _URC_HANDLER_FOUND; 1143 } 1144 else 1145 { 1146 // Search for the catching handler again for the foreign exception. 1147 scan_eh_tab(results, static_cast<_Unwind_Action>(_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME), 1148 native_exception, unwind_exception, context); 1149 if (results.reason != _URC_HANDLER_FOUND) // phase1 search should guarantee to find one 1150 call_terminate(native_exception, unwind_exception); 1151 } 1152 1153 // Install the context for the catching handler 1154 set_registers(unwind_exception, context, results); 1155 return _URC_INSTALL_CONTEXT; 1156 } 1157 1158 // Either we didn't do a phase 1 search (due to forced unwinding), or 1159 // phase 1 reported no catching-handlers. 1160 // Search for a (non-catching) cleanup 1161 scan_eh_tab(results, _UA_CLEANUP_PHASE, native_exception, unwind_exception, context); 1162 if (results.reason == _URC_HANDLER_FOUND) 1163 { 1164 // Found a non-catching handler 1165 1166 // ARM EHABI 8.4.2: Before we can jump to the cleanup handler, we have to setup some 1167 // internal data structures, so that __cxa_end_cleanup() can get unwind_exception from 1168 // __cxa_get_globals(). 1169 __cxa_begin_cleanup(unwind_exception); 1170 1171 // Install the context for the cleanup handler 1172 set_registers(unwind_exception, context, results); 1173 return _URC_INSTALL_CONTEXT; 1174 } 1175 1176 // Did not find any handler 1177 if (results.reason == _URC_CONTINUE_UNWIND) 1178 return continue_unwind(unwind_exception, context); 1179 return results.reason; 1180 1181 case _US_UNWIND_FRAME_RESUME: 1182 return continue_unwind(unwind_exception, context); 1183 } 1184 1185 // We were called improperly: neither a phase 1 or phase 2 search 1186 return _URC_FATAL_PHASE1_ERROR; 1187 } 1188 #endif 1189 1190 1191 __attribute__((noreturn)) 1192 void 1193 __cxa_call_unexpected(void* arg) 1194 { 1195 _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(arg); 1196 if (unwind_exception == 0) 1197 call_terminate(false, unwind_exception); 1198 __cxa_begin_catch(unwind_exception); 1199 bool native_old_exception = 1200 (unwind_exception->exception_class & get_vendor_and_language) == 1201 (kOurExceptionClass & get_vendor_and_language); 1202 std::unexpected_handler u_handler; 1203 std::terminate_handler t_handler; 1204 __cxa_exception* old_exception_header = 0; 1205 int64_t ttypeIndex; 1206 const uint8_t* lsda; 1207 if (native_old_exception) 1208 { 1209 old_exception_header = (__cxa_exception*)(unwind_exception+1) - 1; 1210 t_handler = old_exception_header->terminateHandler; 1211 u_handler = old_exception_header->unexpectedHandler; 1212 // If std::__unexpected(u_handler) rethrows the same exception, 1213 // these values get overwritten by the rethrow. So save them now: 1214 #if LIBCXXABI_ARM_EHABI 1215 ttypeIndex = (int64_t)(int32_t)unwind_exception->barrier_cache.bitpattern[4]; 1216 lsda = (const uint8_t*)unwind_exception->barrier_cache.bitpattern[2]; 1217 #else 1218 ttypeIndex = old_exception_header->handlerSwitchValue; 1219 lsda = old_exception_header->languageSpecificData; 1220 #endif 1221 } 1222 else 1223 { 1224 t_handler = std::get_terminate(); 1225 u_handler = std::get_unexpected(); 1226 } 1227 try 1228 { 1229 std::__unexpected(u_handler); 1230 } 1231 catch (...) 1232 { 1233 // If the old exception is foreign, then all we can do is terminate. 1234 // We have no way to recover the needed old exception spec. There's 1235 // no way to pass that information here. And the personality routine 1236 // can't call us directly and do anything but terminate() if we throw 1237 // from here. 1238 if (native_old_exception) 1239 { 1240 // Have: 1241 // old_exception_header->languageSpecificData 1242 // old_exception_header->actionRecord 1243 // Need 1244 // const uint8_t* classInfo 1245 // uint8_t ttypeEncoding 1246 uint8_t lpStartEncoding = *lsda++; 1247 const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding); 1248 (void)lpStart; // purposefully unused. Just needed to increment lsda. 1249 uint8_t ttypeEncoding = *lsda++; 1250 if (ttypeEncoding == DW_EH_PE_omit) 1251 std::__terminate(t_handler); 1252 uintptr_t classInfoOffset = readULEB128(&lsda); 1253 const uint8_t* classInfo = lsda + classInfoOffset; 1254 // Is this new exception catchable by the exception spec at ttypeIndex? 1255 // The answer is obviously yes if the new and old exceptions are the same exception 1256 // If no 1257 // throw; 1258 __cxa_eh_globals* globals = __cxa_get_globals_fast(); 1259 __cxa_exception* new_exception_header = globals->caughtExceptions; 1260 if (new_exception_header == 0) 1261 // This shouldn't be able to happen! 1262 std::__terminate(t_handler); 1263 bool native_new_exception = 1264 (new_exception_header->unwindHeader.exception_class & get_vendor_and_language) == 1265 (kOurExceptionClass & get_vendor_and_language); 1266 void* adjustedPtr; 1267 if (native_new_exception && (new_exception_header != old_exception_header)) 1268 { 1269 const __shim_type_info* excpType = 1270 static_cast<const __shim_type_info*>(new_exception_header->exceptionType); 1271 adjustedPtr = 1272 new_exception_header->unwindHeader.exception_class == kOurDependentExceptionClass ? 1273 ((__cxa_dependent_exception*)new_exception_header)->primaryException : 1274 new_exception_header + 1; 1275 if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding, 1276 excpType, adjustedPtr, unwind_exception)) 1277 { 1278 // We need to __cxa_end_catch, but for the old exception, 1279 // not the new one. This is a little tricky ... 1280 // Disguise new_exception_header as a rethrown exception, but 1281 // don't actually rethrow it. This means you can temporarily 1282 // end the catch clause enclosing new_exception_header without 1283 // __cxa_end_catch destroying new_exception_header. 1284 new_exception_header->handlerCount = -new_exception_header->handlerCount; 1285 globals->uncaughtExceptions += 1; 1286 // Call __cxa_end_catch for new_exception_header 1287 __cxa_end_catch(); 1288 // Call __cxa_end_catch for old_exception_header 1289 __cxa_end_catch(); 1290 // Renter this catch clause with new_exception_header 1291 __cxa_begin_catch(&new_exception_header->unwindHeader); 1292 // Rethrow new_exception_header 1293 throw; 1294 } 1295 } 1296 // Will a std::bad_exception be catchable by the exception spec at 1297 // ttypeIndex? 1298 // If no 1299 // throw std::bad_exception(); 1300 const __shim_type_info* excpType = 1301 static_cast<const __shim_type_info*>(&typeid(std::bad_exception)); 1302 std::bad_exception be; 1303 adjustedPtr = &be; 1304 if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding, 1305 excpType, adjustedPtr, unwind_exception)) 1306 { 1307 // We need to __cxa_end_catch for both the old exception and the 1308 // new exception. Technically we should do it in that order. 1309 // But it is expedient to do it in the opposite order: 1310 // Call __cxa_end_catch for new_exception_header 1311 __cxa_end_catch(); 1312 // Throw std::bad_exception will __cxa_end_catch for 1313 // old_exception_header 1314 throw be; 1315 } 1316 } 1317 } 1318 std::__terminate(t_handler); 1319 } 1320 1321 } // extern "C" 1322 1323 } // __cxxabiv1 1324