jankratochvil updated this revision to Diff 374774.
jankratochvil retitled this revision from "[lldb] DWZ 4/9: DIERef support" to 
"[lldb] DWZ 12/17: DIERef support".
jankratochvil edited the summary of this revision.
jankratochvil added a comment.

My question about upstreaming of this patchset. 
<https://reviews.llvm.org/D96236#3020116>


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D96239

Files:
  lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
  lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
  lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h

Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -318,6 +318,8 @@
   /// Same as GetLanguage() but reports all C++ versions as C++ (no version).
   static lldb::LanguageType GetLanguageFamily(DWARFUnit &unit);
 
+  llvm::Optional<uint32_t> GetDWARFUnitIndex(uint32_t cu_idx);
+
 protected:
   typedef llvm::DenseMap<DIERef, lldb_private::Type *> DIERefToTypePtr;
   typedef llvm::DenseMap<DIERef, lldb::VariableSP> DIERefToVariableSP;
@@ -471,7 +473,6 @@
   }
 
   void BuildCuTranslationTable();
-  llvm::Optional<uint32_t> GetDWARFUnitIndex(uint32_t cu_idx);
 
   struct DecodedUID {
     SymbolFileDWARF &dwarf;
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1341,10 +1341,31 @@
   if (GetDebugMapSymfile())
     return GetID() | ref.die_offset();
 
-  lldbassert(GetDwoNum().getValueOr(0) <= 0x3fffffff);
-  return user_id_t(GetDwoNum().getValueOr(0)) << 32 | ref.die_offset() |
-         lldb::user_id_t(GetDwoNum().hasValue()) << 62 |
-         lldb::user_id_t(ref.section() == DIERef::Section::DebugTypes) << 63;
+#ifndef NDEBUG
+  DWARFDIE dwarfdie_check = GetDIE(ref);
+  lldbassert(dwarfdie_check.IsValid());
+  lldbassert(*dwarfdie_check.GetDIERef() == ref);
+#endif
+
+  // WARNING: Use ref.dwo_num() as GetDwoNum() may not be valid in 'this'.
+  static_assert(sizeof(ref.die_offset()) * 8 == 32, "");
+  lldbassert(!ref.dwo_num().hasValue() || *ref.dwo_num() <= 0x1fffffff);
+  lldbassert(!ref.main_cu().hasValue() || *ref.main_cu() <= 0x1fffffff);
+  lldbassert(0 <= ref.kind_get());
+  lldbassert(ref.kind_get() <= 3);
+  user_id_t retval =
+      user_id_t(ref.dwo_num() ? *ref.dwo_num()
+                              : (ref.main_cu() ? *ref.main_cu() : 0))
+          << 32 |
+      ref.die_offset() | user_id_t(ref.kind_get()) << 61 |
+      lldb::user_id_t(ref.section() == DIERef::Section::DebugTypes) << 63;
+
+#ifndef NDEBUG
+  DWARFDIE dwarfdie_check2 = GetDIE(retval);
+  lldbassert(dwarfdie_check2 == dwarfdie_check);
+#endif
+
+  return retval;
 }
 
 llvm::Optional<SymbolFileDWARF::DecodedUID>
@@ -1362,8 +1383,9 @@
   if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) {
     SymbolFileDWARF *dwarf = debug_map->GetSymbolFileByOSOIndex(
         debug_map->GetOSOIndexFromUserID(uid));
-    return DecodedUID{
-        *dwarf, {llvm::None, DIERef::Section::DebugInfo, dw_offset_t(uid)}};
+    return DecodedUID{*dwarf,
+                      {llvm::None, llvm::None, DIERef::MainDwz,
+                       DIERef::Section::DebugInfo, dw_offset_t(uid)}};
   }
   dw_offset_t die_offset = uid;
   if (die_offset == DW_INVALID_OFFSET)
@@ -1372,12 +1394,14 @@
   DIERef::Section section =
       uid >> 63 ? DIERef::Section::DebugTypes : DIERef::Section::DebugInfo;
 
+  DIERef::Kind kind = DIERef::Kind(uid >> 61 & 3);
+
   llvm::Optional<uint32_t> dwo_num;
-  bool dwo_valid = uid >> 62 & 1;
-  if (dwo_valid)
-    dwo_num = uid >> 32 & 0x3fffffff;
+  if (kind == DIERef::Kind::DwoKind)
+    dwo_num = uid >> 32 & 0x1fffffff;
 
-  return DecodedUID{*this, {dwo_num, section, die_offset}};
+  return DecodedUID{
+      *this, {dwo_num, llvm::None, DIERef::MainDwz, section, die_offset}};
 }
 
 DWARFDIE
