Home | History | Annotate | Download | only in src
      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 #if !__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     return *reinterpret_cast<const void **>(reinterpret_cast<uintptr_t>(ptr) +
    323                                             offset);
    324 }
    325 
    326 static const __shim_type_info*
    327 get_shim_type_info(uint64_t ttypeIndex, const uint8_t* classInfo,
    328                    uint8_t ttypeEncoding, bool native_exception,
    329                    _Unwind_Exception* unwind_exception)
    330 {
    331     if (classInfo == 0)
    332     {
    333         // this should not happen.  Indicates corrupted eh_table.
    334         call_terminate(native_exception, unwind_exception);
    335     }
    336 
    337     assert(ttypeEncoding == DW_EH_PE_absptr && "Unexpected TTypeEncoding");
    338     (void)ttypeEncoding;
    339 
    340     const uint8_t* ttypePtr = classInfo - ttypeIndex * sizeof(uintptr_t);
    341     return reinterpret_cast<const __shim_type_info *>(
    342         read_target2_value(ttypePtr));
    343 }
    344 #else // !LIBCXXABI_ARM_EHABI
    345 static
    346 const __shim_type_info*
    347 get_shim_type_info(uint64_t ttypeIndex, const uint8_t* classInfo,
    348                    uint8_t ttypeEncoding, bool native_exception,
    349                    _Unwind_Exception* unwind_exception)
    350 {
    351     if (classInfo == 0)
    352     {
    353         // this should not happen.  Indicates corrupted eh_table.
    354         call_terminate(native_exception, unwind_exception);
    355     }
    356     switch (ttypeEncoding & 0x0F)
    357     {
    358     case DW_EH_PE_absptr:
    359         ttypeIndex *= sizeof(void*);
    360         break;
    361     case DW_EH_PE_udata2:
    362     case DW_EH_PE_sdata2:
    363         ttypeIndex *= 2;
    364         break;
    365     case DW_EH_PE_udata4:
    366     case DW_EH_PE_sdata4:
    367         ttypeIndex *= 4;
    368         break;
    369     case DW_EH_PE_udata8:
    370     case DW_EH_PE_sdata8:
    371         ttypeIndex *= 8;
    372         break;
    373     default:
    374         // this should not happen.   Indicates corrupted eh_table.
    375         call_terminate(native_exception, unwind_exception);
    376     }
    377     classInfo -= ttypeIndex;
    378     return (const __shim_type_info*)readEncodedPointer(&classInfo, ttypeEncoding);
    379 }
    380 #endif // !LIBCXXABI_ARM_EHABI
    381 
    382 /*
    383     This is checking a thrown exception type, excpType, against a possibly empty
    384     list of catchType's which make up an exception spec.
    385 
    386     An exception spec acts like a catch handler, but in reverse.  This "catch
    387     handler" will catch an excpType if and only if none of the catchType's in
    388     the list will catch a excpType.  If any catchType in the list can catch an
    389     excpType, then this exception spec does not catch the excpType.
    390 */
    391 #if LIBCXXABI_ARM_EHABI
    392 static
    393 bool
    394 exception_spec_can_catch(int64_t specIndex, const uint8_t* classInfo,
    395                          uint8_t ttypeEncoding, const __shim_type_info* excpType,
    396                          void* adjustedPtr, _Unwind_Exception* unwind_exception)
    397 {
    398     if (classInfo == 0)
    399     {
    400         // this should not happen.   Indicates corrupted eh_table.
    401         call_terminate(false, unwind_exception);
    402     }
    403 
    404     assert(ttypeEncoding == DW_EH_PE_absptr && "Unexpected TTypeEncoding");
    405     (void)ttypeEncoding;
    406 
    407     // specIndex is negative of 1-based byte offset into classInfo;
    408     specIndex = -specIndex;
    409     --specIndex;
    410     const void** temp = reinterpret_cast<const void**>(
    411         reinterpret_cast<uintptr_t>(classInfo) +
    412         static_cast<uintptr_t>(specIndex) * sizeof(uintptr_t));
    413     // If any type in the spec list can catch excpType, return false, else return true
    414     //    adjustments to adjustedPtr are ignored.
    415     while (true)
    416     {
    417         // ARM EHABI exception specification table (filter table) consists of
    418         // several pointers which will directly point to the type info object
    419         // (instead of ttypeIndex).  The table will be terminated with 0.
    420         const void** ttypePtr = temp++;
    421         if (*ttypePtr == 0)
    422             break;
    423         // We can get the __shim_type_info simply by performing a
    424         // R_ARM_TARGET2 relocation, and cast the result to __shim_type_info.
    425         const __shim_type_info* catchType =
    426             static_cast<const __shim_type_info*>(read_target2_value(ttypePtr));
    427         void* tempPtr = adjustedPtr;
    428         if (catchType->can_catch(excpType, tempPtr))
    429             return false;
    430     }
    431     return true;
    432 }
    433 #else
    434 static
    435 bool
    436 exception_spec_can_catch(int64_t specIndex, const uint8_t* classInfo,
    437                          uint8_t ttypeEncoding, const __shim_type_info* excpType,
    438                          void* adjustedPtr, _Unwind_Exception* unwind_exception)
    439 {
    440     if (classInfo == 0)
    441     {
    442         // this should not happen.   Indicates corrupted eh_table.
    443         call_terminate(false, unwind_exception);
    444     }
    445     // specIndex is negative of 1-based byte offset into classInfo;
    446     specIndex = -specIndex;
    447     --specIndex;
    448     const uint8_t* temp = classInfo + specIndex;
    449     // If any type in the spec list can catch excpType, return false, else return true
    450     //    adjustments to adjustedPtr are ignored.
    451     while (true)
    452     {
    453         uint64_t ttypeIndex = readULEB128(&temp);
    454         if (ttypeIndex == 0)
    455             break;
    456         const __shim_type_info* catchType = get_shim_type_info(ttypeIndex,
    457                                                                classInfo,
    458                                                                ttypeEncoding,
    459                                                                true,
    460                                                                unwind_exception);
    461         void* tempPtr = adjustedPtr;
    462         if (catchType->can_catch(excpType, tempPtr))
    463             return false;
    464     }
    465     return true;
    466 }
    467 #endif
    468 
    469 static
    470 void*
    471 get_thrown_object_ptr(_Unwind_Exception* unwind_exception)
    472 {
    473     // Even for foreign exceptions, the exception object is *probably* at unwind_exception + 1
    474     //    Regardless, this library is prohibited from touching a foreign exception
    475     void* adjustedPtr = unwind_exception + 1;
    476     if (unwind_exception->exception_class == kOurDependentExceptionClass)
    477         adjustedPtr = ((__cxa_dependent_exception*)adjustedPtr - 1)->primaryException;
    478     return adjustedPtr;
    479 }
    480 
    481 namespace
    482 {
    483 
    484 struct scan_results
    485 {
    486     int64_t        ttypeIndex;   // > 0 catch handler, < 0 exception spec handler, == 0 a cleanup
    487     const uint8_t* actionRecord;         // Currently unused.  Retained to ease future maintenance.
    488     const uint8_t* languageSpecificData;  // Needed only for __cxa_call_unexpected
    489     uintptr_t      landingPad;   // null -> nothing found, else something found
    490     void*          adjustedPtr;  // Used in cxa_exception.cpp
    491     _Unwind_Reason_Code reason;  // One of _URC_FATAL_PHASE1_ERROR,
    492                                  //        _URC_FATAL_PHASE2_ERROR,
    493                                  //        _URC_CONTINUE_UNWIND,
    494                                  //        _URC_HANDLER_FOUND
    495 };
    496 
    497 }  // unnamed namespace
    498 
    499 static
    500 void
    501 set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context,
    502               const scan_results& results)
    503 {
    504     _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
    505                                  reinterpret_cast<uintptr_t>(unwind_exception));
    506     _Unwind_SetGR(context, __builtin_eh_return_data_regno(1),
    507                                     static_cast<uintptr_t>(results.ttypeIndex));
    508     _Unwind_SetIP(context, results.landingPad);
    509 }
    510 
    511 /*
    512     There are 3 types of scans needed:
    513 
    514     1.  Scan for handler with native or foreign exception.  If handler found,
    515         save state and return _URC_HANDLER_FOUND, else return _URC_CONTINUE_UNWIND.
    516         May also report an error on invalid input.
    517         May terminate for invalid exception table.
    518         _UA_SEARCH_PHASE
    519 
    520     2.  Scan for handler with foreign exception.  Must return _URC_HANDLER_FOUND,
    521         or call terminate.
    522         _UA_CLEANUP_PHASE && _UA_HANDLER_FRAME && !native_exception
    523 
    524     3.  Scan for cleanups.  If a handler is found and this isn't forced unwind,
    525         then terminate, otherwise ignore the handler and keep looking for cleanup.
    526         If a cleanup is found, return _URC_HANDLER_FOUND, else return _URC_CONTINUE_UNWIND.
    527         May also report an error on invalid input.
    528         May terminate for invalid exception table.
    529         _UA_CLEANUP_PHASE && !_UA_HANDLER_FRAME
    530 */
    531 
    532 static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
    533                         bool native_exception,
    534                         _Unwind_Exception *unwind_exception,
    535                         _Unwind_Context *context) {
    536     // Initialize results to found nothing but an error
    537     results.ttypeIndex = 0;
    538     results.actionRecord = 0;
    539     results.languageSpecificData = 0;
    540     results.landingPad = 0;
    541     results.adjustedPtr = 0;
    542     results.reason = _URC_FATAL_PHASE1_ERROR;
    543     // Check for consistent actions
    544     if (actions & _UA_SEARCH_PHASE)
    545     {
    546         // Do Phase 1
    547         if (actions & (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME | _UA_FORCE_UNWIND))
    548         {
    549             // None of these flags should be set during Phase 1
    550             //   Client error
    551             results.reason = _URC_FATAL_PHASE1_ERROR;
    552             return;
    553         }
    554     }
    555     else if (actions & _UA_CLEANUP_PHASE)
    556     {
    557         if ((actions & _UA_HANDLER_FRAME) && (actions & _UA_FORCE_UNWIND))
    558         {
    559             // _UA_HANDLER_FRAME should only be set if phase 1 found a handler.
    560             // If _UA_FORCE_UNWIND is set, phase 1 shouldn't have happened.
    561             //    Client error
    562             results.reason = _URC_FATAL_PHASE2_ERROR;
    563             return;
    564         }
    565     }
    566     else // Neither _UA_SEARCH_PHASE nor _UA_CLEANUP_PHASE is set
    567     {
    568         // One of these should be set.
    569         //   Client error
    570         results.reason = _URC_FATAL_PHASE1_ERROR;
    571         return;
    572     }
    573     // Start scan by getting exception table address
    574     const uint8_t *lsda = (const uint8_t *)_Unwind_GetLanguageSpecificData(context);
    575     if (lsda == 0)
    576     {
    577         // There is no exception table
    578         results.reason = _URC_CONTINUE_UNWIND;
    579         return;
    580     }
    581     results.languageSpecificData = lsda;
    582     // Get the current instruction pointer and offset it before next
    583     // instruction in the current frame which threw the exception.
    584     uintptr_t ip = _Unwind_GetIP(context) - 1;
    585     // Get beginning current frame's code (as defined by the
    586     // emitted dwarf code)
    587     uintptr_t funcStart = _Unwind_GetRegionStart(context);
    588 #if __USING_SJLJ_EXCEPTIONS__
    589     if (ip == uintptr_t(-1))
    590     {
    591         // no action
    592         results.reason = _URC_CONTINUE_UNWIND;
    593         return;
    594     }
    595     else if (ip == 0)
    596         call_terminate(native_exception, unwind_exception);
    597     // ip is 1-based index into call site table
    598 #else  // !__USING_SJLJ_EXCEPTIONS__
    599     uintptr_t ipOffset = ip - funcStart;
    600 #endif  // !defined(_USING_SLJL_EXCEPTIONS__)
    601     const uint8_t* classInfo = NULL;
    602     // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding
    603     //       dwarf emission
    604     // Parse LSDA header.
    605     uint8_t lpStartEncoding = *lsda++;
    606     const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);
    607     if (lpStart == 0)
    608         lpStart = (const uint8_t*)funcStart;
    609     uint8_t ttypeEncoding = *lsda++;
    610     if (ttypeEncoding != DW_EH_PE_omit)
    611     {
    612         // Calculate type info locations in emitted dwarf code which
    613         // were flagged by type info arguments to llvm.eh.selector
    614         // intrinsic
    615         uintptr_t classInfoOffset = readULEB128(&lsda);
    616         classInfo = lsda + classInfoOffset;
    617     }
    618     // Walk call-site table looking for range that
    619     // includes current PC.
    620     uint8_t callSiteEncoding = *lsda++;
    621 #if __USING_SJLJ_EXCEPTIONS__
    622     (void)callSiteEncoding;  // When using SjLj exceptions, callSiteEncoding is never used
    623 #endif
    624     uint32_t callSiteTableLength = static_cast<uint32_t>(readULEB128(&lsda));
    625     const uint8_t* callSiteTableStart = lsda;
    626     const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength;
    627     const uint8_t* actionTableStart = callSiteTableEnd;
    628     const uint8_t* callSitePtr = callSiteTableStart;
    629     while (callSitePtr < callSiteTableEnd)
    630     {
    631         // There is one entry per call site.
    632 #if !__USING_SJLJ_EXCEPTIONS__
    633         // The call sites are non-overlapping in [start, start+length)
    634         // The call sites are ordered in increasing value of start
    635         uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding);
    636         uintptr_t length = readEncodedPointer(&callSitePtr, callSiteEncoding);
    637         uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding);
    638         uintptr_t actionEntry = readULEB128(&callSitePtr);
    639         if ((start <= ipOffset) && (ipOffset < (start + length)))
    640 #else  // __USING_SJLJ_EXCEPTIONS__
    641         // ip is 1-based index into this table
    642         uintptr_t landingPad = readULEB128(&callSitePtr);
    643         uintptr_t actionEntry = readULEB128(&callSitePtr);
    644         if (--ip == 0)
    645 #endif  // __USING_SJLJ_EXCEPTIONS__
    646         {
    647             // Found the call site containing ip.
    648 #if !__USING_SJLJ_EXCEPTIONS__
    649             if (landingPad == 0)
    650             {
    651                 // No handler here
    652                 results.reason = _URC_CONTINUE_UNWIND;
    653                 return;
    654             }
    655             landingPad = (uintptr_t)lpStart + landingPad;
    656 #else  // __USING_SJLJ_EXCEPTIONS__
    657             ++landingPad;
    658 #endif  // __USING_SJLJ_EXCEPTIONS__
    659             if (actionEntry == 0)
    660             {
    661                 // Found a cleanup
    662                 // If this is a type 1 or type 2 search, there are no handlers
    663                 // If this is a type 3 search, you want to install the cleanup.
    664                 if ((actions & _UA_CLEANUP_PHASE) && !(actions & _UA_HANDLER_FRAME))
    665                 {
    666                     results.ttypeIndex = 0;  // Redundant but clarifying
    667                     results.landingPad = landingPad;
    668                     results.reason = _URC_HANDLER_FOUND;
    669                     return;
    670                 }
    671                 // No handler here
    672                 results.reason = _URC_CONTINUE_UNWIND;
    673                 return;
    674             }
    675             // Convert 1-based byte offset into
    676             const uint8_t* action = actionTableStart + (actionEntry - 1);
    677             // Scan action entries until you find a matching handler, cleanup, or the end of action list
    678             while (true)
    679             {
    680                 const uint8_t* actionRecord = action;
    681                 int64_t ttypeIndex = readSLEB128(&action);
    682                 if (ttypeIndex > 0)
    683                 {
    684                     // Found a catch, does it actually catch?
    685                     // First check for catch (...)
    686                     const __shim_type_info* catchType =
    687                         get_shim_type_info(static_cast<uint64_t>(ttypeIndex),
    688                                            classInfo, ttypeEncoding,
    689                                            native_exception, unwind_exception);
    690                     if (catchType == 0)
    691                     {
    692                         // Found catch (...) catches everything, including foreign exceptions
    693                         // If this is a type 1 search save state and return _URC_HANDLER_FOUND
    694                         // If this is a type 2 search save state and return _URC_HANDLER_FOUND
    695                         // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1!
    696                         // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan
    697                         if ((actions & _UA_SEARCH_PHASE) || (actions & _UA_HANDLER_FRAME))
    698                         {
    699                             // Save state and return _URC_HANDLER_FOUND
    700                             results.ttypeIndex = ttypeIndex;
    701                             results.actionRecord = actionRecord;
    702                             results.landingPad = landingPad;
    703                             results.adjustedPtr = get_thrown_object_ptr(unwind_exception);
    704                             results.reason = _URC_HANDLER_FOUND;
    705                             return;
    706                         }
    707                         else if (!(actions & _UA_FORCE_UNWIND))
    708                         {
    709                             // It looks like the exception table has changed
    710                             //    on us.  Likely stack corruption!
    711                             call_terminate(native_exception, unwind_exception);
    712                         }
    713                     }
    714                     // Else this is a catch (T) clause and will never
    715                     //    catch a foreign exception
    716                     else if (native_exception)
    717                     {
    718                         __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
    719                         void* adjustedPtr = get_thrown_object_ptr(unwind_exception);
    720                         const __shim_type_info* excpType =
    721                             static_cast<const __shim_type_info*>(exception_header->exceptionType);
    722                         if (adjustedPtr == 0 || excpType == 0)
    723                         {
    724                             // Something very bad happened
    725                             call_terminate(native_exception, unwind_exception);
    726                         }
    727                         if (catchType->can_catch(excpType, adjustedPtr))
    728                         {
    729                             // Found a matching handler
    730                             // If this is a type 1 search save state and return _URC_HANDLER_FOUND
    731                             // If this is a type 3 search and !_UA_FORCE_UNWIND, we should have found this in phase 1!
    732                             // If this is a type 3 search and _UA_FORCE_UNWIND, ignore handler and continue scan
    733                             if (actions & _UA_SEARCH_PHASE)
    734                             {
    735                                 // Save state and return _URC_HANDLER_FOUND
    736                                 results.ttypeIndex = ttypeIndex;
    737                                 results.actionRecord = actionRecord;
    738                                 results.landingPad = landingPad;
    739                                 results.adjustedPtr = adjustedPtr;
    740                                 results.reason = _URC_HANDLER_FOUND;
    741                                 return;
    742                             }
    743                             else if (!(actions & _UA_FORCE_UNWIND))
    744                             {
    745                                 // It looks like the exception table has changed
    746                                 //    on us.  Likely stack corruption!
    747                                 call_terminate(native_exception, unwind_exception);
    748                             }
    749                         }
    750                     }
    751                     // Scan next action ...
    752                 }
    753                 else if (ttypeIndex < 0)
    754                 {
    755                     // Found an exception spec.  If this is a foreign exception,
    756                     //   it is always caught.
    757                     if (native_exception)
    758                     {
    759                         // Does the exception spec catch this native exception?
    760                         __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
    761                         void* adjustedPtr = get_thrown_object_ptr(unwind_exception);
    762                         const __shim_type_info* excpType =
    763                             static_cast<const __shim_type_info*>(exception_header->exceptionType);
    764                         if (adjustedPtr == 0 || excpType == 0)
    765                         {
    766                             // Something very bad happened
    767                             call_terminate(native_exception, unwind_exception);
    768                         }
    769                         if (exception_spec_can_catch(ttypeIndex, classInfo,
    770                                                      ttypeEncoding, excpType,
    771                                                      adjustedPtr, unwind_exception))
    772                         {
    773                             // native exception caught by exception spec
    774                             // If this is a type 1 search, save state and return _URC_HANDLER_FOUND
    775                             // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1!
    776                             // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan
    777                             if (actions & _UA_SEARCH_PHASE)
    778                             {
    779                                 // Save state and return _URC_HANDLER_FOUND
    780                                 results.ttypeIndex = ttypeIndex;
    781                                 results.actionRecord = actionRecord;
    782                                 results.landingPad = landingPad;
    783                                 results.adjustedPtr = adjustedPtr;
    784                                 results.reason = _URC_HANDLER_FOUND;
    785                                 return;
    786                             }
    787                             else if (!(actions & _UA_FORCE_UNWIND))
    788                             {
    789                                 // It looks like the exception table has changed
    790                                 //    on us.  Likely stack corruption!
    791                                 call_terminate(native_exception, unwind_exception);
    792                             }
    793                         }
    794                     }
    795                     else
    796                     {
    797                         // foreign exception caught by exception spec
    798                         // If this is a type 1 search, save state and return _URC_HANDLER_FOUND
    799                         // If this is a type 2 search, save state and return _URC_HANDLER_FOUND
    800                         // If this is a type 3 search !_UA_FORCE_UNWIND, we should have found this in phase 1!
    801                         // If this is a type 3 search _UA_FORCE_UNWIND, ignore handler and continue scan
    802                         if ((actions & _UA_SEARCH_PHASE) || (actions & _UA_HANDLER_FRAME))
    803                         {
    804                             // Save state and return _URC_HANDLER_FOUND
    805                             results.ttypeIndex = ttypeIndex;
    806                             results.actionRecord = actionRecord;
    807                             results.landingPad = landingPad;
    808                             results.adjustedPtr = get_thrown_object_ptr(unwind_exception);
    809                             results.reason = _URC_HANDLER_FOUND;
    810                             return;
    811                         }
    812                         else if (!(actions & _UA_FORCE_UNWIND))
    813                         {
    814                             // It looks like the exception table has changed
    815                             //    on us.  Likely stack corruption!
    816                             call_terminate(native_exception, unwind_exception);
    817                         }
    818                     }
    819                     // Scan next action ...
    820                 }
    821                 else  // ttypeIndex == 0
    822                 {
    823                     // Found a cleanup
    824                     // If this is a type 1 search, ignore it and continue scan
    825                     // If this is a type 2 search, ignore it and continue scan
    826                     // If this is a type 3 search, save state and return _URC_HANDLER_FOUND
    827                     if ((actions & _UA_CLEANUP_PHASE) && !(actions & _UA_HANDLER_FRAME))
    828                     {
    829                         // Save state and return _URC_HANDLER_FOUND
    830                         results.ttypeIndex = ttypeIndex;
    831                         results.actionRecord = actionRecord;
    832                         results.landingPad = landingPad;
    833                         results.adjustedPtr = get_thrown_object_ptr(unwind_exception);
    834                         results.reason = _URC_HANDLER_FOUND;
    835                         return;
    836                     }
    837                 }
    838                 const uint8_t* temp = action;
    839                 int64_t actionOffset = readSLEB128(&temp);
    840                 if (actionOffset == 0)
    841                 {
    842                     // End of action list, no matching handler or cleanup found
    843                     results.reason = _URC_CONTINUE_UNWIND;
    844                     return;
    845                 }
    846                 // Go to next action
    847                 action += actionOffset;
    848             }  // there is no break out of this loop, only return
    849         }
    850 #if !__USING_SJLJ_EXCEPTIONS__
    851         else if (ipOffset < start)
    852         {
    853             // There is no call site for this ip
    854             // Something bad has happened.  We should never get here.
    855             // Possible stack corruption.
    856             call_terminate(native_exception, unwind_exception);
    857         }
    858 #endif  // !__USING_SJLJ_EXCEPTIONS__
    859     }  // there might be some tricky cases which break out of this loop
    860 
    861     // It is possible that no eh table entry specify how to handle
    862     // this exception. By spec, terminate it immediately.
    863     call_terminate(native_exception, unwind_exception);
    864 }
    865 
    866 // public API
    867 
    868 /*
    869 The personality function branches on actions like so:
    870 
    871 _UA_SEARCH_PHASE
    872 
    873     If _UA_CLEANUP_PHASE or _UA_HANDLER_FRAME or _UA_FORCE_UNWIND there's
    874       an error from above, return _URC_FATAL_PHASE1_ERROR.
    875 
    876     Scan for anything that could stop unwinding:
    877 
    878        1.  A catch clause that will catch this exception
    879            (will never catch foreign).
    880        2.  A catch (...) (will always catch foreign).
    881        3.  An exception spec that will catch this exception
    882            (will always catch foreign).
    883     If a handler is found
    884         If not foreign
    885             Save state in header
    886         return _URC_HANDLER_FOUND
    887     Else a handler not found
    888         return _URC_CONTINUE_UNWIND
    889 
    890 _UA_CLEANUP_PHASE
    891 
    892     If _UA_HANDLER_FRAME
    893         If _UA_FORCE_UNWIND
    894             How did this happen?  return _URC_FATAL_PHASE2_ERROR
    895         If foreign
    896             Do _UA_SEARCH_PHASE to recover state
    897         else
    898             Recover state from header
    899         Transfer control to landing pad.  return _URC_INSTALL_CONTEXT
    900 
    901     Else
    902 
    903         This branch handles both normal C++ non-catching handlers (cleanups)
    904           and forced unwinding.
    905         Scan for anything that can not stop unwinding:
    906 
    907             1.  A cleanup.
    908 
    909         If a cleanup is found
    910             transfer control to it. return _URC_INSTALL_CONTEXT
    911         Else a cleanup is not found: return _URC_CONTINUE_UNWIND
    912 */
    913 
    914 #if !LIBCXXABI_ARM_EHABI
    915 _Unwind_Reason_Code
    916 #if __USING_SJLJ_EXCEPTIONS__
    917 __gxx_personality_sj0
    918 #else
    919 __gxx_personality_v0
    920 #endif
    921                     (int version, _Unwind_Action actions, uint64_t exceptionClass,
    922                      _Unwind_Exception* unwind_exception, _Unwind_Context* context)
    923 {
    924     if (version != 1 || unwind_exception == 0 || context == 0)
    925         return _URC_FATAL_PHASE1_ERROR;
    926 
    927     bool native_exception = (exceptionClass     & get_vendor_and_language) ==
    928                             (kOurExceptionClass & get_vendor_and_language);
    929     scan_results results;
    930     if (actions & _UA_SEARCH_PHASE)
    931     {
    932         // Phase 1 search:  All we're looking for in phase 1 is a handler that
    933         //   halts unwinding
    934         scan_eh_tab(results, actions, native_exception, unwind_exception, context);
    935         if (results.reason == _URC_HANDLER_FOUND)
    936         {
    937             // Found one.  Can we cache the results somewhere to optimize phase 2?
    938             if (native_exception)
    939             {
    940                 __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
    941                 exception_header->handlerSwitchValue = static_cast<int>(results.ttypeIndex);
    942                 exception_header->actionRecord = results.actionRecord;
    943                 exception_header->languageSpecificData = results.languageSpecificData;
    944                 exception_header->catchTemp = reinterpret_cast<void*>(results.landingPad);
    945                 exception_header->adjustedPtr = results.adjustedPtr;
    946             }
    947             return _URC_HANDLER_FOUND;
    948         }
    949         // Did not find a catching-handler.  Return the results of the scan
    950         //    (normally _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE1_ERROR
    951         //     if we were called improperly).
    952         return results.reason;
    953     }
    954     if (actions & _UA_CLEANUP_PHASE)
    955     {
    956         // Phase 2 search:
    957         //  Did we find a catching handler in phase 1?
    958         if (actions & _UA_HANDLER_FRAME)
    959         {
    960             // Yes, phase 1 said we have a catching handler here.
    961             // Did we cache the results of the scan?
    962             if (native_exception)
    963             {
    964                 // Yes, reload the results from the cache.
    965                 __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
    966                 results.ttypeIndex = exception_header->handlerSwitchValue;
    967                 results.actionRecord = exception_header->actionRecord;
    968                 results.languageSpecificData = exception_header->languageSpecificData;
    969                 results.landingPad = reinterpret_cast<uintptr_t>(exception_header->catchTemp);
    970                 results.adjustedPtr = exception_header->adjustedPtr;
    971             }
    972             else
    973             {
    974                 // No, do the scan again to reload the results.
    975                 scan_eh_tab(results, actions, native_exception, unwind_exception, context);
    976                 // Phase 1 told us we would find a handler.  Now in Phase 2 we
    977                 //   didn't find a handler.  The eh table should not be changing!
    978                 if (results.reason != _URC_HANDLER_FOUND)
    979                     call_terminate(native_exception, unwind_exception);
    980             }
    981             // Jump to the handler
    982             set_registers(unwind_exception, context, results);
    983             return _URC_INSTALL_CONTEXT;
    984         }
    985         // Either we didn't do a phase 1 search (due to forced unwinding), or
    986         //   phase 1 reported no catching-handlers.
    987         // Search for a (non-catching) cleanup
    988         scan_eh_tab(results, actions, native_exception, unwind_exception, context);
    989         if (results.reason == _URC_HANDLER_FOUND)
    990         {
    991             // Found a non-catching handler.  Jump to it:
    992             set_registers(unwind_exception, context, results);
    993             return _URC_INSTALL_CONTEXT;
    994         }
    995         // Did not find a cleanup.  Return the results of the scan
    996         //    (normally _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE2_ERROR
    997         //     if we were called improperly).
    998         return results.reason;
    999     }
   1000     // We were called improperly: neither a phase 1 or phase 2 search
   1001     return _URC_FATAL_PHASE1_ERROR;
   1002 }
   1003 #else
   1004 
   1005 // Helper function to unwind one frame.
   1006 // ARM EHABI 7.3 and 7.4: If the personality function returns _URC_CONTINUE_UNWIND, the
   1007 // personality routine should update the virtual register set (VRS) according to the
   1008 // corresponding frame unwinding instructions (ARM EHABI 9.3.)
   1009 static _Unwind_Reason_Code continue_unwind(_Unwind_Context* context,
   1010                                            uint32_t* unwind_opcodes,
   1011                                            size_t opcode_words)
   1012 {
   1013     if (_Unwind_VRS_Interpret(context, unwind_opcodes, 1, opcode_words * 4) !=
   1014         _URC_CONTINUE_UNWIND)
   1015         return _URC_FAILURE;
   1016     return _URC_CONTINUE_UNWIND;
   1017 }
   1018 
   1019 // ARM register names
   1020 static const uint32_t REG_UCB = 12;  // Register to save _Unwind_Control_Block
   1021 static const uint32_t REG_SP = 13;
   1022 
   1023 static void save_results_to_barrier_cache(_Unwind_Exception* unwind_exception,
   1024                                           const scan_results& results)
   1025 {
   1026     unwind_exception->barrier_cache.bitpattern[0] = (uint32_t)results.adjustedPtr;
   1027     unwind_exception->barrier_cache.bitpattern[1] = (uint32_t)results.actionRecord;
   1028     unwind_exception->barrier_cache.bitpattern[2] = (uint32_t)results.languageSpecificData;
   1029     unwind_exception->barrier_cache.bitpattern[3] = (uint32_t)results.landingPad;
   1030     unwind_exception->barrier_cache.bitpattern[4] = (uint32_t)results.ttypeIndex;
   1031 }
   1032 
   1033 static void load_results_from_barrier_cache(scan_results& results,
   1034                                             const _Unwind_Exception* unwind_exception)
   1035 {
   1036     results.adjustedPtr = (void*)unwind_exception->barrier_cache.bitpattern[0];
   1037     results.actionRecord = (const uint8_t*)unwind_exception->barrier_cache.bitpattern[1];
   1038     results.languageSpecificData = (const uint8_t*)unwind_exception->barrier_cache.bitpattern[2];
   1039     results.landingPad = (uintptr_t)unwind_exception->barrier_cache.bitpattern[3];
   1040     results.ttypeIndex = (int64_t)(int32_t)unwind_exception->barrier_cache.bitpattern[4];
   1041 }
   1042 
   1043 extern "C" _Unwind_Reason_Code
   1044 __gxx_personality_v0(_Unwind_State state,
   1045                      _Unwind_Exception* unwind_exception,
   1046                      _Unwind_Context* context)
   1047 {
   1048     if (unwind_exception == 0 || context == 0)
   1049         return _URC_FATAL_PHASE1_ERROR;
   1050 
   1051     bool native_exception = (unwind_exception->exception_class & get_vendor_and_language) ==
   1052                             (kOurExceptionClass & get_vendor_and_language);
   1053 
   1054 #if LIBCXXABI_ARM_EHABI
   1055     // ARM EHABI # 6.2, # 9.2
   1056     //
   1057     //  +---- ehtp
   1058     //  v
   1059     // +--------------------------------------+
   1060     // | +--------+--------+--------+-------+ |
   1061     // | |0| prel31 to __gxx_personality_v0 | |
   1062     // | +--------+--------+--------+-------+ |
   1063     // | |      N |      unwind opcodes     | |  <-- UnwindData
   1064     // | +--------+--------+--------+-------+ |
   1065     // | | Word 2        unwind opcodes     | |
   1066     // | +--------+--------+--------+-------+ |
   1067     // | ...                                  |
   1068     // | +--------+--------+--------+-------+ |
   1069     // | | Word N        unwind opcodes     | |
   1070     // | +--------+--------+--------+-------+ |
   1071     // | | LSDA                             | |  <-- lsda
   1072     // | | ...                              | |
   1073     // | +--------+--------+--------+-------+ |
   1074     // +--------------------------------------+
   1075 
   1076     uint32_t *UnwindData = unwind_exception->pr_cache.ehtp + 1;
   1077     uint32_t FirstDataWord = *UnwindData;
   1078     size_t N = ((FirstDataWord >> 24) & 0xff);
   1079     size_t NDataWords = N + 1;
   1080 #endif
   1081 
   1082     // Copy the address of _Unwind_Control_Block to r12 so that
   1083     // _Unwind_GetLanguageSpecificData() and _Unwind_GetRegionStart() can
   1084     // return correct address.
   1085     _Unwind_SetGR(context, REG_UCB, reinterpret_cast<uint32_t>(unwind_exception));
   1086 
   1087     scan_results results;
   1088     switch (state) {
   1089     case _US_VIRTUAL_UNWIND_FRAME:
   1090         // Phase 1 search:  All we're looking for in phase 1 is a handler that halts unwinding
   1091         scan_eh_tab(results, _UA_SEARCH_PHASE, native_exception, unwind_exception, context);
   1092         if (results.reason == _URC_HANDLER_FOUND)
   1093         {
   1094             unwind_exception->barrier_cache.sp = _Unwind_GetGR(context, REG_SP);
   1095             if (native_exception)
   1096                 save_results_to_barrier_cache(unwind_exception, results);
   1097             return _URC_HANDLER_FOUND;
   1098         }
   1099         // Did not find the catch handler
   1100         if (results.reason == _URC_CONTINUE_UNWIND)
   1101             return continue_unwind(context, UnwindData, NDataWords);
   1102         return results.reason;
   1103 
   1104     case _US_UNWIND_FRAME_STARTING:
   1105         // Phase 2 search
   1106         if (unwind_exception->barrier_cache.sp == _Unwind_GetGR(context, REG_SP))
   1107         {
   1108             // Found a catching handler in phase 1
   1109             if (native_exception)
   1110             {
   1111                 // Load the result from the native exception barrier cache.
   1112                 load_results_from_barrier_cache(results, unwind_exception);
   1113                 results.reason = _URC_HANDLER_FOUND;
   1114             }
   1115             else
   1116             {
   1117                 // Search for the catching handler again for the foreign exception.
   1118                 scan_eh_tab(results, static_cast<_Unwind_Action>(_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME),
   1119                             native_exception, unwind_exception, context);
   1120                 if (results.reason != _URC_HANDLER_FOUND)  // phase1 search should guarantee to find one
   1121                     call_terminate(native_exception, unwind_exception);
   1122             }
   1123 
   1124             // Install the context for the catching handler
   1125             set_registers(unwind_exception, context, results);
   1126             return _URC_INSTALL_CONTEXT;
   1127         }
   1128 
   1129         // Either we didn't do a phase 1 search (due to forced unwinding), or
   1130         //  phase 1 reported no catching-handlers.
   1131         // Search for a (non-catching) cleanup
   1132         scan_eh_tab(results, _UA_CLEANUP_PHASE, native_exception, unwind_exception, context);
   1133         if (results.reason == _URC_HANDLER_FOUND)
   1134         {
   1135             // Found a non-catching handler
   1136 
   1137             // ARM EHABI 8.4.2: Before we can jump to the cleanup handler, we have to setup some
   1138             // internal data structures, so that __cxa_end_cleanup() can get unwind_exception from
   1139             // __cxa_get_globals().
   1140             __cxa_begin_cleanup(unwind_exception);
   1141 
   1142             // Install the context for the cleanup handler
   1143             set_registers(unwind_exception, context, results);
   1144             return _URC_INSTALL_CONTEXT;
   1145         }
   1146 
   1147         // Did not find any handler
   1148         if (results.reason == _URC_CONTINUE_UNWIND)
   1149             return continue_unwind(context, UnwindData, NDataWords);
   1150         return results.reason;
   1151 
   1152     case _US_UNWIND_FRAME_RESUME:
   1153         return continue_unwind(context, UnwindData, NDataWords);
   1154     }
   1155 
   1156     // We were called improperly: neither a phase 1 or phase 2 search
   1157     return _URC_FATAL_PHASE1_ERROR;
   1158 }
   1159 #endif
   1160 
   1161 
   1162 __attribute__((noreturn))
   1163 void
   1164 __cxa_call_unexpected(void* arg)
   1165 {
   1166     _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(arg);
   1167     if (unwind_exception == 0)
   1168         call_terminate(false, unwind_exception);
   1169     __cxa_begin_catch(unwind_exception);
   1170     bool native_old_exception =
   1171         (unwind_exception->exception_class & get_vendor_and_language) ==
   1172         (kOurExceptionClass                & get_vendor_and_language);
   1173     std::unexpected_handler u_handler;
   1174     std::terminate_handler t_handler;
   1175     __cxa_exception* old_exception_header = 0;
   1176     int64_t ttypeIndex;
   1177     const uint8_t* lsda;
   1178     if (native_old_exception)
   1179     {
   1180         old_exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
   1181         t_handler = old_exception_header->terminateHandler;
   1182         u_handler = old_exception_header->unexpectedHandler;
   1183         // If std::__unexpected(u_handler) rethrows the same exception,
   1184         //   these values get overwritten by the rethrow.  So save them now:
   1185 #if LIBCXXABI_ARM_EHABI
   1186         ttypeIndex = (int64_t)(int32_t)unwind_exception->barrier_cache.bitpattern[4];
   1187         lsda = (const uint8_t*)unwind_exception->barrier_cache.bitpattern[2];
   1188 #else
   1189         ttypeIndex = old_exception_header->handlerSwitchValue;
   1190         lsda = old_exception_header->languageSpecificData;
   1191 #endif
   1192     }
   1193     else
   1194     {
   1195         t_handler = std::get_terminate();
   1196         u_handler = std::get_unexpected();
   1197     }
   1198     try
   1199     {
   1200         std::__unexpected(u_handler);
   1201     }
   1202     catch (...)
   1203     {
   1204         // If the old exception is foreign, then all we can do is terminate.
   1205         //   We have no way to recover the needed old exception spec.  There's
   1206         //   no way to pass that information here.  And the personality routine
   1207         //   can't call us directly and do anything but terminate() if we throw
   1208         //   from here.
   1209         if (native_old_exception)
   1210         {
   1211             // Have:
   1212             //   old_exception_header->languageSpecificData
   1213             //   old_exception_header->actionRecord
   1214             // Need
   1215             //   const uint8_t* classInfo
   1216             //   uint8_t ttypeEncoding
   1217             uint8_t lpStartEncoding = *lsda++;
   1218             const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);
   1219             (void)lpStart;  // purposefully unused.  Just needed to increment lsda.
   1220             uint8_t ttypeEncoding = *lsda++;
   1221             if (ttypeEncoding == DW_EH_PE_omit)
   1222                 std::__terminate(t_handler);
   1223             uintptr_t classInfoOffset = readULEB128(&lsda);
   1224             const uint8_t* classInfo = lsda + classInfoOffset;
   1225             // Is this new exception catchable by the exception spec at ttypeIndex?
   1226             // The answer is obviously yes if the new and old exceptions are the same exception
   1227             // If no
   1228             //    throw;
   1229             __cxa_eh_globals* globals = __cxa_get_globals_fast();
   1230             __cxa_exception* new_exception_header = globals->caughtExceptions;
   1231             if (new_exception_header == 0)
   1232                 // This shouldn't be able to happen!
   1233                 std::__terminate(t_handler);
   1234             bool native_new_exception =
   1235                 (new_exception_header->unwindHeader.exception_class & get_vendor_and_language) ==
   1236                                                 (kOurExceptionClass & get_vendor_and_language);
   1237             void* adjustedPtr;
   1238             if (native_new_exception && (new_exception_header != old_exception_header))
   1239             {
   1240                 const __shim_type_info* excpType =
   1241                     static_cast<const __shim_type_info*>(new_exception_header->exceptionType);
   1242                 adjustedPtr =
   1243                     new_exception_header->unwindHeader.exception_class == kOurDependentExceptionClass ?
   1244                         ((__cxa_dependent_exception*)new_exception_header)->primaryException :
   1245                         new_exception_header + 1;
   1246                 if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding,
   1247                                               excpType, adjustedPtr, unwind_exception))
   1248                 {
   1249                     // We need to __cxa_end_catch, but for the old exception,
   1250                     //   not the new one.  This is a little tricky ...
   1251                     // Disguise new_exception_header as a rethrown exception, but
   1252                     //   don't actually rethrow it.  This means you can temporarily
   1253                     //   end the catch clause enclosing new_exception_header without
   1254                     //   __cxa_end_catch destroying new_exception_header.
   1255                     new_exception_header->handlerCount = -new_exception_header->handlerCount;
   1256                     globals->uncaughtExceptions += 1;
   1257                     // Call __cxa_end_catch for new_exception_header
   1258                     __cxa_end_catch();
   1259                     // Call __cxa_end_catch for old_exception_header
   1260                     __cxa_end_catch();
   1261                     // Renter this catch clause with new_exception_header
   1262                     __cxa_begin_catch(&new_exception_header->unwindHeader);
   1263                     // Rethrow new_exception_header
   1264                     throw;
   1265                 }
   1266             }
   1267             // Will a std::bad_exception be catchable by the exception spec at
   1268             //   ttypeIndex?
   1269             // If no
   1270             //    throw std::bad_exception();
   1271             const __shim_type_info* excpType =
   1272                 static_cast<const __shim_type_info*>(&typeid(std::bad_exception));
   1273             std::bad_exception be;
   1274             adjustedPtr = &be;
   1275             if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding,
   1276                                           excpType, adjustedPtr, unwind_exception))
   1277             {
   1278                 // We need to __cxa_end_catch for both the old exception and the
   1279                 //   new exception.  Technically we should do it in that order.
   1280                 //   But it is expedient to do it in the opposite order:
   1281                 // Call __cxa_end_catch for new_exception_header
   1282                 __cxa_end_catch();
   1283                 // Throw std::bad_exception will __cxa_end_catch for
   1284                 //   old_exception_header
   1285                 throw be;
   1286             }
   1287         }
   1288     }
   1289     std::__terminate(t_handler);
   1290 }
   1291 
   1292 }  // extern "C"
   1293 
   1294 }  // __cxxabiv1
   1295