1 //===--------------------------- Unwind-EHABI.cpp -------------------------===//
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 #ifdef __LITTLE_ENDIAN__
35 return byteData
[(offset
& ~(size_t)0x03) + (3 - (offset
& (size_t)0x03))];
37 return byteData
[offset
];
41 const char* getNextWord(const char* data
, uint32_t* out
) {
42 *out
= *reinterpret_cast<const uint32_t*>(data
);
46 const char* getNextNibble(const char* data
, uint32_t* out
) {
47 *out
= *reinterpret_cast<const uint16_t*>(data
);
54 SU16
= 0, // Short descriptor, 16-bit entries
55 LU16
= 1, // Long descriptor, 16-bit entries
56 LU32
= 3, // Long descriptor, 32-bit entries
57 RESERVED0
= 4, RESERVED1
= 5, RESERVED2
= 6, RESERVED3
= 7,
58 RESERVED4
= 8, RESERVED5
= 9, RESERVED6
= 10, RESERVED7
= 11,
59 RESERVED8
= 12, RESERVED9
= 13, RESERVED10
= 14, RESERVED11
= 15
71 _Unwind_Reason_Code
ProcessDescriptors(
73 _Unwind_Control_Block
* ucbp
,
74 struct _Unwind_Context
* context
,
75 Descriptor::Format format
,
76 const char* descriptorStart
,
79 // EHT is inlined in the index using compact form. No descriptors. #5
81 return _URC_CONTINUE_UNWIND
;
83 // TODO: We should check the state here, and determine whether we need to
84 // perform phase1 or phase2 unwinding.
87 const char* descriptor
= descriptorStart
;
88 uint32_t descriptorWord
;
89 getNextWord(descriptor
, &descriptorWord
);
90 while (descriptorWord
) {
91 // Read descriptor based on # 9.2.
95 case Descriptor::LU32
:
96 descriptor
= getNextWord(descriptor
, &length
);
97 descriptor
= getNextWord(descriptor
, &offset
);
98 case Descriptor::LU16
:
99 descriptor
= getNextNibble(descriptor
, &length
);
100 descriptor
= getNextNibble(descriptor
, &offset
);
106 // See # 9.2 table for decoding the kind of descriptor. It's a 2-bit value.
107 Descriptor::Kind kind
=
108 static_cast<Descriptor::Kind
>((length
& 0x1) | ((offset
& 0x1) << 1));
110 // Clear off flag from last bit.
113 uintptr_t scopeStart
= ucbp
->pr_cache
.fnstart
+ offset
;
114 uintptr_t scopeEnd
= scopeStart
+ length
;
115 uintptr_t pc
= _Unwind_GetIP(context
);
116 bool isInScope
= (scopeStart
<= pc
) && (pc
< scopeEnd
);
119 case Descriptor::CLEANUP
: {
120 // TODO(ajwong): Handle cleanup descriptors.
123 case Descriptor::FUNC
: {
124 // TODO(ajwong): Handle function descriptors.
127 case Descriptor::CATCH
: {
128 // Catch descriptors require gobbling one more word.
129 uint32_t landing_pad
;
130 descriptor
= getNextWord(descriptor
, &landing_pad
);
133 // TODO(ajwong): This is only phase1 compatible logic. Implement
135 landing_pad
= signExtendPrel31(landing_pad
& ~0x80000000);
136 if (landing_pad
== 0xffffffff) {
137 return _URC_HANDLER_FOUND
;
138 } else if (landing_pad
== 0xfffffffe) {
142 bool is_reference_type = landing_pad & 0x80000000;
143 void* matched_object;
144 if (__cxxabiv1::__cxa_type_match(
145 ucbp, reinterpret_cast<const std::type_info *>(landing_pad),
147 &matched_object) != __cxxabiv1::ctm_failed)
148 return _URC_HANDLER_FOUND;
150 _LIBUNWIND_ABORT("Type matching not implemented");
156 _LIBUNWIND_ABORT("Invalid descriptor kind found.");
159 getNextWord(descriptor
, &descriptorWord
);
162 return _URC_CONTINUE_UNWIND
;
165 static _Unwind_Reason_Code
unwindOneFrame(_Unwind_State state
,
166 _Unwind_Control_Block
* ucbp
,
167 struct _Unwind_Context
* context
) {
168 // Read the compact model EHT entry's header # 6.3
169 const uint32_t* unwindingData
= ucbp
->pr_cache
.ehtp
;
170 assert((*unwindingData
& 0xf0000000) == 0x80000000 && "Must be a compact entry");
171 Descriptor::Format format
=
172 static_cast<Descriptor::Format
>((*unwindingData
& 0x0f000000) >> 24);
175 reinterpret_cast<const char *>(_Unwind_GetLanguageSpecificData(context
));
177 // Handle descriptors before unwinding so they are processed in the context
178 // of the correct stack frame.
179 _Unwind_Reason_Code result
=
180 ProcessDescriptors(state
, ucbp
, context
, format
, lsda
,
181 ucbp
->pr_cache
.additional
);
183 if (result
!= _URC_CONTINUE_UNWIND
)
186 if (__unw_step(reinterpret_cast<unw_cursor_t
*>(context
)) != UNW_STEP_SUCCESS
)
188 return _URC_CONTINUE_UNWIND
;
191 // Generates mask discriminator for _Unwind_VRS_Pop, e.g. for _UVRSC_CORE /
193 uint32_t RegisterMask(uint8_t start
, uint8_t count_minus_one
) {
194 return ((1U << (count_minus_one
+ 1)) - 1) << start
;
197 // Generates mask discriminator for _Unwind_VRS_Pop, e.g. for _UVRSC_VFP /
199 uint32_t RegisterRange(uint8_t start
, uint8_t count_minus_one
) {
200 return ((uint32_t)start
<< 16) | ((uint32_t)count_minus_one
+ 1);
203 } // end anonymous namespace
206 * Decodes an EHT entry.
208 * @param data Pointer to EHT.
209 * @param[out] off Offset from return value (in bytes) to begin interpretation.
210 * @param[out] len Number of bytes in unwind code.
211 * @return Pointer to beginning of unwind code.
213 extern "C" const uint32_t*
214 decode_eht_entry(const uint32_t* data
, size_t* off
, size_t* len
) {
215 if ((*data
& 0x80000000) == 0) {
216 // 6.2: Generic Model
218 // EHT entry is a prel31 pointing to the PR, followed by data understood
219 // only by the personality routine. Fortunately, all existing assembler
220 // implementations, including GNU assembler, LLVM integrated assembler,
221 // and ARM assembler, assume that the unwind opcodes come after the
222 // personality rountine address.
223 *off
= 1; // First byte is size data.
224 *len
= (((data
[1] >> 24) & 0xff) + 1) * 4;
225 data
++; // Skip the first word, which is the prel31 offset.
227 // 6.3: ARM Compact Model
229 // EHT entries here correspond to the __aeabi_unwind_cpp_pr[012] PRs indeded
231 Descriptor::Format format
=
232 static_cast<Descriptor::Format
>((*data
& 0x0f000000) >> 24);
234 case Descriptor::SU16
:
238 case Descriptor::LU16
:
239 case Descriptor::LU32
:
240 *len
= 4 + 4 * ((*data
& 0x00ff0000) >> 16);
250 _LIBUNWIND_EXPORT _Unwind_Reason_Code
251 _Unwind_VRS_Interpret(_Unwind_Context
*context
, const uint32_t *data
,
252 size_t offset
, size_t len
) {
253 bool wrotePC
= false;
255 while (offset
< len
&& !finish
) {
256 uint8_t byte
= getByte(data
, offset
++);
257 if ((byte
& 0x80) == 0) {
259 _Unwind_VRS_Get(context
, _UVRSC_CORE
, UNW_ARM_SP
, _UVRSD_UINT32
, &sp
);
261 sp
-= (((uint32_t)byte
& 0x3f) << 2) + 4;
263 sp
+= ((uint32_t)byte
<< 2) + 4;
264 _Unwind_VRS_Set(context
, _UVRSC_CORE
, UNW_ARM_SP
, _UVRSD_UINT32
, &sp
);
266 switch (byte
& 0xf0) {
271 (((uint32_t)byte
& 0x0f) << 12) |
272 (((uint32_t)getByte(data
, offset
++)) << 4);
275 if (registers
& (1 << 15))
277 _Unwind_VRS_Pop(context
, _UVRSC_CORE
, registers
, _UVRSD_UINT32
);
281 uint8_t reg
= byte
& 0x0f;
282 if (reg
== 13 || reg
== 15)
285 _Unwind_VRS_Get(context
, _UVRSC_CORE
, UNW_ARM_R0
+ reg
,
287 _Unwind_VRS_Set(context
, _UVRSC_CORE
, UNW_ARM_SP
, _UVRSD_UINT32
,
292 uint32_t registers
= RegisterMask(4, byte
& 0x07);
294 registers
|= 1 << 14;
295 _Unwind_VRS_Pop(context
, _UVRSC_CORE
, registers
, _UVRSD_UINT32
);
306 uint8_t registers
= getByte(data
, offset
++);
307 if (registers
& 0xf0 || !registers
)
309 _Unwind_VRS_Pop(context
, _UVRSC_CORE
, registers
, _UVRSD_UINT32
);
315 // This decodes a uleb128 value.
319 uint32_t v
= getByte(data
, offset
++);
320 addend
|= (v
& 0x7f) << shift
;
326 _Unwind_VRS_Get(context
, _UVRSC_CORE
, UNW_ARM_SP
, _UVRSD_UINT32
,
328 sp
+= 0x204 + (addend
<< 2);
329 _Unwind_VRS_Set(context
, _UVRSC_CORE
, UNW_ARM_SP
, _UVRSD_UINT32
,
334 uint8_t v
= getByte(data
, offset
++);
335 _Unwind_VRS_Pop(context
, _UVRSC_VFP
,
336 RegisterRange(static_cast<uint8_t>(v
>> 4),
337 v
& 0x0f), _UVRSD_VFPX
);
346 _Unwind_VRS_Pop(context
, _UVRSC_VFP
,
347 RegisterRange(8, byte
& 0x07), _UVRSD_VFPX
);
354 #if defined(__ARM_WMMX)
361 _Unwind_VRS_Pop(context
, _UVRSC_WMMXD
,
362 RegisterRange(10, byte
& 0x7), _UVRSD_DOUBLE
);
365 uint8_t v
= getByte(data
, offset
++);
366 uint8_t start
= static_cast<uint8_t>(v
>> 4);
367 uint8_t count_minus_one
= v
& 0xf;
368 if (start
+ count_minus_one
>= 16)
370 _Unwind_VRS_Pop(context
, _UVRSC_WMMXD
,
371 RegisterRange(start
, count_minus_one
),
376 uint8_t v
= getByte(data
, offset
++);
379 _Unwind_VRS_Pop(context
, _UVRSC_WMMXC
, v
, _UVRSD_DOUBLE
);
385 uint8_t v
= getByte(data
, offset
++);
387 static_cast<uint8_t>(((byte
== 0xc8) ? 16 : 0) + (v
>> 4));
388 uint8_t count_minus_one
= v
& 0xf;
389 if (start
+ count_minus_one
>= 32)
391 _Unwind_VRS_Pop(context
, _UVRSC_VFP
,
392 RegisterRange(start
, count_minus_one
),
404 _Unwind_VRS_Pop(context
, _UVRSC_VFP
, RegisterRange(8, byte
& 0x7),
415 _Unwind_VRS_Get(context
, _UVRSC_CORE
, UNW_ARM_LR
, _UVRSD_UINT32
, &lr
);
416 _Unwind_VRS_Set(context
, _UVRSC_CORE
, UNW_ARM_IP
, _UVRSD_UINT32
, &lr
);
418 return _URC_CONTINUE_UNWIND
;
421 extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code
422 __aeabi_unwind_cpp_pr0(_Unwind_State state
, _Unwind_Control_Block
*ucbp
,
423 _Unwind_Context
*context
) {
424 return unwindOneFrame(state
, ucbp
, context
);
427 extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code
428 __aeabi_unwind_cpp_pr1(_Unwind_State state
, _Unwind_Control_Block
*ucbp
,
429 _Unwind_Context
*context
) {
430 return unwindOneFrame(state
, ucbp
, context
);
433 extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code
434 __aeabi_unwind_cpp_pr2(_Unwind_State state
, _Unwind_Control_Block
*ucbp
,
435 _Unwind_Context
*context
) {
436 return unwindOneFrame(state
, ucbp
, context
);
439 static _Unwind_Reason_Code
440 unwind_phase1(unw_context_t
*uc
, unw_cursor_t
*cursor
, _Unwind_Exception
*exception_object
) {
441 // EHABI #7.3 discusses preserving the VRS in a "temporary VRS" during
442 // phase 1 and then restoring it to the "primary VRS" for phase 2. The
443 // effect is phase 2 doesn't see any of the VRS manipulations from phase 1.
444 // In this implementation, the phases don't share the VRS backing store.
445 // Instead, they are passed the original |uc| and they create a new VRS
446 // from scratch thus achieving the same effect.
447 __unw_init_local(cursor
, uc
);
449 // Walk each frame looking for a place to stop.
450 for (bool handlerNotFound
= true; handlerNotFound
;) {
452 // See if frame has code to run (has personality routine).
453 unw_proc_info_t frameInfo
;
454 if (__unw_get_proc_info(cursor
, &frameInfo
) != UNW_ESUCCESS
) {
455 _LIBUNWIND_TRACE_UNWINDING(
456 "unwind_phase1(ex_ojb=%p): __unw_get_proc_info "
457 "failed => _URC_FATAL_PHASE1_ERROR",
458 static_cast<void *>(exception_object
));
459 return _URC_FATAL_PHASE1_ERROR
;
462 // When tracing, print state information.
463 if (_LIBUNWIND_TRACING_UNWINDING
) {
464 char functionBuf
[512];
465 const char *functionName
= functionBuf
;
467 if ((__unw_get_proc_name(cursor
, functionBuf
, sizeof(functionBuf
),
468 &offset
) != UNW_ESUCCESS
) ||
469 (frameInfo
.start_ip
+ offset
> frameInfo
.end_ip
))
470 functionName
= ".anonymous.";
472 __unw_get_reg(cursor
, UNW_REG_IP
, &pc
);
473 _LIBUNWIND_TRACE_UNWINDING(
474 "unwind_phase1(ex_ojb=%p): pc=0x%" PRIxPTR
", start_ip=0x%" PRIxPTR
", func=%s, "
475 "lsda=0x%" PRIxPTR
", personality=0x%" PRIxPTR
,
476 static_cast<void *>(exception_object
), pc
,
477 frameInfo
.start_ip
, functionName
,
478 frameInfo
.lsda
, frameInfo
.handler
);
481 // If there is a personality routine, ask it if it will want to stop at
483 if (frameInfo
.handler
!= 0) {
484 __personality_routine p
=
485 (__personality_routine
)(long)(frameInfo
.handler
);
486 _LIBUNWIND_TRACE_UNWINDING(
487 "unwind_phase1(ex_ojb=%p): calling personality function %p",
488 static_cast<void *>(exception_object
),
489 reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(p
)));
490 struct _Unwind_Context
*context
= (struct _Unwind_Context
*)(cursor
);
491 exception_object
->pr_cache
.fnstart
= frameInfo
.start_ip
;
492 exception_object
->pr_cache
.ehtp
=
493 (_Unwind_EHT_Header
*)frameInfo
.unwind_info
;
494 exception_object
->pr_cache
.additional
= frameInfo
.flags
;
495 _Unwind_Reason_Code personalityResult
=
496 (*p
)(_US_VIRTUAL_UNWIND_FRAME
, exception_object
, context
);
497 _LIBUNWIND_TRACE_UNWINDING(
498 "unwind_phase1(ex_ojb=%p): personality result %d start_ip %x ehtp %p "
500 static_cast<void *>(exception_object
), personalityResult
,
501 exception_object
->pr_cache
.fnstart
,
502 static_cast<void *>(exception_object
->pr_cache
.ehtp
),
503 exception_object
->pr_cache
.additional
);
504 switch (personalityResult
) {
505 case _URC_HANDLER_FOUND
:
506 // found a catch clause or locals that need destructing in this frame
507 // stop search and remember stack pointer at the frame
508 handlerNotFound
= false;
509 // p should have initialized barrier_cache. EHABI #7.3.5
510 _LIBUNWIND_TRACE_UNWINDING(
511 "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND",
512 static_cast<void *>(exception_object
));
513 return _URC_NO_REASON
;
515 case _URC_CONTINUE_UNWIND
:
516 _LIBUNWIND_TRACE_UNWINDING(
517 "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND",
518 static_cast<void *>(exception_object
));
519 // continue unwinding
527 // something went wrong
528 _LIBUNWIND_TRACE_UNWINDING(
529 "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR",
530 static_cast<void *>(exception_object
));
531 return _URC_FATAL_PHASE1_ERROR
;
535 return _URC_NO_REASON
;
538 static _Unwind_Reason_Code
unwind_phase2(unw_context_t
*uc
, unw_cursor_t
*cursor
,
539 _Unwind_Exception
*exception_object
,
541 // See comment at the start of unwind_phase1 regarding VRS integrity.
542 __unw_init_local(cursor
, uc
);
544 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)",
545 static_cast<void *>(exception_object
));
548 // Walk each frame until we reach where search phase said to stop.
550 // Ask libunwind to get next frame (skip over first which is
551 // _Unwind_RaiseException or _Unwind_Resume).
553 // Resume only ever makes sense for 1 frame.
554 _Unwind_State state
=
555 resume
? _US_UNWIND_FRAME_RESUME
: _US_UNWIND_FRAME_STARTING
;
556 if (resume
&& frame_count
== 1) {
557 // On a resume, first unwind the _Unwind_Resume() frame. The next frame
558 // is now the landing pad for the cleanup from a previous execution of
559 // phase2. To continue unwindingly correctly, replace VRS[15] with the
560 // IP of the frame that the previous run of phase2 installed the context
561 // for. After this, continue unwinding as if normal.
563 // See #7.4.6 for details.
564 __unw_set_reg(cursor
, UNW_REG_IP
,
565 exception_object
->unwinder_cache
.reserved2
);
569 // Get info about this frame.
571 unw_proc_info_t frameInfo
;
572 __unw_get_reg(cursor
, UNW_REG_SP
, &sp
);
573 if (__unw_get_proc_info(cursor
, &frameInfo
) != UNW_ESUCCESS
) {
574 _LIBUNWIND_TRACE_UNWINDING(
575 "unwind_phase2(ex_ojb=%p): __unw_get_proc_info "
576 "failed => _URC_FATAL_PHASE2_ERROR",
577 static_cast<void *>(exception_object
));
578 return _URC_FATAL_PHASE2_ERROR
;
581 // When tracing, print state information.
582 if (_LIBUNWIND_TRACING_UNWINDING
) {
583 char functionBuf
[512];
584 const char *functionName
= functionBuf
;
586 if ((__unw_get_proc_name(cursor
, functionBuf
, sizeof(functionBuf
),
587 &offset
) != UNW_ESUCCESS
) ||
588 (frameInfo
.start_ip
+ offset
> frameInfo
.end_ip
))
589 functionName
= ".anonymous.";
590 _LIBUNWIND_TRACE_UNWINDING(
591 "unwind_phase2(ex_ojb=%p): start_ip=0x%" PRIxPTR
", func=%s, sp=0x%" PRIxPTR
", "
592 "lsda=0x%" PRIxPTR
", personality=0x%" PRIxPTR
"",
593 static_cast<void *>(exception_object
), frameInfo
.start_ip
,
594 functionName
, sp
, frameInfo
.lsda
,
598 // If there is a personality routine, tell it we are unwinding.
599 if (frameInfo
.handler
!= 0) {
600 __personality_routine p
=
601 (__personality_routine
)(long)(frameInfo
.handler
);
602 struct _Unwind_Context
*context
= (struct _Unwind_Context
*)(cursor
);
604 exception_object
->pr_cache
.fnstart
= frameInfo
.start_ip
;
605 exception_object
->pr_cache
.ehtp
=
606 (_Unwind_EHT_Header
*)frameInfo
.unwind_info
;
607 exception_object
->pr_cache
.additional
= frameInfo
.flags
;
608 _Unwind_Reason_Code personalityResult
=
609 (*p
)(state
, exception_object
, context
);
610 switch (personalityResult
) {
611 case _URC_CONTINUE_UNWIND
:
612 // Continue unwinding
613 _LIBUNWIND_TRACE_UNWINDING(
614 "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND",
615 static_cast<void *>(exception_object
));
617 if (sp
== exception_object
->barrier_cache
.sp
) {
618 // Phase 1 said we would stop at this frame, but we did not...
619 _LIBUNWIND_ABORT("during phase1 personality function said it would "
620 "stop here, but now in phase2 it did not stop here");
623 case _URC_INSTALL_CONTEXT
:
624 _LIBUNWIND_TRACE_UNWINDING(
625 "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT",
626 static_cast<void *>(exception_object
));
627 // Personality routine says to transfer control to landing pad.
628 // We may get control back if landing pad calls _Unwind_Resume().
629 if (_LIBUNWIND_TRACING_UNWINDING
) {
631 __unw_get_reg(cursor
, UNW_REG_IP
, &pc
);
632 __unw_get_reg(cursor
, UNW_REG_SP
, &sp
);
633 _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
634 "user code with ip=0x%" PRIxPTR
", sp=0x%" PRIxPTR
,
635 static_cast<void *>(exception_object
),
640 // EHABI #7.4.1 says we need to preserve pc for when _Unwind_Resume
641 // is called back, to find this same frame.
643 __unw_get_reg(cursor
, UNW_REG_IP
, &pc
);
644 exception_object
->unwinder_cache
.reserved2
= (uint32_t)pc
;
646 __unw_resume(cursor
);
647 // __unw_resume() only returns if there was an error.
648 return _URC_FATAL_PHASE2_ERROR
;
655 // Personality routine returned an unknown result code.
656 _LIBUNWIND_DEBUG_LOG("personality function returned unknown result %d",
658 return _URC_FATAL_PHASE2_ERROR
;
664 // Clean up phase did not resume at the frame that the search phase
666 return _URC_FATAL_PHASE2_ERROR
;
669 /// Called by __cxa_throw. Only returns if there is a fatal error.
670 _LIBUNWIND_EXPORT _Unwind_Reason_Code
671 _Unwind_RaiseException(_Unwind_Exception
*exception_object
) {
672 _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)",
673 static_cast<void *>(exception_object
));
676 __unw_getcontext(&uc
);
678 // This field for is for compatibility with GCC to say this isn't a forced
679 // unwind. EHABI #7.2
680 exception_object
->unwinder_cache
.reserved1
= 0;
682 // phase 1: the search phase
683 _Unwind_Reason_Code phase1
= unwind_phase1(&uc
, &cursor
, exception_object
);
684 if (phase1
!= _URC_NO_REASON
)
687 // phase 2: the clean up phase
688 return unwind_phase2(&uc
, &cursor
, exception_object
, false);
691 _LIBUNWIND_EXPORT
void _Unwind_Complete(_Unwind_Exception
* exception_object
) {
692 // This is to be called when exception handling completes to give us a chance
693 // to perform any housekeeping. EHABI #7.2. But we have nothing to do here.
694 (void)exception_object
;
697 /// When _Unwind_RaiseException() is in phase2, it hands control
698 /// to the personality function at each frame. The personality
699 /// may force a jump to a landing pad in that function, the landing
700 /// pad code may then call _Unwind_Resume() to continue with the
701 /// unwinding. Note: the call to _Unwind_Resume() is from compiler
702 /// geneated user code. All other _Unwind_* routines are called
703 /// by the C++ runtime __cxa_* routines.
705 /// Note: re-throwing an exception (as opposed to continuing the unwind)
706 /// is implemented by having the code call __cxa_rethrow() which
707 /// in turn calls _Unwind_Resume_or_Rethrow().
708 _LIBUNWIND_EXPORT
void
709 _Unwind_Resume(_Unwind_Exception
*exception_object
) {
710 _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)",
711 static_cast<void *>(exception_object
));
714 __unw_getcontext(&uc
);
716 // _Unwind_RaiseException on EHABI will always set the reserved1 field to 0,
717 // which is in the same position as private_1 below.
718 // TODO(ajwong): Who wronte the above? Why is it true?
719 unwind_phase2(&uc
, &cursor
, exception_object
, true);
721 // Clients assume _Unwind_Resume() does not return, so all we can do is abort.
722 _LIBUNWIND_ABORT("_Unwind_Resume() can't return");
725 /// Called by personality handler during phase 2 to get LSDA for current frame.
726 _LIBUNWIND_EXPORT
uintptr_t
727 _Unwind_GetLanguageSpecificData(struct _Unwind_Context
*context
) {
728 unw_cursor_t
*cursor
= (unw_cursor_t
*)context
;
729 unw_proc_info_t frameInfo
;
730 uintptr_t result
= 0;
731 if (__unw_get_proc_info(cursor
, &frameInfo
) == UNW_ESUCCESS
)
732 result
= (uintptr_t)frameInfo
.lsda
;
733 _LIBUNWIND_TRACE_API(
734 "_Unwind_GetLanguageSpecificData(context=%p) => 0x%llx",
735 static_cast<void *>(context
), (long long)result
);
739 static uint64_t ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation
,
742 switch (representation
) {
745 memcpy(&value
, valuep
, sizeof(uint32_t));
751 memcpy(&value
, valuep
, sizeof(uint64_t));
757 _LIBUNWIND_EXPORT _Unwind_VRS_Result
758 _Unwind_VRS_Set(_Unwind_Context
*context
, _Unwind_VRS_RegClass regclass
,
759 uint32_t regno
, _Unwind_VRS_DataRepresentation representation
,
761 _LIBUNWIND_TRACE_API("_Unwind_VRS_Set(context=%p, regclass=%d, reg=%d, "
762 "rep=%d, value=0x%llX)",
763 static_cast<void *>(context
), regclass
, regno
,
765 ValueAsBitPattern(representation
, valuep
));
766 unw_cursor_t
*cursor
= (unw_cursor_t
*)context
;
769 if (representation
!= _UVRSD_UINT32
|| regno
> 15)
770 return _UVRSR_FAILED
;
771 return __unw_set_reg(cursor
, (unw_regnum_t
)(UNW_ARM_R0
+ regno
),
772 *(unw_word_t
*)valuep
) == UNW_ESUCCESS
776 if (representation
!= _UVRSD_VFPX
&& representation
!= _UVRSD_DOUBLE
)
777 return _UVRSR_FAILED
;
778 if (representation
== _UVRSD_VFPX
) {
779 // Can only touch d0-15 with FSTMFDX.
781 return _UVRSR_FAILED
;
782 __unw_save_vfp_as_X(cursor
);
785 return _UVRSR_FAILED
;
787 return __unw_set_fpreg(cursor
, (unw_regnum_t
)(UNW_ARM_D0
+ regno
),
788 *(unw_fpreg_t
*)valuep
) == UNW_ESUCCESS
791 #if defined(__ARM_WMMX)
793 if (representation
!= _UVRSD_UINT32
|| regno
> 3)
794 return _UVRSR_FAILED
;
795 return __unw_set_reg(cursor
, (unw_regnum_t
)(UNW_ARM_WC0
+ regno
),
796 *(unw_word_t
*)valuep
) == UNW_ESUCCESS
800 if (representation
!= _UVRSD_DOUBLE
|| regno
> 31)
801 return _UVRSR_FAILED
;
802 return __unw_set_fpreg(cursor
, (unw_regnum_t
)(UNW_ARM_WR0
+ regno
),
803 *(unw_fpreg_t
*)valuep
) == UNW_ESUCCESS
812 _LIBUNWIND_ABORT("unsupported register class");
815 static _Unwind_VRS_Result
816 _Unwind_VRS_Get_Internal(_Unwind_Context
*context
,
817 _Unwind_VRS_RegClass regclass
, uint32_t regno
,
818 _Unwind_VRS_DataRepresentation representation
,
820 unw_cursor_t
*cursor
= (unw_cursor_t
*)context
;
823 if (representation
!= _UVRSD_UINT32
|| regno
> 15)
824 return _UVRSR_FAILED
;
825 return __unw_get_reg(cursor
, (unw_regnum_t
)(UNW_ARM_R0
+ regno
),
826 (unw_word_t
*)valuep
) == UNW_ESUCCESS
830 if (representation
!= _UVRSD_VFPX
&& representation
!= _UVRSD_DOUBLE
)
831 return _UVRSR_FAILED
;
832 if (representation
== _UVRSD_VFPX
) {
833 // Can only touch d0-15 with FSTMFDX.
835 return _UVRSR_FAILED
;
836 __unw_save_vfp_as_X(cursor
);
839 return _UVRSR_FAILED
;
841 return __unw_get_fpreg(cursor
, (unw_regnum_t
)(UNW_ARM_D0
+ regno
),
842 (unw_fpreg_t
*)valuep
) == UNW_ESUCCESS
845 #if defined(__ARM_WMMX)
847 if (representation
!= _UVRSD_UINT32
|| regno
> 3)
848 return _UVRSR_FAILED
;
849 return __unw_get_reg(cursor
, (unw_regnum_t
)(UNW_ARM_WC0
+ regno
),
850 (unw_word_t
*)valuep
) == UNW_ESUCCESS
854 if (representation
!= _UVRSD_DOUBLE
|| regno
> 31)
855 return _UVRSR_FAILED
;
856 return __unw_get_fpreg(cursor
, (unw_regnum_t
)(UNW_ARM_WR0
+ regno
),
857 (unw_fpreg_t
*)valuep
) == UNW_ESUCCESS
866 _LIBUNWIND_ABORT("unsupported register class");
869 _LIBUNWIND_EXPORT _Unwind_VRS_Result
870 _Unwind_VRS_Get(_Unwind_Context
*context
, _Unwind_VRS_RegClass regclass
,
871 uint32_t regno
, _Unwind_VRS_DataRepresentation representation
,
873 _Unwind_VRS_Result result
=
874 _Unwind_VRS_Get_Internal(context
, regclass
, regno
, representation
,
876 _LIBUNWIND_TRACE_API("_Unwind_VRS_Get(context=%p, regclass=%d, reg=%d, "
877 "rep=%d, value=0x%llX, result = %d)",
878 static_cast<void *>(context
), regclass
, regno
,
880 ValueAsBitPattern(representation
, valuep
), result
);
885 _Unwind_VRS_Pop(_Unwind_Context
*context
, _Unwind_VRS_RegClass regclass
,
886 uint32_t discriminator
,
887 _Unwind_VRS_DataRepresentation representation
) {
888 _LIBUNWIND_TRACE_API("_Unwind_VRS_Pop(context=%p, regclass=%d, "
889 "discriminator=%d, representation=%d)",
890 static_cast<void *>(context
), regclass
, discriminator
,
894 #if !defined(__ARM_WMMX)
898 if (representation
!= _UVRSD_UINT32
)
899 return _UVRSR_FAILED
;
900 // When popping SP from the stack, we don't want to override it from the
901 // computed new stack location. See EHABI #7.5.4 table 3.
902 bool poppedSP
= false;
904 if (_Unwind_VRS_Get(context
, _UVRSC_CORE
, UNW_ARM_SP
,
905 _UVRSD_UINT32
, &sp
) != _UVRSR_OK
) {
906 return _UVRSR_FAILED
;
908 for (uint32_t i
= 0; i
< 16; ++i
) {
909 if (!(discriminator
& static_cast<uint32_t>(1 << i
)))
911 uint32_t value
= *sp
++;
912 if (regclass
== _UVRSC_CORE
&& i
== 13)
914 if (_Unwind_VRS_Set(context
, regclass
, i
,
915 _UVRSD_UINT32
, &value
) != _UVRSR_OK
) {
916 return _UVRSR_FAILED
;
920 return _Unwind_VRS_Set(context
, _UVRSC_CORE
, UNW_ARM_SP
,
926 #if !defined(__ARM_WMMX)
930 if (representation
!= _UVRSD_VFPX
&& representation
!= _UVRSD_DOUBLE
)
931 return _UVRSR_FAILED
;
932 uint32_t first
= discriminator
>> 16;
933 uint32_t count
= discriminator
& 0xffff;
934 uint32_t end
= first
+count
;
936 if (_Unwind_VRS_Get(context
, _UVRSC_CORE
, UNW_ARM_SP
,
937 _UVRSD_UINT32
, &sp
) != _UVRSR_OK
) {
938 return _UVRSR_FAILED
;
940 // For _UVRSD_VFPX, we're assuming the data is stored in FSTMX "standard
941 // format 1", which is equivalent to FSTMD + a padding word.
942 for (uint32_t i
= first
; i
< end
; ++i
) {
943 // SP is only 32-bit aligned so don't copy 64-bit at a time.
946 #ifdef __LITTLE_ENDIAN__
947 uint64_t value
= (w1
<< 32) | w0
;
949 uint64_t value
= (w0
<< 32) | w1
;
951 if (_Unwind_VRS_Set(context
, regclass
, i
, representation
, &value
) !=
953 return _UVRSR_FAILED
;
955 if (representation
== _UVRSD_VFPX
)
957 return _Unwind_VRS_Set(context
, _UVRSC_CORE
, UNW_ARM_SP
, _UVRSD_UINT32
,
961 _LIBUNWIND_ABORT("unsupported register class");
964 /// Called by personality handler during phase 2 to find the start of the
966 _LIBUNWIND_EXPORT
uintptr_t
967 _Unwind_GetRegionStart(struct _Unwind_Context
*context
) {
968 unw_cursor_t
*cursor
= (unw_cursor_t
*)context
;
969 unw_proc_info_t frameInfo
;
970 uintptr_t result
= 0;
971 if (__unw_get_proc_info(cursor
, &frameInfo
) == UNW_ESUCCESS
)
972 result
= (uintptr_t)frameInfo
.start_ip
;
973 _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%llX",
974 static_cast<void *>(context
), (long long)result
);
979 /// Called by personality handler during phase 2 if a foreign exception
981 _LIBUNWIND_EXPORT
void
982 _Unwind_DeleteException(_Unwind_Exception
*exception_object
) {
983 _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)",
984 static_cast<void *>(exception_object
));
985 if (exception_object
->exception_cleanup
!= NULL
)
986 (*exception_object
->exception_cleanup
)(_URC_FOREIGN_EXCEPTION_CAUGHT
,
990 extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code
991 __gnu_unwind_frame(_Unwind_Exception
*exception_object
,
992 struct _Unwind_Context
*context
) {
993 unw_cursor_t
*cursor
= (unw_cursor_t
*)context
;
994 if (__unw_step(cursor
) != UNW_STEP_SUCCESS
)
999 #endif // defined(_LIBUNWIND_ARM_EHABI)