labath updated this revision to Diff 200227.
labath added a comment.

Rebase so that this does not require any debug_types support.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D62073/new/

https://reviews.llvm.org/D62073

Files:
  source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
  source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
  source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
  source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
  source/Plugins/SymbolFile/DWARF/DWARFUnit.h

Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -31,11 +31,46 @@
   eProcucerOther
 };
 
+/// Base class describing the header of any kind of "unit."  Some information
+/// is specific to certain unit types.  We separate this class out so we can
+/// parse the header before deciding what specific kind of unit to construct.
+class DWARFUnitHeader {
+  dw_offset_t m_offset = 0;
+  dw_offset_t m_length = 0;
+  uint16_t m_version = 0;
+  dw_offset_t m_abbr_offset = 0;
+  uint8_t m_unit_type = 0;
+  uint8_t m_addr_size = 0;
+  uint64_t m_dwo_id = 0;
+
+  DWARFUnitHeader() = default;
+
+public:
+  dw_offset_t GetOffset() const { return m_offset; }
+  uint16_t GetVersion() const { return m_version; }
+  uint16_t GetAddressByteSize() const { return m_addr_size; }
+  dw_offset_t GetLength() const { return m_length; }
+  dw_offset_t GetAbbrOffset() const { return m_abbr_offset; }
+  uint8_t GetUnitType() const { return m_unit_type; }
+  bool IsTypeUnit() const {
+    return m_unit_type == DW_UT_type || m_unit_type == DW_UT_split_type;
+  }
+  uint32_t GetNextUnitOffset() const { return m_offset + m_length + 4; }
+
+  static llvm::Expected<DWARFUnitHeader>
+  extract(const lldb_private::DWARFDataExtractor &data,
+          lldb::offset_t *offset_ptr);
+};
+
 class DWARFUnit : public lldb_private::UserID {
   using die_iterator_range =
       llvm::iterator_range<DWARFDebugInfoEntry::collection::iterator>;
 
 public:
+  static llvm::Expected<DWARFUnitSP>
+  extract(SymbolFileDWARF *dwarf2Data, lldb::user_id_t uid,
+          const lldb_private::DWARFDataExtractor &debug_info,
+          lldb::offset_t *offset_ptr);
   virtual ~DWARFUnit();
 
   void ExtractUnitDIEIfNeeded();
@@ -66,14 +101,16 @@
   ///
   /// \return
   ///   The correct data for the DIE information in this unit.
-  virtual const lldb_private::DWARFDataExtractor &GetData() const = 0;
-  /// Get the size in bytes of the compile unit header.
+  const lldb_private::DWARFDataExtractor &GetData() const;
+
+  /// Get the size in bytes of the unit header.
   ///
   /// \return
-  ///     Byte size of the compile unit header
-  virtual uint32_t GetHeaderByteSize() const = 0;
+  ///     Byte size of the unit header
+  uint32_t GetHeaderByteSize() const;
+
   // Offset of the initial length field.
-  dw_offset_t GetOffset() const { return m_offset; }
+  dw_offset_t GetOffset() const { return m_header.GetOffset(); }
   /// Get the size in bytes of the length field in the header.
   ///
   /// In DWARF32 this is just 4 bytes
@@ -87,17 +124,17 @@
            die_offset < GetNextUnitOffset();
   }
   dw_offset_t GetFirstDIEOffset() const {
-    return m_offset + GetHeaderByteSize();
+    return GetOffset() + GetHeaderByteSize();
   }
-  dw_offset_t GetNextUnitOffset() const;
+  dw_offset_t GetNextUnitOffset() const { return m_header.GetNextUnitOffset(); }
   // Size of the CU data (without initial length and without header).
   size_t GetDebugInfoSize() const;
   // Size of the CU data incl. header but without initial length.
-  uint32_t GetLength() const { return m_length; }
-  uint16_t GetVersion() const { return m_version; }
+  uint32_t GetLength() const { return m_header.GetLength(); }
+  uint16_t GetVersion() const { return m_header.GetVersion(); }
   const DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
   dw_offset_t GetAbbrevOffset() const;
