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