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