jankratochvil created this revision.
jankratochvil added reviewers: ikudrin, dblaikie, labath, clayborg.
jankratochvil added projects: LLDB, LLVM.
Herald added subscribers: JDevlieghere, hiraditya.
jankratochvil requested review of this revision.
@ikudrin has correctly noticed
<https://reviews.llvm.org/D106466#inline-1021833> modifying a copy of
`DWARFDataExtractor` makes no sense. Removed it as it currently has no effect.
In fact one caller needs it as otherwise it assumes `.debug_rnglists` width
from ELF width which in practice works but it is not correct. All callers of
`DWARFListTableHeader::extract`:
- llvm/unittests/DebugInfo/DWARF/DWARFListTableTest.cpp
<https://github.com/llvm/llvm-project/blob/e4977f9cb58ff7820d0287ba309490af57787749/llvm/unittests/DebugInfo/DWARF/DWARFListTableTest.cpp>
- not using address parsing
- llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
<https://github.com/llvm/llvm-project/blob/e4977f9cb58ff7820d0287ba309490af57787749/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp#L314>
`dumpLoclistsSection` - it uses: `Data.setAddressSize(Header.getAddrSize());`
- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
<https://github.com/llvm/llvm-project/blob/e4977f9cb58ff7820d0287ba309490af57787749/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp#L464>
`SetLoclistsBase` - it sets `m_loclist_table_header` which is never used for
parsing addresses
- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
<https://github.com/llvm/llvm-project/blob/e4977f9cb58ff7820d0287ba309490af57787749/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp#L450>
`ParseListTableHeader` - called only by `GetRnglistTable`
Callers of `GetRnglistTable`:
- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
<https://github.com/llvm/llvm-project/blob/e4977f9cb58ff7820d0287ba309490af57787749/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp#L530>
`GetRnglistOffset` - not used for parsing addresses
- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
<https://github.com/llvm/llvm-project/blob/e4977f9cb58ff7820d0287ba309490af57787749/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp#L985>
`FindRnglistFromOffset` - calling findList
<https://github.com/llvm/llvm-project/blob/e4977f9cb58ff7820d0287ba309490af57787749/llvm/include/llvm/DebugInfo/DWARF/DWARFListTable.h#L278>
which does not set the address size. So this part needed a fix in this patch.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D107470
Files:
lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
lldb/unittests/SymbolFile/DWARF/DWARFUnitTest.cpp
llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
llvm/unittests/DebugInfo/DWARF/DWARFListTableTest.cpp
Index: llvm/unittests/DebugInfo/DWARF/DWARFListTableTest.cpp
===================================================================
--- llvm/unittests/DebugInfo/DWARF/DWARFListTableTest.cpp
+++ llvm/unittests/DebugInfo/DWARF/DWARFListTableTest.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFListTable.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
@@ -99,4 +100,76 @@
EXPECT_EQ(Header.length(), sizeof(SecData) - 1);
}
+TEST(DWARFListTableHeader, AddressSize64) {
+ static const char SecData[] = "\x1a\x00\x00\x00" // Length
+ "\x05\x00" // Version
+ "\x08" // Address size
+ "\x00" // Segment selector size
+ "\x00\x00\x00\x00" // Offset entry count
+ "\x06" // DW_RLE_start_end
+ "\x07\x06\x05\x04" // 64-bit starting address
+ "\x03\x02\x01\x00" // 64-bit starting address
+ "\x87\x86\x85\x84" // 64-bit ending address
+ "\x83\x82\x81\x80" // 64-bit ending address
+ "\x00"; // DW_RLE_end_of_list
+ DWARFDataExtractor Extractor(StringRef(SecData, sizeof(SecData) - 1),
+ /*isLittleEndian=*/true,
+ /*AddrSize=*/4);
+ DWARFListTableHeader Header(/*SectionName=*/".debug_rnglists",
+ /*ListTypeString=*/"range");
+ uint64_t Offset = 0;
+ llvm::DWARFDebugRnglistTable Table;
+ llvm::Error E = Table.extractHeaderAndOffsets(Extractor, &Offset);
+ EXPECT_FALSE(!!E);
+ EXPECT_EQ(Offset, 12U);
+ EXPECT_EQ(Table.length(), sizeof(SecData) - 1);
+ EXPECT_EQ(Extractor.getAddressSize(), 4U);
+ EXPECT_EQ(Table.getAddrSize(), 8U);
+ Extractor.setAddressSize(Table.getAddrSize());
+ Expected<DWARFDebugRnglist> List = Table.findList(Extractor, Offset);
+ EXPECT_TRUE(!!List);
+ EXPECT_EQ(List->getEntries().size(), 2U);
+ EXPECT_EQ(List->getEntries()[0].Offset, 12 + 0U);
+ EXPECT_EQ(List->getEntries()[0].EntryKind, dwarf::DW_RLE_start_end);
+ EXPECT_EQ(List->getEntries()[0].Value0, 0x0001020304050607U);
+ EXPECT_EQ(List->getEntries()[0].Value1, 0x8081828384858687U);
+ EXPECT_EQ(List->getEntries()[1].Offset, 12 + 17U);
+ EXPECT_EQ(List->getEntries()[1].EntryKind, dwarf::DW_RLE_end_of_list);
+}
+
+TEST(DWARFListTableHeader, AddressSize32) {
+ static const char SecData[] = "\x12\x00\x00\x00" // Length
+ "\x05\x00" // Version
+ "\x04" // Address size
+ "\x00" // Segment selector size
+ "\x00\x00\x00\x00" // Offset entry count
+ "\x06" // DW_RLE_start_end
+ "\x03\x02\x01\x00" // 32-bit starting address
+ "\x83\x82\x81\x80" // 32-bit ending address
+ "\x00"; // DW_RLE_end_of_list
+ DWARFDataExtractor Extractor(StringRef(SecData, sizeof(SecData) - 1),
+ /*isLittleEndian=*/true,
+ /*AddrSize=*/8);
+ DWARFListTableHeader Header(/*SectionName=*/".debug_rnglists",
+ /*ListTypeString=*/"range");
+ uint64_t Offset = 0;
+ llvm::DWARFDebugRnglistTable Table;
+ llvm::Error E = Table.extractHeaderAndOffsets(Extractor, &Offset);
+ EXPECT_FALSE(!!E);
+ EXPECT_EQ(Offset, 12U);
+ EXPECT_EQ(Table.length(), sizeof(SecData) - 1);
+ EXPECT_EQ(Extractor.getAddressSize(), 8U);
+ EXPECT_EQ(Table.getAddrSize(), 4U);
+ Extractor.setAddressSize(Table.getAddrSize());
+ Expected<DWARFDebugRnglist> List = Table.findList(Extractor, Offset);
+ EXPECT_TRUE(!!List);
+ EXPECT_EQ(List->getEntries().size(), 2U);
+ EXPECT_EQ(List->getEntries()[0].Offset, 12 + 0U);
+ EXPECT_EQ(List->getEntries()[0].EntryKind, dwarf::DW_RLE_start_end);
+ EXPECT_EQ(List->getEntries()[0].Value0, 0x00010203U);
+ EXPECT_EQ(List->getEntries()[0].Value1, 0x80818283U);
+ EXPECT_EQ(List->getEntries()[1].Offset, 12 + 9U);
+ EXPECT_EQ(List->getEntries()[1].EntryKind, dwarf::DW_RLE_end_of_list);
+}
+
} // end anonymous namespace
Index: llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
===================================================================
--- llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
+++ llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
@@ -3152,4 +3152,74 @@
});
}
+TEST(DWARFDebugInfo, TestRnglistsAddressSize) {
+ static const char DebugInfoSecRaw[] =
+ "\x09\x00\x00\x00" // Length
+ "\x05\x00" // Version
+ "\x01" // DW_UT_compile
+ "\x08" // Address size
+ "\x00\x00\x00\x00" // Offset Into Abbrev. Sec.
+ "\x01"; // Abbreviation 1
+ static const char DebugAbbrevSecRaw[] = "\x01" // Abbreviation Code
+ "\x11" // DW_TAG_compile_unit
+ "\x00" // DW_CHILDREN_no
+ "\x00\x00" // End of Abbreviation 1
+ "\x00"; // End of Abbreviations
+ static const char DebugRnglistsSecRaw[] =
+ "\x1A\x00\x00\x00" // Length
+ "\x05\x00" // Version
+ "\x08" // Address Size
+ "\x00" // Segment Selector Size
+ "\x00\x00\x00\x00" // Offset Entry Count
+ "\x06" // DW_RLE_start_end
+ "\x07\x06\x05\x04\x03\x02\x01\x00" // Start Address
+ "\x87\x86\x85\x84\x83\x82\x81\x80" // End Address
+ "\x00"; // DW_RLE_end_of_list
+
+ StringMap<std::unique_ptr<MemoryBuffer>> Sections;
+ Sections.insert(std::make_pair(
+ "debug_info", MemoryBuffer::getMemBuffer(StringRef(
+ DebugInfoSecRaw, sizeof(DebugInfoSecRaw) - 1))));
+ Sections.insert(std::make_pair(
+ "debug_abbrev", MemoryBuffer::getMemBuffer(StringRef(
+ DebugAbbrevSecRaw, sizeof(DebugAbbrevSecRaw) - 1))));
+ Sections.insert(std::make_pair(
+ "debug_rnglists",
+ MemoryBuffer::getMemBuffer(
+ StringRef(DebugRnglistsSecRaw, sizeof(DebugRnglistsSecRaw) - 1))));
+ auto Context = DWARFContext::create(Sections, /* AddrSize = */ 8,
+ /* isLittleEndian = */ true);
+ const auto &Obj = Context->getDWARFObj();
+ Obj.forEachInfoSections([&](const DWARFSection &Sec) {
+ DWARFUnitHeader Header;
+ DWARFDataExtractor Data(Obj, Sec, /* IsLittleEndian = */ true,
+ /* AddressSize = */ 4);
+ uint64_t Offset = 0;
+ EXPECT_TRUE(Header.extract(*Context, Data, &Offset, DW_SECT_INFO));
+ ASSERT_EQ(8, Header.getAddressByteSize());
+
+ // Check that the length can be correctly read in the unit class.
+ DWARFUnitVector DummyUnitVector;
+ DWARFSection DummySec;
+ DWARFDataExtractor AbbrevData(Obj.getAbbrevSection(),
+ /* IsLittleEndian = */ true,
+ /* AddressSize = */ 4);
+ DWARFDebugAbbrev Abbrev;
+ Abbrev.extract(AbbrevData);
+ Abbrev.parse();
+ DWARFCompileUnit CU(*Context, Sec, Header, /* DA = */ &Abbrev,
+ /* RS = */ &Obj.getRnglistsSection(),
+ /* LocSection = */ 0, /* SS = */ StringRef(),
+ /* SOS = */ DummySec, /* AOS = */ 0,
+ /* LS = */ DummySec, /* LE = */ true,
+ /* isDWO= */ false, DummyUnitVector);
+ llvm::Expected<DWARFAddressRangesVector> rnglist =
+ CU.findRnglistFromOffset(12);
+ ASSERT_TRUE(!!rnglist);
+ ASSERT_EQ(rnglist->size(), 1U);
+ ASSERT_EQ(rnglist->at(0).LowPC, 0x0001020304050607U);
+ ASSERT_EQ(rnglist->at(0).HighPC, 0x8081828384858687U);
+ });
+}
+
} // end anonymous namespace
Index: llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
===================================================================
--- llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
+++ llvm/lib/DebugInfo/DWARF/DWARFListTable.cpp
@@ -74,7 +74,6 @@
"%s table at offset 0x%" PRIx64 " has more offset entries (%" PRIu32
") than there is space for",
SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount);
- Data.setAddressSize(HeaderData.AddrSize);
*OffsetPtr += HeaderData.OffsetEntryCount * OffsetByteSize;
return Error::success();
}
Index: lldb/unittests/SymbolFile/DWARF/DWARFUnitTest.cpp
===================================================================
--- lldb/unittests/SymbolFile/DWARF/DWARFUnitTest.cpp
+++ lldb/unittests/SymbolFile/DWARF/DWARFUnitTest.cpp
@@ -84,3 +84,75 @@
EXPECT_EQ(die_first->GetFirstChild(), nullptr);
EXPECT_EQ(die_first->GetSibling(), nullptr);
}
+
+TEST(DWARFUnitTest, Elf64RnglistsAddressSize64) {
+ // Test parsing .debug_rnglists with address size matching its ELF size.
+ const char *yamldata = R"(
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+ Entry: 0x401020
+Sections:
+ - Name: .debug_info
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ Content: '09000000050001080000000001'
+ - Name: .debug_abbrev
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ Content: '011100000000'
+ - Name: .debug_rnglists
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ Content: 1A0000000500080000000000060706050403020100878685848382818000
+)";
+
+ YAMLModuleTester t(yamldata);
+ ASSERT_TRUE((bool)t.GetDwarfUnit());
+
+ DWARFUnit *unit = t.GetDwarfUnit();
+ llvm::Expected<DWARFRangeList> rnglist = unit->FindRnglistFromOffset(12);
+ ASSERT_TRUE(!!rnglist);
+ ASSERT_EQ(rnglist->GetSize(), 1U);
+ ASSERT_EQ(rnglist->GetEntryRef(0).base, 0x0001020304050607U);
+ ASSERT_EQ(rnglist->GetEntryRef(0).size, 0x8080808080808080U);
+}
+
+TEST(DWARFUnitTest, Elf64RnglistsAddressSize32) {
+ // Test parsing .debug_rnglists with address size different than its ELF size.
+ const char *yamldata = R"(
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+ Entry: 0x401020
+Sections:
+ - Name: .debug_info
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ Content: '09000000050001040000000001'
+ - Name: .debug_abbrev
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ Content: '011100000000'
+ - Name: .debug_rnglists
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ Content: 12000000050004000000000006030201008382818000
+)";
+
+ YAMLModuleTester t(yamldata);
+ ASSERT_TRUE((bool)t.GetDwarfUnit());
+
+ DWARFUnit *unit = t.GetDwarfUnit();
+ llvm::Expected<DWARFRangeList> rnglist = unit->FindRnglistFromOffset(12);
+ ASSERT_TRUE(!!rnglist);
+ ASSERT_EQ(rnglist->GetSize(), 1U);
+ ASSERT_EQ(rnglist->GetEntryRef(0).base, 0x00010203U);
+ ASSERT_EQ(rnglist->GetEntryRef(0).size, 0x80808080U);
+}
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -982,8 +982,11 @@
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();
+ 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();
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits