1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 // 8 // Implements ARM zero-cost C++ exceptions 9 // 10 //===----------------------------------------------------------------------===// 11 12 #include "Unwind-EHABI.h" 13 14 #if defined(_LIBUNWIND_ARM_EHABI) 15 16 #include <inttypes.h> 17 #include <stdbool.h> 18 #include <stdint.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 23 #include "config.h" 24 #include "libunwind.h" 25 #include "libunwind_ext.h" 26 #include "unwind.h" 27 28 namespace { 29 30 // Strange order: take words in order, but inside word, take from most to least 31 // signinficant byte. 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]; 38 #else 39 #error "Unable to determine endianess" 40 #endif 41 } 42 43 const char* getNextWord(const char* data, uint32_t* out) { 44 *out = *reinterpret_cast<const uint32_t*>(data); 45 return data + 4; 46 } 47 48 const char* getNextNibble(const char* data, uint32_t* out) { 49 *out = *reinterpret_cast<const uint16_t*>(data); 50 return data + 2; 51 } 52 53 struct 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 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); 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. 202 uint32_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. 208 uint32_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 */ 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 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 indeded 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 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); 450 } 451 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); 456 } 457 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); 462 } 463 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); 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 565 static _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 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_step " 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 /// geneated 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 static uint64_t ValueAsBitPattern(_Unwind_VRS_DataRepresentation representation, 889 void* valuep) { 890 uint64_t value = 0; 891 switch (representation) { 892 case _UVRSD_UINT32: 893 case _UVRSD_FLOAT: 894 memcpy(&value, valuep, sizeof(uint32_t)); 895 break; 896 897 case _UVRSD_VFPX: 898 case _UVRSD_UINT64: 899 case _UVRSD_DOUBLE: 900 memcpy(&value, valuep, sizeof(uint64_t)); 901 break; 902 } 903 return value; 904 } 905 906 _LIBUNWIND_EXPORT _Unwind_VRS_Result 907 _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, 908 uint32_t regno, _Unwind_VRS_DataRepresentation representation, 909 void *valuep) { 910 _LIBUNWIND_TRACE_API("_Unwind_VRS_Set(context=%p, regclass=%d, reg=%d, " 911 "rep=%d, value=0x%llX)", 912 static_cast<void *>(context), regclass, regno, 913 representation, 914 ValueAsBitPattern(representation, valuep)); 915 unw_cursor_t *cursor = (unw_cursor_t *)context; 916 switch (regclass) { 917 case _UVRSC_CORE: 918 if (representation != _UVRSD_UINT32 || regno > 15) 919 return _UVRSR_FAILED; 920 return __unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_R0 + regno), 921 *(unw_word_t *)valuep) == UNW_ESUCCESS 922 ? _UVRSR_OK 923 : _UVRSR_FAILED; 924 case _UVRSC_VFP: 925 if (representation != _UVRSD_VFPX && representation != _UVRSD_DOUBLE) 926 return _UVRSR_FAILED; 927 if (representation == _UVRSD_VFPX) { 928 // Can only touch d0-15 with FSTMFDX. 929 if (regno > 15) 930 return _UVRSR_FAILED; 931 __unw_save_vfp_as_X(cursor); 932 } else { 933 if (regno > 31) 934 return _UVRSR_FAILED; 935 } 936 return __unw_set_fpreg(cursor, (unw_regnum_t)(UNW_ARM_D0 + regno), 937 *(unw_fpreg_t *)valuep) == UNW_ESUCCESS 938 ? _UVRSR_OK 939 : _UVRSR_FAILED; 940 #if defined(__ARM_WMMX) 941 case _UVRSC_WMMXC: 942 if (representation != _UVRSD_UINT32 || regno > 3) 943 return _UVRSR_FAILED; 944 return __unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_WC0 + regno), 945 *(unw_word_t *)valuep) == UNW_ESUCCESS 946 ? _UVRSR_OK 947 : _UVRSR_FAILED; 948 case _UVRSC_WMMXD: 949 if (representation != _UVRSD_DOUBLE || regno > 31) 950 return _UVRSR_FAILED; 951 return __unw_set_fpreg(cursor, (unw_regnum_t)(UNW_ARM_WR0 + regno), 952 *(unw_fpreg_t *)valuep) == UNW_ESUCCESS 953 ? _UVRSR_OK 954 : _UVRSR_FAILED; 955 #else 956 case _UVRSC_WMMXC: 957 case _UVRSC_WMMXD: 958 break; 959 #endif 960 case _UVRSC_PSEUDO: 961 // There's only one pseudo-register, PAC, with regno == 0. 962 if (representation != _UVRSD_UINT32 || regno != 0) 963 return _UVRSR_FAILED; 964 return __unw_set_reg(cursor, (unw_regnum_t)(UNW_ARM_RA_AUTH_CODE), 965 *(unw_word_t *)valuep) == UNW_ESUCCESS 966 ? _UVRSR_OK 967 : _UVRSR_FAILED; 968 break; 969 } 970 _LIBUNWIND_ABORT("unsupported register class"); 971 } 972 973 static _Unwind_VRS_Result 974 _Unwind_VRS_Get_Internal(_Unwind_Context *context, 975 _Unwind_VRS_RegClass regclass, uint32_t regno, 976 _Unwind_VRS_DataRepresentation representation, 977 void *valuep) { 978 unw_cursor_t *cursor = (unw_cursor_t *)context; 979 switch (regclass) { 980 case _UVRSC_CORE: 981 if (representation != _UVRSD_UINT32 || regno > 15) 982 return _UVRSR_FAILED; 983 return __unw_get_reg(cursor, (unw_regnum_t)(UNW_ARM_R0 + regno), 984 (unw_word_t *)valuep) == UNW_ESUCCESS 985 ? _UVRSR_OK 986 : _UVRSR_FAILED; 987 case _UVRSC_VFP: 988 if (representation != _UVRSD_VFPX && representation != _UVRSD_DOUBLE) 989 return _UVRSR_FAILED; 990 if (representation == _UVRSD_VFPX) { 991 // Can only touch d0-15 with FSTMFDX. 992 if (regno > 15) 993 return _UVRSR_FAILED; 994 __unw_save_vfp_as_X(cursor); 995 } else { 996 if (regno > 31) 997 return _UVRSR_FAILED; 998 } 999 return __unw_get_fpreg(cursor, (unw_regnum_t)(UNW_ARM_D0 + regno), 1000 (unw_fpreg_t *)valuep) == UNW_ESUCCESS 1001 ? _UVRSR_OK 1002 : _UVRSR_FAILED; 1003 #if defined(__ARM_WMMX) 1004 case _UVRSC_WMMXC: 1005 if (representation != _UVRSD_UINT32 || regno > 3) 1006 return _UVRSR_FAILED; 1007 return __unw_get_reg(cursor, (unw_regnum_t)(UNW_ARM_WC0 + regno), 1008 (unw_word_t *)valuep) == UNW_ESUCCESS 1009 ? _UVRSR_OK 1010 : _UVRSR_FAILED; 1011 case _UVRSC_WMMXD: 1012 if (representation != _UVRSD_DOUBLE || regno > 31) 1013 return _UVRSR_FAILED; 1014 return __unw_get_fpreg(cursor, (unw_regnum_t)(UNW_ARM_WR0 + regno), 1015 (unw_fpreg_t *)valuep) == UNW_ESUCCESS 1016 ? _UVRSR_OK 1017 : _UVRSR_FAILED; 1018 #else 1019 case _UVRSC_WMMXC: 1020 case _UVRSC_WMMXD: 1021 break; 1022 #endif 1023 case _UVRSC_PSEUDO: 1024 // There's only one pseudo-register, PAC, with regno == 0. 1025 if (representation != _UVRSD_UINT32 || regno != 0) 1026 return _UVRSR_FAILED; 1027 return __unw_get_reg(cursor, (unw_regnum_t)(UNW_ARM_RA_AUTH_CODE), 1028 (unw_word_t *)valuep) == UNW_ESUCCESS 1029 ? _UVRSR_OK 1030 : _UVRSR_FAILED; 1031 break; 1032 } 1033 _LIBUNWIND_ABORT("unsupported register class"); 1034 } 1035 1036 _LIBUNWIND_EXPORT _Unwind_VRS_Result 1037 _Unwind_VRS_Get(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, 1038 uint32_t regno, _Unwind_VRS_DataRepresentation representation, 1039 void *valuep) { 1040 _Unwind_VRS_Result result = 1041 _Unwind_VRS_Get_Internal(context, regclass, regno, representation, 1042 valuep); 1043 _LIBUNWIND_TRACE_API("_Unwind_VRS_Get(context=%p, regclass=%d, reg=%d, " 1044 "rep=%d, value=0x%llX, result = %d)", 1045 static_cast<void *>(context), regclass, regno, 1046 representation, 1047 ValueAsBitPattern(representation, valuep), result); 1048 return result; 1049 } 1050 1051 _Unwind_VRS_Result 1052 _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, 1053 uint32_t discriminator, 1054 _Unwind_VRS_DataRepresentation representation) { 1055 _LIBUNWIND_TRACE_API("_Unwind_VRS_Pop(context=%p, regclass=%d, " 1056 "discriminator=%d, representation=%d)", 1057 static_cast<void *>(context), regclass, discriminator, 1058 representation); 1059 switch (regclass) { 1060 case _UVRSC_WMMXC: 1061 #if !defined(__ARM_WMMX) 1062 break; 1063 #endif 1064 case _UVRSC_CORE: { 1065 if (representation != _UVRSD_UINT32) 1066 return _UVRSR_FAILED; 1067 // When popping SP from the stack, we don't want to override it from the 1068 // computed new stack location. See EHABI #7.5.4 table 3. 1069 bool poppedSP = false; 1070 uint32_t* sp; 1071 if (_Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, 1072 _UVRSD_UINT32, &sp) != _UVRSR_OK) { 1073 return _UVRSR_FAILED; 1074 } 1075 for (uint32_t i = 0; i < 16; ++i) { 1076 if (!(discriminator & static_cast<uint32_t>(1 << i))) 1077 continue; 1078 uint32_t value = *sp++; 1079 if (regclass == _UVRSC_CORE && i == 13) 1080 poppedSP = true; 1081 if (_Unwind_VRS_Set(context, regclass, i, 1082 _UVRSD_UINT32, &value) != _UVRSR_OK) { 1083 return _UVRSR_FAILED; 1084 } 1085 } 1086 if (!poppedSP) { 1087 return _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, 1088 _UVRSD_UINT32, &sp); 1089 } 1090 return _UVRSR_OK; 1091 } 1092 case _UVRSC_WMMXD: 1093 #if !defined(__ARM_WMMX) 1094 break; 1095 #endif 1096 case _UVRSC_VFP: { 1097 if (representation != _UVRSD_VFPX && representation != _UVRSD_DOUBLE) 1098 return _UVRSR_FAILED; 1099 uint32_t first = discriminator >> 16; 1100 uint32_t count = discriminator & 0xffff; 1101 uint32_t end = first+count; 1102 uint32_t* sp; 1103 if (_Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, 1104 _UVRSD_UINT32, &sp) != _UVRSR_OK) { 1105 return _UVRSR_FAILED; 1106 } 1107 // For _UVRSD_VFPX, we're assuming the data is stored in FSTMX "standard 1108 // format 1", which is equivalent to FSTMD + a padding word. 1109 for (uint32_t i = first; i < end; ++i) { 1110 // SP is only 32-bit aligned so don't copy 64-bit at a time. 1111 uint64_t w0 = *sp++; 1112 uint64_t w1 = *sp++; 1113 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 1114 uint64_t value = (w1 << 32) | w0; 1115 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 1116 uint64_t value = (w0 << 32) | w1; 1117 #else 1118 #error "Unable to determine endianess" 1119 #endif 1120 if (_Unwind_VRS_Set(context, regclass, i, representation, &value) != 1121 _UVRSR_OK) 1122 return _UVRSR_FAILED; 1123 } 1124 if (representation == _UVRSD_VFPX) 1125 ++sp; 1126 return _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, 1127 &sp); 1128 } 1129 case _UVRSC_PSEUDO: { 1130 if (representation != _UVRSD_UINT32 || discriminator != 0) 1131 return _UVRSR_FAILED; 1132 // Return Address Authentication code (PAC) - discriminator 0 1133 uint32_t *sp; 1134 if (_Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, 1135 &sp) != _UVRSR_OK) { 1136 return _UVRSR_FAILED; 1137 } 1138 uint32_t pac = *sp++; 1139 _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp); 1140 return _Unwind_VRS_Set(context, _UVRSC_PSEUDO, 0, _UVRSD_UINT32, &pac); 1141 } 1142 } 1143 _LIBUNWIND_ABORT("unsupported register class"); 1144 } 1145 1146 /// Not used by C++. 1147 /// Unwinds stack, calling "stop" function at each frame. 1148 /// Could be used to implement longjmp(). 1149 _LIBUNWIND_EXPORT _Unwind_Reason_Code 1150 _Unwind_ForcedUnwind(_Unwind_Exception *exception_object, _Unwind_Stop_Fn stop, 1151 void *stop_parameter) { 1152 _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)", 1153 (void *)exception_object, (void *)(uintptr_t)stop); 1154 unw_context_t uc; 1155 unw_cursor_t cursor; 1156 __unw_getcontext(&uc); 1157 1158 // Mark that this is a forced unwind, so _Unwind_Resume() can do 1159 // the right thing. 1160 exception_object->unwinder_cache.reserved1 = (uintptr_t)stop; 1161 exception_object->unwinder_cache.reserved3 = (uintptr_t)stop_parameter; 1162 1163 return unwind_phase2_forced(&uc, &cursor, exception_object, stop, 1164 stop_parameter); 1165 } 1166 1167 /// Called by personality handler during phase 2 to find the start of the 1168 /// function. 1169 _LIBUNWIND_EXPORT uintptr_t 1170 _Unwind_GetRegionStart(struct _Unwind_Context *context) { 1171 unw_cursor_t *cursor = (unw_cursor_t *)context; 1172 unw_proc_info_t frameInfo; 1173 uintptr_t result = 0; 1174 if (__unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS) 1175 result = (uintptr_t)frameInfo.start_ip; 1176 _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%llX", 1177 static_cast<void *>(context), (long long)result); 1178 return result; 1179 } 1180 1181 1182 /// Called by personality handler during phase 2 if a foreign exception 1183 // is caught. 1184 _LIBUNWIND_EXPORT void 1185 _Unwind_DeleteException(_Unwind_Exception *exception_object) { 1186 _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)", 1187 static_cast<void *>(exception_object)); 1188 if (exception_object->exception_cleanup != NULL) 1189 (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT, 1190 exception_object); 1191 } 1192 1193 extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code 1194 __gnu_unwind_frame(_Unwind_Exception *exception_object, 1195 struct _Unwind_Context *context) { 1196 (void)exception_object; 1197 unw_cursor_t *cursor = (unw_cursor_t *)context; 1198 switch (__unw_step(cursor)) { 1199 case UNW_STEP_SUCCESS: 1200 return _URC_OK; 1201 case UNW_STEP_END: 1202 return _URC_END_OF_STACK; 1203 default: 1204 return _URC_FAILURE; 1205 } 1206 } 1207 1208 #endif // defined(_LIBUNWIND_ARM_EHABI) 1209