]> granicus.if.org Git - llvm/commitdiff
Use delegation instead of inheritance.
authorRafael Espindola <rafael.espindola@gmail.com>
Wed, 19 Jul 2017 22:27:28 +0000 (22:27 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Wed, 19 Jul 2017 22:27:28 +0000 (22:27 +0000)
This changes DwarfContext to delegate to DwarfObject instead of having
pure virtual methods.

With this DwarfContextInMemory is replaced with an implementation of
DwarfObject that is local to a .cpp file.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308543 91177308-0d34-0410-b5e6-96231b3b80d8

20 files changed:
include/llvm/DebugInfo/DWARF/DWARFContext.h
include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
include/llvm/DebugInfo/DWARF/DWARFObject.h [new file with mode: 0644]
include/llvm/DebugInfo/DWARF/DWARFSection.h
include/llvm/DebugInfo/DWARF/DWARFUnit.h
lib/DebugInfo/DWARF/DWARFContext.cpp
lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
lib/DebugInfo/DWARF/DWARFUnit.cpp
lib/DebugInfo/DWARF/DWARFVerifier.cpp
lib/DebugInfo/Symbolize/Symbolize.cpp
tools/dsymutil/DwarfLinker.cpp
tools/llvm-dwarfdump/llvm-dwarfdump.cpp
tools/llvm-objdump/MachODump.cpp
tools/llvm-objdump/llvm-objdump.cpp
tools/llvm-rtdyld/llvm-rtdyld.cpp
tools/obj2yaml/dwarf2yaml.cpp
tools/obj2yaml/macho2yaml.cpp
tools/obj2yaml/obj2yaml.h
unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp

index ee2e805050c01422d973c27aeb3d50353c11d880..18908ae24fe062dcea2973aa07cd9d3f6af6c0d0 100644 (file)
@@ -26,6 +26,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
 #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
+#include "llvm/DebugInfo/DWARF/DWARFObject.h"
 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
@@ -45,10 +46,14 @@ class DataExtractor;
 class MemoryBuffer;
 class raw_ostream;
 
+/// Used as a return value for a error callback passed to DWARF context.
+/// Callback should return Halt if client application wants to stop
+/// object parsing, or should return Continue otherwise.
+enum class ErrorPolicy { Halt, Continue };
+
 /// DWARFContext
 /// This data structure is the top level entity that deals with dwarf debug
-/// information parsing. The actual data is supplied through pure virtual
-/// methods that a concrete implementation provides.
+/// information parsing. The actual data is supplied through DWARFObj.
 class DWARFContext : public DIContext {
   DWARFUnitSection<DWARFCompileUnit> CUs;
   std::deque<DWARFUnitSection<DWARFTypeUnit>> TUs;
@@ -95,11 +100,17 @@ class DWARFContext : public DIContext {
   /// and store them in DWOTUs.
   void parseDWOTypeUnits();
 
+protected:
+  std::unique_ptr<const DWARFObject> DObj;
+
 public:
-  DWARFContext() : DIContext(CK_DWARF) {}
+  DWARFContext(std::unique_ptr<const DWARFObject> DObj)
+      : DIContext(CK_DWARF), DObj(std::move(DObj)) {}
   DWARFContext(DWARFContext &) = delete;
   DWARFContext &operator=(DWARFContext &) = delete;
 
+  const DWARFObject &getDWARFObj() const { return *DObj; }
+
   static bool classof(const DIContext *DICtx) {
     return DICtx->getKind() == CK_DWARF;
   }
@@ -222,55 +233,24 @@ public:
   DIInliningInfo getInliningInfoForAddress(uint64_t Address,
       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
 
-  virtual StringRef getFileName() const = 0;
-  virtual bool isLittleEndian() const = 0;
-  virtual uint8_t getAddressSize() const = 0;
-  virtual const DWARFSection &getInfoSection() = 0;
-  virtual void forEachTypesSections(function_ref<void(DWARFSection &)> F) = 0;
-  virtual StringRef getAbbrevSection() = 0;
-  virtual const DWARFSection &getLocSection() = 0;
-  virtual StringRef getARangeSection() = 0;
-  virtual StringRef getDebugFrameSection() = 0;
-  virtual StringRef getEHFrameSection() = 0;
-  virtual const DWARFSection &getLineSection() = 0;
-  virtual StringRef getStringSection() = 0;
-  virtual const DWARFSection& getRangeSection() = 0;
-  virtual StringRef getMacinfoSection() = 0;
-  virtual StringRef getPubNamesSection() = 0;
-  virtual StringRef getPubTypesSection() = 0;
-  virtual StringRef getGnuPubNamesSection() = 0;
-  virtual StringRef getGnuPubTypesSection() = 0;
-
-  /// DWARF v5
-  /// @{
-  virtual const DWARFSection &getStringOffsetSection() = 0;
-  /// @}
-
-  // Sections for DWARF5 split dwarf proposal.
-  virtual const DWARFSection &getInfoDWOSection() = 0;
-  virtual void
-  forEachTypesDWOSections(function_ref<void(DWARFSection &)> F) = 0;
-  virtual StringRef getAbbrevDWOSection() = 0;
-  virtual const DWARFSection &getLineDWOSection() = 0;
-  virtual const DWARFSection &getLocDWOSection() = 0;
-  virtual StringRef getStringDWOSection() = 0;
-  virtual const DWARFSection &getStringOffsetDWOSection() = 0;
-  virtual const DWARFSection &getRangeDWOSection() = 0;
-  virtual const DWARFSection &getAddrSection() = 0;
-  virtual const DWARFSection& getAppleNamesSection() = 0;
-  virtual const DWARFSection& getAppleTypesSection() = 0;
-  virtual const DWARFSection& getAppleNamespacesSection() = 0;
-  virtual const DWARFSection& getAppleObjCSection() = 0;
-  virtual StringRef getCUIndexSection() = 0;
-  virtual StringRef getGdbIndexSection() = 0;
-  virtual StringRef getTUIndexSection() = 0;
-
+  bool isLittleEndian() const { return DObj->isLittleEndian(); }
   static bool isSupportedVersion(unsigned version) {
     return version == 2 || version == 3 || version == 4 || version == 5;
   }
 
   std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath);
 
+  /// Function used to handle default error reporting policy. Prints a error
+  /// message and returns Continue, so DWARF context ignores the error.
+  static ErrorPolicy defaultErrorHandler(Error E);
+  static std::unique_ptr<DWARFContext>
+  create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
+         function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler);
+
+  static std::unique_ptr<DWARFContext>
+  create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
+         uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost);
+
 private:
   /// Return the compile unit that includes an offset (relative to .debug_info).
   DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
@@ -280,142 +260,6 @@ private:
   DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
 };
 
-/// Used as a return value for a error callback passed to DWARF context.
-/// Callback should return Halt if client application wants to stop
-/// object parsing, or should return Continue otherwise.
-enum class ErrorPolicy { Halt, Continue };
-
-/// DWARFContextInMemory is the simplest possible implementation of a
-/// DWARFContext. It assumes all content is available in memory and stores
-/// pointers to it.
-class DWARFContextInMemory : public DWARFContext {
-  virtual void anchor();
-
-  using TypeSectionMap = MapVector<object::SectionRef, DWARFSection,
-                                   std::map<object::SectionRef, unsigned>>;
-
-  StringRef FileName;
-  bool IsLittleEndian;
-  uint8_t AddressSize;
-  DWARFSection InfoSection;
-  TypeSectionMap TypesSections;
-  StringRef AbbrevSection;
-  DWARFSection LocSection;
-  StringRef ARangeSection;
-  StringRef DebugFrameSection;
-  StringRef EHFrameSection;
-  DWARFSection LineSection;
-  StringRef StringSection;
-  DWARFSection RangeSection;
-  StringRef MacinfoSection;
-  StringRef PubNamesSection;
-  StringRef PubTypesSection;
-  StringRef GnuPubNamesSection;
-  StringRef GnuPubTypesSection;
-
-  /// DWARF v5
-  /// @{
-  DWARFSection StringOffsetSection;
-  /// @}
-
-  // Sections for DWARF5 split dwarf proposal.
-  DWARFSection InfoDWOSection;
-  TypeSectionMap TypesDWOSections;
-  StringRef AbbrevDWOSection;
-  DWARFSection LineDWOSection;
-  DWARFSection LocDWOSection;
-  StringRef StringDWOSection;
-  DWARFSection StringOffsetDWOSection;
-  DWARFSection RangeDWOSection;
-  DWARFSection AddrSection;
-  DWARFSection AppleNamesSection;
-  DWARFSection AppleTypesSection;
-  DWARFSection AppleNamespacesSection;
-  DWARFSection AppleObjCSection;
-  StringRef CUIndexSection;
-  StringRef GdbIndexSection;
-  StringRef TUIndexSection;
-
-  SmallVector<SmallString<32>, 4> UncompressedSections;
-
-  DWARFSection *mapNameToDWARFSection(StringRef Name);
-  StringRef *mapSectionToMember(StringRef Name);
-
-  /// If Sec is compressed section, decompresses and updates its contents
-  /// provided by Data. Otherwise leaves it unchanged.
-  Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
-                        StringRef &Data);
-
-  /// Function used to handle default error reporting policy. Prints a error
-  /// message and returns Continue, so DWARF context ignores the error.
-  static ErrorPolicy defaultErrorHandler(Error E);
-
-public:
-  DWARFContextInMemory(
-      const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
-      function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler);
-
-  DWARFContextInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
-                       uint8_t AddrSize,
-                       bool isLittleEndian = sys::IsLittleEndianHost);
-
-  StringRef getFileName() const override { return FileName; }
-  bool isLittleEndian() const override { return IsLittleEndian; }
-  uint8_t getAddressSize() const override { return AddressSize; }
-  const DWARFSection &getInfoSection() override { return InfoSection; }
-  void forEachTypesSections(function_ref<void(DWARFSection &)> F) override {
-    for (auto &P : TypesSections)
-      F(P.second);
-  }
-  StringRef getAbbrevSection() override { return AbbrevSection; }
-  const DWARFSection &getLocSection() override { return LocSection; }
-  StringRef getARangeSection() override { return ARangeSection; }
-  StringRef getDebugFrameSection() override { return DebugFrameSection; }
-  StringRef getEHFrameSection() override { return EHFrameSection; }
-  const DWARFSection &getLineSection() override { return LineSection; }
-  StringRef getStringSection() override { return StringSection; }
-  const DWARFSection &getRangeSection() override { return RangeSection; }
-  StringRef getMacinfoSection() override { return MacinfoSection; }
-  StringRef getPubNamesSection() override { return PubNamesSection; }
-  StringRef getPubTypesSection() override { return PubTypesSection; }
-  StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; }
-  StringRef getGnuPubTypesSection() override { return GnuPubTypesSection; }
-  const DWARFSection& getAppleNamesSection() override { return AppleNamesSection; }
-  const DWARFSection& getAppleTypesSection() override { return AppleTypesSection; }
-  const DWARFSection& getAppleNamespacesSection() override { return AppleNamespacesSection; }
-  const DWARFSection& getAppleObjCSection() override { return AppleObjCSection; }
-
-  // DWARF v5
-  const DWARFSection &getStringOffsetSection() override {
-    return StringOffsetSection;
-  }
-
-  // Sections for DWARF5 split dwarf proposal.
-  const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; }
-
-  void forEachTypesDWOSections(function_ref<void(DWARFSection &)> F) override {
-    for (auto &P : TypesDWOSections)
-      F(P.second);
-  }
-
-  StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; }
-  const DWARFSection &getLineDWOSection() override { return LineDWOSection; }
-  const DWARFSection &getLocDWOSection() override { return LocDWOSection; }
-  StringRef getStringDWOSection() override { return StringDWOSection; }
-
-  const DWARFSection &getStringOffsetDWOSection() override {
-    return StringOffsetDWOSection;
-  }
-
-  const DWARFSection &getRangeDWOSection() override { return RangeDWOSection; }
-
-  const DWARFSection &getAddrSection() override { return AddrSection; }
-
-  StringRef getCUIndexSection() override { return CUIndexSection; }
-  StringRef getGdbIndexSection() override { return GdbIndexSection; }
-  StringRef getTUIndexSection() override { return TUIndexSection; }
-};
-
 } // end namespace llvm
 
 #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
