Changeset 173509 in webkit for trunk/Source/JavaScriptCore/ftl/FTLUnwindInfo.cpp
- Timestamp:
- Sep 11, 2014, 1:52:22 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ftl/FTLUnwindInfo.cpp
r164456 r173509 1 1 /* 2 2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 * Copyright (C) 2014 Samsung Electronics 4 * Copyright (C) 2014 University of Szeged 3 5 * 4 6 * Redistribution and use in source and binary forms, with or without … … 21 23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 * ============================================================================== 28 * 29 * University of Illinois/NCSA 30 * Open Source License 31 * 32 * Copyright (c) 2009-2014 by the contributors of LLVM/libc++abi project. 33 * 34 * All rights reserved. 35 * 36 * Developed by: 37 * 38 * LLVM Team 39 * 40 * University of Illinois at Urbana-Champaign 41 * 42 * http://llvm.org 43 * 44 * Permission is hereby granted, free of charge, to any person obtaining a copy of 45 * this software and associated documentation files (the "Software"), to deal with 46 * the Software without restriction, including without limitation the rights to 47 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 48 * of the Software, and to permit persons to whom the Software is furnished to do 49 * so, subject to the following conditions: 50 * 51 * * Redistributions of source code must retain the above copyright notice, 52 * this list of conditions and the following disclaimers. 53 * 54 * * Redistributions in binary form must reproduce the above copyright notice, 55 * this list of conditions and the following disclaimers in the 56 * documentation and/or other materials provided with the distribution. 57 * 58 * * Neither the names of the LLVM Team, University of Illinois at 59 * Urbana-Champaign, nor the names of its contributors may be used to 60 * endorse or promote products derived from this Software without specific 61 * prior written permission. 62 * 63 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 64 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 65 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 66 * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 67 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 68 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE 69 * SOFTWARE. 70 * 71 * ============================================================================== 72 * 73 * Copyright (c) 2009-2014 by the contributors of LLVM/libc++abi project. 74 * 75 * Permission is hereby granted, free of charge, to any person obtaining a copy 76 * of this software and associated documentation files (the "Software"), to deal 77 * in the Software without restriction, including without limitation the rights 78 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 79 * copies of the Software, and to permit persons to whom the Software is 80 * furnished to do so, subject to the following conditions: 81 * 82 * The above copyright notice and this permission notice shall be included in 83 * all copies or substantial portions of the Software. 84 * 85 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 86 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 87 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 88 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 89 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 90 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 91 * THE SOFTWARE. 24 92 */ 25 93 … … 29 97 #if ENABLE(FTL_JIT) 30 98 99 #if OS(DARWIN) 31 100 #include <mach-o/compact_unwind_encoding.h> 101 #endif 32 102 #include <wtf/ListDump.h> 33 103 … … 37 107 UnwindInfo::~UnwindInfo() { } 38 108 109 39 110 namespace { 40 111 #if OS(DARWIN) 41 112 struct CompactUnwind { 42 113 void* function; … … 46 117 void* lsda; 47 118 }; 48 119 #elif OS(LINUX) 120 // DWARF unwind instructions 121 enum { 122 DW_CFA_nop = 0x0, 123 DW_CFA_set_loc = 0x1, 124 DW_CFA_advance_loc1 = 0x2, 125 DW_CFA_advance_loc2 = 0x3, 126 DW_CFA_advance_loc4 = 0x4, 127 DW_CFA_offset_extended = 0x5, 128 DW_CFA_def_cfa = 0xC, 129 DW_CFA_def_cfa_register = 0xD, 130 DW_CFA_def_cfa_offset = 0xE, 131 DW_CFA_offset_extended_sf = 0x11, 132 DW_CFA_def_cfa_sf = 0x12, 133 DW_CFA_def_cfa_offset_sf = 0x13, 134 // high 2 bits are 0x1, lower 6 bits are delta 135 DW_CFA_advance_loc = 0x40, 136 // high 2 bits are 0x2, lower 6 bits are register 137 DW_CFA_offset = 0x80 138 }; 139 140 enum { 141 DW_CFA_operand_mask = 0x3F // low 6 bits mask for opcode-encoded operands in DW_CFA_advance_loc and DW_CFA_offset 142 }; 143 144 // FSF exception handling Pointer-Encoding constants 145 enum { 146 DW_EH_PE_ptr = 0x00, 147 DW_EH_PE_uleb128 = 0x01, 148 DW_EH_PE_udata2 = 0x02, 149 DW_EH_PE_udata4 = 0x03, 150 DW_EH_PE_udata8 = 0x04, 151 DW_EH_PE_sleb128 = 0x09, 152 DW_EH_PE_sdata2 = 0x0A, 153 DW_EH_PE_sdata4 = 0x0B, 154 DW_EH_PE_sdata8 = 0x0C, 155 DW_EH_PE_absptr = 0x00, 156 DW_EH_PE_pcrel = 0x10, 157 DW_EH_PE_indirect = 0x80 158 }; 159 160 enum { 161 DW_EH_PE_relative_mask = 0x70 162 }; 163 164 // 64-bit x86_64 registers 165 enum { 166 UNW_X86_64_rbx = 3, 167 UNW_X86_64_rbp = 6, 168 UNW_X86_64_r12 = 12, 169 UNW_X86_64_r13 = 13, 170 UNW_X86_64_r14 = 14, 171 UNW_X86_64_r15 = 15 172 }; 173 174 enum { 175 DW_X86_64_RET_addr = 16 176 }; 177 178 static uint8_t get8(uintptr_t addr) { return *((uint8_t*)addr); } 179 static uint16_t get16(uintptr_t addr) { return *((uint16_t*)addr); } 180 static uint32_t get32(uintptr_t addr) { return *((uint32_t*)addr); } 181 static uint64_t get64(uintptr_t addr) { return *((uint64_t*)addr); } 182 183 static uintptr_t getP(uintptr_t addr) 184 { 185 // FIXME: add support for 32 bit pointers on 32 bit architectures 186 return get64(addr); 187 } 188 189 static uint64_t getULEB128(uintptr_t& addr, uintptr_t end) 190 { 191 const uint8_t* p = (uint8_t*)addr; 192 const uint8_t* pend = (uint8_t*)end; 193 uint64_t result = 0; 194 int bit = 0; 195 do { 196 uint64_t b; 197 198 RELEASE_ASSERT(p != pend); // truncated uleb128 expression 199 200 b = *p & 0x7f; 201 202 RELEASE_ASSERT(!(bit >= 64 || b << bit >> bit != b)); // malformed uleb128 expression 203 204 result |= b << bit; 205 bit += 7; 206 } while (*p++ >= 0x80); 207 addr = (uintptr_t)p; 208 return result; 209 } 210 211 static int64_t getSLEB128(uintptr_t& addr, uintptr_t end) 212 { 213 const uint8_t* p = (uint8_t*)addr; 214 const uint8_t* pend = (uint8_t*)end; 215 216 int64_t result = 0; 217 int bit = 0; 218 uint8_t byte; 219 do { 220 RELEASE_ASSERT(p != pend); // truncated sleb128 expression 221 222 byte = *p++; 223 result |= ((byte & 0x7f) << bit); 224 bit += 7; 225 } while (byte & 0x80); 226 // sign extend negative numbers 227 if ((byte & 0x40)) 228 result |= (-1LL) << bit; 229 addr = (uintptr_t)p; 230 return result; 231 } 232 233 static uintptr_t getEncodedP(uintptr_t& addr, uintptr_t end, uint8_t encoding) 234 { 235 uintptr_t startAddr = addr; 236 const uint8_t* p = (uint8_t*)addr; 237 uintptr_t result; 238 239 // first get value 240 switch (encoding & 0x0F) { 241 case DW_EH_PE_ptr: 242 result = getP(addr); 243 p += sizeof(uintptr_t); 244 addr = (uintptr_t)p; 245 break; 246 case DW_EH_PE_uleb128: 247 result = getULEB128(addr, end); 248 break; 249 case DW_EH_PE_udata2: 250 result = get16(addr); 251 p += 2; 252 addr = (uintptr_t)p; 253 break; 254 case DW_EH_PE_udata4: 255 result = get32(addr); 256 p += 4; 257 addr = (uintptr_t)p; 258 break; 259 case DW_EH_PE_udata8: 260 result = get64(addr); 261 p += 8; 262 addr = (uintptr_t)p; 263 break; 264 case DW_EH_PE_sleb128: 265 result = getSLEB128(addr, end); 266 break; 267 case DW_EH_PE_sdata2: 268 result = (int16_t)get16(addr); 269 p += 2; 270 addr = (uintptr_t)p; 271 break; 272 case DW_EH_PE_sdata4: 273 result = (int32_t)get32(addr); 274 p += 4; 275 addr = (uintptr_t)p; 276 break; 277 case DW_EH_PE_sdata8: 278 result = get64(addr); 279 p += 8; 280 addr = (uintptr_t)p; 281 break; 282 default: 283 RELEASE_ASSERT_NOT_REACHED(); // unknown pointer encoding 284 } 285 286 // then add relative offset 287 switch (encoding & DW_EH_PE_relative_mask) { 288 case DW_EH_PE_absptr: 289 // do nothing 290 break; 291 case DW_EH_PE_pcrel: 292 result += startAddr; 293 break; 294 default: 295 RELEASE_ASSERT_NOT_REACHED(); // unsupported or unknown pointer encoding 296 } 297 298 if (encoding & DW_EH_PE_indirect) 299 result = getP(result); 300 301 return result; 302 } 303 304 // Information encoded in a CIE (Common Information Entry) 305 struct CIE_Info { 306 uintptr_t cieStart; 307 uintptr_t cieLength; 308 uintptr_t cieInstructions; 309 uint8_t pointerEncoding; 310 uint8_t lsdaEncoding; 311 uint8_t personalityEncoding; 312 uint8_t personalityOffsetInCIE; 313 uintptr_t personality; 314 int dataAlignFactor; 315 bool fdesHaveAugmentationData; 316 }; 317 318 // Information about an FDE (Frame Description Entry) 319 struct FDE_Info { 320 uintptr_t fdeStart; 321 uintptr_t fdeLength; 322 uintptr_t fdeInstructions; 323 uintptr_t lsda; 324 }; 325 326 // Information about a frame layout and registers saved determined 327 // by "running" the dwarf FDE "instructions" 328 enum { MaxRegisterNumber = 17 }; 329 330 struct RegisterLocation { 331 bool saved; 332 int64_t offset; 333 }; 334 335 struct PrologInfo { 336 uint32_t cfaRegister; 337 int32_t cfaRegisterOffset; // CFA = (cfaRegister)+cfaRegisterOffset 338 RegisterLocation savedRegisters[MaxRegisterNumber]; // from where to restore registers 339 }; 340 341 static void parseCIE(uintptr_t cie, CIE_Info* cieInfo) 342 { 343 cieInfo->pointerEncoding = 0; 344 cieInfo->lsdaEncoding = 0; 345 cieInfo->personalityEncoding = 0; 346 cieInfo->personalityOffsetInCIE = 0; 347 cieInfo->personality = 0; 348 cieInfo->dataAlignFactor = 0; 349 cieInfo->fdesHaveAugmentationData = false; 350 cieInfo->cieStart = cie; 351 352 uintptr_t p = cie; 353 uint64_t cieLength = get32(p); 354 p += 4; 355 uintptr_t cieContentEnd = p + cieLength; 356 if (cieLength == 0xffffffff) { 357 // 0xffffffff means length is really next 8 bytes 358 cieLength = get64(p); 359 p += 8; 360 cieContentEnd = p + cieLength; 361 } 362 363 RELEASE_ASSERT(cieLength); 364 365 // CIE ID is always 0 366 RELEASE_ASSERT(!get32(p)); // CIE ID is not zero 367 p += 4; 368 // Version is always 1 or 3 369 uint8_t version = get8(p); 370 RELEASE_ASSERT((version == 1) || (version == 3)); // CIE version is not 1 or 3 371 372 ++p; 373 // save start of augmentation string and find end 374 uintptr_t strStart = p; 375 while (get8(p)) 376 ++p; 377 ++p; 378 // parse code aligment factor 379 getULEB128(p, cieContentEnd); 380 // parse data alignment factor 381 cieInfo->dataAlignFactor = getSLEB128(p, cieContentEnd); 382 // parse return address register 383 getULEB128(p, cieContentEnd); 384 // parse augmentation data based on augmentation string 385 if (get8(strStart) == 'z') { 386 // parse augmentation data length 387 getULEB128(p, cieContentEnd); 388 for (uintptr_t s = strStart; get8(s) != '\0'; ++s) { 389 switch (get8(s)) { 390 case 'z': 391 cieInfo->fdesHaveAugmentationData = true; 392 break; 393 case 'P': // FIXME: should assert on personality (just to keep in sync with the CU behaviour) 394 cieInfo->personalityEncoding = get8(p); 395 ++p; 396 cieInfo->personalityOffsetInCIE = p - cie; 397 cieInfo->personality = getEncodedP(p, cieContentEnd, cieInfo->personalityEncoding); 398 break; 399 case 'L': // FIXME: should assert on LSDA (just to keep in sync with the CU behaviour) 400 cieInfo->lsdaEncoding = get8(p); 401 ++p; 402 break; 403 case 'R': 404 cieInfo->pointerEncoding = get8(p); 405 ++p; 406 break; 407 default: 408 // ignore unknown letters 409 break; 410 } 411 } 412 } 413 cieInfo->cieLength = cieContentEnd - cieInfo->cieStart; 414 cieInfo->cieInstructions = p; 415 } 416 417 static void findFDE(uintptr_t pc, uintptr_t ehSectionStart, uint32_t sectionLength, FDE_Info* fdeInfo, CIE_Info* cieInfo) 418 { 419 uintptr_t p = ehSectionStart; 420 const uintptr_t ehSectionEnd = p + sectionLength; 421 while (p < ehSectionEnd) { 422 uintptr_t currentCFI = p; 423 uint64_t cfiLength = get32(p); 424 p += 4; 425 if (cfiLength == 0xffffffff) { 426 // 0xffffffff means length is really next 8 bytes 427 cfiLength = get64(p); 428 p += 8; 429 } 430 RELEASE_ASSERT(cfiLength); // end marker reached before finding FDE for pc 431 432 uint32_t id = get32(p); 433 if (!id) { 434 // skip over CIEs 435 p += cfiLength; 436 } else { 437 // process FDE to see if it covers pc 438 uintptr_t nextCFI = p + cfiLength; 439 uint32_t ciePointer = get32(p); 440 uintptr_t cieStart = p - ciePointer; 441 // validate pointer to CIE is within section 442 RELEASE_ASSERT((ehSectionStart <= cieStart) && (cieStart < ehSectionEnd)); // malformed FDE. CIE is bad 443 444 parseCIE(cieStart, cieInfo); 445 446 p += 4; 447 // parse pc begin and range 448 uintptr_t pcStart = getEncodedP(p, nextCFI, cieInfo->pointerEncoding); 449 uintptr_t pcRange = getEncodedP(p, nextCFI, cieInfo->pointerEncoding & 0x0F); 450 451 // test if pc is within the function this FDE covers 452 // if pc is not in begin/range, skip this FDE 453 if ((pcStart <= pc) && (pc < pcStart+pcRange)) { 454 // parse rest of info 455 fdeInfo->lsda = 0; 456 // check for augmentation length 457 if (cieInfo->fdesHaveAugmentationData) { 458 uintptr_t augLen = getULEB128(p, nextCFI); 459 uintptr_t endOfAug = p + augLen; 460 if (cieInfo->lsdaEncoding) { 461 // peek at value (without indirection). Zero means no lsda 462 uintptr_t lsdaStart = p; 463 if (getEncodedP(p, nextCFI, cieInfo->lsdaEncoding & 0x0F)) { 464 // reset pointer and re-parse lsda address 465 p = lsdaStart; 466 fdeInfo->lsda = getEncodedP(p, nextCFI, cieInfo->lsdaEncoding); 467 } 468 } 469 p = endOfAug; 470 } 471 fdeInfo->fdeStart = currentCFI; 472 fdeInfo->fdeLength = nextCFI - currentCFI; 473 fdeInfo->fdeInstructions = p; 474 475 return; // FDE found 476 } 477 478 p = nextCFI; 479 } 480 } 481 482 RELEASE_ASSERT_NOT_REACHED(); // no FDE found for pc 483 } 484 485 static void executeDefCFARegister(uint64_t reg, PrologInfo* results) 486 { 487 RELEASE_ASSERT(reg <= MaxRegisterNumber); // reg too big 488 results->cfaRegister = reg; 489 } 490 491 static void executeDefCFAOffset(int64_t offset, PrologInfo* results) 492 { 493 RELEASE_ASSERT(offset <= 0x80000000); // cfa has negative offset (dwarf might contain epilog) 494 results->cfaRegisterOffset = offset; 495 } 496 497 static void executeOffset(uint64_t reg, int64_t offset, PrologInfo *results) 498 { 499 if (reg > MaxRegisterNumber) 500 return; 501 502 RELEASE_ASSERT(!results->savedRegisters[reg].saved); 503 results->savedRegisters[reg].saved = true; 504 results->savedRegisters[reg].offset = offset; 505 } 506 507 static void parseInstructions(uintptr_t instructions, uintptr_t instructionsEnd, const CIE_Info& cieInfo, PrologInfo* results) 508 { 509 uintptr_t p = instructions; 510 511 // see Dwarf Spec, section 6.4.2 for details on unwind opcodes 512 while ((p < instructionsEnd)) { 513 uint64_t reg; 514 uint8_t opcode = get8(p); 515 uint8_t operand; 516 ++p; 517 switch (opcode) { 518 case DW_CFA_nop: 519 break; 520 case DW_CFA_set_loc: 521 getEncodedP(p, instructionsEnd, cieInfo.pointerEncoding); 522 break; 523 case DW_CFA_advance_loc1: 524 p += 1; 525 break; 526 case DW_CFA_advance_loc2: 527 p += 2; 528 break; 529 case DW_CFA_advance_loc4: 530 p += 4; 531 break; 532 case DW_CFA_def_cfa: 533 executeDefCFARegister(getULEB128(p, instructionsEnd), results); 534 executeDefCFAOffset(getULEB128(p, instructionsEnd), results); 535 break; 536 case DW_CFA_def_cfa_sf: 537 executeDefCFARegister(getULEB128(p, instructionsEnd), results); 538 executeDefCFAOffset(getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor, results); 539 break; 540 case DW_CFA_def_cfa_register: 541 executeDefCFARegister(getULEB128(p, instructionsEnd), results); 542 break; 543 case DW_CFA_def_cfa_offset: 544 executeDefCFAOffset(getULEB128(p, instructionsEnd), results); 545 break; 546 case DW_CFA_def_cfa_offset_sf: 547 executeDefCFAOffset(getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor, results); 548 break; 549 case DW_CFA_offset_extended: 550 reg = getULEB128(p, instructionsEnd); 551 executeOffset(reg, getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor, results); 552 break; 553 case DW_CFA_offset_extended_sf: 554 reg = getULEB128(p, instructionsEnd); 555 executeOffset(reg, getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor, results); 556 break; 557 default: 558 operand = opcode & DW_CFA_operand_mask; 559 switch (opcode & ~DW_CFA_operand_mask) { 560 case DW_CFA_offset: 561 executeOffset(operand, getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor, results); 562 break; 563 case DW_CFA_advance_loc: 564 break; 565 default: 566 RELEASE_ASSERT_NOT_REACHED(); // unknown or unsupported CFA opcode 567 } 568 } 569 } 570 } 571 572 static void parseFDEInstructions(const FDE_Info& fdeInfo, const CIE_Info& cieInfo, PrologInfo* results) 573 { 574 // clear results 575 bzero(results, sizeof(PrologInfo)); 576 577 // parse CIE then FDE instructions 578 parseInstructions(cieInfo.cieInstructions, cieInfo.cieStart + cieInfo.cieLength, cieInfo, results); 579 parseInstructions(fdeInfo.fdeInstructions, fdeInfo.fdeStart + fdeInfo.fdeLength, cieInfo, results); 580 } 581 #endif 49 582 } // anonymous namespace 50 583 … … 52 585 { 53 586 m_registers.clear(); 54 55 RELEASE_ASSERT(!!section == !!size); 587 RELEASE_ASSERT(!!section); 56 588 if (!section) 57 589 return false; 58 590 591 #if OS(DARWIN) 59 592 RELEASE_ASSERT(size >= sizeof(CompactUnwind)); 60 593 … … 158 691 #error "Unrecognized architecture" 159 692 #endif 160 693 694 #elif OS(LINUX) 695 FDE_Info fdeInfo; 696 CIE_Info cieInfo; 697 PrologInfo prolog; 698 699 findFDE((uintptr_t)generatedFunction, (uintptr_t)section, size, &fdeInfo, &cieInfo); 700 parseFDEInstructions(fdeInfo, cieInfo, &prolog); 701 702 #if CPU(X86_64) 703 RELEASE_ASSERT(prolog.cfaRegister == UNW_X86_64_rbp); 704 RELEASE_ASSERT(prolog.cfaRegisterOffset == 16); 705 RELEASE_ASSERT(prolog.savedRegisters[UNW_X86_64_rbp].saved); 706 RELEASE_ASSERT(prolog.savedRegisters[UNW_X86_64_rbp].offset == -prolog.cfaRegisterOffset); 707 708 for (int i = 0; i < MaxRegisterNumber; ++i) { 709 if (prolog.savedRegisters[i].saved) { 710 switch (i) { 711 case UNW_X86_64_rbx: 712 m_registers.append(RegisterAtOffset(X86Registers::ebx, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset)); 713 break; 714 case UNW_X86_64_r12: 715 m_registers.append(RegisterAtOffset(X86Registers::r12, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset)); 716 break; 717 case UNW_X86_64_r13: 718 m_registers.append(RegisterAtOffset(X86Registers::r13, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset)); 719 break; 720 case UNW_X86_64_r14: 721 m_registers.append(RegisterAtOffset(X86Registers::r14, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset)); 722 break; 723 case UNW_X86_64_r15: 724 m_registers.append(RegisterAtOffset(X86Registers::r15, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset)); 725 break; 726 case UNW_X86_64_rbp: 727 m_registers.append(RegisterAtOffset(X86Registers::ebp, prolog.savedRegisters[i].offset + prolog.cfaRegisterOffset)); 728 break; 729 case DW_X86_64_RET_addr: 730 break; 731 default: 732 RELEASE_ASSERT_NOT_REACHED(); // non-standard register being saved in prolog 733 } 734 } 735 } 736 #elif CPU(ARM64) 737 // FIXME: Implement stackunwinding based on eh_frame on ARM64 738 #else 739 #error "Unrecognized architecture" 740 #endif 741 742 #endif 161 743 std::sort(m_registers.begin(), m_registers.end()); 162 744 return true;
Note:
See TracChangeset
for help on using the changeset viewer.