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