index ef4360f6662185149fabe8b1fc78b95a869ad32e..a379d9c85b3855560bdcbe7e6c5af40f76ca5cbb 100644 (file)
 #include "llvm/Support/DataExtractor.h"
 
 namespace llvm {
+class DWARFObject;
 
 /// A DataExtractor (typically for an in-memory copy of an object-file section)
 /// plus a relocation map for that section, if there is one.
 class DWARFDataExtractor : public DataExtractor {
-  const RelocAddrMap *RelocMap = nullptr;
+  const DWARFObject *Obj = nullptr;
+  const DWARFSection *Section = nullptr;
+
 public:
   /// Constructor for the normal case of extracting data from a DWARF section.
   /// The DWARFSection's lifetime must be at least as long as the extractor's.
-  DWARFDataExtractor(const DWARFSection &Section, bool IsLittleEndian,
-                     uint8_t AddressSize)
-    : DataExtractor(Section.Data, IsLittleEndian, AddressSize),
-      RelocMap(&Section.Relocs) {}
+  DWARFDataExtractor(const DWARFObject &Obj, const DWARFSection &Section,
+                     bool IsLittleEndian, uint8_t AddressSize)
+      : DataExtractor(Section.Data, IsLittleEndian, AddressSize), Obj(&Obj),
+        Section(&Section) {}
 
   /// Constructor for cases when there are no relocations.
   DWARFDataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize)
diff --git a/include/llvm/DebugInfo/DWARF/DWARFObject.h b/include/llvm/DebugInfo/DWARF/DWARFObject.h
new file mode 100644 (file)
index 0000000..5e43d8c
--- /dev/null
@@ -0,0 +1,75 @@
+//===- DWARFObject.h --------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===-----------------------------------------------------------------------===/
+
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFOBJECT_H
+#define LLVM_DEBUGINFO_DWARF_DWARFOBJECT_H
+
+#include "llvm/DebugInfo/DWARF/DWARFSection.h"
+
+namespace llvm {
+// This is responsible for low level access to the object file. It
+// knows how to find the required sections and compute relocated
+// values.
+// The default implementations of the get<Section> methods return dummy values.
+// This is to allow clients that only need some of those to implement just the
+// ones they need. We can't use unreachable for as many cases because the parser
+// implementation is eager and will call some of these methods even if the
+// result is not used.
+class DWARFObject {
+  DWARFSection Dummy;
+
+public:
+  virtual ~DWARFObject() = default;
+  virtual StringRef getFileName() const { llvm_unreachable("unimplemented"); }
+  virtual bool isLittleEndian() const = 0;
+  virtual uint8_t getAddressSize() const { llvm_unreachable("unimplemented"); }
+  virtual const DWARFSection &getInfoSection() const { return Dummy; }
+  virtual void
+  forEachTypesSections(function_ref<void(const DWARFSection &)> F) const {}
+  virtual StringRef getAbbrevSection() const { return ""; }
+  virtual const DWARFSection &getLocSection() const { return Dummy; }
+  virtual StringRef getARangeSection() const { return ""; }
+  virtual StringRef getDebugFrameSection() const { return ""; }
+  virtual StringRef getEHFrameSection() const { return ""; }
+  virtual const DWARFSection &getLineSection() const { return Dummy; }
+  virtual StringRef getStringSection() const { return ""; }
+  virtual const DWARFSection &getRangeSection() const { return Dummy; }
+  virtual StringRef getMacinfoSection() const { return ""; }
+  virtual StringRef getPubNamesSection() const { return ""; }
+  virtual StringRef getPubTypesSection() const { return ""; }
+  virtual StringRef getGnuPubNamesSection() const { return ""; }
+  virtual StringRef getGnuPubTypesSection() const { return ""; }
+  virtual const DWARFSection &getStringOffsetSection() const { return Dummy; }
+  virtual const DWARFSection &getInfoDWOSection() const { return Dummy; }
+  virtual void
+  forEachTypesDWOSections(function_ref<void(const DWARFSection &)> F) const {}
+  virtual StringRef getAbbrevDWOSection() const { return ""; }
+  virtual const DWARFSection &getLineDWOSection() const { return Dummy; }
+  virtual const DWARFSection &getLocDWOSection() const { return Dummy; }
+  virtual StringRef getStringDWOSection() const { return ""; }
+  virtual const DWARFSection &getStringOffsetDWOSection() const {
+    return Dummy;
+  }
+  virtual const DWARFSection &getRangeDWOSection() const { return Dummy; }
+  virtual const DWARFSection &getAddrSection() const { return Dummy; }
+  virtual const DWARFSection &getAppleNamesSection() const { return Dummy; }
+  virtual const DWARFSection &getAppleTypesSection() const { return Dummy; }
+  virtual const DWARFSection &getAppleNamespacesSection() const {
+    return Dummy;
+  }
+  virtual const DWARFSection &getAppleObjCSection() const { return Dummy; }
+  virtual StringRef getCUIndexSection() const { return ""; }
+  virtual StringRef getGdbIndexSection() const { return ""; }
+  virtual StringRef getTUIndexSection() const { return ""; }
+  virtual Optional<RelocAddrEntry> find(const DWARFSection &Sec,
+                                        uint64_t Pos) const = 0;
+};
+
+} // namespace llvm
+#endif
index 2b8a53a4c93ea661d00470d0a74db3dccc598b10..43df3b36809b89d5b380feebf1a4b2db589e2137 100644 (file)
@@ -17,6 +17,9 @@ namespace llvm {
 
 struct DWARFSection {
   StringRef Data;
+};
+
+struct DWARFSectionMap final : public DWARFSection {
   RelocAddrMap Relocs;
 };
 
index 056c1b77c65d1fdbc5a4d58cbc2b4676d307c698..b4e3f008f31cb28266f6bdc25dfeb861f1cc716d 100644 (file)
@@ -197,19 +197,12 @@ public:
   bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
   bool getStringOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
 
-  DWARFDataExtractor getDebugInfoExtractor() const {
-    return DWARFDataExtractor(InfoSection, isLittleEndian,
-                              getAddressByteSize());
-  }
+  DWARFDataExtractor getDebugInfoExtractor() const;
 
   DataExtractor getStringExtractor() const {
     return DataExtractor(StringSection, false, 0);
   }
 
-  const RelocAddrMap *getRelocMap() const { return &InfoSection.Relocs; }
-  const RelocAddrMap &getStringOffsetsRelocMap() const {
-    return StringOffsetSection.Relocs;
-  }
 
   bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
 
index 495e09fbae355e5d48bec8dfb29ac759d363bb10..c91bd27c91a6df1d76faa4d6ae2fbbbfc824ab88 100644 (file)
@@ -60,9 +60,10 @@ using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
 using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
 
 static void dumpAccelSection(raw_ostream &OS, StringRef Name,
-                             const DWARFSection& Section, StringRef StringSection,
-                             bool LittleEndian) {
-  DWARFDataExtractor AccelSection(Section, LittleEndian, 0);
+                             const DWARFObject &Obj,
+                             const DWARFSection &Section,
+                             StringRef StringSection, bool LittleEndian) {
+  DWARFDataExtractor AccelSection(Obj, Section, LittleEndian, 0);
   DataExtractor StrData(StringSection, LittleEndian, 0);
   OS << "\n." << Name << " contents:\n";
   DWARFAcceleratorTable Accel(AccelSection, StrData);
@@ -73,9 +74,10 @@ static void dumpAccelSection(raw_ostream &OS, StringRef Name,
 
 static void
 dumpDWARFv5StringOffsetsSection(raw_ostream &OS, StringRef SectionName,
+                                const DWARFObject &Obj,
                                 const DWARFSection &StringOffsetsSection,
                                 StringRef StringSection, bool LittleEndian) {
-  DWARFDataExtractor StrOffsetExt(StringOffsetsSection, LittleEndian, 0);
+  DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
   uint32_t Offset = 0;
   uint64_t SectionSize = StringOffsetsSection.Data.size();
 
@@ -153,6 +155,7 @@ dumpDWARFv5StringOffsetsSection(raw_ostream &OS, StringRef SectionName,
 // monolithic series of string offsets, as generated by the pre-DWARF v5
 // implementation of split DWARF.
 static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
+                                     const DWARFObject &Obj,
                                      const DWARFSection &StringOffsetsSection,
                                      StringRef StringSection, bool LittleEndian,
                                      unsigned MaxVersion) {
@@ -163,7 +166,7 @@ static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
   // we assume that the section is formatted like a DWARF v5 string offsets
   // section.
   if (MaxVersion >= 5)
-    dumpDWARFv5StringOffsetsSection(OS, SectionName, StringOffsetsSection,
+    dumpDWARFv5StringOffsetsSection(OS, SectionName, Obj, StringOffsetsSection,
                                     StringSection, LittleEndian);
   else {
     DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
@@ -259,7 +262,7 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
   uint32_t offset = 0;
   if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
     OS << "\n.debug_aranges contents:\n";
-    DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
+    DataExtractor arangesData(DObj->getARangeSection(), isLittleEndian(), 0);
     DWARFDebugArangeSet set;
     while (set.extract(arangesData, &offset))
       set.dump(OS);
@@ -274,8 +277,8 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
       if (!CUDIE)
         continue;
       if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list))) {
-        DWARFDataExtractor lineData(getLineSection(), isLittleEndian(),
-                                    savedAddressByteSize);
+        DWARFDataExtractor lineData(*DObj, DObj->getLineSection(),
+                                    isLittleEndian(), savedAddressByteSize);
         DWARFDebugLine::LineTable LineTable;
         uint32_t Offset = *StmtOffset;
         LineTable.parse(lineData, &Offset);
@@ -297,8 +300,8 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
   if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
     OS << "\n.debug_line.dwo contents:\n";
     unsigned stmtOffset = 0;
-    DWARFDataExtractor lineData(getLineDWOSection(), isLittleEndian(),
-                                savedAddressByteSize);
+    DWARFDataExtractor lineData(*DObj, DObj->getLineDWOSection(),
+                                isLittleEndian(), savedAddressByteSize);
     DWARFDebugLine::LineTable LineTable;
     while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
       LineTable.dump(OS);
@@ -308,7 +311,7 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
 
   if (DumpType == DIDT_All || DumpType == DIDT_Str) {
     OS << "\n.debug_str contents:\n";
-    DataExtractor strData(getStringSection(), isLittleEndian(), 0);
+    DataExtractor strData(DObj->getStringSection(), isLittleEndian(), 0);
     offset = 0;
     uint32_t strOffset = 0;
     while (const char *s = strData.getCStr(&offset)) {
@@ -318,9 +321,9 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
   }
 
   if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
-      !getStringDWOSection().empty()) {
+      !DObj->getStringDWOSection().empty()) {
     OS << "\n.debug_str.dwo contents:\n";
-    DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
+    DataExtractor strDWOData(DObj->getStringDWOSection(), isLittleEndian(), 0);
     offset = 0;
     uint32_t strDWOOffset = 0;
     while (const char *s = strDWOData.getCStr(&offset)) {
@@ -335,8 +338,8 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
     // sizes, but for simplicity we just use the address byte size of the last
     // compile unit (there is no easy and fast way to associate address range
     // list and the compile unit it describes).
-    DWARFDataExtractor rangesData(getRangeSection(), isLittleEndian(),
-                                  savedAddressByteSize);
+    DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(),
+                                  isLittleEndian(), savedAddressByteSize);
     offset = 0;
     DWARFDebugRangeList rangeList;
     while (rangeList.extract(rangesData, &offset))
@@ -344,55 +347,56 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
   }
 
   if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
-    DWARFDebugPubTable(getPubNamesSection(), isLittleEndian(), false)
+    DWARFDebugPubTable(DObj->getPubNamesSection(), isLittleEndian(), false)
         .dump("debug_pubnames", OS);
 
   if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
-    DWARFDebugPubTable(getPubTypesSection(), isLittleEndian(), false)
+    DWARFDebugPubTable(DObj->getPubTypesSection(), isLittleEndian(), false)
         .dump("debug_pubtypes", OS);
 
   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
-    DWARFDebugPubTable(getGnuPubNamesSection(), isLittleEndian(),
+    DWARFDebugPubTable(DObj->getGnuPubNamesSection(), isLittleEndian(),
                        true /* GnuStyle */)
         .dump("debug_gnu_pubnames", OS);
 
   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
-    DWARFDebugPubTable(getGnuPubTypesSection(), isLittleEndian(),
+    DWARFDebugPubTable(DObj->getGnuPubTypesSection(), isLittleEndian(),
                        true /* GnuStyle */)
         .dump("debug_gnu_pubtypes", OS);
 
   if (DumpType == DIDT_All || DumpType == DIDT_StrOffsets)
-    dumpStringOffsetsSection(OS, "debug_str_offsets", getStringOffsetSection(),
-                             getStringSection(), isLittleEndian(),
-                             getMaxVersion());
+    dumpStringOffsetsSection(
+        OS, "debug_str_offsets", *DObj, DObj->getStringOffsetSection(),
+        DObj->getStringSection(), isLittleEndian(), getMaxVersion());
 
   if (DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) {
-    dumpStringOffsetsSection(OS, "debug_str_offsets.dwo",
-                             getStringOffsetDWOSection(), getStringDWOSection(),
-                             isLittleEndian(), getMaxVersion());
+    dumpStringOffsetsSection(
+        OS, "debug_str_offsets.dwo", *DObj, DObj->getStringOffsetDWOSection(),
+        DObj->getStringDWOSection(), isLittleEndian(), getMaxVersion());
   }
 
   if ((DumpType == DIDT_All || DumpType == DIDT_GdbIndex) &&
-      !getGdbIndexSection().empty()) {
+      !DObj->getGdbIndexSection().empty()) {
     OS << "\n.gnu_index contents:\n";
     getGdbIndex().dump(OS);
   }
 
   if (DumpType == DIDT_All || DumpType == DIDT_AppleNames)
-    dumpAccelSection(OS, "apple_names", getAppleNamesSection(),
-                     getStringSection(), isLittleEndian());
+    dumpAccelSection(OS, "apple_names", *DObj, DObj->getAppleNamesSection(),
+                     DObj->getStringSection(), isLittleEndian());
 
   if (DumpType == DIDT_All || DumpType == DIDT_AppleTypes)
-    dumpAccelSection(OS, "apple_types", getAppleTypesSection(),
-                     getStringSection(), isLittleEndian());
+    dumpAccelSection(OS, "apple_types", *DObj, DObj->getAppleTypesSection(),
+                     DObj->getStringSection(), isLittleEndian());
 
   if (DumpType == DIDT_All || DumpType == DIDT_AppleNamespaces)
-    dumpAccelSection(OS, "apple_namespaces", getAppleNamespacesSection(),
-                     getStringSection(), isLittleEndian());
+    dumpAccelSection(OS, "apple_namespaces", *DObj,
+                     DObj->getAppleNamespacesSection(),
+                     DObj->getStringSection(), isLittleEndian());
 
   if (DumpType == DIDT_All || DumpType == DIDT_AppleObjC)
-    dumpAccelSection(OS, "apple_objc", getAppleObjCSection(),
-                     getStringSection(), isLittleEndian());
+    dumpAccelSection(OS, "apple_objc", *DObj, DObj->getAppleObjCSection(),
+                     DObj->getStringSection(), isLittleEndian());
 }
 
 DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
@@ -433,7 +437,7 @@ const DWARFUnitIndex &DWARFContext::getCUIndex() {
   if (CUIndex)
     return *CUIndex;
 
-  DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(), 0);
+  DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0);
 
   CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
   CUIndex->parse(CUIndexData);
@@ -444,7 +448,7 @@ const DWARFUnitIndex &DWARFContext::getTUIndex() {
   if (TUIndex)
     return *TUIndex;
 
-  DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(), 0);
+  DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0);
 
   TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
   TUIndex->parse(TUIndexData);
@@ -455,7 +459,7 @@ DWARFGdbIndex &DWARFContext::getGdbIndex() {
   if (GdbIndex)
     return *GdbIndex;
 
-  DataExtractor GdbIndexData(getGdbIndexSection(), true /*LE*/, 0);
+  DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0);
   GdbIndex = llvm::make_unique<DWARFGdbIndex>();
   GdbIndex->parse(GdbIndexData);
   return *GdbIndex;
@@ -465,7 +469,7 @@ const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
   if (Abbrev)
     return Abbrev.get();
 
-  DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
+  DataExtractor abbrData(DObj->getAbbrevSection(), isLittleEndian(), 0);
 
   Abbrev.reset(new DWARFDebugAbbrev());
   Abbrev->extract(abbrData);
@@ -476,7 +480,7 @@ const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
   if (AbbrevDWO)
     return AbbrevDWO.get();
 
-  DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
+  DataExtractor abbrData(DObj->getAbbrevDWOSection(), isLittleEndian(), 0);
   AbbrevDWO.reset(new DWARFDebugAbbrev());
   AbbrevDWO->extract(abbrData);
   return AbbrevDWO.get();
@@ -489,7 +493,7 @@ const DWARFDebugLoc *DWARFContext::getDebugLoc() {
   Loc.reset(new DWARFDebugLoc);
   // assume all compile units have the same address byte size
   if (getNumCompileUnits()) {
-    DWARFDataExtractor LocData(getLocSection(), isLittleEndian(),
+    DWARFDataExtractor LocData(*DObj, DObj->getLocSection(), isLittleEndian(),
                                getCompileUnitAtIndex(0)->getAddressByteSize());
     Loc->parse(LocData);
   }
@@ -500,7 +504,7 @@ const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
   if (LocDWO)
     return LocDWO.get();
 
-  DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
+  DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(), 0);
   LocDWO.reset(new DWARFDebugLocDWO());
   LocDWO->parse(LocData);
   return LocDWO.get();
@@ -528,8 +532,8 @@ const DWARFDebugFrame *DWARFContext::getDebugFrame() {
   // provides this information). This problem is fixed in DWARFv4
   // See this dwarf-discuss discussion for more details:
   // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
-  DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
-                               getAddressSize());
+  DataExtractor debugFrameData(DObj->getDebugFrameSection(), isLittleEndian(),
+                               DObj->getAddressSize());
   DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
   DebugFrame->parse(debugFrameData);
   return DebugFrame.get();
@@ -539,8 +543,8 @@ const DWARFDebugFrame *DWARFContext::getEHFrame() {
   if (EHFrame)
     return EHFrame.get();
 
-  DataExtractor debugFrameData(getEHFrameSection(), isLittleEndian(),
-                               getAddressSize());
+  DataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
+                               DObj->getAddressSize());
   DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
   DebugFrame->parse(debugFrameData);
   return DebugFrame.get();
@@ -550,7 +554,7 @@ const DWARFDebugMacro *DWARFContext::getDebugMacro() {
   if (Macro)
     return Macro.get();
 
-  DataExtractor MacinfoData(getMacinfoSection(), isLittleEndian(), 0);
+  DataExtractor MacinfoData(DObj->getMacinfoSection(), isLittleEndian(), 0);
   Macro.reset(new DWARFDebugMacro());
   Macro->parse(MacinfoData);
   return Macro.get();
@@ -579,32 +583,32 @@ DWARFContext::getLineTableForUnit(DWARFUnit *U) {
     return nullptr;  
 
   // We have to parse it first.
-  DWARFDataExtractor lineData(U->getLineSection(), isLittleEndian(),
+  DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(),
                               U->getAddressByteSize());
   return Line->getOrParseLineTable(lineData, stmtOffset);
 }
 
 void DWARFContext::parseCompileUnits() {
-  CUs.parse(*this, getInfoSection());
+  CUs.parse(*this, DObj->getInfoSection());
 }
 
 void DWARFContext::parseTypeUnits() {
   if (!TUs.empty())
     return;
-  forEachTypesSections([&](const DWARFSection &S) {
+  DObj->forEachTypesSections([&](const DWARFSection &S) {
     TUs.emplace_back();
     TUs.back().parse(*this, S);
   });
 }
 
 void DWARFContext::parseDWOCompileUnits() {
-  DWOCUs.parseDWO(*this, getInfoDWOSection());
+  DWOCUs.parseDWO(*this, DObj->getInfoDWOSection());
 }
 
 void DWARFContext::parseDWOTypeUnits() {
   if (!DWOTUs.empty())
     return;
-  forEachTypesDWOSections([&](const DWARFSection &S) {
+  DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
     DWOTUs.emplace_back();
     DWOTUs.back().parseDWO(*this, S);
   });
@@ -779,6 +783,20 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address,
   return InliningInfo;
 }
 
+/// DWARFContextInMemory is the simplest possible implementation of a
+/// DWARFContext. It assumes all content is available in memory and stores
+/// pointers to it.
+class DWARFContextInMemory : public DWARFContext {
+public:
+  DWARFContextInMemory(
+      const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
+      function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler);
+
+  DWARFContextInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
+                       uint8_t AddrSize,
+                       bool isLittleEndian = sys::IsLittleEndianHost);
+};
+
 std::shared_ptr<DWARFContext>
 DWARFContext::getDWOContext(StringRef AbsolutePath) {
   if (auto S = DWP.lock()) {
@@ -796,7 +814,7 @@ DWARFContext::getDWOContext(StringRef AbsolutePath) {
   SmallString<128> DWPName;
   Expected<OwningBinary<ObjectFile>> Obj = [&] {
     if (!CheckedForDWP) {
-      (getFileName() + ".dwp").toVector(DWPName);
+      (DObj->getFileName() + ".dwp").toVector(DWPName);
       auto Obj = object::ObjectFile::createObjectFile(DWPName);
       if (Obj) {
         Entry = &DWP;
@@ -820,7 +838,7 @@ DWARFContext::getDWOContext(StringRef AbsolutePath) {
 
   auto S = std::make_shared<DWOFile>();
   S->File = std::move(Obj.get());
-  S->Context = llvm::make_unique<DWARFContextInMemory>(*S->File.getBinary());
+  S->Context = DWARFContext::create(*S->File.getBinary());
   *Entry = S;
   auto *Ctxt = S->Context.get();
   return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
@@ -906,208 +924,355 @@ static bool isRelocScattered(const object::ObjectFile &Obj,
   return MachObj->isRelocationScattered(RelocInfo);
 }
 
-Error DWARFContextInMemory::maybeDecompress(const SectionRef &Sec,
-                                            StringRef Name, StringRef &Data) {
-  if (!Decompressor::isCompressed(Sec))
-    return Error::success();
+ErrorPolicy DWARFContext::defaultErrorHandler(Error E) {
+  errs() << "error: " + toString(std::move(E)) << '\n';
+  return ErrorPolicy::Continue;
+}
 
-  Expected<Decompressor> Decompressor =
-      Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
-  if (!Decompressor)
-    return Decompressor.takeError();
+class DWARFObjInMemory final : public DWARFObject {
+  bool IsLittleEndian;
+  uint8_t AddressSize;
+  StringRef FileName;
+
+  using TypeSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
+                                   std::map<object::SectionRef, unsigned>>;
+
+  TypeSectionMap TypesSections;
+  TypeSectionMap TypesDWOSections;
+
+  DWARFSectionMap InfoSection;
+  DWARFSectionMap LocSection;
+  DWARFSectionMap LineSection;
+  DWARFSectionMap RangeSection;
+  DWARFSectionMap StringOffsetSection;
+  DWARFSectionMap InfoDWOSection;
+  DWARFSectionMap LineDWOSection;
+  DWARFSectionMap LocDWOSection;
+  DWARFSectionMap StringOffsetDWOSection;
+  DWARFSectionMap RangeDWOSection;
+  DWARFSectionMap AddrSection;
+  DWARFSectionMap AppleNamesSection;
+  DWARFSectionMap AppleTypesSection;
+  DWARFSectionMap AppleNamespacesSection;
+  DWARFSectionMap AppleObjCSection;
+
+  DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
+    return StringSwitch<DWARFSectionMap *>(Name)
+        .Case("debug_info", &InfoSection)
+        .Case("debug_loc", &LocSection)
+        .Case("debug_line", &LineSection)
+        .Case("debug_str_offsets", &StringOffsetSection)
+        .Case("debug_ranges", &RangeSection)
+        .Case("debug_info.dwo", &InfoDWOSection)
+        .Case("debug_loc.dwo", &LocDWOSection)
+        .Case("debug_line.dwo", &LineDWOSection)
+        .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
+        .Case("debug_addr", &AddrSection)
+        .Case("apple_names", &AppleNamesSection)
+        .Case("apple_types", &AppleTypesSection)
+        .Case("apple_namespaces", &AppleNamespacesSection)
+        .Case("apple_namespac", &AppleNamespacesSection)
+        .Case("apple_objc", &AppleObjCSection)
+        .Default(nullptr);
+  }
 
-  SmallString<32> Out;
-  if (auto Err = Decompressor->resizeAndDecompress(Out))
-    return Err;
+  StringRef AbbrevSection;
+  StringRef ARangeSection;
+  StringRef DebugFrameSection;
+  StringRef EHFrameSection;
+  StringRef StringSection;
+  StringRef MacinfoSection;
+  StringRef PubNamesSection;
+  StringRef PubTypesSection;
+  StringRef GnuPubNamesSection;
+  StringRef AbbrevDWOSection;
+  StringRef StringDWOSection;
+  StringRef GnuPubTypesSection;
+  StringRef CUIndexSection;
+  StringRef GdbIndexSection;
+  StringRef TUIndexSection;
+
+  SmallVector<SmallString<32>, 4> UncompressedSections;
+
+  StringRef *mapSectionToMember(StringRef Name) {
+    if (DWARFSection *Sec = mapNameToDWARFSection(Name))
+      return &Sec->Data;
+    return StringSwitch<StringRef *>(Name)
+        .Case("debug_abbrev", &AbbrevSection)
+        .Case("debug_aranges", &ARangeSection)
+        .Case("debug_frame", &DebugFrameSection)
+        .Case("eh_frame", &EHFrameSection)
+        .Case("debug_str", &StringSection)
+        .Case("debug_macinfo", &MacinfoSection)
+        .Case("debug_pubnames", &PubNamesSection)
+        .Case("debug_pubtypes", &PubTypesSection)
+        .Case("debug_gnu_pubnames", &GnuPubNamesSection)
+        .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
+        .Case("debug_abbrev.dwo", &AbbrevDWOSection)
+        .Case("debug_str.dwo", &StringDWOSection)
+        .Case("debug_cu_index", &CUIndexSection)
+        .Case("debug_tu_index", &TUIndexSection)
+        .Case("gdb_index", &GdbIndexSection)
+        // Any more debug info sections go here.
+        .Default(nullptr);
+  }
 
-  UncompressedSections.emplace_back(std::move(Out));
-  Data = UncompressedSections.back();
+  /// If Sec is compressed section, decompresses and updates its contents
+  /// provided by Data. Otherwise leaves it unchanged.
+  Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
+                        StringRef &Data) {
+    if (!Decompressor::isCompressed(Sec))
+      return Error::success();
 
-  return Error::success();
-}
+    Expected<Decompressor> Decompressor =
+        Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
+    if (!Decompressor)
+      return Decompressor.takeError();
 
-ErrorPolicy DWARFContextInMemory::defaultErrorHandler(Error E) {
-  errs() << "error: " + toString(std::move(E)) << '\n';
-  return ErrorPolicy::Continue;
-}
+    SmallString<32> Out;
+    if (auto Err = Decompressor->resizeAndDecompress(Out))
+      return Err;
 
-DWARFContextInMemory::DWARFContextInMemory(
-    const object::ObjectFile &Obj, const LoadedObjectInfo *L,
-    function_ref<ErrorPolicy(Error)> HandleError)
-    : FileName(Obj.getFileName()), IsLittleEndian(Obj.isLittleEndian()),
-      AddressSize(Obj.getBytesInAddress()) {
-  for (const SectionRef &Section : Obj.sections()) {
-    StringRef Name;
-    Section.getName(Name);
-    // Skip BSS and Virtual sections, they aren't interesting.
-    if (Section.isBSS() || Section.isVirtual())
-      continue;
-
-    StringRef Data;
-    section_iterator RelocatedSection = Section.getRelocatedSection();
-    // Try to obtain an already relocated version of this section.
-    // Else use the unrelocated section from the object file. We'll have to
-    // apply relocations ourselves later.
-    if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data))
-      Section.getContents(Data);
-
-    if (auto Err = maybeDecompress(Section, Name, Data)) {
-      ErrorPolicy EP = HandleError(
-          createError("failed to decompress '" + Name + "', ", std::move(Err)));
-      if (EP == ErrorPolicy::Halt)
-        return;
-      continue;
-    }
+    UncompressedSections.emplace_back(std::move(Out));
+    Data = UncompressedSections.back();
 
-    // Compressed sections names in GNU style starts from ".z",
-    // at this point section is decompressed and we drop compression prefix.
-    Name = Name.substr(
-        Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
+    return Error::success();
+  }
 
-    // Map platform specific debug section names to DWARF standard section
-    // names.
-    Name = Obj.mapDebugSectionName(Name);
+public:
+  DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
+                   uint8_t AddrSize, bool IsLittleEndian)
+      : IsLittleEndian(IsLittleEndian) {
+    for (const auto &SecIt : Sections) {
+      if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
+        *SectionData = SecIt.second->getBuffer();
+    }
+  }
+  DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
+                   function_ref<ErrorPolicy(Error)> HandleError)
+      : IsLittleEndian(Obj.isLittleEndian()),
+        AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()) {
+
+    for (const SectionRef &Section : Obj.sections()) {
+      StringRef Name;
+      Section.getName(Name);
+      // Skip BSS and Virtual sections, they aren't interesting.
+      if (Section.isBSS() || Section.isVirtual())
+        continue;
 
-    if (StringRef *SectionData = mapSectionToMember(Name)) {
-      *SectionData = Data;
-      if (Name == "debug_ranges") {
-        // FIXME: Use the other dwo range section when we emit it.
-        RangeDWOSection.Data = Data;
+      StringRef Data;
+      section_iterator RelocatedSection = Section.getRelocatedSection();
+      // Try to obtain an already relocated version of this section.
+      // Else use the unrelocated section from the object file. We'll have to
+      // apply relocations ourselves later.
+      if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data))
+        Section.getContents(Data);
+
+      if (auto Err = maybeDecompress(Section, Name, Data)) {
+        ErrorPolicy EP = HandleError(createError(
+            "failed to decompress '" + Name + "', ", std::move(Err)));
+        if (EP == ErrorPolicy::Halt)
+          return;
+        continue;
+      }
+
+      // Compressed sections names in GNU style starts from ".z",
+      // at this point section is decompressed and we drop compression prefix.
+      Name = Name.substr(
+          Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
+
+      // Map platform specific debug section names to DWARF standard section
+      // names.
+      Name = Obj.mapDebugSectionName(Name);
+
+      if (StringRef *SectionData = mapSectionToMember(Name)) {
+        *SectionData = Data;
+        if (Name == "debug_ranges") {
+          // FIXME: Use the other dwo range section when we emit it.
+          RangeDWOSection.Data = Data;
+        }
+      } else if (Name == "debug_types") {
+        // Find debug_types data by section rather than name as there are
+        // multiple, comdat grouped, debug_types sections.
+        TypesSections[Section].Data = Data;
+      } else if (Name == "debug_types.dwo") {
+        TypesDWOSections[Section].Data = Data;
       }
-    } else if (Name == "debug_types") {
-      // Find debug_types data by section rather than name as there are
-      // multiple, comdat grouped, debug_types sections.
-      TypesSections[Section].Data = Data;
-    } else if (Name == "debug_types.dwo") {
-      TypesDWOSections[Section].Data = Data;
-    }
 
-    if (RelocatedSection == Obj.section_end())
-      continue;
-
-    StringRef RelSecName;
-    StringRef RelSecData;
-    RelocatedSection->getName(RelSecName);
-
-    // If the section we're relocating was relocated already by the JIT,
-    // then we used the relocated version above, so we do not need to process
-    // relocations for it now.
-    if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
-      continue;
-
-    // In Mach-o files, the relocations do not need to be applied if
-    // there is no load offset to apply. The value read at the
-    // relocation point already factors in the section address
-    // (actually applying the relocations will produce wrong results
-    // as the section address will be added twice).
-    if (!L && isa<MachOObjectFile>(&Obj))
-      continue;
-
-    RelSecName = RelSecName.substr(
-        RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes.
-
-    // TODO: Add support for relocations in other sections as needed.
-    // Record relocations for the debug_info and debug_line sections.
-    DWARFSection *Sec = mapNameToDWARFSection(RelSecName);
-    RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
-    if (!Map) {
-      // Find debug_types relocs by section rather than name as there are
-      // multiple, comdat grouped, debug_types sections.
-      if (RelSecName == "debug_types")
-        Map = &TypesSections[*RelocatedSection].Relocs;
-      else if (RelSecName == "debug_types.dwo")
-        Map = &TypesDWOSections[*RelocatedSection].Relocs;
-      else
+      if (RelocatedSection == Obj.section_end())
         continue;
-    }
 
-    if (Section.relocation_begin() == Section.relocation_end())
-      continue;
+      StringRef RelSecName;
+      StringRef RelSecData;
+      RelocatedSection->getName(RelSecName);
 
-    // Symbol to [address, section index] cache mapping.
-    std::map<SymbolRef, SymInfo> AddrCache;
-    for (const RelocationRef &Reloc : Section.relocations()) {
-      // FIXME: it's not clear how to correctly handle scattered
-      // relocations.
-      if (isRelocScattered(Obj, Reloc))
+      // If the section we're relocating was relocated already by the JIT,
+      // then we used the relocated version above, so we do not need to process
+      // relocations for it now.
+      if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
         continue;
 
-      Expected<SymInfo> SymInfoOrErr = getSymbolInfo(Obj, Reloc, L, AddrCache);
-      if (!SymInfoOrErr) {
-        if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt)
-          return;
+      // In Mach-o files, the relocations do not need to be applied if
+      // there is no load offset to apply. The value read at the
+      // relocation point already factors in the section address
+      // (actually applying the relocations will produce wrong results
+      // as the section address will be added twice).
+      if (!L && isa<MachOObjectFile>(&Obj))
         continue;
+
+      RelSecName = RelSecName.substr(
+          RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes.
+
+      // TODO: Add support for relocations in other sections as needed.
+      // Record relocations for the debug_info and debug_line sections.
+      DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
+      RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
+      if (!Map) {
+        // Find debug_types relocs by section rather than name as there are
+        // multiple, comdat grouped, debug_types sections.
+        if (RelSecName == "debug_types")
+          Map =
+              &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
+                   .Relocs;
+        else if (RelSecName == "debug_types.dwo")
+          Map = &static_cast<DWARFSectionMap &>(
+                     TypesDWOSections[*RelocatedSection])
+                     .Relocs;
+        else
+          continue;
       }
 
-      object::RelocVisitor V(Obj);
-      uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address);
-      if (V.error()) {
-        SmallString<32> Type;
-        Reloc.getTypeName(Type);
-        ErrorPolicy EP = HandleError(
-            createError("failed to compute relocation: " + Type + ", ",
-                        errorCodeToError(object_error::parse_failed)));
-        if (EP == ErrorPolicy::Halt)
-          return;
+      if (Section.relocation_begin() == Section.relocation_end())
         continue;
+
+      // Symbol to [address, section index] cache mapping.
+      std::map<SymbolRef, SymInfo> AddrCache;
+      for (const RelocationRef &Reloc : Section.relocations()) {
+        // FIXME: it's not clear how to correctly handle scattered
+        // relocations.
+        if (isRelocScattered(Obj, Reloc))
+          continue;
+
+        Expected<SymInfo> SymInfoOrErr =
+            getSymbolInfo(Obj, Reloc, L, AddrCache);
+        if (!SymInfoOrErr) {
+          if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt)
+            return;
+          continue;
+        }
+
+        object::RelocVisitor V(Obj);
+        uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address);
+        if (V.error()) {
+          SmallString<32> Type;
+          Reloc.getTypeName(Type);
+          ErrorPolicy EP = HandleError(
+              createError("failed to compute relocation: " + Type + ", ",
+                          errorCodeToError(object_error::parse_failed)));
+          if (EP == ErrorPolicy::Halt)
+            return;
+          continue;
+        }
+        RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val};
+        Map->insert({Reloc.getOffset(), Rel});
       }
-      RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val};
-      Map->insert({Reloc.getOffset(), Rel});
     }
   }
-}
 
-DWARFContextInMemory::DWARFContextInMemory(
-    const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, uint8_t AddrSize,
-    bool isLittleEndian)
-    : IsLittleEndian(isLittleEndian), AddressSize(AddrSize) {
-  for (const auto &SecIt : Sections) {
-    if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
-      *SectionData = SecIt.second->getBuffer();
+  Optional<RelocAddrEntry> find(const DWARFSection &S,
+                                uint64_t Pos) const override {
+    auto &Sec = static_cast<const DWARFSectionMap &>(S);
+    RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos);
+    if (AI == Sec.Relocs.end())
+      return None;
+    return AI->second;
   }
-}
 
-DWARFSection *DWARFContextInMemory::mapNameToDWARFSection(StringRef Name) {
-  return StringSwitch<DWARFSection *>(Name)
-      .Case("debug_info", &InfoSection)
-      .Case("debug_loc", &LocSection)
-      .Case("debug_line", &LineSection)
-      .Case("debug_str_offsets", &StringOffsetSection)
-      .Case("debug_ranges", &RangeSection)
-      .Case("debug_info.dwo", &InfoDWOSection)
-      .Case("debug_loc.dwo", &LocDWOSection)
-      .Case("debug_line.dwo", &LineDWOSection)
-      .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
-      .Case("debug_addr", &AddrSection)
-      .Case("apple_names", &AppleNamesSection)
-      .Case("apple_types", &AppleTypesSection)
-      .Case("apple_namespaces", &AppleNamespacesSection)
-      .Case("apple_namespac", &AppleNamespacesSection)
-      .Case("apple_objc", &AppleObjCSection)
-      .Default(nullptr);
-}
+  bool isLittleEndian() const override { return IsLittleEndian; }
+  StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }
+  const DWARFSection &getLineDWOSection() const override {
+    return LineDWOSection;
+  }
+  const DWARFSection &getLocDWOSection() const override {
+    return LocDWOSection;
+  }
+  StringRef getStringDWOSection() const override { return StringDWOSection; }
+  const DWARFSection &getStringOffsetDWOSection() const override {
+    return StringOffsetDWOSection;
+  }
+  const DWARFSection &getRangeDWOSection() const override {
+    return RangeDWOSection;
+  }
+  const DWARFSection &getAddrSection() const override { return AddrSection; }
+  StringRef getCUIndexSection() const override { return CUIndexSection; }
+  StringRef getGdbIndexSection() const override { return GdbIndexSection; }
+  StringRef getTUIndexSection() const override { return TUIndexSection; }
+
+  // DWARF v5
+  const DWARFSection &getStringOffsetSection() const override {
+    return StringOffsetSection;
+  }
+
+  // Sections for DWARF5 split dwarf proposal.
+  const DWARFSection &getInfoDWOSection() const override {
+    return InfoDWOSection;
+  }
+  void forEachTypesDWOSections(
+      function_ref<void(const DWARFSection &)> F) const override {
+    for (auto &P : TypesDWOSections)
+      F(P.second);
+  }
 
-StringRef *DWARFContextInMemory::mapSectionToMember(StringRef Name) {
-  if (DWARFSection *Sec = mapNameToDWARFSection(Name))
-    return &Sec->Data;
-  return StringSwitch<StringRef *>(Name)
-      .Case("debug_abbrev", &AbbrevSection)
-      .Case("debug_aranges", &ARangeSection)
-      .Case("debug_frame", &DebugFrameSection)
-      .Case("eh_frame", &EHFrameSection)
-      .Case("debug_str", &StringSection)
-      .Case("debug_macinfo", &MacinfoSection)
-      .Case("debug_pubnames", &PubNamesSection)
-      .Case("debug_pubtypes", &PubTypesSection)
-      .Case("debug_gnu_pubnames", &GnuPubNamesSection)
-      .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
-      .Case("debug_abbrev.dwo", &AbbrevDWOSection)
-      .Case("debug_str.dwo", &StringDWOSection)
-      .Case("debug_cu_index", &CUIndexSection)
-      .Case("debug_tu_index", &TUIndexSection)
-      .Case("gdb_index", &GdbIndexSection)
-      // Any more debug info sections go here.
-      .Default(nullptr);
+  StringRef getAbbrevSection() const override { return AbbrevSection; }
+  const DWARFSection &getLocSection() const override { return LocSection; }
+  StringRef getARangeSection() const override { return ARangeSection; }
+  StringRef getDebugFrameSection() const override { return DebugFrameSection; }
+  StringRef getEHFrameSection() const override { return EHFrameSection; }
+  const DWARFSection &getLineSection() const override { return LineSection; }
+  StringRef getStringSection() const override { return StringSection; }
+  const DWARFSection &getRangeSection() const override { return RangeSection; }
+  StringRef getMacinfoSection() const override { return MacinfoSection; }
+  StringRef getPubNamesSection() const override { return PubNamesSection; }
+  StringRef getPubTypesSection() const override { return PubTypesSection; }
+  StringRef getGnuPubNamesSection() const override {
+    return GnuPubNamesSection;
+  }
+  StringRef getGnuPubTypesSection() const override {
+    return GnuPubTypesSection;
+  }
+  const DWARFSection &getAppleNamesSection() const override {
+    return AppleNamesSection;
+  }
+  const DWARFSection &getAppleTypesSection() const override {
+    return AppleTypesSection;
+  }
+  const DWARFSection &getAppleNamespacesSection() const override {
+    return AppleNamespacesSection;
+  }
+  const DWARFSection &getAppleObjCSection() const override {
+    return AppleObjCSection;
+  }
+
+  StringRef getFileName() const override { return FileName; }
+  uint8_t getAddressSize() const override { return AddressSize; }
+  const DWARFSection &getInfoSection() const override { return InfoSection; }
+  void forEachTypesSections(
+      function_ref<void(const DWARFSection &)> F) const override {
+    for (auto &P : TypesSections)
+      F(P.second);
+  }
+};
+
+std::unique_ptr<DWARFContext>
+DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
+                     function_ref<ErrorPolicy(Error)> HandleError) {
+  auto DObj = make_unique<DWARFObjInMemory>(Obj, L, HandleError);
+  return make_unique<DWARFContext>(std::move(DObj));
 }
 
-void DWARFContextInMemory::anchor() {}
+std::unique_ptr<DWARFContext>
+DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
+                     uint8_t AddrSize, bool isLittleEndian) {
+  auto DObj = make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
+  return make_unique<DWARFContext>(std::move(DObj));
+}
index 001097e56c716ac8d4fb0a3fad731934c8c7d83f..a40635568cdddcb1695ee52c9de335907669ecee 100644 (file)
@@ -8,17 +8,18 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
 
 using namespace llvm;
 
 uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off,
                                                uint64_t *SecNdx) const {
-  if (!RelocMap)
+  if (!Section)
     return getUnsigned(Off, Size);
-  RelocAddrMap::const_iterator AI = RelocMap->find(*Off);
-  if (AI == RelocMap->end())
+  Optional<RelocAddrEntry> Rel = Obj->find(*Section, *Off);
+  if (!Rel)
     return getUnsigned(Off, Size);
   if (SecNdx)
-    *SecNdx = AI->second.SectionIndex;
-  return getUnsigned(Off, Size) + AI->second.Value;
+    *SecNdx = Rel->SectionIndex;
+  return getUnsigned(Off, Size) + Rel->Value;
 }
index 6601393d7459b23a5a073dbfb14324491b9b7896..65c486a6cf3970454444d03930bd7d76587eaa99 100644 (file)
@@ -43,7 +43,8 @@ void DWARFDebugAranges::generate(DWARFContext *CTX) {
     return;
 
   // Extract aranges from .debug_aranges section.
-  DataExtractor ArangesData(CTX->getARangeSection(), CTX->isLittleEndian(), 0);
+  DataExtractor ArangesData(CTX->getDWARFObj().getARangeSection(),
+                            CTX->isLittleEndian(), 0);
   extract(ArangesData);
 
   // Generate aranges from DIEs: even if .debug_aranges section is present,
index 043bdb874f4318c1feb9606a9d1a3db7b992c669..2bcda237a4c5bcfd9174f121b6977ddf9ccac831 100644 (file)
@@ -30,17 +30,19 @@ using namespace llvm;
 using namespace dwarf;
 
 void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) {
-  parseImpl(C, Section, C.getDebugAbbrev(), &C.getRangeSection(),
-            C.getStringSection(), C.getStringOffsetSection(),
-            &C.getAddrSection(), C.getLineSection(), C.isLittleEndian(), false);
+  const DWARFObject &D = C.getDWARFObj();
+  parseImpl(C, Section, C.getDebugAbbrev(), &D.getRangeSection(),
+            D.getStringSection(), D.getStringOffsetSection(),
+            &D.getAddrSection(), D.getLineSection(), D.isLittleEndian(), false);
 }
 
 void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
                                     const DWARFSection &DWOSection,
                                     DWARFUnitIndex *Index) {
-  parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), &C.getRangeDWOSection(),
-            C.getStringDWOSection(), C.getStringOffsetDWOSection(),
-            &C.getAddrSection(), C.getLineDWOSection(), C.isLittleEndian(),
+  const DWARFObject &D = C.getDWARFObj();
+  parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(),
+            D.getStringDWOSection(), D.getStringOffsetDWOSection(),
+            &D.getAddrSection(), D.getLineDWOSection(), C.isLittleEndian(),
             true);
 }
 
@@ -59,13 +61,18 @@ DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
 
 DWARFUnit::~DWARFUnit() = default;
 
+DWARFDataExtractor DWARFUnit::getDebugInfoExtractor() const {
+  return DWARFDataExtractor(Context.getDWARFObj(), InfoSection, isLittleEndian,
+                            getAddressByteSize());
+}
+
 bool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index,
                                                 uint64_t &Result) const {
   uint32_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize();
   if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize())
     return false;
-  DWARFDataExtractor DA(*AddrOffsetSection, isLittleEndian,
-                        getAddressByteSize());
+  DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection,
+                        isLittleEndian, getAddressByteSize());
   Result = DA.getRelocatedAddress(&Offset);
   return true;
 }
