ayermolo created this revision.
Herald added subscribers: hoy, modimo, wenlei.
Herald added a project: All.
ayermolo requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.
Test Plan:
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D142779
Files:
lldb/include/lldb/Core/dwarf.h
lldb/include/lldb/Symbol/DWARFCallFrameInfo.h
lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s
lldb/unittests/Expression/DWARFExpressionTest.cpp
Index: lldb/unittests/Expression/DWARFExpressionTest.cpp
===================================================================
--- lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -683,7 +683,7 @@
- AbbrCode: 0x1
Values:
- CStr: "dwo_unit"
- - Value: 0x01020304
+ - Value: 0x0120304
- AbbrCode: 0x0
)";
Index: lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s
===================================================================
--- lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s
+++ lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s
@@ -8,7 +8,7 @@
# RUN: -o exit | FileCheck %s
# Failure was the block range 1..2 was not printed plus:
-# error: DW_AT_range-DW_FORM_sec_offset.s.tmp {0x0000003f}: DIE has DW_AT_ranges(0xc) attribute, but range extraction failed (missing or invalid range list table), please file a bug and attach the file at the start of this error message
+# error: DW_AT_range-DW_FORM_sec_offset.s.tmp {0x000000000000003f}: DIE has DW_AT_ranges(0xc) attribute, but range extraction failed (missing or invalid range list table), please file a bug and attach the file at the start of this error message
# CHECK-LABEL: image lookup -v -s lookup_rnglists
# CHECK: Function: id = {0x00000029}, name = "rnglists", range = [0x0000000000000000-0x0000000000000003)
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -41,7 +41,7 @@
DWARFDIE
GetDIE(const DIERef &die_ref) override;
- std::optional<uint32_t> GetDwoNum() override { return GetID() >> 32; }
+ std::optional<uint32_t> GetDwoNum() override { return GetID(); }
lldb::offset_t
GetVendorDWARFOpcodeSize(const lldb_private::DataExtractor &data,
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -29,7 +29,7 @@
: SymbolFileDWARF(objfile, objfile->GetSectionList(
/*update_module_section_list*/ false)),
m_base_symbol_file(base_symbol_file) {
- SetID(user_id_t(id) << 32);
+ SetID(id);
// Parsing of the dwarf unit index is not thread-safe, so we need to prime it
// to enable subsequent concurrent lookups.
@@ -42,7 +42,7 @@
if (auto *unit_contrib = entry->getContribution())
return llvm::dyn_cast_or_null<DWARFCompileUnit>(
DebugInfo().GetUnitAtOffset(DIERef::Section::DebugInfo,
- unit_contrib->getOffset32()));
+ unit_contrib->getOffset()));
}
return nullptr;
}
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -17,9 +17,9 @@
#include <optional>
#include <vector>
+#include "SymbolFileDWARF.h"
#include "UniqueDWARFASTType.h"
-class SymbolFileDWARF;
class DWARFCompileUnit;
class DWARFDebugAranges;
class DWARFDeclContext;
@@ -208,9 +208,9 @@
/// the given index contains.
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
- static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) {
- return (uint32_t)((uid >> 32ull) - 1ull);
- }
+ lldb::user_id_t GetUID(SymbolFileDWARF::DecodedUID decoded_uid);
+
+ std::optional<SymbolFileDWARF::DecodedUID> DecodeUID(lldb::user_id_t uid);
static SymbolFileDWARF *GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file);
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -211,7 +211,7 @@
// Set the ID of the symbol file DWARF to the index of the OSO
// shifted left by 32 bits to provide a unique prefix for any
// UserID's that get created in the symbol file.
- oso_symfile->SetID(((uint64_t)m_cu_idx + 1ull) << 32ull);
+ oso_symfile->SetID(m_cu_idx + 1);
}
return symfile;
}
@@ -773,6 +773,29 @@
return 0;
}
+namespace {
+uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) {
+ return static_cast<uint32_t>((uid >> DW_DIE_OFFSET_MAX_BITSIZE) - 1);
+}
+} // namespace
+
+user_id_t
+SymbolFileDWARFDebugMap::GetUID(SymbolFileDWARF::DecodedUID decoded_uid) {
+ return ((static_cast<user_id_t>(decoded_uid.dwarf.GetID()) + 1)
+ << DW_DIE_OFFSET_MAX_BITSIZE) |
+ decoded_uid.ref.die_offset();
+}
+
+std::optional<SymbolFileDWARF::DecodedUID>
+SymbolFileDWARFDebugMap::DecodeUID(user_id_t uid) {
+ if (SymbolFileDWARF *dwarf =
+ GetSymbolFileByOSOIndex(GetOSOIndexFromUserID(uid))) {
+ return SymbolFileDWARF::DecodedUID{
+ *dwarf, {std::nullopt, DIERef::Section::DebugInfo, dw_offset_t(uid)}};
+ }
+ return std::nullopt;
+}
+
Type *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -12,6 +12,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/Threading.h"
+#include "DIERef.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
@@ -1398,12 +1399,15 @@
user_id_t SymbolFileDWARF::GetUID(DIERef ref) {
if (GetDebugMapSymfile())
- return GetID() | ref.die_offset();
+ return GetDebugMapSymfile()->GetUID({*this, ref});
- lldbassert(GetDwoNum().value_or(0) <= 0x3fffffff);
- return user_id_t(GetDwoNum().value_or(0)) << 32 | ref.die_offset() |
- lldb::user_id_t(GetDwoNum().has_value()) << 62 |
- lldb::user_id_t(ref.section() == DIERef::Section::DebugTypes) << 63;
+ lldbassert(ref.dwo_num().value_or(0) <= DIERef::k_dwo_num_mask);
+ return user_id_t(ref.dwo_num().value_or(0)) << DIERef::k_die_offset_bit_size |
+ ref.die_offset() |
+ lldb::user_id_t(ref.dwo_num().has_value())
+ << DIERef::k_dwo_num_valid_bit_shift_by |
+ lldb::user_id_t(ref.section() == DIERef::Section::DebugTypes)
+ << DIERef::k_section_bit_shift_by;
}
std::optional<SymbolFileDWARF::DecodedUID>
@@ -1419,10 +1423,7 @@
// "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
// instance.
if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) {
- SymbolFileDWARF *dwarf = debug_map->GetSymbolFileByOSOIndex(
- debug_map->GetOSOIndexFromUserID(uid));
- return DecodedUID{
- *dwarf, {std::nullopt, DIERef::Section::DebugInfo, dw_offset_t(uid)}};
+ return debug_map->DecodeUID(uid);
}
dw_offset_t die_offset = uid;
if (die_offset == DW_INVALID_OFFSET)
@@ -1432,9 +1433,9 @@
uid >> 63 ? DIERef::Section::DebugTypes : DIERef::Section::DebugInfo;
std::optional<uint32_t> dwo_num;
- bool dwo_valid = uid >> 62 & 1;
+ bool dwo_valid = uid & DIERef::k_dwo_num_valid_bit;
if (dwo_valid)
- dwo_num = uid >> 32 & 0x3fffffff;
+ dwo_num = uid >> DW_DIE_OFFSET_MAX_BITSIZE & DIERef::k_dwo_num_mask;
return DecodedUID{*this, {dwo_num, section, die_offset}};
}
@@ -1694,7 +1695,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() == DIERef::k_dwo_num_mask
? m_dwp_symfile.get()
: this->DebugInfo()
.GetUnitAtIndex(*die_ref.dwo_num())
@@ -3184,7 +3185,8 @@
return 0;
size_t functions_added = 0;
- const dw_offset_t function_die_offset = func.GetID();
+ const dw_offset_t function_die_offset =
+ func.GetID() & DIERef::k_die_offset_mask;
DWARFDIE function_die =
dwarf_cu->GetNonSkeletonUnit().GetDIE(function_die_offset);
if (function_die) {
@@ -4160,8 +4162,8 @@
dwp_file_data_offset);
if (!dwp_obj_file)
return;
- m_dwp_symfile =
- std::make_shared<SymbolFileDWARFDwo>(*this, dwp_obj_file, 0x3fffffff);
+ m_dwp_symfile = std::make_shared<SymbolFileDWARFDwo>(
+ *this, dwp_obj_file, DIERef::k_dwo_num_mask);
}
});
return m_dwp_symfile;
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -136,7 +136,7 @@
});
uint32_t idx = std::distance(m_units.begin(), pos);
if (idx == 0)
- return DW_INVALID_OFFSET;
+ return DW_INVALID_INDEX;
return idx - 1;
}
Index: lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
@@ -12,6 +12,7 @@
#include "lldb/Core/dwarf.h"
#include "llvm/Support/FormatProviders.h"
#include <cassert>
+#include <cstdint>
#include <optional>
#include <vector>
@@ -29,8 +30,8 @@
DIERef(std::optional<uint32_t> dwo_num, Section section,
dw_offset_t die_offset)
- : m_dwo_num(dwo_num.value_or(0)), m_dwo_num_valid(bool(dwo_num)),
- m_section(section), m_die_offset(die_offset) {
+ : m_die_offset(die_offset), m_dwo_num(dwo_num.value_or(0)),
+ m_dwo_num_valid(bool(dwo_num)), m_section(section) {
assert(this->dwo_num() == dwo_num && "Dwo number out of range?");
}
@@ -85,11 +86,32 @@
///
void Encode(lldb_private::DataEncoder &encoder) const;
+ static constexpr uint64_t k_die_offset_bit_size = DW_DIE_OFFSET_MAX_BITSIZE;
+ static constexpr uint64_t k_dwo_num_bit_size =
+ 64 - DW_DIE_OFFSET_MAX_BITSIZE - /* size of control bits */ 2;
+
+ static constexpr uint64_t k_dwo_num_valid_bit_shift_by =
+ k_dwo_num_bit_size + k_die_offset_bit_size;
+ static constexpr uint64_t k_dwo_num_valid_bit =
+ (1ull << k_dwo_num_valid_bit_shift_by);
+ static constexpr uint64_t k_section_bit_shift_by =
+ k_dwo_num_valid_bit_shift_by + 1;
+ static constexpr uint64_t k_section_bit = (1ull << k_section_bit_shift_by);
+
+ static constexpr uint64_t
+ k_dwo_num_mask = (~0ull) >> (64 - k_dwo_num_bit_size); // 0x1fffff;
+ static constexpr uint64_t k_die_offset_mask = (~0ull) >>
+ (64 - k_die_offset_bit_size);
+
private:
- uint32_t m_dwo_num : 30;
- uint32_t m_dwo_num_valid : 1;
- uint32_t m_section : 1;
- dw_offset_t m_die_offset;
+ // Allow 2TB of .debug_info/.debug_types offset
+ dw_offset_t m_die_offset : k_die_offset_bit_size;
+ // Used for DWO index or for .o file index on mac
+ dw_offset_t m_dwo_num : k_dwo_num_bit_size;
+ // Set to 1 if m_file_index is a DWO number
+ dw_offset_t m_dwo_num_valid : 1;
+ // Set to 0 for .debug_info 1 for .debug_types,
+ dw_offset_t m_section : 1;
};
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
@@ -10,6 +10,7 @@
#include "lldb/Utility/DataEncoder.h"
#include "lldb/Utility/DataExtractor.h"
#include "llvm/Support/Format.h"
+#include <cstdint>
#include <optional>
using namespace lldb;
@@ -23,34 +24,29 @@
OS << "/" << format_hex_no_prefix(ref.die_offset(), 8);
}
-constexpr uint32_t k_dwo_num_mask = 0x3FFFFFFF;
-constexpr uint32_t k_dwo_num_valid_bitmask = (1u << 30);
-constexpr uint32_t k_section_bitmask = (1u << 31);
-
std::optional<DIERef> DIERef::Decode(const DataExtractor &data,
lldb::offset_t *offset_ptr) {
- const uint32_t bitfield_storage = data.GetU32(offset_ptr);
- uint32_t dwo_num = bitfield_storage & k_dwo_num_mask;
- bool dwo_num_valid = (bitfield_storage & (k_dwo_num_valid_bitmask)) != 0;
- Section section = (Section)((bitfield_storage & (k_section_bitmask)) != 0);
+ const uint64_t bitfield_storage = data.GetU64(offset_ptr);
+ uint32_t dwo_num =
+ (bitfield_storage >> k_die_offset_bit_size) & k_dwo_num_mask;
+ bool dwo_num_valid = (bitfield_storage & (k_dwo_num_valid_bit)) != 0;
+ Section section = (Section)((bitfield_storage & (k_section_bit)) != 0);
// DIE offsets can't be zero and if we fail to decode something from data,
// it will return 0
- dw_offset_t die_offset = data.GetU32(offset_ptr);
+ dw_offset_t die_offset = bitfield_storage & DIERef::k_die_offset_mask;
if (die_offset == 0)
return std::nullopt;
if (dwo_num_valid)
return DIERef(dwo_num, section, die_offset);
- else
- return DIERef(std::nullopt, section, die_offset);
+
+ return DIERef(std::nullopt, section, die_offset);
}
void DIERef::Encode(DataEncoder &encoder) const {
- uint32_t bitfield_storage = m_dwo_num;
- if (m_dwo_num_valid)
- bitfield_storage |= k_dwo_num_valid_bitmask;
- if (m_section)
- bitfield_storage |= k_section_bitmask;
- encoder.AppendU32(bitfield_storage);
- static_assert(sizeof(m_die_offset) == 4, "m_die_offset must be 4 bytes");
- encoder.AppendU32(m_die_offset);
+ uint64_t bitfield_storage =
+ uint64_t(m_dwo_num) << k_die_offset_bit_size | m_die_offset |
+ uint64_t(m_dwo_num_valid) << DIERef::k_dwo_num_valid_bit_shift_by |
+ uint64_t(section() == DIERef::Section::DebugTypes)
+ << DIERef::k_dwo_num_valid_bit_shift_by;
+ encoder.AppendU64(bitfield_storage);
}
Index: lldb/include/lldb/Symbol/DWARFCallFrameInfo.h
===================================================================
--- lldb/include/lldb/Symbol/DWARFCallFrameInfo.h
+++ lldb/include/lldb/Symbol/DWARFCallFrameInfo.h
@@ -128,7 +128,7 @@
void GetFDEIndex();
- bool FDEToUnwindPlan(uint32_t offset, Address startaddr,
+ bool FDEToUnwindPlan(dw_offset_t offset, Address startaddr,
UnwindPlan &unwind_plan);
const CIE *GetCIE(dw_offset_t cie_offset);
@@ -159,7 +159,7 @@
Type m_type;
CIESP
- ParseCIE(const uint32_t cie_offset);
+ ParseCIE(const dw_offset_t cie_offset);
lldb::RegisterKind GetRegisterKind() const {
return m_type == EH ? lldb::eRegisterKindEHFrame : lldb::eRegisterKindDWARF;
Index: lldb/include/lldb/Core/dwarf.h
===================================================================
--- lldb/include/lldb/Core/dwarf.h
+++ lldb/include/lldb/Core/dwarf.h
@@ -30,11 +30,12 @@
// any addresses in the compile units that get
// parsed
-typedef uint32_t dw_offset_t; // Dwarf Debug Information Entry offset for any
+typedef uint64_t dw_offset_t; // Dwarf Debug Information Entry offset for any
// offset into the file
/* Constants */
-#define DW_INVALID_OFFSET (~(dw_offset_t)0)
+#define DW_DIE_OFFSET_MAX_BITSIZE 40
+#define DW_INVALID_OFFSET (((uint64_t)1u << DW_DIE_OFFSET_MAX_BITSIZE) - 1)
#define DW_INVALID_INDEX 0xFFFFFFFFul
// #define DW_ADDR_none 0x0
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits