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