@@ -76,7 +83,8 @@ bool DWARFUnit::getStringOffsetSectionItem(uint32_t Index,
   uint32_t Offset = StringOffsetSectionBase + Index * ItemSize;
   if (StringOffsetSection.Data.size() < Offset + ItemSize)
     return false;
-  DWARFDataExtractor DA(StringOffsetSection, isLittleEndian, 0);
+  DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
+                        isLittleEndian, 0);
   Result = DA.getRelocatedValue(ItemSize, &Offset);
   return true;
 }
@@ -141,8 +149,8 @@ bool DWARFUnit::extractRangeList(uint32_t RangeListOffset,
                                  DWARFDebugRangeList &RangeList) const {
   // Require that compile unit is extracted.
   assert(!DieArray.empty());
-  DWARFDataExtractor RangesData(*RangeSection, isLittleEndian,
-                                getAddressByteSize());
+  DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
+                                isLittleEndian, getAddressByteSize());
   uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
   return RangeList.extract(RangesData, &ActualRangeListOffset);
 }
index 6cf44ffa3796a90d0502f98d62eb94365f5684e7..50fc45a9e376710782b2c51463f390b0744fd8c3 100644 (file)
@@ -105,8 +105,9 @@ bool DWARFVerifier::verifyUnitContents(DWARFUnit Unit) {
 bool DWARFVerifier::handleDebugInfo() {
   OS << "Verifying .debug_info Unit Header Chain...\n";
 
-  DWARFDataExtractor DebugInfoData(DCtx.getInfoSection(), DCtx.isLittleEndian(),
-                                   0);
+  const DWARFObject &DObj = DCtx.getDWARFObj();
+  DWARFDataExtractor DebugInfoData(DObj, DObj.getInfoSection(),
+                                   DCtx.isLittleEndian(), 0);
   uint32_t NumDebugInfoErrors = 0;
   uint32_t OffsetStart = 0, Offset = 0, UnitIdx = 0;
   uint8_t UnitType = 0;
@@ -127,10 +128,10 @@ bool DWARFVerifier::handleDebugInfo() {
       case dwarf::DW_UT_split_type: {
         DWARFUnitSection<DWARFTypeUnit> TUSection{};
         Unit.reset(new DWARFTypeUnit(
-            DCtx, DCtx.getInfoSection(), DCtx.getDebugAbbrev(),
-            &DCtx.getRangeSection(), DCtx.getStringSection(),
-            DCtx.getStringOffsetSection(), &DCtx.getAppleObjCSection(),
-            DCtx.getLineSection(), DCtx.isLittleEndian(), false, TUSection,
+            DCtx, DObj.getInfoSection(), DCtx.getDebugAbbrev(),
+            &DObj.getRangeSection(), DObj.getStringSection(),
+            DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
+            DObj.getLineSection(), DCtx.isLittleEndian(), false, TUSection,
             nullptr));
         break;
       }
@@ -143,10 +144,10 @@ bool DWARFVerifier::handleDebugInfo() {
       case 0: {
         DWARFUnitSection<DWARFCompileUnit> CUSection{};
         Unit.reset(new DWARFCompileUnit(
-            DCtx, DCtx.getInfoSection(), DCtx.getDebugAbbrev(),
-            &DCtx.getRangeSection(), DCtx.getStringSection(),
-            DCtx.getStringOffsetSection(), &DCtx.getAppleObjCSection(),
-            DCtx.getLineSection(), DCtx.isLittleEndian(), false, CUSection,
+            DCtx, DObj.getInfoSection(), DCtx.getDebugAbbrev(),
+            &DObj.getRangeSection(), DObj.getStringSection(),
+            DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
+            DObj.getLineSection(), DCtx.isLittleEndian(), false, CUSection,
             nullptr));
         break;
       }
@@ -169,13 +170,14 @@ bool DWARFVerifier::handleDebugInfo() {
 
 unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
                                                  DWARFAttribute &AttrValue) {
+  const DWARFObject &DObj = DCtx.getDWARFObj();
   unsigned NumErrors = 0;
   const auto Attr = AttrValue.Attr;
   switch (Attr) {
   case DW_AT_ranges:
     // Make sure the offset in the DW_AT_ranges attribute is valid.
     if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
-      if (*SectionOffset >= DCtx.getRangeSection().Data.size()) {
+      if (*SectionOffset >= DObj.getRangeSection().Data.size()) {
         ++NumErrors;
         OS << "error: DW_AT_ranges offset is beyond .debug_ranges "
               "bounds:\n";
@@ -192,7 +194,7 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
   case DW_AT_stmt_list:
     // Make sure the offset in the DW_AT_stmt_list attribute is valid.
     if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
-      if (*SectionOffset >= DCtx.getLineSection().Data.size()) {
+      if (*SectionOffset >= DObj.getLineSection().Data.size()) {
         ++NumErrors;
         OS << "error: DW_AT_stmt_list offset is beyond .debug_line "
               "bounds: "
@@ -216,6 +218,7 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
 
 unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
                                             DWARFAttribute &AttrValue) {
+  const DWARFObject &DObj = DCtx.getDWARFObj();
   unsigned NumErrors = 0;
   const auto Form = AttrValue.Value.getForm();
   switch (Form) {
@@ -253,7 +256,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
     Optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
     assert(RefVal);
     if (RefVal) {
-      if (*RefVal >= DCtx.getInfoSection().Data.size()) {
+      if (*RefVal >= DObj.getInfoSection().Data.size()) {
         ++NumErrors;
         OS << "error: DW_FORM_ref_addr offset beyond .debug_info "
               "bounds:\n";
@@ -270,7 +273,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
   case DW_FORM_strp: {
     auto SecOffset = AttrValue.Value.getAsSectionOffset();
     assert(SecOffset); // DW_FORM_strp is a section offset.
-    if (SecOffset && *SecOffset >= DCtx.getStringSection().size()) {
+    if (SecOffset && *SecOffset >= DObj.getStringSection().size()) {
       ++NumErrors;
       OS << "error: DW_FORM_strp offset beyond .debug_str bounds:\n";
       Die.dump(OS, 0);
@@ -318,7 +321,7 @@ void DWARFVerifier::verifyDebugLineStmtOffsets() {
       continue;
     const uint32_t LineTableOffset = *StmtSectionOffset;
     auto LineTable = DCtx.getLineTableForUnit(CU.get());
-    if (LineTableOffset < DCtx.getLineSection().Data.size()) {
+    if (LineTableOffset < DCtx.getDWARFObj().getLineSection().Data.size()) {
       if (!LineTable) {
         ++NumDebugLineErrors;
         OS << "error: .debug_line[" << format("0x%08" PRIx32, LineTableOffset)
@@ -408,10 +411,10 @@ bool DWARFVerifier::handleDebugLine() {
 
 bool DWARFVerifier::handleAppleNames() {
   NumAppleNamesErrors = 0;
-
-  DWARFDataExtractor AppleNamesSection(DCtx.getAppleNamesSection(),
+  const DWARFObject &D = DCtx.getDWARFObj();
+  DWARFDataExtractor AppleNamesSection(D, D.getAppleNamesSection(),
                                        DCtx.isLittleEndian(), 0);
-  DataExtractor StrData(DCtx.getStringSection(), DCtx.isLittleEndian(), 0);
+  DataExtractor StrData(D.getStringSection(), DCtx.isLittleEndian(), 0);
   DWARFAcceleratorTable AppleNames(AppleNamesSection, StrData);
 
   if (!AppleNames.extract()) {
index 19711ca58c6f0ff97245020f7622bb85280bbe5a..1d8b432164762335da06aa4db21c440886b07566 100644 (file)
@@ -409,7 +409,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) {
     }
   }
   if (!Context)
-    Context.reset(new DWARFContextInMemory(*Objects.second));
+    Context = DWARFContext::create(*Objects.second);
   assert(Context);
   auto InfoOrErr =
       SymbolizableObjectFile::create(Objects.first, std::move(Context));
index 86621e3260f06d7ce41e2222d32b87c69217b218..94428bcab516307cce389540235a32075312181d 100644 (file)
@@ -845,7 +845,7 @@ void DwarfStreamer::emitLocationsForUnit(const CompileUnit &Unit,
   MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLocSection());
 
   unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
-  const DWARFSection &InputSec = Dwarf.getLocSection();
+  const DWARFSection &InputSec = Dwarf.getDWARFObj().getLocSection();
   DataExtractor Data(InputSec.Data, Dwarf.isLittleEndian(), AddressSize);
   DWARFUnit &OrigUnit = Unit.getOrigUnit();
   auto OrigUnitDie = OrigUnit.getUnitDIE(false);
@@ -1301,7 +1301,7 @@ private:
     /// Construct the output DIE tree by cloning the DIEs we
     /// chose to keep above. If there are no valid relocs, then there's
     /// nothing to clone/emit.
-    void cloneAllCompileUnits(DWARFContextInMemory &DwarfContext);
+    void cloneAllCompileUnits(DWARFContext &DwarfContext);
 
   private:
     typedef DWARFAbbreviationDeclaration::AttributeSpec AttributeSpec;
@@ -2873,7 +2873,8 @@ void DwarfLinker::patchRangesForUnit(const CompileUnit &Unit,
   DWARFDebugRangeList RangeList;
   const auto &FunctionRanges = Unit.getFunctionRanges();
   unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
-  DWARFDataExtractor RangeExtractor(OrigDwarf.getRangeSection(),
+  DWARFDataExtractor RangeExtractor(OrigDwarf.getDWARFObj(),
+                                    OrigDwarf.getDWARFObj().getRangeSection(),
                                     OrigDwarf.isLittleEndian(), AddressSize);
   auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange;
   DWARFUnit &OrigUnit = Unit.getOrigUnit();
@@ -2984,9 +2985,9 @@ void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit,
   // Parse the original line info for the unit.
   DWARFDebugLine::LineTable LineTable;
   uint32_t StmtOffset = *StmtList;
-  DWARFDataExtractor LineExtractor(OrigDwarf.getLineSection(),
-                                   OrigDwarf.isLittleEndian(),
-                                   Unit.getOrigUnit().getAddressByteSize());
+  DWARFDataExtractor LineExtractor(
+      OrigDwarf.getDWARFObj(), OrigDwarf.getDWARFObj().getLineSection(),
+      OrigDwarf.isLittleEndian(), Unit.getOrigUnit().getAddressByteSize());
   LineTable.parse(LineExtractor, &StmtOffset);
 
   // This vector is the output line table.
@@ -3086,7 +3087,7 @@ void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit,
       LineTable.Prologue.OpcodeBase > 13)
     reportWarning("line table parameters mismatch. Cannot emit.");
   else {
-    StringRef LineData = OrigDwarf.getLineSection().Data;
+    StringRef LineData = OrigDwarf.getDWARFObj().getLineSection().Data;
     MCDwarfLineTableParams Params;
     Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase;
     Params.DWARF2LineBase = LineTable.Prologue.LineBase;
@@ -3112,7 +3113,7 @@ void DwarfLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) {
 void DwarfLinker::patchFrameInfoForObject(const DebugMapObject &DMO,
                                           DWARFContext &OrigDwarf,
                                           unsigned AddrSize) {
-  StringRef FrameData = OrigDwarf.getDebugFrameSection();
+  StringRef FrameData = OrigDwarf.getDWARFObj().getDebugFrameSection();
   if (FrameData.empty())
     return;
 
@@ -3323,9 +3324,9 @@ void DwarfLinker::loadClangModule(StringRef Filename, StringRef ModulePath,
   std::unique_ptr<CompileUnit> Unit;
 
   // Setup access to the debug info.
-  DWARFContextInMemory DwarfContext(*ErrOrObj);
+  auto DwarfContext = DWARFContext::create(*ErrOrObj);
   RelocationManager RelocMgr(*this);
-  for (const auto &CU : DwarfContext.compile_units()) {
+  for (const auto &CU : DwarfContext->compile_units()) {
     auto CUDie = CU->getUnitDIE(false);
     // Recursively get all modules imported by this one.
     if (!registerModuleReference(CUDie, *CU, ModuleMap, Indent)) {
@@ -3365,11 +3366,10 @@ void DwarfLinker::loadClangModule(StringRef Filename, StringRef ModulePath,
   std::vector<std::unique_ptr<CompileUnit>> CompileUnits;
   CompileUnits.push_back(std::move(Unit));
   DIECloner(*this, RelocMgr, DIEAlloc, CompileUnits, Options)
-      .cloneAllCompileUnits(DwarfContext);
+      .cloneAllCompileUnits(*DwarfContext);
 }
 
-void DwarfLinker::DIECloner::cloneAllCompileUnits(
-    DWARFContextInMemory &DwarfContext) {
+void DwarfLinker::DIECloner::cloneAllCompileUnits(DWARFContext &DwarfContext) {
   if (!Linker.Streamer)
     return;
 
@@ -3438,11 +3438,11 @@ bool DwarfLinker::link(const DebugMap &Map) {
     }
 
     // Setup access to the debug info.
-    DWARFContextInMemory DwarfContext(*ErrOrObj);
-    startDebugObject(DwarfContext, *Obj);
+    auto DwarfContext = DWARFContext::create(*ErrOrObj);
+    startDebugObject(*DwarfContext, *Obj);
 
     // In a first phase, just read in the debug info and load all clang modules.
-    for (const auto &CU : DwarfContext.compile_units()) {
+    for (const auto &CU : DwarfContext->compile_units()) {
       auto CUDie = CU->getUnitDIE(false);
       if (Options.Verbose) {
         outs() << "Input compilation unit:";
@@ -3476,9 +3476,9 @@ bool DwarfLinker::link(const DebugMap &Map) {
     RelocMgr.resetValidRelocs();
     if (RelocMgr.hasValidRelocs())
       DIECloner(*this, RelocMgr, DIEAlloc, Units, Options)
-          .cloneAllCompileUnits(DwarfContext);
+          .cloneAllCompileUnits(*DwarfContext);
     if (!Options.NoOutput && !Units.empty())
-      patchFrameInfoForObject(*Obj, DwarfContext,
+      patchFrameInfoForObject(*Obj, *DwarfContext,
                               Units[0]->getOrigUnit().getAddressByteSize());
 
     // Clean-up before starting working on the next object.
index ec5e554d4f5f59b132caadd25d4c77fa6018ba8b..62235af31cdb07635bc837f0394f72b36607341c 100644 (file)
@@ -94,7 +94,7 @@ static void error(StringRef Filename, std::error_code EC) {
 }
 
 static void DumpObjectFile(ObjectFile &Obj, Twine Filename) {
-  std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(Obj));
+  std::unique_ptr<DIContext> DICtx = DWARFContext::create(Obj);
 
   outs() << Filename.str() << ":\tfile format " << Obj.getFileFormatName()
          << "\n\n";
@@ -131,8 +131,8 @@ static void DumpInput(StringRef Filename) {
 }
 
 static bool VerifyObjectFile(ObjectFile &Obj, Twine Filename) {
-  std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(Obj));
-  
+  std::unique_ptr<DIContext> DICtx = DWARFContext::create(Obj);
+
   // Verify the DWARF and exit with non-zero exit status if verification
   // fails.
   raw_ostream &stream = Quiet ? nulls() : outs();
index 05c2c3f7c4cbd7edefe287990ce46a08571ecad1..3bab94d681a98cc88923e107e2a91186628daaaf 100644 (file)
@@ -1275,7 +1275,7 @@ static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF,
     printWeakBindTable(MachOOF);
 
   if (DwarfDumpType != DIDT_Null) {
-    std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(*MachOOF));
+    std::unique_ptr<DIContext> DICtx = DWARFContext::create(*MachOOF);
     // Dump the complete DWARF structure.
     DIDumpOptions DumpOpts;
     DumpOpts.DumpType = DwarfDumpType;
@@ -6594,7 +6594,7 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF,
     }
 
     // Setup the DIContext
-    diContext.reset(new DWARFContextInMemory(*DbgObj));
+    diContext = DWARFContext::create(*DbgObj);
   }
 
   if (FilterSections.size() == 0)
index d54b45515f05f31a2198752954c1900ad854656a..c772204a8ed214df6ff773afc1acbf996d03ee84 100644 (file)
@@ -62,8 +62,8 @@
 #include <cctype>
 #include <cstring>
 #include <system_error>
-#include <utility>
 #include <unordered_map>
+#include <utility>
 
 using namespace llvm;
 using namespace object;
@@ -2081,7 +2081,7 @@ static void DumpObject(ObjectFile *o, const Archive *a = nullptr) {
   if (PrintFaultMaps)
     printFaultMaps(o);
   if (DwarfDumpType != DIDT_Null) {
-    std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(*o));
+    std::unique_ptr<DIContext> DICtx = DWARFContext::create(*o);
     // Dump the complete DWARF structure.
     DIDumpOptions DumpOpts;
     DumpOpts.DumpType = DwarfDumpType;
index ba130ce80be8911f8838aab3fdc73b5130d00cdd..daafcdfcc95faae65ab339ce781e62460d2c2692 100644 (file)
@@ -324,8 +324,8 @@ static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) {
       }
     }
 
-    std::unique_ptr<DIContext> Context(
-      new DWARFContextInMemory(*SymbolObj,LoadedObjInfo.get()));
+    std::unique_ptr<DIContext> Context =
+        DWARFContext::create(*SymbolObj, LoadedObjInfo.get());
 
     std::vector<std::pair<SymbolRef, uint64_t>> SymAddr =
         object::computeSymbolSizes(*SymbolObj);
index d97eda30c039914cc8398bb2fdbe13493efb82e0..9a9dcd866567d1f10692aa24f07f1a5a347e775c 100644 (file)
@@ -24,7 +24,7 @@ void dumpInitialLength(DataExtractor &Data, uint32_t &Offset,
     InitialLength.TotalLength64 = Data.getU64(&Offset);
 }
 
-void dumpDebugAbbrev(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
+void dumpDebugAbbrev(DWARFContext &DCtx, DWARFYAML::Data &Y) {
   auto AbbrevSetPtr = DCtx.getDebugAbbrev();
   if (AbbrevSetPtr) {
     for (auto AbbrvDeclSet : *AbbrevSetPtr) {
@@ -48,8 +48,8 @@ void dumpDebugAbbrev(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
   }
 }
 
-void dumpDebugStrings(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
-  StringRef RemainingTable = DCtx.getStringSection();
+void dumpDebugStrings(DWARFContext &DCtx, DWARFYAML::Data &Y) {
+  StringRef RemainingTable = DCtx.getDWARFObj().getStringSection();
   while (RemainingTable.size() > 0) {
     auto SymbolPair = RemainingTable.split('\0');
     RemainingTable = SymbolPair.second;
@@ -57,8 +57,9 @@ void dumpDebugStrings(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
   }
 }
 
-void dumpDebugARanges(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
-  DataExtractor ArangesData(DCtx.getARangeSection(), DCtx.isLittleEndian(), 0);
+void dumpDebugARanges(DWARFContext &DCtx, DWARFYAML::Data &Y) {
+  DataExtractor ArangesData(DCtx.getDWARFObj().getARangeSection(),
+                            DCtx.isLittleEndian(), 0);
   uint32_t Offset = 0;
   DWARFDebugArangeSet Set;
 
@@ -79,7 +80,7 @@ void dumpDebugARanges(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
   }
 }
 
-void dumpPubSection(DWARFContextInMemory &DCtx, DWARFYAML::PubSection &Y,
+void dumpPubSection(DWARFContext &DCtx, DWARFYAML::PubSection &Y,
                     StringRef Section) {
   DataExtractor PubSectionData(Section, DCtx.isLittleEndian(), 0);
   uint32_t Offset = 0;
@@ -97,21 +98,22 @@ void dumpPubSection(DWARFContextInMemory &DCtx, DWARFYAML::PubSection &Y,
   }
 }
 
-void dumpDebugPubSections(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
+void dumpDebugPubSections(DWARFContext &DCtx, DWARFYAML::Data &Y) {
+  const DWARFObject &D = DCtx.getDWARFObj();
   Y.PubNames.IsGNUStyle = false;
-  dumpPubSection(DCtx, Y.PubNames, DCtx.getPubNamesSection());
+  dumpPubSection(DCtx, Y.PubNames, D.getPubNamesSection());
 
   Y.PubTypes.IsGNUStyle = false;
-  dumpPubSection(DCtx, Y.PubTypes, DCtx.getPubTypesSection());
+  dumpPubSection(DCtx, Y.PubTypes, D.getPubTypesSection());
 
   Y.GNUPubNames.IsGNUStyle = true;
-  dumpPubSection(DCtx, Y.GNUPubNames, DCtx.getGnuPubNamesSection());
+  dumpPubSection(DCtx, Y.GNUPubNames, D.getGnuPubNamesSection());
 
   Y.GNUPubTypes.IsGNUStyle = true;
-  dumpPubSection(DCtx, Y.GNUPubTypes, DCtx.getGnuPubTypesSection());
+  dumpPubSection(DCtx, Y.GNUPubTypes, D.getGnuPubTypesSection());
 }
 
-void dumpDebugInfo(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
+void dumpDebugInfo(DWARFContext &DCtx, DWARFYAML::Data &Y) {
   for (const auto &CU : DCtx.compile_units()) {
     DWARFYAML::Unit NewUnit;
     NewUnit.Length.setLength(CU->getLength());
@@ -235,7 +237,7 @@ bool dumpFileEntry(DataExtractor &Data, uint32_t &Offset,
   return true;
 }
 
-void dumpDebugLines(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
+void dumpDebugLines(DWARFContext &DCtx, DWARFYAML::Data &Y) {
   for (const auto &CU : DCtx.compile_units()) {
     auto CUDIE = CU->getUnitDIE();
     if (!CUDIE)
@@ -243,8 +245,8 @@ void dumpDebugLines(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
     if (auto StmtOffset =
             dwarf::toSectionOffset(CUDIE.find(dwarf::DW_AT_stmt_list))) {
       DWARFYAML::LineTable DebugLines;
-      DataExtractor LineData(DCtx.getLineSection().Data, DCtx.isLittleEndian(),
-                             CU->getAddressByteSize());
+      DataExtractor LineData(DCtx.getDWARFObj().getLineSection().Data,
+                             DCtx.isLittleEndian(), CU->getAddressByteSize());
       uint32_t Offset = *StmtOffset;
       dumpInitialLength(LineData, Offset, DebugLines.Length);
       uint64_t LineTableLength = DebugLines.Length.getLength();
@@ -344,7 +346,7 @@ void dumpDebugLines(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
   }
 }
 
-std::error_code dwarf2yaml(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
+std::error_code dwarf2yaml(DWARFContext &DCtx, DWARFYAML::Data &Y) {
   dumpDebugAbbrev(DCtx, Y);
   dumpDebugStrings(DCtx, Y);
   dumpDebugARanges(DCtx, Y);
index a1d107dc5afb02303679ecbd17301c6134a74a9c..fa81ce974ecf6598578738ca335cd1e38c7d3c46 100644 (file)
@@ -35,9 +35,9 @@ class MachODumper {
                        ArrayRef<uint8_t> OpcodeBuffer, bool Lazy = false);
   void dumpExportTrie(std::unique_ptr<MachOYAML::Object> &Y);
   void dumpSymbols(std::unique_ptr<MachOYAML::Object> &Y);
-  void dumpDebugAbbrev(DWARFContextInMemory &DCtx,
+  void dumpDebugAbbrev(DWARFContext &DCtx,
                        std::unique_ptr<MachOYAML::Object> &Y);
-  void dumpDebugStrings(DWARFContextInMemory &DCtx,
+  void dumpDebugStrings(DWARFContext &DCtx,
                         std::unique_ptr<MachOYAML::Object> &Y);
 
 public:
@@ -187,8 +187,8 @@ Expected<std::unique_ptr<MachOYAML::Object>> MachODumper::dump() {
   dumpLoadCommands(Y);
   dumpLinkEdit(Y);
 
-  DWARFContextInMemory DICtx(Obj);
-  if (auto Err = dwarf2yaml(DICtx, Y->DWARF))
+  std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(Obj);
+  if (auto Err = dwarf2yaml(*DICtx, Y->DWARF))
     return errorCodeToError(Err);
   return std::move(Y);
 }
index 69c753296efda97de979b8b13c6082a919f4153f..3e96659462b09040f1d79a69c70cc2de3300634f 100644 (file)
@@ -29,13 +29,12 @@ std::error_code wasm2yaml(llvm::raw_ostream &Out,
 
 // Forward decls for dwarf2yaml
 namespace llvm {
-class DWARFContextInMemory;
+class DWARFContext;
 namespace DWARFYAML {
 struct Data;
 }
 }
 
-std::error_code dwarf2yaml(llvm::DWARFContextInMemory &DCtx,
-                           llvm::DWARFYAML::Data &Y);
+std::error_code dwarf2yaml(llvm::DWARFContext &DCtx, llvm::DWARFYAML::Data &Y);
 
 #endif
index 6ffb710d2549b9aad7d09eee9649885b775f61e5..0bb5cebe9c81d27b6a67b6c62cebd984479b3dcf 100644 (file)
@@ -14,8 +14,8 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/Config/llvm-config.h"
 #include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/Config/llvm-config.h"
 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
@@ -28,8 +28,8 @@
 #include "llvm/ObjectYAML/DWARFYAML.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
 #include "llvm/Testing/Support/Error.h"
 #include "gtest/gtest.h"
 #include <climits>
@@ -228,10 +228,10 @@ void TestAllForms() {
   MemoryBufferRef FileBuffer(FileBytes, "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
   auto DieDG = U->getUnitDIE(false);
   EXPECT_TRUE(DieDG.isValid());
 
@@ -458,12 +458,12 @@ template <uint16_t Version, class AddrType> void TestChildren() {
   MemoryBufferRef FileBuffer(FileBytes, "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
 
   // Get the compile unit DIE is valid.
   auto DieDG = U->getUnitDIE(false);
@@ -629,13 +629,13 @@ template <uint16_t Version, class AddrType> void TestReferences() {
   MemoryBufferRef FileBuffer(FileBytes, "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 2u);
-  DWARFCompileUnit *U1 = DwarfContext.getCompileUnitAtIndex(0);
-  DWARFCompileUnit *U2 = DwarfContext.getCompileUnitAtIndex(1);
+  DWARFCompileUnit *U1 = DwarfContext->getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U2 = DwarfContext->getCompileUnitAtIndex(1);
 
   // Get the compile unit DIE is valid.
   auto Unit1DieDG = U1->getUnitDIE(false);
@@ -837,12 +837,12 @@ template <uint16_t Version, class AddrType> void TestAddresses() {
   MemoryBufferRef FileBuffer(FileBytes, "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
 
   // Get the compile unit DIE is valid.
   auto DieDG = U->getUnitDIE(false);
@@ -1012,12 +1012,12 @@ TEST(DWARFDebugInfo, TestRelations) {
   MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1127,12 +1127,12 @@ TEST(DWARFDebugInfo, TestChildIterators) {
   MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1188,12 +1188,13 @@ TEST(DWARFDebugInfo, TestEmptyChildren) {
 
   auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1235,12 +1236,12 @@ TEST(DWARFDebugInfo, TestAttributeIterators) {
   MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1299,12 +1300,12 @@ TEST(DWARFDebugInfo, TestFindRecurse) {
   MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1505,12 +1506,12 @@ TEST(DWARFDebugInfo, TestFindAttrs) {
   MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1568,8 +1569,8 @@ TEST(DWARFDebugInfo, TestImplicitConstAbbrevs) {
   MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
   EXPECT_TRUE((bool)U);
 
   const auto *Abbrevs = U->getAbbreviations();
@@ -1708,10 +1709,11 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidCURef) {
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
-  VerifyError(DwarfContext, "error: DW_FORM_ref4 CU offset 0x00001234 is "
-                            "invalid (must be less than CU size of "
-                            "0x0000001a):");
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
+  VerifyError(*DwarfContext, "error: DW_FORM_ref4 CU offset 0x00001234 is "
+                             "invalid (must be less than CU size of "
+                             "0x0000001a):");
 }
 
 TEST(DWARFDebugInfo, TestDwarfVerifyInvalidRefAddr) {
@@ -1756,8 +1758,9 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidRefAddr) {
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
-  VerifyError(DwarfContext,
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
+  VerifyError(*DwarfContext,
               "error: DW_FORM_ref_addr offset beyond .debug_info bounds:");
 }
 
@@ -1792,8 +1795,9 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidRanges) {
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
-  VerifyError(DwarfContext,
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
+  VerifyError(*DwarfContext,
               "error: DW_AT_ranges offset is beyond .debug_ranges bounds:");
 }
 
@@ -1828,9 +1832,10 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidStmtList) {
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
   VerifyError(
-      DwarfContext,
+      *DwarfContext,
       "error: DW_AT_stmt_list offset is beyond .debug_line bounds: 0x00001000");
 }
 
@@ -1860,8 +1865,9 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidStrp) {
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
-  VerifyError(DwarfContext,
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
+  VerifyError(*DwarfContext,
               "error: DW_FORM_strp offset beyond .debug_str bounds:");
 }
 
@@ -1907,9 +1913,10 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidRefAddrBetween) {
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
   VerifyError(
-      DwarfContext,
+      *DwarfContext,
       "error: invalid DIE reference 0x00000011. Offset is in between DIEs:");
 }
 
@@ -1977,9 +1984,10 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidLineSequence) {
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
-  VerifyError(DwarfContext, "error: .debug_line[0x00000000] row[1] decreases "
-                            "in address from previous row:");
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
+  VerifyError(*DwarfContext, "error: .debug_line[0x00000000] row[1] decreases "
+                             "in address from previous row:");
 }
 
 TEST(DWARFDebugInfo, TestDwarfVerifyInvalidLineFileIndex) {
@@ -2048,9 +2056,10 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidLineFileIndex) {
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
-  VerifyError(DwarfContext, "error: .debug_line[0x00000000][1] has invalid "
-                            "file index 5 (valid values are [1,1]):");
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
+  VerifyError(*DwarfContext, "error: .debug_line[0x00000000][1] has invalid "
+                             "file index 5 (valid values are [1,1]):");
 }
 
 TEST(DWARFDebugInfo, TestDwarfVerifyCUDontShareLineTable) {
@@ -2128,10 +2137,12 @@ TEST(DWARFDebugInfo, TestDwarfVerifyCUDontShareLineTable) {
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
-  VerifyError(DwarfContext, "error: two compile unit DIEs, 0x0000000b and "
-                            "0x0000001f, have the same DW_AT_stmt_list section "
-                            "offset:");
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
+  VerifyError(*DwarfContext,
+              "error: two compile unit DIEs, 0x0000000b and "
+              "0x0000001f, have the same DW_AT_stmt_list section "
+              "offset:");
 }
 
 TEST(DWARFDebugInfo, TestErrorReportingPolicy) {
@@ -2161,20 +2172,22 @@ TEST(DWARFDebugInfo, TestErrorReportingPolicy) {
   // DWARFContextInMemory
   //         to parse whole file and find both two errors we know about.
   int Errors = 0;
-  DWARFContextInMemory Ctx1(*Obj.get(), nullptr, [&](Error E) {
-    ++Errors;
-    consumeError(std::move(E));
-    return ErrorPolicy::Continue;
-  });
+  std::unique_ptr<DWARFContext> Ctx1 =
+      DWARFContext::create(**Obj, nullptr, [&](Error E) {
+        ++Errors;
+        consumeError(std::move(E));
+        return ErrorPolicy::Continue;
+      });
   EXPECT_TRUE(Errors == 2);
 
   // Case 2: error handler stops parsing of object after first error.
   Errors = 0;
-  DWARFContextInMemory Ctx2(*Obj.get(), nullptr, [&](Error E) {
-    ++Errors;
-    consumeError(std::move(E));
-    return ErrorPolicy::Halt;
-  });
+  std::unique_ptr<DWARFContext> Ctx2 =
+      DWARFContext::create(**Obj, nullptr, [&](Error E) {
+        ++Errors;
+        consumeError(std::move(E));
+        return ErrorPolicy::Halt;
+      });
   EXPECT_TRUE(Errors == 1);
 }