1 //===-------------------------- DwarfInstructions.hpp ---------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 // 9 // Processor specific interpretation of dwarf unwind info. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef __DWARF_INSTRUCTIONS_HPP__ 14 #define __DWARF_INSTRUCTIONS_HPP__ 15 16 #include <stdint.h> 17 #include <stdio.h> 18 #include <stdlib.h> 19 20 #include "dwarf2.h" 21 #include "AddressSpace.hpp" 22 #include "Registers.hpp" 23 #include "DwarfParser.hpp" 24 #include "config.h" 25 26 27 namespace libunwind { 28 29 30 /// DwarfInstructions maps abtract dwarf unwind instructions to a particular 31 /// architecture 32 template <typename A, typename R> 33 class DwarfInstructions { 34 public: 35 typedef typename A::pint_t pint_t; 36 typedef typename A::sint_t sint_t; 37 38 static int stepWithDwarf(A &addressSpace, pint_t pc, pint_t fdeStart, 39 R ®isters); 40 41 private: 42 43 enum { 44 DW_X86_64_RET_ADDR = 16 45 }; 46 47 enum { 48 DW_X86_RET_ADDR = 8 49 }; 50 51 typedef typename CFI_Parser<A>::RegisterLocation RegisterLocation; 52 typedef typename CFI_Parser<A>::PrologInfo PrologInfo; 53 typedef typename CFI_Parser<A>::FDE_Info FDE_Info; 54 typedef typename CFI_Parser<A>::CIE_Info CIE_Info; 55 56 static pint_t evaluateExpression(pint_t expression, A &addressSpace, 57 const R ®isters, 58 pint_t initialStackValue); 59 static pint_t getSavedRegister(A &addressSpace, const R ®isters, 60 pint_t cfa, const RegisterLocation &savedReg); 61 static double getSavedFloatRegister(A &addressSpace, const R ®isters, 62 pint_t cfa, const RegisterLocation &savedReg); 63 static v128 getSavedVectorRegister(A &addressSpace, const R ®isters, 64 pint_t cfa, const RegisterLocation &savedReg); 65 66 static pint_t getCFA(A &addressSpace, const PrologInfo &prolog, 67 const R ®isters) { 68 if (prolog.cfaRegister != 0) 69 return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister) + 70 prolog.cfaRegisterOffset); 71 if (prolog.cfaExpression != 0) 72 return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace, 73 registers, 0); 74 assert(0 && "getCFA(): unknown location"); 75 __builtin_unreachable(); 76 } 77 }; 78 79 80 template <typename A, typename R> 81 typename A::pint_t DwarfInstructions<A, R>::getSavedRegister( 82 A &addressSpace, const R ®isters, pint_t cfa, 83 const RegisterLocation &savedReg) { 84 switch (savedReg.location) { 85 case CFI_Parser<A>::kRegisterInCFA: 86 return addressSpace.getP(cfa + (pint_t)savedReg.value); 87 88 case CFI_Parser<A>::kRegisterAtExpression: 89 return addressSpace.getP( 90 evaluateExpression((pint_t)savedReg.value, addressSpace, 91 registers, cfa)); 92 93 case CFI_Parser<A>::kRegisterIsExpression: 94 return evaluateExpression((pint_t)savedReg.value, addressSpace, 95 registers, cfa); 96 97 case CFI_Parser<A>::kRegisterInRegister: 98 return registers.getRegister((int)savedReg.value); 99 100 case CFI_Parser<A>::kRegisterUnused: 101 case CFI_Parser<A>::kRegisterOffsetFromCFA: 102 // FIX ME 103 break; 104 } 105 _LIBUNWIND_ABORT("unsupported restore location for register"); 106 } 107 108 template <typename A, typename R> 109 double DwarfInstructions<A, R>::getSavedFloatRegister( 110 A &addressSpace, const R ®isters, pint_t cfa, 111 const RegisterLocation &savedReg) { 112 switch (savedReg.location) { 113 case CFI_Parser<A>::kRegisterInCFA: 114 return addressSpace.getDouble(cfa + (pint_t)savedReg.value); 115 116 case CFI_Parser<A>::kRegisterAtExpression: 117 return addressSpace.getDouble( 118 evaluateExpression((pint_t)savedReg.value, addressSpace, 119 registers, cfa)); 120 121 case CFI_Parser<A>::kRegisterIsExpression: 122 case CFI_Parser<A>::kRegisterUnused: 123 case CFI_Parser<A>::kRegisterOffsetFromCFA: 124 case CFI_Parser<A>::kRegisterInRegister: 125 // FIX ME 126 break; 127 } 128 _LIBUNWIND_ABORT("unsupported restore location for float register"); 129 } 130 131 template <typename A, typename R> 132 v128 DwarfInstructions<A, R>::getSavedVectorRegister( 133 A &addressSpace, const R ®isters, pint_t cfa, 134 const RegisterLocation &savedReg) { 135 switch (savedReg.location) { 136 case CFI_Parser<A>::kRegisterInCFA: 137 return addressSpace.getVector(cfa + (pint_t)savedReg.value); 138 139 case CFI_Parser<A>::kRegisterAtExpression: 140 return addressSpace.getVector( 141 evaluateExpression((pint_t)savedReg.value, addressSpace, 142 registers, cfa)); 143 144 case CFI_Parser<A>::kRegisterIsExpression: 145 case CFI_Parser<A>::kRegisterUnused: 146 case CFI_Parser<A>::kRegisterOffsetFromCFA: 147 case CFI_Parser<A>::kRegisterInRegister: 148 // FIX ME 149 break; 150 } 151 _LIBUNWIND_ABORT("unsupported restore location for vector register"); 152 } 153 154 template <typename A, typename R> 155 int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc, 156 pint_t fdeStart, R ®isters) { 157 FDE_Info fdeInfo; 158 CIE_Info cieInfo; 159 if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo, 160 &cieInfo) == NULL) { 161 PrologInfo prolog; 162 if (CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, pc, 163 &prolog)) { 164 // get pointer to cfa (architecture specific) 165 pint_t cfa = getCFA(addressSpace, prolog, registers); 166 167 // restore registers that dwarf says were saved 168 R newRegisters = registers; 169 pint_t returnAddress = 0; 170 const int lastReg = R::lastDwarfRegNum(); 171 assert((int)CFI_Parser<A>::kMaxRegisterNumber > lastReg && 172 "register range too large"); 173 assert(lastReg <= (int)cieInfo.returnAddressRegister && 174 "register range does not contain return address register"); 175 for (int i = 0; i <= lastReg; ++i) { 176 if (prolog.savedRegisters[i].location != 177 CFI_Parser<A>::kRegisterUnused) { 178 if (registers.validFloatRegister(i)) 179 newRegisters.setFloatRegister( 180 i, getSavedFloatRegister(addressSpace, registers, cfa, 181 prolog.savedRegisters[i])); 182 else if (registers.validVectorRegister(i)) 183 newRegisters.setVectorRegister( 184 i, getSavedVectorRegister(addressSpace, registers, cfa, 185 prolog.savedRegisters[i])); 186 else if (i == (int)cieInfo.returnAddressRegister) 187 returnAddress = getSavedRegister(addressSpace, registers, cfa, 188 prolog.savedRegisters[i]); 189 else if (registers.validRegister(i)) 190 newRegisters.setRegister( 191 i, getSavedRegister(addressSpace, registers, cfa, 192 prolog.savedRegisters[i])); 193 else 194 return UNW_EBADREG; 195 } 196 } 197 198 // By definition, the CFA is the stack pointer at the call site, so 199 // restoring SP means setting it to CFA. 200 newRegisters.setSP(cfa); 201 202 // Return address is address after call site instruction, so setting IP to 203 // that does simualates a return. 204 newRegisters.setIP(returnAddress); 205 206 // Simulate the step by replacing the register set with the new ones. 207 registers = newRegisters; 208 209 return UNW_STEP_SUCCESS; 210 } 211 } 212 return UNW_EBADFRAME; 213 } 214 215 template <typename A, typename R> 216 typename A::pint_t 217 DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace, 218 const R ®isters, 219 pint_t initialStackValue) { 220 const bool log = false; 221 pint_t p = expression; 222 pint_t expressionEnd = expression + 20; // temp, until len read 223 pint_t length = (pint_t)addressSpace.getULEB128(p, expressionEnd); 224 expressionEnd = p + length; 225 if (log) 226 fprintf(stderr, "evaluateExpression(): length=%" PRIu64 "\n", 227 (uint64_t)length); 228 pint_t stack[100]; 229 pint_t *sp = stack; 230 *(++sp) = initialStackValue; 231 232 while (p < expressionEnd) { 233 if (log) { 234 for (pint_t *t = sp; t > stack; --t) { 235 fprintf(stderr, "sp[] = 0x%" PRIx64 "\n", (uint64_t)(*t)); 236 } 237 } 238 uint8_t opcode = addressSpace.get8(p++); 239 sint_t svalue, svalue2; 240 pint_t value; 241 uint32_t reg; 242 switch (opcode) { 243 case DW_OP_addr: 244 // push immediate address sized value 245 value = addressSpace.getP(p); 246 p += sizeof(pint_t); 247 *(++sp) = value; 248 if (log) 249 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 250 break; 251 252 case DW_OP_deref: 253 // pop stack, dereference, push result 254 value = *sp--; 255 *(++sp) = addressSpace.getP(value); 256 if (log) 257 fprintf(stderr, "dereference 0x%" PRIx64 "\n", (uint64_t)value); 258 break; 259 260 case DW_OP_const1u: 261 // push immediate 1 byte value 262 value = addressSpace.get8(p); 263 p += 1; 264 *(++sp) = value; 265 if (log) 266 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 267 break; 268 269 case DW_OP_const1s: 270 // push immediate 1 byte signed value 271 svalue = (int8_t) addressSpace.get8(p); 272 p += 1; 273 *(++sp) = (pint_t)svalue; 274 if (log) 275 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue); 276 break; 277 278 case DW_OP_const2u: 279 // push immediate 2 byte value 280 value = addressSpace.get16(p); 281 p += 2; 282 *(++sp) = value; 283 if (log) 284 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 285 break; 286 287 case DW_OP_const2s: 288 // push immediate 2 byte signed value 289 svalue = (int16_t) addressSpace.get16(p); 290 p += 2; 291 *(++sp) = (pint_t)svalue; 292 if (log) 293 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue); 294 break; 295 296 case DW_OP_const4u: 297 // push immediate 4 byte value 298 value = addressSpace.get32(p); 299 p += 4; 300 *(++sp) = value; 301 if (log) 302 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 303 break; 304 305 case DW_OP_const4s: 306 // push immediate 4 byte signed value 307 svalue = (int32_t)addressSpace.get32(p); 308 p += 4; 309 *(++sp) = (pint_t)svalue; 310 if (log) 311 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue); 312 break; 313 314 case DW_OP_const8u: 315 // push immediate 8 byte value 316 value = (pint_t)addressSpace.get64(p); 317 p += 8; 318 *(++sp) = value; 319 if (log) 320 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 321 break; 322 323 case DW_OP_const8s: 324 // push immediate 8 byte signed value 325 value = (pint_t)addressSpace.get64(p); 326 p += 8; 327 *(++sp) = value; 328 if (log) 329 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 330 break; 331 332 case DW_OP_constu: 333 // push immediate ULEB128 value 334 value = (pint_t)addressSpace.getULEB128(p, expressionEnd); 335 *(++sp) = value; 336 if (log) 337 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 338 break; 339 340 case DW_OP_consts: 341 // push immediate SLEB128 value 342 svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd); 343 *(++sp) = (pint_t)svalue; 344 if (log) 345 fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue); 346 break; 347 348 case DW_OP_dup: 349 // push top of stack 350 value = *sp; 351 *(++sp) = value; 352 if (log) 353 fprintf(stderr, "duplicate top of stack\n"); 354 break; 355 356 case DW_OP_drop: 357 // pop 358 --sp; 359 if (log) 360 fprintf(stderr, "pop top of stack\n"); 361 break; 362 363 case DW_OP_over: 364 // dup second 365 value = sp[-1]; 366 *(++sp) = value; 367 if (log) 368 fprintf(stderr, "duplicate second in stack\n"); 369 break; 370 371 case DW_OP_pick: 372 // pick from 373 reg = addressSpace.get8(p); 374 p += 1; 375 value = sp[-reg]; 376 *(++sp) = value; 377 if (log) 378 fprintf(stderr, "duplicate %d in stack\n", reg); 379 break; 380 381 case DW_OP_swap: 382 // swap top two 383 value = sp[0]; 384 sp[0] = sp[-1]; 385 sp[-1] = value; 386 if (log) 387 fprintf(stderr, "swap top of stack\n"); 388 break; 389 390 case DW_OP_rot: 391 // rotate top three 392 value = sp[0]; 393 sp[0] = sp[-1]; 394 sp[-1] = sp[-2]; 395 sp[-2] = value; 396 if (log) 397 fprintf(stderr, "rotate top three of stack\n"); 398 break; 399 400 case DW_OP_xderef: 401 // pop stack, dereference, push result 402 value = *sp--; 403 *sp = *((pint_t*)value); 404 if (log) 405 fprintf(stderr, "x-dereference 0x%" PRIx64 "\n", (uint64_t)value); 406 break; 407 408 case DW_OP_abs: 409 svalue = (sint_t)*sp; 410 if (svalue < 0) 411 *sp = (pint_t)(-svalue); 412 if (log) 413 fprintf(stderr, "abs\n"); 414 break; 415 416 case DW_OP_and: 417 value = *sp--; 418 *sp &= value; 419 if (log) 420 fprintf(stderr, "and\n"); 421 break; 422 423 case DW_OP_div: 424 svalue = (sint_t)(*sp--); 425 svalue2 = (sint_t)*sp; 426 *sp = (pint_t)(svalue2 / svalue); 427 if (log) 428 fprintf(stderr, "div\n"); 429 break; 430 431 case DW_OP_minus: 432 value = *sp--; 433 *sp = *sp - value; 434 if (log) 435 fprintf(stderr, "minus\n"); 436 break; 437 438 case DW_OP_mod: 439 svalue = (sint_t)(*sp--); 440 svalue2 = (sint_t)*sp; 441 *sp = (pint_t)(svalue2 % svalue); 442 if (log) 443 fprintf(stderr, "module\n"); 444 break; 445 446 case DW_OP_mul: 447 svalue = (sint_t)(*sp--); 448 svalue2 = (sint_t)*sp; 449 *sp = (pint_t)(svalue2 * svalue); 450 if (log) 451 fprintf(stderr, "mul\n"); 452 break; 453 454 case DW_OP_neg: 455 *sp = 0 - *sp; 456 if (log) 457 fprintf(stderr, "neg\n"); 458 break; 459 460 case DW_OP_not: 461 svalue = (sint_t)(*sp); 462 *sp = (pint_t)(~svalue); 463 if (log) 464 fprintf(stderr, "not\n"); 465 break; 466 467 case DW_OP_or: 468 value = *sp--; 469 *sp |= value; 470 if (log) 471 fprintf(stderr, "or\n"); 472 break; 473 474 case DW_OP_plus: 475 value = *sp--; 476 *sp += value; 477 if (log) 478 fprintf(stderr, "plus\n"); 479 break; 480 481 case DW_OP_plus_uconst: 482 // pop stack, add uelb128 constant, push result 483 *sp += addressSpace.getULEB128(p, expressionEnd); 484 if (log) 485 fprintf(stderr, "add constant\n"); 486 break; 487 488 case DW_OP_shl: 489 value = *sp--; 490 *sp = *sp << value; 491 if (log) 492 fprintf(stderr, "shift left\n"); 493 break; 494 495 case DW_OP_shr: 496 value = *sp--; 497 *sp = *sp >> value; 498 if (log) 499 fprintf(stderr, "shift left\n"); 500 break; 501 502 case DW_OP_shra: 503 value = *sp--; 504 svalue = (sint_t)*sp; 505 *sp = (pint_t)(svalue >> value); 506 if (log) 507 fprintf(stderr, "shift left arithmetric\n"); 508 break; 509 510 case DW_OP_xor: 511 value = *sp--; 512 *sp ^= value; 513 if (log) 514 fprintf(stderr, "xor\n"); 515 break; 516 517 case DW_OP_skip: 518 svalue = (int16_t) addressSpace.get16(p); 519 p += 2; 520 p = (pint_t)((sint_t)p + svalue); 521 if (log) 522 fprintf(stderr, "skip %" PRIu64 "\n", (uint64_t)svalue); 523 break; 524 525 case DW_OP_bra: 526 svalue = (int16_t) addressSpace.get16(p); 527 p += 2; 528 if (*sp--) 529 p = (pint_t)((sint_t)p + svalue); 530 if (log) 531 fprintf(stderr, "bra %" PRIu64 "\n", (uint64_t)svalue); 532 break; 533 534 case DW_OP_eq: 535 value = *sp--; 536 *sp = (*sp == value); 537 if (log) 538 fprintf(stderr, "eq\n"); 539 break; 540 541 case DW_OP_ge: 542 value = *sp--; 543 *sp = (*sp >= value); 544 if (log) 545 fprintf(stderr, "ge\n"); 546 break; 547 548 case DW_OP_gt: 549 value = *sp--; 550 *sp = (*sp > value); 551 if (log) 552 fprintf(stderr, "gt\n"); 553 break; 554 555 case DW_OP_le: 556 value = *sp--; 557 *sp = (*sp <= value); 558 if (log) 559 fprintf(stderr, "le\n"); 560 break; 561 562 case DW_OP_lt: 563 value = *sp--; 564 *sp = (*sp < value); 565 if (log) 566 fprintf(stderr, "lt\n"); 567 break; 568 569 case DW_OP_ne: 570 value = *sp--; 571 *sp = (*sp != value); 572 if (log) 573 fprintf(stderr, "ne\n"); 574 break; 575 576 case DW_OP_lit0: 577 case DW_OP_lit1: 578 case DW_OP_lit2: 579 case DW_OP_lit3: 580 case DW_OP_lit4: 581 case DW_OP_lit5: 582 case DW_OP_lit6: 583 case DW_OP_lit7: 584 case DW_OP_lit8: 585 case DW_OP_lit9: 586 case DW_OP_lit10: 587 case DW_OP_lit11: 588 case DW_OP_lit12: 589 case DW_OP_lit13: 590 case DW_OP_lit14: 591 case DW_OP_lit15: 592 case DW_OP_lit16: 593 case DW_OP_lit17: 594 case DW_OP_lit18: 595 case DW_OP_lit19: 596 case DW_OP_lit20: 597 case DW_OP_lit21: 598 case DW_OP_lit22: 599 case DW_OP_lit23: 600 case DW_OP_lit24: 601 case DW_OP_lit25: 602 case DW_OP_lit26: 603 case DW_OP_lit27: 604 case DW_OP_lit28: 605 case DW_OP_lit29: 606 case DW_OP_lit30: 607 case DW_OP_lit31: 608 value = static_cast<pint_t>(opcode - DW_OP_lit0); 609 *(++sp) = value; 610 if (log) 611 fprintf(stderr, "push literal 0x%" PRIx64 "\n", (uint64_t)value); 612 break; 613 614 case DW_OP_reg0: 615 case DW_OP_reg1: 616 case DW_OP_reg2: 617 case DW_OP_reg3: 618 case DW_OP_reg4: 619 case DW_OP_reg5: 620 case DW_OP_reg6: 621 case DW_OP_reg7: 622 case DW_OP_reg8: 623 case DW_OP_reg9: 624 case DW_OP_reg10: 625 case DW_OP_reg11: 626 case DW_OP_reg12: 627 case DW_OP_reg13: 628 case DW_OP_reg14: 629 case DW_OP_reg15: 630 case DW_OP_reg16: 631 case DW_OP_reg17: 632 case DW_OP_reg18: 633 case DW_OP_reg19: 634 case DW_OP_reg20: 635 case DW_OP_reg21: 636 case DW_OP_reg22: 637 case DW_OP_reg23: 638 case DW_OP_reg24: 639 case DW_OP_reg25: 640 case DW_OP_reg26: 641 case DW_OP_reg27: 642 case DW_OP_reg28: 643 case DW_OP_reg29: 644 case DW_OP_reg30: 645 case DW_OP_reg31: 646 reg = static_cast<uint32_t>(opcode - DW_OP_reg0); 647 *(++sp) = registers.getRegister((int)reg); 648 if (log) 649 fprintf(stderr, "push reg %d\n", reg); 650 break; 651 652 case DW_OP_regx: 653 reg = static_cast<uint32_t>(addressSpace.getULEB128(p, expressionEnd)); 654 *(++sp) = registers.getRegister((int)reg); 655 if (log) 656 fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue); 657 break; 658 659 case DW_OP_breg0: 660 case DW_OP_breg1: 661 case DW_OP_breg2: 662 case DW_OP_breg3: 663 case DW_OP_breg4: 664 case DW_OP_breg5: 665 case DW_OP_breg6: 666 case DW_OP_breg7: 667 case DW_OP_breg8: 668 case DW_OP_breg9: 669 case DW_OP_breg10: 670 case DW_OP_breg11: 671 case DW_OP_breg12: 672 case DW_OP_breg13: 673 case DW_OP_breg14: 674 case DW_OP_breg15: 675 case DW_OP_breg16: 676 case DW_OP_breg17: 677 case DW_OP_breg18: 678 case DW_OP_breg19: 679 case DW_OP_breg20: 680 case DW_OP_breg21: 681 case DW_OP_breg22: 682 case DW_OP_breg23: 683 case DW_OP_breg24: 684 case DW_OP_breg25: 685 case DW_OP_breg26: 686 case DW_OP_breg27: 687 case DW_OP_breg28: 688 case DW_OP_breg29: 689 case DW_OP_breg30: 690 case DW_OP_breg31: 691 reg = static_cast<uint32_t>(opcode - DW_OP_breg0); 692 svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd); 693 svalue += static_cast<sint_t>(registers.getRegister((int)reg)); 694 *(++sp) = (pint_t)(svalue); 695 if (log) 696 fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue); 697 break; 698 699 case DW_OP_bregx: 700 reg = static_cast<uint32_t>(addressSpace.getULEB128(p, expressionEnd)); 701 svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd); 702 svalue += static_cast<sint_t>(registers.getRegister((int)reg)); 703 *(++sp) = (pint_t)(svalue); 704 if (log) 705 fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue); 706 break; 707 708 case DW_OP_fbreg: 709 _LIBUNWIND_ABORT("DW_OP_fbreg not implemented"); 710 break; 711 712 case DW_OP_piece: 713 _LIBUNWIND_ABORT("DW_OP_piece not implemented"); 714 break; 715 716 case DW_OP_deref_size: 717 // pop stack, dereference, push result 718 value = *sp--; 719 switch (addressSpace.get8(p++)) { 720 case 1: 721 value = addressSpace.get8(value); 722 break; 723 case 2: 724 value = addressSpace.get16(value); 725 break; 726 case 4: 727 value = addressSpace.get32(value); 728 break; 729 case 8: 730 value = (pint_t)addressSpace.get64(value); 731 break; 732 default: 733 _LIBUNWIND_ABORT("DW_OP_deref_size with bad size"); 734 } 735 *(++sp) = value; 736 if (log) 737 fprintf(stderr, "sized dereference 0x%" PRIx64 "\n", (uint64_t)value); 738 break; 739 740 case DW_OP_xderef_size: 741 case DW_OP_nop: 742 case DW_OP_push_object_addres: 743 case DW_OP_call2: 744 case DW_OP_call4: 745 case DW_OP_call_ref: 746 default: 747 _LIBUNWIND_ABORT("dwarf opcode not implemented"); 748 } 749 750 } 751 if (log) 752 fprintf(stderr, "expression evaluates to 0x%" PRIx64 "\n", (uint64_t)*sp); 753 return *sp; 754 } 755 756 757 758 } // namespace libunwind 759 760 #endif // __DWARF_INSTRUCTIONS_HPP__ 761