jankratochvil created this revision.
jankratochvil added reviewers: dblaikie, labath, clayborg.
jankratochvil added projects: LLDB, LLVM.
Herald added subscribers: JDevlieghere, hiraditya.
jankratochvil requested review of this revision.
Fix D98289 <https://reviews.llvm.org/D98289> so that it works even for 2nd..nth
compilation unit (`.debug_rnglists`).
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D106466
Files:
lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s
llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
Index: llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
===================================================================
--- llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
+++ llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
@@ -29,6 +29,32 @@
return Error::success();
}
+Error DWARFListTableHeader::create(DWARFDataExtractor Data, unsigned Version,
+ unsigned AddrSize,
+ dwarf::DwarfFormat FormatParam) {
+ Format = FormatParam;
+ HeaderOffset = 0;
+ if (Data.size() < getHeaderSize(Format))
+ return createStringError(errc::invalid_argument,
+ "%s table at offset 0x%" PRIx64
+ " has too small length (0x%" PRIx64
+ ") to contain a complete header",
+ SectionName.data(), HeaderOffset, Data.size());
+
+ HeaderData.Length = Data.size() - dwarf::getUnitLengthFieldByteSize(Format);
+ HeaderData.Version = Version;
+ HeaderData.AddrSize = AddrSize;
+ HeaderData.SegSize = 0;
+ HeaderData.OffsetEntryCount = 0;
+ if (Error Err = HeaderData.verify())
+ return createStringError(
+ errc::invalid_argument, "parsing %s table at offset 0x%" PRIx64 ": %s",
+ SectionName.data(), HeaderOffset, toString(std::move(Err)).c_str());
+
+ Data.setAddressSize(HeaderData.AddrSize);
+ return Error::success();
+}
+
Error DWARFListTableHeader::extract(DWARFDataExtractor Data,
uint64_t *OffsetPtr) {
HeaderOffset = *OffsetPtr;
Index: llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
===================================================================
--- llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
+++ llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h
@@ -136,6 +136,10 @@
/// Extract the table header and the array of offsets.
Error extract(DWARFDataExtractor Data, uint64_t *OffsetPtr);
+ // Make up a header from DWARFUnit header to cover the whole Data section.
+ Error create(DWARFDataExtractor Data, unsigned Version, unsigned AddrSize,
+ dwarf::DwarfFormat FormatParam);
+
/// Returns the length of the table, including the length field, or 0 if the
/// length has not been determined (e.g. because the table has not yet been
/// parsed, or there was a problem in parsing).
@@ -170,6 +174,11 @@
Error extractHeaderAndOffsets(DWARFDataExtractor Data, uint64_t *OffsetPtr) {
return Header.extract(Data, OffsetPtr);
}
+ // Make up a header from DWARFUnit header to cover the whole Data section.
+ Error createHeaderAndOffsets(DWARFDataExtractor Data, unsigned Version,
+ unsigned AddrSize, dwarf::DwarfFormat Format) {
+ return Header.create(Data, Version, AddrSize, Format);
+ }
/// Extract an entire table, including all list entries.
Error extract(DWARFDataExtractor Data, uint64_t *OffsetPtr);
/// Look up a list based on a given offset. Extract it and enter it into the
Index: lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s
===================================================================
--- lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s
+++ 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:
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -283,6 +283,10 @@
return &m_die_array[0];
}
+ llvm::Expected<llvm::DWARFDebugRnglistTable>
+ CreateListTableHeader(const llvm::DWARFDataExtractor &data, uint64_t offset,
+ DwarfFormat format) const;
+
const llvm::Optional<llvm::DWARFDebugRnglistTable> &GetRnglistTable();
SymbolFileDWARF &m_dwarf;
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -424,24 +424,36 @@
static llvm::Expected<ListTableType>
ParseListTableHeader(const llvm::DWARFDataExtractor &data, uint64_t offset,
DwarfFormat format) {
- // 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;
- }
+ // Correct Offset so that it points to the start of the header.
+ 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);
return Table;
}
+llvm::Expected<llvm::DWARFDebugRnglistTable>
+DWARFUnit::CreateListTableHeader(const llvm::DWARFDataExtractor &data,
+ uint64_t offset, DwarfFormat format) const {
+ if (offset > 0)
+ return ParseListTableHeader<llvm::DWARFDebugRnglistTable>(data, offset,
+ format);
+
+ // Unspecified Offset means only DW_FORM_sec_offset (and not DW_FORM_rnglistx)
+ // will be used. Make up a header covering the whole .debug_rnglists section.
+ llvm::DWARFDebugRnglistTable Table;
+ if (llvm::Error E = Table.createHeaderAndOffsets(
+ data, m_header.GetVersion(), m_header.GetAddressByteSize(), DWARF32))
+ return std::move(E);
+ return Table;
+}
+
void DWARFUnit::SetLoclistsBase(dw_addr_t loclists_base) {
m_loclists_base = loclists_base;
@@ -494,10 +506,9 @@
DWARFUnit::GetRnglistTable() {
if (GetVersion() >= 5 && !m_rnglist_table_done) {
m_rnglist_table_done = true;
- if (auto table_or_error =
- ParseListTableHeader<llvm::DWARFDebugRnglistTable>(
- m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(),
- m_ranges_base, DWARF32))
+ if (auto table_or_error = CreateListTableHeader(
+ m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(),
+ m_ranges_base, DWARF32))
m_rnglist_table = std::move(table_or_error.get());
else
GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits