From 0f3bb3d9cac7c645f42c3e40c4df021e2b58c990 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Sat, 25 May 2019 00:07:22 +0000 Subject: [PATCH] llvm-dwarfdump: Don't error on mixed units using/not using str_offsets This lead to errors when dumping binaries with v4 and v5 units linked together (but could've also errored on v5 units that did/didn't use str_offsets). Also improves error handling and messages around invalid str_offsets contributions. llvm-svn: 361683 --- include/llvm/DebugInfo/DWARF/DWARFUnit.h | 7 +- lib/DebugInfo/DWARF/DWARFContext.cpp | 9 +- lib/DebugInfo/DWARF/DWARFUnit.cpp | 119 +++++++++----- .../X86/dwarfdump-str-offsets-invalid-1.s | 37 ----- .../X86/dwarfdump-str-offsets-invalid-2.s | 39 ----- .../X86/dwarfdump-str-offsets-invalid-3.s | 93 ----------- .../X86/dwarfdump-str-offsets-invalid-4.s | 56 ------- .../X86/dwarfdump-str-offsets-invalid-6.s | 4 +- .../X86/dwarfdump-str-offsets-invalid.s | 154 ++++++++++++++++++ test/DebugInfo/X86/dwarfdump-str-offsets.s | 21 +++ 10 files changed, 264 insertions(+), 275 deletions(-) delete mode 100644 test/DebugInfo/X86/dwarfdump-str-offsets-invalid-1.s delete mode 100644 test/DebugInfo/X86/dwarfdump-str-offsets-invalid-2.s delete mode 100644 test/DebugInfo/X86/dwarfdump-str-offsets-invalid-3.s delete mode 100644 test/DebugInfo/X86/dwarfdump-str-offsets-invalid-4.s create mode 100644 test/DebugInfo/X86/dwarfdump-str-offsets-invalid.s diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index 4e92df2fdb1..f01b6ac0388 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -175,6 +175,7 @@ struct StrOffsetsContributionDescriptor { StrOffsetsContributionDescriptor(uint64_t Base, uint64_t Size, uint8_t Version, dwarf::DwarfFormat Format) : Base(Base), Size(Size), FormParams({Version, 0, Format}) {} + StrOffsetsContributionDescriptor() = default; uint8_t getVersion() const { return FormParams.Version; } dwarf::DwarfFormat getFormat() const { return FormParams.Format; } @@ -184,7 +185,7 @@ struct StrOffsetsContributionDescriptor { /// Determine whether a contribution to the string offsets table is /// consistent with the relevant section size and that its length is /// a multiple of the size of one of its entries. - Optional + Expected validateContributionSize(DWARFDataExtractor &DA); }; @@ -249,14 +250,14 @@ protected: /// Find the unit's contribution to the string offsets table and determine its /// length and form. The given offset is expected to be derived from the unit /// DIE's DW_AT_str_offsets_base attribute. - Optional + Expected> determineStringOffsetsTableContribution(DWARFDataExtractor &DA); /// Find the unit's contribution to the string offsets table and determine its /// length and form. The given offset is expected to be 0 in a dwo file or, /// in a dwp file, the start of the unit's contribution to the string offsets /// table section (as determined by the index table). - Optional + Expected> determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA); public: diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp index 160a171176a..09a42a66ed1 100644 --- a/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -101,7 +101,8 @@ static ContributionCollection collectContributionData(DWARFContext::unit_iterator_range Units) { ContributionCollection Contributions; for (const auto &U : Units) - Contributions.push_back(U->getStringOffsetsTableContribution()); + if (const auto &C = U->getStringOffsetsTableContribution()) + Contributions.push_back(C); // Sort the contributions so that any invalid ones are placed at // the start of the contributions vector. This way they are reported // first. @@ -157,9 +158,9 @@ static void dumpDWARFv5StringOffsetsSection( // Detect overlapping contributions. if (Offset > ContributionHeader) { - OS << "error: overlapping contributions to string offsets table in " - "section ." - << SectionName << ".\n"; + WithColor::error() + << "overlapping contributions to string offsets table in section ." + << SectionName << ".\n"; return; } // Report a gap in the table. diff --git a/lib/DebugInfo/DWARF/DWARFUnit.cpp b/lib/DebugInfo/DWARF/DWARFUnit.cpp index fa165cf2d40..94bfc8c148f 100644 --- a/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -435,12 +435,17 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) { // which may differ from the unit's format. DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection, isLittleEndian, 0); - if (IsDWO) - StringOffsetsTableContribution = - determineStringOffsetsTableContributionDWO(DA); - else if (getVersion() >= 5) - StringOffsetsTableContribution = - determineStringOffsetsTableContribution(DA); + if (IsDWO || getVersion() >= 5) { + auto StringOffsetOrError = + IsDWO ? determineStringOffsetsTableContributionDWO(DA) + : determineStringOffsetsTableContribution(DA); + if (!StringOffsetOrError) { + WithColor::error() << "invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: " + << toString(StringOffsetOrError.takeError()) << '\n'; + } else { + StringOffsetsTableContribution = *StringOffsetOrError; + } + } // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to // describe address ranges. @@ -758,7 +763,7 @@ llvm::Optional DWARFUnit::getBaseAddress() { return BaseAddr; } -Optional +Expected StrOffsetsContributionDescriptor::validateContributionSize( DWARFDataExtractor &DA) { uint8_t EntrySize = getDwarfOffsetByteSize(); @@ -769,65 +774,94 @@ StrOffsetsContributionDescriptor::validateContributionSize( if (ValidationSize >= Size) if (DA.isValidOffsetForDataOfSize((uint32_t)Base, ValidationSize)) return *this; - return None; + return createStringError(errc::invalid_argument, "length exceeds section size"); } // Look for a DWARF64-formatted contribution to the string offsets table // starting at a given offset and record it in a descriptor. -static Optional +static Expected parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) { if (!DA.isValidOffsetForDataOfSize(Offset, 16)) - return None; + return createStringError(errc::invalid_argument, "section offset exceeds section size"); if (DA.getU32(&Offset) != 0xffffffff) - return None; + return createStringError(errc::invalid_argument, "32 bit contribution referenced from a 64 bit unit"); uint64_t Size = DA.getU64(&Offset); uint8_t Version = DA.getU16(&Offset); (void)DA.getU16(&Offset); // padding // The encoded length includes the 2-byte version field and the 2-byte // padding, so we need to subtract them out when we populate the descriptor. - return {{Offset, Size - 4, Version, DWARF64}}; + return StrOffsetsContributionDescriptor(Offset, Size - 4, Version, DWARF64); } // Look for a DWARF32-formatted contribution to the string offsets table // starting at a given offset and record it in a descriptor. -static Optional +static Expected parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) { if (!DA.isValidOffsetForDataOfSize(Offset, 8)) - return None; + return createStringError(errc::invalid_argument, "section offset exceeds section size"); + uint32_t ContributionSize = DA.getU32(&Offset); if (ContributionSize >= 0xfffffff0) - return None; + return createStringError(errc::invalid_argument, "invalid length"); + uint8_t Version = DA.getU16(&Offset); (void)DA.getU16(&Offset); // padding // The encoded length includes the 2-byte version field and the 2-byte // padding, so we need to subtract them out when we populate the descriptor. - return {{Offset, ContributionSize - 4, Version, DWARF32}}; + return StrOffsetsContributionDescriptor(Offset, ContributionSize - 4, Version, + DWARF32); } -Optional -DWARFUnit::determineStringOffsetsTableContribution(DWARFDataExtractor &DA) { - auto Offset = toSectionOffset(getUnitDIE().find(DW_AT_str_offsets_base), 0); - Optional Descriptor; - // Attempt to find a DWARF64 contribution 16 bytes before the base. - switch (Header.getFormat()) { - case dwarf::DwarfFormat::DWARF64: +static Expected +parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA, + llvm::dwarf::DwarfFormat Format, + uint64_t Offset) { + StrOffsetsContributionDescriptor Desc; + switch (Format) { + case dwarf::DwarfFormat::DWARF64: { if (Offset < 16) - return None; - Descriptor = - parseDWARF64StringOffsetsTableHeader(DA, (uint32_t)Offset - 16); - break; - case dwarf::DwarfFormat::DWARF32: - if (Offset < 8) - return None; - Descriptor = parseDWARF32StringOffsetsTableHeader(DA, (uint32_t)Offset - 8); + return createStringError(errc::invalid_argument, "insufficient space for 64 bit header prefix"); + auto DescOrError = parseDWARF64StringOffsetsTableHeader(DA, (uint32_t)Offset - 16); + if (!DescOrError) + return DescOrError.takeError(); + Desc = *DescOrError; break; } - return Descriptor ? Descriptor->validateContributionSize(DA) : Descriptor; + case dwarf::DwarfFormat::DWARF32: { + if (Offset < 8) + return createStringError(errc::invalid_argument, "insufficient space for 32 bit header prefix"); + auto DescOrError = parseDWARF32StringOffsetsTableHeader(DA, (uint32_t)Offset - 8); + if (!DescOrError) + return DescOrError.takeError(); + Desc = *DescOrError; + break; + } + } + return Desc.validateContributionSize(DA); } -Optional +Expected> +DWARFUnit::determineStringOffsetsTableContribution(DWARFDataExtractor &DA) { + uint64_t Offset; + if (IsDWO) { + Offset = 0; + if (DA.getData().data() == nullptr) + return None; + } else { + auto OptOffset = toSectionOffset(getUnitDIE().find(DW_AT_str_offsets_base)); + if (!OptOffset) + return None; + Offset = *OptOffset; + } + auto DescOrError = parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), Offset); + if (!DescOrError) + return DescOrError.takeError(); + return *DescOrError; +} + +Expected> DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) { uint64_t Offset = 0; auto IndexEntry = Header.getIndexEntry(); @@ -836,19 +870,24 @@ DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) { if (C) Offset = C->Offset; if (getVersion() >= 5) { + if (DA.getData().data() == nullptr) + return None; + Offset += Header.getFormat() == dwarf::DwarfFormat::DWARF32 ? 8 : 16; // Look for a valid contribution at the given offset. - auto Descriptor = - parseDWARF64StringOffsetsTableHeader(DA, (uint32_t)Offset); - if (!Descriptor) - Descriptor = parseDWARF32StringOffsetsTableHeader(DA, (uint32_t)Offset); - return Descriptor ? Descriptor->validateContributionSize(DA) : Descriptor; + auto DescOrError = parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), Offset); + if (!DescOrError) + return DescOrError.takeError(); + return *DescOrError; } // Prior to DWARF v5, we derive the contribution size from the // index table (in a package file). In a .dwo file it is simply // the length of the string offsets section. if (!IndexEntry) - return {{0, StringOffsetSection.Data.size(), 4, DWARF32}}; + return { + Optional( + {0, StringOffsetSection.Data.size(), 4, DWARF32})}; if (C) - return {{C->Offset, C->Length, 4, DWARF32}}; + return {Optional( + {C->Offset, C->Length, 4, DWARF32})}; return None; } diff --git a/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-1.s b/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-1.s deleted file mode 100644 index 180029202c5..00000000000 --- a/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-1.s +++ /dev/null @@ -1,37 +0,0 @@ -# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o -# RUN: llvm-dwarfdump -v %t.o | FileCheck --check-prefix=INVALIDCONTRIB %s -# -# Test object to verify that llvm-dwarfdump handles an invalid string offsets -# table. -# -# A rudimentary abbrev section. - .section .debug_abbrev,"",@progbits - .byte 0x01 # Abbrev code - .byte 0x11 # DW_TAG_compile_unit - .byte 0x00 # DW_CHILDREN_no - .byte 0x00 # EOM(1) - .byte 0x00 # EOM(2) - .byte 0x00 # EOM(3) - -# A rudimentary compile unit to convince dwarfdump that we are dealing with a -# DWARF v5 string offsets table. - .section .debug_info,"",@progbits - -# DWARF v5 CU header. - .long CU1_5_end-CU1_5_version # Length of Unit -CU1_5_version: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -# A compile-unit DIE, which has no attributes. - .byte 1 # Abbreviation code -CU1_5_end: - - .section .debug_str_offsets,"",@progbits -# A degenerate section, not enough for a single contribution size. - .byte 2 - -# INVALIDCONTRIB: .debug_str_offsets contents: -# INVALIDCONTRIB-NOT: contents: -# INVALIDCONTRIB: error: invalid contribution to string offsets table in section .debug_str_offsets. diff --git a/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-2.s b/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-2.s deleted file mode 100644 index e8819628f35..00000000000 --- a/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-2.s +++ /dev/null @@ -1,39 +0,0 @@ -# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o -# RUN: llvm-dwarfdump -v %t.o | FileCheck --check-prefix=INVALIDCONTRIB %s -# -# Test object to verify that llvm-dwarfdump handles an invalid string offsets -# table. -# -# A rudimentary abbrev section. - .section .debug_abbrev,"",@progbits - .byte 0x01 # Abbrev code - .byte 0x11 # DW_TAG_compile_unit - .byte 0x00 # DW_CHILDREN_no - .byte 0x00 # EOM(1) - .byte 0x00 # EOM(2) - .byte 0x00 # EOM(3) - -# A rudimentary compile unit to convince dwarfdump that we are dealing with a -# DWARF v5 string offsets table. - .section .debug_info,"",@progbits - -# DWARF v5 CU header. - .long CU1_5_end-CU1_5_version # Length of Unit -CU1_5_version: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -# A compile-unit DIE, which has no attributes. - .byte 1 # Abbreviation code -CU1_5_end: - - .section .debug_str_offsets,"",@progbits -# A degenerate section with fewer bytes than required for a DWARF64 size. - .long 0xffffffff - .long 0 - .short 4 - -# INVALIDCONTRIB: .debug_str_offsets contents: -# INVALIDCONTRIB-NOT: contents: -# INVALIDCONTRIB: error: invalid contribution to string offsets table in section .debug_str_offsets. diff --git a/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-3.s b/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-3.s deleted file mode 100644 index 07c7cfde13f..00000000000 --- a/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-3.s +++ /dev/null @@ -1,93 +0,0 @@ -# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o -# RUN: llvm-dwarfdump -v %t.o | FileCheck --check-prefix=INVALIDCONTRIB %s -# -# Test object to verify that llvm-dwarfdump handles an invalid string offsets -# table. - - .section .debug_str,"MS",@progbits,1 -str_producer: - .asciz "Handmade DWARF producer" -str_CU1: - .asciz "Compile_Unit_1" -str_CU1_dir: - .asciz "/home/test/CU1" -str_CU2: - .asciz "Compile_Unit_2" -str_CU2_dir: - .asciz "/home/test/CU2" -str_TU: - .asciz "Type_Unit" -str_TU_type: - .asciz "MyStruct" - - .section .debug_str.dwo,"MS",@progbits,1 -dwo_str_CU_5_producer: - .asciz "Handmade split DWARF producer" -dwo_str_CU_5_name: - .asciz "V5_split_compile_unit" -dwo_str_CU_5_comp_dir: - .asciz "/home/test/splitCU" -dwo_str_TU_5: - .asciz "V5_split_type_unit" -dwo_str_TU_5_type: - .asciz "V5_split_Mystruct" - -# A rudimentary abbrev section. - .section .debug_abbrev,"",@progbits - .byte 0x01 # Abbrev code - .byte 0x11 # DW_TAG_compile_unit - .byte 0x00 # DW_CHILDREN_no - .byte 0x72 # DW_AT_str_offsets_base - .byte 0x17 # DW_FORM_sec_offset - .byte 0x00 # EOM(1) - .byte 0x00 # EOM(2) - .byte 0x00 # EOM(3) - -# A rudimentary compile unit to convince dwarfdump that we are dealing with a -# DWARF v5 string offsets table. - .section .debug_info,"",@progbits - -# DWARF v5 CU header. - .long CU1_5_end-CU1_5_version # Length of Unit -CU1_5_version: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -# A compile-unit DIE, which has no attributes. - .byte 1 # Abbreviation code - .long .debug_str_offsets_base0 -CU1_5_end: - - .section .debug_str_offsets,"",@progbits -# CU1's contribution -# Invalid length - .long 0xfffffffe - .short 5 # DWARF version - .short 0 # Padding -.debug_str_offsets_base0: - .long str_producer - .long str_CU1 - .long str_CU1_dir -.debug_str_offsets_segment0_end: -# CU2's contribution - .long .debug_str_offsets_segment1_end-.debug_str_offsets_base1+4 - .short 5 # DWARF version - .short 0 # Padding -.debug_str_offsets_base1: - .long str_producer - .long str_CU2 - .long str_CU2_dir -.debug_str_offsets_segment1_end: -# The TU's contribution - .long .debug_str_offsets_segment2_end-.debug_str_offsets_base2+4 - .short 5 # DWARF version - .short 0 # Padding -.debug_str_offsets_base2: - .long str_TU - .long str_TU_type -.debug_str_offsets_segment2_end: - -# INVALIDCONTRIB: .debug_str_offsets contents: -# INVALIDCONTRIB-NOT: contents: -# INVALIDCONTRIB: error: invalid contribution to string offsets table in section .debug_str_offsets. diff --git a/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-4.s b/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-4.s deleted file mode 100644 index d4d56577206..00000000000 --- a/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-4.s +++ /dev/null @@ -1,56 +0,0 @@ -# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o -# RUN: llvm-dwarfdump -v %t.o | FileCheck --check-prefix=INVALIDLENGTH %s -# -# Test object to verify that llvm-dwarfdump handles an invalid string offsets -# table. - - .section .debug_str,"MS",@progbits,1 -str_producer: - .asciz "Handmade DWARF producer" -str_CU1: - .asciz "Compile_Unit_1" - -# A rudimentary abbrev section. - .section .debug_abbrev,"",@progbits - .byte 0x01 # Abbrev code - .byte 0x11 # DW_TAG_compile_unit - .byte 0x00 # DW_CHILDREN_no - .byte 0x72 # DW_AT_str_offsets_base - .byte 0x17 # DW_FORM_sec_offset - .byte 0x00 # EOM(1) - .byte 0x00 # EOM(2) - .byte 0x00 # EOM(3) - -# A rudimentary compile unit to convince dwarfdump that we are dealing with a -# DWARF v5 string offsets table. - .section .debug_info,"",@progbits - -# DWARF v5 CU header. - .long CU1_5_end-CU1_5_version # Length of Unit -CU1_5_version: - .short 5 # DWARF version number - .byte 1 # DWARF Unit Type - .byte 8 # Address Size (in bytes) - .long .debug_abbrev # Offset Into Abbrev. Section -# A compile-unit DIE, which has no attributes. - .byte 1 # Abbreviation code - .long .debug_str_offsets_base0 -CU1_5_end: - -# Every unit contributes to the string_offsets table. - .section .debug_str_offsets,"",@progbits -# CU1's contribution -# The length is not a multiple of 4. Check that we don't read off the -# end. - .long .debug_str_offsets_segment0_end-.debug_str_offsets_base0+4 - .short 5 # DWARF version - .short 0 # Padding -.debug_str_offsets_base0: - .long str_producer - .long str_CU1 - .byte 0 -.debug_str_offsets_segment0_end: - -# INVALIDLENGTH: .debug_str_offsets contents: -# INVALIDLENGTH-NOT: contents: -# INVALIDLENGTH: error: invalid contribution to string offsets table in section .debug_str_offsets. diff --git a/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-6.s b/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-6.s index 0a35c5e93db..03d70347a2f 100644 --- a/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-6.s +++ b/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-6.s @@ -1,5 +1,5 @@ # RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o -# RUN: llvm-dwarfdump -v %t.o | FileCheck --check-prefix=OVERLAP %s +# RUN: llvm-dwarfdump -v %t.o 2>&1 | FileCheck --check-prefix=OVERLAP %s # # Test object to verify that llvm-dwarfdump handles an invalid string offsets # table with overlapping contributions. @@ -89,6 +89,4 @@ CU2_5_end: .long str_CU2_dir .debug_str_offsets_segment1_end: -# OVERLAP: .debug_str_offsets contents: -# OVERLAP-NOT: contents: # OVERLAP: error: overlapping contributions to string offsets table in section .debug_str_offsets. diff --git a/test/DebugInfo/X86/dwarfdump-str-offsets-invalid.s b/test/DebugInfo/X86/dwarfdump-str-offsets-invalid.s new file mode 100644 index 00000000000..a4c22b961b3 --- /dev/null +++ b/test/DebugInfo/X86/dwarfdump-str-offsets-invalid.s @@ -0,0 +1,154 @@ +# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o +# RUN: llvm-dwarfdump -v %t.o 2>&1 | FileCheck %s +# +# Test object to verify that llvm-dwarfdump handles an invalid string offsets +# table. +# +# A rudimentary abbrev section. + .section .debug_abbrev,"",@progbits + .byte 0x01 # Abbrev code + .byte 0x11 # DW_TAG_compile_unit + .byte 0x00 # DW_CHILDREN_no + .byte 0x72 # DW_AT_str_offsets_base + .byte 0x17 # DW_FORM_sec_offset + .byte 0x00 # EOM(1) + .byte 0x00 # EOM(2) + .byte 0x00 # EOM(3) + +# A rudimentary compile unit to convince dwarfdump that we are dealing with a +# DWARF v5 string offsets table. + .section .debug_info,"",@progbits + +# DWARF v5 32 bit CU header. + .long CU1_end-CU1_begin # Length of Unit +CU1_begin: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbreviation code: DW_TAG_compile_unit + .long 0 # DW_AT_str_offsets_base +CU1_end: + +# DWARF v5 64 bit CU header. + .long 0xffffffff + .quad CU2_end-CU2_begin # Length of Unit +CU2_begin: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .quad .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbreviation code: DW_TAG_compile_unit + .quad 0 # DW_AT_str_offsets_base +CU2_end: + .long CU3_end-CU3_begin # Length of Unit +CU3_begin: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbreviation code: DW_TAG_compile_unit + .quad .str_off0 # DW_AT_str_offsets_base +CU3_end: + .long CU4_end-CU4_begin # Length of Unit +CU4_begin: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbreviation code: DW_TAG_compile_unit + .quad .str_off1 # DW_AT_str_offsets_base +CU4_end: + .long CU5_end-CU5_begin # Length of Unit +CU5_begin: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbreviation code: DW_TAG_compile_unit + .long .str_off2_begin # DW_AT_str_offsets_base +CU5_end: + .long CU6_end-CU6_begin # Length of Unit +CU6_begin: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbreviation code: DW_TAG_compile_unit + .long .str_off3_begin # DW_AT_str_offsets_base +CU6_end: + .long 0xffffffff + .quad CU7_end-CU7_begin # Length of Unit +CU7_begin: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .quad .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbreviation code: DW_TAG_compile_unit + .quad .str_off4_begin # DW_AT_str_offsets_base +CU7_end: + .long CU8_end-CU8_begin # Length of Unit +CU8_begin: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbreviation code: DW_TAG_compile_unit + .long .str_off_end+16 # DW_AT_str_offsets_base +CU8_end: + .long 0xffffffff + .quad CU9_end-CU9_begin # Length of Unit +CU9_begin: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .quad .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbreviation code: DW_TAG_compile_unit + .quad .str_off_end+8 # DW_AT_str_offsets_base +CU9_end: + + .section .debug_str_offsets,"",@progbits +# Invalid length + .long 0xfffffff4 + .short 5 # DWARF version + .short 0 # Padding +.str_off0: + .long 0 +# Length beyond section bounds + .long .str_off_end-.str_off1+8 + .short 5 # DWARF version + .short 0 # Padding +.str_off1: + .long 0 +# Length intrudes on following unit + .long .str_off2_end-.str_off2_begin+8 + .short 5 # DWARF version + .short 0 # Padding +.str_off2_begin: + .long 0 +.str_off2_end: +# Plain contribution, no errors here + .long .str_off3_end-.str_off3_begin + .short 5 # DWARF version + .short 0 # Padding +.str_off3_begin: + .long 0 +.str_off3_end: +# 32 bit contribution referenced from a 64 bit unit + .long .str_off4_end-.str_off4_begin + .short 5 # DWARF version + .short 0 # Padding +.str_off4_begin: + .long 0 +.str_off4_end: +.str_off_end: + + +# CHECK: error: invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: insufficient space for 32 bit header prefix +# CHECK: error: invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: insufficient space for 64 bit header prefix +# CHECK: error: invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: invalid length +# CHECK: error: invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: length exceeds section size +# CHECK: error: invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: 32 bit contribution referenced from a 64 bit unit +# CHECK: error: invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: section offset exceeds section size +# CHECK: error: invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: section offset exceeds section size +# CHECK: error: overlapping contributions to string offsets table in section .debug_str_offsets. diff --git a/test/DebugInfo/X86/dwarfdump-str-offsets.s b/test/DebugInfo/X86/dwarfdump-str-offsets.s index 064061b5847..f6303f123ad 100644 --- a/test/DebugInfo/X86/dwarfdump-str-offsets.s +++ b/test/DebugInfo/X86/dwarfdump-str-offsets.s @@ -166,6 +166,11 @@ dwo_str_TU_5_type: .byte 0x0b # DW_FORM_data1 .byte 0x00 # EOM(1) .byte 0x00 # EOM(2) + .byte 0x09 # Abbrev code + .byte 0x11 # DW_TAG_compile_unit + .byte 0x00 # DW_CHILDREN_no + .byte 0x00 # EOM(1) + .byte 0x00 # EOM(2) .byte 0x00 # EOM(3) # And a .dwo copy of a subset for the .dwo sections. @@ -255,6 +260,22 @@ CU2_5_version: .byte 2 # The index of the comp dir string .byte 0 # NULL CU2_5_end: +# DWARF v5 CU without str_offsets_base - this shouldn't produce an error/nor +# prevent other str_offsets contributions from being dumped. + .long CU3_5_end-CU3_5_version # Length of Unit +CU3_5_version: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section +# The compile-unit DIE with no attributes. + .byte 9 # Abbreviation code +CU3_5_end: + + + + + .section .debug_types,"",@progbits # DWARF v5 Type unit header.