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 #elif defined(__MVS__)
916 __zos_cxx_personality_v2
917 #else
918 __gxx_personality_v0
919 #endif
920 #endif
921                     (int version, _Unwind_Action actions, uint64_t exceptionClass,
922                      _Unwind_Exception* unwind_exception, _Unwind_Context* context)
923 {
924     if (version != 1 || unwind_exception == 0 || context == 0)
925         return _URC_FATAL_PHASE1_ERROR;
926 
927     bool native_exception = (exceptionClass     & get_vendor_and_language) ==
928                             (kOurExceptionClass & get_vendor_and_language);
929     scan_results results;
930     // Process a catch handler for a native exception first.
931     if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME) &&
932         native_exception) {
933         // Reload the results from the phase 1 cache.
934         __cxa_exception* exception_header =
935             (__cxa_exception*)(unwind_exception + 1) - 1;
936         results.ttypeIndex = exception_header->handlerSwitchValue;
937         results.actionRecord = exception_header->actionRecord;
938         results.languageSpecificData = exception_header->languageSpecificData;
939         results.landingPad =
940             reinterpret_cast<uintptr_t>(exception_header->catchTemp);
941         results.adjustedPtr = exception_header->adjustedPtr;
942 
943         // Jump to the handler.
944         set_registers(unwind_exception, context, results);
945         // Cache base for calculating the address of ttype in
946         // __cxa_call_unexpected.
947         if (results.ttypeIndex < 0) {
948 #if defined(_AIX)
949           exception_header->catchTemp = (void *)_Unwind_GetDataRelBase(context);
950 #else
951           exception_header->catchTemp = 0;
952 #endif
953         }
954         return _URC_INSTALL_CONTEXT;
955     }
956 
957     // In other cases we need to scan LSDA.
958     scan_eh_tab(results, actions, native_exception, unwind_exception, context);
959     if (results.reason == _URC_CONTINUE_UNWIND ||
960         results.reason == _URC_FATAL_PHASE1_ERROR)
961         return results.reason;
962 
963     if (actions & _UA_SEARCH_PHASE)
964     {
965         // Phase 1 search:  All we're looking for in phase 1 is a handler that
966         //   halts unwinding
967         assert(results.reason == _URC_HANDLER_FOUND);
968         if (native_exception) {
969             // For a native exception, cache the LSDA result.
970             __cxa_exception* exc = (__cxa_exception*)(unwind_exception + 1) - 1;
971             exc->handlerSwitchValue = static_cast<int>(results.ttypeIndex);
972             exc->actionRecord = results.actionRecord;
973             exc->languageSpecificData = results.languageSpecificData;
974             exc->catchTemp = reinterpret_cast<void*>(results.landingPad);
975             exc->adjustedPtr = results.adjustedPtr;
976         }
977         return _URC_HANDLER_FOUND;
978     }
979 
980     assert(actions & _UA_CLEANUP_PHASE);
981     assert(results.reason == _URC_HANDLER_FOUND);
982     set_registers(unwind_exception, context, results);
983     // Cache base for calculating the address of ttype in __cxa_call_unexpected.
984     if (results.ttypeIndex < 0) {
985       __cxa_exception* exception_header =
986             (__cxa_exception*)(unwind_exception + 1) - 1;
987 #if defined(_AIX)
988       exception_header->catchTemp = (void *)_Unwind_GetDataRelBase(context);
989 #else
990       exception_header->catchTemp = 0;
991 #endif
992     }
993     return _URC_INSTALL_CONTEXT;
994 }
995 
996 #if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
997 extern "C" _LIBCXXABI_FUNC_VIS EXCEPTION_DISPOSITION
998 __gxx_personality_seh0(PEXCEPTION_RECORD ms_exc, void *this_frame,
999                        PCONTEXT ms_orig_context, PDISPATCHER_CONTEXT ms_disp)
1000 {
1001   return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context, ms_disp,
1002                                __gxx_personality_imp);
1003 }
1004 #endif
1005 
1006 #else
1007 
1008 extern "C" _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception*,
1009                                                   _Unwind_Context*);
1010 
1011 // Helper function to unwind one frame.
1012 // ARM EHABI 7.3 and 7.4: If the personality function returns _URC_CONTINUE_UNWIND, the
1013 // personality routine should update the virtual register set (VRS) according to the
1014 // corresponding frame unwinding instructions (ARM EHABI 9.3.)
1015 static _Unwind_Reason_Code continue_unwind(_Unwind_Exception* unwind_exception,
1016                                            _Unwind_Context* context)
1017 {
1018   switch (__gnu_unwind_frame(unwind_exception, context)) {
1019   case _URC_OK:
1020     return _URC_CONTINUE_UNWIND;
1021   case _URC_END_OF_STACK:
1022     return _URC_END_OF_STACK;
1023   default:
1024     return _URC_FAILURE;
1025   }
1026 }
1027 
1028 // ARM register names
1029 #if !defined(_LIBUNWIND_VERSION)
1030 static const uint32_t REG_UCB = 12;  // Register to save _Unwind_Control_Block
1031 #endif
1032 static const uint32_t REG_SP = 13;
1033 
1034 static void save_results_to_barrier_cache(_Unwind_Exception* unwind_exception,
1035                                           const scan_results& results)
1036 {
1037     unwind_exception->barrier_cache.bitpattern[0] = (uint32_t)results.adjustedPtr;
1038     unwind_exception->barrier_cache.bitpattern[1] = (uint32_t)results.actionRecord;
1039     unwind_exception->barrier_cache.bitpattern[2] = (uint32_t)results.languageSpecificData;
1040     unwind_exception->barrier_cache.bitpattern[3] = (uint32_t)results.landingPad;
1041     unwind_exception->barrier_cache.bitpattern[4] = (uint32_t)results.ttypeIndex;
1042 }
1043 
1044 static void load_results_from_barrier_cache(scan_results& results,
1045                                             const _Unwind_Exception* unwind_exception)
1046 {
1047     results.adjustedPtr = (void*)unwind_exception->barrier_cache.bitpattern[0];
1048     results.actionRecord = (const uint8_t*)unwind_exception->barrier_cache.bitpattern[1];
1049     results.languageSpecificData = (const uint8_t*)unwind_exception->barrier_cache.bitpattern[2];
1050     results.landingPad = (uintptr_t)unwind_exception->barrier_cache.bitpattern[3];
1051     results.ttypeIndex = (int64_t)(int32_t)unwind_exception->barrier_cache.bitpattern[4];
1052 }
1053 
1054 extern "C" _LIBCXXABI_FUNC_VIS _Unwind_Reason_Code
1055 __gxx_personality_v0(_Unwind_State state,
1056                      _Unwind_Exception* unwind_exception,
1057                      _Unwind_Context* context)
1058 {
1059     if (unwind_exception == 0 || context == 0)
1060         return _URC_FATAL_PHASE1_ERROR;
1061 
1062     bool native_exception = __isOurExceptionClass(unwind_exception);
1063 
1064 #if !defined(_LIBUNWIND_VERSION)
1065     // Copy the address of _Unwind_Control_Block to r12 so that
1066     // _Unwind_GetLanguageSpecificData() and _Unwind_GetRegionStart() can
1067     // return correct address.
1068     _Unwind_SetGR(context, REG_UCB, reinterpret_cast<uint32_t>(unwind_exception));
1069 #endif
1070 
1071     // Check the undocumented force unwinding behavior
1072     bool is_force_unwinding = state & _US_FORCE_UNWIND;
1073     state &= ~_US_FORCE_UNWIND;
1074 
1075     scan_results results;
1076     switch (state) {
1077     case _US_VIRTUAL_UNWIND_FRAME:
1078         if (is_force_unwinding)
1079             return continue_unwind(unwind_exception, context);
1080 
1081         // Phase 1 search:  All we're looking for in phase 1 is a handler that halts unwinding
1082         scan_eh_tab(results, _UA_SEARCH_PHASE, native_exception, unwind_exception, context);
1083         if (results.reason == _URC_HANDLER_FOUND)
1084         {
1085             unwind_exception->barrier_cache.sp = _Unwind_GetGR(context, REG_SP);
1086             if (native_exception)
1087                 save_results_to_barrier_cache(unwind_exception, results);
1088             return _URC_HANDLER_FOUND;
1089         }
1090         // Did not find the catch handler
1091         if (results.reason == _URC_CONTINUE_UNWIND)
1092             return continue_unwind(unwind_exception, context);
1093         return results.reason;
1094 
1095     case _US_UNWIND_FRAME_STARTING:
1096         // TODO: Support force unwinding in the phase 2 search.
1097         // NOTE: In order to call the cleanup functions, _Unwind_ForcedUnwind()
1098         // will call this personality function with (_US_FORCE_UNWIND |
1099         // _US_UNWIND_FRAME_STARTING).
1100 
1101         // Phase 2 search
1102         if (unwind_exception->barrier_cache.sp == _Unwind_GetGR(context, REG_SP))
1103         {
1104             // Found a catching handler in phase 1
1105             if (native_exception)
1106             {
1107                 // Load the result from the native exception barrier cache.
1108                 load_results_from_barrier_cache(results, unwind_exception);
1109                 results.reason = _URC_HANDLER_FOUND;
1110             }
1111             else
1112             {
1113                 // Search for the catching handler again for the foreign exception.
1114                 scan_eh_tab(results, static_cast<_Unwind_Action>(_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME),
1115                             native_exception, unwind_exception, context);
1116                 if (results.reason != _URC_HANDLER_FOUND)  // phase1 search should guarantee to find one
1117                     call_terminate(native_exception, unwind_exception);
1118             }
1119 
1120             // Install the context for the catching handler
1121             set_registers(unwind_exception, context, results);
1122             return _URC_INSTALL_CONTEXT;
1123         }
1124 
1125         // Either we didn't do a phase 1 search (due to forced unwinding), or
1126         // phase 1 reported no catching-handlers.
1127         // Search for a (non-catching) cleanup
1128         if (is_force_unwinding)
1129           scan_eh_tab(
1130               results,
1131               static_cast<_Unwind_Action>(_UA_CLEANUP_PHASE | _UA_FORCE_UNWIND),
1132               native_exception, unwind_exception, context);
1133         else
1134           scan_eh_tab(results, _UA_CLEANUP_PHASE, native_exception,
1135                       unwind_exception, context);
1136         if (results.reason == _URC_HANDLER_FOUND)
1137         {
1138             // Found a non-catching handler
1139 
1140             // ARM EHABI 8.4.2: Before we can jump to the cleanup handler, we have to setup some
1141             // internal data structures, so that __cxa_end_cleanup() can get unwind_exception from
1142             // __cxa_get_globals().
1143             __cxa_begin_cleanup(unwind_exception);
1144 
1145             // Install the context for the cleanup handler
1146             set_registers(unwind_exception, context, results);
1147             return _URC_INSTALL_CONTEXT;
1148         }
1149 
1150         // Did not find any handler
1151         if (results.reason == _URC_CONTINUE_UNWIND)
1152             return continue_unwind(unwind_exception, context);
1153         return results.reason;
1154 
1155     case _US_UNWIND_FRAME_RESUME:
1156         return continue_unwind(unwind_exception, context);
1157     }
1158 
1159     // We were called improperly: neither a phase 1 or phase 2 search
1160     return _URC_FATAL_PHASE1_ERROR;
1161 }
1162 #endif
1163 
1164 
1165 __attribute__((noreturn))
1166 _LIBCXXABI_FUNC_VIS void
1167 __cxa_call_unexpected(void* arg)
1168 {
1169     _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(arg);
1170     if (unwind_exception == 0)
1171         call_terminate(false, unwind_exception);
1172     __cxa_begin_catch(unwind_exception);
1173     bool native_old_exception = __isOurExceptionClass(unwind_exception);
1174     std::unexpected_handler u_handler;
1175     std::terminate_handler t_handler;
1176     __cxa_exception* old_exception_header = 0;
1177     int64_t ttypeIndex;
1178     const uint8_t* lsda;
1179     uintptr_t base = 0;
1180 
1181     if (native_old_exception)
1182     {
1183         old_exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
1184         t_handler = old_exception_header->terminateHandler;
1185         u_handler = old_exception_header->unexpectedHandler;
1186         // If std::__unexpected(u_handler) rethrows the same exception,
1187         //   these values get overwritten by the rethrow.  So save them now:
1188 #if defined(_LIBCXXABI_ARM_EHABI)
1189         ttypeIndex = (int64_t)(int32_t)unwind_exception->barrier_cache.bitpattern[4];
1190         lsda = (const uint8_t*)unwind_exception->barrier_cache.bitpattern[2];
1191 #else
1192         ttypeIndex = old_exception_header->handlerSwitchValue;
1193         lsda = old_exception_header->languageSpecificData;
1194         base = (uintptr_t)old_exception_header->catchTemp;
1195 #endif
1196     }
1197     else
1198     {
1199         t_handler = std::get_terminate();
1200         u_handler = std::get_unexpected();
1201     }
1202     try
1203     {
1204         std::__unexpected(u_handler);
1205     }
1206     catch (...)
1207     {
1208         // If the old exception is foreign, then all we can do is terminate.
1209         //   We have no way to recover the needed old exception spec.  There's
1210         //   no way to pass that information here.  And the personality routine
1211         //   can't call us directly and do anything but terminate() if we throw
1212         //   from here.
1213         if (native_old_exception)
1214         {
1215             // Have:
1216             //   old_exception_header->languageSpecificData
1217             //   old_exception_header->actionRecord
1218             //   old_exception_header->catchTemp, base for calculating ttype
1219             // Need
1220             //   const uint8_t* classInfo
1221             //   uint8_t ttypeEncoding
1222             uint8_t lpStartEncoding = *lsda++;
1223             const uint8_t* lpStart =
1224                 (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding, base);
1225             (void)lpStart;  // purposefully unused.  Just needed to increment lsda.
1226             uint8_t ttypeEncoding = *lsda++;
1227             if (ttypeEncoding == DW_EH_PE_omit)
1228                 std::__terminate(t_handler);
1229             uintptr_t classInfoOffset = readULEB128(&lsda);
1230             const uint8_t* classInfo = lsda + classInfoOffset;
1231             // Is this new exception catchable by the exception spec at ttypeIndex?
1232             // The answer is obviously yes if the new and old exceptions are the same exception
1233             // If no
1234             //    throw;
1235             __cxa_eh_globals* globals = __cxa_get_globals_fast();
1236             __cxa_exception* new_exception_header = globals->caughtExceptions;
1237             if (new_exception_header == 0)
1238                 // This shouldn't be able to happen!
1239                 std::__terminate(t_handler);
1240             bool native_new_exception = __isOurExceptionClass(&new_exception_header->unwindHeader);
1241             void* adjustedPtr;
1242             if (native_new_exception && (new_exception_header != old_exception_header))
1243             {
1244                 const __shim_type_info* excpType =
1245                     static_cast<const __shim_type_info*>(new_exception_header->exceptionType);
1246                 adjustedPtr =
1247                     __getExceptionClass(&new_exception_header->unwindHeader) == kOurDependentExceptionClass ?
1248                         ((__cxa_dependent_exception*)new_exception_header)->primaryException :
1249                         new_exception_header + 1;
1250                 if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding,
1251                                               excpType, adjustedPtr,
1252                                               unwind_exception, base))
1253                 {
1254                     // We need to __cxa_end_catch, but for the old exception,
1255                     //   not the new one.  This is a little tricky ...
1256                     // Disguise new_exception_header as a rethrown exception, but
1257                     //   don't actually rethrow it.  This means you can temporarily
1258                     //   end the catch clause enclosing new_exception_header without
1259                     //   __cxa_end_catch destroying new_exception_header.
1260                     new_exception_header->handlerCount = -new_exception_header->handlerCount;
1261                     globals->uncaughtExceptions += 1;
1262                     // Call __cxa_end_catch for new_exception_header
1263                     __cxa_end_catch();
1264                     // Call __cxa_end_catch for old_exception_header
1265                     __cxa_end_catch();
1266                     // Renter this catch clause with new_exception_header
1267                     __cxa_begin_catch(&new_exception_header->unwindHeader);
1268                     // Rethrow new_exception_header
1269                     throw;
1270                 }
1271             }
1272             // Will a std::bad_exception be catchable by the exception spec at
1273             //   ttypeIndex?
1274             // If no
1275             //    throw std::bad_exception();
1276             const __shim_type_info* excpType =
1277                 static_cast<const __shim_type_info*>(&typeid(std::bad_exception));
1278             std::bad_exception be;
1279             adjustedPtr = &be;
1280             if (!exception_spec_can_catch(ttypeIndex, classInfo, ttypeEncoding,
1281                                           excpType, adjustedPtr,
1282                                           unwind_exception, base))
1283             {
1284                 // We need to __cxa_end_catch for both the old exception and the
1285                 //   new exception.  Technically we should do it in that order.
1286                 //   But it is expedient to do it in the opposite order:
1287                 // Call __cxa_end_catch for new_exception_header
1288                 __cxa_end_catch();
1289                 // Throw std::bad_exception will __cxa_end_catch for
1290                 //   old_exception_header
1291                 throw be;
1292             }
1293         }
1294     }
1295     std::__terminate(t_handler);
1296 }
1297 
1298 #if defined(_AIX)
1299 // Personality routine for EH using the range table. Make it an alias of
1300 // __gxx_personality_v0().
1301 _LIBCXXABI_FUNC_VIS _Unwind_Reason_Code __xlcxx_personality_v1(
1302     int version, _Unwind_Action actions, uint64_t exceptionClass,
1303     _Unwind_Exception* unwind_exception, _Unwind_Context* context)
1304     __attribute__((__alias__("__gxx_personality_v0")));
1305 #endif
1306 
1307 }  // extern "C"
1308 
1309 }  // __cxxabiv1
1310 
1311 #if defined(_AIX)
1312 // Include implementation of the personality and helper functions for the
1313 // state table based EH used by IBM legacy compilers xlC and xlclang++ on AIX.
1314 #  include "aix_state_tab_eh.inc"
1315 #endif
1316