1ff0cc061SDimitry Andric //===-- DWARFDebugFrame.h - Parsing of .debug_frame -------------*- C++ -*-===//
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 
10ff0cc061SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
11ff0cc061SDimitry Andric #include "llvm/ADT/ArrayRef.h"
12ff0cc061SDimitry Andric #include "llvm/ADT/DenseMap.h"
133ca95b02SDimitry Andric #include "llvm/ADT/Optional.h"
14ff0cc061SDimitry Andric #include "llvm/ADT/SmallString.h"
153ca95b02SDimitry Andric #include "llvm/ADT/StringExtras.h"
16ff0cc061SDimitry Andric #include "llvm/Support/Casting.h"
17ff0cc061SDimitry Andric #include "llvm/Support/DataTypes.h"
18ff0cc061SDimitry Andric #include "llvm/Support/Dwarf.h"
19ff0cc061SDimitry Andric #include "llvm/Support/ErrorHandling.h"
20ff0cc061SDimitry Andric #include "llvm/Support/Format.h"
21ff0cc061SDimitry Andric #include "llvm/Support/raw_ostream.h"
22ff0cc061SDimitry Andric #include <string>
233ca95b02SDimitry Andric #include <utility>
24ff0cc061SDimitry Andric #include <vector>
25ff0cc061SDimitry Andric 
26ff0cc061SDimitry Andric using namespace llvm;
27ff0cc061SDimitry Andric using namespace dwarf;
28ff0cc061SDimitry Andric 
29ff0cc061SDimitry Andric 
30ff0cc061SDimitry Andric /// \brief Abstract frame entry defining the common interface concrete
31ff0cc061SDimitry Andric /// entries implement.
32ff0cc061SDimitry Andric class llvm::FrameEntry {
33ff0cc061SDimitry Andric public:
34ff0cc061SDimitry Andric   enum FrameKind {FK_CIE, FK_FDE};
35ff0cc061SDimitry Andric   FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length)
36ff0cc061SDimitry Andric       : Kind(K), Offset(Offset), Length(Length) {}
37ff0cc061SDimitry Andric 
38ff0cc061SDimitry Andric   virtual ~FrameEntry() {
39ff0cc061SDimitry Andric   }
40ff0cc061SDimitry Andric 
41ff0cc061SDimitry Andric   FrameKind getKind() const { return Kind; }
42ff0cc061SDimitry Andric   virtual uint64_t getOffset() const { return Offset; }
43ff0cc061SDimitry Andric 
44ff0cc061SDimitry Andric   /// \brief Parse and store a sequence of CFI instructions from Data,
45ff0cc061SDimitry Andric   /// starting at *Offset and ending at EndOffset. If everything
46ff0cc061SDimitry Andric   /// goes well, *Offset should be equal to EndOffset when this method
47ff0cc061SDimitry Andric   /// returns. Otherwise, an error occurred.
48ff0cc061SDimitry Andric   virtual void parseInstructions(DataExtractor Data, uint32_t *Offset,
49ff0cc061SDimitry Andric                                  uint32_t EndOffset);
50ff0cc061SDimitry Andric 
51ff0cc061SDimitry Andric   /// \brief Dump the entry header to the given output stream.
52ff0cc061SDimitry Andric   virtual void dumpHeader(raw_ostream &OS) const = 0;
53ff0cc061SDimitry Andric 
54ff0cc061SDimitry Andric   /// \brief Dump the entry's instructions to the given output stream.
55ff0cc061SDimitry Andric   virtual void dumpInstructions(raw_ostream &OS) const;
56ff0cc061SDimitry Andric 
57ff0cc061SDimitry Andric protected:
58ff0cc061SDimitry Andric   const FrameKind Kind;
59ff0cc061SDimitry Andric 
60ff0cc061SDimitry Andric   /// \brief Offset of this entry in the section.
61ff0cc061SDimitry Andric   uint64_t Offset;
62ff0cc061SDimitry Andric 
63ff0cc061SDimitry Andric   /// \brief Entry length as specified in DWARF.
64ff0cc061SDimitry Andric   uint64_t Length;
65ff0cc061SDimitry Andric 
66ff0cc061SDimitry Andric   /// An entry may contain CFI instructions. An instruction consists of an
67ff0cc061SDimitry Andric   /// opcode and an optional sequence of operands.
68ff0cc061SDimitry Andric   typedef std::vector<uint64_t> Operands;
69ff0cc061SDimitry Andric   struct Instruction {
70ff0cc061SDimitry Andric     Instruction(uint8_t Opcode)
71ff0cc061SDimitry Andric       : Opcode(Opcode)
72ff0cc061SDimitry Andric     {}
73ff0cc061SDimitry Andric 
74ff0cc061SDimitry Andric     uint8_t Opcode;
75ff0cc061SDimitry Andric     Operands Ops;
76ff0cc061SDimitry Andric   };
77ff0cc061SDimitry Andric 
78ff0cc061SDimitry Andric   std::vector<Instruction> Instructions;
79ff0cc061SDimitry Andric 
80ff0cc061SDimitry Andric   /// Convenience methods to add a new instruction with the given opcode and
81ff0cc061SDimitry Andric   /// operands to the Instructions vector.
82ff0cc061SDimitry Andric   void addInstruction(uint8_t Opcode) {
83ff0cc061SDimitry Andric     Instructions.push_back(Instruction(Opcode));
84ff0cc061SDimitry Andric   }
85ff0cc061SDimitry Andric 
86ff0cc061SDimitry Andric   void addInstruction(uint8_t Opcode, uint64_t Operand1) {
87ff0cc061SDimitry Andric     Instructions.push_back(Instruction(Opcode));
88ff0cc061SDimitry Andric     Instructions.back().Ops.push_back(Operand1);
89ff0cc061SDimitry Andric   }
90ff0cc061SDimitry Andric 
91ff0cc061SDimitry Andric   void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2) {
92ff0cc061SDimitry Andric     Instructions.push_back(Instruction(Opcode));
93ff0cc061SDimitry Andric     Instructions.back().Ops.push_back(Operand1);
94ff0cc061SDimitry Andric     Instructions.back().Ops.push_back(Operand2);
95ff0cc061SDimitry Andric   }
96ff0cc061SDimitry Andric };
97ff0cc061SDimitry Andric 
98ff0cc061SDimitry Andric 
99ff0cc061SDimitry Andric // See DWARF standard v3, section 7.23
100ff0cc061SDimitry Andric const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
101ff0cc061SDimitry Andric const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
102ff0cc061SDimitry Andric 
103ff0cc061SDimitry Andric void FrameEntry::parseInstructions(DataExtractor Data, uint32_t *Offset,
104ff0cc061SDimitry Andric                                    uint32_t EndOffset) {
105ff0cc061SDimitry Andric   while (*Offset < EndOffset) {
106ff0cc061SDimitry Andric     uint8_t Opcode = Data.getU8(Offset);
107ff0cc061SDimitry Andric     // Some instructions have a primary opcode encoded in the top bits.
108ff0cc061SDimitry Andric     uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK;
109ff0cc061SDimitry Andric 
110ff0cc061SDimitry Andric     if (Primary) {
111ff0cc061SDimitry Andric       // If it's a primary opcode, the first operand is encoded in the bottom
112ff0cc061SDimitry Andric       // bits of the opcode itself.
113ff0cc061SDimitry Andric       uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;
114ff0cc061SDimitry Andric       switch (Primary) {
115ff0cc061SDimitry Andric         default: llvm_unreachable("Impossible primary CFI opcode");
116ff0cc061SDimitry Andric         case DW_CFA_advance_loc:
117ff0cc061SDimitry Andric         case DW_CFA_restore:
118ff0cc061SDimitry Andric           addInstruction(Primary, Op1);
119ff0cc061SDimitry Andric           break;
120ff0cc061SDimitry Andric         case DW_CFA_offset:
121ff0cc061SDimitry Andric           addInstruction(Primary, Op1, Data.getULEB128(Offset));
122ff0cc061SDimitry Andric           break;
123ff0cc061SDimitry Andric       }
124ff0cc061SDimitry Andric     } else {
125ff0cc061SDimitry Andric       // Extended opcode - its value is Opcode itself.
126ff0cc061SDimitry Andric       switch (Opcode) {
127ff0cc061SDimitry Andric         default: llvm_unreachable("Invalid extended CFI opcode");
128ff0cc061SDimitry Andric         case DW_CFA_nop:
129ff0cc061SDimitry Andric         case DW_CFA_remember_state:
130ff0cc061SDimitry Andric         case DW_CFA_restore_state:
131ff0cc061SDimitry Andric         case DW_CFA_GNU_window_save:
132ff0cc061SDimitry Andric           // No operands
133ff0cc061SDimitry Andric           addInstruction(Opcode);
134ff0cc061SDimitry Andric           break;
135ff0cc061SDimitry Andric         case DW_CFA_set_loc:
136ff0cc061SDimitry Andric           // Operands: Address
137ff0cc061SDimitry Andric           addInstruction(Opcode, Data.getAddress(Offset));
138ff0cc061SDimitry Andric           break;
139ff0cc061SDimitry Andric         case DW_CFA_advance_loc1:
140ff0cc061SDimitry Andric           // Operands: 1-byte delta
141ff0cc061SDimitry Andric           addInstruction(Opcode, Data.getU8(Offset));
142ff0cc061SDimitry Andric           break;
143ff0cc061SDimitry Andric         case DW_CFA_advance_loc2:
144ff0cc061SDimitry Andric           // Operands: 2-byte delta
145ff0cc061SDimitry Andric           addInstruction(Opcode, Data.getU16(Offset));
146ff0cc061SDimitry Andric           break;
147ff0cc061SDimitry Andric         case DW_CFA_advance_loc4:
148ff0cc061SDimitry Andric           // Operands: 4-byte delta
149ff0cc061SDimitry Andric           addInstruction(Opcode, Data.getU32(Offset));
150ff0cc061SDimitry Andric           break;
151ff0cc061SDimitry Andric         case DW_CFA_restore_extended:
152ff0cc061SDimitry Andric         case DW_CFA_undefined:
153ff0cc061SDimitry Andric         case DW_CFA_same_value:
154ff0cc061SDimitry Andric         case DW_CFA_def_cfa_register:
155ff0cc061SDimitry Andric         case DW_CFA_def_cfa_offset:
156ff0cc061SDimitry Andric           // Operands: ULEB128
157ff0cc061SDimitry Andric           addInstruction(Opcode, Data.getULEB128(Offset));
158ff0cc061SDimitry Andric           break;
159ff0cc061SDimitry Andric         case DW_CFA_def_cfa_offset_sf:
160ff0cc061SDimitry Andric           // Operands: SLEB128
161ff0cc061SDimitry Andric           addInstruction(Opcode, Data.getSLEB128(Offset));
162ff0cc061SDimitry Andric           break;
163ff0cc061SDimitry Andric         case DW_CFA_offset_extended:
164ff0cc061SDimitry Andric         case DW_CFA_register:
165ff0cc061SDimitry Andric         case DW_CFA_def_cfa:
1663ca95b02SDimitry Andric         case DW_CFA_val_offset: {
167ff0cc061SDimitry Andric           // Operands: ULEB128, ULEB128
1683ca95b02SDimitry Andric           // Note: We can not embed getULEB128 directly into function
1693ca95b02SDimitry Andric           // argument list. getULEB128 changes Offset and order of evaluation
1703ca95b02SDimitry Andric           // for arguments is unspecified.
1713ca95b02SDimitry Andric           auto op1 = Data.getULEB128(Offset);
1723ca95b02SDimitry Andric           auto op2 = Data.getULEB128(Offset);
1733ca95b02SDimitry Andric           addInstruction(Opcode, op1, op2);
174ff0cc061SDimitry Andric           break;
1753ca95b02SDimitry Andric         }
176ff0cc061SDimitry Andric         case DW_CFA_offset_extended_sf:
177ff0cc061SDimitry Andric         case DW_CFA_def_cfa_sf:
1783ca95b02SDimitry Andric         case DW_CFA_val_offset_sf: {
179ff0cc061SDimitry Andric           // Operands: ULEB128, SLEB128
1803ca95b02SDimitry Andric           // Note: see comment for the previous case
1813ca95b02SDimitry Andric           auto op1 = Data.getULEB128(Offset);
1823ca95b02SDimitry Andric           auto op2 = (uint64_t)Data.getSLEB128(Offset);
1833ca95b02SDimitry Andric           addInstruction(Opcode, op1, op2);
184ff0cc061SDimitry Andric           break;
1853ca95b02SDimitry Andric         }
186ff0cc061SDimitry Andric         case DW_CFA_def_cfa_expression:
187ff0cc061SDimitry Andric         case DW_CFA_expression:
188ff0cc061SDimitry Andric         case DW_CFA_val_expression:
189ff0cc061SDimitry Andric           // TODO: implement this
190ff0cc061SDimitry Andric           report_fatal_error("Values with expressions not implemented yet!");
191ff0cc061SDimitry Andric       }
192ff0cc061SDimitry Andric     }
193ff0cc061SDimitry Andric   }
194ff0cc061SDimitry Andric }
195ff0cc061SDimitry Andric 
196ff0cc061SDimitry Andric namespace {
197ff0cc061SDimitry Andric /// \brief DWARF Common Information Entry (CIE)
198ff0cc061SDimitry Andric class CIE : public FrameEntry {
199ff0cc061SDimitry Andric public:
200ff0cc061SDimitry Andric   // CIEs (and FDEs) are simply container classes, so the only sensible way to
201ff0cc061SDimitry Andric   // create them is by providing the full parsed contents in the constructor.
202ff0cc061SDimitry Andric   CIE(uint64_t Offset, uint64_t Length, uint8_t Version,
203ff0cc061SDimitry Andric       SmallString<8> Augmentation, uint8_t AddressSize,
204ff0cc061SDimitry Andric       uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor,
2053ca95b02SDimitry Andric       int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,
2063ca95b02SDimitry Andric       SmallString<8> AugmentationData, uint32_t FDEPointerEncoding,
2073ca95b02SDimitry Andric       uint32_t LSDAPointerEncoding)
208ff0cc061SDimitry Andric       : FrameEntry(FK_CIE, Offset, Length), Version(Version),
2093ca95b02SDimitry Andric         Augmentation(std::move(Augmentation)), AddressSize(AddressSize),
210ff0cc061SDimitry Andric         SegmentDescriptorSize(SegmentDescriptorSize),
211ff0cc061SDimitry Andric         CodeAlignmentFactor(CodeAlignmentFactor),
212ff0cc061SDimitry Andric         DataAlignmentFactor(DataAlignmentFactor),
2133ca95b02SDimitry Andric         ReturnAddressRegister(ReturnAddressRegister),
2143ca95b02SDimitry Andric         AugmentationData(std::move(AugmentationData)),
2153ca95b02SDimitry Andric         FDEPointerEncoding(FDEPointerEncoding),
2163ca95b02SDimitry Andric         LSDAPointerEncoding(LSDAPointerEncoding) {}
217ff0cc061SDimitry Andric 
218ff0cc061SDimitry Andric   ~CIE() override {}
219ff0cc061SDimitry Andric 
2203ca95b02SDimitry Andric   StringRef getAugmentationString() const { return Augmentation; }
221ff0cc061SDimitry Andric   uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; }
222ff0cc061SDimitry Andric   int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; }
2233ca95b02SDimitry Andric   uint32_t getFDEPointerEncoding() const {
2243ca95b02SDimitry Andric     return FDEPointerEncoding;
2253ca95b02SDimitry Andric   }
2263ca95b02SDimitry Andric   uint32_t getLSDAPointerEncoding() const {
2273ca95b02SDimitry Andric     return LSDAPointerEncoding;
2283ca95b02SDimitry Andric   }
229ff0cc061SDimitry Andric 
230ff0cc061SDimitry Andric   void dumpHeader(raw_ostream &OS) const override {
231ff0cc061SDimitry Andric     OS << format("%08x %08x %08x CIE",
232ff0cc061SDimitry Andric                  (uint32_t)Offset, (uint32_t)Length, DW_CIE_ID)
233ff0cc061SDimitry Andric        << "\n";
234ff0cc061SDimitry Andric     OS << format("  Version:               %d\n", Version);
235ff0cc061SDimitry Andric     OS << "  Augmentation:          \"" << Augmentation << "\"\n";
236ff0cc061SDimitry Andric     if (Version >= 4) {
237ff0cc061SDimitry Andric       OS << format("  Address size:          %u\n",
238ff0cc061SDimitry Andric                    (uint32_t)AddressSize);
239ff0cc061SDimitry Andric       OS << format("  Segment desc size:     %u\n",
240ff0cc061SDimitry Andric                    (uint32_t)SegmentDescriptorSize);
241ff0cc061SDimitry Andric     }
242ff0cc061SDimitry Andric     OS << format("  Code alignment factor: %u\n",
243ff0cc061SDimitry Andric                  (uint32_t)CodeAlignmentFactor);
244ff0cc061SDimitry Andric     OS << format("  Data alignment factor: %d\n",
245ff0cc061SDimitry Andric                  (int32_t)DataAlignmentFactor);
246ff0cc061SDimitry Andric     OS << format("  Return address column: %d\n",
247ff0cc061SDimitry Andric                  (int32_t)ReturnAddressRegister);
2483ca95b02SDimitry Andric     if (!AugmentationData.empty()) {
2493ca95b02SDimitry Andric       OS << "  Augmentation data:    ";
2503ca95b02SDimitry Andric       for (uint8_t Byte : AugmentationData)
2513ca95b02SDimitry Andric         OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
2523ca95b02SDimitry Andric       OS << "\n";
2533ca95b02SDimitry Andric     }
254ff0cc061SDimitry Andric     OS << "\n";
255ff0cc061SDimitry Andric   }
256ff0cc061SDimitry Andric 
257ff0cc061SDimitry Andric   static bool classof(const FrameEntry *FE) {
258ff0cc061SDimitry Andric     return FE->getKind() == FK_CIE;
259ff0cc061SDimitry Andric   }
260ff0cc061SDimitry Andric 
261ff0cc061SDimitry Andric private:
262ff0cc061SDimitry Andric   /// The following fields are defined in section 6.4.1 of the DWARF standard v4
263ff0cc061SDimitry Andric   uint8_t Version;
264ff0cc061SDimitry Andric   SmallString<8> Augmentation;
265ff0cc061SDimitry Andric   uint8_t AddressSize;
266ff0cc061SDimitry Andric   uint8_t SegmentDescriptorSize;
267ff0cc061SDimitry Andric   uint64_t CodeAlignmentFactor;
268ff0cc061SDimitry Andric   int64_t DataAlignmentFactor;
269ff0cc061SDimitry Andric   uint64_t ReturnAddressRegister;
2703ca95b02SDimitry Andric 
2713ca95b02SDimitry Andric   // The following are used when the CIE represents an EH frame entry.
2723ca95b02SDimitry Andric   SmallString<8> AugmentationData;
2733ca95b02SDimitry Andric   uint32_t FDEPointerEncoding;
2743ca95b02SDimitry Andric   uint32_t LSDAPointerEncoding;
275ff0cc061SDimitry Andric };
276ff0cc061SDimitry Andric 
277ff0cc061SDimitry Andric 
278ff0cc061SDimitry Andric /// \brief DWARF Frame Description Entry (FDE)
279ff0cc061SDimitry Andric class FDE : public FrameEntry {
280ff0cc061SDimitry Andric public:
281ff0cc061SDimitry Andric   // Each FDE has a CIE it's "linked to". Our FDE contains is constructed with
282ff0cc061SDimitry Andric   // an offset to the CIE (provided by parsing the FDE header). The CIE itself
283ff0cc061SDimitry Andric   // is obtained lazily once it's actually required.
284ff0cc061SDimitry Andric   FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,
285ff0cc061SDimitry Andric       uint64_t InitialLocation, uint64_t AddressRange,
286ff0cc061SDimitry Andric       CIE *Cie)
287ff0cc061SDimitry Andric       : FrameEntry(FK_FDE, Offset, Length), LinkedCIEOffset(LinkedCIEOffset),
288ff0cc061SDimitry Andric         InitialLocation(InitialLocation), AddressRange(AddressRange),
289ff0cc061SDimitry Andric         LinkedCIE(Cie) {}
290ff0cc061SDimitry Andric 
291ff0cc061SDimitry Andric   ~FDE() override {}
292ff0cc061SDimitry Andric 
293ff0cc061SDimitry Andric   CIE *getLinkedCIE() const { return LinkedCIE; }
294ff0cc061SDimitry Andric 
295ff0cc061SDimitry Andric   void dumpHeader(raw_ostream &OS) const override {
296ff0cc061SDimitry Andric     OS << format("%08x %08x %08x FDE ",
297ff0cc061SDimitry Andric                  (uint32_t)Offset, (uint32_t)Length, (int32_t)LinkedCIEOffset);
298ff0cc061SDimitry Andric     OS << format("cie=%08x pc=%08x...%08x\n",
299ff0cc061SDimitry Andric                  (int32_t)LinkedCIEOffset,
300ff0cc061SDimitry Andric                  (uint32_t)InitialLocation,
301ff0cc061SDimitry Andric                  (uint32_t)InitialLocation + (uint32_t)AddressRange);
302ff0cc061SDimitry Andric   }
303ff0cc061SDimitry Andric 
304ff0cc061SDimitry Andric   static bool classof(const FrameEntry *FE) {
305ff0cc061SDimitry Andric     return FE->getKind() == FK_FDE;
306ff0cc061SDimitry Andric   }
307ff0cc061SDimitry Andric 
308ff0cc061SDimitry Andric private:
309ff0cc061SDimitry Andric   /// The following fields are defined in section 6.4.1 of the DWARF standard v3
310ff0cc061SDimitry Andric   uint64_t LinkedCIEOffset;
311ff0cc061SDimitry Andric   uint64_t InitialLocation;
312ff0cc061SDimitry Andric   uint64_t AddressRange;
313ff0cc061SDimitry Andric   CIE *LinkedCIE;
314ff0cc061SDimitry Andric };
315ff0cc061SDimitry Andric 
316ff0cc061SDimitry Andric /// \brief Types of operands to CF instructions.
317ff0cc061SDimitry Andric enum OperandType {
318ff0cc061SDimitry Andric   OT_Unset,
319ff0cc061SDimitry Andric   OT_None,
320ff0cc061SDimitry Andric   OT_Address,
321ff0cc061SDimitry Andric   OT_Offset,
322ff0cc061SDimitry Andric   OT_FactoredCodeOffset,
323ff0cc061SDimitry Andric   OT_SignedFactDataOffset,
324ff0cc061SDimitry Andric   OT_UnsignedFactDataOffset,
325ff0cc061SDimitry Andric   OT_Register,
326ff0cc061SDimitry Andric   OT_Expression
327ff0cc061SDimitry Andric };
328ff0cc061SDimitry Andric 
329ff0cc061SDimitry Andric } // end anonymous namespace
330ff0cc061SDimitry Andric 
331ff0cc061SDimitry Andric /// \brief Initialize the array describing the types of operands.
332ff0cc061SDimitry Andric static ArrayRef<OperandType[2]> getOperandTypes() {
333ff0cc061SDimitry Andric   static OperandType OpTypes[DW_CFA_restore+1][2];
334ff0cc061SDimitry Andric 
335ff0cc061SDimitry Andric #define DECLARE_OP2(OP, OPTYPE0, OPTYPE1)       \
336ff0cc061SDimitry Andric   do {                                          \
337ff0cc061SDimitry Andric     OpTypes[OP][0] = OPTYPE0;                   \
338ff0cc061SDimitry Andric     OpTypes[OP][1] = OPTYPE1;                   \
339ff0cc061SDimitry Andric   } while (0)
340ff0cc061SDimitry Andric #define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
341ff0cc061SDimitry Andric #define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
342ff0cc061SDimitry Andric 
343ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_set_loc, OT_Address);
344ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
345ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
346ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
347ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
348ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
349ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
350ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);
351ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register);
352ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset);
353ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
354ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
355ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_undefined, OT_Register);
356ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_same_value, OT_Register);
357ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);
358ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
359ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
360ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);
361ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
362ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
363ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
364ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
365ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_restore, OT_Register);
366ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_restore_extended, OT_Register);
367ff0cc061SDimitry Andric   DECLARE_OP0(DW_CFA_remember_state);
368ff0cc061SDimitry Andric   DECLARE_OP0(DW_CFA_restore_state);
369ff0cc061SDimitry Andric   DECLARE_OP0(DW_CFA_GNU_window_save);
370ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);
371ff0cc061SDimitry Andric   DECLARE_OP0(DW_CFA_nop);
372ff0cc061SDimitry Andric 
373ff0cc061SDimitry Andric #undef DECLARE_OP0
374ff0cc061SDimitry Andric #undef DECLARE_OP1
375ff0cc061SDimitry Andric #undef DECLARE_OP2
376ff0cc061SDimitry Andric   return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);
377ff0cc061SDimitry Andric }
378ff0cc061SDimitry Andric 
379ff0cc061SDimitry Andric static ArrayRef<OperandType[2]> OpTypes = getOperandTypes();
380ff0cc061SDimitry Andric 
381ff0cc061SDimitry Andric /// \brief Print \p Opcode's operand number \p OperandIdx which has
382ff0cc061SDimitry Andric /// value \p Operand.
383ff0cc061SDimitry Andric static void printOperand(raw_ostream &OS, uint8_t Opcode, unsigned OperandIdx,
384ff0cc061SDimitry Andric                          uint64_t Operand, uint64_t CodeAlignmentFactor,
385ff0cc061SDimitry Andric                          int64_t DataAlignmentFactor) {
386ff0cc061SDimitry Andric   assert(OperandIdx < 2);
387ff0cc061SDimitry Andric   OperandType Type = OpTypes[Opcode][OperandIdx];
388ff0cc061SDimitry Andric 
389ff0cc061SDimitry Andric   switch (Type) {
390ff0cc061SDimitry Andric   case OT_Unset:
391ff0cc061SDimitry Andric     OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";
392ff0cc061SDimitry Andric     if (const char *OpcodeName = CallFrameString(Opcode))
393ff0cc061SDimitry Andric       OS << " " << OpcodeName;
394ff0cc061SDimitry Andric     else
395ff0cc061SDimitry Andric       OS << format(" Opcode %x",  Opcode);
396ff0cc061SDimitry Andric     break;
397ff0cc061SDimitry Andric   case OT_None:
398ff0cc061SDimitry Andric     break;
399ff0cc061SDimitry Andric   case OT_Address:
400ff0cc061SDimitry Andric     OS << format(" %" PRIx64, Operand);
401ff0cc061SDimitry Andric     break;
402ff0cc061SDimitry Andric   case OT_Offset:
403ff0cc061SDimitry Andric     // The offsets are all encoded in a unsigned form, but in practice
404ff0cc061SDimitry Andric     // consumers use them signed. It's most certainly legacy due to
405ff0cc061SDimitry Andric     // the lack of signed variants in the first Dwarf standards.
406ff0cc061SDimitry Andric     OS << format(" %+" PRId64, int64_t(Operand));
407ff0cc061SDimitry Andric     break;
408ff0cc061SDimitry Andric   case OT_FactoredCodeOffset: // Always Unsigned
409ff0cc061SDimitry Andric     if (CodeAlignmentFactor)
410ff0cc061SDimitry Andric       OS << format(" %" PRId64, Operand * CodeAlignmentFactor);
411ff0cc061SDimitry Andric     else
412ff0cc061SDimitry Andric       OS << format(" %" PRId64 "*code_alignment_factor" , Operand);
413ff0cc061SDimitry Andric     break;
414ff0cc061SDimitry Andric   case OT_SignedFactDataOffset:
415ff0cc061SDimitry Andric     if (DataAlignmentFactor)
416ff0cc061SDimitry Andric       OS << format(" %" PRId64, int64_t(Operand) * DataAlignmentFactor);
417ff0cc061SDimitry Andric     else
418ff0cc061SDimitry Andric       OS << format(" %" PRId64 "*data_alignment_factor" , int64_t(Operand));
419ff0cc061SDimitry Andric     break;
420ff0cc061SDimitry Andric   case OT_UnsignedFactDataOffset:
421ff0cc061SDimitry Andric     if (DataAlignmentFactor)
422ff0cc061SDimitry Andric       OS << format(" %" PRId64, Operand * DataAlignmentFactor);
423ff0cc061SDimitry Andric     else
424ff0cc061SDimitry Andric       OS << format(" %" PRId64 "*data_alignment_factor" , Operand);
425ff0cc061SDimitry Andric     break;
426ff0cc061SDimitry Andric   case OT_Register:
427ff0cc061SDimitry Andric     OS << format(" reg%" PRId64, Operand);
428ff0cc061SDimitry Andric     break;
429ff0cc061SDimitry Andric   case OT_Expression:
430ff0cc061SDimitry Andric     OS << " expression";
431ff0cc061SDimitry Andric     break;
432ff0cc061SDimitry Andric   }
433ff0cc061SDimitry Andric }
434ff0cc061SDimitry Andric 
435ff0cc061SDimitry Andric void FrameEntry::dumpInstructions(raw_ostream &OS) const {
436ff0cc061SDimitry Andric   uint64_t CodeAlignmentFactor = 0;
437ff0cc061SDimitry Andric   int64_t DataAlignmentFactor = 0;
438ff0cc061SDimitry Andric   const CIE *Cie = dyn_cast<CIE>(this);
439ff0cc061SDimitry Andric 
440ff0cc061SDimitry Andric   if (!Cie)
441ff0cc061SDimitry Andric     Cie = cast<FDE>(this)->getLinkedCIE();
442ff0cc061SDimitry Andric   if (Cie) {
443ff0cc061SDimitry Andric     CodeAlignmentFactor = Cie->getCodeAlignmentFactor();
444ff0cc061SDimitry Andric     DataAlignmentFactor = Cie->getDataAlignmentFactor();
445ff0cc061SDimitry Andric   }
446ff0cc061SDimitry Andric 
447ff0cc061SDimitry Andric   for (const auto &Instr : Instructions) {
448ff0cc061SDimitry Andric     uint8_t Opcode = Instr.Opcode;
449ff0cc061SDimitry Andric     if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
450ff0cc061SDimitry Andric       Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
451ff0cc061SDimitry Andric     OS << "  " << CallFrameString(Opcode) << ":";
452ff0cc061SDimitry Andric     for (unsigned i = 0; i < Instr.Ops.size(); ++i)
453ff0cc061SDimitry Andric       printOperand(OS, Opcode, i, Instr.Ops[i], CodeAlignmentFactor,
454ff0cc061SDimitry Andric                    DataAlignmentFactor);
455ff0cc061SDimitry Andric     OS << '\n';
456ff0cc061SDimitry Andric   }
457ff0cc061SDimitry Andric }
458ff0cc061SDimitry Andric 
4593ca95b02SDimitry Andric DWARFDebugFrame::DWARFDebugFrame(bool IsEH) : IsEH(IsEH) {
460ff0cc061SDimitry Andric }
461ff0cc061SDimitry Andric 
462ff0cc061SDimitry Andric DWARFDebugFrame::~DWARFDebugFrame() {
463ff0cc061SDimitry Andric }
464ff0cc061SDimitry Andric 
465ff0cc061SDimitry Andric static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
466ff0cc061SDimitry Andric                                               uint32_t Offset, int Length) {
467ff0cc061SDimitry Andric   errs() << "DUMP: ";
468ff0cc061SDimitry Andric   for (int i = 0; i < Length; ++i) {
469ff0cc061SDimitry Andric     uint8_t c = Data.getU8(&Offset);
470ff0cc061SDimitry Andric     errs().write_hex(c); errs() << " ";
471ff0cc061SDimitry Andric   }
472ff0cc061SDimitry Andric   errs() << "\n";
473ff0cc061SDimitry Andric }
474ff0cc061SDimitry Andric 
4753ca95b02SDimitry Andric static unsigned getSizeForEncoding(const DataExtractor &Data,
4763ca95b02SDimitry Andric                                    unsigned symbolEncoding) {
4773ca95b02SDimitry Andric   unsigned format = symbolEncoding & 0x0f;
4783ca95b02SDimitry Andric   switch (format) {
4793ca95b02SDimitry Andric     default: llvm_unreachable("Unknown Encoding");
4803ca95b02SDimitry Andric     case dwarf::DW_EH_PE_absptr:
4813ca95b02SDimitry Andric     case dwarf::DW_EH_PE_signed:
4823ca95b02SDimitry Andric       return Data.getAddressSize();
4833ca95b02SDimitry Andric     case dwarf::DW_EH_PE_udata2:
4843ca95b02SDimitry Andric     case dwarf::DW_EH_PE_sdata2:
4853ca95b02SDimitry Andric       return 2;
4863ca95b02SDimitry Andric     case dwarf::DW_EH_PE_udata4:
4873ca95b02SDimitry Andric     case dwarf::DW_EH_PE_sdata4:
4883ca95b02SDimitry Andric       return 4;
4893ca95b02SDimitry Andric     case dwarf::DW_EH_PE_udata8:
4903ca95b02SDimitry Andric     case dwarf::DW_EH_PE_sdata8:
4913ca95b02SDimitry Andric       return 8;
4923ca95b02SDimitry Andric   }
4933ca95b02SDimitry Andric }
4943ca95b02SDimitry Andric 
4953ca95b02SDimitry Andric static uint64_t readPointer(const DataExtractor &Data, uint32_t &Offset,
4963ca95b02SDimitry Andric                             unsigned Encoding) {
4973ca95b02SDimitry Andric   switch (getSizeForEncoding(Data, Encoding)) {
4983ca95b02SDimitry Andric     case 2:
4993ca95b02SDimitry Andric       return Data.getU16(&Offset);
5003ca95b02SDimitry Andric     case 4:
5013ca95b02SDimitry Andric       return Data.getU32(&Offset);
5023ca95b02SDimitry Andric     case 8:
5033ca95b02SDimitry Andric       return Data.getU64(&Offset);
5043ca95b02SDimitry Andric     default:
5053ca95b02SDimitry Andric       llvm_unreachable("Illegal data size");
5063ca95b02SDimitry Andric   }
5073ca95b02SDimitry Andric }
508ff0cc061SDimitry Andric 
509ff0cc061SDimitry Andric void DWARFDebugFrame::parse(DataExtractor Data) {
510ff0cc061SDimitry Andric   uint32_t Offset = 0;
511ff0cc061SDimitry Andric   DenseMap<uint32_t, CIE *> CIEs;
512ff0cc061SDimitry Andric 
513ff0cc061SDimitry Andric   while (Data.isValidOffset(Offset)) {
514ff0cc061SDimitry Andric     uint32_t StartOffset = Offset;
515ff0cc061SDimitry Andric 
5163ca95b02SDimitry Andric     auto ReportError = [StartOffset](const char *ErrorMsg) {
5173ca95b02SDimitry Andric       std::string Str;
5183ca95b02SDimitry Andric       raw_string_ostream OS(Str);
5193ca95b02SDimitry Andric       OS << format(ErrorMsg, StartOffset);
5203ca95b02SDimitry Andric       OS.flush();
5213ca95b02SDimitry Andric       report_fatal_error(Str);
5223ca95b02SDimitry Andric     };
5233ca95b02SDimitry Andric 
524ff0cc061SDimitry Andric     bool IsDWARF64 = false;
525ff0cc061SDimitry Andric     uint64_t Length = Data.getU32(&Offset);
526ff0cc061SDimitry Andric     uint64_t Id;
527ff0cc061SDimitry Andric 
528ff0cc061SDimitry Andric     if (Length == UINT32_MAX) {
529ff0cc061SDimitry Andric       // DWARF-64 is distinguished by the first 32 bits of the initial length
530ff0cc061SDimitry Andric       // field being 0xffffffff. Then, the next 64 bits are the actual entry
531ff0cc061SDimitry Andric       // length.
532ff0cc061SDimitry Andric       IsDWARF64 = true;
533ff0cc061SDimitry Andric       Length = Data.getU64(&Offset);
534ff0cc061SDimitry Andric     }
535ff0cc061SDimitry Andric 
536ff0cc061SDimitry Andric     // At this point, Offset points to the next field after Length.
537ff0cc061SDimitry Andric     // Length is the structure size excluding itself. Compute an offset one
538ff0cc061SDimitry Andric     // past the end of the structure (needed to know how many instructions to
539ff0cc061SDimitry Andric     // read).
540ff0cc061SDimitry Andric     // TODO: For honest DWARF64 support, DataExtractor will have to treat
541ff0cc061SDimitry Andric     //       offset_ptr as uint64_t*
5423ca95b02SDimitry Andric     uint32_t StartStructureOffset = Offset;
543ff0cc061SDimitry Andric     uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length);
544ff0cc061SDimitry Andric 
545ff0cc061SDimitry Andric     // The Id field's size depends on the DWARF format
5463ca95b02SDimitry Andric     Id = Data.getUnsigned(&Offset, (IsDWARF64 && !IsEH) ? 8 : 4);
5473ca95b02SDimitry Andric     bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) ||
5483ca95b02SDimitry Andric                   Id == DW_CIE_ID ||
5493ca95b02SDimitry Andric                   (IsEH && !Id));
550ff0cc061SDimitry Andric 
551ff0cc061SDimitry Andric     if (IsCIE) {
552ff0cc061SDimitry Andric       uint8_t Version = Data.getU8(&Offset);
553ff0cc061SDimitry Andric       const char *Augmentation = Data.getCStr(&Offset);
5543ca95b02SDimitry Andric       StringRef AugmentationString(Augmentation ? Augmentation : "");
5553ca95b02SDimitry Andric       uint8_t AddressSize = Version < 4 ? Data.getAddressSize() :
5563ca95b02SDimitry Andric                                           Data.getU8(&Offset);
557ff0cc061SDimitry Andric       Data.setAddressSize(AddressSize);
558ff0cc061SDimitry Andric       uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset);
559ff0cc061SDimitry Andric       uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
560ff0cc061SDimitry Andric       int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
561ff0cc061SDimitry Andric       uint64_t ReturnAddressRegister = Data.getULEB128(&Offset);
562ff0cc061SDimitry Andric 
5633ca95b02SDimitry Andric       // Parse the augmentation data for EH CIEs
5643ca95b02SDimitry Andric       StringRef AugmentationData("");
5653ca95b02SDimitry Andric       uint32_t FDEPointerEncoding = DW_EH_PE_omit;
5663ca95b02SDimitry Andric       uint32_t LSDAPointerEncoding = DW_EH_PE_omit;
5673ca95b02SDimitry Andric       if (IsEH) {
5683ca95b02SDimitry Andric         Optional<uint32_t> PersonalityEncoding;
5693ca95b02SDimitry Andric         Optional<uint64_t> Personality;
5703ca95b02SDimitry Andric 
5713ca95b02SDimitry Andric         Optional<uint64_t> AugmentationLength;
5723ca95b02SDimitry Andric         uint32_t StartAugmentationOffset;
5733ca95b02SDimitry Andric         uint32_t EndAugmentationOffset;
5743ca95b02SDimitry Andric 
5753ca95b02SDimitry Andric         // Walk the augmentation string to get all the augmentation data.
5763ca95b02SDimitry Andric         for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) {
5773ca95b02SDimitry Andric           switch (AugmentationString[i]) {
5783ca95b02SDimitry Andric             default:
5793ca95b02SDimitry Andric               ReportError("Unknown augmentation character in entry at %lx");
5803ca95b02SDimitry Andric             case 'L':
5813ca95b02SDimitry Andric               LSDAPointerEncoding = Data.getU8(&Offset);
5823ca95b02SDimitry Andric               break;
5833ca95b02SDimitry Andric             case 'P': {
5843ca95b02SDimitry Andric               if (Personality)
5853ca95b02SDimitry Andric                 ReportError("Duplicate personality in entry at %lx");
5863ca95b02SDimitry Andric               PersonalityEncoding = Data.getU8(&Offset);
5873ca95b02SDimitry Andric               Personality = readPointer(Data, Offset, *PersonalityEncoding);
5883ca95b02SDimitry Andric               break;
5893ca95b02SDimitry Andric             }
5903ca95b02SDimitry Andric             case 'R':
5913ca95b02SDimitry Andric               FDEPointerEncoding = Data.getU8(&Offset);
5923ca95b02SDimitry Andric               break;
5933ca95b02SDimitry Andric             case 'z':
5943ca95b02SDimitry Andric               if (i)
5953ca95b02SDimitry Andric                 ReportError("'z' must be the first character at %lx");
5963ca95b02SDimitry Andric               // Parse the augmentation length first.  We only parse it if
5973ca95b02SDimitry Andric               // the string contains a 'z'.
5983ca95b02SDimitry Andric               AugmentationLength = Data.getULEB128(&Offset);
5993ca95b02SDimitry Andric               StartAugmentationOffset = Offset;
6003ca95b02SDimitry Andric               EndAugmentationOffset = Offset +
6013ca95b02SDimitry Andric                 static_cast<uint32_t>(*AugmentationLength);
6023ca95b02SDimitry Andric           }
6033ca95b02SDimitry Andric         }
6043ca95b02SDimitry Andric 
6053ca95b02SDimitry Andric         if (AugmentationLength.hasValue()) {
6063ca95b02SDimitry Andric           if (Offset != EndAugmentationOffset)
6073ca95b02SDimitry Andric             ReportError("Parsing augmentation data at %lx failed");
6083ca95b02SDimitry Andric 
6093ca95b02SDimitry Andric           AugmentationData = Data.getData().slice(StartAugmentationOffset,
6103ca95b02SDimitry Andric                                                   EndAugmentationOffset);
6113ca95b02SDimitry Andric         }
6123ca95b02SDimitry Andric       }
6133ca95b02SDimitry Andric 
614ff0cc061SDimitry Andric       auto Cie = make_unique<CIE>(StartOffset, Length, Version,
6153ca95b02SDimitry Andric                                   AugmentationString, AddressSize,
616ff0cc061SDimitry Andric                                   SegmentDescriptorSize, CodeAlignmentFactor,
6173ca95b02SDimitry Andric                                   DataAlignmentFactor, ReturnAddressRegister,
6183ca95b02SDimitry Andric                                   AugmentationData, FDEPointerEncoding,
6193ca95b02SDimitry Andric                                   LSDAPointerEncoding);
620ff0cc061SDimitry Andric       CIEs[StartOffset] = Cie.get();
621ff0cc061SDimitry Andric       Entries.emplace_back(std::move(Cie));
622ff0cc061SDimitry Andric     } else {
623ff0cc061SDimitry Andric       // FDE
624ff0cc061SDimitry Andric       uint64_t CIEPointer = Id;
6253ca95b02SDimitry Andric       uint64_t InitialLocation = 0;
6263ca95b02SDimitry Andric       uint64_t AddressRange = 0;
6273ca95b02SDimitry Andric       CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
6283ca95b02SDimitry Andric 
6293ca95b02SDimitry Andric       if (IsEH) {
6303ca95b02SDimitry Andric         // The address size is encoded in the CIE we reference.
6313ca95b02SDimitry Andric         if (!Cie)
6323ca95b02SDimitry Andric           ReportError("Parsing FDE data at %lx failed due to missing CIE");
6333ca95b02SDimitry Andric 
6343ca95b02SDimitry Andric         InitialLocation = readPointer(Data, Offset,
6353ca95b02SDimitry Andric                                       Cie->getFDEPointerEncoding());
6363ca95b02SDimitry Andric         AddressRange = readPointer(Data, Offset,
6373ca95b02SDimitry Andric                                    Cie->getFDEPointerEncoding());
6383ca95b02SDimitry Andric 
6393ca95b02SDimitry Andric         StringRef AugmentationString = Cie->getAugmentationString();
6403ca95b02SDimitry Andric         if (!AugmentationString.empty()) {
6413ca95b02SDimitry Andric           // Parse the augmentation length and data for this FDE.
6423ca95b02SDimitry Andric           uint64_t AugmentationLength = Data.getULEB128(&Offset);
6433ca95b02SDimitry Andric 
6443ca95b02SDimitry Andric           uint32_t EndAugmentationOffset =
6453ca95b02SDimitry Andric             Offset + static_cast<uint32_t>(AugmentationLength);
6463ca95b02SDimitry Andric 
6473ca95b02SDimitry Andric           // Decode the LSDA if the CIE augmentation string said we should.
6483ca95b02SDimitry Andric           if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit)
6493ca95b02SDimitry Andric             readPointer(Data, Offset, Cie->getLSDAPointerEncoding());
6503ca95b02SDimitry Andric 
6513ca95b02SDimitry Andric           if (Offset != EndAugmentationOffset)
6523ca95b02SDimitry Andric             ReportError("Parsing augmentation data at %lx failed");
6533ca95b02SDimitry Andric         }
6543ca95b02SDimitry Andric       } else {
6553ca95b02SDimitry Andric         InitialLocation = Data.getAddress(&Offset);
6563ca95b02SDimitry Andric         AddressRange = Data.getAddress(&Offset);
6573ca95b02SDimitry Andric       }
658ff0cc061SDimitry Andric 
659ff0cc061SDimitry Andric       Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
660ff0cc061SDimitry Andric                                    InitialLocation, AddressRange,
6613ca95b02SDimitry Andric                                    Cie));
662ff0cc061SDimitry Andric     }
663ff0cc061SDimitry Andric 
664ff0cc061SDimitry Andric     Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset);
665ff0cc061SDimitry Andric 
6663ca95b02SDimitry Andric     if (Offset != EndStructureOffset)
6673ca95b02SDimitry Andric       ReportError("Parsing entry instructions at %lx failed");
668ff0cc061SDimitry Andric   }
669ff0cc061SDimitry Andric }
670ff0cc061SDimitry Andric 
671ff0cc061SDimitry Andric 
672ff0cc061SDimitry Andric void DWARFDebugFrame::dump(raw_ostream &OS) const {
673ff0cc061SDimitry Andric   OS << "\n";
674ff0cc061SDimitry Andric   for (const auto &Entry : Entries) {
675ff0cc061SDimitry Andric     Entry->dumpHeader(OS);
676ff0cc061SDimitry Andric     Entry->dumpInstructions(OS);
677ff0cc061SDimitry Andric     OS << "\n";
678ff0cc061SDimitry Andric   }
679ff0cc061SDimitry Andric }
680ff0cc061SDimitry Andric 
681