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 <cstdint> 17 #include <cstdlib> 18 19 #include "dwarf2.h" 20 #include "AddressSpace.hpp" 21 #include "Registers.hpp" 22 #include "DwarfParser.hpp" 23 24 namespace _Unwind { 25 26 enum step_result { 27 UNW_STEP_SUCCESS, 28 UNW_STEP_END, 29 UNW_STEP_FAILED 30 }; 31 32 /// DwarfInstructions maps abtract dwarf unwind instructions to a particular 33 /// architecture 34 template <typename A, typename R> class DwarfInstructions { 35 public: 36 typedef typename A::pint_t pint_t; 37 typedef typename A::sint_t sint_t; 38 39 static step_result stepWithDwarf(A &, pint_t, pint_t, R &, unw_proc_info_t *); 40 41 private: 42 // Pseudo-register used for return addresses. 43 enum { 44 DW_X86_RET_ADDR = 8, 45 DW_X86_64_RET_ADDR = 16, 46 }; 47 48 static pint_t evaluateExpression(pint_t, A &, const R &, pint_t); 49 static pint_t 50 getSavedRegister(A &, const R &, pint_t, 51 const typename CFI_Parser<A, R>::RegisterLocation &); 52 static pint_t 53 computeRegisterLocation(A &, const R &, pint_t, 54 const typename CFI_Parser<A, R>::RegisterLocation &); 55 56 static int lastRestoreReg(const R &) { return R::LAST_RESTORE_REG; } 57 static bool isReturnAddressRegister(int regno, const R &) { 58 return regno == R::IP_PSEUDO_REG; 59 } 60 61 static pint_t getCFA(A &addressSpace, 62 const typename CFI_Parser<A, R>::PrologInfo &prolog, 63 const R ®isters) { 64 if (prolog.cfaRegister != 0) 65 return registers.getRegister(prolog.cfaRegister) + 66 prolog.cfaRegisterOffset; 67 if (prolog.cfaExpression != 0) 68 return evaluateExpression(prolog.cfaExpression, addressSpace, registers, 69 0); 70 assert(0 && "getCFA(): unknown location"); 71 __builtin_unreachable(); 72 } 73 }; 74 75 template <typename A, typename R> 76 typename A::pint_t DwarfInstructions<A, R>::getSavedRegister( 77 A &addressSpace, const R ®isters, pint_t cfa, 78 const typename CFI_Parser<A, R>::RegisterLocation &savedReg) { 79 switch (savedReg.location) { 80 case CFI_Parser<A, R>::kRegisterInCFA: 81 return addressSpace.getP(cfa + savedReg.value); 82 83 case CFI_Parser<A, R>::kRegisterAtExpression: 84 return addressSpace.getP( 85 evaluateExpression(savedReg.value, addressSpace, registers, cfa)); 86 87 case CFI_Parser<A, R>::kRegisterIsExpression: 88 return evaluateExpression(savedReg.value, addressSpace, registers, cfa); 89 90 case CFI_Parser<A, R>::kRegisterInRegister: 91 return registers.getRegister(savedReg.value); 92 93 case CFI_Parser<A, R>::kRegisterUnused: 94 case CFI_Parser<A, R>::kRegisterOffsetFromCFA: 95 assert(0 && "unsupported restore location for register"); 96 } 97 __builtin_unreachable(); 98 } 99 100 template <typename A, typename R> 101 typename DwarfInstructions<A, R>::pint_t 102 DwarfInstructions<A, R>::computeRegisterLocation( 103 A &addressSpace, const R ®isters, pint_t cfa, 104 const typename CFI_Parser<A, R>::RegisterLocation &savedReg) { 105 switch (savedReg.location) { 106 case CFI_Parser<A, R>::kRegisterInCFA: 107 return cfa + savedReg.value; 108 109 case CFI_Parser<A, R>::kRegisterAtExpression: 110 return evaluateExpression(savedReg.value, addressSpace, registers, cfa); 111 112 case CFI_Parser<A, R>::kRegisterIsExpression: 113 case CFI_Parser<A, R>::kRegisterUnused: 114 case CFI_Parser<A, R>::kRegisterOffsetFromCFA: 115 case CFI_Parser<A, R>::kRegisterInRegister: 116 assert(0 && "unsupported restore location for float/vector register"); 117 } 118 __builtin_unreachable(); 119 } 120 121 template <typename A, typename R> 122 step_result DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc, 123 pint_t fdeStart, 124 R ®isters, 125 unw_proc_info_t *ctx) { 126 typename CFI_Parser<A, R>::FDE_Info fdeInfo; 127 typename CFI_Parser<A, R>::CIE_Info cieInfo; 128 if (!CFI_Parser<A, R>::decodeFDE(addressSpace, fdeStart, &fdeInfo, &cieInfo, 129 ctx)) 130 return UNW_STEP_FAILED; 131 132 typename CFI_Parser<A, R>::PrologInfo prolog; 133 if (!CFI_Parser<A, R>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, 134 pc, &prolog, ctx)) 135 return UNW_STEP_FAILED; 136 137 // Create working copy of the register set. 138 R newRegisters = registers; 139 140 // Get pointer to CFA by the architecture-specific code. 141 pint_t cfa = getCFA(addressSpace, prolog, registers); 142 143 // Restore registers according to DWARF instructions 144 pint_t returnAddress = 0; 145 for (int i = 0; i <= lastRestoreReg(newRegisters); ++i) { 146 if (prolog.savedRegisters[i].location == CFI_Parser<A, R>::kRegisterUnused) 147 continue; 148 if (isReturnAddressRegister(i, registers)) 149 returnAddress = getSavedRegister(addressSpace, registers, cfa, 150 prolog.savedRegisters[i]); 151 else if (registers.validRegister(i)) 152 newRegisters.setRegister(i, getSavedRegister(addressSpace, registers, cfa, 153 prolog.savedRegisters[i])); 154 else if (registers.validFloatVectorRegister(i)) 155 newRegisters.copyFloatVectorRegister( 156 i, computeRegisterLocation(addressSpace, registers, cfa, 157 prolog.savedRegisters[i])); 158 else 159 return UNW_STEP_FAILED; 160 } 161 162 // The CFA is defined as the stack pointer at the call site. 163 // Therefore the SP is restored by setting it to the CFA. 164 newRegisters.setSP(cfa); 165 newRegisters.setIP(returnAddress); 166 167 // Now replace register set with the working copy. 168 registers = newRegisters; 169 170 return UNW_STEP_SUCCESS; 171 } 172 173 template <typename A, typename R> 174 typename A::pint_t 175 DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace, 176 const R ®isters, 177 pint_t initialStackValue) { 178 pint_t p = expression; 179 pint_t expressionEnd = expression + 20; // Rough estimate 180 uint64_t length = addressSpace.getULEB128(p, expressionEnd); 181 expressionEnd = p + length; 182 pint_t stack[100]; 183 pint_t *sp = stack; 184 *(++sp) = initialStackValue; 185 186 while (p < expressionEnd) { 187 uint8_t opcode = addressSpace.get8(p++); 188 sint_t svalue; 189 pint_t value; 190 uint32_t reg; 191 switch (opcode) { 192 case DW_OP_addr: 193 // push immediate address sized value 194 value = addressSpace.getP(p); 195 p += sizeof(pint_t); 196 *(++sp) = value; 197 break; 198 199 case DW_OP_deref: 200 // pop stack, dereference, push result 201 value = *sp--; 202 *(++sp) = addressSpace.getP(value); 203 break; 204 205 case DW_OP_const1u: 206 // push immediate 1 byte value 207 value = addressSpace.get8(p); 208 p += 1; 209 *(++sp) = value; 210 break; 211 212 case DW_OP_const1s: 213 // push immediate 1 byte signed value 214 svalue = (int8_t)addressSpace.get8(p); 215 p += 1; 216 *(++sp) = svalue; 217 break; 218 219 case DW_OP_const2u: 220 // push immediate 2 byte value 221 value = addressSpace.get16(p); 222 p += 2; 223 *(++sp) = value; 224 break; 225 226 case DW_OP_const2s: 227 // push immediate 2 byte signed value 228 svalue = (int16_t)addressSpace.get16(p); 229 p += 2; 230 *(++sp) = svalue; 231 break; 232 233 case DW_OP_const4u: 234 // push immediate 4 byte value 235 value = addressSpace.get32(p); 236 p += 4; 237 *(++sp) = value; 238 break; 239 240 case DW_OP_const4s: 241 // push immediate 4 byte signed value 242 svalue = (int32_t)addressSpace.get32(p); 243 p += 4; 244 *(++sp) = svalue; 245 break; 246 247 case DW_OP_const8u: 248 // push immediate 8 byte value 249 value = addressSpace.get64(p); 250 p += 8; 251 *(++sp) = value; 252 break; 253 254 case DW_OP_const8s: 255 // push immediate 8 byte signed value 256 value = (int32_t)addressSpace.get64(p); 257 p += 8; 258 *(++sp) = value; 259 break; 260 261 case DW_OP_constu: 262 // push immediate ULEB128 value 263 value = addressSpace.getULEB128(p, expressionEnd); 264 *(++sp) = value; 265 break; 266 267 case DW_OP_consts: 268 // push immediate SLEB128 value 269 svalue = addressSpace.getSLEB128(p, expressionEnd); 270 *(++sp) = svalue; 271 break; 272 273 case DW_OP_dup: 274 // push top of stack 275 value = *sp; 276 *(++sp) = value; 277 break; 278 279 case DW_OP_drop: 280 // pop 281 --sp; 282 break; 283 284 case DW_OP_over: 285 // dup second 286 value = sp[-1]; 287 *(++sp) = value; 288 break; 289 290 case DW_OP_pick: 291 // pick from 292 reg = addressSpace.get8(p); 293 p += 1; 294 value = sp[-reg]; 295 *(++sp) = value; 296 break; 297 298 case DW_OP_swap: 299 // swap top two 300 value = sp[0]; 301 sp[0] = sp[-1]; 302 sp[-1] = value; 303 break; 304 305 case DW_OP_rot: 306 // rotate top three 307 value = sp[0]; 308 sp[0] = sp[-1]; 309 sp[-1] = sp[-2]; 310 sp[-2] = value; 311 break; 312 313 case DW_OP_xderef: 314 // pop stack, dereference, push result 315 value = *sp--; 316 *sp = *((uint64_t *)value); 317 break; 318 319 case DW_OP_abs: 320 svalue = *sp; 321 if (svalue < 0) 322 *sp = -svalue; 323 break; 324 325 case DW_OP_and: 326 value = *sp--; 327 *sp &= value; 328 break; 329 330 case DW_OP_div: 331 svalue = *sp--; 332 *sp = *sp / svalue; 333 break; 334 335 case DW_OP_minus: 336 svalue = *sp--; 337 *sp = *sp - svalue; 338 break; 339 340 case DW_OP_mod: 341 svalue = *sp--; 342 *sp = *sp % svalue; 343 break; 344 345 case DW_OP_mul: 346 svalue = *sp--; 347 *sp = *sp * svalue; 348 break; 349 350 case DW_OP_neg: 351 *sp = 0 - *sp; 352 break; 353 354 case DW_OP_not: 355 svalue = *sp; 356 *sp = ~svalue; 357 break; 358 359 case DW_OP_or: 360 value = *sp--; 361 *sp |= value; 362 break; 363 364 case DW_OP_plus: 365 value = *sp--; 366 *sp += value; 367 break; 368 369 case DW_OP_plus_uconst: 370 // pop stack, add uelb128 constant, push result 371 *sp += addressSpace.getULEB128(p, expressionEnd); 372 break; 373 374 case DW_OP_shl: 375 value = *sp--; 376 *sp = *sp << value; 377 break; 378 379 case DW_OP_shr: 380 value = *sp--; 381 *sp = *sp >> value; 382 break; 383 384 case DW_OP_shra: 385 value = *sp--; 386 svalue = *sp; 387 *sp = svalue >> value; 388 break; 389 390 case DW_OP_xor: 391 value = *sp--; 392 *sp ^= value; 393 break; 394 395 case DW_OP_skip: 396 svalue = (int16_t)addressSpace.get16(p); 397 p += 2; 398 p += svalue; 399 break; 400 401 case DW_OP_bra: 402 svalue = (int16_t)addressSpace.get16(p); 403 p += 2; 404 if (*sp--) 405 p += svalue; 406 break; 407 408 case DW_OP_eq: 409 value = *sp--; 410 *sp = (*sp == value); 411 break; 412 413 case DW_OP_ge: 414 value = *sp--; 415 *sp = (*sp >= value); 416 break; 417 418 case DW_OP_gt: 419 value = *sp--; 420 *sp = (*sp > value); 421 break; 422 423 case DW_OP_le: 424 value = *sp--; 425 *sp = (*sp <= value); 426 break; 427 428 case DW_OP_lt: 429 value = *sp--; 430 *sp = (*sp < value); 431 break; 432 433 case DW_OP_ne: 434 value = *sp--; 435 *sp = (*sp != value); 436 break; 437 438 case DW_OP_lit0: 439 case DW_OP_lit1: 440 case DW_OP_lit2: 441 case DW_OP_lit3: 442 case DW_OP_lit4: 443 case DW_OP_lit5: 444 case DW_OP_lit6: 445 case DW_OP_lit7: 446 case DW_OP_lit8: 447 case DW_OP_lit9: 448 case DW_OP_lit10: 449 case DW_OP_lit11: 450 case DW_OP_lit12: 451 case DW_OP_lit13: 452 case DW_OP_lit14: 453 case DW_OP_lit15: 454 case DW_OP_lit16: 455 case DW_OP_lit17: 456 case DW_OP_lit18: 457 case DW_OP_lit19: 458 case DW_OP_lit20: 459 case DW_OP_lit21: 460 case DW_OP_lit22: 461 case DW_OP_lit23: 462 case DW_OP_lit24: 463 case DW_OP_lit25: 464 case DW_OP_lit26: 465 case DW_OP_lit27: 466 case DW_OP_lit28: 467 case DW_OP_lit29: 468 case DW_OP_lit30: 469 case DW_OP_lit31: 470 value = opcode - DW_OP_lit0; 471 *(++sp) = value; 472 break; 473 474 case DW_OP_reg0: 475 case DW_OP_reg1: 476 case DW_OP_reg2: 477 case DW_OP_reg3: 478 case DW_OP_reg4: 479 case DW_OP_reg5: 480 case DW_OP_reg6: 481 case DW_OP_reg7: 482 case DW_OP_reg8: 483 case DW_OP_reg9: 484 case DW_OP_reg10: 485 case DW_OP_reg11: 486 case DW_OP_reg12: 487 case DW_OP_reg13: 488 case DW_OP_reg14: 489 case DW_OP_reg15: 490 case DW_OP_reg16: 491 case DW_OP_reg17: 492 case DW_OP_reg18: 493 case DW_OP_reg19: 494 case DW_OP_reg20: 495 case DW_OP_reg21: 496 case DW_OP_reg22: 497 case DW_OP_reg23: 498 case DW_OP_reg24: 499 case DW_OP_reg25: 500 case DW_OP_reg26: 501 case DW_OP_reg27: 502 case DW_OP_reg28: 503 case DW_OP_reg29: 504 case DW_OP_reg30: 505 case DW_OP_reg31: 506 reg = opcode - DW_OP_reg0; 507 *(++sp) = registers.getRegister(reg); 508 break; 509 510 case DW_OP_regx: 511 reg = addressSpace.getULEB128(p, expressionEnd); 512 *(++sp) = registers.getRegister(reg); 513 break; 514 515 case DW_OP_breg0: 516 case DW_OP_breg1: 517 case DW_OP_breg2: 518 case DW_OP_breg3: 519 case DW_OP_breg4: 520 case DW_OP_breg5: 521 case DW_OP_breg6: 522 case DW_OP_breg7: 523 case DW_OP_breg8: 524 case DW_OP_breg9: 525 case DW_OP_breg10: 526 case DW_OP_breg11: 527 case DW_OP_breg12: 528 case DW_OP_breg13: 529 case DW_OP_breg14: 530 case DW_OP_breg15: 531 case DW_OP_breg16: 532 case DW_OP_breg17: 533 case DW_OP_breg18: 534 case DW_OP_breg19: 535 case DW_OP_breg20: 536 case DW_OP_breg21: 537 case DW_OP_breg22: 538 case DW_OP_breg23: 539 case DW_OP_breg24: 540 case DW_OP_breg25: 541 case DW_OP_breg26: 542 case DW_OP_breg27: 543 case DW_OP_breg28: 544 case DW_OP_breg29: 545 case DW_OP_breg30: 546 case DW_OP_breg31: 547 reg = opcode - DW_OP_breg0; 548 svalue = addressSpace.getSLEB128(p, expressionEnd); 549 *(++sp) = registers.getRegister(reg) + svalue; 550 break; 551 552 case DW_OP_bregx: 553 reg = addressSpace.getULEB128(p, expressionEnd); 554 svalue = addressSpace.getSLEB128(p, expressionEnd); 555 *(++sp) = registers.getRegister(reg) + svalue; 556 break; 557 558 case DW_OP_deref_size: 559 // pop stack, dereference, push result 560 value = *sp--; 561 switch (addressSpace.get8(p++)) { 562 case 1: 563 value = addressSpace.get8(value); 564 break; 565 case 2: 566 value = addressSpace.get16(value); 567 break; 568 case 4: 569 value = addressSpace.get32(value); 570 break; 571 case 8: 572 value = addressSpace.get64(value); 573 break; 574 default: 575 assert(0 && "DW_OP_deref_size with bad size"); 576 } 577 *(++sp) = value; 578 break; 579 580 case DW_OP_fbreg: 581 case DW_OP_piece: 582 case DW_OP_xderef_size: 583 case DW_OP_nop: 584 case DW_OP_push_object_addres: 585 case DW_OP_call2: 586 case DW_OP_call4: 587 case DW_OP_call_ref: 588 default: 589 assert(0 && "dwarf opcode not implemented"); 590 } 591 } 592 return *sp; 593 } 594 595 } // namespace _Unwind 596 597 #endif // __DWARF_INSTRUCTIONS_HPP__ 598