Index: include/lldb/lldb-forward.h =================================================================== --- include/lldb/lldb-forward.h +++ include/lldb/lldb-forward.h @@ -76,6 +76,7 @@ class ConstString; class CXXSyntheticChildren; class DWARFCallFrameInfo; +class DWARFConcatenatingDataExtractor; class DWARFDataExtractor; class DWARFExpression; class DataBuffer; Index: source/Plugins/SymbolFile/DWARF/CMakeLists.txt =================================================================== --- source/Plugins/SymbolFile/DWARF/CMakeLists.txt +++ source/Plugins/SymbolFile/DWARF/CMakeLists.txt @@ -10,6 +10,7 @@ DWARFAttribute.cpp DWARFBaseDIE.cpp DWARFCompileUnit.cpp + DWARFConcatenatingDataExtractor.cpp DWARFDataExtractor.cpp DWARFDebugAbbrev.cpp DWARFDebugAranges.cpp Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -2778,7 +2778,8 @@ if (form_value.BlockData()) { Value initialValue(0); Value memberOffset(0); - const DWARFDataExtractor &debug_info_data = die.GetData(); + const DWARFDataExtractor &debug_info_data = + die.GetData().GetDWARFDataExtractor(form_value.BlockData()); uint32_t block_length = form_value.Unsigned(); uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); @@ -3230,7 +3231,8 @@ if (form_value.BlockData()) { Value initialValue(0); Value memberOffset(0); - const DWARFDataExtractor &debug_info_data = die.GetData(); + const DWARFDataExtractor &debug_info_data = + die.GetData().GetDWARFDataExtractor(form_value.BlockData()); uint32_t block_length = form_value.Unsigned(); uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp @@ -655,7 +655,8 @@ if (form_value.BlockData()) { Value initialValue(0); Value memberOffset(0); - const DWARFDataExtractor &debug_info_data = die.GetData(); + const DWARFDataExtractor &debug_info_data = + die.GetData().GetDWARFDataExtractor(form_value.BlockData()); uint32_t block_length = form_value.Unsigned(); uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); Index: source/Plugins/SymbolFile/DWARF/DWARFAttribute.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFAttribute.h +++ source/Plugins/SymbolFile/DWARF/DWARFAttribute.h @@ -56,7 +56,7 @@ return m_infos[i].cu; } dw_offset_t DIEOffsetAtIndex(uint32_t i) const { - return m_infos[i].die_offset; + return /*m_infos[i].cu->GetOffset() +*/ m_infos[i].die_offset; } dw_attr_t AttributeAtIndex(uint32_t i) const { return m_infos[i].attr.get_attr(); Index: source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h +++ source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h @@ -87,7 +87,7 @@ // // Clients must validate that this object is valid before calling this. //---------------------------------------------------------------------- - const lldb_private::DWARFDataExtractor &GetData() const; + const lldb_private::DWARFConcatenatingDataExtractor &GetData() const; //---------------------------------------------------------------------- // Accessing information about a DIE Index: source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp @@ -186,7 +186,7 @@ return !(lhs == rhs); } -const DWARFDataExtractor &DWARFBaseDIE::GetData() const { +const DWARFConcatenatingDataExtractor &DWARFBaseDIE::GetData() const { // Clients must check if this DIE is valid before calling this function. assert(IsValid()); return m_cu->GetData(); Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -19,16 +19,6 @@ 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. /// Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -35,8 +35,3 @@ m_offset, m_length, m_version, GetAbbrevOffset(), m_addr_size, GetNextCompileUnitOffset()); } - - -const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const { - return m_dwarf->get_debug_info_data(); -} Index: source/Plugins/SymbolFile/DWARF/DWARFConcatenatingDataExtractor.h =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/DWARF/DWARFConcatenatingDataExtractor.h @@ -0,0 +1,166 @@ +//===-- DWARFConcatenatingDataExtractor.h -----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_DWARFConcatenatingDataExtractor_h_ +#define liblldb_DWARFConcatenatingDataExtractor_h_ + +#include "DWARFDataExtractor.h" + +// Other libraries and framework includes. +#include "lldb/Core/dwarf.h" + +namespace lldb_private { + +class DWARFConcatenatingDataExtractor { +public: + DWARFConcatenatingDataExtractor(const DWARFDataExtractor &extractor) + : m_extractors({&extractor}) {} + DWARFConcatenatingDataExtractor() {} + void AppendDWARFDataExtractor(const DWARFDataExtractor &extractor) { + if (extractor.GetByteSize()) + m_extractors.push_back(&extractor); + } + const DWARFDataExtractor &GetDWARFDataExtractor_slow( + const uint8_t *inner) const; + inline const DWARFDataExtractor &GetDWARFDataExtractor( + const uint8_t *inner) const; + inline const DWARFDataExtractor &GetDWARFDataExtractor( + lldb::offset_t offset) const { + return offset_to_extractor(offset, nullptr); + } + inline bool IsDWARF64(lldb::offset_t offset) const + { return GetDWARFDataExtractor(offset).IsDWARF64(); } + // forwarder-based implementation would assert on out of bound 'offset'. + bool ValidOffset(lldb::offset_t offset) const; + +#define FORWARDER(Extractor, FuncName, RetType, ParamListParen, ...) \ + inline RetType FuncName ParamListParen const \ + { return forwarder(&Extractor::FuncName, __VA_ARGS__); } + FORWARDER(DataExtractor, GetFloat, float, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DataExtractor, GetDouble, double, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DataExtractor, GetLongDouble, long double, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DataExtractor, GetMaxU32, uint32_t, + (lldb::offset_t *offset_ptr, size_t byte_size), offset_ptr, byte_size) + FORWARDER(DataExtractor, GetMaxU64, uint64_t, + (lldb::offset_t *offset_ptr, size_t byte_size), offset_ptr, byte_size) + FORWARDER(DataExtractor, GetMaxU64_unchecked, uint64_t, + (lldb::offset_t *offset_ptr, size_t byte_size), offset_ptr, byte_size) + FORWARDER(DataExtractor, GetMaxS64, int64_t, + (lldb::offset_t *offset_ptr, size_t byte_size), offset_ptr, byte_size) + FORWARDER(DataExtractor, GetMaxU64Bitfield, uint64_t, + (lldb::offset_t *offset_ptr, size_t size, uint32_t bitfield_bit_size, + uint32_t bitfield_bit_offset), + offset_ptr, size, bitfield_bit_size, bitfield_bit_offset) + FORWARDER(DataExtractor, GetMaxS64Bitfield, int64_t, + (lldb::offset_t *offset_ptr, size_t size, uint32_t bitfield_bit_size, + uint32_t bitfield_bit_offset), + offset_ptr, size, bitfield_bit_size, bitfield_bit_offset) + FORWARDER(DataExtractor, GetPointer, uint64_t, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DataExtractor, GetU8, uint8_t, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DataExtractor, GetU8_unchecked, uint8_t, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DataExtractor, GetU16_unchecked, uint16_t, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DataExtractor, GetU32_unchecked, uint32_t, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DataExtractor, GetU64_unchecked, uint64_t, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DataExtractor, GetU8, void *, + (lldb::offset_t *offset_ptr, void *dst, uint32_t count), + offset_ptr, dst, count) + FORWARDER(DataExtractor, GetU16, uint16_t, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DataExtractor, GetU16, void *, + (lldb::offset_t *offset_ptr, void *dst, uint32_t count), + offset_ptr, dst, count) + FORWARDER(DataExtractor, GetU32, uint32_t, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DataExtractor, GetU32, void *, + (lldb::offset_t *offset_ptr, void *dst, uint32_t count), + offset_ptr, dst, count) + FORWARDER(DataExtractor, GetU64, uint64_t, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DataExtractor, GetU64, void *, + (lldb::offset_t *offset_ptr, void *dst, uint32_t count), + offset_ptr, dst, count) + FORWARDER(DataExtractor, GetSLEB128, int64_t, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DataExtractor, GetULEB128, uint64_t, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DataExtractor, PeekData, const uint8_t *, + (lldb::offset_t offset, lldb::offset_t length), offset, length) + FORWARDER(DataExtractor, GetCStr, const char *, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DataExtractor, Skip_LEB128, uint32_t, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DataExtractor, ValidOffsetForDataOfSize, bool, + (lldb::offset_t offset, lldb::offset_t length), offset, length) + FORWARDER(DWARFDataExtractor, GetDWARFOffset, dw_offset_t, + (lldb::offset_t *offset_ptr), offset_ptr) + FORWARDER(DWARFDataExtractor, GetDWARFInitialLength, uint64_t, + (lldb::offset_t *offset_ptr), offset_ptr) +#undef FORWARDER + +private: + const DWARFDataExtractor &offset_to_extractor_slow(lldb::offset_t offset, + lldb::offset_t *extractor_offsetp) const; + inline const DWARFDataExtractor &offset_to_extractor(lldb::offset_t offset, + lldb::offset_t *extractor_offsetp) const; + template + inline RetType forwarder( + RetType (Extractor::*mptr)(lldb::offset_t *offset_ptr, Args...) const, + lldb::offset_t *offset_ptr, Args... args) const { + lldb::offset_t extractor_offset; + const Extractor &extractor = + offset_to_extractor(*offset_ptr, &extractor_offset); + *offset_ptr -= extractor_offset; + RetType retval = (extractor.*mptr)(offset_ptr, std::forward(args)...); + *offset_ptr += extractor_offset; + return retval; + } + template + inline RetType forwarder( + RetType (Extractor::*mptr)(lldb::offset_t offset, Args...) const, + lldb::offset_t offset, Args... args) const { + lldb::offset_t extractor_offset; + const Extractor &extractor = offset_to_extractor(offset, &extractor_offset); + offset -= extractor_offset; + return (extractor.*mptr)(offset, std::forward(args)...); + } + + llvm::SmallVector m_extractors; +}; + +const DWARFDataExtractor &DWARFConcatenatingDataExtractor::offset_to_extractor( + lldb::offset_t offset, lldb::offset_t *extractor_offsetp) const { + if (extractor_offsetp) + *extractor_offsetp = 0; + if (m_extractors.size() == 1) + return *m_extractors[0]; + + return offset_to_extractor_slow(offset, extractor_offsetp); +} + +const DWARFDataExtractor & + DWARFConcatenatingDataExtractor::GetDWARFDataExtractor( + const uint8_t *inner) const { + if (m_extractors.size() == 1) + return *m_extractors[0]; + + return GetDWARFDataExtractor_slow(inner); +} + +} + +#endif // liblldb_DWARFConcatenatingDataExtractor_h_ Index: source/Plugins/SymbolFile/DWARF/DWARFConcatenatingDataExtractor.cpp =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/DWARF/DWARFConcatenatingDataExtractor.cpp @@ -0,0 +1,48 @@ +//===-- DWARFConcatenatingDataExtractor.cpp ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DWARFConcatenatingDataExtractor.h" +#include "lldb/Utility/LLDBAssert.h" + +namespace lldb_private { + +const DWARFDataExtractor & + DWARFConcatenatingDataExtractor::offset_to_extractor_slow( + lldb::offset_t offset, lldb::offset_t *extractor_offsetp) const { + for (const DWARFDataExtractor *extractorp : m_extractors) { + if (offset < extractorp->GetByteSize()) + return *extractorp; + offset -= extractorp->GetByteSize(); + if (extractor_offsetp) + *extractor_offsetp += extractorp->GetByteSize(); + } + lldbassert(0); + return *m_extractors[0]; +} + +const DWARFDataExtractor & + DWARFConcatenatingDataExtractor::GetDWARFDataExtractor_slow( + const uint8_t *inner) const { + for (const DWARFDataExtractor *extractorp : m_extractors) + if (inner >= extractorp->GetDataStart() && inner < extractorp->GetDataEnd()) + return *extractorp; + lldbassert(0); + return *m_extractors[0]; +} + +bool DWARFConcatenatingDataExtractor::ValidOffset(lldb::offset_t offset) const { + for (const DWARFDataExtractor *extractorp : m_extractors) { + if (offset < extractorp->GetByteSize()) + return true; + offset -= extractorp->GetByteSize(); + } + return false; +} + +} Index: source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h +++ source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h @@ -32,30 +32,6 @@ size_t GetDWARFSizeOfOffset() const { return m_is_dwarf64 ? 8 : 4; } bool IsDWARF64() const { return m_is_dwarf64; } - //------------------------------------------------------------------ - /// Slide the data in the buffer so that access to the data will - /// start at offset \a offset. - /// - /// This is currently used to provide access to the .debug_types - /// section and pretend it starts at at offset of the size of the - /// .debug_info section. This allows a minimally invasive change to - /// add support for .debug_types by allowing all DIEs to have unique - /// offsets and thus allowing no code to change in the DWARF parser. - /// Modifying the offsets in the .debug_types doesn't affect - /// anything because since all info in the .debug_types is type unit - /// relative and no types within a type unit can refer to any DIEs - /// outside of the type unit without using DW_AT_signature. It also - /// sets us up to move to DWARF5 where there is no .debug_types - /// section as compile units and type units are in the .debug_info. - /// - /// @param[in] offset - /// The amount to slide the data contents by. - //------------------------------------------------------------------ - void OffsetData(lldb::offset_t offset) { - if (GetByteSize()) - m_start -= offset; - } - protected: mutable bool m_is_dwarf64; }; Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -103,9 +103,11 @@ lldb::offset_t offset = 0; DWARFCompileUnitSP cu_sp; - const auto &debug_info_data = m_dwarf2Data->get_debug_info_data(); - while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, debug_info_data, - &offset))) { + const DWARFDataExtractor &debug_info_data = + m_dwarf2Data->get_debug_info_data(); + while (offset < debug_info_data.GetByteSize() + && (cu_sp = DWARFCompileUnit::Extract( + m_dwarf2Data, debug_info_data, &offset))) { m_compile_units.push_back(cu_sp); offset = cu_sp->GetNextCompileUnitOffset(); } @@ -119,15 +121,12 @@ // types in the .debug_types to have a unique DIE offset that is: // offset = sizeof(.debug_info) + debug_type_offset // - // So below we set "offset" to be the size of the .debug_info section. We have - // modified the debug_types_data to know that its first byte starts at this - // offset. - auto debug_types_data = m_dwarf2Data->get_debug_types_data(); - if (debug_types_data.GetByteSize() == 0) - return; - offset = debug_info_data.GetByteSize(); + // We must use get_debug_concatenated_data() so that .debug_types start at + // size of the .debug_info section. + const DWARFConcatenatingDataExtractor &debug_concatenated_data = + m_dwarf2Data->get_debug_concatenated_data(); DWARFTypeUnitSP tu_sp; - while ((tu_sp = DWARFTypeUnit::Extract(m_dwarf2Data, debug_types_data, + while ((tu_sp = DWARFTypeUnit::Extract(m_dwarf2Data, debug_concatenated_data, &offset))) { m_type_sig_to_cu_index[tu_sp->GetTypeSignature()] = m_compile_units.size(); m_compile_units.push_back(tu_sp); Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h +++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h @@ -72,10 +72,11 @@ const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const; - bool FastExtract(const lldb_private::DWARFDataExtractor &debug_info_data, - const DWARFUnit *cu, - const DWARFFormValue::FixedFormSizes &fixed_form_sizes, - lldb::offset_t *offset_ptr); + bool FastExtract( + const lldb_private::DWARFConcatenatingDataExtractor &debug_info_data, + const DWARFUnit *cu, + const DWARFFormValue::FixedFormSizes &fixed_form_sizes, + lldb::offset_t *offset_ptr); bool Extract(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, lldb::offset_t *offset_ptr); Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -34,7 +34,7 @@ extern int g_verbose; bool DWARFDebugInfoEntry::FastExtract( - const DWARFDataExtractor &debug_info_data, const DWARFUnit *cu, + const DWARFConcatenatingDataExtractor &debug_info_data, const DWARFUnit *cu, const DWARFFormValue::FixedFormSizes &fixed_form_sizes, lldb::offset_t *offset_ptr) { m_offset = *offset_ptr; @@ -196,7 +196,7 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, lldb::offset_t *offset_ptr) { - const DWARFDataExtractor &debug_info_data = cu->GetData(); + const DWARFConcatenatingDataExtractor &debug_info_data = cu->GetData(); // const DWARFDataExtractor& debug_str_data = // dwarf2Data->get_debug_str_data(); const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset(); @@ -403,7 +403,7 @@ lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule(); if (abbrevDecl) { - const DWARFDataExtractor &debug_info_data = cu->GetData(); + const DWARFConcatenatingDataExtractor &debug_info_data = cu->GetData(); if (!debug_info_data.ValidOffset(offset)) return false; @@ -514,10 +514,12 @@ case DW_AT_frame_base: if (frame_base) { if (form_value.BlockData()) { - uint32_t block_offset = - form_value.BlockData() - debug_info_data.GetDataStart(); + const DWARFDataExtractor &block_extractor = + debug_info_data.GetDWARFDataExtractor(form_value.BlockData()); + uint32_t block_offset = form_value.BlockData() + - block_extractor.GetDataStart(); uint32_t block_length = form_value.Unsigned(); - frame_base->SetOpcodeData(module, debug_info_data, block_offset, + frame_base->SetOpcodeData(module, block_extractor, block_offset, block_length); } else { const DWARFDataExtractor &debug_loc_data = @@ -586,7 +588,7 @@ void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, Stream &s, uint32_t recurse_depth) const { - const DWARFDataExtractor &debug_info_data = cu->GetData(); + const DWARFConcatenatingDataExtractor &debug_info_data = cu->GetData(); lldb::offset_t offset = m_offset; if (debug_info_data.ValidOffset(offset)) { @@ -612,8 +614,9 @@ for (i = 0; i < numAttributes; ++i) { abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); - DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr, - form); + DumpAttribute(dwarf2Data, cu, + debug_info_data.GetDWARFDataExtractor(offset), &offset, + s, attr, form); } const DWARFDebugInfoEntry *child = GetFirstChild(); @@ -779,7 +782,7 @@ } if (abbrevDecl) { - const DWARFDataExtractor &debug_info_data = cu->GetData(); + const DWARFConcatenatingDataExtractor &debug_info_data = cu->GetData(); if (fixed_form_sizes.Empty()) fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize( @@ -861,7 +864,7 @@ uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr); if (attr_idx != DW_INVALID_INDEX) { - const DWARFDataExtractor &debug_info_data = cu->GetData(); + const DWARFConcatenatingDataExtractor &debug_info_data = cu->GetData(); uint32_t idx = 0; while (idx < attr_idx) Index: source/Plugins/SymbolFile/DWARF/DWARFFormValue.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFFormValue.h +++ source/Plugins/SymbolFile/DWARF/DWARFFormValue.h @@ -11,7 +11,7 @@ #define SymbolFileDWARF_DWARFFormValue_h_ #include "DWARFDIE.h" -#include "DWARFDataExtractor.h" +#include "DWARFConcatenatingDataExtractor.h" #include // for NULL class DWARFUnit; @@ -63,7 +63,7 @@ void SetForm(dw_form_t form) { m_form = form; } const ValueType &Value() const { return m_value; } void Dump(lldb_private::Stream &s) const; - bool ExtractValue(const lldb_private::DWARFDataExtractor &data, + bool ExtractValue(const lldb_private::DWARFConcatenatingDataExtractor &data, lldb::offset_t *offset_ptr); const uint8_t *BlockData() const; uint64_t Reference() const; @@ -77,11 +77,13 @@ const char *AsCString() const; dw_addr_t Address() const; bool IsValid() const { return m_form != 0; } - bool SkipValue(const lldb_private::DWARFDataExtractor &debug_info_data, - lldb::offset_t *offset_ptr) const; - static bool SkipValue(const dw_form_t form, - const lldb_private::DWARFDataExtractor &debug_info_data, - lldb::offset_t *offset_ptr, const DWARFUnit *cu); + bool SkipValue( + const lldb_private::DWARFConcatenatingDataExtractor &debug_info_data, + lldb::offset_t *offset_ptr) const; + static bool SkipValue( + const dw_form_t form, + const lldb_private::DWARFConcatenatingDataExtractor &debug_info_data, + lldb::offset_t *offset_ptr, const DWARFUnit *cu); static bool IsBlockForm(const dw_form_t form); static bool IsDataForm(const dw_form_t form); static FixedFormSizes GetFixedFormSizesForAddressSize(uint8_t addr_size, Index: source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -163,7 +163,7 @@ memset(&m_value, 0, sizeof(m_value)); } -bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, +bool DWARFFormValue::ExtractValue(const DWARFConcatenatingDataExtractor &data, lldb::offset_t *offset_ptr) { bool indirect = false; bool is_block = false; @@ -288,15 +288,15 @@ return true; } -bool DWARFFormValue::SkipValue(const DWARFDataExtractor &debug_info_data, - lldb::offset_t *offset_ptr) const { +bool DWARFFormValue::SkipValue( + const DWARFConcatenatingDataExtractor &debug_info_data, + lldb::offset_t *offset_ptr) const { return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, m_cu); } -bool DWARFFormValue::SkipValue(dw_form_t form, - const DWARFDataExtractor &debug_info_data, - lldb::offset_t *offset_ptr, - const DWARFUnit *cu) { +bool DWARFFormValue::SkipValue( + dw_form_t form, const DWARFConcatenatingDataExtractor &debug_info_data, + lldb::offset_t *offset_ptr, const DWARFUnit *cu) { uint8_t ref_addr_size; switch (form) { // Blocks if inlined data that have a length field and the data bytes inlined Index: source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h +++ source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h @@ -18,23 +18,13 @@ public: virtual ~DWARFTypeUnit(); - static DWARFTypeUnitSP Extract(SymbolFileDWARF *dwarf2Data, - const lldb_private::DWARFDataExtractor &data, - lldb::offset_t *offset_ptr); + static DWARFTypeUnitSP Extract( + SymbolFileDWARF *dwarf2Data, + const lldb_private::DWARFConcatenatingDataExtractor &data, + 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. /// Index: source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp @@ -30,7 +30,7 @@ } DWARFTypeUnitSP DWARFTypeUnit::Extract(SymbolFileDWARF *dwarf, - const lldb_private::DWARFDataExtractor &data, lldb::offset_t *offset_ptr) { + const DWARFConcatenatingDataExtractor &data, lldb::offset_t *offset_ptr) { // std::make_shared would require the ctor to be public. std::shared_ptr cu_sp(new DWARFTypeUnit(dwarf)); // Out of memory? @@ -51,13 +51,3 @@ // unit offset to ensure we get the correct DIE. return GetDIE(GetTypeUnitDIEOffset()); } - -const lldb_private::DWARFDataExtractor &DWARFTypeUnit::GetData() const { - // In DWARF 5, type units are in the .debug_info section. Prior to DWARF 5 - // type units are in the .debug_types section. - if (GetVersion() < 5) - return m_dwarf->get_debug_types_data(); - else - return m_dwarf->get_debug_info_data(); -} - Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -43,7 +43,7 @@ virtual ~DWARFUnit(); bool ExtractHeader(SymbolFileDWARF *dwarf, - const lldb_private::DWARFDataExtractor &data, + const lldb_private::DWARFConcatenatingDataExtractor &data, lldb::offset_t *offset_ptr); DWARFTypeUnit *GetAsTypeUnit(); @@ -79,7 +79,7 @@ /// @return /// The correct data for the DIE information in this unit. //------------------------------------------------------------------ - virtual const lldb_private::DWARFDataExtractor &GetData() const = 0; + const lldb_private::DWARFConcatenatingDataExtractor &GetData() const; //------------------------------------------------------------------ /// Get the size in bytes of the compile unit header. /// Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -61,7 +61,7 @@ // We are in our compile unit, parse starting at the offset we were told to // parse - const DWARFDataExtractor &data = GetData(); + const DWARFConcatenatingDataExtractor &data = GetData(); DWARFFormValue::FixedFormSizes fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(GetAddressByteSize(), IsDWARF64()); @@ -183,7 +183,7 @@ uint32_t depth = 0; // We are in our compile unit, parse starting at the offset we were told to // parse - const DWARFDataExtractor &data = GetData(); + const DWARFConcatenatingDataExtractor &data = GetData(); std::vector die_index_stack; die_index_stack.reserve(32); die_index_stack.push_back(0); @@ -786,7 +786,7 @@ bool DWARFUnit::ExtractHeader(SymbolFileDWARF *dwarf, - const lldb_private::DWARFDataExtractor &data, + const DWARFConcatenatingDataExtractor &data, lldb::offset_t *offset_ptr) { m_offset = *offset_ptr; @@ -794,7 +794,7 @@ dw_offset_t abbr_offset; const DWARFDebugAbbrev *abbr = dwarf->DebugAbbrev(); m_length = data.GetDWARFInitialLength(offset_ptr); - m_is_dwarf64 = data.IsDWARF64(); + m_is_dwarf64 = data.IsDWARF64(*offset_ptr); m_version = data.GetU16(offset_ptr); abbr_offset = data.GetDWARFOffset(offset_ptr); m_addr_size = data.GetU8(offset_ptr); @@ -816,3 +816,6 @@ return false; } +const lldb_private::DWARFConcatenatingDataExtractor &DWARFUnit::GetData() const { + return m_dwarf->get_debug_concatenated_data(); +} Index: source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h +++ source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h @@ -10,6 +10,7 @@ #ifndef LLDB_DEBUGNAMESDWARFINDEX_H #define LLDB_DEBUGNAMESDWARFINDEX_H +#include "Plugins/SymbolFile/DWARF/DWARFDataExtractor.h" #include "Plugins/SymbolFile/DWARF/DWARFIndex.h" #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h" #include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h" Index: source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h =================================================================== --- source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h +++ source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h @@ -17,6 +17,7 @@ #include "lldb/Utility/RegularExpression.h" #include "lldb/lldb-defines.h" +#include "DWARFDataExtractor.h" #include "DWARFDefines.h" #include "DWARFFormValue.h" #include "NameToDIE.h" Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -36,6 +36,7 @@ #include "lldb/lldb-private.h" // Project includes +#include "DWARFConcatenatingDataExtractor.h" #include "DWARFDataExtractor.h" #include "DWARFDefines.h" #include "DWARFIndex.h" @@ -252,6 +253,9 @@ const lldb_private::DWARFDataExtractor &get_apple_objc_data(); const lldb_private::DWARFDataExtractor &get_gnu_debugaltlink(); + const lldb_private::DWARFConcatenatingDataExtractor & + get_debug_concatenated_data(); + DWARFDebugAbbrev *DebugAbbrev(); const DWARFDebugAbbrev *DebugAbbrev() const; @@ -459,6 +463,8 @@ std::unique_ptr m_dwp_symfile; lldb_private::DWARFDataExtractor m_dwarf_data; + llvm::once_flag m_concatenated_data_once; + lldb_private::DWARFConcatenatingDataExtractor m_concatenated_data; DWARFDataSegment m_data_debug_abbrev; DWARFDataSegment m_data_debug_addr; Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -580,24 +580,8 @@ const DWARFDataExtractor & SymbolFileDWARF::GetCachedSectionData(lldb::SectionType sect_type, DWARFDataSegment &data_segment) { - llvm::call_once(data_segment.m_flag, [&] { + llvm::call_once(data_segment.m_flag, [this, sect_type, &data_segment] { this->LoadSectionData(sect_type, std::ref(data_segment.m_data)); - if (sect_type == eSectionTypeDWARFDebugTypes) { - // To add .debug_types support in DWARF 4 and earlier with minimally - // invasive changes to the current DWARF parsing code, we pretend that - // any DIEs in .debug_types start at the end of the .debug_info section. - // All info in .debug_types is relative and has no external DIE - // references unless thay are DW_AT_signature references, so the DIE - // offset for things in the .debug_types. If we do this, then we can - // just add the type units to the compile units collection and treat all - // information just as we do for all other information in the DWARF and - // everything just works. If we were to try to split this out, we would - // end up having to change a TON of code. Also DWARF 5 will have compile - // and type units in the .debug_info, so coding it this way will prepare - // use for an easy transition to DWARF 5. - uint64_t debug_info_size = get_debug_info_data().GetByteSize(); - data_segment.m_data.OffsetData(debug_info_size); - } }); return data_segment.m_data; } @@ -695,6 +679,15 @@ m_data_gnu_debugaltlink); } +const DWARFConcatenatingDataExtractor & + SymbolFileDWARF::get_debug_concatenated_data() { + llvm::call_once(m_concatenated_data_once, [&] { + m_concatenated_data.AppendDWARFDataExtractor(get_debug_info_data()); + m_concatenated_data.AppendDWARFDataExtractor(get_debug_types_data()); + }); + return m_concatenated_data; +} + DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() { if (m_abbr.get() == NULL) { const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data(); @@ -3239,10 +3232,12 @@ auto debug_info_data = die.GetData(); if (DWARFFormValue::IsBlockForm(form_value.Form())) { // Retrieve the value as a block expression. + const DWARFDataExtractor &block_extractor = + debug_info_data.GetDWARFDataExtractor(form_value.BlockData()); uint32_t block_offset = - form_value.BlockData() - debug_info_data.GetDataStart(); + form_value.BlockData() - block_extractor.GetDataStart(); uint32_t block_length = form_value.Unsigned(); - location.CopyOpcodeData(module, debug_info_data, block_offset, + location.CopyOpcodeData(module, block_extractor, block_offset, block_length); } else if (DWARFFormValue::IsDataForm(form_value.Form())) { // Retrieve the value as a data expression. @@ -3262,9 +3257,12 @@ // create the variable const_value = form_value; } - } else - location.CopyOpcodeData(module, debug_info_data, data_offset, + } else { + const DWARFDataExtractor &block_extractor = + debug_info_data.GetDWARFDataExtractor(data_offset); + location.CopyOpcodeData(module, block_extractor, data_offset, data_length); + } } else { // Retrieve the value as a string expression. if (form_value.Form() == DW_FORM_strp) { @@ -3274,16 +3272,21 @@ ->GetAddressByteSize(), attributes.CompileUnitAtIndex(i)->IsDWARF64()); uint32_t data_offset = attributes.DIEOffsetAtIndex(i); + const DWARFDataExtractor &block_extractor = + debug_info_data.GetDWARFDataExtractor(data_offset); uint32_t data_length = fixed_form_sizes.GetSize(form_value.Form()); - location.CopyOpcodeData(module, debug_info_data, data_offset, + location.CopyOpcodeData(module, block_extractor, data_offset, data_length); } else { const char *str = form_value.AsCString(); + const DWARFDataExtractor &block_extractor = + debug_info_data.GetDWARFDataExtractor( + (const uint8_t *)str); uint32_t string_offset = - str - (const char *)debug_info_data.GetDataStart(); + str - (const char *)block_extractor.GetDataStart(); uint32_t string_length = strlen(str) + 1; - location.CopyOpcodeData(module, debug_info_data, + location.CopyOpcodeData(module, block_extractor, string_offset, string_length); } } @@ -3295,10 +3298,13 @@ if (DWARFFormValue::IsBlockForm(form_value.Form())) { auto data = die.GetData(); + const DWARFDataExtractor &block_extractor = + data.GetDWARFDataExtractor(form_value.BlockData()); uint32_t block_offset = - form_value.BlockData() - data.GetDataStart(); + form_value.BlockData() - block_extractor.GetDataStart(); uint32_t block_length = form_value.Unsigned(); - location.CopyOpcodeData(module, data, block_offset, block_length); + location.CopyOpcodeData( + module, block_extractor, block_offset, block_length); } else { const DWARFDataExtractor &debug_loc_data = get_debug_loc_data(); const dw_offset_t debug_loc_offset = form_value.Unsigned();