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 // Processor specific interpretation of DWARF unwind info. 9 // 10 //===----------------------------------------------------------------------===// 11 12 #ifndef __DWARF_INSTRUCTIONS_HPP__ 13 #define __DWARF_INSTRUCTIONS_HPP__ 14 15 #include <stdint.h> 16 #include <stdio.h> 17 #include <stdlib.h> 18 19 #include "dwarf2.h" 20 #include "Registers.hpp" 21 #include "DwarfParser.hpp" 22 #include "config.h" 23 24 25 namespace libunwind { 26 27 28 /// DwarfInstructions maps abtract DWARF unwind instructions to a particular 29 /// architecture 30 template <typename A, typename R> 31 class DwarfInstructions { 32 public: 33 typedef typename A::pint_t pint_t; 34 typedef typename A::sint_t sint_t; 35 36 static int stepWithDwarf(A &addressSpace, pint_t pc, pint_t fdeStart, 37 R ®isters, bool &isSignalFrame); 38 39 private: 40 41 enum { 42 DW_X86_64_RET_ADDR = 16 43 }; 44 45 enum { 46 DW_X86_RET_ADDR = 8 47 }; 48 49 typedef typename CFI_Parser<A>::RegisterLocation RegisterLocation; 50 typedef typename CFI_Parser<A>::PrologInfo PrologInfo; 51 typedef typename CFI_Parser<A>::FDE_Info FDE_Info; 52 typedef typename CFI_Parser<A>::CIE_Info CIE_Info; 53 54 static pint_t evaluateExpression(pint_t expression, A &addressSpace, 55 const R ®isters, 56 pint_t initialStackValue); 57 static pint_t getSavedRegister(A &addressSpace, const R ®isters, 58 pint_t cfa, const RegisterLocation &savedReg); 59 static double getSavedFloatRegister(A &addressSpace, const R ®isters, 60 pint_t cfa, const RegisterLocation &savedReg); 61 static v128 getSavedVectorRegister(A &addressSpace, const R ®isters, 62 pint_t cfa, const RegisterLocation &savedReg); 63 64 static pint_t getCFA(A &addressSpace, const PrologInfo &prolog, 65 const R ®isters) { 66 if (prolog.cfaRegister != 0) 67 return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister) + 68 prolog.cfaRegisterOffset); 69 if (prolog.cfaExpression != 0) 70 return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace, 71 registers, 0); 72 assert(0 && "getCFA(): unknown location"); 73 __builtin_unreachable(); 74 } 75 }; 76 77 78 template <typename A, typename R> 79 typename A::pint_t DwarfInstructions<A, R>::getSavedRegister( 80 A &addressSpace, const R ®isters, pint_t cfa, 81 const RegisterLocation &savedReg) { 82 switch (savedReg.location) { 83 case CFI_Parser<A>::kRegisterInCFA: 84 return (pint_t)addressSpace.getRegister(cfa + (pint_t)savedReg.value); 85 86 case CFI_Parser<A>::kRegisterAtExpression: 87 return (pint_t)addressSpace.getRegister(evaluateExpression( 88 (pint_t)savedReg.value, addressSpace, registers, cfa)); 89 90 case CFI_Parser<A>::kRegisterIsExpression: 91 return evaluateExpression((pint_t)savedReg.value, addressSpace, 92 registers, cfa); 93 94 case CFI_Parser<A>::kRegisterInRegister: 95 return registers.getRegister((int)savedReg.value); 96 97 case CFI_Parser<A>::kRegisterUnused: 98 case CFI_Parser<A>::kRegisterOffsetFromCFA: 99 // FIX ME 100 break; 101 } 102 _LIBUNWIND_ABORT("unsupported restore location for register"); 103 } 104 105 template <typename A, typename R> 106 double DwarfInstructions<A, R>::getSavedFloatRegister( 107 A &addressSpace, const R ®isters, pint_t cfa, 108 const RegisterLocation &savedReg) { 109 switch (savedReg.location) { 110 case CFI_Parser<A>::kRegisterInCFA: 111 return addressSpace.getDouble(cfa + (pint_t)savedReg.value); 112 113 case CFI_Parser<A>::kRegisterAtExpression: 114 return addressSpace.getDouble( 115 evaluateExpression((pint_t)savedReg.value, addressSpace, 116 registers, cfa)); 117 case CFI_Parser<A>::kRegisterUndefined: 118 return 0.0; 119 case CFI_Parser<A>::kRegisterInRegister: 120 #ifndef _LIBUNWIND_TARGET_ARM 121 return registers.getFloatRegister((int)savedReg.value); 122 #endif 123 case CFI_Parser<A>::kRegisterIsExpression: 124 case CFI_Parser<A>::kRegisterUnused: 125 case CFI_Parser<A>::kRegisterOffsetFromCFA: 126 // FIX ME 127 break; 128 } 129 _LIBUNWIND_ABORT("unsupported restore location for float register"); 130 } 131 132 template <typename A, typename R> 133 v128 DwarfInstructions<A, R>::getSavedVectorRegister( 134 A &addressSpace, const R ®isters, pint_t cfa, 135 const RegisterLocation &savedReg) { 136 switch (savedReg.location) { 137 case CFI_Parser<A>::kRegisterInCFA: 138 return addressSpace.getVector(cfa + (pint_t)savedReg.value); 139 140 case CFI_Parser<A>::kRegisterAtExpression: 141 return addressSpace.getVector( 142 evaluateExpression((pint_t)savedReg.value, addressSpace, 143 registers, cfa)); 144 145 case CFI_Parser<A>::kRegisterIsExpression: 146 case CFI_Parser<A>::kRegisterUnused: 147 case CFI_Parser<A>::kRegisterOffsetFromCFA: 148 case CFI_Parser<A>::kRegisterInRegister: 149 // FIX ME 150 break; 151 } 152 _LIBUNWIND_ABORT("unsupported restore location for vector register"); 153 } 154 155 template <typename A, typename R> 156 int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc, 157 pint_t fdeStart, R ®isters, 158 bool &isSignalFrame) { 159 FDE_Info fdeInfo; 160 CIE_Info cieInfo; 161 if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo, 162 &cieInfo) == NULL) { 163 PrologInfo prolog; 164 if (CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, pc, 165 R::getArch(), &prolog)) { 166 // get pointer to cfa (architecture specific) 167 pint_t cfa = getCFA(addressSpace, prolog, registers); 168 169 // restore registers that DWARF says were saved 170 R newRegisters = registers; 171 172 // Typically, the CFA is the stack pointer at the call site in 173 // the previous frame. However, there are scenarios in which this is not 174 // true. For example, if we switched to a new stack. In that case, the 175 // value of the previous SP might be indicated by a CFI directive. 176 // 177 // We set the SP here to the CFA, allowing for it to be overridden 178 // by a CFI directive later on. 179 newRegisters.setSP(cfa); 180 181 pint_t returnAddress = 0; 182 const int lastReg = R::lastDwarfRegNum(); 183 assert(static_cast<int>(CFI_Parser<A>::kMaxRegisterNumber) >= lastReg && 184 "register range too large"); 185 assert(lastReg >= (int)cieInfo.returnAddressRegister && 186 "register range does not contain return address register"); 187 for (int i = 0; i <= lastReg; ++i) { 188 if (prolog.savedRegisters[i].location != 189 CFI_Parser<A>::kRegisterUnused) { 190 if (registers.validFloatRegister(i)) 191 newRegisters.setFloatRegister( 192 i, getSavedFloatRegister(addressSpace, registers, cfa, 193 prolog.savedRegisters[i])); 194 else if (registers.validVectorRegister(i)) 195 newRegisters.setVectorRegister( 196 i, getSavedVectorRegister(addressSpace, registers, cfa, 197 prolog.savedRegisters[i])); 198 else if (i == (int)cieInfo.returnAddressRegister) 199 returnAddress = getSavedRegister(addressSpace, registers, cfa, 200 prolog.savedRegisters[i]); 201 else if (registers.validRegister(i)) 202 newRegisters.setRegister( 203 i, getSavedRegister(addressSpace, registers, cfa, 204 prolog.savedRegisters[i])); 205 else 206 return UNW_EBADREG; 207 } 208 } 209 210 isSignalFrame = cieInfo.isSignalFrame; 211 212 #if defined(_LIBUNWIND_TARGET_AARCH64) 213 // If the target is aarch64 then the return address may have been signed 214 // using the v8.3 pointer authentication extensions. The original 215 // return address needs to be authenticated before the return address is 216 // restored. autia1716 is used instead of autia as autia1716 assembles 217 // to a NOP on pre-v8.3a architectures. 218 if ((R::getArch() == REGISTERS_ARM64) && 219 prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE].value && 220 returnAddress != 0) { 221 #if !defined(_LIBUNWIND_IS_NATIVE_ONLY) 222 return UNW_ECROSSRASIGNING; 223 #else 224 register unsigned long long x17 __asm("x17") = returnAddress; 225 register unsigned long long x16 __asm("x16") = cfa; 226 227 // These are the autia1716/autib1716 instructions. The hint instructions 228 // are used here as gcc does not assemble autia1716/autib1716 for pre 229 // armv8.3a targets. 230 if (cieInfo.addressesSignedWithBKey) 231 asm("hint 0xe" : "+r"(x17) : "r"(x16)); // autib1716 232 else 233 asm("hint 0xc" : "+r"(x17) : "r"(x16)); // autia1716 234 returnAddress = x17; 235 #endif 236 } 237 #endif 238 239 #if defined(_LIBUNWIND_TARGET_SPARC) 240 if (R::getArch() == REGISTERS_SPARC) { 241 // Skip call site instruction and delay slot 242 returnAddress += 8; 243 // Skip unimp instruction if function returns a struct 244 if ((addressSpace.get32(returnAddress) & 0xC1C00000) == 0) 245 returnAddress += 4; 246 } 247 #endif 248 249 #if defined(_LIBUNWIND_TARGET_PPC64) 250 #define PPC64_ELFV1_R2_LOAD_INST_ENCODING 0xe8410028u // ld r2,40(r1) 251 #define PPC64_ELFV1_R2_OFFSET 40 252 #define PPC64_ELFV2_R2_LOAD_INST_ENCODING 0xe8410018u // ld r2,24(r1) 253 #define PPC64_ELFV2_R2_OFFSET 24 254 // If the instruction at return address is a TOC (r2) restore, 255 // then r2 was saved and needs to be restored. 256 // ELFv2 ABI specifies that the TOC Pointer must be saved at SP + 24, 257 // while in ELFv1 ABI it is saved at SP + 40. 258 if (R::getArch() == REGISTERS_PPC64 && returnAddress != 0) { 259 pint_t sp = newRegisters.getRegister(UNW_REG_SP); 260 pint_t r2 = 0; 261 switch (addressSpace.get32(returnAddress)) { 262 case PPC64_ELFV1_R2_LOAD_INST_ENCODING: 263 r2 = addressSpace.get64(sp + PPC64_ELFV1_R2_OFFSET); 264 break; 265 case PPC64_ELFV2_R2_LOAD_INST_ENCODING: 266 r2 = addressSpace.get64(sp + PPC64_ELFV2_R2_OFFSET); 267 break; 268 } 269 if (r2) 270 newRegisters.setRegister(UNW_PPC64_R2, r2); 271 } 272 #endif 273 274 // Return address is address after call site instruction, so setting IP to 275 // that does simualates a return. 276 newRegisters.setIP(returnAddress); 277 278 // Simulate the step by replacing the register set with the new ones. 279 registers = newRegisters; 280 281 return UNW_STEP_SUCCESS; 282 } 283 } 284 return UNW_EBADFRAME; 285 } 286 287 template <typename A, typename R> 288 typename A::pint_t 289 DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace, 290 const R ®isters, 291 pint_t initialStackValue) { 292 const bool log = false; 293 pint_t p = expression; 294 pint_t expressionEnd = expression + 20; // temp, until len read 295 pint_t length = (pint_t)addressSpace.getULEB128(p, expressionEnd); 296 expressionEnd = p + length; 297 if (log) 298 fprintf(stderr, "evaluateExpression(): length=%" PRIu64 "\n", 299 (uint64_t)length); 300 pint_t stack[100]; 301 pint_t *sp = stack; 302 *(++sp) = initialStackValue; 303 304 while (p < expressionEnd) { 305 if (log) { 306 for (pint_t *t = sp; t > stack; --t) { 307 fprintf(stderr, "sp[] = 0x%" PRIx64 "\n", (uint64_t)(*t)); 308 } 309 } 310 uint8_t opcode = addressSpace.get8(p++); 311 sint_t svalue, svalue2; 312 pint_t value; 313 uint32_t reg; 314 switch (opcode) { 315 case DW_OP_addr: 316 // push immediate address sized value 317 value = addressSpace.getP(p); 318 p += sizeof(pint_t); 319 *(++sp) = value; 320 if (log) 321 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 322 break; 323 324 case DW_OP_deref: 325 // pop stack, dereference, push result 326 value = *sp--; 327 *(++sp) = addressSpace.getP(value); 328 if (log) 329 fprintf(stderr, "dereference 0x%" PRIx64 "\n", (uint64_t)value); 330 break; 331 332 case DW_OP_const1u: 333 // push immediate 1 byte value 334 value = addressSpace.get8(p); 335 p += 1; 336 *(++sp) = value; 337 if (log) 338 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 339 break; 340 341 case DW_OP_const1s: 342 // push immediate 1 byte signed value 343 svalue = (int8_t) addressSpace.get8(p); 344 p += 1; 345 *(++sp) = (pint_t)svalue; 346 if (log) 347 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue); 348 break; 349 350 case DW_OP_const2u: 351 // push immediate 2 byte value 352 value = addressSpace.get16(p); 353 p += 2; 354 *(++sp) = value; 355 if (log) 356 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 357 break; 358 359 case DW_OP_const2s: 360 // push immediate 2 byte signed value 361 svalue = (int16_t) addressSpace.get16(p); 362 p += 2; 363 *(++sp) = (pint_t)svalue; 364 if (log) 365 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue); 366 break; 367 368 case DW_OP_const4u: 369 // push immediate 4 byte value 370 value = addressSpace.get32(p); 371 p += 4; 372 *(++sp) = value; 373 if (log) 374 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 375 break; 376 377 case DW_OP_const4s: 378 // push immediate 4 byte signed value 379 svalue = (int32_t)addressSpace.get32(p); 380 p += 4; 381 *(++sp) = (pint_t)svalue; 382 if (log) 383 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue); 384 break; 385 386 case DW_OP_const8u: 387 // push immediate 8 byte value 388 value = (pint_t)addressSpace.get64(p); 389 p += 8; 390 *(++sp) = value; 391 if (log) 392 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 393 break; 394 395 case DW_OP_const8s: 396 // push immediate 8 byte signed value 397 value = (pint_t)addressSpace.get64(p); 398 p += 8; 399 *(++sp) = value; 400 if (log) 401 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 402 break; 403 404 case DW_OP_constu: 405 // push immediate ULEB128 value 406 value = (pint_t)addressSpace.getULEB128(p, expressionEnd); 407 *(++sp) = value; 408 if (log) 409 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 410 break; 411 412 case DW_OP_consts: 413 // push immediate SLEB128 value 414 svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd); 415 *(++sp) = (pint_t)svalue; 416 if (log) 417 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue); 418 break; 419 420 case DW_OP_dup: 421 // push top of stack 422 value = *sp; 423 *(++sp) = value; 424 if (log) 425 fprintf(stderr, "duplicate top of stack\n"); 426 break; 427 428 case DW_OP_drop: 429 // pop 430 --sp; 431 if (log) 432 fprintf(stderr, "pop top of stack\n"); 433 break; 434 435 case DW_OP_over: 436 // dup second 437 value = sp[-1]; 438 *(++sp) = value; 439 if (log) 440 fprintf(stderr, "duplicate second in stack\n"); 441 break; 442 443 case DW_OP_pick: 444 // pick from 445 reg = addressSpace.get8(p); 446 p += 1; 447 value = sp[-(int)reg]; 448 *(++sp) = value; 449 if (log) 450 fprintf(stderr, "duplicate %d in stack\n", reg); 451 break; 452 453 case DW_OP_swap: 454 // swap top two 455 value = sp[0]; 456 sp[0] = sp[-1]; 457 sp[-1] = value; 458 if (log) 459 fprintf(stderr, "swap top of stack\n"); 460 break; 461 462 case DW_OP_rot: 463 // rotate top three 464 value = sp[0]; 465 sp[0] = sp[-1]; 466 sp[-1] = sp[-2]; 467 sp[-2] = value; 468 if (log) 469 fprintf(stderr, "rotate top three of stack\n"); 470 break; 471 472 case DW_OP_xderef: 473 // pop stack, dereference, push result 474 value = *sp--; 475 *sp = *((pint_t*)value); 476 if (log) 477 fprintf(stderr, "x-dereference 0x%" PRIx64 "\n", (uint64_t)value); 478 break; 479 480 case DW_OP_abs: 481 svalue = (sint_t)*sp; 482 if (svalue < 0) 483 *sp = (pint_t)(-svalue); 484 if (log) 485 fprintf(stderr, "abs\n"); 486 break; 487 488 case DW_OP_and: 489 value = *sp--; 490 *sp &= value; 491 if (log) 492 fprintf(stderr, "and\n"); 493 break; 494 495 case DW_OP_div: 496 svalue = (sint_t)(*sp--); 497 svalue2 = (sint_t)*sp; 498 *sp = (pint_t)(svalue2 / svalue); 499 if (log) 500 fprintf(stderr, "div\n"); 501 break; 502 503 case DW_OP_minus: 504 value = *sp--; 505 *sp = *sp - value; 506 if (log) 507 fprintf(stderr, "minus\n"); 508 break; 509 510 case DW_OP_mod: 511 svalue = (sint_t)(*sp--); 512 svalue2 = (sint_t)*sp; 513 *sp = (pint_t)(svalue2 % svalue); 514 if (log) 515 fprintf(stderr, "module\n"); 516 break; 517 518 case DW_OP_mul: 519 svalue = (sint_t)(*sp--); 520 svalue2 = (sint_t)*sp; 521 *sp = (pint_t)(svalue2 * svalue); 522 if (log) 523 fprintf(stderr, "mul\n"); 524 break; 525 526 case DW_OP_neg: 527 *sp = 0 - *sp; 528 if (log) 529 fprintf(stderr, "neg\n"); 530 break; 531 532 case DW_OP_not: 533 svalue = (sint_t)(*sp); 534 *sp = (pint_t)(~svalue); 535 if (log) 536 fprintf(stderr, "not\n"); 537 break; 538 539 case DW_OP_or: 540 value = *sp--; 541 *sp |= value; 542 if (log) 543 fprintf(stderr, "or\n"); 544 break; 545 546 case DW_OP_plus: 547 value = *sp--; 548 *sp += value; 549 if (log) 550 fprintf(stderr, "plus\n"); 551 break; 552 553 case DW_OP_plus_uconst: 554 // pop stack, add uelb128 constant, push result 555 *sp += static_cast<pint_t>(addressSpace.getULEB128(p, expressionEnd)); 556 if (log) 557 fprintf(stderr, "add constant\n"); 558 break; 559 560 case DW_OP_shl: 561 value = *sp--; 562 *sp = *sp << value; 563 if (log) 564 fprintf(stderr, "shift left\n"); 565 break; 566 567 case DW_OP_shr: 568 value = *sp--; 569 *sp = *sp >> value; 570 if (log) 571 fprintf(stderr, "shift left\n"); 572 break; 573 574 case DW_OP_shra: 575 value = *sp--; 576 svalue = (sint_t)*sp; 577 *sp = (pint_t)(svalue >> value); 578 if (log) 579 fprintf(stderr, "shift left arithmetric\n"); 580 break; 581 582 case DW_OP_xor: 583 value = *sp--; 584 *sp ^= value; 585 if (log) 586 fprintf(stderr, "xor\n"); 587 break; 588 589 case DW_OP_skip: 590 svalue = (int16_t) addressSpace.get16(p); 591 p += 2; 592 p = (pint_t)((sint_t)p + svalue); 593 if (log) 594 fprintf(stderr, "skip %" PRIu64 "\n", (uint64_t)svalue); 595 break; 596 597 case DW_OP_bra: 598 svalue = (int16_t) addressSpace.get16(p); 599 p += 2; 600 if (*sp--) 601 p = (pint_t)((sint_t)p + svalue); 602 if (log) 603 fprintf(stderr, "bra %" PRIu64 "\n", (uint64_t)svalue); 604 break; 605 606 case DW_OP_eq: 607 value = *sp--; 608 *sp = (*sp == value); 609 if (log) 610 fprintf(stderr, "eq\n"); 611 break; 612 613 case DW_OP_ge: 614 value = *sp--; 615 *sp = (*sp >= value); 616 if (log) 617 fprintf(stderr, "ge\n"); 618 break; 619 620 case DW_OP_gt: 621 value = *sp--; 622 *sp = (*sp > value); 623 if (log) 624 fprintf(stderr, "gt\n"); 625 break; 626 627 case DW_OP_le: 628 value = *sp--; 629 *sp = (*sp <= value); 630 if (log) 631 fprintf(stderr, "le\n"); 632 break; 633 634 case DW_OP_lt: 635 value = *sp--; 636 *sp = (*sp < value); 637 if (log) 638 fprintf(stderr, "lt\n"); 639 break; 640 641 case DW_OP_ne: 642 value = *sp--; 643 *sp = (*sp != value); 644 if (log) 645 fprintf(stderr, "ne\n"); 646 break; 647 648 case DW_OP_lit0: 649 case DW_OP_lit1: 650 case DW_OP_lit2: 651 case DW_OP_lit3: 652 case DW_OP_lit4: 653 case DW_OP_lit5: 654 case DW_OP_lit6: 655 case DW_OP_lit7: 656 case DW_OP_lit8: 657 case DW_OP_lit9: 658 case DW_OP_lit10: 659 case DW_OP_lit11: 660 case DW_OP_lit12: 661 case DW_OP_lit13: 662 case DW_OP_lit14: 663 case DW_OP_lit15: 664 case DW_OP_lit16: 665 case DW_OP_lit17: 666 case DW_OP_lit18: 667 case DW_OP_lit19: 668 case DW_OP_lit20: 669 case DW_OP_lit21: 670 case DW_OP_lit22: 671 case DW_OP_lit23: 672 case DW_OP_lit24: 673 case DW_OP_lit25: 674 case DW_OP_lit26: 675 case DW_OP_lit27: 676 case DW_OP_lit28: 677 case DW_OP_lit29: 678 case DW_OP_lit30: 679 case DW_OP_lit31: 680 value = static_cast<pint_t>(opcode - DW_OP_lit0); 681 *(++sp) = value; 682 if (log) 683 fprintf(stderr, "push literal 0x%" PRIx64 "\n", (uint64_t)value); 684 break; 685 686 case DW_OP_reg0: 687 case DW_OP_reg1: 688 case DW_OP_reg2: 689 case DW_OP_reg3: 690 case DW_OP_reg4: 691 case DW_OP_reg5: 692 case DW_OP_reg6: 693 case DW_OP_reg7: 694 case DW_OP_reg8: 695 case DW_OP_reg9: 696 case DW_OP_reg10: 697 case DW_OP_reg11: 698 case DW_OP_reg12: 699 case DW_OP_reg13: 700 case DW_OP_reg14: 701 case DW_OP_reg15: 702 case DW_OP_reg16: 703 case DW_OP_reg17: 704 case DW_OP_reg18: 705 case DW_OP_reg19: 706 case DW_OP_reg20: 707 case DW_OP_reg21: 708 case DW_OP_reg22: 709 case DW_OP_reg23: 710 case DW_OP_reg24: 711 case DW_OP_reg25: 712 case DW_OP_reg26: 713 case DW_OP_reg27: 714 case DW_OP_reg28: 715 case DW_OP_reg29: 716 case DW_OP_reg30: 717 case DW_OP_reg31: 718 reg = static_cast<uint32_t>(opcode - DW_OP_reg0); 719 *(++sp) = registers.getRegister((int)reg); 720 if (log) 721 fprintf(stderr, "push reg %d\n", reg); 722 break; 723 724 case DW_OP_regx: 725 reg = static_cast<uint32_t>(addressSpace.getULEB128(p, expressionEnd)); 726 *(++sp) = registers.getRegister((int)reg); 727 if (log) 728 fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue); 729 break; 730 731 case DW_OP_breg0: 732 case DW_OP_breg1: 733 case DW_OP_breg2: 734 case DW_OP_breg3: 735 case DW_OP_breg4: 736 case DW_OP_breg5: 737 case DW_OP_breg6: 738 case DW_OP_breg7: 739 case DW_OP_breg8: 740 case DW_OP_breg9: 741 case DW_OP_breg10: 742 case DW_OP_breg11: 743 case DW_OP_breg12: 744 case DW_OP_breg13: 745 case DW_OP_breg14: 746 case DW_OP_breg15: 747 case DW_OP_breg16: 748 case DW_OP_breg17: 749 case DW_OP_breg18: 750 case DW_OP_breg19: 751 case DW_OP_breg20: 752 case DW_OP_breg21: 753 case DW_OP_breg22: 754 case DW_OP_breg23: 755 case DW_OP_breg24: 756 case DW_OP_breg25: 757 case DW_OP_breg26: 758 case DW_OP_breg27: 759 case DW_OP_breg28: 760 case DW_OP_breg29: 761 case DW_OP_breg30: 762 case DW_OP_breg31: 763 reg = static_cast<uint32_t>(opcode - DW_OP_breg0); 764 svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd); 765 svalue += static_cast<sint_t>(registers.getRegister((int)reg)); 766 *(++sp) = (pint_t)(svalue); 767 if (log) 768 fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue); 769 break; 770 771 case DW_OP_bregx: 772 reg = static_cast<uint32_t>(addressSpace.getULEB128(p, expressionEnd)); 773 svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd); 774 svalue += static_cast<sint_t>(registers.getRegister((int)reg)); 775 *(++sp) = (pint_t)(svalue); 776 if (log) 777 fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue); 778 break; 779 780 case DW_OP_fbreg: 781 _LIBUNWIND_ABORT("DW_OP_fbreg not implemented"); 782 break; 783 784 case DW_OP_piece: 785 _LIBUNWIND_ABORT("DW_OP_piece not implemented"); 786 break; 787 788 case DW_OP_deref_size: 789 // pop stack, dereference, push result 790 value = *sp--; 791 switch (addressSpace.get8(p++)) { 792 case 1: 793 value = addressSpace.get8(value); 794 break; 795 case 2: 796 value = addressSpace.get16(value); 797 break; 798 case 4: 799 value = addressSpace.get32(value); 800 break; 801 case 8: 802 value = (pint_t)addressSpace.get64(value); 803 break; 804 default: 805 _LIBUNWIND_ABORT("DW_OP_deref_size with bad size"); 806 } 807 *(++sp) = value; 808 if (log) 809 fprintf(stderr, "sized dereference 0x%" PRIx64 "\n", (uint64_t)value); 810 break; 811 812 case DW_OP_xderef_size: 813 case DW_OP_nop: 814 case DW_OP_push_object_addres: 815 case DW_OP_call2: 816 case DW_OP_call4: 817 case DW_OP_call_ref: 818 default: 819 _LIBUNWIND_ABORT("DWARF opcode not implemented"); 820 } 821 822 } 823 if (log) 824 fprintf(stderr, "expression evaluates to 0x%" PRIx64 "\n", (uint64_t)*sp); 825 return *sp; 826 } 827 828 829 830 } // namespace libunwind 831 832 #endif // __DWARF_INSTRUCTIONS_HPP__ 833