@@ -1639,7 +1663,7 @@
 DWARFDIE
 SymbolFileDWARF::GetDIE(const DIERef &die_ref) {
   if (die_ref.dwo_num()) {
-    SymbolFileDWARF *dwarf = *die_ref.dwo_num() == 0x3fffffff
+    SymbolFileDWARF *dwarf = *die_ref.dwo_num() == 0x1fffffff
                                  ? m_dwp_symfile.get()
                                  : this->DebugInfo()
                                        .GetUnitAtIndex(*die_ref.dwo_num())
@@ -1728,6 +1752,7 @@
   if (dwo_obj_file == nullptr)
     return nullptr;
 
+  lldbassert(dwarf_cu->GetID() < 0x1fffffff);
   return std::make_shared<SymbolFileDWARFDwo>(*this, dwo_obj_file,
                                               dwarf_cu->GetID());
 }
@@ -3870,7 +3895,7 @@
       if (!dwp_obj_file)
         return;
       m_dwp_symfile =
-          std::make_shared<SymbolFileDWARFDwo>(*this, dwp_obj_file, 0x3fffffff);
+          std::make_shared<SymbolFileDWARFDwo>(*this, dwp_obj_file, 0x1fffffff);
     }
   });
   return m_dwp_symfile;
Index: lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
@@ -7,7 +7,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "NameToDIE.h"
+#include "DWARFDebugInfo.h"
 #include "DWARFUnit.h"
+#include "lldb/Core/Module.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Utility/ConstString.h"
 #include "lldb/Utility/RegularExpression.h"
@@ -48,16 +50,24 @@
     DWARFUnit &s_unit, llvm::function_ref<bool(DIERef ref)> callback) const {
   lldbassert(!s_unit.GetSymbolFileDWARF().GetDwoNum());
   const DWARFUnit &ns_unit = s_unit.GetNonSkeletonUnit();
+  SymbolFileDWARF *ns_symfile = &ns_unit.GetSymbolFileDWARF();
   const uint32_t size = m_map.GetSize();
   for (uint32_t i = 0; i < size; ++i) {
     const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i);
-    if (ns_unit.GetSymbolFileDWARF().GetDwoNum() == die_ref.dwo_num() &&
-        ns_unit.GetDebugSection() == die_ref.section() &&
-        ns_unit.GetOffset() <= die_ref.die_offset() &&
-        die_ref.die_offset() < ns_unit.GetNextUnitOffset()) {
-      if (!callback(die_ref))
-        return;
-    }
+    if (ns_unit.GetDebugSection() != die_ref.section())
+      continue;
+    if (die_ref.main_cu()) {
+      DWARFDebugInfo &ns_info = ns_symfile->DebugInfo();
+      DWARFUnit *die_main_unit = ns_info.GetUnitAtIndex(
+          *ns_symfile->GetDWARFUnitIndex(*die_ref.main_cu()));
+      if (&ns_unit != die_main_unit)
+        continue;
+    } else if (!(ns_symfile->GetDwoNum() == die_ref.dwo_num() &&
+                 ns_unit.GetOffset() <= die_ref.die_offset() &&
+                 die_ref.die_offset() < ns_unit.GetNextUnitOffset()))
+      continue;
+    if (!callback(die_ref))
+      return;
   }
 }
 
Index: lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
+++ lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
@@ -65,7 +65,8 @@
     DIEInfo(dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h);
 
     explicit operator DIERef() const {
-      return DIERef(llvm::None, DIERef::Section::DebugInfo, die_offset);
+      return DIERef(llvm::None, llvm::None, DIERef::MainDwz,
+                    DIERef::Section::DebugInfo, die_offset);
     }
   };
 
Index: lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -53,8 +53,9 @@
   cu = &cu->GetNonSkeletonUnit();
   if (llvm::Optional<uint64_t> die_offset = entry.getDIEUnitOffset())
     // FIXME: .debug_names have no DWZ support yet.
-    return DIERef(cu->GetSymbolFileDWARF().GetDwoNum(),
-                  DIERef::Section::DebugInfo, cu->GetOffset() + *die_offset);
+    return DIERef(cu->GetSymbolFileDWARF().GetDwoNum(), llvm::None,
+                  DIERef::MainDwz, DIERef::Section::DebugInfo,
+                  cu->GetOffset() + *die_offset);
 
   return llvm::None;
 }
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
@@ -24,8 +24,17 @@
   if (!IsValid())
     return llvm::None;
 
