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