[DWARF parser] Fix nasty memory corruption in .dwo files handling.
[oota-llvm.git] / lib / DebugInfo / DWARFContext.h
index 9ff094bd484d4099e0b614cd56762927a83af7ba..b72c119d2534da5ba4a9d5fa5921a4c57e4a0b1a 100644 (file)
@@ -7,14 +7,17 @@
 //
 //===----------------------------------------------------------------------===/
 
-#ifndef LLVM_DEBUGINFO_DWARFCONTEXT_H
-#define LLVM_DEBUGINFO_DWARFCONTEXT_H
+#ifndef LLVM_LIB_DEBUGINFO_DWARFCONTEXT_H
+#define LLVM_LIB_DEBUGINFO_DWARFCONTEXT_H
 
 #include "DWARFCompileUnit.h"
 #include "DWARFDebugAranges.h"
+#include "DWARFDebugFrame.h"
 #include "DWARFDebugLine.h"
+#include "DWARFDebugLoc.h"
 #include "DWARFDebugRangeList.h"
-#include "llvm/ADT/OwningPtr.h"
+#include "DWARFTypeUnit.h"
+#include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/DebugInfo/DIContext.h"
 
@@ -25,97 +28,177 @@ namespace llvm {
 /// information parsing. The actual data is supplied through pure virtual
 /// methods that a concrete implementation provides.
 class DWARFContext : public DIContext {
-  SmallVector<DWARFCompileUnit, 1> CUs;
-  OwningPtr<DWARFDebugAbbrev> Abbrev;
-  OwningPtr<DWARFDebugAranges> Aranges;
-  OwningPtr<DWARFDebugLine> Line;
+  typedef SmallVector<std::unique_ptr<DWARFCompileUnit>, 1> CUVector;
+  typedef SmallVector<std::unique_ptr<DWARFTypeUnit>, 1> TUVector;
 
-  SmallVector<DWARFCompileUnit, 1> DWOCUs;
-  OwningPtr<DWARFDebugAbbrev> AbbrevDWO;
+  CUVector CUs;
+  TUVector TUs;
+  std::unique_ptr<DWARFDebugAbbrev> Abbrev;
+  std::unique_ptr<DWARFDebugLoc> Loc;
+  std::unique_ptr<DWARFDebugAranges> Aranges;
+  std::unique_ptr<DWARFDebugLine> Line;
+  std::unique_ptr<DWARFDebugFrame> DebugFrame;
+
+  CUVector DWOCUs;
+  TUVector DWOTUs;
+  std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
+  std::unique_ptr<DWARFDebugLocDWO> LocDWO;
 
   DWARFContext(DWARFContext &) LLVM_DELETED_FUNCTION;
   DWARFContext &operator=(DWARFContext &) LLVM_DELETED_FUNCTION;
 
-  /// Read compile units from the debug_info section and store them in CUs.
+  /// Read compile units from the debug_info section (if necessary)
+  /// and store them in CUs.
   void parseCompileUnits();
 
-  /// Read compile units from the debug_info.dwo section and store them in
-  /// DWOCUs.
+  /// Read type units from the debug_types sections (if necessary)
+  /// and store them in TUs.
+  void parseTypeUnits();
+
+  /// Read compile units from the debug_info.dwo section (if necessary)
+  /// and store them in DWOCUs.
   void parseDWOCompileUnits();
 
+  /// Read type units from the debug_types.dwo section (if necessary)
+  /// and store them in DWOTUs.
+  void parseDWOTypeUnits();
+
 public:
-  DWARFContext() {}
-  virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All);
+  struct Section {
+    StringRef Data;
+    RelocAddrMap Relocs;
+  };
+
+  DWARFContext() : DIContext(CK_DWARF) {}
+
+  static bool classof(const DIContext *DICtx) {
+    return DICtx->getKind() == CK_DWARF;
+  }
+
+  void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override;
+
+  typedef iterator_range<CUVector::iterator> cu_iterator_range;
+  typedef iterator_range<TUVector::iterator> tu_iterator_range;
+
+  /// Get compile units in this context.
+  cu_iterator_range compile_units() {
+    parseCompileUnits();
+    return cu_iterator_range(CUs.begin(), CUs.end());
+  }
+
+  /// Get type units in this context.
+  tu_iterator_range type_units() {
+    parseTypeUnits();
+    return tu_iterator_range(TUs.begin(), TUs.end());
+  }
+
+  /// Get compile units in the DWO context.
+  cu_iterator_range dwo_compile_units() {
+    parseDWOCompileUnits();
+    return cu_iterator_range(DWOCUs.begin(), DWOCUs.end());
+  }
+
+  /// Get type units in the DWO context.
+  tu_iterator_range dwo_type_units() {
+    parseDWOTypeUnits();
+    return tu_iterator_range(DWOTUs.begin(), DWOTUs.end());
+  }
 
   /// Get the number of compile units in this context.
   unsigned getNumCompileUnits() {
-    if (CUs.empty())
-      parseCompileUnits();
+    parseCompileUnits();
     return CUs.size();
   }
 
+  /// Get the number of compile units in this context.
+  unsigned getNumTypeUnits() {
+    parseTypeUnits();
+    return TUs.size();
+  }
+
   /// Get the number of compile units in the DWO context.
   unsigned getNumDWOCompileUnits() {
-    if (DWOCUs.empty())
-      parseDWOCompileUnits();
+    parseDWOCompileUnits();
     return DWOCUs.size();
   }
 
+  /// Get the number of compile units in the DWO context.
+  unsigned getNumDWOTypeUnits() {
+    parseDWOTypeUnits();
+    return DWOTUs.size();
+  }
+
   /// Get the compile unit at the specified index for this compile unit.
   DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) {
-    if (CUs.empty())
-      parseCompileUnits();
-    return &CUs[index];
+    parseCompileUnits();
+    return CUs[index].get();
   }
 
   /// Get the compile unit at the specified index for the DWO compile units.
   DWARFCompileUnit *getDWOCompileUnitAtIndex(unsigned index) {
-    if (DWOCUs.empty())
-      parseDWOCompileUnits();
-    return &DWOCUs[index];
+    parseDWOCompileUnits();
+    return DWOCUs[index].get();
   }
 
   /// Get a pointer to the parsed DebugAbbrev object.
   const DWARFDebugAbbrev *getDebugAbbrev();
 