-  uint8_t GetAddressByteSize() const { return m_addr_size; }
+  uint8_t GetAddressByteSize() const { return m_header.GetAddressByteSize(); }
   dw_addr_t GetBaseAddress() const { return m_base_addr; }
   dw_addr_t GetAddrBase() const { return m_addr_base; }
   dw_addr_t GetRangesBase() const { return m_ranges_base; }
@@ -170,10 +207,13 @@
   virtual DIERef::Section GetDebugSection() const = 0;
 
 protected:
-  DWARFUnit(SymbolFileDWARF *dwarf, lldb::user_id_t uid);
+  DWARFUnit(SymbolFileDWARF *dwarf, lldb::user_id_t uid,
+            const DWARFUnitHeader &header,
+            const DWARFAbbreviationDeclarationSet &abbrevs);
 
   SymbolFileDWARF *m_dwarf = nullptr;
   std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file;
+  DWARFUnitHeader m_header;
   const DWARFAbbreviationDeclarationSet *m_abbrevs = nullptr;
   void *m_user_data = nullptr;
   // The compile unit debug information entry item
@@ -193,11 +233,6 @@
   // exact DW_TAG_subprogram DIEs
   std::unique_ptr<DWARFDebugAranges> m_func_aranges_up;
   dw_addr_t m_base_addr = 0;
-  dw_offset_t m_length = 0;
-  uint16_t m_version = 0;
-  uint8_t m_addr_size = 0;
-  uint8_t m_unit_type = 0;
-  uint64_t m_dwo_id = 0;
   DWARFProducer m_producer = eProducerInvalid;
   uint32_t m_producer_version_major = 0;
   uint32_t m_producer_version_minor = 0;
@@ -211,8 +246,6 @@
   // in the main object file
   dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET;
   dw_offset_t m_str_offsets_base = 0; // Value of DW_AT_str_offsets_base.
-  // Offset of the initial length field.
-  dw_offset_t m_offset;
 
 private:
   void ParseProducerInfo();
Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -16,7 +16,9 @@
 #include "lldb/Utility/LLDBAssert.h"
 #include "lldb/Utility/StreamString.h"
 #include "lldb/Utility/Timer.h"
+#include "llvm/Object/Error.h"
 
+#include "DWARFCompileUnit.h"
 #include "DWARFDebugAranges.h"
 #include "DWARFDebugInfo.h"
 #include "LogChannelDWARF.h"
@@ -29,10 +31,13 @@
 
 extern int g_verbose;
 
-DWARFUnit::DWARFUnit(SymbolFileDWARF *dwarf, user_id_t uid)
-    : UserID(uid), m_dwarf(dwarf), m_cancel_scopes(false) {}
+DWARFUnit::DWARFUnit(SymbolFileDWARF *dwarf, lldb::user_id_t uid,
+                     const DWARFUnitHeader &header,
+                     const DWARFAbbreviationDeclarationSet &abbrevs)
+    : UserID(uid), m_dwarf(dwarf), m_header(header), m_abbrevs(&abbrevs),
+      m_cancel_scopes(false) {}
 
-DWARFUnit::~DWARFUnit() {}
+DWARFUnit::~DWARFUnit() = default;
 
 // Parses first DIE of a compile unit.
 void DWARFUnit::ExtractUnitDIEIfNeeded() {
@@ -46,8 +51,8 @@
     return; // Already parsed
 
   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
-  Timer scoped_timer(
-      func_cat, "%8.8x: DWARFUnit::ExtractUnitDIEIfNeeded()", m_offset);
+  Timer scoped_timer(func_cat, "%8.8x: DWARFUnit::ExtractUnitDIEIfNeeded()",
+                     GetOffset());
 
   // Set the offset to that of the first DIE and calculate the start of the
   // next compilation unit header.
@@ -145,8 +150,8 @@
   llvm::sys::ScopedWriter first_die_lock(m_first_die_mutex);
 
   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
-  Timer scoped_timer(
-      func_cat, "%8.8x: DWARFUnit::ExtractDIEsIfNeeded()", m_offset);
+  Timer scoped_timer(func_cat, "%8.8x: DWARFUnit::ExtractDIEsIfNeeded()",
+                     GetOffset());
 
   // Set the offset to that of the first DIE and calculate the start of the
   // next compilation unit header.
@@ -332,7 +337,7 @@
                                                      DW_AT_GNU_ranges_base, 0);
   dwo_cu->SetRangesBase(ranges_base);
 
-  dwo_cu->SetBaseObjOffset(m_offset);
+  dwo_cu->SetBaseObjOffset(GetOffset());
 
   SetDwoStrOffsetsBase(dwo_cu);
 }
@@ -366,10 +371,6 @@
   return dies.size() - old_size;
 }
 
-dw_offset_t DWARFUnit::GetNextUnitOffset() const {
-  return m_offset + GetLengthByteSize() + GetLength();
-}
-
 size_t DWARFUnit::GetDebugInfoSize() const {
   return GetLengthByteSize() + GetLength() - GetHeaderByteSize();
 }
@@ -790,3 +791,92 @@
   return *m_func_aranges_up;
 }
 
+llvm::Expected<DWARFUnitHeader>
+DWARFUnitHeader::extract(const DWARFDataExtractor &data,
+                         lldb::offset_t *offset_ptr) {
+  DWARFUnitHeader header;
+  header.m_offset = *offset_ptr;
+  header.m_length = data.GetDWARFInitialLength(offset_ptr);
+  header.m_version = data.GetU16(offset_ptr);
+  if (header.m_version == 5) {
+    header.m_unit_type = data.GetU8(offset_ptr);
+    header.m_addr_size = data.GetU8(offset_ptr);
+    header.m_abbr_offset = data.GetDWARFOffset(offset_ptr);
+    if (header.m_unit_type == llvm::dwarf::DW_UT_skeleton)
+      header.m_dwo_id = data.GetU64(offset_ptr);
+  } else {
+    header.m_abbr_offset = data.GetDWARFOffset(offset_ptr);
+    header.m_addr_size = data.GetU8(offset_ptr);
+    // Only compile units supported so far.
+    header.m_unit_type = DW_UT_compile;
+  }
+
+  bool length_OK = data.ValidOffset(header.GetNextUnitOffset() - 1);
+  bool version_OK = SymbolFileDWARF::SupportedVersion(header.m_version);
+  bool addr_size_OK = (header.m_addr_size == 4) || (header.m_addr_size == 8);
+
+  if (!length_OK)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Invalid unit length");
+  if (!version_OK)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Unsupported unit version");
+  if (!addr_size_OK)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Invalid unit address size");
+
+  return header;
+}
+
+llvm::Expected<DWARFUnitSP>
+DWARFUnit::extract(SymbolFileDWARF *dwarf, user_id_t uid,
+                   const DWARFDataExtractor &debug_info,
+                   lldb::offset_t *offset_ptr) {
+  assert(debug_info.ValidOffset(*offset_ptr));
+
+  auto expected_header = DWARFUnitHeader::extract(debug_info, offset_ptr);
+  if (!expected_header)
+    return expected_header.takeError();
+
+  const DWARFDebugAbbrev *abbr = dwarf->DebugAbbrev();
+  if (!abbr)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "No debug_abbrev data");
+
+  bool abbr_offset_OK =
+      dwarf->GetDWARFContext().getOrLoadAbbrevData().ValidOffset(
+          expected_header->GetAbbrOffset());
+  if (!abbr_offset_OK)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Abbreviation offset for unit is not valid");
+
+  const DWARFAbbreviationDeclarationSet *abbrevs =
+      abbr->GetAbbreviationDeclarationSet(expected_header->GetAbbrOffset());
+  if (!abbrevs)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "No abbrev exists at the specified offset.");
+
+  DWARFUnitSP unit_sp(
+      new DWARFCompileUnit(dwarf, uid, *expected_header, *abbrevs));
+
+  return unit_sp;
+}
+
+const lldb_private::DWARFDataExtractor &DWARFUnit::GetData() const {
+  return m_dwarf->GetDWARFContext().getOrLoadDebugInfoData();
+}
+
+uint32_t DWARFUnit::GetHeaderByteSize() const {
+  switch (m_header.GetUnitType()) {
+  case llvm::dwarf::DW_UT_compile:
+  case llvm::dwarf::DW_UT_partial:
+    return GetVersion() < 5 ? 11 : 12;
+  case llvm::dwarf::DW_UT_skeleton:
+  case llvm::dwarf::DW_UT_split_compile:
+    return 20;
+  case llvm::dwarf::DW_UT_type:
+  case llvm::dwarf::DW_UT_split_type:
+    return GetVersion() < 5 ? 23 : 24;
+  }
+  llvm_unreachable("invalid UnitType.");
+}
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -81,23 +81,22 @@
 
   lldb::offset_t offset = 0;
   const auto &debug_info_data = m_context.getOrLoadDebugInfoData();
-
   while (debug_info_data.ValidOffset(offset)) {
-    llvm::Expected<DWARFUnitSP> cu_sp = DWARFCompileUnit::extract(
+    llvm::Expected<DWARFUnitSP> unit_sp = DWARFUnit::extract(
         m_dwarf2Data, m_units.size(), debug_info_data, &offset);
 
-    if (!cu_sp) {
+    if (!unit_sp) {
       // FIXME: Propagate this error up.
-      llvm::consumeError(cu_sp.takeError());
+      llvm::consumeError(unit_sp.takeError());
       return;
     }
 
     // If it didn't return an error, then it should be returning a valid Unit.
-    assert(*cu_sp);
+    assert(*unit_sp);
 
-    m_units.push_back(*cu_sp);
+    m_units.push_back(*unit_sp);
 
-    offset = (*cu_sp)->GetNextUnitOffset();
+    offset = (*unit_sp)->GetNextUnitOffset();
   }
 }
 
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -14,33 +14,21 @@
 
 class DWARFCompileUnit : public DWARFUnit {
 public:
-  static llvm::Expected<DWARFUnitSP>
-  extract(SymbolFileDWARF *dwarf2Data, lldb::user_id_t uid,
-          const lldb_private::DWARFDataExtractor &debug_info,
-          lldb::offset_t *offset_ptr);
   void Dump(lldb_private::Stream *s) const override;
 
-  /// Get the data that contains the DIE information for this unit.
-  ///
-  /// \return
-  ///   The correct data (.debug_types for DWARF 4 and earlier, and
-  ///   .debug_info for DWARF 5 and later) for the DIE information in
-  ///   this unit.
-  const lldb_private::DWARFDataExtractor &GetData() const override;
-
-  /// Get the size in bytes of the header.
-  ///
-  /// \return
-  ///     Byte size of the compile unit header
-  uint32_t GetHeaderByteSize() const override;
-
   DIERef::Section GetDebugSection() const override {
     return DIERef::Section::DebugInfo;
   }
 
 private:
-  DWARFCompileUnit(SymbolFileDWARF *dwarf2Data, lldb::user_id_t uid);
+  DWARFCompileUnit(SymbolFileDWARF *dwarf, lldb::user_id_t uid,
+                   const DWARFUnitHeader &header,
+                   const DWARFAbbreviationDeclarationSet &abbrevs)
+      : DWARFUnit(dwarf, uid, header, abbrevs) {}
+
   DISALLOW_COPY_AND_ASSIGN(DWARFCompileUnit);
+
+  friend class DWARFUnit;
 };
 
 #endif // SymbolFileDWARF_DWARFCompileUnit_h_
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -8,104 +8,15 @@
 
 #include "DWARFCompileUnit.h"
 
-#include "SymbolFileDWARF.h"
 #include "lldb/Utility/Stream.h"
-#include "llvm/Object/Error.h"
 
 using namespace lldb;
 using namespace lldb_private;
 
-DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF *dwarf2Data,
-                                   lldb::user_id_t uid)
-    : DWARFUnit(dwarf2Data, uid) {}
-
-
-llvm::Expected<DWARFUnitSP> DWARFCompileUnit::extract(
-    SymbolFileDWARF *dwarf2Data, user_id_t uid,
-    const DWARFDataExtractor &debug_info, lldb::offset_t *offset_ptr) {
-  assert(debug_info.ValidOffset(*offset_ptr));
-
-  // std::make_shared would require the ctor to be public.
-  std::shared_ptr<DWARFCompileUnit> cu_sp(
-      new DWARFCompileUnit(dwarf2Data, uid));
-
-  cu_sp->m_offset = *offset_ptr;
-
-  dw_offset_t abbr_offset;
-  const DWARFDebugAbbrev *abbr = dwarf2Data->DebugAbbrev();
-  if (!abbr)
-    return llvm::make_error<llvm::object::GenericBinaryError>(
-        "No debug_abbrev data");
-
-  cu_sp->m_length = debug_info.GetDWARFInitialLength(offset_ptr);
-  cu_sp->m_version = debug_info.GetU16(offset_ptr);
-
-  if (cu_sp->m_version == 5) {
-    cu_sp->m_unit_type = debug_info.GetU8(offset_ptr);
-    cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
-    abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
-
-    if (cu_sp->m_unit_type == llvm::dwarf::DW_UT_skeleton)
-      cu_sp->m_dwo_id = debug_info.GetU64(offset_ptr);
-  } else {
-    abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
-    cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
-  }
-
-  bool length_OK = debug_info.ValidOffset(cu_sp->GetNextUnitOffset() - 1);
-  bool version_OK = SymbolFileDWARF::SupportedVersion(cu_sp->m_version);
-  bool abbr_offset_OK =
-      dwarf2Data->GetDWARFContext().getOrLoadAbbrevData().ValidOffset(
-          abbr_offset);
-  bool addr_size_OK = (cu_sp->m_addr_size == 4) || (cu_sp->m_addr_size == 8);
-
-  if (!length_OK)
-    return llvm::make_error<llvm::object::GenericBinaryError>(
-        "Invalid compile unit length");
-  if (!version_OK)
-    return llvm::make_error<llvm::object::GenericBinaryError>(
-        "Unsupported compile unit version");
-  if (!abbr_offset_OK)
-    return llvm::make_error<llvm::object::GenericBinaryError>(
-        "Abbreviation offset for compile unit is not valid");
-  if (!addr_size_OK)
-    return llvm::make_error<llvm::object::GenericBinaryError>(
-        "Invalid compile unit address size");
-
-  cu_sp->m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset);
-  if (!cu_sp->m_abbrevs)
-    return llvm::make_error<llvm::object::GenericBinaryError>(
-        "No abbrev exists at the specified offset.");
-
-  return cu_sp;
-}
-
 void DWARFCompileUnit::Dump(Stream *s) const {
   s->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, "
             "abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at "
             "{0x%8.8x})\n",
-            m_offset, m_length, m_version, GetAbbrevOffset(), m_addr_size,
-            GetNextUnitOffset());
-}
-
-uint32_t DWARFCompileUnit::GetHeaderByteSize() const {
-  if (m_version < 5)
-    return 11;
-
-  switch (m_unit_type) {
-  case llvm::dwarf::DW_UT_compile:
-  case llvm::dwarf::DW_UT_partial:
-    return 12;
-  case llvm::dwarf::DW_UT_skeleton:
-  case llvm::dwarf::DW_UT_split_compile:
-    return 20;
-  case llvm::dwarf::DW_UT_type:
-  case llvm::dwarf::DW_UT_split_type:
-    return 24;
-  }
-  llvm_unreachable("invalid UnitType.");
-}
-
-const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const {
-  return m_dwarf->GetDWARFContext().getOrLoadDebugInfoData();
+            GetOffset(), GetLength(), GetVersion(), GetAbbrevOffset(),
+            GetAddressByteSize(), GetNextUnitOffset());
 }
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to