diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -437,15 +437,20 @@ // We are expected to be called with Offset 0 or pointing just past the table // header. Correct Offset in the latter case so that it points to the start // of the header. - if (offset > 0) { - uint64_t HeaderSize = llvm::DWARFListTableHeader::getHeaderSize(format); - if (offset < HeaderSize) - return llvm::createStringError(errc::invalid_argument, - "did not detect a valid" - " list table with base = 0x%" PRIx64 "\n", - offset); - offset -= HeaderSize; + if (offset == 0) { + // This means DW_AT_rnglists_base is missing and therefore DW_FORM_rnglistx + // cannot be handled. Returning a default-constructed ListTableType allows + // DW_FORM_sec_offset to be supported. + return ListTableType(); } + + uint64_t HeaderSize = llvm::DWARFListTableHeader::getHeaderSize(format); + if (offset < HeaderSize) + return llvm::createStringError(errc::invalid_argument, + "did not detect a valid" + " list table with base = 0x%" PRIx64 "\n", + offset); + offset -= HeaderSize; ListTableType Table; if (llvm::Error E = Table.extractHeaderAndOffsets(data, &offset)) return std::move(E); @@ -996,8 +1001,12 @@ return llvm::createStringError(errc::invalid_argument, "missing or invalid range list table"); - auto range_list_or_error = GetRnglistTable()->findList( - m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), offset); + llvm::DWARFDataExtractor data = + m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(); + + // As DW_AT_rnglists_base may be missing we need to call setAddressSize. + data.setAddressSize(m_header.GetAddressByteSize()); + auto range_list_or_error = GetRnglistTable()->findList(data, offset); if (!range_list_or_error) return range_list_or_error.takeError(); diff --git a/lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s b/lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s --- a/lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s +++ b/lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s @@ -29,7 +29,7 @@ # RUN: -o exit 2>&1 | FileCheck --check-prefix=RNGLISTBASE %s # RNGLISTBASE-LABEL: image lookup -v -s lookup_rnglists -# RNGLISTBASE: error: {{.*}}-rnglistbase {0x00000043}: DIE has DW_AT_ranges(DW_FORM_rnglistx 0x0) attribute, but range extraction failed (invalid range list table index 0; OffsetEntryCount is 0, DW_AT_rnglists_base is 12), please file a bug and attach the file at the start of this error message +# RNGLISTBASE: error: {{.*}}-rnglistbase {0x00000043}: DIE has DW_AT_ranges(DW_FORM_rnglistx 0x0) attribute, but range extraction failed (invalid range list table index 0; OffsetEntryCount is 0, DW_AT_rnglists_base is 24), please file a bug and attach the file at the start of this error message .text rnglists: @@ -97,7 +97,7 @@ .long .Lrnglists_end-rnglists # DW_AT_high_pc .long .Laddr_table_base0 # DW_AT_addr_base .ifdef RNGLISTBASE - .long .Ldebug_ranges0 # DW_AT_rnglists_base + .long .Ldebug_ranges1 # DW_AT_rnglists_base .endif .byte 2 # Abbrev [2] 0x2b:0x37 DW_TAG_subprogram .quad rnglists # DW_AT_low_pc @@ -105,7 +105,7 @@ .asciz "rnglists" # DW_AT_name .byte 5 # Abbrev [5] 0x52:0xf DW_TAG_lexical_block .ifndef RNGLISTX - .long .Ldebug_ranges0 # DW_AT_ranges DW_FORM_sec_offset + .long .Ldebug_ranges1 # DW_AT_ranges DW_FORM_sec_offset .else .uleb128 0 # DW_AT_ranges DW_FORM_rnglistx .endif @@ -130,9 +130,17 @@ .byte 8 # Address size .byte 0 # Segment selector size .long 0 # Offset entry count -.Ldebug_ranges0: +.Ldebug_rnglist_table_end0: + + .long .Ldebug_rnglist_table_end1-.Ldebug_rnglist_table_start1 # Length +.Ldebug_rnglist_table_start1: + .short 5 # Version + .byte 8 # Address size + .byte 0 # Segment selector size + .long 0 # Offset entry count +.Ldebug_ranges1: .byte 4 # DW_RLE_offset_pair .uleb128 .Lblock1_begin-rnglists # starting offset .uleb128 .Lblock1_end-rnglists # ending offset .byte 0 # DW_RLE_end_of_list -.Ldebug_rnglist_table_end0: +.Ldebug_rnglist_table_end1: