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"
13ff0cc061SDimitry Andric #include "llvm/ADT/SmallString.h"
14ff0cc061SDimitry Andric #include "llvm/Support/Casting.h"
15ff0cc061SDimitry Andric #include "llvm/Support/DataTypes.h"
16ff0cc061SDimitry Andric #include "llvm/Support/Dwarf.h"
17ff0cc061SDimitry Andric #include "llvm/Support/ErrorHandling.h"
18ff0cc061SDimitry Andric #include "llvm/Support/Format.h"
19ff0cc061SDimitry Andric #include "llvm/Support/raw_ostream.h"
20ff0cc061SDimitry Andric #include <string>
21ff0cc061SDimitry Andric #include <vector>
22ff0cc061SDimitry Andric 
23ff0cc061SDimitry Andric using namespace llvm;
24ff0cc061SDimitry Andric using namespace dwarf;
25ff0cc061SDimitry Andric 
26ff0cc061SDimitry Andric 
27ff0cc061SDimitry Andric /// \brief Abstract frame entry defining the common interface concrete
28ff0cc061SDimitry Andric /// entries implement.
29ff0cc061SDimitry Andric class llvm::FrameEntry {
30ff0cc061SDimitry Andric public:
31ff0cc061SDimitry Andric   enum FrameKind {FK_CIE, FK_FDE};
32ff0cc061SDimitry Andric   FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length)
33ff0cc061SDimitry Andric       : Kind(K), Offset(Offset), Length(Length) {}
34ff0cc061SDimitry Andric 
35ff0cc061SDimitry Andric   virtual ~FrameEntry() {
36ff0cc061SDimitry Andric   }
37ff0cc061SDimitry Andric 
38ff0cc061SDimitry Andric   FrameKind getKind() const { return Kind; }
39ff0cc061SDimitry Andric   virtual uint64_t getOffset() const { return Offset; }
40ff0cc061SDimitry Andric 
41ff0cc061SDimitry Andric   /// \brief Parse and store a sequence of CFI instructions from Data,
42ff0cc061SDimitry Andric   /// starting at *Offset and ending at EndOffset. If everything
43ff0cc061SDimitry Andric   /// goes well, *Offset should be equal to EndOffset when this method
44ff0cc061SDimitry Andric   /// returns. Otherwise, an error occurred.
45ff0cc061SDimitry Andric   virtual void parseInstructions(DataExtractor Data, uint32_t *Offset,
46ff0cc061SDimitry Andric                                  uint32_t EndOffset);
47ff0cc061SDimitry Andric 
48ff0cc061SDimitry Andric   /// \brief Dump the entry header to the given output stream.
49ff0cc061SDimitry Andric   virtual void dumpHeader(raw_ostream &OS) const = 0;
50ff0cc061SDimitry Andric 
51ff0cc061SDimitry Andric   /// \brief Dump the entry's instructions to the given output stream.
52ff0cc061SDimitry Andric   virtual void dumpInstructions(raw_ostream &OS) const;
53ff0cc061SDimitry Andric 
54ff0cc061SDimitry Andric protected:
55ff0cc061SDimitry Andric   const FrameKind Kind;
56ff0cc061SDimitry Andric 
57ff0cc061SDimitry Andric   /// \brief Offset of this entry in the section.
58ff0cc061SDimitry Andric   uint64_t Offset;
59ff0cc061SDimitry Andric 
60ff0cc061SDimitry Andric   /// \brief Entry length as specified in DWARF.
61ff0cc061SDimitry Andric   uint64_t Length;
62ff0cc061SDimitry Andric 
63ff0cc061SDimitry Andric   /// An entry may contain CFI instructions. An instruction consists of an
64ff0cc061SDimitry Andric   /// opcode and an optional sequence of operands.
65ff0cc061SDimitry Andric   typedef std::vector<uint64_t> Operands;
66ff0cc061SDimitry Andric   struct Instruction {
67ff0cc061SDimitry Andric     Instruction(uint8_t Opcode)
68ff0cc061SDimitry Andric       : Opcode(Opcode)
69ff0cc061SDimitry Andric     {}
70ff0cc061SDimitry Andric 
71ff0cc061SDimitry Andric     uint8_t Opcode;
72ff0cc061SDimitry Andric     Operands Ops;
73ff0cc061SDimitry Andric   };
74ff0cc061SDimitry Andric 
75ff0cc061SDimitry Andric   std::vector<Instruction> Instructions;
76ff0cc061SDimitry Andric 
77ff0cc061SDimitry Andric   /// Convenience methods to add a new instruction with the given opcode and
78ff0cc061SDimitry Andric   /// operands to the Instructions vector.
79ff0cc061SDimitry Andric   void addInstruction(uint8_t Opcode) {
80ff0cc061SDimitry Andric     Instructions.push_back(Instruction(Opcode));
81ff0cc061SDimitry Andric   }
82ff0cc061SDimitry Andric 
83ff0cc061SDimitry Andric   void addInstruction(uint8_t Opcode, uint64_t Operand1) {
84ff0cc061SDimitry Andric     Instructions.push_back(Instruction(Opcode));
85ff0cc061SDimitry Andric     Instructions.back().Ops.push_back(Operand1);
86ff0cc061SDimitry Andric   }
87ff0cc061SDimitry Andric 
88ff0cc061SDimitry Andric   void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2) {
89ff0cc061SDimitry Andric     Instructions.push_back(Instruction(Opcode));
90ff0cc061SDimitry Andric     Instructions.back().Ops.push_back(Operand1);
91ff0cc061SDimitry Andric     Instructions.back().Ops.push_back(Operand2);
92ff0cc061SDimitry Andric   }
93ff0cc061SDimitry Andric };
94ff0cc061SDimitry Andric 
95ff0cc061SDimitry Andric 
96ff0cc061SDimitry Andric // See DWARF standard v3, section 7.23
97ff0cc061SDimitry Andric const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
98ff0cc061SDimitry Andric const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
99ff0cc061SDimitry Andric 
100ff0cc061SDimitry Andric void FrameEntry::parseInstructions(DataExtractor Data, uint32_t *Offset,
101ff0cc061SDimitry Andric                                    uint32_t EndOffset) {
102ff0cc061SDimitry Andric   while (*Offset < EndOffset) {
103ff0cc061SDimitry Andric     uint8_t Opcode = Data.getU8(Offset);
104ff0cc061SDimitry Andric     // Some instructions have a primary opcode encoded in the top bits.
105ff0cc061SDimitry Andric     uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK;
106ff0cc061SDimitry Andric 
107ff0cc061SDimitry Andric     if (Primary) {
108ff0cc061SDimitry Andric       // If it's a primary opcode, the first operand is encoded in the bottom
109ff0cc061SDimitry Andric       // bits of the opcode itself.
110ff0cc061SDimitry Andric       uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;
111ff0cc061SDimitry Andric       switch (Primary) {
112ff0cc061SDimitry Andric         default: llvm_unreachable("Impossible primary CFI opcode");
113ff0cc061SDimitry Andric         case DW_CFA_advance_loc:
114ff0cc061SDimitry Andric         case DW_CFA_restore:
115ff0cc061SDimitry Andric           addInstruction(Primary, Op1);
116ff0cc061SDimitry Andric           break;
117ff0cc061SDimitry Andric         case DW_CFA_offset:
118ff0cc061SDimitry Andric           addInstruction(Primary, Op1, Data.getULEB128(Offset));
119ff0cc061SDimitry Andric           break;
120ff0cc061SDimitry Andric       }
121ff0cc061SDimitry Andric     } else {
122ff0cc061SDimitry Andric       // Extended opcode - its value is Opcode itself.
123ff0cc061SDimitry Andric       switch (Opcode) {
124ff0cc061SDimitry Andric         default: llvm_unreachable("Invalid extended CFI opcode");
125ff0cc061SDimitry Andric         case DW_CFA_nop:
126ff0cc061SDimitry Andric         case DW_CFA_remember_state:
127ff0cc061SDimitry Andric         case DW_CFA_restore_state:
128ff0cc061SDimitry Andric         case DW_CFA_GNU_window_save:
129ff0cc061SDimitry Andric           // No operands
130ff0cc061SDimitry Andric           addInstruction(Opcode);
131ff0cc061SDimitry Andric           break;
132ff0cc061SDimitry Andric         case DW_CFA_set_loc:
133ff0cc061SDimitry Andric           // Operands: Address
134ff0cc061SDimitry Andric           addInstruction(Opcode, Data.getAddress(Offset));
135ff0cc061SDimitry Andric           break;
136ff0cc061SDimitry Andric         case DW_CFA_advance_loc1:
137ff0cc061SDimitry Andric           // Operands: 1-byte delta
138ff0cc061SDimitry Andric           addInstruction(Opcode, Data.getU8(Offset));
139ff0cc061SDimitry Andric           break;
140ff0cc061SDimitry Andric         case DW_CFA_advance_loc2:
141ff0cc061SDimitry Andric           // Operands: 2-byte delta
142ff0cc061SDimitry Andric           addInstruction(Opcode, Data.getU16(Offset));
143ff0cc061SDimitry Andric           break;
144ff0cc061SDimitry Andric         case DW_CFA_advance_loc4:
145ff0cc061SDimitry Andric           // Operands: 4-byte delta
146ff0cc061SDimitry Andric           addInstruction(Opcode, Data.getU32(Offset));
147ff0cc061SDimitry Andric           break;
148ff0cc061SDimitry Andric         case DW_CFA_restore_extended:
149ff0cc061SDimitry Andric         case DW_CFA_undefined:
150ff0cc061SDimitry Andric         case DW_CFA_same_value:
151ff0cc061SDimitry Andric         case DW_CFA_def_cfa_register:
152ff0cc061SDimitry Andric         case DW_CFA_def_cfa_offset:
153ff0cc061SDimitry Andric           // Operands: ULEB128
154ff0cc061SDimitry Andric           addInstruction(Opcode, Data.getULEB128(Offset));
155ff0cc061SDimitry Andric           break;
156ff0cc061SDimitry Andric         case DW_CFA_def_cfa_offset_sf:
157ff0cc061SDimitry Andric           // Operands: SLEB128
158ff0cc061SDimitry Andric           addInstruction(Opcode, Data.getSLEB128(Offset));
159ff0cc061SDimitry Andric           break;
160ff0cc061SDimitry Andric         case DW_CFA_offset_extended:
161ff0cc061SDimitry Andric         case DW_CFA_register:
162ff0cc061SDimitry Andric         case DW_CFA_def_cfa:
163ff0cc061SDimitry Andric         case DW_CFA_val_offset:
164ff0cc061SDimitry Andric           // Operands: ULEB128, ULEB128
165ff0cc061SDimitry Andric           addInstruction(Opcode, Data.getULEB128(Offset),
166ff0cc061SDimitry Andric                                  Data.getULEB128(Offset));
167ff0cc061SDimitry Andric           break;
168ff0cc061SDimitry Andric         case DW_CFA_offset_extended_sf:
169ff0cc061SDimitry Andric         case DW_CFA_def_cfa_sf:
170ff0cc061SDimitry Andric         case DW_CFA_val_offset_sf:
171ff0cc061SDimitry Andric           // Operands: ULEB128, SLEB128
172ff0cc061SDimitry Andric           addInstruction(Opcode, Data.getULEB128(Offset),
173ff0cc061SDimitry Andric                                  Data.getSLEB128(Offset));
174ff0cc061SDimitry Andric           break;
175ff0cc061SDimitry Andric         case DW_CFA_def_cfa_expression:
176ff0cc061SDimitry Andric         case DW_CFA_expression:
177ff0cc061SDimitry Andric         case DW_CFA_val_expression:
178ff0cc061SDimitry Andric           // TODO: implement this
179ff0cc061SDimitry Andric           report_fatal_error("Values with expressions not implemented yet!");
180ff0cc061SDimitry Andric       }
181ff0cc061SDimitry Andric     }
182ff0cc061SDimitry Andric   }
183ff0cc061SDimitry Andric }
184ff0cc061SDimitry Andric 
185ff0cc061SDimitry Andric namespace {
186ff0cc061SDimitry Andric /// \brief DWARF Common Information Entry (CIE)
187ff0cc061SDimitry Andric class CIE : public FrameEntry {
188ff0cc061SDimitry Andric public:
189ff0cc061SDimitry Andric   // CIEs (and FDEs) are simply container classes, so the only sensible way to
190ff0cc061SDimitry Andric   // create them is by providing the full parsed contents in the constructor.
191ff0cc061SDimitry Andric   CIE(uint64_t Offset, uint64_t Length, uint8_t Version,
192ff0cc061SDimitry Andric       SmallString<8> Augmentation, uint8_t AddressSize,
193ff0cc061SDimitry Andric       uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor,
194ff0cc061SDimitry Andric       int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister)
195ff0cc061SDimitry Andric       : FrameEntry(FK_CIE, Offset, Length), Version(Version),
196ff0cc061SDimitry Andric         Augmentation(std::move(Augmentation)),
197ff0cc061SDimitry Andric         AddressSize(AddressSize),
198ff0cc061SDimitry Andric         SegmentDescriptorSize(SegmentDescriptorSize),
199ff0cc061SDimitry Andric         CodeAlignmentFactor(CodeAlignmentFactor),
200ff0cc061SDimitry Andric         DataAlignmentFactor(DataAlignmentFactor),
201ff0cc061SDimitry Andric         ReturnAddressRegister(ReturnAddressRegister) {}
202ff0cc061SDimitry Andric 
203ff0cc061SDimitry Andric   ~CIE() override {}
204ff0cc061SDimitry Andric 
205ff0cc061SDimitry Andric   uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; }
206ff0cc061SDimitry Andric   int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; }
207ff0cc061SDimitry Andric 
208ff0cc061SDimitry Andric   void dumpHeader(raw_ostream &OS) const override {
209ff0cc061SDimitry Andric     OS << format("%08x %08x %08x CIE",
210ff0cc061SDimitry Andric                  (uint32_t)Offset, (uint32_t)Length, DW_CIE_ID)
211ff0cc061SDimitry Andric        << "\n";
212ff0cc061SDimitry Andric     OS << format("  Version:               %d\n", Version);
213ff0cc061SDimitry Andric     OS << "  Augmentation:          \"" << Augmentation << "\"\n";
214ff0cc061SDimitry Andric     if (Version >= 4) {
215ff0cc061SDimitry Andric       OS << format("  Address size:          %u\n",
216ff0cc061SDimitry Andric                    (uint32_t)AddressSize);
217ff0cc061SDimitry Andric       OS << format("  Segment desc size:     %u\n",
218ff0cc061SDimitry Andric                    (uint32_t)SegmentDescriptorSize);
219ff0cc061SDimitry Andric     }
220ff0cc061SDimitry Andric     OS << format("  Code alignment factor: %u\n",
221ff0cc061SDimitry Andric                  (uint32_t)CodeAlignmentFactor);
222ff0cc061SDimitry Andric     OS << format("  Data alignment factor: %d\n",
223ff0cc061SDimitry Andric                  (int32_t)DataAlignmentFactor);
224ff0cc061SDimitry Andric     OS << format("  Return address column: %d\n",
225ff0cc061SDimitry Andric                  (int32_t)ReturnAddressRegister);
226ff0cc061SDimitry Andric     OS << "\n";
227ff0cc061SDimitry Andric   }
228ff0cc061SDimitry Andric 
229ff0cc061SDimitry Andric   static bool classof(const FrameEntry *FE) {
230ff0cc061SDimitry Andric     return FE->getKind() == FK_CIE;
231ff0cc061SDimitry Andric   }
232ff0cc061SDimitry Andric 
233ff0cc061SDimitry Andric private:
234ff0cc061SDimitry Andric   /// The following fields are defined in section 6.4.1 of the DWARF standard v4
235ff0cc061SDimitry Andric   uint8_t Version;
236ff0cc061SDimitry Andric   SmallString<8> Augmentation;
237ff0cc061SDimitry Andric   uint8_t AddressSize;
238ff0cc061SDimitry Andric   uint8_t SegmentDescriptorSize;
239ff0cc061SDimitry Andric   uint64_t CodeAlignmentFactor;
240ff0cc061SDimitry Andric   int64_t DataAlignmentFactor;
241ff0cc061SDimitry Andric   uint64_t ReturnAddressRegister;
242ff0cc061SDimitry Andric };
243ff0cc061SDimitry Andric 
244ff0cc061SDimitry Andric 
245ff0cc061SDimitry Andric /// \brief DWARF Frame Description Entry (FDE)
246ff0cc061SDimitry Andric class FDE : public FrameEntry {
247ff0cc061SDimitry Andric public:
248ff0cc061SDimitry Andric   // Each FDE has a CIE it's "linked to". Our FDE contains is constructed with
249ff0cc061SDimitry Andric   // an offset to the CIE (provided by parsing the FDE header). The CIE itself
250ff0cc061SDimitry Andric   // is obtained lazily once it's actually required.
251ff0cc061SDimitry Andric   FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,
252ff0cc061SDimitry Andric       uint64_t InitialLocation, uint64_t AddressRange,
253ff0cc061SDimitry Andric       CIE *Cie)
254ff0cc061SDimitry Andric       : FrameEntry(FK_FDE, Offset, Length), LinkedCIEOffset(LinkedCIEOffset),
255ff0cc061SDimitry Andric         InitialLocation(InitialLocation), AddressRange(AddressRange),
256ff0cc061SDimitry Andric         LinkedCIE(Cie) {}
257ff0cc061SDimitry Andric 
258ff0cc061SDimitry Andric   ~FDE() override {}
259ff0cc061SDimitry Andric 
260ff0cc061SDimitry Andric   CIE *getLinkedCIE() const { return LinkedCIE; }
261ff0cc061SDimitry Andric 
262ff0cc061SDimitry Andric   void dumpHeader(raw_ostream &OS) const override {
263ff0cc061SDimitry Andric     OS << format("%08x %08x %08x FDE ",
264ff0cc061SDimitry Andric                  (uint32_t)Offset, (uint32_t)Length, (int32_t)LinkedCIEOffset);
265ff0cc061SDimitry Andric     OS << format("cie=%08x pc=%08x...%08x\n",
266ff0cc061SDimitry Andric                  (int32_t)LinkedCIEOffset,
267ff0cc061SDimitry Andric                  (uint32_t)InitialLocation,
268ff0cc061SDimitry Andric                  (uint32_t)InitialLocation + (uint32_t)AddressRange);
269ff0cc061SDimitry Andric   }
270ff0cc061SDimitry Andric 
271ff0cc061SDimitry Andric   static bool classof(const FrameEntry *FE) {
272ff0cc061SDimitry Andric     return FE->getKind() == FK_FDE;
273ff0cc061SDimitry Andric   }
274ff0cc061SDimitry Andric 
275ff0cc061SDimitry Andric private:
276ff0cc061SDimitry Andric   /// The following fields are defined in section 6.4.1 of the DWARF standard v3
277ff0cc061SDimitry Andric   uint64_t LinkedCIEOffset;
278ff0cc061SDimitry Andric   uint64_t InitialLocation;
279ff0cc061SDimitry Andric   uint64_t AddressRange;
280ff0cc061SDimitry Andric   CIE *LinkedCIE;
281ff0cc061SDimitry Andric };
282ff0cc061SDimitry Andric 
283ff0cc061SDimitry Andric /// \brief Types of operands to CF instructions.
284ff0cc061SDimitry Andric enum OperandType {
285ff0cc061SDimitry Andric   OT_Unset,
286ff0cc061SDimitry Andric   OT_None,
287ff0cc061SDimitry Andric   OT_Address,
288ff0cc061SDimitry Andric   OT_Offset,
289ff0cc061SDimitry Andric   OT_FactoredCodeOffset,
290ff0cc061SDimitry Andric   OT_SignedFactDataOffset,
291ff0cc061SDimitry Andric   OT_UnsignedFactDataOffset,
292ff0cc061SDimitry Andric   OT_Register,
293ff0cc061SDimitry Andric   OT_Expression
294ff0cc061SDimitry Andric };
295ff0cc061SDimitry Andric 
296ff0cc061SDimitry Andric } // end anonymous namespace
297ff0cc061SDimitry Andric 
298ff0cc061SDimitry Andric /// \brief Initialize the array describing the types of operands.
299ff0cc061SDimitry Andric static ArrayRef<OperandType[2]> getOperandTypes() {
300ff0cc061SDimitry Andric   static OperandType OpTypes[DW_CFA_restore+1][2];
301ff0cc061SDimitry Andric 
302ff0cc061SDimitry Andric #define DECLARE_OP2(OP, OPTYPE0, OPTYPE1)       \
303ff0cc061SDimitry Andric   do {                                          \
304ff0cc061SDimitry Andric     OpTypes[OP][0] = OPTYPE0;                   \
305ff0cc061SDimitry Andric     OpTypes[OP][1] = OPTYPE1;                   \
306ff0cc061SDimitry Andric   } while (0)
307ff0cc061SDimitry Andric #define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
308ff0cc061SDimitry Andric #define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
309ff0cc061SDimitry Andric 
310ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_set_loc, OT_Address);
311ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
312ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
313ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
314ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
315ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
316ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
317ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);
318ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register);
319ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset);
320ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
321ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
322ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_undefined, OT_Register);
323ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_same_value, OT_Register);
324ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);
325ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
326ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
327ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);
328ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
329ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
330ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
331ff0cc061SDimitry Andric   DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
332ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_restore, OT_Register);
333ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_restore_extended, OT_Register);
334ff0cc061SDimitry Andric   DECLARE_OP0(DW_CFA_remember_state);
335ff0cc061SDimitry Andric   DECLARE_OP0(DW_CFA_restore_state);
336ff0cc061SDimitry Andric   DECLARE_OP0(DW_CFA_GNU_window_save);
337ff0cc061SDimitry Andric   DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);
338ff0cc061SDimitry Andric   DECLARE_OP0(DW_CFA_nop);
339ff0cc061SDimitry Andric 
340ff0cc061SDimitry Andric #undef DECLARE_OP0
341ff0cc061SDimitry Andric #undef DECLARE_OP1
342ff0cc061SDimitry Andric #undef DECLARE_OP2
343ff0cc061SDimitry Andric   return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);
344ff0cc061SDimitry Andric }
345ff0cc061SDimitry Andric 
346ff0cc061SDimitry Andric static ArrayRef<OperandType[2]> OpTypes = getOperandTypes();
347ff0cc061SDimitry Andric 
348ff0cc061SDimitry Andric /// \brief Print \p Opcode's operand number \p OperandIdx which has
349ff0cc061SDimitry Andric /// value \p Operand.
350ff0cc061SDimitry Andric static void printOperand(raw_ostream &OS, uint8_t Opcode, unsigned OperandIdx,
351ff0cc061SDimitry Andric                          uint64_t Operand, uint64_t CodeAlignmentFactor,
352ff0cc061SDimitry Andric                          int64_t DataAlignmentFactor) {
353ff0cc061SDimitry Andric   assert(OperandIdx < 2);
354ff0cc061SDimitry Andric   OperandType Type = OpTypes[Opcode][OperandIdx];
355ff0cc061SDimitry Andric 
356ff0cc061SDimitry Andric   switch (Type) {
357ff0cc061SDimitry Andric   case OT_Unset:
358ff0cc061SDimitry Andric     OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";
359ff0cc061SDimitry Andric     if (const char *OpcodeName = CallFrameString(Opcode))
360ff0cc061SDimitry Andric       OS << " " << OpcodeName;
361ff0cc061SDimitry Andric     else
362ff0cc061SDimitry Andric       OS << format(" Opcode %x",  Opcode);
363ff0cc061SDimitry Andric     break;
364ff0cc061SDimitry Andric   case OT_None:
365ff0cc061SDimitry Andric     break;
366ff0cc061SDimitry Andric   case OT_Address:
367ff0cc061SDimitry Andric     OS << format(" %" PRIx64, Operand);
368ff0cc061SDimitry Andric     break;
369ff0cc061SDimitry Andric   case OT_Offset:
370ff0cc061SDimitry Andric     // The offsets are all encoded in a unsigned form, but in practice
371ff0cc061SDimitry Andric     // consumers use them signed. It's most certainly legacy due to
372ff0cc061SDimitry Andric     // the lack of signed variants in the first Dwarf standards.
373ff0cc061SDimitry Andric     OS << format(" %+" PRId64, int64_t(Operand));
374ff0cc061SDimitry Andric     break;
375ff0cc061SDimitry Andric   case OT_FactoredCodeOffset: // Always Unsigned
376ff0cc061SDimitry Andric     if (CodeAlignmentFactor)
377ff0cc061SDimitry Andric       OS << format(" %" PRId64, Operand * CodeAlignmentFactor);
378ff0cc061SDimitry Andric     else
379ff0cc061SDimitry Andric       OS << format(" %" PRId64 "*code_alignment_factor" , Operand);
380ff0cc061SDimitry Andric     break;
381ff0cc061SDimitry Andric   case OT_SignedFactDataOffset:
382ff0cc061SDimitry Andric     if (DataAlignmentFactor)
383ff0cc061SDimitry Andric       OS << format(" %" PRId64, int64_t(Operand) * DataAlignmentFactor);
384ff0cc061SDimitry Andric     else
385ff0cc061SDimitry Andric       OS << format(" %" PRId64 "*data_alignment_factor" , int64_t(Operand));
386ff0cc061SDimitry Andric     break;
387ff0cc061SDimitry Andric   case OT_UnsignedFactDataOffset:
388ff0cc061SDimitry Andric     if (DataAlignmentFactor)
389ff0cc061SDimitry Andric       OS << format(" %" PRId64, Operand * DataAlignmentFactor);
390ff0cc061SDimitry Andric     else
391ff0cc061SDimitry Andric       OS << format(" %" PRId64 "*data_alignment_factor" , Operand);
392ff0cc061SDimitry Andric     break;
393ff0cc061SDimitry Andric   case OT_Register:
394ff0cc061SDimitry Andric     OS << format(" reg%" PRId64, Operand);
395ff0cc061SDimitry Andric     break;
396ff0cc061SDimitry Andric   case OT_Expression:
397ff0cc061SDimitry Andric     OS << " expression";
398ff0cc061SDimitry Andric     break;
399ff0cc061SDimitry Andric   }
400ff0cc061SDimitry Andric }
401ff0cc061SDimitry Andric 
402ff0cc061SDimitry Andric void FrameEntry::dumpInstructions(raw_ostream &OS) const {
403ff0cc061SDimitry Andric   uint64_t CodeAlignmentFactor = 0;
404ff0cc061SDimitry Andric   int64_t DataAlignmentFactor = 0;
405ff0cc061SDimitry Andric   const CIE *Cie = dyn_cast<CIE>(this);
406ff0cc061SDimitry Andric 
407ff0cc061SDimitry Andric   if (!Cie)
408ff0cc061SDimitry Andric     Cie = cast<FDE>(this)->getLinkedCIE();
409ff0cc061SDimitry Andric   if (Cie) {
410ff0cc061SDimitry Andric     CodeAlignmentFactor = Cie->getCodeAlignmentFactor();
411ff0cc061SDimitry Andric     DataAlignmentFactor = Cie->getDataAlignmentFactor();
412ff0cc061SDimitry Andric   }
413ff0cc061SDimitry Andric 
414ff0cc061SDimitry Andric   for (const auto &Instr : Instructions) {
415ff0cc061SDimitry Andric     uint8_t Opcode = Instr.Opcode;
416ff0cc061SDimitry Andric     if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
417ff0cc061SDimitry Andric       Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
418ff0cc061SDimitry Andric     OS << "  " << CallFrameString(Opcode) << ":";
419ff0cc061SDimitry Andric     for (unsigned i = 0; i < Instr.Ops.size(); ++i)
420ff0cc061SDimitry Andric       printOperand(OS, Opcode, i, Instr.Ops[i], CodeAlignmentFactor,
421ff0cc061SDimitry Andric                    DataAlignmentFactor);
422ff0cc061SDimitry Andric     OS << '\n';
423ff0cc061SDimitry Andric   }
424ff0cc061SDimitry Andric }
425ff0cc061SDimitry Andric 
426ff0cc061SDimitry Andric DWARFDebugFrame::DWARFDebugFrame() {
427ff0cc061SDimitry Andric }
428ff0cc061SDimitry Andric 
429ff0cc061SDimitry Andric DWARFDebugFrame::~DWARFDebugFrame() {
430ff0cc061SDimitry Andric }
431ff0cc061SDimitry Andric 
432ff0cc061SDimitry Andric static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
433ff0cc061SDimitry Andric                                               uint32_t Offset, int Length) {
434ff0cc061SDimitry Andric   errs() << "DUMP: ";
435ff0cc061SDimitry Andric   for (int i = 0; i < Length; ++i) {
436ff0cc061SDimitry Andric     uint8_t c = Data.getU8(&Offset);
437ff0cc061SDimitry Andric     errs().write_hex(c); errs() << " ";
438ff0cc061SDimitry Andric   }
439ff0cc061SDimitry Andric   errs() << "\n";
440ff0cc061SDimitry Andric }
441ff0cc061SDimitry Andric 
442ff0cc061SDimitry Andric 
443ff0cc061SDimitry Andric void DWARFDebugFrame::parse(DataExtractor Data) {
444ff0cc061SDimitry Andric   uint32_t Offset = 0;
445ff0cc061SDimitry Andric   DenseMap<uint32_t, CIE *> CIEs;
446ff0cc061SDimitry Andric 
447ff0cc061SDimitry Andric   while (Data.isValidOffset(Offset)) {
448ff0cc061SDimitry Andric     uint32_t StartOffset = Offset;
449ff0cc061SDimitry Andric 
450ff0cc061SDimitry Andric     bool IsDWARF64 = false;
451ff0cc061SDimitry Andric     uint64_t Length = Data.getU32(&Offset);
452ff0cc061SDimitry Andric     uint64_t Id;
453ff0cc061SDimitry Andric 
454ff0cc061SDimitry Andric     if (Length == UINT32_MAX) {
455ff0cc061SDimitry Andric       // DWARF-64 is distinguished by the first 32 bits of the initial length
456ff0cc061SDimitry Andric       // field being 0xffffffff. Then, the next 64 bits are the actual entry
457ff0cc061SDimitry Andric       // length.
458ff0cc061SDimitry Andric       IsDWARF64 = true;
459ff0cc061SDimitry Andric       Length = Data.getU64(&Offset);
460ff0cc061SDimitry Andric     }
461ff0cc061SDimitry Andric 
462ff0cc061SDimitry Andric     // At this point, Offset points to the next field after Length.
463ff0cc061SDimitry Andric     // Length is the structure size excluding itself. Compute an offset one
464ff0cc061SDimitry Andric     // past the end of the structure (needed to know how many instructions to
465ff0cc061SDimitry Andric     // read).
466ff0cc061SDimitry Andric     // TODO: For honest DWARF64 support, DataExtractor will have to treat
467ff0cc061SDimitry Andric     //       offset_ptr as uint64_t*
468ff0cc061SDimitry Andric     uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length);
469ff0cc061SDimitry Andric 
470ff0cc061SDimitry Andric     // The Id field's size depends on the DWARF format
471ff0cc061SDimitry Andric     Id = Data.getUnsigned(&Offset, IsDWARF64 ? 8 : 4);
472ff0cc061SDimitry Andric     bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID);
473ff0cc061SDimitry Andric 
474ff0cc061SDimitry Andric     if (IsCIE) {
475ff0cc061SDimitry Andric       uint8_t Version = Data.getU8(&Offset);
476ff0cc061SDimitry Andric       const char *Augmentation = Data.getCStr(&Offset);
477ff0cc061SDimitry Andric       uint8_t AddressSize = Version < 4 ? Data.getAddressSize() : Data.getU8(&Offset);
478ff0cc061SDimitry Andric       Data.setAddressSize(AddressSize);
479ff0cc061SDimitry Andric       uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset);
480ff0cc061SDimitry Andric       uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
481ff0cc061SDimitry Andric       int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
482ff0cc061SDimitry Andric       uint64_t ReturnAddressRegister = Data.getULEB128(&Offset);
483ff0cc061SDimitry Andric 
484ff0cc061SDimitry Andric       auto Cie = make_unique<CIE>(StartOffset, Length, Version,
485ff0cc061SDimitry Andric                                   StringRef(Augmentation), AddressSize,
486ff0cc061SDimitry Andric                                   SegmentDescriptorSize, CodeAlignmentFactor,
487ff0cc061SDimitry Andric                                   DataAlignmentFactor, ReturnAddressRegister);
488ff0cc061SDimitry Andric       CIEs[StartOffset] = Cie.get();
489ff0cc061SDimitry Andric       Entries.emplace_back(std::move(Cie));
490ff0cc061SDimitry Andric     } else {
491ff0cc061SDimitry Andric       // FDE
492ff0cc061SDimitry Andric       uint64_t CIEPointer = Id;
493ff0cc061SDimitry Andric       uint64_t InitialLocation = Data.getAddress(&Offset);
494ff0cc061SDimitry Andric       uint64_t AddressRange = Data.getAddress(&Offset);
495ff0cc061SDimitry Andric 
496ff0cc061SDimitry Andric       Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
497ff0cc061SDimitry Andric                                    InitialLocation, AddressRange,
498ff0cc061SDimitry Andric                                    CIEs[CIEPointer]));
499ff0cc061SDimitry Andric     }
500ff0cc061SDimitry Andric 
501ff0cc061SDimitry Andric     Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset);
502ff0cc061SDimitry Andric 
503ff0cc061SDimitry Andric     if (Offset != EndStructureOffset) {
504ff0cc061SDimitry Andric       std::string Str;
505ff0cc061SDimitry Andric       raw_string_ostream OS(Str);
506ff0cc061SDimitry Andric       OS << format("Parsing entry instructions at %lx failed", StartOffset);
507ff0cc061SDimitry Andric       report_fatal_error(Str);
508ff0cc061SDimitry Andric     }
509ff0cc061SDimitry Andric   }
510ff0cc061SDimitry Andric }
511ff0cc061SDimitry Andric 
512ff0cc061SDimitry Andric 
513ff0cc061SDimitry Andric void DWARFDebugFrame::dump(raw_ostream &OS) const {
514ff0cc061SDimitry Andric   OS << "\n";
515ff0cc061SDimitry Andric   for (const auto &Entry : Entries) {
516ff0cc061SDimitry Andric     Entry->dumpHeader(OS);
517ff0cc061SDimitry Andric     Entry->dumpInstructions(OS);
518ff0cc061SDimitry Andric     OS << "\n";
519ff0cc061SDimitry Andric   }
520ff0cc061SDimitry Andric }
521ff0cc061SDimitry Andric 
522