17a7e6055SDimitry Andric //===- DWARFDebugFrame.h - Parsing of .debug_frame ------------------------===// 2ff0cc061SDimitry Andric // 3ff0cc061SDimitry Andric // The LLVM Compiler Infrastructure 4ff0cc061SDimitry Andric // 5ff0cc061SDimitry Andric // This file is distributed under the University of Illinois Open Source 6ff0cc061SDimitry Andric // License. See LICENSE.TXT for details. 7ff0cc061SDimitry Andric // 8ff0cc061SDimitry Andric //===----------------------------------------------------------------------===// 9ff0cc061SDimitry Andric 10db17bf38SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h" 11db17bf38SDimitry Andric 12ff0cc061SDimitry Andric #include "llvm/ADT/ArrayRef.h" 13ff0cc061SDimitry Andric #include "llvm/ADT/DenseMap.h" 143ca95b02SDimitry Andric #include "llvm/ADT/Optional.h" 15d88c1a5aSDimitry Andric #include "llvm/ADT/STLExtras.h" 16db17bf38SDimitry Andric #include "llvm/ADT/SmallString.h" 173ca95b02SDimitry Andric #include "llvm/ADT/StringExtras.h" 18d88c1a5aSDimitry Andric #include "llvm/ADT/StringRef.h" 19db17bf38SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 20ff0cc061SDimitry Andric #include "llvm/Support/Casting.h" 21d88c1a5aSDimitry Andric #include "llvm/Support/Compiler.h" 22d88c1a5aSDimitry Andric #include "llvm/Support/DataExtractor.h" 23ff0cc061SDimitry Andric #include "llvm/Support/ErrorHandling.h" 24ff0cc061SDimitry Andric #include "llvm/Support/Format.h" 25ff0cc061SDimitry Andric #include "llvm/Support/raw_ostream.h" 26d88c1a5aSDimitry Andric #include <algorithm> 27d88c1a5aSDimitry Andric #include <cassert> 28d88c1a5aSDimitry Andric #include <cinttypes> 29d88c1a5aSDimitry Andric #include <cstdint> 30ff0cc061SDimitry Andric #include <string> 31ff0cc061SDimitry Andric #include <vector> 32ff0cc061SDimitry Andric 33ff0cc061SDimitry Andric using namespace llvm; 34ff0cc061SDimitry Andric using namespace dwarf; 35ff0cc061SDimitry Andric 36ff0cc061SDimitry Andric /// \brief Abstract frame entry defining the common interface concrete 37ff0cc061SDimitry Andric /// entries implement. 38ff0cc061SDimitry Andric class llvm::FrameEntry { 39ff0cc061SDimitry Andric public: 40ff0cc061SDimitry Andric enum FrameKind {FK_CIE, FK_FDE}; 41d88c1a5aSDimitry Andric 42ff0cc061SDimitry Andric FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length) 43ff0cc061SDimitry Andric : Kind(K), Offset(Offset), Length(Length) {} 44ff0cc061SDimitry Andric 45d88c1a5aSDimitry Andric virtual ~FrameEntry() = default; 46ff0cc061SDimitry Andric 47ff0cc061SDimitry Andric FrameKind getKind() const { return Kind; } 48ff0cc061SDimitry Andric virtual uint64_t getOffset() const { return Offset; } 49ff0cc061SDimitry Andric 50ff0cc061SDimitry Andric /// \brief Parse and store a sequence of CFI instructions from Data, 51ff0cc061SDimitry Andric /// starting at *Offset and ending at EndOffset. If everything 52ff0cc061SDimitry Andric /// goes well, *Offset should be equal to EndOffset when this method 53ff0cc061SDimitry Andric /// returns. Otherwise, an error occurred. 54ff0cc061SDimitry Andric virtual void parseInstructions(DataExtractor Data, uint32_t *Offset, 55ff0cc061SDimitry Andric uint32_t EndOffset); 56ff0cc061SDimitry Andric 57ff0cc061SDimitry Andric /// \brief Dump the entry header to the given output stream. 58ff0cc061SDimitry Andric virtual void dumpHeader(raw_ostream &OS) const = 0; 59ff0cc061SDimitry Andric 60ff0cc061SDimitry Andric /// \brief Dump the entry's instructions to the given output stream. 61ff0cc061SDimitry Andric virtual void dumpInstructions(raw_ostream &OS) const; 62ff0cc061SDimitry Andric 63ff0cc061SDimitry Andric protected: 64ff0cc061SDimitry Andric const FrameKind Kind; 65ff0cc061SDimitry Andric 66ff0cc061SDimitry Andric /// \brief Offset of this entry in the section. 67ff0cc061SDimitry Andric uint64_t Offset; 68ff0cc061SDimitry Andric 69ff0cc061SDimitry Andric /// \brief Entry length as specified in DWARF. 70ff0cc061SDimitry Andric uint64_t Length; 71ff0cc061SDimitry Andric 72ff0cc061SDimitry Andric /// An entry may contain CFI instructions. An instruction consists of an 73ff0cc061SDimitry Andric /// opcode and an optional sequence of operands. 74ff0cc061SDimitry Andric typedef std::vector<uint64_t> Operands; 75ff0cc061SDimitry Andric struct Instruction { 76ff0cc061SDimitry Andric Instruction(uint8_t Opcode) 77ff0cc061SDimitry Andric : Opcode(Opcode) 78ff0cc061SDimitry Andric {} 79ff0cc061SDimitry Andric 80ff0cc061SDimitry Andric uint8_t Opcode; 81ff0cc061SDimitry Andric Operands Ops; 82ff0cc061SDimitry Andric }; 83ff0cc061SDimitry Andric 84ff0cc061SDimitry Andric std::vector<Instruction> Instructions; 85ff0cc061SDimitry Andric 86ff0cc061SDimitry Andric /// Convenience methods to add a new instruction with the given opcode and 87ff0cc061SDimitry Andric /// operands to the Instructions vector. 88ff0cc061SDimitry Andric void addInstruction(uint8_t Opcode) { 89ff0cc061SDimitry Andric Instructions.push_back(Instruction(Opcode)); 90ff0cc061SDimitry Andric } 91ff0cc061SDimitry Andric 92ff0cc061SDimitry Andric void addInstruction(uint8_t Opcode, uint64_t Operand1) { 93ff0cc061SDimitry Andric Instructions.push_back(Instruction(Opcode)); 94ff0cc061SDimitry Andric Instructions.back().Ops.push_back(Operand1); 95ff0cc061SDimitry Andric } 96ff0cc061SDimitry Andric 97ff0cc061SDimitry Andric void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2) { 98ff0cc061SDimitry Andric Instructions.push_back(Instruction(Opcode)); 99ff0cc061SDimitry Andric Instructions.back().Ops.push_back(Operand1); 100ff0cc061SDimitry Andric Instructions.back().Ops.push_back(Operand2); 101ff0cc061SDimitry Andric } 102ff0cc061SDimitry Andric }; 103ff0cc061SDimitry Andric 104ff0cc061SDimitry Andric // See DWARF standard v3, section 7.23 105ff0cc061SDimitry Andric const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0; 106ff0cc061SDimitry Andric const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f; 107ff0cc061SDimitry Andric 108ff0cc061SDimitry Andric void FrameEntry::parseInstructions(DataExtractor Data, uint32_t *Offset, 109ff0cc061SDimitry Andric uint32_t EndOffset) { 110ff0cc061SDimitry Andric while (*Offset < EndOffset) { 111ff0cc061SDimitry Andric uint8_t Opcode = Data.getU8(Offset); 112ff0cc061SDimitry Andric // Some instructions have a primary opcode encoded in the top bits. 113ff0cc061SDimitry Andric uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK; 114ff0cc061SDimitry Andric 115ff0cc061SDimitry Andric if (Primary) { 116ff0cc061SDimitry Andric // If it's a primary opcode, the first operand is encoded in the bottom 117ff0cc061SDimitry Andric // bits of the opcode itself. 118ff0cc061SDimitry Andric uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK; 119ff0cc061SDimitry Andric switch (Primary) { 120ff0cc061SDimitry Andric default: llvm_unreachable("Impossible primary CFI opcode"); 121ff0cc061SDimitry Andric case DW_CFA_advance_loc: 122ff0cc061SDimitry Andric case DW_CFA_restore: 123ff0cc061SDimitry Andric addInstruction(Primary, Op1); 124ff0cc061SDimitry Andric break; 125ff0cc061SDimitry Andric case DW_CFA_offset: 126ff0cc061SDimitry Andric addInstruction(Primary, Op1, Data.getULEB128(Offset)); 127ff0cc061SDimitry Andric break; 128ff0cc061SDimitry Andric } 129ff0cc061SDimitry Andric } else { 130ff0cc061SDimitry Andric // Extended opcode - its value is Opcode itself. 131ff0cc061SDimitry Andric switch (Opcode) { 132ff0cc061SDimitry Andric default: llvm_unreachable("Invalid extended CFI opcode"); 133ff0cc061SDimitry Andric case DW_CFA_nop: 134ff0cc061SDimitry Andric case DW_CFA_remember_state: 135ff0cc061SDimitry Andric case DW_CFA_restore_state: 136ff0cc061SDimitry Andric case DW_CFA_GNU_window_save: 137ff0cc061SDimitry Andric // No operands 138ff0cc061SDimitry Andric addInstruction(Opcode); 139ff0cc061SDimitry Andric break; 140ff0cc061SDimitry Andric case DW_CFA_set_loc: 141ff0cc061SDimitry Andric // Operands: Address 142ff0cc061SDimitry Andric addInstruction(Opcode, Data.getAddress(Offset)); 143ff0cc061SDimitry Andric break; 144ff0cc061SDimitry Andric case DW_CFA_advance_loc1: 145ff0cc061SDimitry Andric // Operands: 1-byte delta 146ff0cc061SDimitry Andric addInstruction(Opcode, Data.getU8(Offset)); 147ff0cc061SDimitry Andric break; 148ff0cc061SDimitry Andric case DW_CFA_advance_loc2: 149ff0cc061SDimitry Andric // Operands: 2-byte delta 150ff0cc061SDimitry Andric addInstruction(Opcode, Data.getU16(Offset)); 151ff0cc061SDimitry Andric break; 152ff0cc061SDimitry Andric case DW_CFA_advance_loc4: 153ff0cc061SDimitry Andric // Operands: 4-byte delta 154ff0cc061SDimitry Andric addInstruction(Opcode, Data.getU32(Offset)); 155ff0cc061SDimitry Andric break; 156ff0cc061SDimitry Andric case DW_CFA_restore_extended: 157ff0cc061SDimitry Andric case DW_CFA_undefined: 158ff0cc061SDimitry Andric case DW_CFA_same_value: 159ff0cc061SDimitry Andric case DW_CFA_def_cfa_register: 160ff0cc061SDimitry Andric case DW_CFA_def_cfa_offset: 161ff0cc061SDimitry Andric // Operands: ULEB128 162ff0cc061SDimitry Andric addInstruction(Opcode, Data.getULEB128(Offset)); 163ff0cc061SDimitry Andric break; 164ff0cc061SDimitry Andric case DW_CFA_def_cfa_offset_sf: 165ff0cc061SDimitry Andric // Operands: SLEB128 166ff0cc061SDimitry Andric addInstruction(Opcode, Data.getSLEB128(Offset)); 167ff0cc061SDimitry Andric break; 168ff0cc061SDimitry Andric case DW_CFA_offset_extended: 169ff0cc061SDimitry Andric case DW_CFA_register: 170ff0cc061SDimitry Andric case DW_CFA_def_cfa: 1713ca95b02SDimitry Andric case DW_CFA_val_offset: { 172ff0cc061SDimitry Andric // Operands: ULEB128, ULEB128 1733ca95b02SDimitry Andric // Note: We can not embed getULEB128 directly into function 1743ca95b02SDimitry Andric // argument list. getULEB128 changes Offset and order of evaluation 1753ca95b02SDimitry Andric // for arguments is unspecified. 1763ca95b02SDimitry Andric auto op1 = Data.getULEB128(Offset); 1773ca95b02SDimitry Andric auto op2 = Data.getULEB128(Offset); 1783ca95b02SDimitry Andric addInstruction(Opcode, op1, op2); 179ff0cc061SDimitry Andric break; 1803ca95b02SDimitry Andric } 181ff0cc061SDimitry Andric case DW_CFA_offset_extended_sf: 182ff0cc061SDimitry Andric case DW_CFA_def_cfa_sf: 1833ca95b02SDimitry Andric case DW_CFA_val_offset_sf: { 184ff0cc061SDimitry Andric // Operands: ULEB128, SLEB128 1853ca95b02SDimitry Andric // Note: see comment for the previous case 1863ca95b02SDimitry Andric auto op1 = Data.getULEB128(Offset); 1873ca95b02SDimitry Andric auto op2 = (uint64_t)Data.getSLEB128(Offset); 1883ca95b02SDimitry Andric addInstruction(Opcode, op1, op2); 189ff0cc061SDimitry Andric break; 1903ca95b02SDimitry Andric } 191ff0cc061SDimitry Andric case DW_CFA_def_cfa_expression: 192ff0cc061SDimitry Andric case DW_CFA_expression: 193ff0cc061SDimitry Andric case DW_CFA_val_expression: 194ff0cc061SDimitry Andric // TODO: implement this 195ff0cc061SDimitry Andric report_fatal_error("Values with expressions not implemented yet!"); 196ff0cc061SDimitry Andric } 197ff0cc061SDimitry Andric } 198ff0cc061SDimitry Andric } 199ff0cc061SDimitry Andric } 200ff0cc061SDimitry Andric 201ff0cc061SDimitry Andric namespace { 202d88c1a5aSDimitry Andric 203ff0cc061SDimitry Andric /// \brief DWARF Common Information Entry (CIE) 204ff0cc061SDimitry Andric class CIE : public FrameEntry { 205ff0cc061SDimitry Andric public: 206ff0cc061SDimitry Andric // CIEs (and FDEs) are simply container classes, so the only sensible way to 207ff0cc061SDimitry Andric // create them is by providing the full parsed contents in the constructor. 208ff0cc061SDimitry Andric CIE(uint64_t Offset, uint64_t Length, uint8_t Version, 209ff0cc061SDimitry Andric SmallString<8> Augmentation, uint8_t AddressSize, 210ff0cc061SDimitry Andric uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor, 2113ca95b02SDimitry Andric int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister, 2123ca95b02SDimitry Andric SmallString<8> AugmentationData, uint32_t FDEPointerEncoding, 2133ca95b02SDimitry Andric uint32_t LSDAPointerEncoding) 214ff0cc061SDimitry Andric : FrameEntry(FK_CIE, Offset, Length), Version(Version), 2153ca95b02SDimitry Andric Augmentation(std::move(Augmentation)), AddressSize(AddressSize), 216ff0cc061SDimitry Andric SegmentDescriptorSize(SegmentDescriptorSize), 217ff0cc061SDimitry Andric CodeAlignmentFactor(CodeAlignmentFactor), 218ff0cc061SDimitry Andric DataAlignmentFactor(DataAlignmentFactor), 2193ca95b02SDimitry Andric ReturnAddressRegister(ReturnAddressRegister), 2203ca95b02SDimitry Andric AugmentationData(std::move(AugmentationData)), 2213ca95b02SDimitry Andric FDEPointerEncoding(FDEPointerEncoding), 2223ca95b02SDimitry Andric LSDAPointerEncoding(LSDAPointerEncoding) {} 223ff0cc061SDimitry Andric 224d88c1a5aSDimitry Andric ~CIE() override = default; 225ff0cc061SDimitry Andric 2263ca95b02SDimitry Andric StringRef getAugmentationString() const { return Augmentation; } 227ff0cc061SDimitry Andric uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; } 228ff0cc061SDimitry Andric int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; } 229d88c1a5aSDimitry Andric 2303ca95b02SDimitry Andric uint32_t getFDEPointerEncoding() const { 2313ca95b02SDimitry Andric return FDEPointerEncoding; 2323ca95b02SDimitry Andric } 233d88c1a5aSDimitry Andric 2343ca95b02SDimitry Andric uint32_t getLSDAPointerEncoding() const { 2353ca95b02SDimitry Andric return LSDAPointerEncoding; 2363ca95b02SDimitry Andric } 237ff0cc061SDimitry Andric 238ff0cc061SDimitry Andric void dumpHeader(raw_ostream &OS) const override { 239ff0cc061SDimitry Andric OS << format("%08x %08x %08x CIE", 240ff0cc061SDimitry Andric (uint32_t)Offset, (uint32_t)Length, DW_CIE_ID) 241ff0cc061SDimitry Andric << "\n"; 242ff0cc061SDimitry Andric OS << format(" Version: %d\n", Version); 243ff0cc061SDimitry Andric OS << " Augmentation: \"" << Augmentation << "\"\n"; 244ff0cc061SDimitry Andric if (Version >= 4) { 245ff0cc061SDimitry Andric OS << format(" Address size: %u\n", 246ff0cc061SDimitry Andric (uint32_t)AddressSize); 247ff0cc061SDimitry Andric OS << format(" Segment desc size: %u\n", 248ff0cc061SDimitry Andric (uint32_t)SegmentDescriptorSize); 249ff0cc061SDimitry Andric } 250ff0cc061SDimitry Andric OS << format(" Code alignment factor: %u\n", 251ff0cc061SDimitry Andric (uint32_t)CodeAlignmentFactor); 252ff0cc061SDimitry Andric OS << format(" Data alignment factor: %d\n", 253ff0cc061SDimitry Andric (int32_t)DataAlignmentFactor); 254ff0cc061SDimitry Andric OS << format(" Return address column: %d\n", 255ff0cc061SDimitry Andric (int32_t)ReturnAddressRegister); 2563ca95b02SDimitry Andric if (!AugmentationData.empty()) { 2573ca95b02SDimitry Andric OS << " Augmentation data: "; 2583ca95b02SDimitry Andric for (uint8_t Byte : AugmentationData) 2593ca95b02SDimitry Andric OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf); 2603ca95b02SDimitry Andric OS << "\n"; 2613ca95b02SDimitry Andric } 262ff0cc061SDimitry Andric OS << "\n"; 263ff0cc061SDimitry Andric } 264ff0cc061SDimitry Andric 265ff0cc061SDimitry Andric static bool classof(const FrameEntry *FE) { 266ff0cc061SDimitry Andric return FE->getKind() == FK_CIE; 267ff0cc061SDimitry Andric } 268ff0cc061SDimitry Andric 269ff0cc061SDimitry Andric private: 270ff0cc061SDimitry Andric /// The following fields are defined in section 6.4.1 of the DWARF standard v4 271ff0cc061SDimitry Andric uint8_t Version; 272ff0cc061SDimitry Andric SmallString<8> Augmentation; 273ff0cc061SDimitry Andric uint8_t AddressSize; 274ff0cc061SDimitry Andric uint8_t SegmentDescriptorSize; 275ff0cc061SDimitry Andric uint64_t CodeAlignmentFactor; 276ff0cc061SDimitry Andric int64_t DataAlignmentFactor; 277ff0cc061SDimitry Andric uint64_t ReturnAddressRegister; 2783ca95b02SDimitry Andric 2793ca95b02SDimitry Andric // The following are used when the CIE represents an EH frame entry. 2803ca95b02SDimitry Andric SmallString<8> AugmentationData; 2813ca95b02SDimitry Andric uint32_t FDEPointerEncoding; 2823ca95b02SDimitry Andric uint32_t LSDAPointerEncoding; 283ff0cc061SDimitry Andric }; 284ff0cc061SDimitry Andric 285ff0cc061SDimitry Andric /// \brief DWARF Frame Description Entry (FDE) 286ff0cc061SDimitry Andric class FDE : public FrameEntry { 287ff0cc061SDimitry Andric public: 288ff0cc061SDimitry Andric // Each FDE has a CIE it's "linked to". Our FDE contains is constructed with 289ff0cc061SDimitry Andric // an offset to the CIE (provided by parsing the FDE header). The CIE itself 290ff0cc061SDimitry Andric // is obtained lazily once it's actually required. 291ff0cc061SDimitry Andric FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset, 292ff0cc061SDimitry Andric uint64_t InitialLocation, uint64_t AddressRange, 293ff0cc061SDimitry Andric CIE *Cie) 294ff0cc061SDimitry Andric : FrameEntry(FK_FDE, Offset, Length), LinkedCIEOffset(LinkedCIEOffset), 295ff0cc061SDimitry Andric InitialLocation(InitialLocation), AddressRange(AddressRange), 296ff0cc061SDimitry Andric LinkedCIE(Cie) {} 297ff0cc061SDimitry Andric 298d88c1a5aSDimitry Andric ~FDE() override = default; 299ff0cc061SDimitry Andric 300ff0cc061SDimitry Andric CIE *getLinkedCIE() const { return LinkedCIE; } 301ff0cc061SDimitry Andric 302ff0cc061SDimitry Andric void dumpHeader(raw_ostream &OS) const override { 303ff0cc061SDimitry Andric OS << format("%08x %08x %08x FDE ", 304ff0cc061SDimitry Andric (uint32_t)Offset, (uint32_t)Length, (int32_t)LinkedCIEOffset); 305ff0cc061SDimitry Andric OS << format("cie=%08x pc=%08x...%08x\n", 306ff0cc061SDimitry Andric (int32_t)LinkedCIEOffset, 307ff0cc061SDimitry Andric (uint32_t)InitialLocation, 308ff0cc061SDimitry Andric (uint32_t)InitialLocation + (uint32_t)AddressRange); 309ff0cc061SDimitry Andric } 310ff0cc061SDimitry Andric 311ff0cc061SDimitry Andric static bool classof(const FrameEntry *FE) { 312ff0cc061SDimitry Andric return FE->getKind() == FK_FDE; 313ff0cc061SDimitry Andric } 314ff0cc061SDimitry Andric 315ff0cc061SDimitry Andric private: 316ff0cc061SDimitry Andric /// The following fields are defined in section 6.4.1 of the DWARF standard v3 317ff0cc061SDimitry Andric uint64_t LinkedCIEOffset; 318ff0cc061SDimitry Andric uint64_t InitialLocation; 319ff0cc061SDimitry Andric uint64_t AddressRange; 320ff0cc061SDimitry Andric CIE *LinkedCIE; 321ff0cc061SDimitry Andric }; 322ff0cc061SDimitry Andric 323ff0cc061SDimitry Andric /// \brief Types of operands to CF instructions. 324ff0cc061SDimitry Andric enum OperandType { 325ff0cc061SDimitry Andric OT_Unset, 326ff0cc061SDimitry Andric OT_None, 327ff0cc061SDimitry Andric OT_Address, 328ff0cc061SDimitry Andric OT_Offset, 329ff0cc061SDimitry Andric OT_FactoredCodeOffset, 330ff0cc061SDimitry Andric OT_SignedFactDataOffset, 331ff0cc061SDimitry Andric OT_UnsignedFactDataOffset, 332ff0cc061SDimitry Andric OT_Register, 333ff0cc061SDimitry Andric OT_Expression 334ff0cc061SDimitry Andric }; 335ff0cc061SDimitry Andric 336ff0cc061SDimitry Andric } // end anonymous namespace 337ff0cc061SDimitry Andric 338ff0cc061SDimitry Andric /// \brief Initialize the array describing the types of operands. 339ff0cc061SDimitry Andric static ArrayRef<OperandType[2]> getOperandTypes() { 340ff0cc061SDimitry Andric static OperandType OpTypes[DW_CFA_restore+1][2]; 341ff0cc061SDimitry Andric 342ff0cc061SDimitry Andric #define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \ 343ff0cc061SDimitry Andric do { \ 344ff0cc061SDimitry Andric OpTypes[OP][0] = OPTYPE0; \ 345ff0cc061SDimitry Andric OpTypes[OP][1] = OPTYPE1; \ 346d88c1a5aSDimitry Andric } while (false) 347ff0cc061SDimitry Andric #define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None) 348ff0cc061SDimitry Andric #define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None) 349ff0cc061SDimitry Andric 350ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_set_loc, OT_Address); 351ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset); 352ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset); 353ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset); 354ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset); 355ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset); 356ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset); 357ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset); 358ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register); 359ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset); 360ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset); 361ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression); 362ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_undefined, OT_Register); 363ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_same_value, OT_Register); 364ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset); 365ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset); 366ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset); 367ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset); 368ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset); 369ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register); 370ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression); 371ff0cc061SDimitry Andric DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression); 372ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_restore, OT_Register); 373ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_restore_extended, OT_Register); 374ff0cc061SDimitry Andric DECLARE_OP0(DW_CFA_remember_state); 375ff0cc061SDimitry Andric DECLARE_OP0(DW_CFA_restore_state); 376ff0cc061SDimitry Andric DECLARE_OP0(DW_CFA_GNU_window_save); 377ff0cc061SDimitry Andric DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset); 378ff0cc061SDimitry Andric DECLARE_OP0(DW_CFA_nop); 379ff0cc061SDimitry Andric 380ff0cc061SDimitry Andric #undef DECLARE_OP0 381ff0cc061SDimitry Andric #undef DECLARE_OP1 382ff0cc061SDimitry Andric #undef DECLARE_OP2 383d88c1a5aSDimitry Andric 384ff0cc061SDimitry Andric return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1); 385ff0cc061SDimitry Andric } 386ff0cc061SDimitry Andric 387ff0cc061SDimitry Andric static ArrayRef<OperandType[2]> OpTypes = getOperandTypes(); 388ff0cc061SDimitry Andric 389ff0cc061SDimitry Andric /// \brief Print \p Opcode's operand number \p OperandIdx which has 390ff0cc061SDimitry Andric /// value \p Operand. 391ff0cc061SDimitry Andric static void printOperand(raw_ostream &OS, uint8_t Opcode, unsigned OperandIdx, 392ff0cc061SDimitry Andric uint64_t Operand, uint64_t CodeAlignmentFactor, 393ff0cc061SDimitry Andric int64_t DataAlignmentFactor) { 394ff0cc061SDimitry Andric assert(OperandIdx < 2); 395ff0cc061SDimitry Andric OperandType Type = OpTypes[Opcode][OperandIdx]; 396ff0cc061SDimitry Andric 397ff0cc061SDimitry Andric switch (Type) { 398d88c1a5aSDimitry Andric case OT_Unset: { 399ff0cc061SDimitry Andric OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to"; 400d88c1a5aSDimitry Andric auto OpcodeName = CallFrameString(Opcode); 401d88c1a5aSDimitry Andric if (!OpcodeName.empty()) 402ff0cc061SDimitry Andric OS << " " << OpcodeName; 403ff0cc061SDimitry Andric else 404ff0cc061SDimitry Andric OS << format(" Opcode %x", Opcode); 405ff0cc061SDimitry Andric break; 406d88c1a5aSDimitry Andric } 407ff0cc061SDimitry Andric case OT_None: 408ff0cc061SDimitry Andric break; 409ff0cc061SDimitry Andric case OT_Address: 410ff0cc061SDimitry Andric OS << format(" %" PRIx64, Operand); 411ff0cc061SDimitry Andric break; 412ff0cc061SDimitry Andric case OT_Offset: 413ff0cc061SDimitry Andric // The offsets are all encoded in a unsigned form, but in practice 414ff0cc061SDimitry Andric // consumers use them signed. It's most certainly legacy due to 415ff0cc061SDimitry Andric // the lack of signed variants in the first Dwarf standards. 416ff0cc061SDimitry Andric OS << format(" %+" PRId64, int64_t(Operand)); 417ff0cc061SDimitry Andric break; 418ff0cc061SDimitry Andric case OT_FactoredCodeOffset: // Always Unsigned 419ff0cc061SDimitry Andric if (CodeAlignmentFactor) 420ff0cc061SDimitry Andric OS << format(" %" PRId64, Operand * CodeAlignmentFactor); 421ff0cc061SDimitry Andric else 422ff0cc061SDimitry Andric OS << format(" %" PRId64 "*code_alignment_factor" , Operand); 423ff0cc061SDimitry Andric break; 424ff0cc061SDimitry Andric case OT_SignedFactDataOffset: 425ff0cc061SDimitry Andric if (DataAlignmentFactor) 426ff0cc061SDimitry Andric OS << format(" %" PRId64, int64_t(Operand) * DataAlignmentFactor); 427ff0cc061SDimitry Andric else 428ff0cc061SDimitry Andric OS << format(" %" PRId64 "*data_alignment_factor" , int64_t(Operand)); 429ff0cc061SDimitry Andric break; 430ff0cc061SDimitry Andric case OT_UnsignedFactDataOffset: 431ff0cc061SDimitry Andric if (DataAlignmentFactor) 432ff0cc061SDimitry Andric OS << format(" %" PRId64, Operand * DataAlignmentFactor); 433ff0cc061SDimitry Andric else 434ff0cc061SDimitry Andric OS << format(" %" PRId64 "*data_alignment_factor" , Operand); 435ff0cc061SDimitry Andric break; 436ff0cc061SDimitry Andric case OT_Register: 437ff0cc061SDimitry Andric OS << format(" reg%" PRId64, Operand); 438ff0cc061SDimitry Andric break; 439ff0cc061SDimitry Andric case OT_Expression: 440ff0cc061SDimitry Andric OS << " expression"; 441ff0cc061SDimitry Andric break; 442ff0cc061SDimitry Andric } 443ff0cc061SDimitry Andric } 444ff0cc061SDimitry Andric 445ff0cc061SDimitry Andric void FrameEntry::dumpInstructions(raw_ostream &OS) const { 446ff0cc061SDimitry Andric uint64_t CodeAlignmentFactor = 0; 447ff0cc061SDimitry Andric int64_t DataAlignmentFactor = 0; 448ff0cc061SDimitry Andric const CIE *Cie = dyn_cast<CIE>(this); 449ff0cc061SDimitry Andric 450ff0cc061SDimitry Andric if (!Cie) 451ff0cc061SDimitry Andric Cie = cast<FDE>(this)->getLinkedCIE(); 452ff0cc061SDimitry Andric if (Cie) { 453ff0cc061SDimitry Andric CodeAlignmentFactor = Cie->getCodeAlignmentFactor(); 454ff0cc061SDimitry Andric DataAlignmentFactor = Cie->getDataAlignmentFactor(); 455ff0cc061SDimitry Andric } 456ff0cc061SDimitry Andric 457ff0cc061SDimitry Andric for (const auto &Instr : Instructions) { 458ff0cc061SDimitry Andric uint8_t Opcode = Instr.Opcode; 459ff0cc061SDimitry Andric if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) 460ff0cc061SDimitry Andric Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK; 461ff0cc061SDimitry Andric OS << " " << CallFrameString(Opcode) << ":"; 462ff0cc061SDimitry Andric for (unsigned i = 0; i < Instr.Ops.size(); ++i) 463ff0cc061SDimitry Andric printOperand(OS, Opcode, i, Instr.Ops[i], CodeAlignmentFactor, 464ff0cc061SDimitry Andric DataAlignmentFactor); 465ff0cc061SDimitry Andric OS << '\n'; 466ff0cc061SDimitry Andric } 467ff0cc061SDimitry Andric } 468ff0cc061SDimitry Andric 4697a7e6055SDimitry Andric DWARFDebugFrame::DWARFDebugFrame(bool IsEH) : IsEH(IsEH) {} 470ff0cc061SDimitry Andric 471d88c1a5aSDimitry Andric DWARFDebugFrame::~DWARFDebugFrame() = default; 472ff0cc061SDimitry Andric 473ff0cc061SDimitry Andric static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data, 474ff0cc061SDimitry Andric uint32_t Offset, int Length) { 475ff0cc061SDimitry Andric errs() << "DUMP: "; 476ff0cc061SDimitry Andric for (int i = 0; i < Length; ++i) { 477ff0cc061SDimitry Andric uint8_t c = Data.getU8(&Offset); 478ff0cc061SDimitry Andric errs().write_hex(c); errs() << " "; 479ff0cc061SDimitry Andric } 480ff0cc061SDimitry Andric errs() << "\n"; 481ff0cc061SDimitry Andric } 482ff0cc061SDimitry Andric 4833ca95b02SDimitry Andric static unsigned getSizeForEncoding(const DataExtractor &Data, 4843ca95b02SDimitry Andric unsigned symbolEncoding) { 4853ca95b02SDimitry Andric unsigned format = symbolEncoding & 0x0f; 4863ca95b02SDimitry Andric switch (format) { 4873ca95b02SDimitry Andric default: llvm_unreachable("Unknown Encoding"); 4887a7e6055SDimitry Andric case DW_EH_PE_absptr: 4897a7e6055SDimitry Andric case DW_EH_PE_signed: 4903ca95b02SDimitry Andric return Data.getAddressSize(); 4917a7e6055SDimitry Andric case DW_EH_PE_udata2: 4927a7e6055SDimitry Andric case DW_EH_PE_sdata2: 4933ca95b02SDimitry Andric return 2; 4947a7e6055SDimitry Andric case DW_EH_PE_udata4: 4957a7e6055SDimitry Andric case DW_EH_PE_sdata4: 4963ca95b02SDimitry Andric return 4; 4977a7e6055SDimitry Andric case DW_EH_PE_udata8: 4987a7e6055SDimitry Andric case DW_EH_PE_sdata8: 4993ca95b02SDimitry Andric return 8; 5003ca95b02SDimitry Andric } 5013ca95b02SDimitry Andric } 5023ca95b02SDimitry Andric 5033ca95b02SDimitry Andric static uint64_t readPointer(const DataExtractor &Data, uint32_t &Offset, 5043ca95b02SDimitry Andric unsigned Encoding) { 5053ca95b02SDimitry Andric switch (getSizeForEncoding(Data, Encoding)) { 5063ca95b02SDimitry Andric case 2: 5073ca95b02SDimitry Andric return Data.getU16(&Offset); 5083ca95b02SDimitry Andric case 4: 5093ca95b02SDimitry Andric return Data.getU32(&Offset); 5103ca95b02SDimitry Andric case 8: 5113ca95b02SDimitry Andric return Data.getU64(&Offset); 5123ca95b02SDimitry Andric default: 5133ca95b02SDimitry Andric llvm_unreachable("Illegal data size"); 5143ca95b02SDimitry Andric } 5153ca95b02SDimitry Andric } 516ff0cc061SDimitry Andric 51724d58133SDimitry Andric // This is a workaround for old compilers which do not allow 51824d58133SDimitry Andric // noreturn attribute usage in lambdas. Once the support for those 51924d58133SDimitry Andric // compilers are phased out, we can remove this and return back to 52024d58133SDimitry Andric // a ReportError lambda: [StartOffset](const char *ErrorMsg). 52124d58133SDimitry Andric #define ReportError(ErrorMsg) ReportErrorImpl(StartOffset,ErrorMsg) 52224d58133SDimitry Andric static void LLVM_ATTRIBUTE_NORETURN 52324d58133SDimitry Andric ReportErrorImpl(uint32_t StartOffset, const char *ErrorMsg) { 52424d58133SDimitry Andric std::string Str; 52524d58133SDimitry Andric raw_string_ostream OS(Str); 52624d58133SDimitry Andric OS << format(ErrorMsg, StartOffset); 52724d58133SDimitry Andric OS.flush(); 52824d58133SDimitry Andric report_fatal_error(Str); 52924d58133SDimitry Andric } 53024d58133SDimitry Andric 531ff0cc061SDimitry Andric void DWARFDebugFrame::parse(DataExtractor Data) { 532ff0cc061SDimitry Andric uint32_t Offset = 0; 533ff0cc061SDimitry Andric DenseMap<uint32_t, CIE *> CIEs; 534ff0cc061SDimitry Andric 535ff0cc061SDimitry Andric while (Data.isValidOffset(Offset)) { 536ff0cc061SDimitry Andric uint32_t StartOffset = Offset; 537ff0cc061SDimitry Andric 538ff0cc061SDimitry Andric bool IsDWARF64 = false; 539ff0cc061SDimitry Andric uint64_t Length = Data.getU32(&Offset); 540ff0cc061SDimitry Andric uint64_t Id; 541ff0cc061SDimitry Andric 542ff0cc061SDimitry Andric if (Length == UINT32_MAX) { 543ff0cc061SDimitry Andric // DWARF-64 is distinguished by the first 32 bits of the initial length 544ff0cc061SDimitry Andric // field being 0xffffffff. Then, the next 64 bits are the actual entry 545ff0cc061SDimitry Andric // length. 546ff0cc061SDimitry Andric IsDWARF64 = true; 547ff0cc061SDimitry Andric Length = Data.getU64(&Offset); 548ff0cc061SDimitry Andric } 549ff0cc061SDimitry Andric 550ff0cc061SDimitry Andric // At this point, Offset points to the next field after Length. 551ff0cc061SDimitry Andric // Length is the structure size excluding itself. Compute an offset one 552ff0cc061SDimitry Andric // past the end of the structure (needed to know how many instructions to 553ff0cc061SDimitry Andric // read). 554ff0cc061SDimitry Andric // TODO: For honest DWARF64 support, DataExtractor will have to treat 555ff0cc061SDimitry Andric // offset_ptr as uint64_t* 5563ca95b02SDimitry Andric uint32_t StartStructureOffset = Offset; 557ff0cc061SDimitry Andric uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length); 558ff0cc061SDimitry Andric 559ff0cc061SDimitry Andric // The Id field's size depends on the DWARF format 5603ca95b02SDimitry Andric Id = Data.getUnsigned(&Offset, (IsDWARF64 && !IsEH) ? 8 : 4); 5613ca95b02SDimitry Andric bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) || 5623ca95b02SDimitry Andric Id == DW_CIE_ID || 5633ca95b02SDimitry Andric (IsEH && !Id)); 564ff0cc061SDimitry Andric 565ff0cc061SDimitry Andric if (IsCIE) { 566ff0cc061SDimitry Andric uint8_t Version = Data.getU8(&Offset); 567ff0cc061SDimitry Andric const char *Augmentation = Data.getCStr(&Offset); 5683ca95b02SDimitry Andric StringRef AugmentationString(Augmentation ? Augmentation : ""); 5693ca95b02SDimitry Andric uint8_t AddressSize = Version < 4 ? Data.getAddressSize() : 5703ca95b02SDimitry Andric Data.getU8(&Offset); 571ff0cc061SDimitry Andric Data.setAddressSize(AddressSize); 572ff0cc061SDimitry Andric uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset); 573ff0cc061SDimitry Andric uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset); 574ff0cc061SDimitry Andric int64_t DataAlignmentFactor = Data.getSLEB128(&Offset); 575ff0cc061SDimitry Andric uint64_t ReturnAddressRegister = Data.getULEB128(&Offset); 576ff0cc061SDimitry Andric 5773ca95b02SDimitry Andric // Parse the augmentation data for EH CIEs 5783ca95b02SDimitry Andric StringRef AugmentationData(""); 5793ca95b02SDimitry Andric uint32_t FDEPointerEncoding = DW_EH_PE_omit; 5803ca95b02SDimitry Andric uint32_t LSDAPointerEncoding = DW_EH_PE_omit; 5813ca95b02SDimitry Andric if (IsEH) { 5823ca95b02SDimitry Andric Optional<uint32_t> PersonalityEncoding; 5833ca95b02SDimitry Andric Optional<uint64_t> Personality; 5843ca95b02SDimitry Andric 5853ca95b02SDimitry Andric Optional<uint64_t> AugmentationLength; 5863ca95b02SDimitry Andric uint32_t StartAugmentationOffset; 5873ca95b02SDimitry Andric uint32_t EndAugmentationOffset; 5883ca95b02SDimitry Andric 5893ca95b02SDimitry Andric // Walk the augmentation string to get all the augmentation data. 5903ca95b02SDimitry Andric for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) { 5913ca95b02SDimitry Andric switch (AugmentationString[i]) { 5923ca95b02SDimitry Andric default: 5933ca95b02SDimitry Andric ReportError("Unknown augmentation character in entry at %lx"); 5943ca95b02SDimitry Andric case 'L': 5953ca95b02SDimitry Andric LSDAPointerEncoding = Data.getU8(&Offset); 5963ca95b02SDimitry Andric break; 5973ca95b02SDimitry Andric case 'P': { 5983ca95b02SDimitry Andric if (Personality) 5993ca95b02SDimitry Andric ReportError("Duplicate personality in entry at %lx"); 6003ca95b02SDimitry Andric PersonalityEncoding = Data.getU8(&Offset); 6013ca95b02SDimitry Andric Personality = readPointer(Data, Offset, *PersonalityEncoding); 6023ca95b02SDimitry Andric break; 6033ca95b02SDimitry Andric } 6043ca95b02SDimitry Andric case 'R': 6053ca95b02SDimitry Andric FDEPointerEncoding = Data.getU8(&Offset); 6063ca95b02SDimitry Andric break; 6073ca95b02SDimitry Andric case 'z': 6083ca95b02SDimitry Andric if (i) 6093ca95b02SDimitry Andric ReportError("'z' must be the first character at %lx"); 6103ca95b02SDimitry Andric // Parse the augmentation length first. We only parse it if 6113ca95b02SDimitry Andric // the string contains a 'z'. 6123ca95b02SDimitry Andric AugmentationLength = Data.getULEB128(&Offset); 6133ca95b02SDimitry Andric StartAugmentationOffset = Offset; 6143ca95b02SDimitry Andric EndAugmentationOffset = Offset + 6153ca95b02SDimitry Andric static_cast<uint32_t>(*AugmentationLength); 6163ca95b02SDimitry Andric } 6173ca95b02SDimitry Andric } 6183ca95b02SDimitry Andric 6193ca95b02SDimitry Andric if (AugmentationLength.hasValue()) { 6203ca95b02SDimitry Andric if (Offset != EndAugmentationOffset) 6213ca95b02SDimitry Andric ReportError("Parsing augmentation data at %lx failed"); 6223ca95b02SDimitry Andric 6233ca95b02SDimitry Andric AugmentationData = Data.getData().slice(StartAugmentationOffset, 6243ca95b02SDimitry Andric EndAugmentationOffset); 6253ca95b02SDimitry Andric } 6263ca95b02SDimitry Andric } 6273ca95b02SDimitry Andric 628d88c1a5aSDimitry Andric auto Cie = llvm::make_unique<CIE>(StartOffset, Length, Version, 6293ca95b02SDimitry Andric AugmentationString, AddressSize, 630d88c1a5aSDimitry Andric SegmentDescriptorSize, 631d88c1a5aSDimitry Andric CodeAlignmentFactor, 632d88c1a5aSDimitry Andric DataAlignmentFactor, 633d88c1a5aSDimitry Andric ReturnAddressRegister, 6343ca95b02SDimitry Andric AugmentationData, FDEPointerEncoding, 6353ca95b02SDimitry Andric LSDAPointerEncoding); 636ff0cc061SDimitry Andric CIEs[StartOffset] = Cie.get(); 637ff0cc061SDimitry Andric Entries.emplace_back(std::move(Cie)); 638ff0cc061SDimitry Andric } else { 639ff0cc061SDimitry Andric // FDE 640ff0cc061SDimitry Andric uint64_t CIEPointer = Id; 6413ca95b02SDimitry Andric uint64_t InitialLocation = 0; 6423ca95b02SDimitry Andric uint64_t AddressRange = 0; 6433ca95b02SDimitry Andric CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer]; 6443ca95b02SDimitry Andric 6453ca95b02SDimitry Andric if (IsEH) { 6463ca95b02SDimitry Andric // The address size is encoded in the CIE we reference. 6473ca95b02SDimitry Andric if (!Cie) 6483ca95b02SDimitry Andric ReportError("Parsing FDE data at %lx failed due to missing CIE"); 6493ca95b02SDimitry Andric 6503ca95b02SDimitry Andric InitialLocation = readPointer(Data, Offset, 6513ca95b02SDimitry Andric Cie->getFDEPointerEncoding()); 6523ca95b02SDimitry Andric AddressRange = readPointer(Data, Offset, 6533ca95b02SDimitry Andric Cie->getFDEPointerEncoding()); 6543ca95b02SDimitry Andric 6553ca95b02SDimitry Andric StringRef AugmentationString = Cie->getAugmentationString(); 6563ca95b02SDimitry Andric if (!AugmentationString.empty()) { 6573ca95b02SDimitry Andric // Parse the augmentation length and data for this FDE. 6583ca95b02SDimitry Andric uint64_t AugmentationLength = Data.getULEB128(&Offset); 6593ca95b02SDimitry Andric 6603ca95b02SDimitry Andric uint32_t EndAugmentationOffset = 6613ca95b02SDimitry Andric Offset + static_cast<uint32_t>(AugmentationLength); 6623ca95b02SDimitry Andric 6633ca95b02SDimitry Andric // Decode the LSDA if the CIE augmentation string said we should. 6643ca95b02SDimitry Andric if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit) 6653ca95b02SDimitry Andric readPointer(Data, Offset, Cie->getLSDAPointerEncoding()); 6663ca95b02SDimitry Andric 6673ca95b02SDimitry Andric if (Offset != EndAugmentationOffset) 6683ca95b02SDimitry Andric ReportError("Parsing augmentation data at %lx failed"); 6693ca95b02SDimitry Andric } 6703ca95b02SDimitry Andric } else { 6713ca95b02SDimitry Andric InitialLocation = Data.getAddress(&Offset); 6723ca95b02SDimitry Andric AddressRange = Data.getAddress(&Offset); 6733ca95b02SDimitry Andric } 674ff0cc061SDimitry Andric 675ff0cc061SDimitry Andric Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer, 676ff0cc061SDimitry Andric InitialLocation, AddressRange, 6773ca95b02SDimitry Andric Cie)); 678ff0cc061SDimitry Andric } 679ff0cc061SDimitry Andric 680ff0cc061SDimitry Andric Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset); 681ff0cc061SDimitry Andric 6823ca95b02SDimitry Andric if (Offset != EndStructureOffset) 6833ca95b02SDimitry Andric ReportError("Parsing entry instructions at %lx failed"); 684ff0cc061SDimitry Andric } 685ff0cc061SDimitry Andric } 686ff0cc061SDimitry Andric 687ff0cc061SDimitry Andric void DWARFDebugFrame::dump(raw_ostream &OS) const { 688ff0cc061SDimitry Andric OS << "\n"; 689ff0cc061SDimitry Andric for (const auto &Entry : Entries) { 690ff0cc061SDimitry Andric Entry->dumpHeader(OS); 691ff0cc061SDimitry Andric Entry->dumpInstructions(OS); 692ff0cc061SDimitry Andric OS << "\n"; 693ff0cc061SDimitry Andric } 694ff0cc061SDimitry Andric } 695