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