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