1 1.1 joerg //===--------------------------- DwarfParser.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 // Parses DWARF CFIs (FDEs and CIEs). 10 1.1 joerg // 11 1.1 joerg //===----------------------------------------------------------------------===// 12 1.1 joerg 13 1.1 joerg #ifndef __DWARF_PARSER_HPP__ 14 1.1 joerg #define __DWARF_PARSER_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 22 1.1 joerg namespace _Unwind { 23 1.1 joerg 24 1.1 joerg /// CFI_Parser does basic parsing of a CFI (Call Frame Information) records. 25 1.1 joerg /// See Dwarf Spec for details: 26 1.1 joerg /// http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html 27 1.1 joerg /// 28 1.1 joerg template <typename A, typename R> class CFI_Parser { 29 1.1 joerg public: 30 1.1 joerg typedef typename A::pint_t pint_t; 31 1.1 joerg 32 1.1 joerg /// Information encoded in a CIE (Common Information Entry) 33 1.1 joerg struct CIE_Info { 34 1.1 joerg pint_t cieStart; 35 1.1 joerg pint_t cieLength; 36 1.1 joerg pint_t cieInstructions; 37 1.1 joerg pint_t personality; 38 1.1 joerg uint32_t codeAlignFactor; 39 1.1 joerg int dataAlignFactor; 40 1.1 joerg uint8_t pointerEncoding; 41 1.1 joerg uint8_t lsdaEncoding; 42 1.1 joerg uint8_t personalityEncoding; 43 1.1 joerg uint8_t personalityOffsetInCIE; 44 1.1 joerg bool isSignalFrame; 45 1.1 joerg bool fdesHaveAugmentationData; 46 1.4 joerg uint8_t returnAddressRegister; 47 1.1 joerg }; 48 1.1 joerg 49 1.1 joerg /// Information about an FDE (Frame Description Entry) 50 1.1 joerg struct FDE_Info { 51 1.1 joerg pint_t fdeStart; 52 1.1 joerg pint_t fdeLength; 53 1.1 joerg pint_t fdeInstructions; 54 1.1 joerg pint_t pcStart; 55 1.1 joerg pint_t pcEnd; 56 1.1 joerg pint_t lsda; 57 1.1 joerg }; 58 1.1 joerg 59 1.1 joerg /// Information about a frame layout and registers saved determined 60 1.1 joerg /// by "running" the DWARF FDE "instructions" 61 1.1 joerg enum { 62 1.1 joerg kMaxRegisterNumber = R::LAST_REGISTER + 1 63 1.1 joerg }; 64 1.1 joerg enum RegisterSavedWhere { 65 1.1 joerg kRegisterUnused, 66 1.1 joerg kRegisterInCFA, 67 1.1 joerg kRegisterOffsetFromCFA, 68 1.1 joerg kRegisterInRegister, 69 1.1 joerg kRegisterAtExpression, 70 1.1 joerg kRegisterIsExpression, 71 1.1 joerg }; 72 1.1 joerg struct RegisterLocation { 73 1.1 joerg RegisterSavedWhere location; 74 1.1 joerg int64_t value; 75 1.1 joerg }; 76 1.1 joerg struct PrologInfo { 77 1.1 joerg uint32_t cfaRegister; 78 1.1 joerg int32_t cfaRegisterOffset; // CFA = (cfaRegister)+cfaRegisterOffset 79 1.1 joerg int64_t cfaExpression; // CFA = expression 80 1.1 joerg uint32_t spExtraArgSize; 81 1.1 joerg uint32_t codeOffsetAtStackDecrement; 82 1.1 joerg RegisterLocation savedRegisters[kMaxRegisterNumber]; 83 1.1 joerg }; 84 1.1 joerg 85 1.1 joerg struct PrologInfoStackEntry { 86 1.1 joerg PrologInfoStackEntry(PrologInfoStackEntry *n, const PrologInfo &i) 87 1.1 joerg : next(n), info(i) {} 88 1.1 joerg PrologInfoStackEntry *next; 89 1.1 joerg PrologInfo info; 90 1.1 joerg }; 91 1.1 joerg 92 1.1 joerg static void findPCRange(A &, pint_t, pint_t &, pint_t &); 93 1.1 joerg 94 1.1 joerg static bool decodeFDE(A &, pint_t, FDE_Info *, CIE_Info *, 95 1.1 joerg unw_proc_info_t *ctx); 96 1.1 joerg static bool parseFDEInstructions(A &, const FDE_Info &, const CIE_Info &, 97 1.1 joerg pint_t, PrologInfo *, unw_proc_info_t *ctx); 98 1.1 joerg 99 1.1 joerg static bool parseCIE(A &, pint_t, CIE_Info *); 100 1.1 joerg 101 1.1 joerg private: 102 1.1 joerg static bool parseInstructions(A &, pint_t, pint_t, const CIE_Info &, pint_t, 103 1.1 joerg PrologInfoStackEntry *&, PrologInfo *, 104 1.1 joerg unw_proc_info_t *ctx); 105 1.1 joerg }; 106 1.1 joerg 107 1.1 joerg /// 108 1.1 joerg /// Parse a FDE and return the last PC it covers. 109 1.1 joerg /// 110 1.1 joerg template <typename A, typename R> 111 1.1 joerg void CFI_Parser<A, R>::findPCRange(A &addressSpace, pint_t fde, pint_t &pcStart, 112 1.1 joerg pint_t &pcEnd) { 113 1.1 joerg pcStart = 0; 114 1.1 joerg pcEnd = 0; 115 1.1 joerg pint_t p = fde; 116 1.1 joerg uint64_t cfiLength = addressSpace.get32(p); 117 1.1 joerg p += 4; 118 1.1 joerg if (cfiLength == 0xffffffff) { 119 1.1 joerg // 0xffffffff means length is really the next 8 Bytes. 120 1.1 joerg cfiLength = addressSpace.get64(p); 121 1.1 joerg p += 8; 122 1.1 joerg } 123 1.1 joerg if (cfiLength == 0) 124 1.1 joerg return; 125 1.1 joerg uint32_t ciePointer = addressSpace.get32(p); 126 1.1 joerg if (ciePointer == 0) 127 1.1 joerg return; 128 1.1 joerg pint_t nextCFI = p + cfiLength; 129 1.1 joerg pint_t cieStart = p - ciePointer; 130 1.1 joerg typename CFI_Parser<A, R>::CIE_Info cieInfo; 131 1.1 joerg if (!parseCIE(addressSpace, cieStart, &cieInfo)) 132 1.1 joerg return; 133 1.1 joerg p += 4; 134 1.1 joerg // Parse pc begin and range. 135 1.1 joerg pcStart = addressSpace.getEncodedP(p, nextCFI, cieInfo.pointerEncoding, NULL); 136 1.1 joerg pcEnd = pcStart + addressSpace.getEncodedP( 137 1.1 joerg p, nextCFI, cieInfo.pointerEncoding & 0x0F, NULL); 138 1.1 joerg } 139 1.1 joerg 140 1.1 joerg /// 141 1.1 joerg /// Parse a FDE into a CIE_Info and an FDE_Info 142 1.1 joerg /// 143 1.1 joerg template <typename A, typename R> 144 1.1 joerg bool CFI_Parser<A, R>::decodeFDE(A &addressSpace, pint_t fdeStart, 145 1.1 joerg FDE_Info *fdeInfo, CIE_Info *cieInfo, 146 1.1 joerg unw_proc_info_t *ctx) { 147 1.1 joerg pint_t p = fdeStart; 148 1.1 joerg uint64_t cfiLength = addressSpace.get32(p); 149 1.1 joerg p += 4; 150 1.1 joerg if (cfiLength == 0xffffffff) { 151 1.1 joerg // 0xffffffff means length is really the next 8 Bytes. 152 1.1 joerg cfiLength = addressSpace.get64(p); 153 1.1 joerg p += 8; 154 1.1 joerg } 155 1.1 joerg if (cfiLength == 0) 156 1.1 joerg return false; 157 1.1 joerg uint32_t ciePointer = addressSpace.get32(p); 158 1.1 joerg if (ciePointer == 0) 159 1.1 joerg return false; 160 1.1 joerg pint_t nextCFI = p + cfiLength; 161 1.1 joerg pint_t cieStart = p - ciePointer; 162 1.1 joerg if (!parseCIE(addressSpace, cieStart, cieInfo)) 163 1.1 joerg return false; 164 1.1 joerg p += 4; 165 1.1 joerg // Parse pc begin and range. 166 1.1 joerg pint_t pcStart = 167 1.1 joerg addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding, ctx); 168 1.1 joerg pint_t pcRange = addressSpace.getEncodedP( 169 1.1 joerg p, nextCFI, cieInfo->pointerEncoding & 0x0F, ctx); 170 1.1 joerg // Parse rest of info. 171 1.1 joerg fdeInfo->lsda = 0; 172 1.1 joerg // Check for augmentation length 173 1.1 joerg if (cieInfo->fdesHaveAugmentationData) { 174 1.1 joerg uintptr_t augLen = addressSpace.getULEB128(p, nextCFI); 175 1.1 joerg pint_t endOfAug = p + augLen; 176 1.2 joerg if (cieInfo->lsdaEncoding != DW_EH_PE_omit) { 177 1.1 joerg // Peek at value (without indirection). Zero means no LSDA. 178 1.1 joerg pint_t lsdaStart = p; 179 1.1 joerg if (addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding & 0x0F, 180 1.1 joerg ctx) != 0) { 181 1.1 joerg // Reset pointer and re-parse LSDA address. 182 1.1 joerg p = lsdaStart; 183 1.1 joerg fdeInfo->lsda = 184 1.1 joerg addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding, ctx); 185 1.1 joerg } 186 1.1 joerg } 187 1.1 joerg p = endOfAug; 188 1.1 joerg } 189 1.1 joerg fdeInfo->fdeStart = fdeStart; 190 1.1 joerg fdeInfo->fdeLength = nextCFI - fdeStart; 191 1.1 joerg fdeInfo->fdeInstructions = p; 192 1.1 joerg fdeInfo->pcStart = pcStart; 193 1.1 joerg fdeInfo->pcEnd = pcStart + pcRange; 194 1.1 joerg return true; 195 1.1 joerg } 196 1.1 joerg 197 1.1 joerg /// Extract info from a CIE 198 1.1 joerg template <typename A, typename R> 199 1.1 joerg bool CFI_Parser<A, R>::parseCIE(A &addressSpace, pint_t cie, 200 1.1 joerg CIE_Info *cieInfo) { 201 1.1 joerg cieInfo->pointerEncoding = 0; 202 1.2 joerg cieInfo->lsdaEncoding = DW_EH_PE_omit; 203 1.1 joerg cieInfo->personalityEncoding = 0; 204 1.1 joerg cieInfo->personalityOffsetInCIE = 0; 205 1.1 joerg cieInfo->personality = 0; 206 1.1 joerg cieInfo->codeAlignFactor = 0; 207 1.1 joerg cieInfo->dataAlignFactor = 0; 208 1.1 joerg cieInfo->isSignalFrame = false; 209 1.1 joerg cieInfo->fdesHaveAugmentationData = false; 210 1.1 joerg cieInfo->cieStart = cie; 211 1.1 joerg pint_t p = cie; 212 1.1 joerg uint64_t cieLength = addressSpace.get32(p); 213 1.1 joerg p += 4; 214 1.1 joerg pint_t cieContentEnd = p + cieLength; 215 1.1 joerg if (cieLength == 0xffffffff) { 216 1.1 joerg // 0xffffffff means length is really the next 8 Bytes. 217 1.1 joerg cieLength = addressSpace.get64(p); 218 1.1 joerg p += 8; 219 1.1 joerg cieContentEnd = p + cieLength; 220 1.1 joerg } 221 1.1 joerg if (cieLength == 0) 222 1.1 joerg return true; 223 1.1 joerg // CIE ID is always 0 224 1.1 joerg if (addressSpace.get32(p) != 0) 225 1.1 joerg return false; 226 1.1 joerg p += 4; 227 1.1 joerg // Version is always 1 or 3 228 1.1 joerg uint8_t version = addressSpace.get8(p); 229 1.1 joerg if (version != 1 && version != 3) 230 1.1 joerg return false; 231 1.1 joerg ++p; 232 1.1 joerg // Save start of augmentation string and find end. 233 1.1 joerg pint_t strStart = p; 234 1.1 joerg while (addressSpace.get8(p) != 0) 235 1.1 joerg ++p; 236 1.1 joerg ++p; 237 1.7 andvar // Parse code alignment factor 238 1.1 joerg cieInfo->codeAlignFactor = addressSpace.getULEB128(p, cieContentEnd); 239 1.1 joerg // Parse data alignment factor 240 1.1 joerg cieInfo->dataAlignFactor = addressSpace.getSLEB128(p, cieContentEnd); 241 1.1 joerg // Parse return address register 242 1.6 joerg cieInfo->returnAddressRegister = R::dwarf2regno((uint8_t)addressSpace.getULEB128(p, cieContentEnd)); 243 1.1 joerg // Parse augmentation data based on augmentation string. 244 1.1 joerg if (addressSpace.get8(strStart) == 'z') { 245 1.1 joerg // parse augmentation data length 246 1.1 joerg addressSpace.getULEB128(p, cieContentEnd); 247 1.1 joerg for (pint_t s = strStart; addressSpace.get8(s) != '\0'; ++s) { 248 1.1 joerg switch (addressSpace.get8(s)) { 249 1.1 joerg case 'z': 250 1.1 joerg cieInfo->fdesHaveAugmentationData = true; 251 1.1 joerg break; 252 1.1 joerg case 'P': 253 1.1 joerg cieInfo->personalityEncoding = addressSpace.get8(p); 254 1.1 joerg ++p; 255 1.1 joerg cieInfo->personalityOffsetInCIE = p - cie; 256 1.1 joerg cieInfo->personality = addressSpace.getEncodedP( 257 1.1 joerg p, cieContentEnd, cieInfo->personalityEncoding, NULL); 258 1.1 joerg break; 259 1.1 joerg case 'L': 260 1.1 joerg cieInfo->lsdaEncoding = addressSpace.get8(p); 261 1.1 joerg ++p; 262 1.1 joerg break; 263 1.1 joerg case 'R': 264 1.1 joerg cieInfo->pointerEncoding = addressSpace.get8(p); 265 1.1 joerg ++p; 266 1.1 joerg break; 267 1.1 joerg case 'S': 268 1.1 joerg cieInfo->isSignalFrame = true; 269 1.1 joerg break; 270 1.1 joerg default: 271 1.1 joerg // ignore unknown letters 272 1.1 joerg break; 273 1.1 joerg } 274 1.1 joerg } 275 1.1 joerg } 276 1.1 joerg cieInfo->cieLength = cieContentEnd - cieInfo->cieStart; 277 1.1 joerg cieInfo->cieInstructions = p; 278 1.1 joerg return true; 279 1.1 joerg } 280 1.1 joerg 281 1.1 joerg /// "Run" the dwarf instructions and create the abstact PrologInfo for an FDE. 282 1.1 joerg template <typename A, typename R> 283 1.1 joerg bool CFI_Parser<A, R>::parseFDEInstructions(A &addressSpace, 284 1.1 joerg const FDE_Info &fdeInfo, 285 1.1 joerg const CIE_Info &cieInfo, 286 1.1 joerg pint_t upToPC, PrologInfo *results, 287 1.1 joerg unw_proc_info_t *ctx) { 288 1.1 joerg // Clear results. 289 1.1 joerg memset(results, 0, sizeof(*results)); 290 1.1 joerg PrologInfoStackEntry *rememberStack = NULL; 291 1.1 joerg 292 1.1 joerg // First parse the CIE then FDE instructions. 293 1.1 joerg if (!parseInstructions(addressSpace, cieInfo.cieInstructions, 294 1.1 joerg cieInfo.cieStart + cieInfo.cieLength, cieInfo, 295 1.1 joerg (pint_t)(-1), rememberStack, results, ctx)) 296 1.1 joerg return false; 297 1.1 joerg return parseInstructions(addressSpace, fdeInfo.fdeInstructions, 298 1.1 joerg fdeInfo.fdeStart + fdeInfo.fdeLength, cieInfo, 299 1.1 joerg upToPC - fdeInfo.pcStart, rememberStack, results, 300 1.1 joerg ctx); 301 1.1 joerg } 302 1.1 joerg 303 1.1 joerg /// "Run" the DWARF instructions. 304 1.1 joerg template <typename A, typename R> 305 1.1 joerg bool 306 1.1 joerg CFI_Parser<A, R>::parseInstructions(A &addressSpace, pint_t instructions, 307 1.1 joerg pint_t instructionsEnd, 308 1.1 joerg const CIE_Info &cieInfo, pint_t pcoffset, 309 1.1 joerg PrologInfoStackEntry *&rememberStack, 310 1.1 joerg PrologInfo *results, unw_proc_info_t *ctx) { 311 1.1 joerg pint_t p = instructions; 312 1.1 joerg uint32_t codeOffset = 0; 313 1.1 joerg PrologInfo initialState = *results; 314 1.1 joerg 315 1.1 joerg // See Dwarf Spec, section 6.4.2 for details on unwind opcodes. 316 1.1 joerg while (p < instructionsEnd && codeOffset < pcoffset) { 317 1.1 joerg uint64_t reg; 318 1.1 joerg uint64_t reg2; 319 1.1 joerg int64_t offset; 320 1.1 joerg uint64_t length; 321 1.1 joerg uint8_t opcode = addressSpace.get8(p); 322 1.1 joerg uint8_t operand; 323 1.1 joerg PrologInfoStackEntry *entry; 324 1.1 joerg ++p; 325 1.1 joerg switch (opcode) { 326 1.1 joerg case DW_CFA_nop: 327 1.1 joerg break; 328 1.1 joerg case DW_CFA_set_loc: 329 1.1 joerg codeOffset = addressSpace.getEncodedP(p, instructionsEnd, 330 1.1 joerg cieInfo.pointerEncoding, ctx); 331 1.1 joerg break; 332 1.1 joerg case DW_CFA_advance_loc1: 333 1.1 joerg codeOffset += (addressSpace.get8(p) * cieInfo.codeAlignFactor); 334 1.1 joerg p += 1; 335 1.1 joerg break; 336 1.1 joerg case DW_CFA_advance_loc2: 337 1.1 joerg codeOffset += (addressSpace.get16(p) * cieInfo.codeAlignFactor); 338 1.1 joerg p += 2; 339 1.1 joerg break; 340 1.1 joerg case DW_CFA_advance_loc4: 341 1.1 joerg codeOffset += (addressSpace.get32(p) * cieInfo.codeAlignFactor); 342 1.1 joerg p += 4; 343 1.1 joerg break; 344 1.1 joerg case DW_CFA_offset_extended: 345 1.1 joerg reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd)); 346 1.1 joerg offset = 347 1.1 joerg addressSpace.getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor; 348 1.1 joerg if (reg > kMaxRegisterNumber) 349 1.1 joerg return false; 350 1.1 joerg results->savedRegisters[reg].location = kRegisterInCFA; 351 1.1 joerg results->savedRegisters[reg].value = offset; 352 1.1 joerg break; 353 1.1 joerg case DW_CFA_restore_extended: 354 1.1 joerg reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd)); 355 1.1 joerg if (reg > kMaxRegisterNumber) 356 1.1 joerg return false; 357 1.1 joerg results->savedRegisters[reg] = initialState.savedRegisters[reg]; 358 1.1 joerg break; 359 1.1 joerg case DW_CFA_undefined: 360 1.1 joerg reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd)); 361 1.1 joerg if (reg > kMaxRegisterNumber) 362 1.1 joerg return false; 363 1.1 joerg results->savedRegisters[reg].location = kRegisterUnused; 364 1.1 joerg break; 365 1.1 joerg case DW_CFA_same_value: 366 1.1 joerg reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd)); 367 1.1 joerg if (reg > kMaxRegisterNumber) 368 1.1 joerg return false; 369 1.1 joerg // "same value" means register was stored in frame, but its current 370 1.1 joerg // value has not changed, so no need to restore from frame. 371 1.1 joerg // We model this as if the register was never saved. 372 1.1 joerg results->savedRegisters[reg].location = kRegisterUnused; 373 1.1 joerg break; 374 1.1 joerg case DW_CFA_register: 375 1.1 joerg reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd)); 376 1.1 joerg reg2 = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd)); 377 1.1 joerg if (reg > kMaxRegisterNumber) 378 1.1 joerg return false; 379 1.1 joerg if (reg2 > kMaxRegisterNumber) 380 1.1 joerg return false; 381 1.1 joerg results->savedRegisters[reg].location = kRegisterInRegister; 382 1.1 joerg results->savedRegisters[reg].value = reg2; 383 1.1 joerg break; 384 1.1 joerg case DW_CFA_remember_state: 385 1.1 joerg // avoid operator new, because that would be an upward dependency 386 1.1 joerg entry = (PrologInfoStackEntry *)malloc(sizeof(PrologInfoStackEntry)); 387 1.1 joerg if (entry == NULL) 388 1.1 joerg return false; 389 1.1 joerg 390 1.1 joerg entry->next = rememberStack; 391 1.1 joerg entry->info = *results; 392 1.1 joerg rememberStack = entry; 393 1.1 joerg break; 394 1.1 joerg case DW_CFA_restore_state: 395 1.1 joerg if (rememberStack == NULL) 396 1.1 joerg return false; 397 1.1 joerg { 398 1.1 joerg PrologInfoStackEntry *top = rememberStack; 399 1.1 joerg *results = top->info; 400 1.1 joerg rememberStack = top->next; 401 1.1 joerg free((char *)top); 402 1.1 joerg } 403 1.1 joerg break; 404 1.1 joerg case DW_CFA_def_cfa: 405 1.1 joerg reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd)); 406 1.1 joerg offset = addressSpace.getULEB128(p, instructionsEnd); 407 1.1 joerg if (reg > kMaxRegisterNumber) 408 1.1 joerg return false; 409 1.1 joerg results->cfaRegister = reg; 410 1.1 joerg results->cfaRegisterOffset = offset; 411 1.1 joerg break; 412 1.1 joerg case DW_CFA_def_cfa_register: 413 1.1 joerg reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd)); 414 1.1 joerg if (reg > kMaxRegisterNumber) 415 1.1 joerg return false; 416 1.1 joerg results->cfaRegister = reg; 417 1.1 joerg break; 418 1.1 joerg case DW_CFA_def_cfa_offset: 419 1.1 joerg results->cfaRegisterOffset = addressSpace.getULEB128(p, instructionsEnd); 420 1.1 joerg results->codeOffsetAtStackDecrement = codeOffset; 421 1.1 joerg break; 422 1.1 joerg case DW_CFA_def_cfa_expression: 423 1.1 joerg results->cfaRegister = 0; 424 1.1 joerg results->cfaExpression = p; 425 1.1 joerg length = addressSpace.getULEB128(p, instructionsEnd); 426 1.1 joerg p += length; 427 1.1 joerg break; 428 1.1 joerg case DW_CFA_expression: 429 1.1 joerg reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd)); 430 1.1 joerg if (reg > kMaxRegisterNumber) 431 1.1 joerg return false; 432 1.1 joerg results->savedRegisters[reg].location = kRegisterAtExpression; 433 1.1 joerg results->savedRegisters[reg].value = p; 434 1.1 joerg length = addressSpace.getULEB128(p, instructionsEnd); 435 1.1 joerg p += length; 436 1.1 joerg break; 437 1.1 joerg case DW_CFA_offset_extended_sf: 438 1.1 joerg reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd)); 439 1.1 joerg if (reg > kMaxRegisterNumber) 440 1.1 joerg return false; 441 1.1 joerg offset = 442 1.1 joerg addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor; 443 1.1 joerg results->savedRegisters[reg].location = kRegisterInCFA; 444 1.1 joerg results->savedRegisters[reg].value = offset; 445 1.1 joerg break; 446 1.1 joerg case DW_CFA_def_cfa_sf: 447 1.1 joerg reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd)); 448 1.1 joerg offset = 449 1.1 joerg addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor; 450 1.1 joerg if (reg > kMaxRegisterNumber) 451 1.1 joerg return false; 452 1.1 joerg results->cfaRegister = reg; 453 1.1 joerg results->cfaRegisterOffset = offset; 454 1.1 joerg break; 455 1.1 joerg case DW_CFA_def_cfa_offset_sf: 456 1.1 joerg results->cfaRegisterOffset = 457 1.1 joerg addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor; 458 1.1 joerg results->codeOffsetAtStackDecrement = codeOffset; 459 1.1 joerg break; 460 1.1 joerg case DW_CFA_val_offset: 461 1.1 joerg reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd)); 462 1.1 joerg offset = 463 1.1 joerg addressSpace.getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor; 464 1.5 joerg if (reg > kMaxRegisterNumber) 465 1.5 joerg return false; 466 1.1 joerg results->savedRegisters[reg].location = kRegisterOffsetFromCFA; 467 1.1 joerg results->savedRegisters[reg].value = offset; 468 1.1 joerg break; 469 1.1 joerg case DW_CFA_val_offset_sf: 470 1.1 joerg reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd)); 471 1.1 joerg if (reg > kMaxRegisterNumber) 472 1.1 joerg return false; 473 1.1 joerg offset = 474 1.1 joerg addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor; 475 1.1 joerg results->savedRegisters[reg].location = kRegisterOffsetFromCFA; 476 1.1 joerg results->savedRegisters[reg].value = offset; 477 1.1 joerg break; 478 1.1 joerg case DW_CFA_val_expression: 479 1.1 joerg reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd)); 480 1.1 joerg if (reg > kMaxRegisterNumber) 481 1.1 joerg return false; 482 1.1 joerg results->savedRegisters[reg].location = kRegisterIsExpression; 483 1.1 joerg results->savedRegisters[reg].value = p; 484 1.1 joerg length = addressSpace.getULEB128(p, instructionsEnd); 485 1.1 joerg p += length; 486 1.1 joerg break; 487 1.3 joerg case DW_CFA_GNU_window_save: 488 1.3 joerg #if defined(__sparc__) 489 1.3 joerg for (reg = 8; reg < 16; ++reg) { 490 1.3 joerg results->savedRegisters[reg].location = kRegisterInRegister; 491 1.3 joerg results->savedRegisters[reg].value = reg + 16; 492 1.3 joerg } 493 1.3 joerg for (reg = 16; reg < 32; ++reg) { 494 1.3 joerg results->savedRegisters[reg].location = kRegisterInCFA; 495 1.3 joerg results->savedRegisters[reg].value = (reg - 16) * sizeof(typename R::reg_t); 496 1.3 joerg } 497 1.3 joerg break; 498 1.3 joerg #else 499 1.3 joerg return false; 500 1.3 joerg #endif 501 1.1 joerg case DW_CFA_GNU_args_size: 502 1.1 joerg offset = addressSpace.getULEB128(p, instructionsEnd); 503 1.1 joerg results->spExtraArgSize = offset; 504 1.1 joerg break; 505 1.1 joerg case DW_CFA_GNU_negative_offset_extended: 506 1.1 joerg reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd)); 507 1.1 joerg if (reg > kMaxRegisterNumber) 508 1.1 joerg return false; 509 1.1 joerg offset = 510 1.1 joerg addressSpace.getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor; 511 1.1 joerg results->savedRegisters[reg].location = kRegisterInCFA; 512 1.1 joerg results->savedRegisters[reg].value = -offset; 513 1.1 joerg break; 514 1.1 joerg default: 515 1.1 joerg operand = opcode & 0x3F; 516 1.1 joerg switch (opcode & 0xC0) { 517 1.1 joerg case DW_CFA_offset: 518 1.1 joerg reg = R::dwarf2regno(operand); 519 1.1 joerg if (reg > kMaxRegisterNumber) 520 1.1 joerg return false; 521 1.1 joerg offset = addressSpace.getULEB128(p, instructionsEnd) * 522 1.1 joerg cieInfo.dataAlignFactor; 523 1.1 joerg results->savedRegisters[reg].location = kRegisterInCFA; 524 1.1 joerg results->savedRegisters[reg].value = offset; 525 1.1 joerg break; 526 1.1 joerg case DW_CFA_advance_loc: 527 1.1 joerg codeOffset += operand * cieInfo.codeAlignFactor; 528 1.1 joerg break; 529 1.1 joerg case DW_CFA_restore: 530 1.1 joerg reg = R::dwarf2regno(operand); 531 1.1 joerg if (reg > kMaxRegisterNumber) 532 1.1 joerg return false; 533 1.1 joerg results->savedRegisters[reg] = initialState.savedRegisters[reg]; 534 1.1 joerg break; 535 1.1 joerg default: 536 1.1 joerg return false; 537 1.1 joerg } 538 1.1 joerg } 539 1.1 joerg } 540 1.1 joerg 541 1.1 joerg return true; 542 1.1 joerg } 543 1.1 joerg 544 1.1 joerg } // namespace _Unwind 545 1.1 joerg 546 1.1 joerg #endif // __DWARF_PARSER_HPP__ 547