[llvm] 07e50c7 - [DebugInfo] Add support for DWARF64 into DWARFDebugAddr.
Igor Kudrin via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 11 22:36:26 PST 2020
Author: Igor Kudrin
Date: 2020-02-12T13:33:01+07:00
New Revision: 07e50c7b9161e32c43e095aed586614bf8b02c71
URL: https://github.com/llvm/llvm-project/commit/07e50c7b9161e32c43e095aed586614bf8b02c71
DIFF: https://github.com/llvm/llvm-project/commit/07e50c7b9161e32c43e095aed586614bf8b02c71.diff
LOG: [DebugInfo] Add support for DWARF64 into DWARFDebugAddr.
Differential Revision: https://reviews.llvm.org/D74198
Added:
llvm/test/tools/llvm-dwarfdump/X86/debug_addr_reserved_length.s
llvm/test/tools/llvm-dwarfdump/X86/debug_addr_too_small_for_extended_length_field.s
Modified:
llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h
llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
llvm/test/tools/llvm-dwarfdump/X86/debug_addr_dwarf64.s
Removed:
################################################################################
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h
index fd9c5dc55c02..32844ffd570f 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h
@@ -31,7 +31,7 @@ class DWARFDebugAddrTable {
uint64_t Offset;
/// 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
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
index d2344e7e4f5d..273d316e0912 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
@@ -50,34 +50,48 @@ Error DWARFDebugAddrTable::extractV5(const DWARFDataExtractor &Data,
"section is not large enough to contain an "
"address table length at offset 0x%" PRIx64,
Offset);
- // TODO: Add support for DWARF64.
Format = dwarf::DwarfFormat::DWARF32;
Length = Data.getU32(OffsetPtr);
if (Length == dwarf::DW_LENGTH_DWARF64) {
+ // Check that we can read the extended unit length field.
+ if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, 8)) {
+ invalidateLength();
+ return createStringError(
+ errc::invalid_argument,
+ "section is not large enough to contain an extended length field "
+ "of the address table at offset 0x%" PRIx64,
+ Offset);
+ }
+ Format = dwarf::DwarfFormat::DWARF64;
+ Length = Data.getU64(OffsetPtr);
+ } else if (Length >= dwarf::DW_LENGTH_lo_reserved) {
+ uint64_t DiagnosticLength = Length;
invalidateLength();
return createStringError(
errc::not_supported,
- "DWARF64 is not supported in .debug_addr at offset 0x%" PRIx64, Offset);
+ "address table at offset 0x%" PRIx64
+ " has unsupported reserved unit length of value 0x%" PRIx64,
+ Offset, DiagnosticLength);
}
if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, Length)) {
- uint32_t DiagnosticLength = Length;
+ uint64_t DiagnosticLength = Length;
invalidateLength();
return createStringError(
errc::invalid_argument,
"section is not large enough to contain an address table "
- "at offset 0x%" PRIx64 " with a unit_length value of 0x%" PRIx32,
+ "at offset 0x%" PRIx64 " with a unit_length value of 0x%" PRIx64,
Offset, DiagnosticLength);
}
uint64_t EndOffset = *OffsetPtr + Length;
// Ensure that we can read the remaining header fields.
if (Length < 4) {
- uint32_t DiagnosticLength = Length;
+ uint64_t DiagnosticLength = Length;
invalidateLength();
return createStringError(
errc::invalid_argument,
"address table at offset 0x%" PRIx64
- " has a unit_length value of 0x%" PRIx32
+ " has a unit_length value of 0x%" PRIx64
", which is too small to contain a complete header",
Offset, DiagnosticLength);
}
@@ -142,12 +156,14 @@ Error DWARFDebugAddrTable::extract(const DWARFDataExtractor &Data,
void DWARFDebugAddrTable::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
if (DumpOpts.Verbose)
- OS << format("0x%8.8" PRIx32 ": ", Offset);
- if (Length)
- OS << format("Address table header: length = 0x%8.8" PRIx32
+ OS << format("0x%8.8" PRIx64 ": ", Offset);
+ if (Length) {
+ int LengthFieldWidth = (Format == dwarf::DwarfFormat::DWARF64) ? 16 : 8;
+ OS << format("Address table header: length = 0x%0*" PRIx64
", version = 0x%4.4" PRIx16 ", addr_size = 0x%2.2" PRIx8
", seg_size = 0x%2.2" PRIx8 "\n",
- Length, Version, AddrSize, SegSize);
+ LengthFieldWidth, Length, Version, AddrSize, SegSize);
+ }
if (Addrs.size() > 0) {
const char *AddrFmt =
@@ -171,7 +187,6 @@ Expected<uint64_t> DWARFDebugAddrTable::getAddrEntry(uint32_t Index) const {
Optional<uint64_t> DWARFDebugAddrTable::getFullLength() const {
if (Length == 0)
return None;
- // TODO: DWARF64 support.
- return Length + sizeof(uint32_t);
+ return Length + dwarf::getUnitLengthFieldByteSize(Format);
}
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_addr_dwarf64.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_addr_dwarf64.s
index bed41952df05..6c97ae81909d 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/debug_addr_dwarf64.s
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_addr_dwarf64.s
@@ -1,19 +1,25 @@
-# RUN: llvm-mc %s -filetype obj -triple i386-pc-linux -o - | \
-# RUN: llvm-dwarfdump -debug-addr - 2> %t.err | FileCheck %s
-# RUN: FileCheck %s -input-file %t.err -check-prefix=ERR
+# RUN: llvm-mc %s -filetype obj -triple x86_64-pc-linux -o - | \
+# RUN: llvm-dwarfdump -debug-addr - | \
+# RUN: FileCheck %s
-# CHECK: .debug_addr contents:
-# CHECK-NOT: {{.}}
-# ERR: DWARF64 is not supported in .debug_addr at offset 0x0
-# ERR-NOT: {{.}}
+# CHECK: .debug_addr contents:
+# CHECK-NEXT: Address table header:
+# CHECK-SAME: length = 0x000000000000000c,
+# CHECK-SAME: version = 0x0005,
+# CHECK-SAME: addr_size = 0x04,
+# CHECK-SAME: seg_size = 0x00
+# CHECK-NEXT: Addrs: [
+# CHECK-NEXT: 0x00000000
+# CHECK-NEXT: 0x00001000
+# CHECK-NEXT: ]
-# DWARF64 table
- .section .debug_addr,"", at progbits
-.Ldebug_addr0:
- .long 0xffffffff # unit_length DWARF64 mark
- .quad 12 # unit_length
- .short 5 # version
- .byte 3 # address_size
- .byte 0 # segment_selector_size
- .long 0x00000000
- .long 0x00000001
+ .section .debug_addr,"", at progbits
+ .long 0xffffffff # DWARF64 mark
+ .quad .LAddr0end-.LAddr0version # Length
+.LAddr0version:
+ .short 5 # Version
+ .byte 4 # Address size
+ .byte 0 # Segment selector size
+ .long 0x00000000
+ .long 0x00001000
+.LAddr0end:
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_addr_reserved_length.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_addr_reserved_length.s
new file mode 100644
index 000000000000..58857808422f
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_addr_reserved_length.s
@@ -0,0 +1,8 @@
+# RUN: llvm-mc %s -filetype obj -triple x86_64-pc-linux -o - | \
+# RUN: llvm-dwarfdump --debug-addr - 2>&1 | \
+# RUN: FileCheck %s --implicit-check-not=error
+
+# CHECK: error: address table at offset 0x0 has unsupported reserved unit length of value 0xfffffff0
+
+.section .debug_addr,"", at progbits
+.long 0xfffffff0
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_addr_too_small_for_extended_length_field.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_addr_too_small_for_extended_length_field.s
new file mode 100644
index 000000000000..8c2cc11de854
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_addr_too_small_for_extended_length_field.s
@@ -0,0 +1,13 @@
+# RUN: llvm-mc %s -filetype obj -triple i386-pc-linux -o - | \
+# RUN: llvm-dwarfdump -debug-addr - 2> %t.err | FileCheck %s
+# RUN: FileCheck %s -input-file %t.err -check-prefix=ERR
+
+# CHECK: .debug_addr contents:
+# CHECK-NOT: {{.}}
+# ERR: section is not large enough to contain an extended length field of the address table at offset 0x0
+# ERR-NOT: {{.}}
+
+# too small section to contain an extended length field of a DWARF64 address table.
+ .section .debug_addr,"", at progbits
+ .long 0xffffffff # DWARF64 mark
+ .space 7 # a DWARF64 unit length field takes 8 bytes.
More information about the llvm-commits
mailing list