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