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