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