1 //===- DWARFDebugFrame.h - Parsing of .debug_frame ------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h" 11 12 #include "llvm/ADT/ArrayRef.h" 13 #include "llvm/ADT/DenseMap.h" 14 #include "llvm/ADT/Optional.h" 15 #include "llvm/ADT/STLExtras.h" 16 #include "llvm/ADT/SmallString.h" 17 #include "llvm/ADT/StringExtras.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/BinaryFormat/Dwarf.h" 20 #include "llvm/Support/Casting.h" 21 #include "llvm/Support/Compiler.h" 22 #include "llvm/Support/DataExtractor.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include "llvm/Support/Format.h" 25 #include "llvm/Support/raw_ostream.h" 26 #include <algorithm> 27 #include <cassert> 28 #include <cinttypes> 29 #include <cstdint> 30 #include <string> 31 #include <vector> 32 33 using namespace llvm; 34 using namespace dwarf; 35 36 /// \brief Abstract frame entry defining the common interface concrete 37 /// entries implement. 38 class llvm::FrameEntry { 39 public: 40 enum FrameKind {FK_CIE, FK_FDE}; 41 42 FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length) 43 : Kind(K), Offset(Offset), Length(Length) {} 44 45 virtual ~FrameEntry() = default; 46 47 FrameKind getKind() const { return Kind; } 48 virtual uint64_t getOffset() const { return Offset; } 49 50 /// \brief Parse and store a sequence of CFI instructions from Data, 51 /// starting at *Offset and ending at EndOffset. If everything 52 /// goes well, *Offset should be equal to EndOffset when this method 53 /// returns. Otherwise, an error occurred. 54 virtual void parseInstructions(DataExtractor Data, uint32_t *Offset, 55 uint32_t EndOffset); 56 57 /// \brief Dump the entry header to the given output stream. 58 virtual void dumpHeader(raw_ostream &OS) const = 0; 59 60 /// \brief Dump the entry's instructions to the given output stream. 61 virtual void dumpInstructions(raw_ostream &OS) const; 62 63 protected: 64 const FrameKind Kind; 65 66 /// \brief Offset of this entry in the section. 67 uint64_t Offset; 68 69 /// \brief Entry length as specified in DWARF. 70 uint64_t Length; 71 72 /// An entry may contain CFI instructions. An instruction consists of an 73 /// opcode and an optional sequence of operands. 74 typedef std::vector<uint64_t> Operands; 75 struct Instruction { 76 Instruction(uint8_t Opcode) 77 : Opcode(Opcode) 78 {} 79 80 uint8_t Opcode; 81 Operands Ops; 82 }; 83 84 std::vector<Instruction> Instructions; 85 86 /// Convenience methods to add a new instruction with the given opcode and 87 /// operands to the Instructions vector. 88 void addInstruction(uint8_t Opcode) { 89 Instructions.push_back(Instruction(Opcode)); 90 } 91 92 void addInstruction(uint8_t Opcode, uint64_t Operand1) { 93 Instructions.push_back(Instruction(Opcode)); 94 Instructions.back().Ops.push_back(Operand1); 95 } 96 97 void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2) { 98 Instructions.push_back(Instruction(Opcode)); 99 Instructions.back().Ops.push_back(Operand1); 100 Instructions.back().Ops.push_back(Operand2); 101 } 102 }; 103 104 // See DWARF standard v3, section 7.23 105 const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0; 106 const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f; 107 108 void FrameEntry::parseInstructions(DataExtractor Data, uint32_t *Offset, 109 uint32_t EndOffset) { 110 while (*Offset < EndOffset) { 111 uint8_t Opcode = Data.getU8(Offset); 112 // Some instructions have a primary opcode encoded in the top bits. 113 uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK; 114 115 if (Primary) { 116 // If it's a primary opcode, the first operand is encoded in the bottom 117 // bits of the opcode itself. 118 uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK; 119 switch (Primary) { 120 default: llvm_unreachable("Impossible primary CFI opcode"); 121 case DW_CFA_advance_loc: 122 case DW_CFA_restore: 123 addInstruction(Primary, Op1); 124 break; 125 case DW_CFA_offset: 126 addInstruction(Primary, Op1, Data.getULEB128(Offset)); 127 break; 128 } 129 } else { 130 // Extended opcode - its value is Opcode itself. 131 switch (Opcode) { 132 default: llvm_unreachable("Invalid extended CFI opcode"); 133 case DW_CFA_nop: 134 case DW_CFA_remember_state: 135 case DW_CFA_restore_state: 136 case DW_CFA_GNU_window_save: 137 // No operands 138 addInstruction(Opcode); 139 break; 140 case DW_CFA_set_loc: 141 // Operands: Address 142 addInstruction(Opcode, Data.getAddress(Offset)); 143 break; 144 case DW_CFA_advance_loc1: 145 // Operands: 1-byte delta 146 addInstruction(Opcode, Data.getU8(Offset)); 147 break; 148 case DW_CFA_advance_loc2: 149 // Operands: 2-byte delta 150 addInstruction(Opcode, Data.getU16(Offset)); 151 break; 152 case DW_CFA_advance_loc4: 153 // Operands: 4-byte delta 154 addInstruction(Opcode, Data.getU32(Offset)); 155 break; 156 case DW_CFA_restore_extended: 157 case DW_CFA_undefined: 158 case DW_CFA_same_value: 159 case DW_CFA_def_cfa_register: 160 case DW_CFA_def_cfa_offset: 161 // Operands: ULEB128 162 addInstruction(Opcode, Data.getULEB128(Offset)); 163 break; 164 case DW_CFA_def_cfa_offset_sf: 165 // Operands: SLEB128 166 addInstruction(Opcode, Data.getSLEB128(Offset)); 167 break; 168 case DW_CFA_offset_extended: 169 case DW_CFA_register: 170 case DW_CFA_def_cfa: 171 case DW_CFA_val_offset: { 172 // Operands: ULEB128, ULEB128 173 // Note: We can not embed getULEB128 directly into function 174 // argument list. getULEB128 changes Offset and order of evaluation 175 // for arguments is unspecified. 176 auto op1 = Data.getULEB128(Offset); 177 auto op2 = Data.getULEB128(Offset); 178 addInstruction(Opcode, op1, op2); 179 break; 180 } 181 case DW_CFA_offset_extended_sf: 182 case DW_CFA_def_cfa_sf: 183 case DW_CFA_val_offset_sf: { 184 // Operands: ULEB128, SLEB128 185 // Note: see comment for the previous case 186 auto op1 = Data.getULEB128(Offset); 187 auto op2 = (uint64_t)Data.getSLEB128(Offset); 188 addInstruction(Opcode, op1, op2); 189 break; 190 } 191 case DW_CFA_def_cfa_expression: 192 case DW_CFA_expression: 193 case DW_CFA_val_expression: 194 // TODO: implement this 195 report_fatal_error("Values with expressions not implemented yet!"); 196 } 197 } 198 } 199 } 200 201 namespace { 202 203 /// \brief DWARF Common Information Entry (CIE) 204 class CIE : public FrameEntry { 205 public: 206 // CIEs (and FDEs) are simply container classes, so the only sensible way to 207 // create them is by providing the full parsed contents in the constructor. 208 CIE(uint64_t Offset, uint64_t Length, uint8_t Version, 209 SmallString<8> Augmentation, uint8_t AddressSize, 210 uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor, 211 int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister, 212 SmallString<8> AugmentationData, uint32_t FDEPointerEncoding, 213 uint32_t LSDAPointerEncoding) 214 : FrameEntry(FK_CIE, Offset, Length), Version(Version), 215 Augmentation(std::move(Augmentation)), AddressSize(AddressSize), 216 SegmentDescriptorSize(SegmentDescriptorSize), 217 CodeAlignmentFactor(CodeAlignmentFactor), 218 DataAlignmentFactor(DataAlignmentFactor), 219 ReturnAddressRegister(ReturnAddressRegister), 220 AugmentationData(std::move(AugmentationData)), 221 FDEPointerEncoding(FDEPointerEncoding), 222 LSDAPointerEncoding(LSDAPointerEncoding) {} 223 224 ~CIE() override = default; 225 226 StringRef getAugmentationString() const { return Augmentation; } 227 uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; } 228 int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; } 229 230 uint32_t getFDEPointerEncoding() const { 231 return FDEPointerEncoding; 232 } 233 234 uint32_t getLSDAPointerEncoding() const { 235 return LSDAPointerEncoding; 236 } 237 238 void dumpHeader(raw_ostream &OS) const override { 239 OS << format("%08x %08x %08x CIE", 240 (uint32_t)Offset, (uint32_t)Length, DW_CIE_ID) 241 << "\n"; 242 OS << format(" Version: %d\n", Version); 243 OS << " Augmentation: \"" << Augmentation << "\"\n"; 244 if (Version >= 4) { 245 OS << format(" Address size: %u\n", 246 (uint32_t)AddressSize); 247 OS << format(" Segment desc size: %u\n", 248 (uint32_t)SegmentDescriptorSize); 249 } 250 OS << format(" Code alignment factor: %u\n", 251 (uint32_t)CodeAlignmentFactor); 252 OS << format(" Data alignment factor: %d\n", 253 (int32_t)DataAlignmentFactor); 254 OS << format(" Return address column: %d\n", 255 (int32_t)ReturnAddressRegister); 256 if (!AugmentationData.empty()) { 257 OS << " Augmentation data: "; 258 for (uint8_t Byte : AugmentationData) 259 OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf); 260 OS << "\n"; 261 } 262 OS << "\n"; 263 } 264 265 static bool classof(const FrameEntry *FE) { 266 return FE->getKind() == FK_CIE; 267 } 268 269 private: 270 /// The following fields are defined in section 6.4.1 of the DWARF standard v4 271 uint8_t Version; 272 SmallString<8> Augmentation; 273 uint8_t AddressSize; 274 uint8_t SegmentDescriptorSize; 275 uint64_t CodeAlignmentFactor; 276 int64_t DataAlignmentFactor; 277 uint64_t ReturnAddressRegister; 278 279 // The following are used when the CIE represents an EH frame entry. 280 SmallString<8> AugmentationData; 281 uint32_t FDEPointerEncoding; 282 uint32_t LSDAPointerEncoding; 283 }; 284 285 /// \brief DWARF Frame Description Entry (FDE) 286 class FDE : public FrameEntry { 287 public: 288 // Each FDE has a CIE it's "linked to". Our FDE contains is constructed with 289 // an offset to the CIE (provided by parsing the FDE header). The CIE itself 290 // is obtained lazily once it's actually required. 291 FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset, 292 uint64_t InitialLocation, uint64_t AddressRange, 293 CIE *Cie) 294 : FrameEntry(FK_FDE, Offset, Length), LinkedCIEOffset(LinkedCIEOffset), 295 InitialLocation(InitialLocation), AddressRange(AddressRange), 296 LinkedCIE(Cie) {} 297 298 ~FDE() override = default; 299 300 CIE *getLinkedCIE() const { return LinkedCIE; } 301 302 void dumpHeader(raw_ostream &OS) const override { 303 OS << format("%08x %08x %08x FDE ", 304 (uint32_t)Offset, (uint32_t)Length, (int32_t)LinkedCIEOffset); 305 OS << format("cie=%08x pc=%08x...%08x\n", 306 (int32_t)LinkedCIEOffset, 307 (uint32_t)InitialLocation, 308 (uint32_t)InitialLocation + (uint32_t)AddressRange); 309 } 310 311 static bool classof(const FrameEntry *FE) { 312 return FE->getKind() == FK_FDE; 313 } 314 315 private: 316 /// The following fields are defined in section 6.4.1 of the DWARF standard v3 317 uint64_t LinkedCIEOffset; 318 uint64_t InitialLocation; 319 uint64_t AddressRange; 320 CIE *LinkedCIE; 321 }; 322 323 /// \brief Types of operands to CF instructions. 324 enum OperandType { 325 OT_Unset, 326 OT_None, 327 OT_Address, 328 OT_Offset, 329 OT_FactoredCodeOffset, 330 OT_SignedFactDataOffset, 331 OT_UnsignedFactDataOffset, 332 OT_Register, 333 OT_Expression 334 }; 335 336 } // end anonymous namespace 337 338 /// \brief Initialize the array describing the types of operands. 339 static ArrayRef<OperandType[2]> getOperandTypes() { 340 static OperandType OpTypes[DW_CFA_restore+1][2]; 341 342 #define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \ 343 do { \ 344 OpTypes[OP][0] = OPTYPE0; \ 345 OpTypes[OP][1] = OPTYPE1; \ 346 } while (false) 347 #define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None) 348 #define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None) 349 350 DECLARE_OP1(DW_CFA_set_loc, OT_Address); 351 DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset); 352 DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset); 353 DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset); 354 DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset); 355 DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset); 356 DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset); 357 DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset); 358 DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register); 359 DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset); 360 DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset); 361 DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression); 362 DECLARE_OP1(DW_CFA_undefined, OT_Register); 363 DECLARE_OP1(DW_CFA_same_value, OT_Register); 364 DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset); 365 DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset); 366 DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset); 367 DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset); 368 DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset); 369 DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register); 370 DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression); 371 DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression); 372 DECLARE_OP1(DW_CFA_restore, OT_Register); 373 DECLARE_OP1(DW_CFA_restore_extended, OT_Register); 374 DECLARE_OP0(DW_CFA_remember_state); 375 DECLARE_OP0(DW_CFA_restore_state); 376 DECLARE_OP0(DW_CFA_GNU_window_save); 377 DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset); 378 DECLARE_OP0(DW_CFA_nop); 379 380 #undef DECLARE_OP0 381 #undef DECLARE_OP1 382 #undef DECLARE_OP2 383 384 return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1); 385 } 386 387 static ArrayRef<OperandType[2]> OpTypes = getOperandTypes(); 388 389 /// \brief Print \p Opcode's operand number \p OperandIdx which has 390 /// value \p Operand. 391 static void printOperand(raw_ostream &OS, uint8_t Opcode, unsigned OperandIdx, 392 uint64_t Operand, uint64_t CodeAlignmentFactor, 393 int64_t DataAlignmentFactor) { 394 assert(OperandIdx < 2); 395 OperandType Type = OpTypes[Opcode][OperandIdx]; 396 397 switch (Type) { 398 case OT_Unset: { 399 OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to"; 400 auto OpcodeName = CallFrameString(Opcode); 401 if (!OpcodeName.empty()) 402 OS << " " << OpcodeName; 403 else 404 OS << format(" Opcode %x", Opcode); 405 break; 406 } 407 case OT_None: 408 break; 409 case OT_Address: 410 OS << format(" %" PRIx64, Operand); 411 break; 412 case OT_Offset: 413 // The offsets are all encoded in a unsigned form, but in practice 414 // consumers use them signed. It's most certainly legacy due to 415 // the lack of signed variants in the first Dwarf standards. 416 OS << format(" %+" PRId64, int64_t(Operand)); 417 break; 418 case OT_FactoredCodeOffset: // Always Unsigned 419 if (CodeAlignmentFactor) 420 OS << format(" %" PRId64, Operand * CodeAlignmentFactor); 421 else 422 OS << format(" %" PRId64 "*code_alignment_factor" , Operand); 423 break; 424 case OT_SignedFactDataOffset: 425 if (DataAlignmentFactor) 426 OS << format(" %" PRId64, int64_t(Operand) * DataAlignmentFactor); 427 else 428 OS << format(" %" PRId64 "*data_alignment_factor" , int64_t(Operand)); 429 break; 430 case OT_UnsignedFactDataOffset: 431 if (DataAlignmentFactor) 432 OS << format(" %" PRId64, Operand * DataAlignmentFactor); 433 else 434 OS << format(" %" PRId64 "*data_alignment_factor" , Operand); 435 break; 436 case OT_Register: 437 OS << format(" reg%" PRId64, Operand); 438 break; 439 case OT_Expression: 440 OS << " expression"; 441 break; 442 } 443 } 444 445 void FrameEntry::dumpInstructions(raw_ostream &OS) const { 446 uint64_t CodeAlignmentFactor = 0; 447 int64_t DataAlignmentFactor = 0; 448 const CIE *Cie = dyn_cast<CIE>(this); 449 450 if (!Cie) 451 Cie = cast<FDE>(this)->getLinkedCIE(); 452 if (Cie) { 453 CodeAlignmentFactor = Cie->getCodeAlignmentFactor(); 454 DataAlignmentFactor = Cie->getDataAlignmentFactor(); 455 } 456 457 for (const auto &Instr : Instructions) { 458 uint8_t Opcode = Instr.Opcode; 459 if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) 460 Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK; 461 OS << " " << CallFrameString(Opcode) << ":"; 462 for (unsigned i = 0; i < Instr.Ops.size(); ++i) 463 printOperand(OS, Opcode, i, Instr.Ops[i], CodeAlignmentFactor, 464 DataAlignmentFactor); 465 OS << '\n'; 466 } 467 } 468 469 DWARFDebugFrame::DWARFDebugFrame(bool IsEH) : IsEH(IsEH) {} 470 471 DWARFDebugFrame::~DWARFDebugFrame() = default; 472 473 static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data, 474 uint32_t Offset, int Length) { 475 errs() << "DUMP: "; 476 for (int i = 0; i < Length; ++i) { 477 uint8_t c = Data.getU8(&Offset); 478 errs().write_hex(c); errs() << " "; 479 } 480 errs() << "\n"; 481 } 482 483 static unsigned getSizeForEncoding(const DataExtractor &Data, 484 unsigned symbolEncoding) { 485 unsigned format = symbolEncoding & 0x0f; 486 switch (format) { 487 default: llvm_unreachable("Unknown Encoding"); 488 case DW_EH_PE_absptr: 489 case DW_EH_PE_signed: 490 return Data.getAddressSize(); 491 case DW_EH_PE_udata2: 492 case DW_EH_PE_sdata2: 493 return 2; 494 case DW_EH_PE_udata4: 495 case DW_EH_PE_sdata4: 496 return 4; 497 case DW_EH_PE_udata8: 498 case DW_EH_PE_sdata8: 499 return 8; 500 } 501 } 502 503 static uint64_t readPointer(const DataExtractor &Data, uint32_t &Offset, 504 unsigned Encoding) { 505 switch (getSizeForEncoding(Data, Encoding)) { 506 case 2: 507 return Data.getU16(&Offset); 508 case 4: 509 return Data.getU32(&Offset); 510 case 8: 511 return Data.getU64(&Offset); 512 default: 513 llvm_unreachable("Illegal data size"); 514 } 515 } 516 517 void DWARFDebugFrame::parse(DataExtractor Data) { 518 uint32_t Offset = 0; 519 DenseMap<uint32_t, CIE *> CIEs; 520 521 while (Data.isValidOffset(Offset)) { 522 uint32_t StartOffset = Offset; 523 524 auto ReportError = [StartOffset](const char *ErrorMsg) { 525 std::string Str; 526 raw_string_ostream OS(Str); 527 OS << format(ErrorMsg, StartOffset); 528 OS.flush(); 529 report_fatal_error(Str); 530 }; 531 532 bool IsDWARF64 = false; 533 uint64_t Length = Data.getU32(&Offset); 534 uint64_t Id; 535 536 if (Length == UINT32_MAX) { 537 // DWARF-64 is distinguished by the first 32 bits of the initial length 538 // field being 0xffffffff. Then, the next 64 bits are the actual entry 539 // length. 540 IsDWARF64 = true; 541 Length = Data.getU64(&Offset); 542 } 543 544 // At this point, Offset points to the next field after Length. 545 // Length is the structure size excluding itself. Compute an offset one 546 // past the end of the structure (needed to know how many instructions to 547 // read). 548 // TODO: For honest DWARF64 support, DataExtractor will have to treat 549 // offset_ptr as uint64_t* 550 uint32_t StartStructureOffset = Offset; 551 uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length); 552 553 // The Id field's size depends on the DWARF format 554 Id = Data.getUnsigned(&Offset, (IsDWARF64 && !IsEH) ? 8 : 4); 555 bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) || 556 Id == DW_CIE_ID || 557 (IsEH && !Id)); 558 559 if (IsCIE) { 560 uint8_t Version = Data.getU8(&Offset); 561 const char *Augmentation = Data.getCStr(&Offset); 562 StringRef AugmentationString(Augmentation ? Augmentation : ""); 563 uint8_t AddressSize = Version < 4 ? Data.getAddressSize() : 564 Data.getU8(&Offset); 565 Data.setAddressSize(AddressSize); 566 uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset); 567 uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset); 568 int64_t DataAlignmentFactor = Data.getSLEB128(&Offset); 569 uint64_t ReturnAddressRegister = Data.getULEB128(&Offset); 570 571 // Parse the augmentation data for EH CIEs 572 StringRef AugmentationData(""); 573 uint32_t FDEPointerEncoding = DW_EH_PE_omit; 574 uint32_t LSDAPointerEncoding = DW_EH_PE_omit; 575 if (IsEH) { 576 Optional<uint32_t> PersonalityEncoding; 577 Optional<uint64_t> Personality; 578 579 Optional<uint64_t> AugmentationLength; 580 uint32_t StartAugmentationOffset; 581 uint32_t EndAugmentationOffset; 582 583 // Walk the augmentation string to get all the augmentation data. 584 for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) { 585 switch (AugmentationString[i]) { 586 default: 587 ReportError("Unknown augmentation character in entry at %lx"); 588 case 'L': 589 LSDAPointerEncoding = Data.getU8(&Offset); 590 break; 591 case 'P': { 592 if (Personality) 593 ReportError("Duplicate personality in entry at %lx"); 594 PersonalityEncoding = Data.getU8(&Offset); 595 Personality = readPointer(Data, Offset, *PersonalityEncoding); 596 break; 597 } 598 case 'R': 599 FDEPointerEncoding = Data.getU8(&Offset); 600 break; 601 case 'z': 602 if (i) 603 ReportError("'z' must be the first character at %lx"); 604 // Parse the augmentation length first. We only parse it if 605 // the string contains a 'z'. 606 AugmentationLength = Data.getULEB128(&Offset); 607 StartAugmentationOffset = Offset; 608 EndAugmentationOffset = Offset + 609 static_cast<uint32_t>(*AugmentationLength); 610 } 611 } 612 613 if (AugmentationLength.hasValue()) { 614 if (Offset != EndAugmentationOffset) 615 ReportError("Parsing augmentation data at %lx failed"); 616 617 AugmentationData = Data.getData().slice(StartAugmentationOffset, 618 EndAugmentationOffset); 619 } 620 } 621 622 auto Cie = llvm::make_unique<CIE>(StartOffset, Length, Version, 623 AugmentationString, AddressSize, 624 SegmentDescriptorSize, 625 CodeAlignmentFactor, 626 DataAlignmentFactor, 627 ReturnAddressRegister, 628 AugmentationData, FDEPointerEncoding, 629 LSDAPointerEncoding); 630 CIEs[StartOffset] = Cie.get(); 631 Entries.emplace_back(std::move(Cie)); 632 } else { 633 // FDE 634 uint64_t CIEPointer = Id; 635 uint64_t InitialLocation = 0; 636 uint64_t AddressRange = 0; 637 CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer]; 638 639 if (IsEH) { 640 // The address size is encoded in the CIE we reference. 641 if (!Cie) 642 ReportError("Parsing FDE data at %lx failed due to missing CIE"); 643 644 InitialLocation = readPointer(Data, Offset, 645 Cie->getFDEPointerEncoding()); 646 AddressRange = readPointer(Data, Offset, 647 Cie->getFDEPointerEncoding()); 648 649 StringRef AugmentationString = Cie->getAugmentationString(); 650 if (!AugmentationString.empty()) { 651 // Parse the augmentation length and data for this FDE. 652 uint64_t AugmentationLength = Data.getULEB128(&Offset); 653 654 uint32_t EndAugmentationOffset = 655 Offset + static_cast<uint32_t>(AugmentationLength); 656 657 // Decode the LSDA if the CIE augmentation string said we should. 658 if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit) 659 readPointer(Data, Offset, Cie->getLSDAPointerEncoding()); 660 661 if (Offset != EndAugmentationOffset) 662 ReportError("Parsing augmentation data at %lx failed"); 663 } 664 } else { 665 InitialLocation = Data.getAddress(&Offset); 666 AddressRange = Data.getAddress(&Offset); 667 } 668 669 Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer, 670 InitialLocation, AddressRange, 671 Cie)); 672 } 673 674 Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset); 675 676 if (Offset != EndStructureOffset) 677 ReportError("Parsing entry instructions at %lx failed"); 678 } 679 } 680 681 void DWARFDebugFrame::dump(raw_ostream &OS) const { 682 OS << "\n"; 683 for (const auto &Entry : Entries) { 684 Entry->dumpHeader(OS); 685 Entry->dumpInstructions(OS); 686 OS << "\n"; 687 } 688 } 689