jankratochvil created this revision.
jankratochvil added reviewers: labath, clayborg.
jankratochvil added a project: LLDB.
Herald added subscribers: JDevlieghere, arphaman.
jankratochvil requested review of this revision.
DIERef needs to contain more context information as DWZ needs to track main
unit and it also needs to locate some DIEs in a separate shared common file in
`/usr/lib/debug/.dwz/` .
All DWZ patches are also applied at: `git clone -b dwz
git://git.jankratochvil.net/lldb`
There is a copy: `git clone -b dwz
https://github.com/jankratochvil/llvm-project`
Repository:
rG LLVM Github Monorepo
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/SymbolFileDWARF.cpp
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1300,10 +1300,15 @@
// 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() <= 0x3fffffff);
+ 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().getValueOr(0)) << 32 | ref.die_offset() |
- lldb::user_id_t(ref.dwo_num().hasValue()) << 62 |
+ 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
@@ -1330,8 +1335,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)
@@ -1340,12 +1346,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
@@ -1619,7 +1627,7 @@
DWARFDIE
SymbolFileDWARF::GetDIE(const DIERef &die_ref, DWARFUnit **main_unit_return) {
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())
@@ -1712,6 +1720,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());
}
@@ -3958,7 +3967,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/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
@@ -52,8 +52,9 @@
cu = &cu->GetNonSkeletonUnit();
if (llvm::Optional<uint64_t> die_offset = entry.getDIEUnitOffset())
- 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
@@ -27,8 +27,10 @@
if (m_cu == main_unit)
main_unit = nullptr;
- return DIERef(m_cu->GetSymbolFileDWARF().GetDwoNum(), m_cu->GetDebugSection(),
- m_die->GetOffset());
+ 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
@@ -15,10 +15,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
@@ -27,46 +32,87 @@
public:
enum Section : uint8_t { DebugInfo, DebugTypes };
- DIERef(llvm::Optional<uint32_t> dwo_num, Section section,
- dw_offset_t die_offset)
- : m_dwo_num(dwo_num.getValueOr(0)), m_dwo_num_valid(bool(dwo_num)),
+ // 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_data(dwo_num.getValueOr(0) | main_cu.getValueOr(0)),
+ m_data_kind(dwo_num ? DwoKind
+ : (main_cu ? (dwz_common == MainDwz ? MainDwzKind
+ : DwzCommonKind)
+ : NoneKind)),
m_section(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_dwo_num_valid)
- return m_dwo_num;
+ if (m_data_kind == DwoKind)
+ return m_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_data_kind == MainDwzKind || m_data_kind == DwzCommonKind)
+ return m_data;
return llvm::None;
}
+ DwzCommon dwz_common() const {
+ assert(m_data_kind == MainDwzKind || m_data_kind == DwzCommonKind);
+ return m_data_kind == MainDwzKind ? MainDwz : CommonDwz;
+ }
+
+ Kind kind_get() const { return Kind(m_data_kind); }
+
Section section() const { return static_cast<Section>(m_section); }
dw_offset_t die_offset() const { return m_die_offset; }
bool operator<(DIERef other) const {
- if (m_dwo_num_valid != other.m_dwo_num_valid)
- return m_dwo_num_valid < other.m_dwo_num_valid;
- if (m_dwo_num_valid && (m_dwo_num != other.m_dwo_num))
- return m_dwo_num < other.m_dwo_num;
+ if (m_data_kind != other.m_data_kind)
+ return m_data_kind < other.m_data_kind;
+ if (m_data_kind != NoneKind && (m_data != other.m_data))
+ return m_data < other.m_data;
if (m_section != other.m_section)
return m_section < other.m_section;
return m_die_offset < other.m_die_offset;
}
bool operator==(DIERef other) const {
- if (m_dwo_num_valid != other.m_dwo_num_valid ||
- m_section != other.m_section || m_die_offset != other.m_die_offset)
- return false;
- if (m_dwo_num_valid && m_dwo_num != other.m_dwo_num)
- return false;
- return true;
+ if (m_data_kind != other.m_data_kind)
+ return m_data_kind == other.m_data_kind;
+ if (m_data_kind != NoneKind && (m_data != other.m_data))
+ return m_data == other.m_data;
+ if (m_section != other.m_section)
+ return m_section == other.m_section;
+ return m_die_offset == other.m_die_offset;
}
private:
- uint32_t m_dwo_num : 30;
- uint32_t m_dwo_num_valid : 1;
- uint32_t m_section : 1;
+ uint32_t m_data : 29;
+ uint32_t m_data_kind : 2; // Kind type
+ uint32_t m_section : 1; // Section type
dw_offset_t m_die_offset;
};
static_assert(sizeof(DIERef) == 8, "");
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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits