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