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