labath created this revision.
labath added reviewers: JDevlieghere, aprantl, clayborg.
Herald added subscribers: mgrang, mgorny.
Herald added a project: LLDB.
labath added a parent revision: D73782: [lldb/DWARF] Don't hold a unique 
SymbolFileDWARFDwo in a DWARFUnit.

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. Righ 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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73783

Files:
  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
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
  lldb/test/Shell/SymbolFile/DWARF/dwp.s
  lldb/unittests/Expression/DWARFExpressionTest.cpp

Index: lldb/unittests/Expression/DWARFExpressionTest.cpp
===================================================================
--- lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -164,7 +164,7 @@
     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();
   }
Index: lldb/test/Shell/SymbolFile/DWARF/dwp.s
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/dwp.s
@@ -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: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
+++ /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_
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
+++ /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;
-}
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
+++ /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_
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
+++ /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);
-}
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -43,9 +43,6 @@
   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;
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -29,27 +29,27 @@
                                    /*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;
@@ -60,8 +60,6 @@
 
 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: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -453,7 +453,7 @@
   };
   llvm::Optional<DecodedUID> DecodeUID(lldb::user_id_t uid);
 
-  SymbolFileDWARFDwp *GetDwpSymbolFile();
+  void FindDwpSymbolFile();
 
   const lldb_private::FileSpecList &GetTypeUnitSupportFiles(DWARFTypeUnit &tu);
 
@@ -461,12 +461,14 @@
   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: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -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"
@@ -597,13 +596,13 @@
 }
 
 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();
 }
 
@@ -1507,10 +1506,12 @@
 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();
@@ -1574,14 +1575,9 @@
   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);
@@ -3940,7 +3936,7 @@
   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();
@@ -3951,9 +3947,16 @@
     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();
 }
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -39,6 +39,9 @@
   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 @@
 
   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 @@
   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: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -788,10 +788,13 @@
 }
 
 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) {
@@ -807,6 +810,25 @@
         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);
@@ -837,11 +859,12 @@
 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: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -61,7 +61,10 @@
 
   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: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -72,10 +72,16 @@
   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::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: lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h
@@ -31,6 +31,7 @@
   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 @@
   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: lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp
@@ -28,18 +28,23 @@
 }
 
 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 @@
     };
 
     AddSection("debug_line_str", getOrLoadLineStrData());
+    AddSection("debug_cu_index", getOrLoadCuIndexData());
 
     m_llvm_context = llvm::DWARFContext::create(section_map, addr_size);
   }
Index: lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
+++ lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
@@ -37,8 +37,6 @@
   NameToDIE.cpp
   SymbolFileDWARF.cpp
   SymbolFileDWARFDwo.cpp
-  SymbolFileDWARFDwoDwp.cpp
-  SymbolFileDWARFDwp.cpp
   SymbolFileDWARFDebugMap.cpp
   UniqueDWARFASTType.cpp
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to