DWARFDebugFrame.cpp revision 8ff0631967c64d51b193b862aa0a6f1e8eb06f78
103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)//===-- DWARFDebugFrame.h - Parsing of .debug_frame -------------*- C++ -*-===//
203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)//
303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)//
503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// License. See LICENSE.TXT for details.
703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)//
803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)//===----------------------------------------------------------------------===//
903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "DWARFDebugFrame.h"
1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "llvm/ADT/SmallString.h"
1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "llvm/Support/DataTypes.h"
1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "llvm/Support/Dwarf.h"
1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "llvm/Support/Format.h"
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using namespace llvm;
1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using namespace dwarf;
1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)/// \brief Abstract frame entry defining the common interface concrete
2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)/// entries implement.
2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class llvm::FrameEntry {
2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)public:
2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  enum FrameKind {FK_CIE, FK_FDE};
2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FrameEntry(FrameKind K, DataExtractor D, uint64_t Offset, uint64_t Length)
2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    : Kind(K), Data(D), Offset(Offset), Length(Length) {}
2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual ~FrameEntry() {
2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FrameKind getKind() const { return Kind; }
3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void dumpHeader(raw_ostream &OS) const = 0;
3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)protected:
3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const FrameKind Kind;
3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  /// \brief The data stream holding the section from which the entry was
3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  /// parsed.
4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DataExtractor Data;
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  /// \brief Offset of this entry in the section.
4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  uint64_t Offset;
4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  /// \brief Entry length as specified in DWARF.
4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  uint64_t Length;
4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)};
4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)/// \brief DWARF Common Information Entry (CIE)
5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class CIE : public FrameEntry {
5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)public:
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // CIEs (and FDEs) are simply container classes, so the only sensible way to
5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // create them is by providing the full parsed contents in the constructor.
5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  CIE(DataExtractor D, uint64_t Offset, uint64_t Length, uint8_t Version,
5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      SmallString<8> Augmentation, uint64_t CodeAlignmentFactor,
5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister)
5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)   : FrameEntry(FK_CIE, D, Offset, Length), Version(Version),
5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     Augmentation(Augmentation), CodeAlignmentFactor(CodeAlignmentFactor),
6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     DataAlignmentFactor(DataAlignmentFactor),
6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     ReturnAddressRegister(ReturnAddressRegister) {}
6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ~CIE() {
6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void dumpHeader(raw_ostream &OS) const {
6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    OS << format("%08x %08x %08x CIE",
6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 (uint32_t)Offset, (uint32_t)Length, DW_CIE_ID)
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)       << "\n";
7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    OS << format("  Version:               %d\n", Version);
7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    OS << "  Augmentation:          \"" << Augmentation << "\"\n";
7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    OS << format("  Code alignment factor: %u\n", CodeAlignmentFactor);
7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    OS << format("  Data alignment factor: %d\n", DataAlignmentFactor);
7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    OS << format("  Return address column: %d\n", ReturnAddressRegister);
7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    OS << "\n";
7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  static bool classof(const FrameEntry *FE) {
7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return FE->getKind() == FK_CIE;
8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)private:
8303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  /// The following fields are defined in section 6.4.1 of the DWARF standard v3
8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  uint8_t Version;
8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  SmallString<8> Augmentation;
8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  uint64_t CodeAlignmentFactor;
8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  int64_t DataAlignmentFactor;
8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  uint64_t ReturnAddressRegister;
8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)};
9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)/// \brief DWARF Frame Description Entry (FDE)
9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class FDE : public FrameEntry {
9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)public:
9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Each FDE has a CIE it's "linked to". Our FDE contains is constructed with
9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // an offset to the CIE (provided by parsing the FDE header). The CIE itself
9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // is obtained lazily once it's actually required.
9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FDE(DataExtractor D, uint64_t Offset, uint64_t Length,
9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      int64_t LinkedCIEOffset, uint64_t InitialLocation, uint64_t AddressRange)
10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)   : FrameEntry(FK_FDE, D, Offset, Length), LinkedCIEOffset(LinkedCIEOffset),
10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     InitialLocation(InitialLocation), AddressRange(AddressRange),
10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)     LinkedCIE(NULL) {}
10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ~FDE() {
10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void dumpHeader(raw_ostream &OS) const {
10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    OS << format("%08x %08x %08x FDE ",
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 (uint32_t)Offset, (uint32_t)Length, LinkedCIEOffset);
11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    OS << format("cie=%08x pc=%08x...%08x\n",
11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 (uint32_t)LinkedCIEOffset,
11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 (uint32_t)InitialLocation,
11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 (uint32_t)InitialLocation + (uint32_t)AddressRange);
11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    OS << "\n";
11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (LinkedCIE) {
11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      OS << format("%p\n", LinkedCIE);
11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  static bool classof(const FrameEntry *FE) {
12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return FE->getKind() == FK_FDE;
12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)private:
12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  /// The following fields are defined in section 6.4.1 of the DWARF standard v3
12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  uint64_t LinkedCIEOffset;
12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  uint64_t InitialLocation;
12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  uint64_t AddressRange;
12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  CIE *LinkedCIE;
13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)};
13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)DWARFDebugFrame::DWARFDebugFrame() {
13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)DWARFDebugFrame::~DWARFDebugFrame() {
13803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  for (EntryVector::iterator I = Entries.begin(), E = Entries.end();
13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)       I != E; ++I) {
14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    delete *I;
14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                              uint32_t Offset, int Length) {
14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  errs() << "DUMP: ";
14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  for (int i = 0; i < Length; ++i) {
14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    uint8_t c = Data.getU8(&Offset);
15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    errs().write_hex(c); errs() << " ";
15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  errs() << "\n";
15303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void DWARFDebugFrame::parse(DataExtractor Data) {
15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  uint32_t Offset = 0;
15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  while (Data.isValidOffset(Offset)) {
16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    uint32_t StartOffset = Offset;
16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    bool IsDWARF64 = false;
16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    uint64_t Length = Data.getU32(&Offset);
16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    uint64_t Id;
16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (Length == UINT32_MAX) {
16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // DWARF-64 is distinguished by the first 32 bits of the initial length
16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // field being 0xffffffff. Then, the next 64 bits are the actual entry
16903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // length.
17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      IsDWARF64 = true;
17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      Length = Data.getU64(&Offset);
17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // At this point, Offset points to the next field after Length.
17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // Length is the structure size excluding itself. Compute an offset one
17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // past the end of the structure (needed to know how many instructions to
17703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // read).
17803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // TODO: For honest DWARF64 support, DataExtractor will have to treat
17903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    //       offset_ptr as uint64_t*
18003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length);
18103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // The Id field's size depends on the DWARF format
18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    Id = Data.getUnsigned(&Offset, IsDWARF64 ? 8 : 4);
18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID);
18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (IsCIE) {
18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // Note: this is specifically DWARFv3 CIE header structure. It was
18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // changed in DWARFv4.
18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      uint8_t Version = Data.getU8(&Offset);
19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      const char *Augmentation = Data.getCStr(&Offset);
19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
19203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
19303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      uint64_t ReturnAddressRegister = Data.getULEB128(&Offset);
19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      CIE *NewCIE = new CIE(Data, StartOffset, Length, Version,
19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                            StringRef(Augmentation), CodeAlignmentFactor,
19703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                            DataAlignmentFactor, ReturnAddressRegister);
19803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      Entries.push_back(NewCIE);
19903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    } else {
20003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      // FDE
20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      uint64_t CIEPointer = Id;
20203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      uint64_t InitialLocation = Data.getAddress(&Offset);
20303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      uint64_t AddressRange = Data.getAddress(&Offset);
20403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
20503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FDE *NewFDE = new FDE(Data, StartOffset, Length, CIEPointer,
20603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                            InitialLocation, AddressRange);
20703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      Entries.push_back(NewFDE);
20803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
20903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    Offset = EndStructureOffset;
21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
21203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
21303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
21403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
21503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void DWARFDebugFrame::dump(raw_ostream &OS) const {
21603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  OS << "\n";
21703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  for (EntryVector::const_iterator I = Entries.begin(), E = Entries.end();
21803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)       I != E; ++I) {
21903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    (*I)->dumpHeader(OS);
22003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
22103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
22203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
22303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)