diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile')
5 files changed, 105 insertions, 12 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 26ca8c3acf4..f42164deafc 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -1067,9 +1067,9 @@ size_t DWARFDebugInfoEntry::GetAttributeAddressRanges( dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET, check_specification_or_abstract_origin); if (debug_ranges_offset != DW_INVALID_OFFSET) { - DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges(); - - debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, ranges); + if (DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges()) + debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, + ranges); ranges.Slide(cu->GetBaseAddress()); } else if (check_hi_lo_pc) { dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp index 89e27efb3cc..e891fce4288 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp @@ -123,3 +123,71 @@ bool DWARFDebugRanges::FindRanges(dw_addr_t debug_ranges_base, } return false; } + +bool DWARFDebugRngLists::ExtractRangeList(const DWARFDataExtractor &data, + uint8_t addrSize, + lldb::offset_t *offset_ptr, + DWARFRangeList &rangeList) { + rangeList.Clear(); + + bool error = false; + while (!error) { + switch (data.GetU8(offset_ptr)) { + case DW_RLE_end_of_list: + return true; + + case DW_RLE_start_length: { + dw_addr_t begin = data.GetMaxU64(offset_ptr, addrSize); + dw_addr_t len = data.GetULEB128(offset_ptr); + rangeList.Append(DWARFRangeList::Entry(begin, len)); + break; + } + + default: + // Next encodings are not yet supported: + // DW_RLE_base_addressx, DW_RLE_startx_endx, DW_RLE_startx_length, + // DW_RLE_offset_pair, DW_RLE_base_address, DW_RLE_start_end + lldbassert(0 && "unknown range list entry encoding"); + error = true; + } + } + + return false; +} + +void DWARFDebugRngLists::Extract(SymbolFileDWARF *dwarf2Data) { + const DWARFDataExtractor &data = dwarf2Data->get_debug_rnglists_data(); + lldb::offset_t offset = 0; + + uint64_t length = data.GetU32(&offset); + bool isDwarf64 = false; + if (length == 0xffffffff) { + length = data.GetU64(&offset); + isDwarf64 = true; + } + lldb::offset_t end = offset + length; + + // Check version. + if (data.GetU16(&offset) < 5) + return; + + uint8_t addrSize = data.GetU8(&offset); + + // We do not support non-zero segment selector size. + if (data.GetU8(&offset) != 0) { + lldbassert(0 && "not implemented"); + return; + } + + uint32_t offsetsAmount = data.GetU32(&offset); + for (uint32_t i = 0; i < offsetsAmount; ++i) + Offsets.push_back(data.GetPointer(&offset)); + + lldb::offset_t listOffset = offset; + DWARFRangeList rangeList; + while (offset < end && ExtractRangeList(data, addrSize, &offset, rangeList)) { + rangeList.Sort(); + m_range_map[listOffset] = rangeList; + listOffset = offset; + } +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h index f514359e00a..e239bc54add 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h @@ -18,8 +18,9 @@ class DWARFDebugRanges { public: DWARFDebugRanges(); - ~DWARFDebugRanges(); - void Extract(SymbolFileDWARF *dwarf2Data); + virtual ~DWARFDebugRanges(); + virtual void Extract(SymbolFileDWARF *dwarf2Data); + static void Dump(lldb_private::Stream &s, const lldb_private::DWARFDataExtractor &debug_ranges_data, lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr); @@ -37,4 +38,17 @@ protected: range_map m_range_map; }; +// DWARF v5 .debug_rnglists section. +class DWARFDebugRngLists : public DWARFDebugRanges { +public: + void Extract(SymbolFileDWARF *dwarf2Data) override; + +protected: + bool ExtractRangeList(const lldb_private::DWARFDataExtractor &data, + uint8_t addrSize, lldb::offset_t *offset_ptr, + DWARFRangeList &list); + + std::vector<uint64_t> Offsets; +}; + #endif // SymbolFileDWARF_DWARFDebugRanges_h_ diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 4f9e726f065..59163a9a027 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -410,9 +410,9 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile) m_debug_map_module_wp(), m_debug_map_symfile(NULL), m_data_debug_abbrev(), m_data_debug_aranges(), m_data_debug_frame(), m_data_debug_info(), m_data_debug_line(), m_data_debug_macro(), m_data_debug_loc(), - m_data_debug_ranges(), m_data_debug_str(), m_data_apple_names(), - m_data_apple_types(), m_data_apple_namespaces(), m_abbr(), m_info(), - m_line(), m_fetched_external_modules(false), + m_data_debug_ranges(), m_data_debug_rnglists(), m_data_debug_str(), + m_data_apple_names(), m_data_apple_types(), m_data_apple_namespaces(), + m_abbr(), m_info(), m_line(), m_fetched_external_modules(false), m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), m_ranges(), m_unique_ast_type_map() {} @@ -659,6 +659,11 @@ const DWARFDataExtractor &SymbolFileDWARF::get_debug_ranges_data() { m_data_debug_ranges); } +const DWARFDataExtractor &SymbolFileDWARF::get_debug_rnglists_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugRngLists, + m_data_debug_rnglists); +} + const DWARFDataExtractor &SymbolFileDWARF::get_debug_str_data() { return GetCachedSectionData(eSectionTypeDWARFDebugStr, m_data_debug_str); } @@ -753,11 +758,14 @@ DWARFDebugRanges *SymbolFileDWARF::DebugRanges() { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION, static_cast<void *>(this)); - if (get_debug_ranges_data().GetByteSize() > 0) { + + if (get_debug_ranges_data().GetByteSize() > 0) m_ranges.reset(new DWARFDebugRanges()); - if (m_ranges.get()) - m_ranges->Extract(this); - } + else if (get_debug_rnglists_data().GetByteSize() > 0) + m_ranges.reset(new DWARFDebugRngLists()); + + if (m_ranges.get()) + m_ranges->Extract(this); } return m_ranges.get(); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index abf4e39bc47..b3d087f0812 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -54,6 +54,7 @@ class DWARFDebugInfo; class DWARFDebugInfoEntry; class DWARFDebugLine; class DWARFDebugRanges; +class DWARFDebugRngLists; class DWARFDeclContext; class DWARFDIECollection; class DWARFFormValue; @@ -244,6 +245,7 @@ public: const lldb_private::DWARFDataExtractor &get_debug_macro_data(); const lldb_private::DWARFDataExtractor &get_debug_loc_data(); const lldb_private::DWARFDataExtractor &get_debug_ranges_data(); + const lldb_private::DWARFDataExtractor &get_debug_rnglists_data(); const lldb_private::DWARFDataExtractor &get_debug_str_data(); const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data(); const lldb_private::DWARFDataExtractor &get_debug_types_data(); @@ -474,6 +476,7 @@ protected: DWARFDataSegment m_data_debug_macro; DWARFDataSegment m_data_debug_loc; DWARFDataSegment m_data_debug_ranges; + DWARFDataSegment m_data_debug_rnglists; DWARFDataSegment m_data_debug_str; DWARFDataSegment m_data_debug_str_offsets; DWARFDataSegment m_data_debug_types; |