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