+  /// Get a pointer to the parsed DebugLoc object.
+  const DWARFDebugLoc *getDebugLoc();
+
   /// Get a pointer to the parsed dwo abbreviations object.
   const DWARFDebugAbbrev *getDebugAbbrevDWO();
 
+  /// Get a pointer to the parsed DebugLoc object.
+  const DWARFDebugLocDWO *getDebugLocDWO();
+
   /// Get a pointer to the parsed DebugAranges object.
   const DWARFDebugAranges *getDebugAranges();
 
+  /// Get a pointer to the parsed frame information object.
+  const DWARFDebugFrame *getDebugFrame();
+
   /// Get a pointer to a parsed line table corresponding to a compile unit.
-  const DWARFDebugLine::LineTable *
-  getLineTableForCompileUnit(DWARFCompileUnit *cu);
+  const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu);
 
-  virtual DILineInfo getLineInfoForAddress(uint64_t Address,
-      DILineInfoSpecifier Specifier = DILineInfoSpecifier());
-  virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address,
-      uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier());
-  virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address,
-      DILineInfoSpecifier Specifier = DILineInfoSpecifier());
+  DILineInfo getLineInfoForAddress(uint64_t Address,
+      DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+  DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
+      DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+  DIInliningInfo getInliningInfoForAddress(uint64_t Address,
+      DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
 
   virtual bool isLittleEndian() const = 0;
-  virtual const RelocAddrMap &infoRelocMap() const = 0;
-  virtual const RelocAddrMap &lineRelocMap() const = 0;
-  virtual StringRef getInfoSection() = 0;
+  virtual uint8_t getAddressSize() const = 0;
+  virtual const Section &getInfoSection() = 0;
+  typedef MapVector<object::SectionRef, Section,
+                    std::map<object::SectionRef, unsigned> > TypeSectionMap;
+  virtual const TypeSectionMap &getTypesSections() = 0;
   virtual StringRef getAbbrevSection() = 0;
+  virtual const Section &getLocSection() = 0;
+  virtual const Section &getLocDWOSection() = 0;
   virtual StringRef getARangeSection() = 0;
-  virtual StringRef getLineSection() = 0;
+  virtual StringRef getDebugFrameSection() = 0;
+  virtual const Section &getLineSection() = 0;
+  virtual const Section &getLineDWOSection() = 0;
   virtual StringRef getStringSection() = 0;
   virtual StringRef getRangeSection() = 0;
+  virtual StringRef getPubNamesSection() = 0;
+  virtual StringRef getPubTypesSection() = 0;
+  virtual StringRef getGnuPubNamesSection() = 0;
+  virtual StringRef getGnuPubTypesSection() = 0;
 
   // Sections for DWARF5 split dwarf proposal.
-  virtual StringRef getInfoDWOSection() = 0;
+  virtual const Section &getInfoDWOSection() = 0;
+  virtual const TypeSectionMap &getTypesDWOSections() = 0;
   virtual StringRef getAbbrevDWOSection() = 0;
   virtual StringRef getStringDWOSection() = 0;
   virtual StringRef getStringOffsetDWOSection() = 0;
   virtual StringRef getRangeDWOSection() = 0;
   virtual StringRef getAddrSection() = 0;
-  virtual const RelocAddrMap &infoDWORelocMap() const = 0;
 
   static bool isSupportedVersion(unsigned version) {
-    return version == 2 || version == 3;
+    return version == 2 || version == 3 || version == 4;
   }
 private:
   /// Return the compile unit that includes an offset (relative to .debug_info).
@@ -132,50 +215,68 @@ private:
 class DWARFContextInMemory : public DWARFContext {
   virtual void anchor();
   bool IsLittleEndian;
-  RelocAddrMap InfoRelocMap;
-  RelocAddrMap LineRelocMap;
-  StringRef InfoSection;
+  uint8_t AddressSize;
+  Section InfoSection;
+  TypeSectionMap TypesSections;
   StringRef AbbrevSection;
+  Section LocSection;
+  Section LocDWOSection;
   StringRef ARangeSection;
-  StringRef LineSection;
+  StringRef DebugFrameSection;
+  Section LineSection;
+  Section LineDWOSection;
   StringRef StringSection;
   StringRef RangeSection;
+  StringRef PubNamesSection;
+  StringRef PubTypesSection;
+  StringRef GnuPubNamesSection;
+  StringRef GnuPubTypesSection;
 
   // Sections for DWARF5 split dwarf proposal.
-  RelocAddrMap InfoDWORelocMap;
-  StringRef InfoDWOSection;
+  Section InfoDWOSection;
+  TypeSectionMap TypesDWOSections;
   StringRef AbbrevDWOSection;
   StringRef StringDWOSection;
   StringRef StringOffsetDWOSection;
   StringRef RangeDWOSection;
   StringRef AddrSection;
 
+  SmallVector<SmallString<32>, 4> UncompressedSections;
+
 public:
-  DWARFContextInMemory(object::ObjectFile *);
-  virtual bool isLittleEndian() const { return IsLittleEndian; }
-  virtual const RelocAddrMap &infoRelocMap() const { return InfoRelocMap; }
-  virtual const RelocAddrMap &lineRelocMap() const { return LineRelocMap; }
-  virtual StringRef getInfoSection() { return InfoSection; }
-  virtual StringRef getAbbrevSection() { return AbbrevSection; }
-  virtual StringRef getARangeSection() { return ARangeSection; }
-  virtual StringRef getLineSection() { return LineSection; }
-  virtual StringRef getStringSection() { return StringSection; }
-  virtual StringRef getRangeSection() { return RangeSection; }
+  DWARFContextInMemory(object::ObjectFile &);
+  bool isLittleEndian() const override { return IsLittleEndian; }
+  uint8_t getAddressSize() const override { return AddressSize; }
+  const Section &getInfoSection() override { return InfoSection; }
+  const TypeSectionMap &getTypesSections() override { return TypesSections; }
+  StringRef getAbbrevSection() override { return AbbrevSection; }
+  const Section &getLocSection() override { return LocSection; }
+  const Section &getLocDWOSection() override { return LocDWOSection; }
+  StringRef getARangeSection() override { return ARangeSection; }
+  StringRef getDebugFrameSection() override { return DebugFrameSection; }
+  const Section &getLineSection() override { return LineSection; }
+  const Section &getLineDWOSection() override { return LineDWOSection; }
+  StringRef getStringSection() override { return StringSection; }
+  StringRef getRangeSection() override { return RangeSection; }
+  StringRef getPubNamesSection() override { return PubNamesSection; }
+  StringRef getPubTypesSection() override { return PubTypesSection; }
+  StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; }
+  StringRef getGnuPubTypesSection() override { return GnuPubTypesSection; }
 
   // Sections for DWARF5 split dwarf proposal.
-  virtual StringRef getInfoDWOSection() { return InfoDWOSection; }
-  virtual StringRef getAbbrevDWOSection() { return AbbrevDWOSection; }
-  virtual StringRef getStringDWOSection() { return StringDWOSection; }
-  virtual StringRef getStringOffsetDWOSection() {
+  const Section &getInfoDWOSection() override { return InfoDWOSection; }
+  const TypeSectionMap &getTypesDWOSections() override {
+    return TypesDWOSections;
+  }
+  StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; }
+  StringRef getStringDWOSection() override { return StringDWOSection; }
+  StringRef getStringOffsetDWOSection() override {
     return StringOffsetDWOSection;
   }
-  virtual StringRef getRangeDWOSection() { return RangeDWOSection; }
-  virtual StringRef getAddrSection() {
+  StringRef getRangeDWOSection() override { return RangeDWOSection; }
+  StringRef getAddrSection() override {
     return AddrSection;
   }
-  virtual const RelocAddrMap &infoDWORelocMap() const {
-    return InfoDWORelocMap;
-  }
 };
 
 }