diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -214,11 +214,12 @@ if (expected_ranges) return std::move(*expected_ranges); unit.GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( - "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 ") attribute, but " + "{0x%8.8x}: DIE has DW_AT_ranges(%s 0x%" PRIx64 ") attribute, but " "range extraction failed (%s), please file a bug " "and attach the file at the start of this error message", - die.GetOffset(), value.Unsigned(), - toString(expected_ranges.takeError()).c_str()); + die.GetOffset(), + llvm::dwarf::FormEncodingString(value.Form()).str().c_str(), + value.Unsigned(), toString(expected_ranges.takeError()).c_str()); return DWARFRangeList(); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -235,7 +235,7 @@ /// Return a rangelist's offset based on an index. The index designates /// an entry in the rangelist table's offset array and is supplied by /// DW_FORM_rnglistx. - llvm::Optional GetRnglistOffset(uint32_t Index); + llvm::Expected GetRnglistOffset(uint32_t Index); llvm::Optional GetLoclistOffset(uint32_t Index) { if (!m_loclist_table_header) 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 @@ -507,19 +507,23 @@ } // This function is called only for DW_FORM_rnglistx. -llvm::Optional DWARFUnit::GetRnglistOffset(uint32_t Index) { +llvm::Expected DWARFUnit::GetRnglistOffset(uint32_t Index) { if (!GetRnglist()) - return llvm::None; - if (!m_ranges_base) { - GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( - "%8.8x: DW_FORM_rnglistx cannot be used without DW_AT_rnglists_base", - GetOffset()); - return llvm::None; - } + return llvm::createStringError(errc::invalid_argument, + "missing or invalid range list table"); + if (!m_ranges_base) + return llvm::createStringError(errc::invalid_argument, + "DW_FORM_rnglistx cannot be used without " + "DW_AT_rnglists_base for CU at 0x%8.8x", + GetOffset()); if (llvm::Optional off = GetRnglist()->getOffsetEntry( m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), Index)) return *off + m_ranges_base; - return llvm::None; + return llvm::createStringError( + errc::invalid_argument, + "invalid range list table index %u; OffsetEntryCount is %u, " + "DW_AT_rnglists_base is %" PRIu64, + Index, GetRnglist()->getOffsetEntryCount(), m_ranges_base); } void DWARFUnit::SetStrOffsetsBase(dw_offset_t str_offsets_base) { @@ -996,12 +1000,8 @@ llvm::Expected DWARFUnit::FindRnglistFromIndex(uint32_t index) { - if (llvm::Optional offset = GetRnglistOffset(index)) - return FindRnglistFromOffset(*offset); - if (GetRnglist()) - return llvm::createStringError(errc::invalid_argument, - "invalid range list table index %d", index); - - return llvm::createStringError(errc::invalid_argument, - "missing or invalid range list table"); + llvm::Expected maybe_offset = GetRnglistOffset(index); + if (!maybe_offset) + return maybe_offset.takeError(); + return FindRnglistFromOffset(*maybe_offset); } 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 @@ -21,7 +21,7 @@ # RUN: -o exit 2>&1 | FileCheck --check-prefix=RNGLISTX %s # RNGLISTX-LABEL: image lookup -v -s lookup_rnglists -# RNGLISTX: error: {{.*}} 00000000: DW_FORM_rnglistx cannot be used without DW_AT_rnglists_base +# RNGLISTX: error: {{.*}} {0x0000003f}: DIE has DW_AT_ranges(DW_FORM_rnglistx 0x0) attribute, but range extraction failed (DW_FORM_rnglistx cannot be used without DW_AT_rnglists_base for CU at 0x00000000), please file a bug and attach the file at the start of this error message # RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj \ # RUN: --defsym RNGLISTX=0 --defsym RNGLISTBASE=0 %s > %t-rnglistbase @@ -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(0x0) attribute, but range extraction failed (invalid range list table index 0), 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 12), please file a bug and attach the file at the start of this error message .text rnglists: diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_ranges-missing-section.s b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_ranges-missing-section.s --- a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_ranges-missing-section.s +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_ranges-missing-section.s @@ -1,7 +1,7 @@ # RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s > %t # RUN: %lldb %t -o "image lookup -v -s lookup_ranges" -o exit 2>&1 | FileCheck %s -# CHECK: DIE has DW_AT_ranges(0x47) attribute, but range extraction failed (No debug_ranges section), +# CHECK: DIE has DW_AT_ranges(DW_FORM_sec_offset 0x47) attribute, but range extraction failed (No debug_ranges section), # CHECK: Function: id = {0x0000001c}, name = "ranges", range = [0x0000000000000000-0x0000000000000004) # CHECK: Blocks: id = {0x0000001c}, range = [0x00000000-0x00000004) diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h @@ -94,6 +94,7 @@ uint8_t getAddrSize() const { return HeaderData.AddrSize; } uint64_t getLength() const { return HeaderData.Length; } uint16_t getVersion() const { return HeaderData.Version; } + uint32_t getOffsetEntryCount() const { return HeaderData.OffsetEntryCount; } StringRef getSectionName() const { return SectionName; } StringRef getListTypeString() const { return ListTypeString; } dwarf::DwarfFormat getFormat() const { return Format; } @@ -175,6 +176,7 @@ uint64_t getHeaderOffset() const { return Header.getHeaderOffset(); } uint8_t getAddrSize() const { return Header.getAddrSize(); } + uint32_t getOffsetEntryCount() const { return Header.getOffsetEntryCount(); } dwarf::DwarfFormat getFormat() const { return Header.getFormat(); } void dump(DWARFDataExtractor Data, raw_ostream &OS,