-  return DIERef(m_cu->GetSymbolFileDWARF().GetDwoNum(), m_cu->GetDebugSection(),
-                m_die->GetOffset());
+  DWARFUnit *main_unit = GetMainCU();
+
+  if (GetCU()->GetSymbolFileDWARF().GetDwoNum().hasValue())
+    main_unit = nullptr;
+  if (GetCU().GetCU() == main_unit)
+    main_unit = nullptr;
+
+  return DIERef(
+      m_cu->GetSymbolFileDWARF().GetDwoNum(),
+      (!main_unit ? llvm::None : llvm::Optional<uint32_t>(main_unit->GetID())),
+      DIERef::MainDwz, m_cu->GetDebugSection(), m_die->GetOffset());
 }
 
 dw_tag_t DWARFBaseDIE::Tag() const {
Index: lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
@@ -16,10 +16,15 @@
 #include <cassert>
 #include <vector>
 
-/// Identifies a DWARF debug info entry within a given Module. It contains three
-/// "coordinates":
-/// - dwo_num: identifies the dwo file in the Module. If this field is not set,
-///   the DIERef references the main file.
+/// Identifies a DWARF debug info entry within a given Module. It contains
+/// multiple "coordinates":
+/// - dwo_num: -gsplit-dwarf only: identifies the dwo file in the Module.
+///   If this field is not set, the DIERef references the main file.
+/// - main_cu: DWZ only: index of main compilation unit which used
+///   DW_TAG_imported_unit for this DIERef or some its parent.
+///   For transitive imports this is the very first CU.
+///   It is always a CU in the main file (and not DWZ common symbol file).
+/// - DWZ common flag: DWZ only: the DIE is in a shared DWZ common symbol file.
 /// - section: identifies the section of the debug info entry in the given file:
 ///   debug_info or debug_types.
 /// - die_offset: The offset of the debug info entry as an absolute offset from
@@ -28,39 +33,75 @@
 public:
   enum Section : uint8_t { DebugInfo, DebugTypes };
 
-  DIERef(llvm::Optional<uint32_t> dwo_num, Section section,
-         dw_offset_t die_offset)
-      : m_u(dwo_num, section), m_die_offset(die_offset) {
+  // DWZ only: Is the DIE located in DWZ common symbol file?
+  enum DwzCommon : uint8_t { MainDwz, CommonDwz };
+
+  enum Kind : uint8_t {
+    NoneKind,
+
+    // DWZ only: The DIE is in DW_TAG_partial_unit in main symbol file and it
+    // needs main_cu.
+    MainDwzKind,
+
+    // -gsplit-dwarf only: The DIE is in a separate dwo file specified by
+    // dwo_num.
+    DwoKind,
+
+    // DWZ only: The DIE is in DW_TAG_partial_unit in DWZ common symbol file and
+    // it needs main_cu.
+    DwzCommonKind
+  };
+
+  DIERef(llvm::Optional<uint32_t> dwo_num, llvm::Optional<uint32_t> main_cu,
+         DwzCommon dwz_common, Section section, dw_offset_t die_offset)
+      : m_u(dwo_num, main_cu, dwz_common, section), m_die_offset(die_offset) {
     assert(this->dwo_num() == dwo_num && "Dwo number out of range?");
+    assert(this->main_cu() == main_cu && "Main Cu number out of range?");
+    assert(dwz_common == MainDwz || main_cu);
   }
 
   llvm::Optional<uint32_t> dwo_num() const {
-    if (m_u.s.dwo_num_valid)
-      return m_u.s.dwo_num;
+    if (m_u.s.data_kind == DwoKind)
+      return m_u.s.data;
     return llvm::None;
   }
 
+  // It indexes DWARFCompileUnit's excl. DWARFTypeUnit's.
+  // It is the index used as parameter of SymbolFileDWARF::GetDWARFUnitIndex.
+  llvm::Optional<uint32_t> main_cu() const {
+    if (m_u.s.data_kind == MainDwzKind || m_u.s.data_kind == DwzCommonKind)
+      return m_u.s.data;
+    return llvm::None;
+  }
+
+  DwzCommon dwz_common() const {
+    assert(m_u.s.data_kind == MainDwzKind || m_u.s.data_kind == DwzCommonKind);
+    return m_u.s.data_kind == MainDwzKind ? MainDwz : CommonDwz;
+  }
+
+  Kind kind_get() const { return Kind(m_u.s.data_kind); }
+
   Section section() const { return static_cast<Section>(m_u.s.section); }
 
   dw_offset_t die_offset() const { return m_die_offset; }
 
   bool operator<(DIERef other) const {
-    if (m_u.s.dwo_num_valid != other.m_u.s.dwo_num_valid)
-      return m_u.s.dwo_num_valid < other.m_u.s.dwo_num_valid;
-    // Assuming if not m_u.s.dwo_num_valid then m_u.s.dwo_num is zero.
-    if (m_u.s.dwo_num != other.m_u.s.dwo_num)
-      return m_u.s.dwo_num < other.m_u.s.dwo_num;
+    if (m_u.s.data_kind != other.m_u.s.data_kind)
+      return m_u.s.data_kind < other.m_u.s.data_kind;
+    // Assuming if m_u.s.data_kind == NoneKind then m_u.s.data is zero.
+    if (m_u.s.data != other.m_u.s.data)
+      return m_u.s.data < other.m_u.s.data;
     if (m_u.s.section != other.m_u.s.section)
       return m_u.s.section < other.m_u.s.section;
     return m_die_offset < other.m_die_offset;
   }
 
   bool operator==(DIERef other) const {
-    if (m_u.s.dwo_num_valid != other.m_u.s.dwo_num_valid)
-      return m_u.s.dwo_num_valid == other.m_u.s.dwo_num_valid;
-    // Assuming if not m_u.s.dwo_num_valid then m_u.s.dwo_num is zero.
-    if (m_u.s.dwo_num != other.m_u.s.dwo_num)
-      return m_u.s.dwo_num == other.m_u.s.dwo_num;
+    if (m_u.s.data_kind != other.m_u.s.data_kind)
+      return m_u.s.data_kind == other.m_u.s.data_kind;
+    // Assuming if m_u.s.data_kind == NoneKind then m_u.s.data is zero.
+    if (m_u.s.data != other.m_u.s.data)
+      return m_u.s.data == other.m_u.s.data;
     if (m_u.s.section != other.m_u.s.section)
       return m_u.s.section == other.m_u.s.section;
     return m_die_offset == other.m_die_offset;
@@ -68,8 +109,9 @@
 
 private:
   friend struct llvm::DenseMapInfo<DIERef>;
-  DIERef(unsigned unique) : m_u(llvm::None, DebugInfo), m_die_offset(0) {
-    m_u.s.dwo_num = unique;
+  DIERef(unsigned unique)
+      : m_u(llvm::None, llvm::None, MainDwz, DebugInfo), m_die_offset(0) {
+    m_u.s.data = unique;
   }
   uint32_t get_hash_value() const {
     return llvm::detail::combineHashValue(m_u.hash_bits, m_die_offset);
@@ -77,16 +119,23 @@
 
   union U {
     struct S {
-      uint32_t dwo_num : 30;
-      uint32_t dwo_num_valid : 1;
-      uint32_t section : 1;
-      S(llvm::Optional<uint32_t> dwo_num_, Section section_)
-          : dwo_num(dwo_num_.getValueOr(0)), dwo_num_valid(bool(dwo_num_)),
+      uint32_t data : 29;
+      uint32_t data_kind : 2; // Kind type
+      uint32_t section : 1;   // Section type
+      S(llvm::Optional<uint32_t> dwo_num, llvm::Optional<uint32_t> main_cu,
+        DwzCommon dwz_common, Section section_)
+          : data(dwo_num.getValueOr(0) | main_cu.getValueOr(0)),
+            data_kind(dwo_num
+                          ? DwoKind
+                          : (main_cu ? (dwz_common == MainDwz ? MainDwzKind
+                                                              : DwzCommonKind)
+                                     : NoneKind)),
             section(section_) {}
     } s;
     uint32_t hash_bits;
-    U(llvm::Optional<uint32_t> dwo_num, Section section)
-        : s(dwo_num, section) {}
+    U(llvm::Optional<uint32_t> dwo_num, llvm::Optional<uint32_t> main_cu,
+      DwzCommon dwz_common, Section section)
+        : s(dwo_num, main_cu, dwz_common, section) {}
   } m_u;
   dw_offset_t m_die_offset;
 };
Index: lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
@@ -13,6 +13,19 @@
                                            StringRef Style) {
   if (ref.dwo_num())
     OS << format_hex_no_prefix(*ref.dwo_num(), 8) << "/";
-  OS << (ref.section() == DIERef::DebugInfo ? "INFO" : "TYPE");
+  if (ref.main_cu())
+    OS << format_hex_no_prefix(*ref.main_cu(), 8) << "/";
+  OS << (ref.section() == DIERef::Section::DebugInfo ? "INFO" : "TYPE");
+  switch (ref.kind_get()) {
+  case DIERef::Kind::NoneKind:
+  case DIERef::Kind::DwoKind:
+    break;
+  case DIERef::Kind::MainDwzKind:
+    OS << "/DWZ";
+    break;
+  case DIERef::Kind::DwzCommonKind:
+    OS << "/DWZCOMMON";
+    break;
+  }
   OS << "/" << format_hex_no_prefix(ref.die_offset(), 8);
 }
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
  • [Lldb-commits] [PATCH] D96... Jan Kratochvil via Phabricator via lldb-commits

Reply via email to