[lldb/DWARF] Re-enable basic dwp support
authorPavel Labath <pavel@labath.sk>
Wed, 29 Jan 2020 11:00:29 +0000 (12:00 +0100)
committerPavel Labath <pavel@labath.sk>
Mon, 17 Feb 2020 13:10:36 +0000 (14:10 +0100)
Summary:
This patch removes the bitrotted SymbolFileDWARF(Dwo)Dwp classes, and
replaces them with dwp support implemented directly inside
SymbolFileDWARFDwo, in a manner mirroring the implementation in llvm.
This patch does:
- add support for the .debug_cu_index section to our DWARFContext
- adds a llvm::DWARFUnitIndex argument to the DWARFUnit constructors.
  This argument is used to look up the offsets of the debug_info and
  debug_abbrev contributions in the sections of the dwp file.
- makes sure the creation of the DebugInfo object as well as the initial
  discovery of DWARFUnits is thread-safe, as we can now call this
  concurrently when doing parallel indexing.

This patch does not:
- use the DWARFUnitIndex to search for other kinds of contributions
  (debug_loc, debug_ranges, etc.). This means that units which reference
  these sections will not work correctly. These will be handled by
  follow-up patches, but even the present level of support is sufficient
  to enable basic functionality.
- Make the llvm::DWARFContext thread-safe. Right now, it just avoids this
  problem by ensuring everything is initialized ahead of time. However,
  this is something we will run into more often as we try to use more of
  llvm, and so I plan to start looking into our options here.

Reviewers: JDevlieghere, aprantl, clayborg

Subscribers: mgorny, mgrang, lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D73783

17 files changed:
lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp [deleted file]
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h [deleted file]
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp [deleted file]
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h [deleted file]
lldb/test/Shell/SymbolFile/DWARF/dwp.s [new file with mode: 0644]
lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp

index 49de7df..5504043 100644 (file)
@@ -37,8 +37,6 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
   NameToDIE.cpp
   SymbolFileDWARF.cpp
   SymbolFileDWARFDwo.cpp
-  SymbolFileDWARFDwoDwp.cpp
-  SymbolFileDWARFDwp.cpp
   SymbolFileDWARFDebugMap.cpp
   UniqueDWARFASTType.cpp
 
index b3009f7..79601e3 100644 (file)
@@ -28,18 +28,23 @@ static DWARFDataExtractor LoadSection(SectionList *section_list,
 }
 
 const DWARFDataExtractor &
