1 //===----------------------------------------------------------------------===//
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
8 // Implements ARM zero-cost C++ exceptions
10 //===----------------------------------------------------------------------===//
12 #include "Unwind-EHABI.h"
14 #if defined(_LIBUNWIND_ARM_EHABI)
24 #include "libunwind.h"
25 #include "libunwind_ext.h"
30 // Strange order: take words in order, but inside word, take from most to least
32 uint8_t getByte(const uint32_t* data
, size_t offset
) {
33 const uint8_t* byteData
= reinterpret_cast<const uint8_t*>(data
);
34 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
35 return byteData
[(offset
& ~(size_t)0x03) + (3 - (offset
& (size_t)0x03))];
36 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
37 return byteData
[offset
];
39 #error "Unable to determine endianess"
43 const char* getNextWord(const char* data
, uint32_t* out
) {
44 *out
= *reinterpret_cast<const uint32_t*>(data
);
48 const char* getNextNibble(const char* data
, uint32_t* out
) {
49 *out
= *reinterpret_cast<const uint16_t*>(data
);
56 SU16
= 0, // Short descriptor, 16-bit entries
57 LU16
= 1, // Long descriptor, 16-bit entries
58 LU32
= 3, // Long descriptor, 32-bit entries
59 RESERVED0
= 4, RESERVED1
= 5, RESERVED2
= 6, RESERVED3
= 7,
60 RESERVED4
= 8, RESERVED5
= 9, RESERVED6
= 10, RESERVED7
= 11,
61 RESERVED8
= 12, RESERVED9
= 13, RESERVED10
= 14, RESERVED11
= 15
73 _Unwind_Reason_Code
ProcessDescriptors(
75 _Unwind_Control_Block
* ucbp
,
76 struct _Unwind_Context
* context
,
77 Descriptor::Format format
,
78 const char* descriptorStart
,
81 // EHT is inlined in the index using compact form. No descriptors. #5
83 return _URC_CONTINUE_UNWIND
;
85 // TODO: We should check the state here, and determine whether we need to
86 // perform phase1 or phase2 unwinding.
89 const char* descriptor
= descriptorStart
;
90 uint32_t descriptorWord
;
91 getNextWord(descriptor
, &descriptorWord
);
92 while (descriptorWord
) {
93 // Read descriptor based on # 9.2.
97 case Descriptor::LU32
:
98 descriptor
= getNextWord(descriptor
, &length
);
99 descriptor
= getNextWord(descriptor
, &offset
);
101 case Descriptor::LU16
:
102 descriptor
= getNextNibble(descriptor
, &length
);
103 descriptor
= getNextNibble(descriptor
, &offset
);
110 // See # 9.2 table for decoding the kind of descriptor. It's a 2-bit value.
111 Descriptor::Kind kind
=
112 static_cast<Descriptor::Kind
>((length
& 0x1) | ((offset
& 0x1) << 1));
114 // Clear off flag from last bit.
117 uintptr_t scopeStart
= ucbp
->pr_cache
.fnstart
+ offset
;
118 uintptr_t scopeEnd
= scopeStart
+ length
;
119 uintptr_t pc
= _Unwind_GetIP(context
);
120 bool isInScope
= (scopeStart
<= pc
) && (pc
< scopeEnd
);
123 case Descriptor::CLEANUP
: {
124 // TODO(ajwong): Handle cleanup descriptors.
127 case Descriptor::FUNC
: {
128 // TODO(ajwong): Handle function descriptors.
131 case Descriptor::CATCH
: {
132 // Catch descriptors require gobbling one more word.
133 uint32_t landing_pad
;
134 descriptor
= getNextWord(descriptor
, &landing_pad
);
137 // TODO(ajwong): This is only phase1 compatible logic. Implement
139 landing_pad
= signExtendPrel31(landing_pad
& ~0x80000000);
140 if (landing_pad
== 0xffffffff) {
141 return _URC_HANDLER_FOUND
;
142 } else if (landing_pad
== 0xfffffffe) {
146 bool is_reference_type = landing_pad & 0x80000000;
147 void* matched_object;
148 if (__cxxabiv1::__cxa_type_match(
149 ucbp, reinterpret_cast<const std::type_info *>(landing_pad),
151 &matched_object) != __cxxabiv1::ctm_failed)
152 return _URC_HANDLER_FOUND;
154 _LIBUNWIND_ABORT("Type matching not implemented");
160 _LIBUNWIND_ABORT("Invalid descriptor kind found.");
163 getNextWord(descriptor
, &descriptorWord
);
166 return _URC_CONTINUE_UNWIND
;
169 static _Unwind_Reason_Code
unwindOneFrame(_Unwind_State state
,
170 _Unwind_Control_Block
* ucbp
,
171 struct _Unwind_Context
* context
) {
172 // Read the compact model EHT entry's header # 6.3
173 const uint32_t* unwindingData
= ucbp
->pr_cache
.ehtp
;
174 assert((*unwindingData
& 0xf0000000) == 0x80000000 && "Must be a compact entry");
175 Descriptor::Format format
=
176 static_cast<Descriptor::Format
>((*unwindingData
& 0x0f000000) >> 24);
179 reinterpret_cast<const char *>(_Unwind_GetLanguageSpecificData(context
));
181 // Handle descriptors before unwinding so they are processed in the context
182 // of the correct stack frame.
183 _Unwind_Reason_Code result
=
184 ProcessDescriptors(state
, ucbp
, context
, format
, lsda
,
185 ucbp
->pr_cache
.additional
);
187 if (result
!= _URC_CONTINUE_UNWIND
)
190 switch (__unw_step(reinterpret_cast<unw_cursor_t
*>(context
))) {
191 case UNW_STEP_SUCCESS
:
192 return _URC_CONTINUE_UNWIND
;
194 return _URC_END_OF_STACK
;
200 // Generates mask discriminator for _Unwind_VRS_Pop, e.g. for _UVRSC_CORE /
202 uint32_t RegisterMask(uint8_t start
, uint8_t count_minus_one
) {
203 return ((1U << (count_minus_one
+ 1)) - 1) << start
;
206 // Generates mask discriminator for _Unwind_VRS_Pop, e.g. for _UVRSC_VFP /
208 uint32_t RegisterRange(uint8_t start
, uint8_t count_minus_one
) {
209 return ((uint32_t)start
<< 16) | ((uint32_t)count_minus_one
+ 1);
212 } // end anonymous namespace
215 * Decodes an EHT entry.
217 * @param data Pointer to EHT.
218 * @param[out] off Offset from return value (in bytes) to begin interpretation.
219 * @param[out] len Number of bytes in unwind code.
220 * @return Pointer to beginning of unwind code.
222 extern "C" const uint32_t*
223 decode_eht_entry(const uint32_t* data
, size_t* off
, size_t* len
) {
224 if ((*data
& 0x80000000) == 0) {
225 // 6.2: Generic Model
227 // EHT entry is a prel31 pointing to the PR, followed by data understood
228 // only by the personality routine. Fortunately, all existing assembler
229 // implementations, including GNU assembler, LLVM integrated assembler,
230 // and ARM assembler, assume that the unwind opcodes come after the
231 // personality rountine address.
232 *off
= 1; // First byte is size data.
233 *len
= (((data
[1] >> 24) & 0xff) + 1) * 4;
234 data
++; // Skip the first word, which is the prel31 offset.
236 // 6.3: ARM Compact Model
238 // EHT entries here correspond to the __aeabi_unwind_cpp_pr[012] PRs indeed
240 Descriptor::Format format
=
241 static_cast<Descriptor::Format
>((*data
& 0x0f000000) >> 24);
243 case Descriptor::SU16
:
247 case Descriptor::LU16
:
248 case Descriptor::LU32
:
249 *len
= 4 + 4 * ((*data
& 0x00ff0000) >> 16);
259 _LIBUNWIND_EXPORT _Unwind_Reason_Code
260 _Unwind_VRS_Interpret(_Unwind_Context
*context
, const uint32_t *data
,
261 size_t offset
, size_t len
) {
262 bool wrotePC
= false;
264 bool hasReturnAddrAuthCode
= false;
265 while (offset
< len
&& !finish
) {
266 uint8_t byte
= getByte(data
, offset
++);
267 if ((byte
& 0x80) == 0) {
269 _Unwind_VRS_Get(context
, _UVRSC_CORE
, UNW_ARM_SP
, _UVRSD_UINT32
, &sp
);
271 sp
-= (((uint32_t)byte
& 0x3f) << 2) + 4;
273 sp
+= ((uint32_t)byte
<< 2) + 4;
274 _Unwind_VRS_Set(context
, _UVRSC_CORE
, UNW_ARM_SP
, _UVRSD_UINT32
, &sp
);
276 switch (byte
& 0xf0) {
281 (((uint32_t)byte
& 0x0f) << 12) |
282 (((uint32_t)getByte(data
, offset
++)) << 4);
285 if (registers
& (1 << 15))
287 _Unwind_VRS_Pop(context
, _UVRSC_CORE
, registers
, _UVRSD_UINT32
);
291 uint8_t reg
= byte
& 0x0f;
292 if (reg
== 13 || reg
== 15)
295 _Unwind_VRS_Get(context
, _UVRSC_CORE
, UNW_ARM_R0
+ reg
,
297 _Unwind_VRS_Set(context
, _UVRSC_CORE
, UNW_ARM_SP
, _UVRSD_UINT32
,
302 uint32_t registers
= RegisterMask(4, byte
& 0x07);
304 registers
|= 1 << 14;
305 _Unwind_VRS_Pop(context
, _UVRSC_CORE
, registers
, _UVRSD_UINT32
);
316 uint8_t registers
= getByte(data
, offset
++);
317 if (registers
& 0xf0 || !registers
)
319 _Unwind_VRS_Pop(context
, _UVRSC_CORE
, registers
, _UVRSD_UINT32
);
325 // This decodes a uleb128 value.
329 uint32_t v
= getByte(data
, offset
++);
330 addend
|= (v
& 0x7f) << shift
;
336 _Unwind_VRS_Get(context
, _UVRSC_CORE
, UNW_ARM_SP
, _UVRSD_UINT32
,
338 sp
+= 0x204 + (addend
<< 2);
339 _Unwind_VRS_Set(context
, _UVRSC_CORE
, UNW_ARM_SP
, _UVRSD_UINT32
,
344 uint8_t v
= getByte(data
, offset
++);
345 _Unwind_VRS_Pop(context
, _UVRSC_VFP
,
346 RegisterRange(static_cast<uint8_t>(v
>> 4),
347 v
& 0x0f), _UVRSD_VFPX
);
351 hasReturnAddrAuthCode
= true;
352 _Unwind_VRS_Pop(context
, _UVRSC_PSEUDO
,
353 0 /* Return Address Auth Code */, _UVRSD_UINT32
);
360 _Unwind_VRS_Pop(context
, _UVRSC_VFP
,
361 RegisterRange(8, byte
& 0x07), _UVRSD_VFPX
);
368 #if defined(__ARM_WMMX)
375 _Unwind_VRS_Pop(context
, _UVRSC_WMMXD
,
376 RegisterRange(10, byte
& 0x7), _UVRSD_DOUBLE
);
379 uint8_t v
= getByte(data
, offset
++);
380 uint8_t start
= static_cast<uint8_t>(v
>> 4);
381 uint8_t count_minus_one
= v
& 0xf;
382 if (start
+ count_minus_one
>= 16)
384 _Unwind_VRS_Pop(context
, _UVRSC_WMMXD
,
385 RegisterRange(start
, count_minus_one
),
390 uint8_t v
= getByte(data
, offset
++);
393 _Unwind_VRS_Pop(context
, _UVRSC_WMMXC
, v
, _UVRSD_DOUBLE
);
399 uint8_t v
= getByte(data
, offset
++);
401 static_cast<uint8_t>(((byte
== 0xc8) ? 16 : 0) + (v
>> 4));
402 uint8_t count_minus_one
= v
& 0xf;
403 if (start
+ count_minus_one
>= 32)
405 _Unwind_VRS_Pop(context
, _UVRSC_VFP
,
406 RegisterRange(start
, count_minus_one
),
418 _Unwind_VRS_Pop(context
, _UVRSC_VFP
, RegisterRange(8, byte
& 0x7),
429 _Unwind_VRS_Get(context
, _UVRSC_CORE
, UNW_ARM_LR
, _UVRSD_UINT32
, &lr
);
430 #ifdef __ARM_FEATURE_PAUTH
431 if (hasReturnAddrAuthCode
) {
434 _Unwind_VRS_Get(context
, _UVRSC_CORE
, UNW_ARM_SP
, _UVRSD_UINT32
, &sp
);
435 _Unwind_VRS_Get(context
, _UVRSC_PSEUDO
, 0, _UVRSD_UINT32
, &pac
);
436 __asm__
__volatile__("autg %0, %1, %2" : : "r"(pac
), "r"(lr
), "r"(sp
) :);
439 (void)hasReturnAddrAuthCode
;
441 _Unwind_VRS_Set(context
, _UVRSC_CORE
, UNW_ARM_IP
, _UVRSD_UINT32
, &lr
);
443 return _URC_CONTINUE_UNWIND
;
446 extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code
447 __aeabi_unwind_cpp_pr0(_Unwind_State state
, _Unwind_Control_Block
*ucbp
,
448 _Unwind_Context
*context
) {
449 return unwindOneFrame(state
, ucbp
, context
);
452 extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code
453 __aeabi_unwind_cpp_pr1(_Unwind_State state
, _Unwind_Control_Block
*ucbp
,
454 _Unwind_Context
*context
) {
455 return unwindOneFrame(state
, ucbp
, context
);
458 extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code
459 __aeabi_unwind_cpp_pr2(_Unwind_State state
, _Unwind_Control_Block
*ucbp
,
460 _Unwind_Context
*context
) {
461 return unwindOneFrame(state
, ucbp
, context
);
464 static _Unwind_Reason_Code
465 unwind_phase1(unw_context_t
*uc
, unw_cursor_t
*cursor
, _Unwind_Exception
*exception_object
) {
466 // EHABI #7.3 discusses preserving the VRS in a "temporary VRS" during
467 // phase 1 and then restoring it to the "primary VRS" for phase 2. The
468 // effect is phase 2 doesn't see any of the VRS manipulations from phase 1.
469 // In this implementation, the phases don't share the VRS backing store.
470 // Instead, they are passed the original |uc| and they create a new VRS
471 // from scratch thus achieving the same effect.
472 __unw_init_local(cursor
, uc
);
474 // Walk each frame looking for a place to stop.
475 for (bool handlerNotFound
= true; handlerNotFound
;) {
477 // See if frame has code to run (has personality routine).
478 unw_proc_info_t frameInfo
;
479 if (__unw_get_proc_info(cursor
, &frameInfo
) != UNW_ESUCCESS
) {
480 _LIBUNWIND_TRACE_UNWINDING(
481 "unwind_phase1(ex_ojb=%p): __unw_get_proc_info "
482 "failed => _URC_FATAL_PHASE1_ERROR",
483 static_cast<void *>(exception_object
));
484 return _URC_FATAL_PHASE1_ERROR
;
488 // When tracing, print state information.
489 if (_LIBUNWIND_TRACING_UNWINDING
) {
490 char functionBuf
[512];
491 const char *functionName
= functionBuf
;
493 if ((__unw_get_proc_name(cursor
, functionBuf
, sizeof(functionBuf
),
494 &offset
) != UNW_ESUCCESS
) ||
495 (frameInfo
.start_ip
+ offset
> frameInfo
.end_ip
))
496 functionName
= ".anonymous.";
498 __unw_get_reg(cursor
, UNW_REG_IP
, &pc
);
499 _LIBUNWIND_TRACE_UNWINDING(
500 "unwind_phase1(ex_ojb=%p): pc=0x%" PRIxPTR
", start_ip=0x%" PRIxPTR
", func=%s, "
501 "lsda=0x%" PRIxPTR
", personality=0x%" PRIxPTR
,
502 static_cast<void *>(exception_object
), pc
,
503 frameInfo
.start_ip
, functionName
,
504 frameInfo
.lsda
, frameInfo
.handler
);
508 // If there is a personality routine, ask it if it will want to stop at
510 if (frameInfo
.handler
!= 0) {
511 _Unwind_Personality_Fn p
=
512 (_Unwind_Personality_Fn
)(long)(frameInfo
.handler
);
513 _LIBUNWIND_TRACE_UNWINDING(
514 "unwind_phase1(ex_ojb=%p): calling personality function %p",
515 static_cast<void *>(exception_object
),
516 reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(p
)));
517 struct _Unwind_Context
*context
= (struct _Unwind_Context
*)(cursor
);
518 exception_object
->pr_cache
.fnstart
= frameInfo
.start_ip
;
519 exception_object
->pr_cache
.ehtp
=
520 (_Unwind_EHT_Header
*)frameInfo
.unwind_info
;
521 exception_object
->pr_cache
.additional
= frameInfo
.flags
;
522 _Unwind_Reason_Code personalityResult
=
523 (*p
)(_US_VIRTUAL_UNWIND_FRAME
, exception_object
, context
);
524 _LIBUNWIND_TRACE_UNWINDING(
525 "unwind_phase1(ex_ojb=%p): personality result %d start_ip %x ehtp %p "
527 static_cast<void *>(exception_object
), personalityResult
,
528 exception_object
->pr_cache
.fnstart
,
529 static_cast<void *>(exception_object
->pr_cache
.ehtp
),
530 exception_object
->pr_cache
.additional
);
531 switch (personalityResult
) {
532 case _URC_HANDLER_FOUND
:
533 // found a catch clause or locals that need destructing in this frame
534 // stop search and remember stack pointer at the frame
535 handlerNotFound
= false;
536 // p should have initialized barrier_cache. EHABI #7.3.5
537 _LIBUNWIND_TRACE_UNWINDING(
538 "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND",
539 static_cast<void *>(exception_object
));
540 return _URC_NO_REASON
;
542 case _URC_CONTINUE_UNWIND
:
543 _LIBUNWIND_TRACE_UNWINDING(
544 "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND",
545 static_cast<void *>(exception_object
));
546 // continue unwinding
554 // something went wrong
555 _LIBUNWIND_TRACE_UNWINDING(
556 "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR",
557 static_cast<void *>(exception_object
));
558 return _URC_FATAL_PHASE1_ERROR
;
562 return _URC_NO_REASON
;
565 static _Unwind_Reason_Code
unwind_phase2(unw_context_t
*uc
, unw_cursor_t
*cursor
,
566 _Unwind_Exception
*exception_object
,
568 // See comment at the start of unwind_phase1 regarding VRS integrity.
569 __unw_init_local(cursor
, uc
);
571 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)",
572 static_cast<void *>(exception_object
));
575 // Walk each frame until we reach where search phase said to stop.
577 // Ask libunwind to get next frame (skip over first which is
578 // _Unwind_RaiseException or _Unwind_Resume).
580 // Resume only ever makes sense for 1 frame.
581 _Unwind_State state
=
582 resume
? _US_UNWIND_FRAME_RESUME
: _US_UNWIND_FRAME_STARTING
;
583 if (resume
&& frame_count
== 1) {
584 // On a resume, first unwind the _Unwind_Resume() frame. The next frame
585 // is now the landing pad for the cleanup from a previous execution of
586 // phase2. To continue unwindingly correctly, replace VRS[15] with the
587 // IP of the frame that the previous run of phase2 installed the context
588 // for. After this, continue unwinding as if normal.
590 // See #7.4.6 for details.
591 __unw_set_reg(cursor
, UNW_REG_IP
,
592 exception_object
->unwinder_cache
.reserved2
);
596 // Get info about this frame.
598 unw_proc_info_t frameInfo
;
599 __unw_get_reg(cursor
, UNW_REG_SP
, &sp
);
600 if (__unw_get_proc_info(cursor
, &frameInfo
) != UNW_ESUCCESS
) {
601 _LIBUNWIND_TRACE_UNWINDING(
602 "unwind_phase2(ex_ojb=%p): __unw_get_proc_info "
603 "failed => _URC_FATAL_PHASE2_ERROR",
604 static_cast<void *>(exception_object
));
605 return _URC_FATAL_PHASE2_ERROR
;
609 // When tracing, print state information.
610 if (_LIBUNWIND_TRACING_UNWINDING
) {
611 char functionBuf
[512];
612 const char *functionName
= functionBuf
;
614 if ((__unw_get_proc_name(cursor
, functionBuf
, sizeof(functionBuf
),
615 &offset
) != UNW_ESUCCESS
) ||
616 (frameInfo
.start_ip
+ offset
> frameInfo
.end_ip
))
617 functionName
= ".anonymous.";
618 _LIBUNWIND_TRACE_UNWINDING(
619 "unwind_phase2(ex_ojb=%p): start_ip=0x%" PRIxPTR
", func=%s, sp=0x%" PRIxPTR
", "
620 "lsda=0x%" PRIxPTR
", personality=0x%" PRIxPTR
"",
621 static_cast<void *>(exception_object
), frameInfo
.start_ip
,
622 functionName
, sp
, frameInfo
.lsda
,
627 // If there is a personality routine, tell it we are unwinding.
628 if (frameInfo
.handler
!= 0) {
629 _Unwind_Personality_Fn p
=
630 (_Unwind_Personality_Fn
)(intptr_t)(frameInfo
.handler
);
631 struct _Unwind_Context
*context
= (struct _Unwind_Context
*)(cursor
);
633 exception_object
->pr_cache
.fnstart
= frameInfo
.start_ip
;
634 exception_object
->pr_cache
.ehtp
=
635 (_Unwind_EHT_Header
*)frameInfo
.unwind_info
;
636 exception_object
->pr_cache
.additional
= frameInfo
.flags
;
637 _Unwind_Reason_Code personalityResult
=
638 (*p
)(state
, exception_object
, context
);
639 switch (personalityResult
) {
640 case _URC_CONTINUE_UNWIND
:
641 // Continue unwinding
642 _LIBUNWIND_TRACE_UNWINDING(
643 "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND",
644 static_cast<void *>(exception_object
));
646 if (sp
== exception_object
->barrier_cache
.sp
) {
647 // Phase 1 said we would stop at this frame, but we did not...
648 _LIBUNWIND_ABORT("during phase1 personality function said it would "
649 "stop here, but now in phase2 it did not stop here");
652 case _URC_INSTALL_CONTEXT
:
653 _LIBUNWIND_TRACE_UNWINDING(
654 "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT",
655 static_cast<void *>(exception_object
));
656 // Personality routine says to transfer control to landing pad.
657 // We may get control back if landing pad calls _Unwind_Resume().
658 if (_LIBUNWIND_TRACING_UNWINDING
) {
660 __unw_get_reg(cursor
, UNW_REG_IP
, &pc
);
661 __unw_get_reg(cursor
, UNW_REG_SP
, &sp
);
662 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
663 "user code with ip=0x%" PRIxPTR
", sp=0x%" PRIxPTR
,
664 static_cast<void *>(exception_object
),
669 // EHABI #7.4.1 says we need to preserve pc for when _Unwind_Resume
670 // is called back, to find this same frame.
672 __unw_get_reg(cursor
, UNW_REG_IP
, &pc
);
673 exception_object
->unwinder_cache
.reserved2
= (uint32_t)pc
;
675 __unw_resume(cursor
);
676 // __unw_resume() only returns if there was an error.
677 return _URC_FATAL_PHASE2_ERROR
;
684 // Personality routine returned an unknown result code.
685 _LIBUNWIND_DEBUG_LOG("personality function returned unknown result %d",
687 return _URC_FATAL_PHASE2_ERROR
;
693 // Clean up phase did not resume at the frame that the search phase
695 return _URC_FATAL_PHASE2_ERROR
;
698 static _Unwind_Reason_Code
699 unwind_phase2_forced(unw_context_t
*uc
, unw_cursor_t
*cursor
,
700 _Unwind_Exception
*exception_object
, _Unwind_Stop_Fn stop
,
701 void *stop_parameter
) {
702 bool endOfStack
= false;
703 // See comment at the start of unwind_phase1 regarding VRS integrity.
704 __unw_init_local(cursor
, uc
);
705 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_force(ex_ojb=%p)",
706 static_cast<void *>(exception_object
));
707 // Walk each frame until we reach where search phase said to stop
708 while (!endOfStack
) {
709 // Update info about this frame.
710 unw_proc_info_t frameInfo
;
711 if (__unw_get_proc_info(cursor
, &frameInfo
) != UNW_ESUCCESS
) {
712 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): __unw_get_proc_info "
713 "failed => _URC_END_OF_STACK",
714 (void *)exception_object
);
715 return _URC_FATAL_PHASE2_ERROR
;
719 // When tracing, print state information.
720 if (_LIBUNWIND_TRACING_UNWINDING
) {
721 char functionBuf
[512];
722 const char *functionName
= functionBuf
;
724 if ((__unw_get_proc_name(cursor
, functionBuf
, sizeof(functionBuf
),
725 &offset
) != UNW_ESUCCESS
) ||
726 (frameInfo
.start_ip
+ offset
> frameInfo
.end_ip
))
727 functionName
= ".anonymous.";
728 _LIBUNWIND_TRACE_UNWINDING(
729 "unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIxPTR
730 ", func=%s, lsda=0x%" PRIxPTR
", personality=0x%" PRIxPTR
,
731 (void *)exception_object
, frameInfo
.start_ip
, functionName
,
732 frameInfo
.lsda
, frameInfo
.handler
);
736 // Call stop function at each frame.
737 _Unwind_Action action
=
738 (_Unwind_Action
)(_UA_FORCE_UNWIND
| _UA_CLEANUP_PHASE
);
739 _Unwind_Reason_Code stopResult
=
740 (*stop
)(1, action
, exception_object
->exception_class
, exception_object
,
741 (_Unwind_Context
*)(cursor
), stop_parameter
);
742 _LIBUNWIND_TRACE_UNWINDING(
743 "unwind_phase2_forced(ex_ojb=%p): stop function returned %d",
744 (void *)exception_object
, stopResult
);
745 if (stopResult
!= _URC_NO_REASON
) {
746 _LIBUNWIND_TRACE_UNWINDING(
747 "unwind_phase2_forced(ex_ojb=%p): stopped by stop function",
748 (void *)exception_object
);
749 return _URC_FATAL_PHASE2_ERROR
;
752 // If there is a personality routine, tell it we are unwinding.
753 if (frameInfo
.handler
!= 0) {
754 _Unwind_Personality_Fn p
=
755 (_Unwind_Personality_Fn
)(uintptr_t)(frameInfo
.handler
);
756 struct _Unwind_Context
*context
= (struct _Unwind_Context
*)(cursor
);
758 exception_object
->pr_cache
.fnstart
= frameInfo
.start_ip
;
759 exception_object
->pr_cache
.ehtp
=
760 (_Unwind_EHT_Header
*)frameInfo
.unwind_info
;
761 exception_object
->pr_cache
.additional
= frameInfo
.flags
;
762 _Unwind_Reason_Code personalityResult
=
763 (*p
)(_US_FORCE_UNWIND
| _US_UNWIND_FRAME_STARTING
, exception_object
,
765 switch (personalityResult
) {
766 case _URC_CONTINUE_UNWIND
:
767 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
768 "personality returned "
769 "_URC_CONTINUE_UNWIND",
770 (void *)exception_object
);
771 // Destructors called, continue unwinding
773 case _URC_INSTALL_CONTEXT
:
774 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
775 "personality returned "
776 "_URC_INSTALL_CONTEXT",
777 (void *)exception_object
);
778 // We may get control back if landing pad calls _Unwind_Resume().
779 __unw_resume(cursor
);
781 case _URC_END_OF_STACK
:
782 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
783 "personality returned "
785 (void *)exception_object
);
786 // Personalty routine did the step and it can't step forward.
790 // Personality routine returned an unknown result code.
791 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
792 "personality returned %d, "
793 "_URC_FATAL_PHASE2_ERROR",
794 (void *)exception_object
, personalityResult
);
795 return _URC_FATAL_PHASE2_ERROR
;
800 // Call stop function one last time and tell it we've reached the end
802 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop "
803 "function with _UA_END_OF_STACK",
804 (void *)exception_object
);
805 _Unwind_Action lastAction
=
806 (_Unwind_Action
)(_UA_FORCE_UNWIND
| _UA_CLEANUP_PHASE
| _UA_END_OF_STACK
);
807 (*stop
)(1, lastAction
, exception_object
->exception_class
, exception_object
,
808 (struct _Unwind_Context
*)(cursor
), stop_parameter
);
810 // Clean up phase did not resume at the frame that the search phase said it
812 return _URC_FATAL_PHASE2_ERROR
;
815 /// Called by __cxa_throw. Only returns if there is a fatal error.
816 _LIBUNWIND_EXPORT _Unwind_Reason_Code
817 _Unwind_RaiseException(_Unwind_Exception
*exception_object
) {
818 _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)",
819 static_cast<void *>(exception_object
));
822 __unw_getcontext(&uc
);
824 // This field for is for compatibility with GCC to say this isn't a forced
825 // unwind. EHABI #7.2
826 exception_object
->unwinder_cache
.reserved1
= 0;
828 // phase 1: the search phase
829 _Unwind_Reason_Code phase1
= unwind_phase1(&uc
, &cursor
, exception_object
);
830 if (phase1
!= _URC_NO_REASON
)
833 // phase 2: the clean up phase
834 return unwind_phase2(&uc
, &cursor
, exception_object
, false);
837 _LIBUNWIND_EXPORT
void _Unwind_Complete(_Unwind_Exception
* exception_object
) {
838 // This is to be called when exception handling completes to give us a chance
839 // to perform any housekeeping. EHABI #7.2. But we have nothing to do here.
840 (void)exception_object
;
843 /// When _Unwind_RaiseException() is in phase2, it hands control
844 /// to the personality function at each frame. The personality
845 /// may force a jump to a landing pad in that function, the landing
846 /// pad code may then call _Unwind_Resume() to continue with the
847 /// unwinding. Note: the call to _Unwind_Resume() is from compiler
848 /// generated user code. All other _Unwind_* routines are called
849 /// by the C++ runtime __cxa_* routines.
851 /// Note: re-throwing an exception (as opposed to continuing the unwind)
852 /// is implemented by having the code call __cxa_rethrow() which
853 /// in turn calls _Unwind_Resume_or_Rethrow().
854 _LIBUNWIND_EXPORT
void
855 _Unwind_Resume(_Unwind_Exception
*exception_object
) {
856 _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)",
857 static_cast<void *>(exception_object
));
860 __unw_getcontext(&uc
);
862 if (exception_object
->unwinder_cache
.reserved1
)
863 unwind_phase2_forced(
864 &uc
, &cursor
, exception_object
,
865 (_Unwind_Stop_Fn
)exception_object
->unwinder_cache
.reserved1
,
866 (void *)exception_object
->unwinder_cache
.reserved3
);
868 unwind_phase2(&uc
, &cursor
, exception_object
, true);
870 // Clients assume _Unwind_Resume() does not return, so all we can do is abort.
871 _LIBUNWIND_ABORT("_Unwind_Resume() can't return");
874 /// Called by personality handler during phase 2 to get LSDA for current frame.
875 _LIBUNWIND_EXPORT
uintptr_t
876 _Unwind_GetLanguageSpecificData(struct _Unwind_Context
*context
) {
877 unw_cursor_t
*cursor
= (unw_cursor_t
*)context
;
878 unw_proc_info_t frameInfo
;
879 uintptr_t result
= 0;
880 if (__unw_get_proc_info(cursor
, &frameInfo
) == UNW_ESUCCESS
)
881 result
= (uintptr_t)frameInfo
.lsda
;
882 _LIBUNWIND_TRACE_API(
883 "_Unwind_GetLanguageSpecificData(context=%p) => 0x%llx",
884 static_cast<void *>(context
), (long long)result
);
888 // Only used in _LIBUNWIND_TRACE_API, which is a no-op when assertions are
890 [[gnu::unused
]] static uint64_t
891 ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation
,
892 const void *valuep
) {
894 switch (representation
) {
897 memcpy(&value
, valuep
, sizeof(uint32_t));
903 memcpy(&value
, valuep
, sizeof(uint64_t));
909 _LIBUNWIND_EXPORT _Unwind_VRS_Result
910 _Unwind_VRS_Set(_Unwind_Context
*context
, _Unwind_VRS_RegClass regclass
,
911 uint32_t regno
, _Unwind_VRS_DataRepresentation representation
,
913 _LIBUNWIND_TRACE_API("_Unwind_VRS_Set(context=%p, regclass=%d, reg=%d, "
914 "rep=%d, value=0x%llX)",
915 static_cast<void *>(context
), regclass
, regno
,
917 ValueAsBitPattern(representation
, valuep
));
918 unw_cursor_t
*cursor
= (unw_cursor_t
*)context
;
921 if (representation
!= _UVRSD_UINT32
|| regno
> 15)
922 return _UVRSR_FAILED
;
923 return __unw_set_reg(cursor
, (unw_regnum_t
)(UNW_ARM_R0
+ regno
),
924 *(unw_word_t
*)valuep
) == UNW_ESUCCESS
928 if (representation
!= _UVRSD_VFPX
&& representation
!= _UVRSD_DOUBLE
)
929 return _UVRSR_FAILED
;
930 if (representation
== _UVRSD_VFPX
) {
931 // Can only touch d0-15 with FSTMFDX.
933 return _UVRSR_FAILED
;
934 __unw_save_vfp_as_X(cursor
);
937 return _UVRSR_FAILED
;
939 return __unw_set_fpreg(cursor
, (unw_regnum_t
)(UNW_ARM_D0
+ regno
),
940 *(unw_fpreg_t
*)valuep
) == UNW_ESUCCESS
943 #if defined(__ARM_WMMX)
945 if (representation
!= _UVRSD_UINT32
|| regno
> 3)
946 return _UVRSR_FAILED
;
947 return __unw_set_reg(cursor
, (unw_regnum_t
)(UNW_ARM_WC0
+ regno
),
948 *(unw_word_t
*)valuep
) == UNW_ESUCCESS
952 if (representation
!= _UVRSD_DOUBLE
|| regno
> 31)
953 return _UVRSR_FAILED
;
954 return __unw_set_fpreg(cursor
, (unw_regnum_t
)(UNW_ARM_WR0
+ regno
),
955 *(unw_fpreg_t
*)valuep
) == UNW_ESUCCESS
964 // There's only one pseudo-register, PAC, with regno == 0.
965 if (representation
!= _UVRSD_UINT32
|| regno
!= 0)
966 return _UVRSR_FAILED
;
967 return __unw_set_reg(cursor
, (unw_regnum_t
)(UNW_ARM_RA_AUTH_CODE
),
968 *(unw_word_t
*)valuep
) == UNW_ESUCCESS
973 _LIBUNWIND_ABORT("unsupported register class");
976 static _Unwind_VRS_Result
977 _Unwind_VRS_Get_Internal(_Unwind_Context
*context
,
978 _Unwind_VRS_RegClass regclass
, uint32_t regno
,
979 _Unwind_VRS_DataRepresentation representation
,
981 unw_cursor_t
*cursor
= (unw_cursor_t
*)context
;
984 if (representation
!= _UVRSD_UINT32
|| regno
> 15)
985 return _UVRSR_FAILED
;
986 return __unw_get_reg(cursor
, (unw_regnum_t
)(UNW_ARM_R0
+ regno
),
987 (unw_word_t
*)valuep
) == UNW_ESUCCESS
991 if (representation
!= _UVRSD_VFPX
&& representation
!= _UVRSD_DOUBLE
)
992 return _UVRSR_FAILED
;
993 if (representation
== _UVRSD_VFPX
) {
994 // Can only touch d0-15 with FSTMFDX.
996 return _UVRSR_FAILED
;
997 __unw_save_vfp_as_X(cursor
);
1000 return _UVRSR_FAILED
;
1002 return __unw_get_fpreg(cursor
, (unw_regnum_t
)(UNW_ARM_D0
+ regno
),
1003 (unw_fpreg_t
*)valuep
) == UNW_ESUCCESS
1006 #if defined(__ARM_WMMX)
1008 if (representation
!= _UVRSD_UINT32
|| regno
> 3)
1009 return _UVRSR_FAILED
;
1010 return __unw_get_reg(cursor
, (unw_regnum_t
)(UNW_ARM_WC0
+ regno
),
1011 (unw_word_t
*)valuep
) == UNW_ESUCCESS
1015 if (representation
!= _UVRSD_DOUBLE
|| regno
> 31)
1016 return _UVRSR_FAILED
;
1017 return __unw_get_fpreg(cursor
, (unw_regnum_t
)(UNW_ARM_WR0
+ regno
),
1018 (unw_fpreg_t
*)valuep
) == UNW_ESUCCESS
1027 // There's only one pseudo-register, PAC, with regno == 0.
1028 if (representation
!= _UVRSD_UINT32
|| regno
!= 0)
1029 return _UVRSR_FAILED
;
1030 return __unw_get_reg(cursor
, (unw_regnum_t
)(UNW_ARM_RA_AUTH_CODE
),
1031 (unw_word_t
*)valuep
) == UNW_ESUCCESS
1036 _LIBUNWIND_ABORT("unsupported register class");
1039 _LIBUNWIND_EXPORT _Unwind_VRS_Result
1040 _Unwind_VRS_Get(_Unwind_Context
*context
, _Unwind_VRS_RegClass regclass
,
1041 uint32_t regno
, _Unwind_VRS_DataRepresentation representation
,
1043 _Unwind_VRS_Result result
=
1044 _Unwind_VRS_Get_Internal(context
, regclass
, regno
, representation
,
1046 _LIBUNWIND_TRACE_API("_Unwind_VRS_Get(context=%p, regclass=%d, reg=%d, "
1047 "rep=%d, value=0x%llX, result = %d)",
1048 static_cast<void *>(context
), regclass
, regno
,
1050 ValueAsBitPattern(representation
, valuep
), result
);
1055 _Unwind_VRS_Pop(_Unwind_Context
*context
, _Unwind_VRS_RegClass regclass
,
1056 uint32_t discriminator
,
1057 _Unwind_VRS_DataRepresentation representation
) {
1058 _LIBUNWIND_TRACE_API("_Unwind_VRS_Pop(context=%p, regclass=%d, "
1059 "discriminator=%d, representation=%d)",
1060 static_cast<void *>(context
), regclass
, discriminator
,
1064 #if !defined(__ARM_WMMX)
1068 if (representation
!= _UVRSD_UINT32
)
1069 return _UVRSR_FAILED
;
1070 // When popping SP from the stack, we don't want to override it from the
1071 // computed new stack location. See EHABI #7.5.4 table 3.
1072 bool poppedSP
= false;
1074 if (_Unwind_VRS_Get(context
, _UVRSC_CORE
, UNW_ARM_SP
,
1075 _UVRSD_UINT32
, &sp
) != _UVRSR_OK
) {
1076 return _UVRSR_FAILED
;
1078 for (uint32_t i
= 0; i
< 16; ++i
) {
1079 if (!(discriminator
& static_cast<uint32_t>(1 << i
)))
1081 uint32_t value
= *sp
++;
1082 if (regclass
== _UVRSC_CORE
&& i
== 13)
1084 if (_Unwind_VRS_Set(context
, regclass
, i
,
1085 _UVRSD_UINT32
, &value
) != _UVRSR_OK
) {
1086 return _UVRSR_FAILED
;
1090 return _Unwind_VRS_Set(context
, _UVRSC_CORE
, UNW_ARM_SP
,
1091 _UVRSD_UINT32
, &sp
);
1096 #if !defined(__ARM_WMMX)
1100 if (representation
!= _UVRSD_VFPX
&& representation
!= _UVRSD_DOUBLE
)
1101 return _UVRSR_FAILED
;
1102 uint32_t first
= discriminator
>> 16;
1103 uint32_t count
= discriminator
& 0xffff;
1104 uint32_t end
= first
+count
;
1106 if (_Unwind_VRS_Get(context
, _UVRSC_CORE
, UNW_ARM_SP
,
1107 _UVRSD_UINT32
, &sp
) != _UVRSR_OK
) {
1108 return _UVRSR_FAILED
;
1110 // For _UVRSD_VFPX, we're assuming the data is stored in FSTMX "standard
1111 // format 1", which is equivalent to FSTMD + a padding word.
1112 for (uint32_t i
= first
; i
< end
; ++i
) {
1113 // SP is only 32-bit aligned so don't copy 64-bit at a time.
1114 uint64_t w0
= *sp
++;
1115 uint64_t w1
= *sp
++;
1116 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1117 uint64_t value
= (w1
<< 32) | w0
;
1118 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1119 uint64_t value
= (w0
<< 32) | w1
;
1121 #error "Unable to determine endianess"
1123 if (_Unwind_VRS_Set(context
, regclass
, i
, representation
, &value
) !=
1125 return _UVRSR_FAILED
;
1127 if (representation
== _UVRSD_VFPX
)
1129 return _Unwind_VRS_Set(context
, _UVRSC_CORE
, UNW_ARM_SP
, _UVRSD_UINT32
,
1132 case _UVRSC_PSEUDO
: {
1133 if (representation
!= _UVRSD_UINT32
|| discriminator
!= 0)
1134 return _UVRSR_FAILED
;
1135 // Return Address Authentication code (PAC) - discriminator 0
1137 if (_Unwind_VRS_Get(context
, _UVRSC_CORE
, UNW_ARM_SP
, _UVRSD_UINT32
,
1138 &sp
) != _UVRSR_OK
) {
1139 return _UVRSR_FAILED
;
1141 uint32_t pac
= *sp
++;
1142 _Unwind_VRS_Set(context
, _UVRSC_CORE
, UNW_ARM_SP
, _UVRSD_UINT32
, &sp
);
1143 return _Unwind_VRS_Set(context
, _UVRSC_PSEUDO
, 0, _UVRSD_UINT32
, &pac
);
1146 _LIBUNWIND_ABORT("unsupported register class");
1149 /// Not used by C++.
1150 /// Unwinds stack, calling "stop" function at each frame.
1151 /// Could be used to implement longjmp().
1152 _LIBUNWIND_EXPORT _Unwind_Reason_Code
1153 _Unwind_ForcedUnwind(_Unwind_Exception
*exception_object
, _Unwind_Stop_Fn stop
,
1154 void *stop_parameter
) {
1155 _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)",
1156 (void *)exception_object
, (void *)(uintptr_t)stop
);
1158 unw_cursor_t cursor
;
1159 __unw_getcontext(&uc
);
1161 // Mark that this is a forced unwind, so _Unwind_Resume() can do
1163 exception_object
->unwinder_cache
.reserved1
= (uintptr_t)stop
;
1164 exception_object
->unwinder_cache
.reserved3
= (uintptr_t)stop_parameter
;
1166 return unwind_phase2_forced(&uc
, &cursor
, exception_object
, stop
,
1170 /// Called by personality handler during phase 2 to find the start of the
1172 _LIBUNWIND_EXPORT
uintptr_t
1173 _Unwind_GetRegionStart(struct _Unwind_Context
*context
) {
1174 unw_cursor_t
*cursor
= (unw_cursor_t
*)context
;
1175 unw_proc_info_t frameInfo
;
1176 uintptr_t result
= 0;
1177 if (__unw_get_proc_info(cursor
, &frameInfo
) == UNW_ESUCCESS
)
1178 result
= (uintptr_t)frameInfo
.start_ip
;
1179 _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%llX",
1180 static_cast<void *>(context
), (long long)result
);
1185 /// Called by personality handler during phase 2 if a foreign exception
1187 _LIBUNWIND_EXPORT
void
1188 _Unwind_DeleteException(_Unwind_Exception
*exception_object
) {
1189 _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)",
1190 static_cast<void *>(exception_object
));
1191 if (exception_object
->exception_cleanup
!= NULL
)
1192 (*exception_object
->exception_cleanup
)(_URC_FOREIGN_EXCEPTION_CAUGHT
,
1196 extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code
1197 __gnu_unwind_frame(_Unwind_Exception
*exception_object
,
1198 struct _Unwind_Context
*context
) {
1199 (void)exception_object
;
1200 unw_cursor_t
*cursor
= (unw_cursor_t
*)context
;
1201 switch (__unw_step(cursor
)) {
1202 case UNW_STEP_SUCCESS
:
1205 return _URC_END_OF_STACK
;
1207 return _URC_FAILURE
;
1211 #endif // defined(_LIBUNWIND_ARM_EHABI)