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