1151497Sru//===----------------------------------------------------------------------===//
2151497Sru//
3151497Sru// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4151497Sru// See https://llvm.org/LICENSE.txt for license information.
5151497Sru// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6151497Sru//
7151497Sru//
8151497Sru//  Implements ARM zero-cost C++ exceptions
9151497Sru//
10151497Sru//===----------------------------------------------------------------------===//
11151497Sru
12151497Sru#include "Unwind-EHABI.h"
13151497Sru
14151497Sru#if defined(_LIBUNWIND_ARM_EHABI)
15151497Sru
16151497Sru#include <inttypes.h>
17151497Sru#include <stdbool.h>
18151497Sru#include <stdint.h>
19151497Sru#include <stdio.h>
20151497Sru#include <stdlib.h>
21151497Sru#include <string.h>
22151497Sru
23151497Sru#include "config.h"
24151497Sru#include "libunwind.h"
25151497Sru#include "libunwind_ext.h"
26151497Sru#include "unwind.h"
27151497Sru
28151497Srunamespace {
29151497Sru
30151497Sru// Strange order: take words in order, but inside word, take from most to least
31151497Sru// signinficant byte.
32151497Sruuint8_t getByte(const uint32_t* data, size_t offset) {
33151497Sru  const uint8_t* byteData = reinterpret_cast<const uint8_t*>(data);
34151497Sru#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
35151497Sru  return byteData[(offset & ~(size_t)0x03) + (3 - (offset & (size_t)0x03))];
36151497Sru#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
37151497Sru  return byteData[offset];
38151497Sru#else
39151497Sru#error "Unable to determine endianess"
40151497Sru#endif
41151497Sru}
42151497Sru
43151497Sruconst char* getNextWord(const char* data, uint32_t* out) {
44151497Sru  *out = *reinterpret_cast<const uint32_t*>(data);
45151497Sru  return data + 4;
46151497Sru}
47
48const char* getNextNibble(const char* data, uint32_t* out) {
49  *out = *reinterpret_cast<const uint16_t*>(data);
50  return data + 2;
51}
52
53struct Descriptor {
54  // See # 9.2
55  typedef enum {
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
62  } Format;
63
64  // See # 9.2
65  typedef enum {
66    CLEANUP = 0x0,
67    FUNC    = 0x1,
68    CATCH   = 0x2,
69    INVALID = 0x4
70  } Kind;
71};
72
73_Unwind_Reason_Code ProcessDescriptors(
74    _Unwind_State state,
75    _Unwind_Control_Block* ucbp,
76    struct _Unwind_Context* context,
77    Descriptor::Format format,
78    const char* descriptorStart,
79    uint32_t flags) {
80
81  // EHT is inlined in the index using compact form. No descriptors. #5
82  if (flags & 0x1)
83    return _URC_CONTINUE_UNWIND;
84
85  // TODO: We should check the state here, and determine whether we need to
86  // perform phase1 or phase2 unwinding.
87  (void)state;
88
89  const char* descriptor = descriptorStart;
90  uint32_t descriptorWord;
91  getNextWord(descriptor, &descriptorWord);
92  while (descriptorWord) {
93    // Read descriptor based on # 9.2.
94    uint32_t length;
95    uint32_t offset;
96    switch (format) {
97      case Descriptor::LU32:
98        descriptor = getNextWord(descriptor, &length);
99        descriptor = getNextWord(descriptor, &offset);
100        break;
101      case Descriptor::LU16:
102        descriptor = getNextNibble(descriptor, &length);
103        descriptor = getNextNibble(descriptor, &offset);
104        break;
105      default:
106        assert(false);
107        return _URC_FAILURE;
108    }
109
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));
113
114    // Clear off flag from last bit.
115    length &= ~1u;
116    offset &= ~1u;
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);
121
122    switch (kind) {
123      case Descriptor::CLEANUP: {
124        // TODO(ajwong): Handle cleanup descriptors.
125        break;
126      }
127      case Descriptor::FUNC: {
128        // TODO(ajwong): Handle function descriptors.
129        break;
130      }
131      case Descriptor::CATCH: {
132        // Catch descriptors require gobbling one more word.
133        uint32_t landing_pad;
134        descriptor = getNextWord(descriptor, &landing_pad);
135
136        if (isInScope) {
137          // TODO(ajwong): This is only phase1 compatible logic. Implement
138          // phase2.
139          landing_pad = signExtendPrel31(landing_pad & ~0x80000000);
140          if (landing_pad == 0xffffffff) {
141            return _URC_HANDLER_FOUND;
142          } else if (landing_pad == 0xfffffffe) {
143            return _URC_FAILURE;
144          } else {
145            /*
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),
150                    is_reference_type,
151                    &matched_object) != __cxxabiv1::ctm_failed)
152                return _URC_HANDLER_FOUND;
153                */
154            _LIBUNWIND_ABORT("Type matching not implemented");
155          }
156        }
157        break;
158      }
159      default:
160        _LIBUNWIND_ABORT("Invalid descriptor kind found.");
161    }
162
163    getNextWord(descriptor, &descriptorWord);
164  }
165
166  return _URC_CONTINUE_UNWIND;
167}
168
169static _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);
177
178  const char *lsda =
179      reinterpret_cast<const char *>(_Unwind_GetLanguageSpecificData(context));
180
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);
186
187  if (result != _URC_CONTINUE_UNWIND)
188    return result;
189
190  switch (__unw_step(reinterpret_cast<unw_cursor_t *>(context))) {
191  case UNW_STEP_SUCCESS:
192    return _URC_CONTINUE_UNWIND;
193  case UNW_STEP_END:
194    return _URC_END_OF_STACK;
195  default:
196    return _URC_FAILURE;
197  }
198}
199
200// Generates mask discriminator for _Unwind_VRS_Pop, e.g. for _UVRSC_CORE /
201// _UVRSD_UINT32.
202uint32_t RegisterMask(uint8_t start, uint8_t count_minus_one) {
203  return ((1U << (count_minus_one + 1)) - 1) << start;
204}
205
206// Generates mask discriminator for _Unwind_VRS_Pop, e.g. for _UVRSC_VFP /
207// _UVRSD_DOUBLE.
208uint32_t RegisterRange(uint8_t start, uint8_t count_minus_one) {
209  return ((uint32_t)start << 16) | ((uint32_t)count_minus_one + 1);
210}
211
212} // end anonymous namespace
213
214/**
215 * Decodes an EHT entry.
216 *
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.
221 */
222extern "C" const uint32_t*
223decode_eht_entry(const uint32_t* data, size_t* off, size_t* len) {
224  if ((*data & 0x80000000) == 0) {
225    // 6.2: Generic Model
226    //
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.
235  } else {
236    // 6.3: ARM Compact Model
237    //
238    // EHT entries here correspond to the __aeabi_unwind_cpp_pr[012] PRs indeed
239    // by format:
240    Descriptor::Format format =
241        static_cast<Descriptor::Format>((*data & 0x0f000000) >> 24);
242    switch (format) {
243      case Descriptor::SU16:
244        *len = 4;
245        *off = 1;
246        break;
247      case Descriptor::LU16:
248      case Descriptor::LU32:
249        *len = 4 + 4 * ((*data & 0x00ff0000) >> 16);
250        *off = 2;
251        break;
252      default:
253        return nullptr;
254    }
255  }
256  return data;
257}
258
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;
263  bool finish = false;
264  bool hasReturnAddrAuthCode = false;
265  while (offset < len && !finish) {
266    uint8_t byte = getByte(data, offset++);
267    if ((byte & 0x80) == 0) {
268      uint32_t sp;
269      _Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp);
270      if (byte & 0x40)
271        sp -= (((uint32_t)byte & 0x3f) << 2) + 4;
272      else
273        sp += ((uint32_t)byte << 2) + 4;
274      _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp);
275    } else {
276      switch (byte & 0xf0) {
277        case 0x80: {
278          if (offset >= len)
279            return _URC_FAILURE;
280          uint32_t registers =
281              (((uint32_t)byte & 0x0f) << 12) |
282              (((uint32_t)getByte(data, offset++)) << 4);
283          if (!registers)
284            return _URC_FAILURE;
285          if (registers & (1 << 15))
286            wrotePC = true;
287          _Unwind_VRS_Pop(context, _UVRSC_CORE, registers, _UVRSD_UINT32);
288          break;
289        }
290        case 0x90: {
291          uint8_t reg = byte & 0x0f;
292          if (reg == 13 || reg == 15)
293            return _URC_FAILURE;
294          uint32_t sp;
295          _Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_R0 + reg,
296                          _UVRSD_UINT32, &sp);
297          _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32,
298                          &sp);
299          break;
300        }
301        case 0xa0: {
302          uint32_t registers = RegisterMask(4, byte & 0x07);
303          if (byte & 0x08)
304            registers |= 1 << 14;
305          _Unwind_VRS_Pop(context, _UVRSC_CORE, registers, _UVRSD_UINT32);
306          break;
307        }
308        case 0xb0: {
309          switch (byte) {
310            case 0xb0:
311              finish = true;
312              break;
313            case 0xb1: {
314              if (offset >= len)
315                return _URC_FAILURE;
316              uint8_t registers = getByte(data, offset++);
317              if (registers & 0xf0 || !registers)
318                return _URC_FAILURE;
319              _Unwind_VRS_Pop(context, _UVRSC_CORE, registers, _UVRSD_UINT32);
320              break;
321            }
322            case 0xb2: {
323              uint32_t addend = 0;
324              uint32_t shift = 0;
325              // This decodes a uleb128 value.
326              while (true) {
327                if (offset >= len)
328                  return _URC_FAILURE;
329                uint32_t v = getByte(data, offset++);
330                addend |= (v & 0x7f) << shift;
331                if ((v & 0x80) == 0)
332                  break;
333                shift += 7;
334              }
335              uint32_t sp;
336              _Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32,
337                              &sp);
338              sp += 0x204 + (addend << 2);
339              _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32,
340                              &sp);
341              break;
342            }
343            case 0xb3: {
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);
348              break;
349            }
350            case 0xb4:
351              hasReturnAddrAuthCode = true;
352              _Unwind_VRS_Pop(context, _UVRSC_PSEUDO,
353                              0 /* Return Address Auth Code */, _UVRSD_UINT32);
354              break;
355            case 0xb5:
356            case 0xb6:
357            case 0xb7:
358              return _URC_FAILURE;
359            default:
360              _Unwind_VRS_Pop(context, _UVRSC_VFP,
361                              RegisterRange(8, byte & 0x07), _UVRSD_VFPX);
362              break;
363          }
364          break;
365        }
366        case 0xc0: {
367          switch (byte) {
368#if defined(__ARM_WMMX)
369            case 0xc0:
370            case 0xc1:
371            case 0xc2:
372            case 0xc3:
373            case 0xc4:
374            case 0xc5:
375              _Unwind_VRS_Pop(context, _UVRSC_WMMXD,
376                              RegisterRange(10, byte & 0x7), _UVRSD_DOUBLE);
377              break;
378            case 0xc6: {
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)
383                return _URC_FAILURE;
384              _Unwind_VRS_Pop(context, _UVRSC_WMMXD,
385                              RegisterRange(start, count_minus_one),
386                              _UVRSD_DOUBLE);
387              break;
388            }
389            case 0xc7: {
390              uint8_t v = getByte(data, offset++);
391              if (!v || v & 0xf0)
392                return _URC_FAILURE;
393              _Unwind_VRS_Pop(context, _UVRSC_WMMXC, v, _UVRSD_DOUBLE);
394              break;
395            }
396#endif
397            case 0xc8:
398            case 0xc9: {
399              uint8_t v = getByte(data, offset++);
400              uint8_t start =
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)
404                return _URC_FAILURE;
405              _Unwind_VRS_Pop(context, _UVRSC_VFP,
406                              RegisterRange(start, count_minus_one),
407                              _UVRSD_DOUBLE);
408              break;
409            }
410            default:
411              return _URC_FAILURE;
412          }
413          break;
414        }
415        case 0xd0: {
416          if (byte & 0x08)
417            return _URC_FAILURE;
418          _Unwind_VRS_Pop(context, _UVRSC_VFP, RegisterRange(8, byte & 0x7),
419                          _UVRSD_DOUBLE);
420          break;
421        }
422        default:
423          return _URC_FAILURE;
424      }
425    }
426  }
427  if (!wrotePC) {
428    uint32_t lr;
429    _Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_LR, _UVRSD_UINT32, &lr);
430#ifdef __ARM_FEATURE_PAUTH
431    if (hasReturnAddrAuthCode) {
432      uint32_t sp;
433      uint32_t pac;
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) :);
437    }
438#else
439    (void)hasReturnAddrAuthCode;
440#endif
441    _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_IP, _UVRSD_UINT32, &lr);
442  }
443  return _URC_CONTINUE_UNWIND;
444}
445
446extern "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);
450}
451
452extern "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);
456}
457
458extern "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);
462}
463
464static _Unwind_Reason_Code
465unwind_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);
473
474  // Walk each frame looking for a place to stop.
475  for (bool handlerNotFound = true; handlerNotFound;) {
476
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;
485    }
486
487#ifndef NDEBUG
488    // When tracing, print state information.
489    if (_LIBUNWIND_TRACING_UNWINDING) {
490      char functionBuf[512];
491      const char *functionName = functionBuf;
492      unw_word_t offset;
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.";
497      unw_word_t pc;
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);
505    }
506#endif
507
508    // If there is a personality routine, ask it if it will want to stop at
509    // this frame.
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 "
526          "additional %x",
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;
541
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
547        break;
548
549      // EHABI #7.3.3
550      case _URC_FAILURE:
551        return _URC_FAILURE;
552
553      default:
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;
559      }
560    }
561  }
562  return _URC_NO_REASON;
563}
564
565static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor,
566                                         _Unwind_Exception *exception_object,
567                                         bool resume) {
568  // See comment at the start of unwind_phase1 regarding VRS integrity.
569  __unw_init_local(cursor, uc);
570
571  _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)",
572                             static_cast<void *>(exception_object));
573  int frame_count = 0;
574
575  // Walk each frame until we reach where search phase said to stop.
576  while (true) {
577    // Ask libunwind to get next frame (skip over first which is
578    // _Unwind_RaiseException or _Unwind_Resume).
579    //
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.
589      //
590      // See #7.4.6 for details.
591      __unw_set_reg(cursor, UNW_REG_IP,
592                    exception_object->unwinder_cache.reserved2);
593      resume = false;
594    }
595
596    // Get info about this frame.
597    unw_word_t sp;
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;
606    }
607
608#ifndef NDEBUG
609    // When tracing, print state information.
610    if (_LIBUNWIND_TRACING_UNWINDING) {
611      char functionBuf[512];
612      const char *functionName = functionBuf;
613      unw_word_t offset;
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,
623          frameInfo.handler);
624    }
625#endif
626
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);
632      // EHABI #7.2
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));
645        // EHABI #7.2
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");
650        }
651        break;
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) {
659          unw_word_t pc;
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),
665                                     pc, sp);
666        }
667
668        {
669          // EHABI #7.4.1 says we need to preserve pc for when _Unwind_Resume
670          // is called back, to find this same frame.
671          unw_word_t pc;
672          __unw_get_reg(cursor, UNW_REG_IP, &pc);
673          exception_object->unwinder_cache.reserved2 = (uint32_t)pc;
674        }
675        __unw_resume(cursor);
676        // __unw_resume() only returns if there was an error.
677        return _URC_FATAL_PHASE2_ERROR;
678
679      // # EHABI #7.4.3
680      case _URC_FAILURE:
681        abort();
682
683      default:
684        // Personality routine returned an unknown result code.
685        _LIBUNWIND_DEBUG_LOG("personality function returned unknown result %d",
686                      personalityResult);
687        return _URC_FATAL_PHASE2_ERROR;
688      }
689    }
690    frame_count++;
691  }
692
693  // Clean up phase did not resume at the frame that the search phase
694  // said it would...
695  return _URC_FATAL_PHASE2_ERROR;
696}
697
698static _Unwind_Reason_Code
699unwind_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;
716    }
717
718#ifndef NDEBUG
719    // When tracing, print state information.
720    if (_LIBUNWIND_TRACING_UNWINDING) {
721      char functionBuf[512];
722      const char *functionName = functionBuf;
723      unw_word_t offset;
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);
733    }
734#endif
735
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;
750    }
751
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);
757      // EHABI #7.2
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,
764               context);
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
772        break;
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);
780        break;
781      case _URC_END_OF_STACK:
782        _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
783                                   "personality returned "
784                                   "_URC_END_OF_STACK",
785                                   (void *)exception_object);
786        // Personalty routine did the step and it can't step forward.
787        endOfStack = true;
788        break;
789      default:
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;
796      }
797    }
798  }
799
800  // Call stop function one last time and tell it we've reached the end
801  // of the stack.
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);
809
810  // Clean up phase did not resume at the frame that the search phase said it
811  // would.
812  return _URC_FATAL_PHASE2_ERROR;
813}
814
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));
820  unw_context_t uc;
821  unw_cursor_t cursor;
822  __unw_getcontext(&uc);
823
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;
827
828  // phase 1: the search phase
829  _Unwind_Reason_Code phase1 = unwind_phase1(&uc, &cursor, exception_object);
830  if (phase1 != _URC_NO_REASON)
831    return phase1;
832
833  // phase 2: the clean up phase
834  return unwind_phase2(&uc, &cursor, exception_object, false);
835}
836
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;
841}
842
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.
850///
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));
858  unw_context_t uc;
859  unw_cursor_t cursor;
860  __unw_getcontext(&uc);
861
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);
867  else
868    unwind_phase2(&uc, &cursor, exception_object, true);
869
870  // Clients assume _Unwind_Resume() does not return, so all we can do is abort.
871  _LIBUNWIND_ABORT("_Unwind_Resume() can't return");
872}
873
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);
885  return result;
886}
887
888// Only used in _LIBUNWIND_TRACE_API, which is a no-op when assertions are
889// disabled.
890[[gnu::unused]] static uint64_t
891ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation,
892                  const void *valuep) {
893  uint64_t value = 0;
894  switch (representation) {
895    case _UVRSD_UINT32:
896    case _UVRSD_FLOAT:
897      memcpy(&value, valuep, sizeof(uint32_t));
898      break;
899
900    case _UVRSD_VFPX:
901    case _UVRSD_UINT64:
902    case _UVRSD_DOUBLE:
903      memcpy(&value, valuep, sizeof(uint64_t));
904      break;
905  }
906  return value;
907}
908
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,
912                void *valuep) {
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,
916                       representation,
917                       ValueAsBitPattern(representation, valuep));
918  unw_cursor_t *cursor = (unw_cursor_t *)context;
919  switch (regclass) {
920    case _UVRSC_CORE:
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
925                 ? _UVRSR_OK
926                 : _UVRSR_FAILED;
927    case _UVRSC_VFP:
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.
932        if (regno > 15)
933          return _UVRSR_FAILED;
934        __unw_save_vfp_as_X(cursor);
935      } else {
936        if (regno > 31)
937          return _UVRSR_FAILED;
938      }
939      return __unw_set_fpreg(cursor, (unw_regnum_t)(UNW_ARM_D0 + regno),
940                             *(unw_fpreg_t *)valuep) == UNW_ESUCCESS
941                 ? _UVRSR_OK
942                 : _UVRSR_FAILED;
943#if defined(__ARM_WMMX)
944    case _UVRSC_WMMXC:
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
949                 ? _UVRSR_OK
950                 : _UVRSR_FAILED;
951    case _UVRSC_WMMXD:
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
956                 ? _UVRSR_OK
957                 : _UVRSR_FAILED;
958#else
959    case _UVRSC_WMMXC:
960    case _UVRSC_WMMXD:
961      break;
962#endif
963    case _UVRSC_PSEUDO:
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
969                 ? _UVRSR_OK
970                 : _UVRSR_FAILED;
971      break;
972  }
973  _LIBUNWIND_ABORT("unsupported register class");
974}
975
976static _Unwind_VRS_Result
977_Unwind_VRS_Get_Internal(_Unwind_Context *context,
978                         _Unwind_VRS_RegClass regclass, uint32_t regno,
979                         _Unwind_VRS_DataRepresentation representation,
980                         void *valuep) {
981  unw_cursor_t *cursor = (unw_cursor_t *)context;
982  switch (regclass) {
983    case _UVRSC_CORE:
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
988                 ? _UVRSR_OK
989                 : _UVRSR_FAILED;
990    case _UVRSC_VFP:
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.
995        if (regno > 15)
996          return _UVRSR_FAILED;
997        __unw_save_vfp_as_X(cursor);
998      } else {
999        if (regno > 31)
1000          return _UVRSR_FAILED;
1001      }
1002      return __unw_get_fpreg(cursor, (unw_regnum_t)(UNW_ARM_D0 + regno),
1003                             (unw_fpreg_t *)valuep) == UNW_ESUCCESS
1004                 ? _UVRSR_OK
1005                 : _UVRSR_FAILED;
1006#if defined(__ARM_WMMX)
1007    case _UVRSC_WMMXC:
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
1012                 ? _UVRSR_OK
1013                 : _UVRSR_FAILED;
1014    case _UVRSC_WMMXD:
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
1019                 ? _UVRSR_OK
1020                 : _UVRSR_FAILED;
1021#else
1022    case _UVRSC_WMMXC:
1023    case _UVRSC_WMMXD:
1024      break;
1025#endif
1026    case _UVRSC_PSEUDO:
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
1032                 ? _UVRSR_OK
1033                 : _UVRSR_FAILED;
1034      break;
1035  }
1036  _LIBUNWIND_ABORT("unsupported register class");
1037}
1038
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,
1042                void *valuep) {
1043  _Unwind_VRS_Result result =
1044      _Unwind_VRS_Get_Internal(context, regclass, regno, representation,
1045                               valuep);
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,
1049                       representation,
1050                       ValueAsBitPattern(representation, valuep), result);
1051  return result;
1052}
1053
1054_Unwind_VRS_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,
1061                       representation);
1062  switch (regclass) {
1063    case _UVRSC_WMMXC:
1064#if !defined(__ARM_WMMX)
1065      break;
1066#endif
1067    case _UVRSC_CORE: {
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;
1073      uint32_t* sp;
1074      if (_Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP,
1075                          _UVRSD_UINT32, &sp) != _UVRSR_OK) {
1076        return _UVRSR_FAILED;
1077      }
1078      for (uint32_t i = 0; i < 16; ++i) {
1079        if (!(discriminator & static_cast<uint32_t>(1 << i)))
1080          continue;
1081        uint32_t value = *sp++;
1082        if (regclass == _UVRSC_CORE && i == 13)
1083          poppedSP = true;
1084        if (_Unwind_VRS_Set(context, regclass, i,
1085                            _UVRSD_UINT32, &value) != _UVRSR_OK) {
1086          return _UVRSR_FAILED;
1087        }
1088      }
1089      if (!poppedSP) {
1090        return _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP,
1091                               _UVRSD_UINT32, &sp);
1092      }
1093      return _UVRSR_OK;
1094    }
1095    case _UVRSC_WMMXD:
1096#if !defined(__ARM_WMMX)
1097      break;
1098#endif
1099    case _UVRSC_VFP: {
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;
1105      uint32_t* sp;
1106      if (_Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP,
1107                          _UVRSD_UINT32, &sp) != _UVRSR_OK) {
1108        return _UVRSR_FAILED;
1109      }
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;
1120#else
1121#error "Unable to determine endianess"
1122#endif
1123        if (_Unwind_VRS_Set(context, regclass, i, representation, &value) !=
1124            _UVRSR_OK)
1125          return _UVRSR_FAILED;
1126      }
1127      if (representation == _UVRSD_VFPX)
1128        ++sp;
1129      return _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32,
1130                             &sp);
1131    }
1132    case _UVRSC_PSEUDO: {
1133      if (representation != _UVRSD_UINT32 || discriminator != 0)
1134        return _UVRSR_FAILED;
1135      // Return Address Authentication code (PAC) - discriminator 0
1136      uint32_t *sp;
1137      if (_Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32,
1138                          &sp) != _UVRSR_OK) {
1139        return _UVRSR_FAILED;
1140      }
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);
1144    }
1145  }
1146  _LIBUNWIND_ABORT("unsupported register class");
1147}
1148
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);
1157  unw_context_t uc;
1158  unw_cursor_t cursor;
1159  __unw_getcontext(&uc);
1160
1161  // Mark that this is a forced unwind, so _Unwind_Resume() can do
1162  // the right thing.
1163  exception_object->unwinder_cache.reserved1 = (uintptr_t)stop;
1164  exception_object->unwinder_cache.reserved3 = (uintptr_t)stop_parameter;
1165
1166  return unwind_phase2_forced(&uc, &cursor, exception_object, stop,
1167                              stop_parameter);
1168}
1169
1170/// Called by personality handler during phase 2 to find the start of the
1171/// function.
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);
1181  return result;
1182}
1183
1184
1185/// Called by personality handler during phase 2 if a foreign exception
1186// is caught.
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,
1193                                           exception_object);
1194}
1195
1196extern "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:
1203    return _URC_OK;
1204  case UNW_STEP_END:
1205    return _URC_END_OF_STACK;
1206  default:
1207    return _URC_FAILURE;
1208  }
1209}
1210
1211#endif  // defined(_LIBUNWIND_ARM_EHABI)
1212