[LLDB] Enable 64 bit debug/type offset
This came out of from https://discourse.llvm.org/t/dwarf-dwp-4gb-limit/63902 With big binaries we can have .dwp files where .debug_info.dwo section can grow beyond 4GB. We would like to support this in LLVM and in LLDB. The plan is to enable manual parsing of cu/tu index in DWARF library (https://reviews.llvm.org/D137882), and then switch internal index data structure to 64 bit. For the second part is to enable 64bit offset support in LLDB with this patch. Reviewed By: labath Differential Revision: https://reviews.llvm.org/D138618
This commit is contained in:
committed by
Alexander Yermolovich
parent
89b144ece3
commit
34a8e6eee6
@@ -30,11 +30,12 @@ typedef uint64_t dw_addr_t; // Dwarf address define that must be big enough for
|
||||
// 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
|
||||
|
||||
@@ -128,7 +128,7 @@ private:
|
||||
|
||||
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 @@ private:
|
||||
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;
|
||||
|
||||
@@ -80,7 +80,6 @@ void AppleDWARFIndex::GetGlobalVariables(
|
||||
if (!m_apple_names_up)
|
||||
return;
|
||||
|
||||
lldbassert(!cu.GetSymbolFileDWARF().GetDwoNum());
|
||||
const DWARFUnit &non_skeleton_cu = cu.GetNonSkeletonUnit();
|
||||
DWARFMappedHash::DIEInfoArray hash_data;
|
||||
m_apple_names_up->AppendAllDIEsInRange(non_skeleton_cu.GetOffset(),
|
||||
|
||||
@@ -17,40 +17,22 @@ using namespace lldb_private;
|
||||
|
||||
void llvm::format_provider<DIERef>::format(const DIERef &ref, raw_ostream &OS,
|
||||
StringRef Style) {
|
||||
if (ref.dwo_num())
|
||||
OS << format_hex_no_prefix(*ref.dwo_num(), 8) << "/";
|
||||
if (ref.file_index())
|
||||
OS << format_hex_no_prefix(*ref.file_index(), 8) << "/";
|
||||
OS << (ref.section() == DIERef::DebugInfo ? "INFO" : "TYPE");
|
||||
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);
|
||||
DIERef die_ref(data.GetU64(offset_ptr));
|
||||
|
||||
// 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);
|
||||
if (die_offset == 0)
|
||||
if (!die_ref.die_offset())
|
||||
return std::nullopt;
|
||||
if (dwo_num_valid)
|
||||
return DIERef(dwo_num, section, die_offset);
|
||||
else
|
||||
return DIERef(std::nullopt, section, die_offset);
|
||||
|
||||
return die_ref;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
void DIERef::Encode(DataEncoder &encoder) const { encoder.AppendU64(get_id()); }
|
||||
|
||||
@@ -10,15 +10,17 @@
|
||||
#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H
|
||||
|
||||
#include "lldb/Core/dwarf.h"
|
||||
#include "llvm/Support/FormatProviders.h"
|
||||
#include "lldb/Utility/LLDBAssert.h"
|
||||
#include <cassert>
|
||||
#include <optional>
|
||||
#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.
|
||||
/// - file_index: identifies the separate stand alone debug info file
|
||||
/// that is referred to by the main debug info file. This will be the
|
||||
/// index of a DWO file for fission, or the .o file on mac when not
|
||||
/// using a dSYM file. If this field is not set, then this references
|
||||
/// a DIE inside the original object 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
|
||||
@@ -26,17 +28,35 @@
|
||||
class DIERef {
|
||||
public:
|
||||
enum Section : uint8_t { DebugInfo, DebugTypes };
|
||||
|
||||
DIERef(std::optional<uint32_t> dwo_num, Section section,
|
||||
DIERef(std::optional<uint32_t> file_index, 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) {
|
||||
assert(this->dwo_num() == dwo_num && "Dwo number out of range?");
|
||||
: m_die_offset(die_offset), m_file_index(file_index.value_or(0)),
|
||||
m_file_index_valid(file_index ? true : false), m_section(section) {
|
||||
assert(this->file_index() == file_index && "File Index is out of range?");
|
||||
}
|
||||
|
||||
std::optional<uint32_t> dwo_num() const {
|
||||
if (m_dwo_num_valid)
|
||||
return m_dwo_num;
|
||||
explicit DIERef(lldb::user_id_t uid) {
|
||||
m_die_offset = uid & k_die_offset_mask;
|
||||
m_file_index_valid = (uid & k_file_index_valid_bit) != 0;
|
||||
m_file_index = m_file_index_valid
|
||||
? (uid >> k_die_offset_bit_size) & k_file_index_mask
|
||||
: 0;
|
||||
m_section =
|
||||
(uid & k_section_bit) != 0 ? Section::DebugTypes : Section::DebugInfo;
|
||||
}
|
||||
|
||||
lldb::user_id_t get_id() const {
|
||||
if (m_die_offset == k_die_offset_mask)
|
||||
return LLDB_INVALID_UID;
|
||||
|
||||
return lldb::user_id_t(file_index().value_or(0)) << k_die_offset_bit_size |
|
||||
die_offset() | (m_file_index_valid ? k_file_index_valid_bit : 0) |
|
||||
(section() == Section::DebugTypes ? k_section_bit : 0);
|
||||
}
|
||||
|
||||
std::optional<uint32_t> file_index() const {
|
||||
if (m_file_index_valid)
|
||||
return m_file_index;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -45,17 +65,17 @@ public:
|
||||
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_file_index_valid != other.m_file_index_valid)
|
||||
return m_file_index_valid < other.m_file_index_valid;
|
||||
if (m_file_index_valid && (m_file_index != other.m_file_index))
|
||||
return m_file_index < other.m_file_index;
|
||||
if (m_section != other.m_section)
|
||||
return m_section < other.m_section;
|
||||
return m_die_offset < other.m_die_offset;
|
||||
}
|
||||
|
||||
bool operator==(const DIERef &rhs) const {
|
||||
return dwo_num() == rhs.dwo_num() && m_section == rhs.m_section &&
|
||||
return file_index() == rhs.file_index() && m_section == rhs.m_section &&
|
||||
m_die_offset == rhs.m_die_offset;
|
||||
}
|
||||
|
||||
@@ -85,11 +105,28 @@ public:
|
||||
///
|
||||
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_file_index_bit_size =
|
||||
64 - DW_DIE_OFFSET_MAX_BITSIZE - /* size of control bits */ 2;
|
||||
|
||||
static constexpr uint64_t k_file_index_valid_bit =
|
||||
(1ull << (k_file_index_bit_size + k_die_offset_bit_size));
|
||||
static constexpr uint64_t k_section_bit =
|
||||
(1ull << (k_file_index_bit_size + k_die_offset_bit_size + 1));
|
||||
static constexpr uint64_t
|
||||
k_file_index_mask = (~0ull) >> (64 - k_file_index_bit_size); // 0x3fffff;
|
||||
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_file_index : k_file_index_bit_size;
|
||||
// Set to 1 if m_file_index is a DWO number
|
||||
dw_offset_t m_file_index_valid : 1;
|
||||
// Set to 0 for .debug_info 1 for .debug_types,
|
||||
dw_offset_t m_section : 1;
|
||||
};
|
||||
static_assert(sizeof(DIERef) == 8);
|
||||
|
||||
|
||||
@@ -731,10 +731,10 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
|
||||
}
|
||||
}
|
||||
|
||||
type_sp = dwarf->MakeType(
|
||||
die.GetID(), attrs.name, attrs.byte_size, nullptr,
|
||||
dwarf->GetUID(attrs.type.Reference()), encoding_data_type, &attrs.decl,
|
||||
clang_type, resolve_state, TypePayloadClang(GetOwningClangModule(die)));
|
||||
type_sp = dwarf->MakeType(die.GetID(), attrs.name, attrs.byte_size, nullptr,
|
||||
attrs.type.Reference().GetID(), encoding_data_type,
|
||||
&attrs.decl, clang_type, resolve_state,
|
||||
TypePayloadClang(GetOwningClangModule(die)));
|
||||
|
||||
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
|
||||
return type_sp;
|
||||
@@ -834,11 +834,11 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc,
|
||||
|
||||
LinkDeclContextToDIE(TypeSystemClang::GetDeclContextForType(clang_type), die);
|
||||
|
||||
type_sp = dwarf->MakeType(die.GetID(), attrs.name, attrs.byte_size, nullptr,
|
||||
dwarf->GetUID(attrs.type.Reference()),
|
||||
Type::eEncodingIsUID, &attrs.decl, clang_type,
|
||||
Type::ResolveState::Forward,
|
||||
TypePayloadClang(GetOwningClangModule(die)));
|
||||
type_sp =
|
||||
dwarf->MakeType(die.GetID(), attrs.name, attrs.byte_size, nullptr,
|
||||
attrs.type.Reference().GetID(), Type::eEncodingIsUID,
|
||||
&attrs.decl, clang_type, Type::ResolveState::Forward,
|
||||
TypePayloadClang(GetOwningClangModule(die)));
|
||||
|
||||
if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) {
|
||||
if (die.HasChildren()) {
|
||||
@@ -1336,7 +1336,7 @@ DWARFASTParserClang::ParseArrayType(const DWARFDIE &die,
|
||||
ConstString empty_name;
|
||||
TypeSP type_sp =
|
||||
dwarf->MakeType(die.GetID(), empty_name, array_element_bit_stride / 8,
|
||||
nullptr, dwarf->GetUID(type_die), Type::eEncodingIsUID,
|
||||
nullptr, type_die.GetID(), Type::eEncodingIsUID,
|
||||
&attrs.decl, clang_type, Type::ResolveState::Full);
|
||||
type_sp->SetEncodingType(element_type);
|
||||
const clang::Type *type = ClangUtil::GetQualType(clang_type).getTypePtr();
|
||||
|
||||
@@ -23,8 +23,8 @@ std::optional<DIERef> DWARFBaseDIE::GetDIERef() const {
|
||||
if (!IsValid())
|
||||
return std::nullopt;
|
||||
|
||||
return DIERef(m_cu->GetSymbolFileDWARF().GetDwoNum(), m_cu->GetDebugSection(),
|
||||
m_die->GetOffset());
|
||||
return DIERef(m_cu->GetSymbolFileDWARF().GetFileIndex(),
|
||||
m_cu->GetDebugSection(), m_die->GetOffset());
|
||||
}
|
||||
|
||||
dw_tag_t DWARFBaseDIE::Tag() const {
|
||||
@@ -70,8 +70,10 @@ uint64_t DWARFBaseDIE::GetAttributeValueAsAddress(const dw_attr_t attr,
|
||||
}
|
||||
|
||||
lldb::user_id_t DWARFBaseDIE::GetID() const {
|
||||
if (IsValid())
|
||||
return GetDWARF()->GetUID(*this);
|
||||
const std::optional<DIERef> &ref = this->GetDIERef();
|
||||
if (ref)
|
||||
return ref->get_id();
|
||||
|
||||
return LLDB_INVALID_UID;
|
||||
}
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ uint32_t DWARFDebugInfo::FindUnitIndex(DIERef::Section section,
|
||||
});
|
||||
uint32_t idx = std::distance(m_units.begin(), pos);
|
||||
if (idx == 0)
|
||||
return DW_INVALID_OFFSET;
|
||||
return DW_INVALID_INDEX;
|
||||
return idx - 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
|
||||
"[{0:x16}]: invalid abbreviation code {1}, "
|
||||
"please file a bug and "
|
||||
"attach the file at the start of this error message",
|
||||
m_offset, (unsigned)abbr_idx);
|
||||
(uint64_t)m_offset, (unsigned)abbr_idx);
|
||||
// WE can't parse anymore if the DWARF is borked...
|
||||
*offset_ptr = UINT32_MAX;
|
||||
return false;
|
||||
@@ -195,7 +195,7 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
|
||||
"[{0:x16}]: Unsupported DW_FORM_{1:x}, please file a bug "
|
||||
"and "
|
||||
"attach the file at the start of this error message",
|
||||
m_offset, (unsigned)form);
|
||||
(uint64_t)m_offset, (unsigned)form);
|
||||
*offset_ptr = m_offset;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,8 @@ public:
|
||||
typedef collection::const_iterator const_iterator;
|
||||
|
||||
DWARFDebugInfoEntry()
|
||||
: m_offset(DW_INVALID_OFFSET), m_sibling_idx(0), m_has_children(false) {}
|
||||
: m_offset(DW_INVALID_OFFSET), m_parent_idx(0), m_sibling_idx(0),
|
||||
m_has_children(false) {}
|
||||
|
||||
explicit operator bool() const { return m_offset != DW_INVALID_OFFSET; }
|
||||
bool operator==(const DWARFDebugInfoEntry &rhs) const;
|
||||
@@ -165,14 +166,16 @@ protected:
|
||||
static DWARFDeclContext
|
||||
GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnit *cu);
|
||||
|
||||
dw_offset_t m_offset; // Offset within the .debug_info/.debug_types
|
||||
uint32_t m_parent_idx = 0; // How many to subtract from "this" to get the
|
||||
// parent. If zero this die has no parent
|
||||
uint32_t m_sibling_idx : 31, // How many to add to "this" to get the sibling.
|
||||
// If it is zero, then the DIE doesn't have children, or the
|
||||
// DWARF claimed it had children but the DIE only contained
|
||||
// a single NULL terminating child.
|
||||
m_has_children : 1;
|
||||
// Up to 2TB offset within the .debug_info/.debug_types
|
||||
dw_offset_t m_offset : DW_DIE_OFFSET_MAX_BITSIZE;
|
||||
// How many to subtract from "this" to get the parent. If zero this die has no
|
||||
// parent
|
||||
dw_offset_t m_parent_idx : 64 - DW_DIE_OFFSET_MAX_BITSIZE;
|
||||
// How many to add to "this" to get the sibling.
|
||||
// If it is zero, then the DIE doesn't have children,
|
||||
// or the DWARF claimed it had children but the DIE
|
||||
// only contained a single NULL terminating child.
|
||||
uint32_t m_sibling_idx : 31, m_has_children : 1;
|
||||
uint16_t m_abbr_idx = 0;
|
||||
/// A copy of the DW_TAG value so we don't have to go through the compile
|
||||
/// unit abbrev table
|
||||
|
||||
@@ -341,7 +341,7 @@ void DWARFUnit::SetDwoStrOffsetsBase() {
|
||||
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) {
|
||||
if (const auto *contribution =
|
||||
entry->getContribution(llvm::DW_SECT_STR_OFFSETS))
|
||||
baseOffset = contribution->getOffset32();
|
||||
baseOffset = contribution->getOffset();
|
||||
else
|
||||
return;
|
||||
}
|
||||
@@ -489,7 +489,7 @@ void DWARFUnit::SetLoclistsBase(dw_addr_t loclists_base) {
|
||||
*GetDWOId());
|
||||
return;
|
||||
}
|
||||
offset += contribution->getOffset32();
|
||||
offset += contribution->getOffset();
|
||||
}
|
||||
m_loclists_base = loclists_base;
|
||||
|
||||
@@ -527,7 +527,7 @@ DWARFDataExtractor DWARFUnit::GetLocationData() const {
|
||||
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) {
|
||||
if (const auto *contribution = entry->getContribution(
|
||||
GetVersion() >= 5 ? llvm::DW_SECT_LOCLISTS : llvm::DW_SECT_EXT_LOC))
|
||||
return DWARFDataExtractor(data, contribution->getOffset32(),
|
||||
return DWARFDataExtractor(data, contribution->getOffset(),
|
||||
contribution->getLength32());
|
||||
return DWARFDataExtractor();
|
||||
}
|
||||
@@ -540,7 +540,7 @@ DWARFDataExtractor DWARFUnit::GetRnglistData() const {
|
||||
if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) {
|
||||
if (const auto *contribution =
|
||||
entry->getContribution(llvm::DW_SECT_RNGLISTS))
|
||||
return DWARFDataExtractor(data, contribution->getOffset32(),
|
||||
return DWARFDataExtractor(data, contribution->getOffset(),
|
||||
contribution->getLength32());
|
||||
GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
|
||||
"Failed to find range list contribution for CU with signature {0:x16}",
|
||||
@@ -935,7 +935,7 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data,
|
||||
llvm::inconvertibleErrorCode(),
|
||||
"DWARF package index missing abbreviation column");
|
||||
}
|
||||
header.m_abbr_offset = abbr_entry->getOffset32();
|
||||
header.m_abbr_offset = abbr_entry->getOffset();
|
||||
}
|
||||
|
||||
bool length_OK = data.ValidOffset(header.GetNextUnitOffset() - 1);
|
||||
|
||||
@@ -54,7 +54,7 @@ DebugNamesDWARFIndex::ToDIERef(const DebugNames::Entry &entry) {
|
||||
|
||||
cu = &cu->GetNonSkeletonUnit();
|
||||
if (std::optional<uint64_t> die_offset = entry.getDIEUnitOffset())
|
||||
return DIERef(cu->GetSymbolFileDWARF().GetDwoNum(),
|
||||
return DIERef(cu->GetSymbolFileDWARF().GetFileIndex(),
|
||||
DIERef::Section::DebugInfo, cu->GetOffset() + *die_offset);
|
||||
|
||||
return std::nullopt;
|
||||
@@ -126,7 +126,7 @@ void DebugNamesDWARFIndex::GetGlobalVariables(
|
||||
|
||||
void DebugNamesDWARFIndex::GetGlobalVariables(
|
||||
DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) {
|
||||
lldbassert(!cu.GetSymbolFileDWARF().GetDwoNum());
|
||||
lldbassert(!cu.GetSymbolFileDWARF().GetFileIndex());
|
||||
uint64_t cu_offset = cu.GetOffset();
|
||||
bool found_entry_for_cu = false;
|
||||
for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
|
||||
|
||||
@@ -401,7 +401,6 @@ void ManualDWARFIndex::GetGlobalVariables(
|
||||
|
||||
void ManualDWARFIndex::GetGlobalVariables(
|
||||
DWARFUnit &unit, llvm::function_ref<bool(DWARFDIE die)> callback) {
|
||||
lldbassert(!unit.GetSymbolFileDWARF().GetDwoNum());
|
||||
Index();
|
||||
m_set.globals.FindAllEntriesForUnit(unit, DIERefCallback(callback));
|
||||
}
|
||||
@@ -539,7 +538,10 @@ enum DataID {
|
||||
kDataIDEnd = 255u,
|
||||
|
||||
};
|
||||
constexpr uint32_t CURRENT_CACHE_VERSION = 1;
|
||||
|
||||
// Version 2 changes the encoding of DIERef objects used in the DWARF manual
|
||||
// index name tables. See DIERef class for details.
|
||||
constexpr uint32_t CURRENT_CACHE_VERSION = 2;
|
||||
|
||||
bool ManualDWARFIndex::IndexSet::Decode(const DataExtractor &data,
|
||||
lldb::offset_t *offset_ptr) {
|
||||
|
||||
@@ -50,12 +50,11 @@ bool NameToDIE::Find(const RegularExpression ®ex,
|
||||
|
||||
void NameToDIE::FindAllEntriesForUnit(
|
||||
DWARFUnit &s_unit, llvm::function_ref<bool(DIERef ref)> callback) const {
|
||||
lldbassert(!s_unit.GetSymbolFileDWARF().GetDwoNum());
|
||||
const DWARFUnit &ns_unit = s_unit.GetNonSkeletonUnit();
|
||||
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() &&
|
||||
if (ns_unit.GetSymbolFileDWARF().GetFileIndex() == die_ref.file_index() &&
|
||||
ns_unit.GetDebugSection() == die_ref.section() &&
|
||||
ns_unit.GetOffset() <= die_ref.die_offset() &&
|
||||
die_ref.die_offset() < ns_unit.GetNextUnitOffset()) {
|
||||
|
||||
@@ -408,11 +408,8 @@ SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) {
|
||||
|
||||
SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp,
|
||||
SectionList *dwo_section_list)
|
||||
: SymbolFileCommon(std::move(objfile_sp)),
|
||||
UserID(0x7fffffff00000000), // Used by SymbolFileDWARFDebugMap to
|
||||
// when this class parses .o files to
|
||||
// contain the .o file index/ID
|
||||
m_debug_map_module_wp(), m_debug_map_symfile(nullptr),
|
||||
: SymbolFileCommon(std::move(objfile_sp)), m_debug_map_module_wp(),
|
||||
m_debug_map_symfile(nullptr),
|
||||
m_context(m_objfile_sp->GetModule()->GetSectionList(), dwo_section_list),
|
||||
m_fetched_external_modules(false),
|
||||
m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
|
||||
@@ -587,6 +584,14 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
|
||||
}
|
||||
}
|
||||
|
||||
constexpr uint64_t MaxDebugInfoSize = (1ull) << DW_DIE_OFFSET_MAX_BITSIZE;
|
||||
if (debug_info_file_size >= MaxDebugInfoSize) {
|
||||
m_objfile_sp->GetModule()->ReportWarning(
|
||||
"SymbolFileDWARF can't load this DWARF. It's larger then {0:x+16}",
|
||||
MaxDebugInfoSize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
|
||||
abilities |= CompileUnits | Functions | Blocks | GlobalVariables |
|
||||
LocalVariables | VariableTypes;
|
||||
@@ -1396,62 +1401,8 @@ void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) {
|
||||
decl_ctx);
|
||||
}
|
||||
|
||||
user_id_t SymbolFileDWARF::GetUID(DIERef ref) {
|
||||
if (GetDebugMapSymfile())
|
||||
return GetID() | ref.die_offset();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
std::optional<SymbolFileDWARF::DecodedUID>
|
||||
SymbolFileDWARF::DecodeUID(lldb::user_id_t uid) {
|
||||
// This method can be called without going through the symbol vendor so we
|
||||
// need to lock the module.
|
||||
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
|
||||
// Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we
|
||||
// must make sure we use the correct DWARF file when resolving things. On
|
||||
// MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
|
||||
// SymbolFileDWARF classes, one for each .o file. We can often end up with
|
||||
// references to other DWARF objects and we must be ready to receive a
|
||||
// "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)}};
|
||||
}
|
||||
dw_offset_t die_offset = uid;
|
||||
if (die_offset == DW_INVALID_OFFSET)
|
||||
return std::nullopt;
|
||||
|
||||
DIERef::Section section =
|
||||
uid >> 63 ? DIERef::Section::DebugTypes : DIERef::Section::DebugInfo;
|
||||
|
||||
std::optional<uint32_t> dwo_num;
|
||||
bool dwo_valid = uid >> 62 & 1;
|
||||
if (dwo_valid)
|
||||
dwo_num = uid >> 32 & 0x3fffffff;
|
||||
|
||||
return DecodedUID{*this, {dwo_num, section, die_offset}};
|
||||
}
|
||||
|
||||
DWARFDIE
|
||||
SymbolFileDWARF::GetDIE(lldb::user_id_t uid) {
|
||||
// This method can be called without going through the symbol vendor so we
|
||||
// need to lock the module.
|
||||
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
|
||||
|
||||
std::optional<DecodedUID> decoded = DecodeUID(uid);
|
||||
|
||||
if (decoded)
|
||||
return decoded->dwarf.GetDIE(decoded->ref);
|
||||
|
||||
return DWARFDIE();
|
||||
}
|
||||
SymbolFileDWARF::GetDIE(lldb::user_id_t uid) { return GetDIE(DIERef(uid)); }
|
||||
|
||||
CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) {
|
||||
// This method can be called without going through the symbol vendor so we
|
||||
@@ -1693,15 +1644,41 @@ lldb::ModuleSP SymbolFileDWARF::GetExternalModule(ConstString name) {
|
||||
|
||||
DWARFDIE
|
||||
SymbolFileDWARF::GetDIE(const DIERef &die_ref) {
|
||||
if (die_ref.dwo_num()) {
|
||||
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);
|
||||
// This method can be called without going through the symbol vendor so we
|
||||
// need to lock the module.
|
||||
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
|
||||
|
||||
SymbolFileDWARF *symbol_file = nullptr;
|
||||
|
||||
// Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we
|
||||
// must make sure we use the correct DWARF file when resolving things. On
|
||||
// MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
|
||||
// SymbolFileDWARF classes, one for each .o file. We can often end up with
|
||||
// references to other DWARF objects and we must be ready to receive a
|
||||
// "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
|
||||
// instance.
|
||||
std::optional<uint32_t> file_index = die_ref.file_index();
|
||||
if (file_index) {
|
||||
if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) {
|
||||
symbol_file = debug_map->GetSymbolFileByOSOIndex(*file_index); // OSO case
|
||||
if (symbol_file)
|
||||
return symbol_file->DebugInfo().GetDIE(die_ref);
|
||||
return DWARFDIE();
|
||||
}
|
||||
|
||||
if (*file_index == DIERef::k_file_index_mask)
|
||||
symbol_file = m_dwp_symfile.get(); // DWP case
|
||||
else
|
||||
symbol_file = this->DebugInfo()
|
||||
.GetUnitAtIndex(*die_ref.file_index())
|
||||
->GetDwoSymbolFile(); // DWO case
|
||||
} else if (die_ref.die_offset() == DW_INVALID_OFFSET) {
|
||||
return DWARFDIE();
|
||||
}
|
||||
|
||||
if (symbol_file)
|
||||
return symbol_file->GetDIE(die_ref);
|
||||
|
||||
return DebugInfo().GetDIE(die_ref);
|
||||
}
|
||||
|
||||
@@ -3190,7 +3167,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {
|
||||
return 0;
|
||||
|
||||
size_t functions_added = 0;
|
||||
const dw_offset_t function_die_offset = func.GetID();
|
||||
const dw_offset_t function_die_offset = DIERef(func.GetID()).die_offset();
|
||||
DWARFDIE function_die =
|
||||
dwarf_cu->GetNonSkeletonUnit().GetDIE(function_die_offset);
|
||||
if (function_die) {
|
||||
@@ -3612,7 +3589,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
|
||||
}
|
||||
|
||||
auto type_sp = std::make_shared<SymbolFileType>(
|
||||
*this, GetUID(type_die_form.Reference()));
|
||||
*this, type_die_form.Reference().GetID());
|
||||
|
||||
if (use_type_size_for_value && type_sp->GetType()) {
|
||||
DWARFExpression *location = location_list.GetMutableExpressionAtAddress();
|
||||
@@ -4108,7 +4085,7 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<lldb_private::CallEdge>>
|
||||
SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) {
|
||||
SymbolFileDWARF::ParseCallEdgesInFunction(lldb_private::UserID func_id) {
|
||||
// ParseCallEdgesInFunction must be called at the behest of an exclusively
|
||||
// locked lldb::Function instance. Storage for parsed call edges is owned by
|
||||
// the lldb::Function instance: locking at the SymbolFile level would be too
|
||||
@@ -4166,8 +4143,8 @@ const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {
|
||||
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_file_index_mask);
|
||||
}
|
||||
});
|
||||
return m_dwp_symfile;
|
||||
|
||||
@@ -55,11 +55,11 @@ class DWARFTypeUnit;
|
||||
class SymbolFileDWARFDebugMap;
|
||||
class SymbolFileDWARFDwo;
|
||||
class SymbolFileDWARFDwp;
|
||||
class UserID;
|
||||
|
||||
#define DIE_IS_BEING_PARSED ((lldb_private::Type *)1)
|
||||
|
||||
class SymbolFileDWARF : public lldb_private::SymbolFileCommon,
|
||||
public lldb_private::UserID {
|
||||
class SymbolFileDWARF : public lldb_private::SymbolFileCommon {
|
||||
/// LLVM RTTI support.
|
||||
static char ID;
|
||||
|
||||
@@ -265,22 +265,10 @@ public:
|
||||
|
||||
DWARFDIE GetDIE(lldb::user_id_t uid);
|
||||
|
||||
lldb::user_id_t GetUID(const DWARFBaseDIE &die) {
|
||||
return GetUID(die.GetDIERef());
|
||||
}
|
||||
|
||||
lldb::user_id_t GetUID(const std::optional<DIERef> &ref) {
|
||||
return ref ? GetUID(*ref) : LLDB_INVALID_UID;
|
||||
}
|
||||
|
||||
lldb::user_id_t GetUID(DIERef ref);
|
||||
|
||||
std::shared_ptr<SymbolFileDWARFDwo>
|
||||
GetDwoSymbolFileForCompileUnit(DWARFUnit &dwarf_cu,
|
||||
const DWARFDebugInfoEntry &cu_die);
|
||||
|
||||
virtual std::optional<uint32_t> GetDwoNum() { return std::nullopt; }
|
||||
|
||||
/// If this is a DWARF object with a single CU, return its DW_AT_dwo_id.
|
||||
std::optional<uint64_t> GetDWOId();
|
||||
|
||||
@@ -289,7 +277,7 @@ public:
|
||||
const DWARFDIE &die);
|
||||
|
||||
std::vector<std::unique_ptr<lldb_private::CallEdge>>
|
||||
ParseCallEdgesInFunction(UserID func_id) override;
|
||||
ParseCallEdgesInFunction(lldb_private::UserID func_id) override;
|
||||
|
||||
void Dump(lldb_private::Stream &s) override;
|
||||
|
||||
@@ -347,6 +335,11 @@ public:
|
||||
|
||||
lldb_private::ConstString ConstructFunctionDemangledName(const DWARFDIE &die);
|
||||
|
||||
std::optional<uint64_t> GetFileIndex() const { return m_file_index; }
|
||||
void SetFileIndex(std::optional<uint64_t> file_index) {
|
||||
m_file_index = file_index;
|
||||
}
|
||||
|
||||
protected:
|
||||
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
|
||||
DIEToTypePtr;
|
||||
@@ -521,12 +514,6 @@ protected:
|
||||
void BuildCuTranslationTable();
|
||||
std::optional<uint32_t> GetDWARFUnitIndex(uint32_t cu_idx);
|
||||
|
||||
struct DecodedUID {
|
||||
SymbolFileDWARF &dwarf;
|
||||
DIERef ref;
|
||||
};
|
||||
std::optional<DecodedUID> DecodeUID(lldb::user_id_t uid);
|
||||
|
||||
void FindDwpSymbolFile();
|
||||
|
||||
const lldb_private::FileSpecList &GetTypeUnitSupportFiles(DWARFTypeUnit &tu);
|
||||
@@ -580,6 +567,11 @@ protected:
|
||||
lldb::addr_t m_first_code_address = LLDB_INVALID_ADDRESS;
|
||||
lldb_private::StatsDuration m_parse_time;
|
||||
std::atomic_flag m_dwo_warning_issued = ATOMIC_FLAG_INIT;
|
||||
/// If this DWARF file a .DWO file or a DWARF .o file on mac when
|
||||
/// no dSYM file is being used, this file index will be set to a
|
||||
/// valid value that can be used in DIERef objects which will contain
|
||||
/// an index that identifies the .DWO or .o file.
|
||||
std::optional<uint64_t> m_file_index = std::nullopt;
|
||||
};
|
||||
|
||||
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H
|
||||
|
||||
@@ -211,7 +211,7 @@ public:
|
||||
// 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->SetFileIndex((uint64_t)m_cu_idx);
|
||||
}
|
||||
return symfile;
|
||||
}
|
||||
@@ -1121,7 +1121,8 @@ void SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<lldb_private::CallEdge>>
|
||||
SymbolFileDWARFDebugMap::ParseCallEdgesInFunction(UserID func_id) {
|
||||
SymbolFileDWARFDebugMap::ParseCallEdgesInFunction(
|
||||
lldb_private::UserID func_id) {
|
||||
uint32_t oso_idx = GetOSOIndexFromUserID(func_id.GetID());
|
||||
SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
|
||||
if (oso_dwarf)
|
||||
@@ -1468,7 +1469,8 @@ SymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data,
|
||||
for (size_t idx = 0; idx < file_range_map.GetSize(); idx++) {
|
||||
const FileRangeMap::Entry *entry = file_range_map.GetEntryAtIndex(idx);
|
||||
if (entry) {
|
||||
debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(),
|
||||
debug_aranges->AppendRange(*dwarf2Data->GetFileIndex(),
|
||||
entry->GetRangeBase(),
|
||||
entry->GetRangeEnd());
|
||||
num_line_entries_added++;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H
|
||||
#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H
|
||||
|
||||
#include "DIERef.h"
|
||||
#include "lldb/Symbol/SymbolFile.h"
|
||||
#include "lldb/Utility/RangeMap.h"
|
||||
#include "llvm/Support/Chrono.h"
|
||||
@@ -209,7 +210,9 @@ protected:
|
||||
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
|
||||
|
||||
static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) {
|
||||
return (uint32_t)((uid >> 32ull) - 1ull);
|
||||
std::optional<uint32_t> OsoNum = DIERef(uid).file_index();
|
||||
lldbassert(OsoNum && "Invalid OSO Index");
|
||||
return *OsoNum;
|
||||
}
|
||||
|
||||
static SymbolFileDWARF *GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file);
|
||||
|
||||
@@ -29,7 +29,7 @@ SymbolFileDWARFDwo::SymbolFileDWARFDwo(SymbolFileDWARF &base_symbol_file,
|
||||
: SymbolFileDWARF(objfile, objfile->GetSectionList(
|
||||
/*update_module_section_list*/ false)),
|
||||
m_base_symbol_file(base_symbol_file) {
|
||||
SetID(user_id_t(id) << 32);
|
||||
SetFileIndex(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 @@ DWARFCompileUnit *SymbolFileDWARFDwo::GetDWOCompileUnitForHash(uint64_t hash) {
|
||||
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;
|
||||
}
|
||||
@@ -137,7 +137,7 @@ SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) {
|
||||
|
||||
DWARFDIE
|
||||
SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) {
|
||||
if (die_ref.dwo_num() == GetDwoNum())
|
||||
if (die_ref.file_index() == GetFileIndex())
|
||||
return DebugInfo().GetDIE(die_ref);
|
||||
return GetBaseSymbolFile().GetDIE(die_ref);
|
||||
}
|
||||
|
||||
@@ -41,8 +41,6 @@ public:
|
||||
DWARFDIE
|
||||
GetDIE(const DIERef &die_ref) override;
|
||||
|
||||
std::optional<uint32_t> GetDwoNum() override { return GetID() >> 32; }
|
||||
|
||||
lldb::offset_t
|
||||
GetVendorDWARFOpcodeSize(const lldb_private::DataExtractor &data,
|
||||
const lldb::offset_t data_offset,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -713,7 +713,7 @@ DWARF:
|
||||
// Entries:
|
||||
// - AbbrCode: 0x1
|
||||
// Values:
|
||||
// - Value: 0x01020304
|
||||
// - Value: 0x0120304
|
||||
// - AbbrCode: 0x0
|
||||
const char *dwo_yamldata = R"(
|
||||
--- !ELF
|
||||
@@ -750,7 +750,7 @@ Sections:
|
||||
auto dwo_module_sp = std::make_shared<Module>(dwo_file->moduleSpec());
|
||||
SymbolFileDWARFDwo dwo_symfile(
|
||||
skeleton_symfile, dwo_module_sp->GetObjectFile()->shared_from_this(),
|
||||
0x01020304);
|
||||
0x0120304);
|
||||
auto *dwo_dwarf_unit = dwo_symfile.DebugInfo().GetUnitAtIndex(0);
|
||||
|
||||
testExpressionVendorExtensions(dwo_module_sp, *dwo_dwarf_unit);
|
||||
|
||||
@@ -45,6 +45,26 @@ TEST(DWARFIndexCachingTest, DIERefEncodeDecode) {
|
||||
EncodeDecode(DIERef(200, DIERef::Section::DebugTypes, 0x11223344));
|
||||
}
|
||||
|
||||
TEST(DWARFIndexCachingTest, DIERefEncodeDecodeMax) {
|
||||
// Tests DIERef::Encode(...) and DIERef::Decode(...)
|
||||
EncodeDecode(DIERef(std::nullopt, DIERef::Section::DebugInfo,
|
||||
DIERef::k_die_offset_mask - 1));
|
||||
EncodeDecode(DIERef(std::nullopt, DIERef::Section::DebugTypes,
|
||||
DIERef::k_die_offset_mask - 1));
|
||||
EncodeDecode(
|
||||
DIERef(100, DIERef::Section::DebugInfo, DIERef::k_die_offset_mask - 1));
|
||||
EncodeDecode(
|
||||
DIERef(200, DIERef::Section::DebugTypes, DIERef::k_die_offset_mask - 1));
|
||||
EncodeDecode(DIERef(DIERef::k_file_index_mask, DIERef::Section::DebugInfo,
|
||||
DIERef::k_file_index_mask));
|
||||
EncodeDecode(DIERef(DIERef::k_file_index_mask, DIERef::Section::DebugTypes,
|
||||
DIERef::k_file_index_mask));
|
||||
EncodeDecode(DIERef(DIERef::k_file_index_mask, DIERef::Section::DebugInfo,
|
||||
0x11223344));
|
||||
EncodeDecode(DIERef(DIERef::k_file_index_mask, DIERef::Section::DebugTypes,
|
||||
0x11223344));
|
||||
}
|
||||
|
||||
static void EncodeDecode(const NameToDIE &object, ByteOrder byte_order) {
|
||||
const uint8_t addr_size = 8;
|
||||
DataEncoder encoder(byte_order, addr_size);
|
||||
|
||||
Reference in New Issue
Block a user