Index: lldb/trunk/include/lldb/lldb-enumerations.h =================================================================== --- lldb/trunk/include/lldb/lldb-enumerations.h +++ lldb/trunk/include/lldb/lldb-enumerations.h @@ -675,6 +675,7 @@ eSectionTypeDWARFDebugNames, // DWARF v5 .debug_names eSectionTypeOther, eSectionTypeDWARFDebugLineStr, // DWARF v5 .debug_line_str + eSectionTypeDWARFDebugRngLists, // DWARF v5 .debug_rnglists }; FLAGS_ENUM(EmulateInstructionOptions){ Index: lldb/trunk/lit/Breakpoint/Inputs/debug_rnglist_basic.yaml =================================================================== --- lldb/trunk/lit/Breakpoint/Inputs/debug_rnglist_basic.yaml +++ lldb/trunk/lit/Breakpoint/Inputs/debug_rnglist_basic.yaml @@ -0,0 +1,50 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 + Entry: 0x0000000000400440 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x0000000000400440 + AddressAlign: 0x0000000000000010 + Content: 31ED4989D15E4889E24883E4F0505449C7C0C005400048C7C15005400048C7C730054000E8B7FFFFFFF4660F1F44000055B820204000483D202040004889E57417B8000000004885C0740D5DBF20204000FFE00F1F4400005DC3660F1F440000BE20204000554881EE202040004889E548C1FE034889F048C1E83F4801C648D1FE7415B8000000004885C0740B5DBF20204000FFE00F1F005DC3660F1F440000803D391B0000007517554889E5E87EFFFFFFC605271B0000015DC30F1F440000F3C30F1F4000662E0F1F840000000000554889E55DEB89900F1F840000000000554889E5B8010000005DC30F1F440000554889E54883EC10C745FC00000000E8DCFFFFFF4883C4105DC3660F1F440000415741564189FF415541544C8D25A618000055488D2DA6180000534989F64989D54C29E54883EC0848C1FD03E86FFEFFFF4885ED742031DB0F1F8400000000004C89EA4C89F64489FF41FF14DC4883C3014839EB75EA4883C4085B5D415C415D415E415FC390662E0F1F840000000000F3C3 + - Name: .debug_str_offsets + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 200000000500000000000000230000002C0000005D00000065000000690000006D000000 + - Name: .debug_str + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + Content: 636C616E672076657273696F6E20382E302E3020287472756E6B203334333438372900746573742E637070002F686F6D652F756D622F74657374735F323031382F313033726E676C697374732F6C6C64622F63726561746574657374005F5A337A656476007A656400696E74006D61696E00 + - Name: .debug_abbrev + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 011101252513050325721710171B251101551774170000022E001101120640186E2503253A0B3B0B49133F190000032E0011011206401803253A0B3B0B49133F19000004240003253E0B0B0B000000 + - Name: .debug_info + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 580000000500010800000000010004000108000000000000000200000000000000000C0000000C0000000220054000000000000B000000015603040101570000000330054000000000001A0000000156060105570000000405050400 + - Name: .debug_rnglists + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 1D00000005000800000000000720054000000000000B0730054000000000001A00 + - Name: .debug_macinfo + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: '00' + - Name: .debug_line + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 82000000050008004C000000010101FB0E0D00010101010000000100000101011F010000000003011F020F051E023100000000F7B7492A97F18E69F7EC76B19E9024873100000000F7B7492A97F18E69F7EC76B19E90248700090220054000000000000105020A4B020700010100090230054000000000001605090AE5050206580206000101 + - Name: .debug_line_str + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + Content: 2F686F6D652F756D622F74657374735F323031382F313033726E676C697374732F6C6C64622F6372656174657465737400746573742E63707000 +Symbols: +... Index: lldb/trunk/lit/Breakpoint/debug_rnglist_basic.test =================================================================== --- lldb/trunk/lit/Breakpoint/debug_rnglist_basic.test +++ lldb/trunk/lit/Breakpoint/debug_rnglist_basic.test @@ -0,0 +1,30 @@ +# RUN: yaml2obj %p/Inputs/debug_rnglist_basic.yaml > %ttest +# RUN: lldb-test breakpoints %ttest %s | FileCheck %s + +# The following code and invocation were used to produce yaml file, +# which was manually reduced after that. +# clang -O0 -gdwarf-5 test.cpp -o test -fuse-ld=lld -ffunction-sections +# +# //test.cpp: +# int zed() { +# return 1; +# } +# +# int main() { +# return zed(); +# } +# +# clang and LLD versions were 8.0.0 (trunk 343487) +# +# Output file contains .debug_rnglists section with basic entries: +# DW_RLE_start_length and DW_RLE_end_of_list. +# If LLDB would not be able to parse the section and entries correctly, +# then reported location would be incorrect. + +b main +# CHECK-LABEL: b main +# CHECK: Address: {{.*}}`main + 15 at test.cpp:6:9 + +b zed +# CHECK-LABEL: b zed +# CHECK: Address: {{.*}}`zed() + 4 at test.cpp:2:2 Index: lldb/trunk/source/Core/Section.cpp =================================================================== --- lldb/trunk/source/Core/Section.cpp +++ lldb/trunk/source/Core/Section.cpp @@ -87,6 +87,8 @@ return "dwarf-pubtypes"; case eSectionTypeDWARFDebugRanges: return "dwarf-ranges"; + case eSectionTypeDWARFDebugRngLists: + return "dwarf-rnglists"; case eSectionTypeDWARFDebugStr: return "dwarf-str"; case eSectionTypeDWARFDebugStrOffsets: Index: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp =================================================================== --- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -1796,6 +1796,7 @@ static ConstString g_sect_name_dwarf_debug_pubnames(".debug_pubnames"); static ConstString g_sect_name_dwarf_debug_pubtypes(".debug_pubtypes"); static ConstString g_sect_name_dwarf_debug_ranges(".debug_ranges"); + static ConstString g_sect_name_dwarf_debug_rnglists(".debug_rnglists"); static ConstString g_sect_name_dwarf_debug_str(".debug_str"); static ConstString g_sect_name_dwarf_debug_str_offsets( ".debug_str_offsets"); @@ -1879,6 +1880,8 @@ sect_type = eSectionTypeDWARFDebugPubTypes; else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges; + else if (name == g_sect_name_dwarf_debug_rnglists) + sect_type = eSectionTypeDWARFDebugRngLists; else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr; else if (name == g_sect_name_dwarf_debug_types) Index: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp =================================================================== --- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -1205,6 +1205,7 @@ case eSectionTypeDWARFDebugPubNames: case eSectionTypeDWARFDebugPubTypes: case eSectionTypeDWARFDebugRanges: + case eSectionTypeDWARFDebugRngLists: case eSectionTypeDWARFDebugStr: case eSectionTypeDWARFDebugStrOffsets: case eSectionTypeDWARFDebugTypes: @@ -1494,7 +1495,7 @@ if (section_name == g_sect_name_dwarf_debug_pubtypes) return eSectionTypeDWARFDebugPubTypes; if (section_name == g_sect_name_dwarf_debug_ranges) - return eSectionTypeDWARFDebugRanges; + return eSectionTypeDWARFDebugRanges; if (section_name == g_sect_name_dwarf_debug_str) return eSectionTypeDWARFDebugStr; if (section_name == g_sect_name_dwarf_debug_types) Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -1067,9 +1067,9 @@ 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; Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h +++ lldb/trunk/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 @@ 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 Offsets; +}; + #endif // SymbolFileDWARF_DWARFDebugRanges_h_ Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp @@ -123,3 +123,71 @@ } 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; + } +} Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -54,6 +54,7 @@ class DWARFDebugInfoEntry; class DWARFDebugLine; class DWARFDebugRanges; +class DWARFDebugRngLists; class DWARFDeclContext; class DWARFDIECollection; class DWARFFormValue; @@ -244,6 +245,7 @@ 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 @@ 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; Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -410,9 +410,9 @@ 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 @@ 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 @@ static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION, static_cast(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(); } Index: lldb/trunk/source/Symbol/ObjectFile.cpp =================================================================== --- lldb/trunk/source/Symbol/ObjectFile.cpp +++ lldb/trunk/source/Symbol/ObjectFile.cpp @@ -358,6 +358,7 @@ case eSectionTypeDWARFDebugPubNames: case eSectionTypeDWARFDebugPubTypes: case eSectionTypeDWARFDebugRanges: + case eSectionTypeDWARFDebugRngLists: case eSectionTypeDWARFDebugStr: case eSectionTypeDWARFDebugStrOffsets: case eSectionTypeDWARFDebugTypes: