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