[llvm] r371014 - [DWARF] Support DWARF64 in DWARFListTableHeader.
Igor Kudrin via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 4 23:49:05 PDT 2019
Author: ikudrin
Date: Wed Sep 4 23:49:05 2019
New Revision: 371014
URL: http://llvm.org/viewvc/llvm-project?rev=371014&view=rev
Log:
[DWARF] Support DWARF64 in DWARFListTableHeader.
This enables 64-bit DWARF support for parsing range and location list tables.
Differential Revision: https://reviews.llvm.org/D66643
Added:
llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_dwarf64.s
llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_reserved_length.s
Removed:
llvm/trunk/test/tools/llvm-dwarfdump/X86/Inputs/debug_rnglists_DWARF64.s
Modified:
llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFListTable.h
llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp
llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFListTable.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFListTable.h?rev=371014&r1=371013&r2=371014&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFListTable.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFListTable.h Wed Sep 4 23:49:05 2019
@@ -57,7 +57,7 @@ class DWARFListTableHeader {
struct Header {
/// The total length of the entries for this table, not including the length
/// field itself.
- uint32_t Length = 0;
+ uint64_t Length = 0;
/// The DWARF version number.
uint16_t Version;
/// The size in bytes of an address on the target architecture. For
@@ -75,7 +75,7 @@ class DWARFListTableHeader {
/// The offset table, which contains offsets to the individual list entries.
/// It is used by forms such as DW_FORM_rnglistx.
/// FIXME: Generate the table and use the appropriate forms.
- std::vector<uint32_t> Offsets;
+ std::vector<uint64_t> Offsets;
/// The table's format, either DWARF32 or DWARF64.
dwarf::DwarfFormat Format;
/// The offset at which the header (and hence the table) is located within
@@ -97,14 +97,26 @@ public:
}
uint64_t getHeaderOffset() const { return HeaderOffset; }
uint8_t getAddrSize() const { return HeaderData.AddrSize; }
- uint32_t getLength() const { return HeaderData.Length; }
+ uint64_t getLength() const { return HeaderData.Length; }
uint16_t getVersion() const { return HeaderData.Version; }
StringRef getSectionName() const { return SectionName; }
StringRef getListTypeString() const { return ListTypeString; }
dwarf::DwarfFormat getFormat() const { return Format; }
+ /// Return the size of the table header including the length but not including
+ /// the offsets.
+ static uint8_t getHeaderSize(dwarf::DwarfFormat Format) {
+ switch (Format) {
+ case dwarf::DwarfFormat::DWARF32:
+ return 12;
+ case dwarf::DwarfFormat::DWARF64:
+ return 20;
+ }
+ llvm_unreachable("Invalid DWARF format (expected DWARF32 or DWARF64");
+ }
+
void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) const;
- Optional<uint32_t> getOffsetEntry(uint32_t Index) const {
+ Optional<uint64_t> getOffsetEntry(uint32_t Index) const {
if (Index < Offsets.size())
return Offsets[Index];
return None;
@@ -116,7 +128,7 @@ public:
/// 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).
- uint32_t length() const;
+ uint64_t length() const;
};
/// A class representing a table of lists as specified in the DWARF v5
@@ -155,6 +167,7 @@ public:
uint64_t getHeaderOffset() const { return Header.getHeaderOffset(); }
uint8_t getAddrSize() const { return Header.getAddrSize(); }
+ dwarf::DwarfFormat getFormat() const { return Header.getFormat(); }
void dump(raw_ostream &OS,
llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
@@ -162,23 +175,17 @@ public:
DIDumpOptions DumpOpts = {}) const;
/// Return the contents of the offset entry designated by a given index.
- Optional<uint32_t> getOffsetEntry(uint32_t Index) const {
+ Optional<uint64_t> getOffsetEntry(uint32_t Index) const {
return Header.getOffsetEntry(Index);
}
/// Return the size of the table header including the length but not including
/// the offsets. This is dependent on the table format, which is unambiguously
/// derived from parsing the table.
uint8_t getHeaderSize() const {
- switch (Header.getFormat()) {
- case dwarf::DwarfFormat::DWARF32:
- return 12;
- case dwarf::DwarfFormat::DWARF64:
- return 20;
- }
- llvm_unreachable("Invalid DWARF format (expected DWARF32 or DWARF64");
+ return DWARFListTableHeader::getHeaderSize(getFormat());
}
- uint32_t length() { return Header.length(); }
+ uint64_t length() { return Header.length(); }
};
template <typename DWARFListType>
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h?rev=371014&r1=371013&r2=371014&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h Wed Sep 4 23:49:05 2019
@@ -416,7 +416,7 @@ public:
/// 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.
- Optional<uint32_t> getRnglistOffset(uint32_t Index) {
+ Optional<uint64_t> getRnglistOffset(uint32_t Index) {
if (RngListTable)
return RngListTable->getOffsetEntry(Index);
return None;
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp?rev=371014&r1=371013&r2=371014&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp Wed Sep 4 23:49:05 2019
@@ -24,25 +24,34 @@ Error DWARFListTableHeader::extract(DWAR
"section is not large enough to contain a "
"%s table length at offset 0x%" PRIx64,
SectionName.data(), *OffsetPtr);
- // TODO: Add support for DWARF64.
- HeaderData.Length = Data.getRelocatedValue(4, OffsetPtr);
- if (HeaderData.Length == dwarf::DW_LENGTH_DWARF64)
- return createStringError(errc::not_supported,
- "DWARF64 is not supported in %s at offset 0x%" PRIx64,
- SectionName.data(), HeaderOffset);
Format = dwarf::DwarfFormat::DWARF32;
- if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header))
+ uint8_t OffsetByteSize = 4;
+ HeaderData.Length = Data.getRelocatedValue(4, OffsetPtr);
+ if (HeaderData.Length == dwarf::DW_LENGTH_DWARF64) {
+ Format = dwarf::DwarfFormat::DWARF64;
+ OffsetByteSize = 8;
+ HeaderData.Length = Data.getU64(OffsetPtr);
+ } else if (HeaderData.Length >= dwarf::DW_LENGTH_lo_reserved) {
+ return createStringError(errc::invalid_argument,
+ "%s table at offset 0x%" PRIx64
+ " has unsupported reserved unit length of value 0x%8.8" PRIx64,
+ SectionName.data(), HeaderOffset, HeaderData.Length);
+ }
+ uint64_t FullLength =
+ HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format);
+ assert(FullLength == length());
+ if (FullLength < getHeaderSize(Format))
return createStringError(errc::invalid_argument,
"%s table at offset 0x%" PRIx64
- " has too small length (0x%" PRIx32
+ " has too small length (0x%" PRIx64
") to contain a complete header",
- SectionName.data(), HeaderOffset, length());
- uint64_t End = HeaderOffset + length();
- if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset))
+ SectionName.data(), HeaderOffset, FullLength);
+ uint64_t End = HeaderOffset + FullLength;
+ if (!Data.isValidOffsetForDataOfSize(HeaderOffset, FullLength))
return createStringError(errc::invalid_argument,
"section is not large enough to contain a %s table "
- "of length 0x%" PRIx32 " at offset 0x%" PRIx64,
- SectionName.data(), length(), HeaderOffset);
+ "of length 0x%" PRIx64 " at offset 0x%" PRIx64,
+ SectionName.data(), FullLength, HeaderOffset);
HeaderData.Version = Data.getU16(OffsetPtr);
HeaderData.AddrSize = Data.getU8(OffsetPtr);
@@ -65,15 +74,15 @@ Error DWARFListTableHeader::extract(DWAR
"%s table at offset 0x%" PRIx64
" has unsupported segment selector size %" PRIu8,
SectionName.data(), HeaderOffset, HeaderData.SegSize);
- if (End < HeaderOffset + sizeof(HeaderData) +
- HeaderData.OffsetEntryCount * sizeof(uint32_t))
+ if (End < HeaderOffset + getHeaderSize(Format) +
+ HeaderData.OffsetEntryCount * OffsetByteSize)
return createStringError(errc::invalid_argument,
"%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);
for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I)
- Offsets.push_back(Data.getRelocatedValue(4, OffsetPtr));
+ Offsets.push_back(Data.getRelocatedValue(OffsetByteSize, OffsetPtr));
return Error::success();
}
@@ -81,7 +90,7 @@ void DWARFListTableHeader::dump(raw_ostr
if (DumpOpts.Verbose)
OS << format("0x%8.8" PRIx64 ": ", HeaderOffset);
OS << format(
- "%s list header: length = 0x%8.8" PRIx32 ", version = 0x%4.4" PRIx16 ", "
+ "%s list header: length = 0x%8.8" PRIx64 ", version = 0x%4.4" PRIx16 ", "
"addr_size = 0x%2.2" PRIx8 ", seg_size = 0x%2.2" PRIx8
", offset_entry_count = "
"0x%8.8" PRIx32 "\n",
@@ -91,18 +100,17 @@ void DWARFListTableHeader::dump(raw_ostr
if (HeaderData.OffsetEntryCount > 0) {
OS << "offsets: [";
for (const auto &Off : Offsets) {
- OS << format("\n0x%8.8" PRIx32, Off);
+ OS << format("\n0x%8.8" PRIx64, Off);
if (DumpOpts.Verbose)
OS << format(" => 0x%8.8" PRIx64,
- Off + HeaderOffset + sizeof(HeaderData));
+ Off + HeaderOffset + getHeaderSize(Format));
}
OS << "\n]\n";
}
}
-uint32_t DWARFListTableHeader::length() const {
+uint64_t DWARFListTableHeader::length() const {
if (HeaderData.Length == 0)
return 0;
- // TODO: DWARF64 support.
- return HeaderData.Length + sizeof(uint32_t);
+ return HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format);
}
Removed: llvm/trunk/test/tools/llvm-dwarfdump/X86/Inputs/debug_rnglists_DWARF64.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/Inputs/debug_rnglists_DWARF64.s?rev=371013&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/Inputs/debug_rnglists_DWARF64.s (original)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/Inputs/debug_rnglists_DWARF64.s (removed)
@@ -1,2 +0,0 @@
-.section .debug_rnglists,"", at progbits
-.long 0xffffffff # Unsupported DWARF64 format
Added: llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_dwarf64.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_dwarf64.s?rev=371014&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_dwarf64.s (added)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_dwarf64.s Wed Sep 4 23:49:05 2019
@@ -0,0 +1,39 @@
+# RUN: llvm-mc %s -filetype obj -triple x86_64-pc-linux -o - | \
+# RUN: llvm-dwarfdump -v --debug-rnglists - | \
+# RUN: FileCheck %s
+
+# CHECK: .debug_rnglists contents:
+# CHECK-NEXT: 0x00000000: range list header:
+# CHECK-SAME: length = 0x0000001a,
+# CHECK-SAME: version = 0x0005,
+# CHECK-SAME: addr_size = 0x08,
+# CHECK-SAME: seg_size = 0x00,
+# CHECK-SAME: offset_entry_count = 0x00000002
+# CHECK-NEXT: offsets: [
+# CHECK-NEXT: 0x00000010 => 0x00000024
+# CHECK-NEXT: 0x00000011 => 0x00000025
+# CHECK-NEXT: ]
+# CHECK-NEXT: ranges:
+# CHECK-NEXT: 0x00000024: [DW_RLE_end_of_list]
+# CHECK-NEXT: 0x00000025: [DW_RLE_end_of_list]
+
+ .section .debug_rnglists,"", at progbits
+ .long 0xffffffff # DWARF64 mark
+ .quad .Lend - .Lversion # Table length
+.Lversion:
+ .short 5 # Version
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+ .long 2 # Offset entry count
+
+.Loffsets:
+ .quad .Ltable0 - .Loffsets
+ .quad .Ltable1 - .Loffsets
+
+.Ltable0:
+ .byte 0 # DW_RLE_end_of_list
+
+.Ltable1:
+ .byte 0 # DW_RLE_end_of_list
+
+.Lend:
Modified: llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s?rev=371014&r1=371013&r2=371014&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s (original)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s Wed Sep 4 23:49:05 2019
@@ -37,11 +37,6 @@
# CHECK-NEXT: error: section is not large enough to contain a .debug_rnglists table of length 0x1f at offset 0xe5
# CHECK-NOT: error:
-# RUN: llvm-mc %S/Inputs/debug_rnglists_DWARF64.s -filetype obj -triple x86_64-pc-linux -o - | \
-# RUN: llvm-dwarfdump --debug-rnglists - 2>&1 | FileCheck %s --check-prefix=DWARF64
-
-# DWARF64: DWARF64 is not supported in .debug_rnglists at offset 0x0
-
.section .debug_rnglists,"", at progbits
# Table 1 (good)
Added: llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_reserved_length.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_reserved_length.s?rev=371014&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_reserved_length.s (added)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/debug_rnglists_reserved_length.s Wed Sep 4 23:49:05 2019
@@ -0,0 +1,8 @@
+# RUN: llvm-mc %s -filetype obj -triple x86_64-pc-linux -o - | \
+# RUN: llvm-dwarfdump --debug-rnglists - 2>&1 | \
+# RUN: FileCheck %s --implicit-check-not=error
+
+# CHECK: error: .debug_rnglists table at offset 0x0 has unsupported reserved unit length of value 0xfffffff0
+
+.section .debug_rnglists,"", at progbits
+.long 0xfffffff0
More information about the llvm-commits
mailing list