[X86][Haswell][SchedModel] Add architecture specific scheduling models.
[oota-llvm.git] / lib / DebugInfo / DWARFDebugFrame.cpp
index 951c7a024dcfd03df5a200cb7e4f044b385c1d27..a33548e95b0b99a700a72ddc800ea8d010deb65f 100644 (file)
@@ -10,8 +10,8 @@
 #include "DWARFDebugFrame.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/DataTypes.h"
-#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Dwarf.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/raw_ostream.h"
 #include <string>
@@ -26,8 +26,8 @@ using namespace dwarf;
 class llvm::FrameEntry {
 public:
   enum FrameKind {FK_CIE, FK_FDE};
-  FrameEntry(FrameKind K, DataExtractor D, uint64_t Offset, uint64_t Length)
-    : Kind(K), Data(D), Offset(Offset), Length(Length) {}
+  FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length)
+      : Kind(K), Offset(Offset), Length(Length) {}
 
   virtual ~FrameEntry() {
   }
@@ -35,12 +35,12 @@ public:
   FrameKind getKind() const { return Kind; }
   virtual uint64_t getOffset() const { return Offset; }
 
-  /// \brief Parse and store a sequence of CFI instructions from our data
-  /// stream, starting at Offset and ending at EndOffset. If everything
-  /// goes well, Offset should be equal to EndOffset when this method
+  /// \brief Parse and store a sequence of CFI instructions from Data,
+  /// starting at *Offset and ending at EndOffset. If everything
+  /// goes well, *Offset should be equal to EndOffset when this method
   /// returns. Otherwise, an error occurred.
-  /// TODO: Improve error reporting...
-  virtual void parseInstructions(uint32_t &Offset, uint32_t EndOffset);
+  virtual void parseInstructions(DataExtractor Data, uint32_t *Offset,
+                                 uint32_t EndOffset);
 
   /// \brief Dump the entry header to the given output stream.
   virtual void dumpHeader(raw_ostream &OS) const = 0;
@@ -51,10 +51,6 @@ public:
 protected:
   const FrameKind Kind;
 
-  /// \brief The data stream holding the section from which the entry was
-  /// parsed.
-  DataExtractor Data;
-
   /// \brief Offset of this entry in the section.
   uint64_t Offset;
 
@@ -98,10 +94,10 @@ protected:
 const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
 const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
 
-
-void FrameEntry::parseInstructions(uint32_t &Offset, uint32_t EndOffset) {
-  while (Offset < EndOffset) {
-    uint8_t Opcode = Data.getU8(&Offset);
+void FrameEntry::parseInstructions(DataExtractor Data, uint32_t *Offset,
+                                   uint32_t EndOffset) {
+  while (*Offset < EndOffset) {
+    uint8_t Opcode = Data.getU8(Offset);
     // Some instructions have a primary opcode encoded in the top bits.
     uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK;
 
@@ -116,7 +112,7 @@ void FrameEntry::parseInstructions(uint32_t &Offset, uint32_t EndOffset) {
           addInstruction(Primary, Op1);
           break;
         case DW_CFA_offset:
-          addInstruction(Primary, Op1, Data.getULEB128(&Offset));
+          addInstruction(Primary, Op1, Data.getULEB128(Offset));
           break;
       }
     } else {
@@ -126,24 +122,25 @@ void FrameEntry::parseInstructions(uint32_t &Offset, uint32_t EndOffset) {
         case DW_CFA_nop:
         case DW_CFA_remember_state:
         case DW_CFA_restore_state:
+        case DW_CFA_GNU_window_save:
           // No operands
           addInstruction(Opcode);
           break;
         case DW_CFA_set_loc:
           // Operands: Address
-          addInstruction(Opcode, Data.getAddress(&Offset));
+          addInstruction(Opcode, Data.getAddress(Offset));
           break;
         case DW_CFA_advance_loc1:
           // Operands: 1-byte delta
-          addInstruction(Opcode, Data.getU8(&Offset));
+          addInstruction(Opcode, Data.getU8(Offset));
           break;
         case DW_CFA_advance_loc2:
           // Operands: 2-byte delta
-          addInstruction(Opcode, Data.getU16(&Offset));
+          addInstruction(Opcode, Data.getU16(Offset));
           break;
         case DW_CFA_advance_loc4:
           // Operands: 4-byte delta
-          addInstruction(Opcode, Data.getU32(&Offset));
+          addInstruction(Opcode, Data.getU32(Offset));
           break;
         case DW_CFA_restore_extended:
         case DW_CFA_undefined:
@@ -151,26 +148,26 @@ void FrameEntry::parseInstructions(uint32_t &Offset, uint32_t EndOffset) {
         case DW_CFA_def_cfa_register:
         case DW_CFA_def_cfa_offset:
           // Operands: ULEB128
-          addInstruction(Opcode, Data.getULEB128(&Offset));
+          addInstruction(Opcode, Data.getULEB128(Offset));
           break;
         case DW_CFA_def_cfa_offset_sf:
           // Operands: SLEB128
-          addInstruction(Opcode, Data.getSLEB128(&Offset));
+          addInstruction(Opcode, Data.getSLEB128(Offset));
           break;
         case DW_CFA_offset_extended:
         case DW_CFA_register:
         case DW_CFA_def_cfa:
         case DW_CFA_val_offset:
           // Operands: ULEB128, ULEB128
-          addInstruction(Opcode, Data.getULEB128(&Offset),
-                                 Data.getULEB128(&Offset));
+          addInstruction(Opcode, Data.getULEB128(Offset),
+                                 Data.getULEB128(Offset));
           break;
         case DW_CFA_offset_extended_sf:
         case DW_CFA_def_cfa_sf:
         case DW_CFA_val_offset_sf:
           // Operands: ULEB128, SLEB128
-          addInstruction(Opcode, Data.getULEB128(&Offset),
-                                 Data.getSLEB128(&Offset));
+          addInstruction(Opcode, Data.getULEB128(Offset),
+                                 Data.getSLEB128(Offset));
           break;
         case DW_CFA_def_cfa_expression:
         case DW_CFA_expression:
@@ -186,10 +183,8 @@ void FrameEntry::parseInstructions(uint32_t &Offset, uint32_t EndOffset) {
 void FrameEntry::dumpInstructions(raw_ostream &OS) const {
   // TODO: at the moment only instruction names are dumped. Expand this to
   // dump operands as well.
-  for (std::vector<Instruction>::const_iterator I = Instructions.begin(),
-                                                E = Instructions.end();
-       I != E; ++I) {
-    uint8_t Opcode = I->Opcode;
+  for (const auto &Instr : Instructions) {
+    uint8_t Opcode = Instr.Opcode;
     if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
       Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
     OS << "  " << CallFrameString(Opcode) << ":\n";
@@ -203,18 +198,18 @@ class CIE : public FrameEntry {
 public:
   // CIEs (and FDEs) are simply container classes, so the only sensible way to
   // create them is by providing the full parsed contents in the constructor.
-  CIE(DataExtractor D, uint64_t Offset, uint64_t Length, uint8_t Version,
+  CIE(uint64_t Offset, uint64_t Length, uint8_t Version,
       SmallString<8> Augmentation, uint64_t CodeAlignmentFactor,
       int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister)
-   : FrameEntry(FK_CIE, D, Offset, Length), Version(Version),
-     Augmentation(Augmentation), CodeAlignmentFactor(CodeAlignmentFactor),
-     DataAlignmentFactor(DataAlignmentFactor),
-     ReturnAddressRegister(ReturnAddressRegister) {}
+      : FrameEntry(FK_CIE, Offset, Length), Version(Version),
+        Augmentation(Augmentation), CodeAlignmentFactor(CodeAlignmentFactor),
+        DataAlignmentFactor(DataAlignmentFactor),
+        ReturnAddressRegister(ReturnAddressRegister) {}
 
   ~CIE() {
   }
 
-  void dumpHeader(raw_ostream &OS) const {
+  void dumpHeader(raw_ostream &OS) const override {
     OS << format("%08x %08x %08x CIE",
                  (uint32_t)Offset, (uint32_t)Length, DW_CIE_ID)
        << "\n";
@@ -231,7 +226,7 @@ public:
 
   static bool classof(const FrameEntry *FE) {
     return FE->getKind() == FK_CIE;
-  } 
+  }
 
 private:
   /// The following fields are defined in section 6.4.1 of the DWARF standard v3
@@ -249,16 +244,16 @@ public:
   // Each FDE has a CIE it's "linked to". Our FDE contains is constructed with
   // an offset to the CIE (provided by parsing the FDE header). The CIE itself
   // is obtained lazily once it's actually required.
-  FDE(DataExtractor D, uint64_t Offset, uint64_t Length,
-      int64_t LinkedCIEOffset, uint64_t InitialLocation, uint64_t AddressRange)
-   : FrameEntry(FK_FDE, D, Offset, Length), LinkedCIEOffset(LinkedCIEOffset),
-     InitialLocation(InitialLocation), AddressRange(AddressRange),
-     LinkedCIE(NULL) {}
+  FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,
+      uint64_t InitialLocation, uint64_t AddressRange)
+      : FrameEntry(FK_FDE, Offset, Length), LinkedCIEOffset(LinkedCIEOffset),
+        InitialLocation(InitialLocation), AddressRange(AddressRange),
+        LinkedCIE(nullptr) {}
 
   ~FDE() {
   }
 
-  void dumpHeader(raw_ostream &OS) const {
+  void dumpHeader(raw_ostream &OS) const override {
     OS << format("%08x %08x %08x FDE ",
                  (uint32_t)Offset, (uint32_t)Length, (int32_t)LinkedCIEOffset);
     OS << format("cie=%08x pc=%08x...%08x\n",
@@ -272,9 +267,9 @@ public:
 
   static bool classof(const FrameEntry *FE) {
     return FE->getKind() == FK_FDE;
-  } 
-private:
+  }
 
+private:
   /// The following fields are defined in section 6.4.1 of the DWARF standard v3
   uint64_t LinkedCIEOffset;
   uint64_t InitialLocation;
@@ -287,15 +282,9 @@ private:
 DWARFDebugFrame::DWARFDebugFrame() {
 }
 
-
 DWARFDebugFrame::~DWARFDebugFrame() {
-  for (EntryVector::iterator I = Entries.begin(), E = Entries.end();
-       I != E; ++I) {
-    delete *I;
-  }
 }
 
-
 static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
                                               uint32_t Offset, int Length) {
   errs() << "DUMP: ";
@@ -339,35 +328,34 @@ void DWARFDebugFrame::parse(DataExtractor Data) {
 
     if (IsCIE) {
       // Note: this is specifically DWARFv3 CIE header structure. It was
-      // changed in DWARFv4.
+      // changed in DWARFv4. We currently don't support reading DWARFv4
+      // here because LLVM itself does not emit it (and LLDB doesn't
+      // support it either).
       uint8_t Version = Data.getU8(&Offset);
       const char *Augmentation = Data.getCStr(&Offset);
       uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
       int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
       uint64_t ReturnAddressRegister = Data.getULEB128(&Offset);
 
-      CIE *NewCIE = new CIE(Data, StartOffset, Length, Version,
-                            StringRef(Augmentation), CodeAlignmentFactor,
-                            DataAlignmentFactor, ReturnAddressRegister);
-      Entries.push_back(NewCIE);
+      Entries.emplace_back(new CIE(StartOffset, Length, Version,
+                                   StringRef(Augmentation), CodeAlignmentFactor,
+                                   DataAlignmentFactor, ReturnAddressRegister));
     } else {
       // FDE
       uint64_t CIEPointer = Id;
       uint64_t InitialLocation = Data.getAddress(&Offset);
       uint64_t AddressRange = Data.getAddress(&Offset);
 
-      FDE *NewFDE = new FDE(Data, StartOffset, Length, CIEPointer,
-                            InitialLocation, AddressRange);
-      Entries.push_back(NewFDE);
+      Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
+                                   InitialLocation, AddressRange));
     }
 
-    Entries.back()->parseInstructions(Offset, EndStructureOffset);
+    Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset);
 
     if (Offset != EndStructureOffset) {
       std::string Str;
       raw_string_ostream OS(Str);
-      OS << format("Parsing entry instructions at %lx failed",
-                   Entries.back()->getOffset());
+      OS << format("Parsing entry instructions at %lx failed", StartOffset);
       report_fatal_error(Str);
     }
   }
@@ -376,9 +364,7 @@ void DWARFDebugFrame::parse(DataExtractor Data) {
 
 void DWARFDebugFrame::dump(raw_ostream &OS) const {
   OS << "\n";
-  for (EntryVector::const_iterator I = Entries.begin(), E = Entries.end();
-       I != E; ++I) {
-    FrameEntry *Entry = *I;
+  for (const auto &Entry : Entries) {
     Entry->dumpHeader(OS);
     Entry->dumpInstructions(OS);
     OS << "\n";