-DWARFContext::LoadOrGetSection(SectionType main_section_type,
+DWARFContext::LoadOrGetSection(llvm::Optional<SectionType> main_section_type,
                                llvm::Optional<SectionType> dwo_section_type,
                                SectionData &data) {
   llvm::call_once(data.flag, [&] {
     if (dwo_section_type && isDwo())
       data.data = LoadSection(m_dwo_section_list, *dwo_section_type);
-    else
-      data.data = LoadSection(m_main_section_list, main_section_type);
+    else if (main_section_type)
+      data.data = LoadSection(m_main_section_list, *main_section_type);
   });
   return data.data;
 }
 
+const DWARFDataExtractor &DWARFContext::getOrLoadCuIndexData() {
+  return LoadOrGetSection(llvm::None, eSectionTypeDWARFDebugCuIndex,
+                          m_data_debug_cu_index);
+}
+
 const DWARFDataExtractor &DWARFContext::getOrLoadAbbrevData() {
   return LoadOrGetSection(eSectionTypeDWARFDebugAbbrev,
                           eSectionTypeDWARFDebugAbbrevDwo, m_data_debug_abbrev);
@@ -128,6 +133,7 @@ llvm::DWARFContext &DWARFContext::GetAsLLVM() {
     };
 
     AddSection("debug_line_str", getOrLoadLineStrData());
+    AddSection("debug_cu_index", getOrLoadCuIndexData());
 
     m_llvm_context = llvm::DWARFContext::create(section_map, addr_size);
   }
index 8691001..c9548e5 100644 (file)
@@ -31,6 +31,7 @@ private:
   SectionData m_data_debug_abbrev;
   SectionData m_data_debug_addr;
   SectionData m_data_debug_aranges;
+  SectionData m_data_debug_cu_index;
   SectionData m_data_debug_info;
   SectionData m_data_debug_line;
   SectionData m_data_debug_line_str;
@@ -44,10 +45,12 @@ private:
   SectionData m_data_debug_types;
 
   const DWARFDataExtractor &
-  LoadOrGetSection(lldb::SectionType main_section_type,
+  LoadOrGetSection(llvm::Optional<lldb::SectionType> main_section_type,
                    llvm::Optional<lldb::SectionType> dwo_section_type,
                    SectionData &data);
 
+  const DWARFDataExtractor &getOrLoadCuIndexData();
+
 public:
   explicit DWARFContext(SectionList *main_section_list,
                         SectionList *dwo_section_list)
index 8ca1a8f..941a547 100644 (file)
@@ -72,10 +72,16 @@ void DWARFDebugInfo::ParseUnitsFor(DIERef::Section section) {
   DWARFDataExtractor data = section == DIERef::Section::DebugTypes
                                 ? m_context.getOrLoadDebugTypesData()
                                 : m_context.getOrLoadDebugInfoData();
+  const llvm::DWARFUnitIndex *index = nullptr;
+  if (m_context.isDwo())
+    index = &llvm::getDWARFUnitIndex(m_context.GetAsLLVM(),
+                                     section == DIERef::Section::DebugTypes
+                                         ? llvm::DW_SECT_TYPES
+                                         : llvm::DW_SECT_INFO);
   lldb::offset_t offset = 0;
   while (data.ValidOffset(offset)) {
-    llvm::Expected<DWARFUnitSP> unit_sp =
-        DWARFUnit::extract(m_dwarf, m_units.size(), data, section, &offset);
+    llvm::Expected<DWARFUnitSP> unit_sp = DWARFUnit::extract(
+        m_dwarf, m_units.size(), data, section, &offset, index);
 
     if (!unit_sp) {
       // FIXME: Propagate this error up.
@@ -96,12 +102,11 @@ void DWARFDebugInfo::ParseUnitsFor(DIERef::Section section) {
 }
 
 void DWARFDebugInfo::ParseUnitHeadersIfNeeded() {
-  if (!m_units.empty())
-    return;
-
-  ParseUnitsFor(DIERef::Section::DebugInfo);
-  ParseUnitsFor(DIERef::Section::DebugTypes);
-  llvm::sort(m_type_hash_to_unit_index, llvm::less_first());
+  llvm::call_once(m_units_once_flag, [&] {
+    ParseUnitsFor(DIERef::Section::DebugInfo);
+    ParseUnitsFor(DIERef::Section::DebugTypes);
+    llvm::sort(m_type_hash_to_unit_index, llvm::less_first());
+  });
 }
 
 size_t DWARFDebugInfo::GetNumUnits() {
index db6a0f8..3abdba3 100644 (file)
@@ -61,7 +61,10 @@ protected:
 
   SymbolFileDWARF &m_dwarf;
   lldb_private::DWARFContext &m_context;
+
+  llvm::once_flag m_units_once_flag;
   UnitColl m_units;
+
   std::unique_ptr<DWARFDebugAranges>
       m_cu_aranges_up; // A quick address to compile unit table
 
index 1e8c465..37e5233 100644 (file)
@@ -773,10 +773,13 @@ const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() {
 }
 
 llvm::Expected<DWARFUnitHeader>
-DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section,
-                         lldb::offset_t *offset_ptr) {
+DWARFUnitHeader::extract(const DWARFDataExtractor &data,
+                         DIERef::Section section, lldb::offset_t *offset_ptr,
+                         const llvm::DWARFUnitIndex *index) {
   DWARFUnitHeader header;
   header.m_offset = *offset_ptr;
+  if (index)
+    header.m_index_entry = index->getFromOffset(*offset_ptr);
   header.m_length = data.GetDWARFInitialLength(offset_ptr);
   header.m_version = data.GetU16(offset_ptr);
   if (header.m_version == 5) {
@@ -792,6 +795,25 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section
         section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile;
   }
 
+  if (header.m_index_entry) {
+    if (header.m_abbr_offset) {
+      return llvm::createStringError(
+          llvm::inconvertibleErrorCode(),
+          "Package unit with a non-zero abbreviation offset");
+    }
+    auto *unit_contrib = header.m_index_entry->getOffset();
+    if (!unit_contrib || unit_contrib->Length != header.m_length + 4) {
+      return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                     "Inconsistent DWARF package unit index");
+    }
+    auto *abbr_entry = header.m_index_entry->getOffset(llvm::DW_SECT_ABBREV);
+    if (!abbr_entry) {
+      return llvm::createStringError(
+          llvm::inconvertibleErrorCode(),
+          "DWARF package index missing abbreviation column");
+    }
+    header.m_abbr_offset = abbr_entry->Offset;
+  }
   if (header.IsTypeUnit()) {
     header.m_type_hash = data.GetU64(offset_ptr);
     header.m_type_offset = data.GetDWARFOffset(offset_ptr);
@@ -822,11 +844,12 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section
 llvm::Expected<DWARFUnitSP>
 DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid,
                    const DWARFDataExtractor &debug_info,
-                   DIERef::Section section, lldb::offset_t *offset_ptr) {
+                   DIERef::Section section, lldb::offset_t *offset_ptr,
+                   const llvm::DWARFUnitIndex *index) {
   assert(debug_info.ValidOffset(*offset_ptr));
 
   auto expected_header =
-      DWARFUnitHeader::extract(debug_info, section, offset_ptr);
+      DWARFUnitHeader::extract(debug_info, section, offset_ptr, index);
   if (!expected_header)
     return expected_header.takeError();
 
index 7852e5a..c013add 100644 (file)
@@ -39,6 +39,9 @@ class DWARFUnitHeader {
   dw_offset_t m_length = 0;
   uint16_t m_version = 0;
   dw_offset_t m_abbr_offset = 0;
+
+  const llvm::DWARFUnitIndex::Entry *m_index_entry = nullptr;
+
   uint8_t m_unit_type = 0;
   uint8_t m_addr_size = 0;
 
@@ -65,7 +68,7 @@ public:
 
   static llvm::Expected<DWARFUnitHeader>
   extract(const lldb_private::DWARFDataExtractor &data, DIERef::Section section,
-          lldb::offset_t *offset_ptr);
+          lldb::offset_t *offset_ptr, const llvm::DWARFUnitIndex *index);
 };
 
 class DWARFUnit : public lldb_private::UserID {
@@ -76,7 +79,8 @@ public:
   static llvm::Expected<DWARFUnitSP>
   extract(SymbolFileDWARF &dwarf2Data, lldb::user_id_t uid,
           const lldb_private::DWARFDataExtractor &debug_info,
-          DIERef::Section section, lldb::offset_t *offset_ptr);
+          DIERef::Section section, lldb::offset_t *offset_ptr,
+          const llvm::DWARFUnitIndex *index);
   virtual ~DWARFUnit();
 
   bool IsDWOUnit() { return m_is_dwo; }
index 2ed050c..b7e91c0 100644 (file)
@@ -70,7 +70,6 @@
 #include "ManualDWARFIndex.h"
 #include "SymbolFileDWARFDebugMap.h"
 #include "SymbolFileDWARFDwo.h"
-#include "SymbolFileDWARFDwp.h"
 
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/Support/FileSystem.h"
@@ -601,13 +600,13 @@ DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
 }
 
 DWARFDebugInfo *SymbolFileDWARF::DebugInfo() {
-  if (m_info == nullptr) {
+  llvm::call_once(m_info_once_flag, [&] {
     static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
     Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
                        static_cast<void *>(this));
     if (m_context.getOrLoadDebugInfoData().GetByteSize() > 0)
       m_info = std::make_unique<DWARFDebugInfo>(*this, m_context);
-  }
+  });
   return m_info.get();
 }
 
@@ -1509,10 +1508,12 @@ lldb::ModuleSP SymbolFileDWARF::GetExternalModule(ConstString name) {
 DWARFDIE
 SymbolFileDWARF::GetDIE(const DIERef &die_ref) {
   if (die_ref.dwo_num()) {
-    return DebugInfo()
-        ->GetUnitAtIndex(*die_ref.dwo_num())
-        ->GetDwoSymbolFile()
-        ->GetDIE(die_ref);
+    SymbolFileDWARF *dwarf = *die_ref.dwo_num() == 0x3fffffff
+                                 ? m_dwp_symfile.get()
+                                 : this->DebugInfo()
+                                       ->GetUnitAtIndex(*die_ref.dwo_num())
+                                       ->GetDwoSymbolFile();
+    return dwarf->DebugInfo()->GetDIE(die_ref);
   }
 
   DWARFDebugInfo *debug_info = DebugInfo();
@@ -1576,14 +1577,9 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
   if (!dwo_name)
     return nullptr;
 
-  SymbolFileDWARFDwp *dwp_symfile = GetDwpSymbolFile();
-  if (dwp_symfile) {
-    uint64_t dwo_id = ::GetDWOId(*dwarf_cu, cu_die);
-    std::unique_ptr<SymbolFileDWARFDwo> dwo_symfile =
-        dwp_symfile->GetSymbolFileForDwoId(*dwarf_cu, dwo_id);
-    if (dwo_symfile)
-      return dwo_symfile;
-  }
+  FindDwpSymbolFile();
+  if (m_dwp_symfile)
+    return m_dwp_symfile;
 
   FileSpec dwo_file(dwo_name);
   FileSystem::Instance().Resolve(dwo_file);
@@ -3935,7 +3931,7 @@ SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {
   return m_debug_map_symfile;
 }
 
-SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() {
+void SymbolFileDWARF::FindDwpSymbolFile() {
   llvm::call_once(m_dwp_symfile_once_flag, [this]() {
     ModuleSpec module_spec;
     module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec();
@@ -3946,11 +3942,18 @@ SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() {
     FileSpec dwp_filespec =
         Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
     if (FileSystem::Instance().Exists(dwp_filespec)) {
-      m_dwp_symfile = SymbolFileDWARFDwp::Create(GetObjectFile()->GetModule(),
-                                                 dwp_filespec);
+      DataBufferSP dwp_file_data_sp;
+      lldb::offset_t dwp_file_data_offset = 0;
+      ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin(
+          GetObjectFile()->GetModule(), &dwp_filespec, 0,
+          FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp,
+          dwp_file_data_offset);
+      if (!dwp_obj_file)
+        return;
+      m_dwp_symfile =
+          std::make_shared<SymbolFileDWARFDwo>(*this, dwp_obj_file, 0x3fffffff);
     }
   });
-  return m_dwp_symfile.get();
 }
 
 llvm::Expected<TypeSystem &> SymbolFileDWARF::GetTypeSystem(DWARFUnit &unit) {
index c9fd678..c592561 100644 (file)
@@ -473,7 +473,7 @@ protected:
   };
   llvm::Optional<DecodedUID> DecodeUID(lldb::user_id_t uid);
 
-  SymbolFileDWARFDwp *GetDwpSymbolFile();
+  void FindDwpSymbolFile();
 
   const lldb_private::FileSpecList &GetTypeUnitSupportFiles(DWARFTypeUnit &tu);
 
@@ -481,12 +481,14 @@ protected:
   SymbolFileDWARFDebugMap *m_debug_map_symfile;
 
   llvm::once_flag m_dwp_symfile_once_flag;
-  std::unique_ptr<SymbolFileDWARFDwp> m_dwp_symfile;
+  std::shared_ptr<SymbolFileDWARFDwo> m_dwp_symfile;
 
   lldb_private::DWARFContext m_context;
 
-  std::unique_ptr<DWARFDebugAbbrev> m_abbr;
+  llvm::once_flag m_info_once_flag;
   std::unique_ptr<DWARFDebugInfo> m_info;
+
+  std::unique_ptr<DWARFDebugAbbrev> m_abbr;
   std::unique_ptr<GlobalVariableMap> m_global_aranges_up;
 
   typedef std::unordered_map<lldb::offset_t, lldb_private::DebugMacrosSP>
index cf33d05..652c910 100644 (file)
@@ -29,27 +29,27 @@ SymbolFileDWARFDwo::SymbolFileDWARFDwo(SymbolFileDWARF &base_symbol_file,
                                    /*update_module_section_list*/ false)),
       m_base_symbol_file(base_symbol_file) {
   SetID(user_id_t(id) << 32);
-}
 
-void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type,
-                                         DWARFDataExtractor &data) {
-  const SectionList *section_list =
-      m_objfile_sp->GetSectionList(false /* update_module_section_list */);
-  if (section_list) {
-    SectionSP section_sp(section_list->FindSectionByType(sect_type, true));
-    if (section_sp) {
+  // Parsing of the dwarf unit index is not thread-safe, so we need to prime it
+  // to enable subsequent concurrent lookups.
+  m_context.GetAsLLVM().getCUIndex();
+}
 
-      if (m_objfile_sp->ReadSectionData(section_sp.get(), data) != 0)
-        return;
+DWARFCompileUnit *SymbolFileDWARFDwo::GetDWOCompileUnitForHash(uint64_t hash) {
+  DWARFDebugInfo *debug_info = DebugInfo();
+  if (!debug_info)
+    return nullptr;
 
-      data.Clear();
+  if (const llvm::DWARFUnitIndex &index = m_context.GetAsLLVM().getCUIndex()) {
+    if (const llvm::DWARFUnitIndex::Entry *entry = index.getFromHash(hash)) {
+      if (auto *unit_contrib = entry->getOffset())
+        return llvm::dyn_cast_or_null<DWARFCompileUnit>(
+            debug_info->GetUnitAtOffset(DIERef::Section::DebugInfo,
+                                        unit_contrib->Offset));
     }
+    return nullptr;
   }
 
-  SymbolFileDWARF::LoadSectionData(sect_type, data);
-}
-
-DWARFCompileUnit *SymbolFileDWARFDwo::GetDWOCompileUnitForHash(uint64_t hash) {
   DWARFCompileUnit *cu = FindSingleCompileUnit();
   if (!cu)
     return nullptr;
@@ -61,8 +61,6 @@ DWARFCompileUnit *SymbolFileDWARFDwo::GetDWOCompileUnitForHash(uint64_t hash) {
 
 DWARFCompileUnit *SymbolFileDWARFDwo::FindSingleCompileUnit() {
   DWARFDebugInfo *debug_info = DebugInfo();
-  if (!debug_info)
-    return nullptr;
 
   // Right now we only support dwo files with one compile unit. If we don't have
   // type units, we can just check for the unit count.
index 37cc2cb..90bed7e 100644 (file)
@@ -43,9 +43,6 @@ public:
   llvm::Optional<uint32_t> GetDwoNum() override { return GetID() >> 32; }
 
 protected:
-  void LoadSectionData(lldb::SectionType sect_type,
-                       lldb_private::DWARFDataExtractor &data) override;
-
   DIEToTypePtr &GetDIEToType() override;
 
   DIEToVariableSP &GetDIEToVariable() override;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
deleted file mode 100644 (file)
index 05c7e5c..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-//===-- SymbolFileDWARFDwoDwp.cpp -----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "SymbolFileDWARFDwoDwp.h"
-
-#include "lldb/Core/Section.h"
-#include "lldb/Expression/DWARFExpression.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Utility/LLDBAssert.h"
-
-#include "DWARFCompileUnit.h"
-#include "DWARFDebugInfo.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-char SymbolFileDWARFDwoDwp::ID;
-
-SymbolFileDWARFDwoDwp::SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile,
-                                             ObjectFileSP objfile,
-                                             DWARFCompileUnit &dwarf_cu,
-                                             uint64_t dwo_id)
-    : SymbolFileDWARFDwo(dwarf_cu.GetSymbolFileDWARF(), objfile,
-                         dwarf_cu.GetID()),
-      m_dwp_symfile(dwp_symfile), m_dwo_id(dwo_id) {}
-
-void SymbolFileDWARFDwoDwp::LoadSectionData(lldb::SectionType sect_type,
-                                            DWARFDataExtractor &data) {
-  if (m_dwp_symfile->LoadSectionData(m_dwo_id, sect_type, data))
-    return;
-
-  SymbolFileDWARF::LoadSectionData(sect_type, data);
-}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
deleted file mode 100644 (file)
index a55795b..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-//===-- SymbolFileDWARFDwoDwp.h ---------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_
-#define SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_
-
-#include "SymbolFileDWARFDwo.h"
-#include "SymbolFileDWARFDwp.h"
-
-class SymbolFileDWARFDwoDwp : public SymbolFileDWARFDwo {
-  /// LLVM RTTI support.
-  static char ID;
-
-public:
-  /// LLVM RTTI support.
-  /// \{
-  bool isA(const void *ClassID) const override {
-    return ClassID == &ID || SymbolFileDWARFDwo::isA(ClassID);
-  }
-  static bool classof(const SymbolFile *obj) { return obj->isA(&ID); }
-  /// \}
-  SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile,
-                        lldb::ObjectFileSP objfile, DWARFCompileUnit &dwarf_cu,
-                        uint64_t dwo_id);
-
-protected:
-  void LoadSectionData(lldb::SectionType sect_type,
-                       lldb_private::DWARFDataExtractor &data) override;
-
-  SymbolFileDWARFDwp *m_dwp_symfile;
-  uint64_t m_dwo_id;
-};
-
-#endif // SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
deleted file mode 100644 (file)
index a7eadc8..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-//===-- SymbolFileDWARFDwp.cpp --------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "SymbolFileDWARFDwp.h"
-
-#include "lldb/Core/Section.h"
-#include "lldb/Symbol/ObjectFile.h"
-
-#include "SymbolFileDWARFDwoDwp.h"
-
-static llvm::DWARFSectionKind
-lldbSectTypeToLlvmSectionKind(lldb::SectionType type) {
-  switch (type) {
-  case lldb::eSectionTypeDWARFDebugInfo:
-    return llvm::DW_SECT_INFO;
-  // case lldb::eSectionTypeDWARFDebugTypes:
-  //   return llvm::DW_SECT_TYPES;
-  case lldb::eSectionTypeDWARFDebugAbbrev:
-    return llvm::DW_SECT_ABBREV;
-  case lldb::eSectionTypeDWARFDebugLine:
-    return llvm::DW_SECT_LINE;
-  case lldb::eSectionTypeDWARFDebugLoc:
-    return llvm::DW_SECT_LOC; 
-  case lldb::eSectionTypeDWARFDebugStrOffsets:
-    return llvm::DW_SECT_STR_OFFSETS;
-  // case lldb::eSectionTypeDWARFDebugMacinfo:
-  //   return llvm::DW_SECT_MACINFO;
-  case lldb::eSectionTypeDWARFDebugMacro:
-    return llvm::DW_SECT_MACRO;
-  default:
-    // Note: 0 is an invalid dwarf section kind.
-    return llvm::DWARFSectionKind(0);
-  }
-}
-
-std::unique_ptr<SymbolFileDWARFDwp>
-SymbolFileDWARFDwp::Create(lldb::ModuleSP module_sp,
-                           const lldb_private::FileSpec &file_spec) {
-  const lldb::offset_t file_offset = 0;
-  lldb::DataBufferSP file_data_sp;
-  lldb::offset_t file_data_offset = 0;
-  lldb::ObjectFileSP obj_file = lldb_private::ObjectFile::FindPlugin(
-      module_sp, &file_spec, file_offset,
-      lldb_private::FileSystem::Instance().GetByteSize(file_spec), file_data_sp,
-      file_data_offset);
-  if (obj_file == nullptr)
-    return nullptr;
-
-  std::unique_ptr<SymbolFileDWARFDwp> dwp_symfile(
-      new SymbolFileDWARFDwp(module_sp, obj_file));
-
-  lldb_private::DWARFDataExtractor debug_cu_index;
-  if (!dwp_symfile->LoadRawSectionData(lldb::eSectionTypeDWARFDebugCuIndex,
-                                       debug_cu_index))
-    return nullptr;
-
-  llvm::DataExtractor llvm_debug_cu_index(
-      llvm::StringRef(debug_cu_index.PeekCStr(0), debug_cu_index.GetByteSize()),
-      debug_cu_index.GetByteOrder() == lldb::eByteOrderLittle,
-      debug_cu_index.GetAddressByteSize());
-  if (!dwp_symfile->m_debug_cu_index.parse(llvm_debug_cu_index))
-    return nullptr;
-  dwp_symfile->InitDebugCUIndexMap();
-  return dwp_symfile;
-}
-
-void SymbolFileDWARFDwp::InitDebugCUIndexMap() {
-  m_debug_cu_index_map.clear();
-  for (const auto &entry : m_debug_cu_index.getRows())
-    m_debug_cu_index_map.emplace(entry.getSignature(), &entry);
-}
-
-SymbolFileDWARFDwp::SymbolFileDWARFDwp(lldb::ModuleSP module_sp,
-                                       lldb::ObjectFileSP obj_file)
-    : m_obj_file(std::move(obj_file)), m_debug_cu_index(llvm::DW_SECT_INFO) 
-{}
-
-std::unique_ptr<SymbolFileDWARFDwo>
-SymbolFileDWARFDwp::GetSymbolFileForDwoId(DWARFCompileUnit &dwarf_cu,
-                                          uint64_t dwo_id) {
-  return std::unique_ptr<SymbolFileDWARFDwo>(
-      new SymbolFileDWARFDwoDwp(this, m_obj_file, dwarf_cu, dwo_id));
-}
-
-bool SymbolFileDWARFDwp::LoadSectionData(
-    uint64_t dwo_id, lldb::SectionType sect_type,
-    lldb_private::DWARFDataExtractor &data) {
-  lldb_private::DWARFDataExtractor section_data;
-  if (!LoadRawSectionData(sect_type, section_data))
-    return false;
-
-  auto it = m_debug_cu_index_map.find(dwo_id);
-  if (it == m_debug_cu_index_map.end())
-    return false;
-
-  auto *offsets =
-      it->second->getOffset(lldbSectTypeToLlvmSectionKind(sect_type));
-  if (offsets) {
-    data.SetData(section_data, offsets->Offset, offsets->Length);
-  } else {
-    data.SetData(section_data, 0, section_data.GetByteSize());
-  }
-  return true;
-}
-
-bool SymbolFileDWARFDwp::LoadRawSectionData(
-    lldb::SectionType sect_type, lldb_private::DWARFDataExtractor &data) {
-  std::lock_guard<std::mutex> lock(m_sections_mutex);
-
-  auto it = m_sections.find(sect_type);
-  if (it != m_sections.end()) {
-    if (it->second.GetByteSize() == 0)
-      return false;
-
-    data = it->second;
-    return true;
-  }
-
-  const lldb_private::SectionList *section_list =
-      m_obj_file->GetSectionList(false /* update_module_section_list */);
-  if (section_list) {
-    lldb::SectionSP section_sp(
-        section_list->FindSectionByType(sect_type, true));
-    if (section_sp) {
-      if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0) {
-        m_sections[sect_type] = data;
-        return true;
-      }
-    }
-  }
-  m_sections[sect_type].Clear();
-  return false;
-}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
deleted file mode 100644 (file)
index ef06b9d..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-//===-- SymbolFileDWARFDwp.h ------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_
-#define SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_
-
-#include <memory>
-
-#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
-
-#include "lldb/Core/Module.h"
-
-#include "DWARFDataExtractor.h"
-#include "SymbolFileDWARFDwo.h"
-
-class SymbolFileDWARFDwp {
-public:
-  static std::unique_ptr<SymbolFileDWARFDwp>
-  Create(lldb::ModuleSP module_sp, const lldb_private::FileSpec &file_spec);
-
-  std::unique_ptr<SymbolFileDWARFDwo>
-  GetSymbolFileForDwoId(DWARFCompileUnit &dwarf_cu, uint64_t dwo_id);
-
-  bool LoadSectionData(uint64_t dwo_id, lldb::SectionType sect_type,
-                       lldb_private::DWARFDataExtractor &data);
-
-private:
-  explicit SymbolFileDWARFDwp(lldb::ModuleSP module_sp,
-                              lldb::ObjectFileSP obj_file);
-
-  bool LoadRawSectionData(lldb::SectionType sect_type,
-                          lldb_private::DWARFDataExtractor &data);
-  
-  void InitDebugCUIndexMap();
-
-  lldb::ObjectFileSP m_obj_file;
-
-  std::mutex m_sections_mutex;
-  std::map<lldb::SectionType, lldb_private::DWARFDataExtractor> m_sections;
-
-  llvm::DWARFUnitIndex m_debug_cu_index;
-  std::map<uint64_t, const llvm::DWARFUnitIndex::Entry *> m_debug_cu_index_map;
-};
-
-#endif // SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_
diff --git a/lldb/test/Shell/SymbolFile/DWARF/dwp.s b/lldb/test/Shell/SymbolFile/DWARF/dwp.s
new file mode 100644 (file)
index 0000000..47ac804
--- /dev/null
@@ -0,0 +1,149 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc --filetype=obj --triple x86_64-pc-linux %s -o %t --defsym MAIN=0
+# RUN: llvm-mc --filetype=obj --triple x86_64-pc-linux %s -o %t.dwp --defsym DWP=0
+# RUN: %lldb %t -o "target variable A" -b | FileCheck %s
+# RUN: lldb-test symbols %t | FileCheck %s --check-prefix=SYMBOLS
+
+# CHECK: (int) A = 0
+# CHECK: (int) A = 1
+# CHECK: (int) A = 2
+# CHECK: (int) A = 3
+
+# SYMBOLS:      Compile units:
+# SYMBOLS-NEXT: CompileUnit{0x00000000}, language = "unknown", file = '0.c'
+# SYMBOLS-NEXT:   Variable{{.*}}, name = "A", {{.*}}, location = DW_OP_GNU_addr_index 0x0
+# SYMBOLS-NEXT: CompileUnit{0x00000001}, language = "unknown", file = '1.c'
+# SYMBOLS-NEXT:   Variable{{.*}}, name = "A", {{.*}}, location = DW_OP_GNU_addr_index 0x1
+# SYMBOLS-NEXT: CompileUnit{0x00000002}, language = "unknown", file = '2.c'
+# SYMBOLS-NEXT:   Variable{{.*}}, name = "A", {{.*}}, location = DW_OP_GNU_addr_index 0x2
+# SYMBOLS-NEXT: CompileUnit{0x00000003}, language = "unknown", file = '3.c'
+# SYMBOLS-NEXT:   Variable{{.*}}, name = "A", {{.*}}, location = DW_OP_GNU_addr_index 0x3
+# SYMBOLS-NEXT: CompileUnit{0x00000004}, language = "unknown", file = ''
+# SYMBOLS-EMPTY:
+
+        .section        .debug_abbrev,"",@progbits
+        .byte   1                       # Abbreviation Code
+        .byte   17                      # DW_TAG_compile_unit
+        .byte   0                       # DW_CHILDREN_no
+        .ascii  "\260B"                 # DW_AT_GNU_dwo_name
+        .byte   8                       # DW_FORM_string
+        .ascii  "\261B"                 # DW_AT_GNU_dwo_id
+        .byte   7                       # DW_FORM_data8
+        .ascii  "\263B"                 # DW_AT_GNU_addr_base
+        .byte   23                      # DW_FORM_sec_offset
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   0                       # EOM(3)
+
+.ifdef MAIN
+.irpc I,01234
+        .data
+A\I:
+        .long \I
+
+        .section        .debug_info,"",@progbits
+.Lcu_begin\I:
+        .long   .Ldebug_info_end\I-.Ldebug_info_start\I # Length of Unit
+.Ldebug_info_start\I:
+        .short  4                       # DWARF version number
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .byte   8                       # Address Size (in bytes)
+        .byte   1                       # Abbrev [1] 0xb:0x25 DW_TAG_compile_unit
+        .asciz  "A.dwo"                 # DW_AT_GNU_dwo_name
+        .quad   \I                      # DW_AT_GNU_dwo_id
+        .long   .debug_addr             # DW_AT_GNU_addr_base
+.Ldebug_info_end\I:
+
+        .section        .debug_addr,"",@progbits
+        .quad   A\I
+.endr
+.endif
+
+.ifdef DWP
+# This deliberately excludes compile unit 4 to check test the case of a missing
+# split unit.
+.irpc I,0123
+        .section        .debug_abbrev.dwo,"e",@progbits
+.Labbrev\I:
+        .byte   \I*10+1                 # Abbreviation Code
+        .byte   17                      # DW_TAG_compile_unit
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   37                      # DW_AT_producer
+        .byte   8                       # DW_FORM_string
+        .byte   3                       # DW_AT_name
+        .byte   8                       # DW_FORM_string
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   \I*10+2                 # Abbreviation Code
+        .byte   52                      # DW_TAG_variable
+        .byte   0                       # DW_CHILDREN_no
+        .byte   3                       # DW_AT_name
+        .byte   8                       # DW_FORM_string
+        .byte   73                      # DW_AT_type
+        .byte   19                      # DW_FORM_ref4
+        .byte   2                       # DW_AT_location
+        .byte   24                      # DW_FORM_exprloc
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   \I*10+3                 # Abbreviation Code
+        .byte   36                      # DW_TAG_base_type
+        .byte   0                       # DW_CHILDREN_no
+        .byte   3                       # DW_AT_name
+        .byte   14                      # DW_FORM_string
+        .byte   62                      # DW_AT_encoding
+        .byte   11                      # DW_FORM_data1
+        .byte   11                      # DW_AT_byte_size
+        .byte   11                      # DW_FORM_data1
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   0                       # EOM(3)
+.Labbrev_end\I:
+
+        .section        .debug_info.dwo,"e",@progbits
+.Lcu_begin\I:
+        .long   .Ldebug_info_end\I-.Ldebug_info_start\I # Length of Unit
+.Ldebug_info_start\I:
+        .short  4                       # DWARF version number
+        .long   0                       # Offset Into Abbrev. Section
+        .byte   8                       # Address Size (in bytes)
+        .byte   \I*10+1                 # Abbrev DW_TAG_compile_unit
+        .asciz  "Hand-written DWARF"    # DW_AT_producer
+        .byte   '0'+\I, '.', 'c', 0     # DW_AT_name
+        .byte   \I*10+2                 # Abbrev DW_TAG_variable
+        .asciz  "A"                     # DW_AT_name
+        .long   .Ltype\I-.Lcu_begin\I   # DW_AT_type
+        .byte   2                       # DW_AT_location
+        .byte   0xfb                    # DW_OP_GNU_addr_index
+        .byte   \I
+.Ltype\I:
+        .byte   \I*10+3                 # Abbrev DW_TAG_base_type
+        .asciz  "int"                   # DW_AT_name
+        .byte   5                       # DW_AT_encoding
+        .byte   4                       # DW_AT_byte_size
+        .byte   0                       # End Of Children Mark
+.Ldebug_info_end\I:
+.endr
+
+        .section        .debug_cu_index,"e",@progbits
+        .short  2                       # DWARF version number
+        .short  0                       # Reserved
+        .long   2                       # Section count
+        .long   4                       # Unit count
+        .long   8                       # Slot count
+
+        .quad   0, 1, 2, 3, 0, 0, 0, 0  # Hash table
+        .long   1, 2, 3, 4, 0, 0, 0, 0  # Index table
+
+        .long   1, 3                    # DW_SECT_INFO, DW_SECT_ABBREV
+
+.irpc I,0123
+        .long .Lcu_begin\I-.debug_info.dwo
+        .long .Labbrev\I-.debug_abbrev.dwo
+.endr
+.irpc I,0123
+        .long .Ldebug_info_end\I-.Lcu_begin\I
+        .long .Labbrev_end\I-.Labbrev\I
+.endr
+
+.endif
index c4550d0..59b6bcc 100644 (file)
@@ -111,7 +111,7 @@ YAMLModuleTester::YAMLModuleTester(llvm::StringRef yaml_data,
   llvm::Expected<DWARFUnitSP> dwarf_unit = DWARFUnit::extract(
       *m_symfile_dwarf, uid,
       *static_cast<lldb_private::DWARFDataExtractor *>(&debug_info),
-      DIERef::DebugInfo, &offset_ptr);
+      DIERef::DebugInfo, &offset_ptr, nullptr);
   if (dwarf_unit)
     m_dwarf_unit = dwarf_unit.get();
 }