[llvm] 7157264 - [DebugInfo] Add error-handling to DWARFAbbreviationDeclarationSet
Alex Langford via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 8 11:16:56 PDT 2023
Author: Alex Langford
Date: 2023-06-08T11:16:42-07:00
New Revision: 715726429ec4fc4f0f5f0f2e3dc6c3c31ce8f3a6
URL: https://github.com/llvm/llvm-project/commit/715726429ec4fc4f0f5f0f2e3dc6c3c31ce8f3a6
DIFF: https://github.com/llvm/llvm-project/commit/715726429ec4fc4f0f5f0f2e3dc6c3c31ce8f3a6.diff
LOG: [DebugInfo] Add error-handling to DWARFAbbreviationDeclarationSet
This commit aims to improve error handling in the
DWARFAbbreviationDeclarationSet class. Specifically, we change the return type
of DWARFAbbreviationDeclarationSet::extract to an llvm::Error. In doing
so, we propagate the error from DWARFAbbreviationDeclaration::extract
another layer upward.
I have built on the previous unittest for DWARFDebugAbbrev that I
wrote a few days prior.
Namely, I am verifying that the following should give an error:
- An invalid tag following a non-null code
- An invalid attribute with a valid form
- A valid attribute with an invalid form
- An incorrectly terminated DWARFAbbreviationDeclaration
Additionally, I uncovered some invalid DWARF in an unrelated dsymutil
test. Namely the last Abbreviation Decl was missing a code.
This test has been updated accordingly. However, this commit does
not fix the underlying issue: llvm-dwarfdump does not correctly
verify the debug abbreviation section to catch these kinds of
mistakes. I have updated DWARFVerifier to not dereference a
pointer without first checking it and left a FIXME for future
contributors.
Differential Revision: https://reviews.llvm.org/D151353
Added:
Modified:
llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h
llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp
llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
llvm/test/DebugInfo/ARM/dwarfdump-rela.yaml
llvm/test/DebugInfo/X86/dwarfdump-header-64.s
llvm/test/DebugInfo/X86/dwarfdump-rela-dwo.s
llvm/test/tools/dsymutil/Inputs/empty-CU.s
llvm/test/tools/dsymutil/Inputs/swift-interface.s
llvm/test/tools/dsymutil/X86/empty-CU.test
llvm/test/tools/llvm-dwarfdump/X86/debug-abbrev.s
llvm/test/tools/llvm-dwarfdump/X86/no_debug_addr.s
llvm/test/tools/llvm-dwarfdump/X86/verify_strings.s
llvm/test/tools/llvm-dwarfdump/X86/verify_unit_header_chain.s
llvm/unittests/DebugInfo/DWARF/DWARFDebugAbbrevTest.cpp
Removed:
llvm/test/tools/dsymutil/Inputs/empty-CU.o
################################################################################
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h
index aa3885d7a9d6b..76833cc33142b 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h
@@ -34,7 +34,7 @@ class DWARFAbbreviationDeclarationSet {
uint64_t getOffset() const { return Offset; }
void dump(raw_ostream &OS) const;
- bool extract(DataExtractor Data, uint64_t *OffsetPtr);
+ Error extract(DataExtractor Data, uint64_t *OffsetPtr);
const DWARFAbbreviationDeclaration *
getAbbreviationDeclaration(uint32_t AbbrCode) const;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp
index a8df634d6a63d..54093dd032af0 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp
@@ -25,21 +25,18 @@ void DWARFAbbreviationDeclarationSet::clear() {
Decls.clear();
}
-bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
- uint64_t *OffsetPtr) {
+Error DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
+ uint64_t *OffsetPtr) {
clear();
const uint64_t BeginOffset = *OffsetPtr;
Offset = BeginOffset;
DWARFAbbreviationDeclaration AbbrDecl;
uint32_t PrevAbbrCode = 0;
while (true) {
- llvm::Expected<DWARFAbbreviationDeclaration::ExtractState> ES =
+ Expected<DWARFAbbreviationDeclaration::ExtractState> ES =
AbbrDecl.extract(Data, OffsetPtr);
- if (!ES) {
- // FIXME: We should propagate the error upwards.
- llvm::consumeError(ES.takeError());
- break;
- }
+ if (!ES)
+ return ES.takeError();
if (*ES == DWARFAbbreviationDeclaration::ExtractState::Complete)
break;
@@ -53,7 +50,7 @@ bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
PrevAbbrCode = AbbrDecl.getCode();
Decls.push_back(std::move(AbbrDecl));
}
- return BeginOffset != *OffsetPtr;
+ return Error::success();
}
void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const {
@@ -127,8 +124,11 @@ void DWARFDebugAbbrev::parse() const {
++I;
uint64_t CUAbbrOffset = Offset;
DWARFAbbreviationDeclarationSet AbbrDecls;
- if (!AbbrDecls.extract(*Data, &Offset))
+ if (Error Err = AbbrDecls.extract(*Data, &Offset)) {
+ // FIXME: We should propagate the error upwards.
+ consumeError(std::move(Err));
break;
+ }
AbbrDeclSets.insert(I, std::make_pair(CUAbbrOffset, std::move(AbbrDecls)));
}
Data = std::nullopt;
@@ -164,8 +164,11 @@ DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const {
if (Data && CUAbbrOffset < Data->getData().size()) {
uint64_t Offset = CUAbbrOffset;
DWARFAbbreviationDeclarationSet AbbrDecls;
- if (!AbbrDecls.extract(*Data, &Offset))
+ if (Error Err = AbbrDecls.extract(*Data, &Offset)) {
+ // FIXME: We should propagate the error upwards.
+ consumeError(std::move(Err));
return nullptr;
+ }
PrevAbbrOffsetPos =
AbbrDeclSets.insert(std::make_pair(CUAbbrOffset, std::move(AbbrDecls)))
.first;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index e0f2fdd718b3a..54591447d449c 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -299,20 +299,27 @@ unsigned DWARFVerifier::verifyDebugInfoCallSite(const DWARFDie &Die) {
}
unsigned DWARFVerifier::verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev) {
+ if (!Abbrev)
+ return 0;
+
+ const DWARFAbbreviationDeclarationSet *AbbrDecls =
+ Abbrev->getAbbreviationDeclarationSet(0);
+ // FIXME: If we failed to get a DWARFAbbreviationDeclarationSet, it's possible
+ // that there are errors. We need to propagate the error from
+ // getAbbreviationDeclarationSet.
+ if (!AbbrDecls)
+ return 0;
+
unsigned NumErrors = 0;
- if (Abbrev) {
- const DWARFAbbreviationDeclarationSet *AbbrDecls =
- Abbrev->getAbbreviationDeclarationSet(0);
- for (auto AbbrDecl : *AbbrDecls) {
- SmallDenseSet<uint16_t> AttributeSet;
- for (auto Attribute : AbbrDecl.attributes()) {
- auto Result = AttributeSet.insert(Attribute.Attr);
- if (!Result.second) {
- error() << "Abbreviation declaration contains multiple "
- << AttributeString(Attribute.Attr) << " attributes.\n";
- AbbrDecl.dump(OS);
- ++NumErrors;
- }
+ for (auto AbbrDecl : *AbbrDecls) {
+ SmallDenseSet<uint16_t> AttributeSet;
+ for (auto Attribute : AbbrDecl.attributes()) {
+ auto Result = AttributeSet.insert(Attribute.Attr);
+ if (!Result.second) {
+ error() << "Abbreviation declaration contains multiple "
+ << AttributeString(Attribute.Attr) << " attributes.\n";
+ AbbrDecl.dump(OS);
+ ++NumErrors;
}
}
}
diff --git a/llvm/test/DebugInfo/ARM/dwarfdump-rela.yaml b/llvm/test/DebugInfo/ARM/dwarfdump-rela.yaml
index 9e307f4665cd2..f65e56a196bde 100644
--- a/llvm/test/DebugInfo/ARM/dwarfdump-rela.yaml
+++ b/llvm/test/DebugInfo/ARM/dwarfdump-rela.yaml
@@ -24,7 +24,7 @@ Sections:
Content: 17000000050001040000000001A000000000000000020000000000
- Name: .debug_abbrev
Type: SHT_PROGBITS
- Content: 011101030E49130000022400030E0000
+ Content: 011101030E49130000022400030E000000
- Name: .debug_str
Type: SHT_PROGBITS
- Name: .rela.debug_info
diff --git a/llvm/test/DebugInfo/X86/dwarfdump-header-64.s b/llvm/test/DebugInfo/X86/dwarfdump-header-64.s
index 6f3cf691dc340..a8f250a5a2818 100644
--- a/llvm/test/DebugInfo/X86/dwarfdump-header-64.s
+++ b/llvm/test/DebugInfo/X86/dwarfdump-header-64.s
@@ -41,6 +41,7 @@ abbrev:
.byte 0x17 # DW_FORM_sec_offset
.byte 0x00 # EOM(1)
.byte 0x00 # EOM(2)
+ .byte 0x00 # EOM(3)
.ifdef ELF
.section .debug_info,"", at progbits
diff --git a/llvm/test/DebugInfo/X86/dwarfdump-rela-dwo.s b/llvm/test/DebugInfo/X86/dwarfdump-rela-dwo.s
index cff1331f491f0..d55f70f2c9488 100644
--- a/llvm/test/DebugInfo/X86/dwarfdump-rela-dwo.s
+++ b/llvm/test/DebugInfo/X86/dwarfdump-rela-dwo.s
@@ -31,6 +31,7 @@
.byte 0x25 # DW_FORM_strx1
.byte 0x00 # EOM(1)
.byte 0x00 # EOM(2)
+ .byte 0x00 # EOM(3)
.section .debug_info.dwo,"e", at progbits
# CHECK-LABEL: .debug_info.dwo
diff --git a/llvm/test/tools/dsymutil/Inputs/empty-CU.o b/llvm/test/tools/dsymutil/Inputs/empty-CU.o
deleted file mode 100644
index 11c5905bc12ae..0000000000000
Binary files a/llvm/test/tools/dsymutil/Inputs/empty-CU.o and /dev/null
diff er
diff --git a/llvm/test/tools/dsymutil/Inputs/empty-CU.s b/llvm/test/tools/dsymutil/Inputs/empty-CU.s
index c539588da1796..d5ba26c02f862 100644
--- a/llvm/test/tools/dsymutil/Inputs/empty-CU.s
+++ b/llvm/test/tools/dsymutil/Inputs/empty-CU.s
@@ -10,7 +10,8 @@
.byte 4
.section __DWARF,__debug_abbrev,regular,debug
.byte 1 # Abbrev code
-.byte 0x11 # TAG_compile_unit
-.byte 0 # no children
-.byte 0 # no attributes
-.byte 0
+.byte 0x11 # DW_TAG_compile_unit
+.byte 0 # DW_CHILDREN_no
+.byte 0 # Terminating attribute
+.byte 0 # Terminating form
+.byte 0 # Terminating abbrev code
diff --git a/llvm/test/tools/dsymutil/Inputs/swift-interface.s b/llvm/test/tools/dsymutil/Inputs/swift-interface.s
index f08ab9aaf601f..a69f008a6cf3e 100644
--- a/llvm/test/tools/dsymutil/Inputs/swift-interface.s
+++ b/llvm/test/tools/dsymutil/Inputs/swift-interface.s
@@ -2,16 +2,16 @@
##;
##; target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
##; target triple = "x86_64-apple-macosx10.9.0"
-##;
+##;
##; @__swift_reflection_version = linkonce_odr hidden constant i16 3
##; @llvm.used = appending global [1 x i8*] [i8* bitcast (i16* @__swift_reflection_version to i8*)], section "llvm.metadata", align 8
-##;
+##;
##; define i32 @main(i32, i8**) !dbg !29 {
##; entry:
##; %2 = bitcast i8** %1 to i8*
##; ret i32 0, !dbg !35
##; }
-##;
+##;
##; !llvm.dbg.cu = !{!0}
##; !swift.module.flags = !{!14}
##; !llvm.module.flags = !{!20, !21, !24}
@@ -23,9 +23,9 @@
##; !4 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !1, entity: !5, file: !1)
##; !5 = !DIModule(scope: null, name: "Foo", includePath: "/Foo/x86_64.swiftinterface")
##; !6 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !1, entity: !7, file: !1)
-##; !7 = !DIModule(scope: null, name: "Swift", includePath: "/SDK/Swift.swiftmodule/x86_64.swiftinterface", sysroot: "/SDK")
+##; !7 = !DIModule(scope: null, name: "Swift", includePath: "/SDK/Swift.swiftmodule/x86_64.swiftinterface")
##; !8 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !1, entity: !7, file: !1)
-##; !9 = !DIModule(scope: null, name: "Foundation", includePath: "/SDK/Foundation.swiftmodu
+##; !9 = !DIModule(scope: null, name: "Foundation", includePath: "/SDK/Foundation.swiftmodule")
##; !14 = !{!"standard-library", i1 false}
##; !20 = !{i32 2, !"Dwarf Version", i32 4}
##; !21 = !{i32 2, !"Debug Info Version", i32 3}
@@ -36,14 +36,14 @@
##; !35 = !DILocation(line: 0, scope: !36)
##; !36 = !DILexicalBlockFile(scope: !29, file: !37, discriminator: 0)
##; !37 = !DIFile(filename: "<compiler-generated>", directory: "")
- .section __TEXT,__text,regular,pure_instructions
+ .section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 9
- .globl _main ## -- Begin function main
+ .globl _main ## -- Begin function main
.p2align 4, 0x90
_main: ## @main
Lfunc_begin0:
- .file 1 "/ParseableInterfaceImports.swift"
- .loc 1 0 0 ## ParseableInterfaceImports.swift:0:0
+ .file 1 "/" "ParseableInterfaceImports.swift"
+ .loc 1 0 0 ## ParseableInterfaceImports.swift:0:0
.cfi_startproc
## %bb.0: ## %entry
xorl %eax, %eax
@@ -56,160 +56,209 @@ Lfunc_end0:
.section __TEXT,__const
.globl ___swift_reflection_version
.weak_definition ___swift_reflection_version
- .p2align 1
+ .p2align 1, 0x0
___swift_reflection_version:
- .short 3 ## 0x3
+ .short 3 ## 0x3
.no_dead_strip ___swift_reflection_version
- .section __DWARF,__debug_str,regular,debug
-Linfo_string:
- .byte 0 ## string offset=0
- .asciz "ParseableInterfaceImports.swift" ## string offset=1
- .asciz "/" ## string offset=33
- .asciz "Foo" ## string offset=35
- .asciz "/Foo/x86_64.swiftinterface" ## string offset=39
- .asciz "Swift" ## string offset=66
- .asciz "/SDK/Swift.swiftmodule/x86_64.swiftinterface" ## string offset=72
- .asciz "/SDK" ## string offset=117
- .asciz "main" ## string offset=122
- .asciz "Foundation" ## string offset=127
- .asciz "/SDK/Foundation.swiftmodule/x86_64.swiftinterface" ## string offset=138
.section __DWARF,__debug_abbrev,regular,debug
Lsection_abbrev:
- .byte 1 ## Abbreviation Code
- .byte 17 ## DW_TAG_compile_unit
- .byte 1 ## DW_CHILDREN_yes
- .byte 37 ## DW_AT_producer
- .byte 14 ## DW_FORM_strp
- .byte 19 ## DW_AT_language
- .byte 5 ## DW_FORM_data2
- .byte 3 ## DW_AT_name
- .byte 14 ## DW_FORM_strp
- .ascii "\202|" ## DW_AT_LLVM_sysroot
- .byte 14 ## DW_FORM_strp
- .byte 16 ## DW_AT_stmt_list
- .byte 23 ## DW_FORM_sec_offset
- .byte 27 ## DW_AT_comp_dir
- .byte 14 ## DW_FORM_strp
- .ascii "\345\177" ## DW_AT_APPLE_major_runtime_vers
- .byte 11 ## DW_FORM_data1
- .byte 17 ## DW_AT_low_pc
- .byte 1 ## DW_FORM_addr
- .byte 18 ## DW_AT_high_pc
- .byte 6 ## DW_FORM_data4
- .byte 0 ## EOM(1)
- .byte 0 ## EOM(2)
- .byte 2 ## Abbreviation Code
- .byte 30 ## DW_TAG_module
- .byte 1 ## DW_CHILDREN_yes
- .byte 3 ## DW_AT_name
- .byte 14 ## DW_FORM_strp
- .ascii "\200|" ## DW_AT_LLVM_include_path
- .byte 14 ## DW_FORM_strp
- .byte 0 ## EOM(1)
- .byte 0 ## EOM(2)
- .byte 3 ## Abbreviation Code
- .byte 46 ## DW_TAG_subprogram
- .byte 0 ## DW_CHILDREN_no
- .byte 17 ## DW_AT_low_pc
- .byte 1 ## DW_FORM_addr
- .byte 18 ## DW_AT_high_pc
- .byte 6 ## DW_FORM_data4
- .ascii "\347\177" ## DW_AT_APPLE_omit_frame_ptr
- .byte 25 ## DW_FORM_flag_present
- .byte 64 ## DW_AT_frame_base
- .byte 24 ## DW_FORM_exprloc
- .byte 110 ## DW_AT_linkage_name
- .byte 14 ## DW_FORM_strp
- .byte 3 ## DW_AT_name
- .byte 14 ## DW_FORM_strp
- .byte 58 ## DW_AT_decl_file
- .byte 11 ## DW_FORM_data1
- .byte 59 ## DW_AT_decl_line
- .byte 11 ## DW_FORM_data1
- .byte 63 ## DW_AT_external
- .byte 25 ## DW_FORM_flag_present
- .byte 0 ## EOM(1)
- .byte 0 ## EOM(2)
- .byte 4 ## Abbreviation Code
- .byte 58 ## DW_TAG_imported_module
- .byte 0 ## DW_CHILDREN_no
- .byte 24 ## DW_AT_import
- .byte 19 ## DW_FORM_ref4
- .byte 0 ## EOM(1)
- .byte 0 ## EOM(2)
- .byte 5 ## Abbreviation Code
- .byte 30 ## DW_TAG_module
- .byte 0 ## DW_CHILDREN_no
- .byte 3 ## DW_AT_name
- .byte 14 ## DW_FORM_strp
- .ascii "\200|" ## DW_AT_LLVM_include_path
- .byte 14 ## DW_FORM_strp
- .ascii "\202|" ## DW_AT_LLVM_sysroot
- .byte 14 ## DW_FORM_strp
- .byte 0 ## EOM(1)
- .byte 0 ## EOM(2)
- .byte 30 ## DW_TAG_module
- .byte 1 ## DW_CHILDREN_no
- .byte 3 ## DW_AT_name
- .byte 14 ## DW_FORM_strp
- .ascii "\200|" ## DW_AT_LLVM_include_path
- .byte 14 ## DW_FORM_strp
- .byte 0 ## EOM(1)
- .byte 0 ## EOM(2)
- .byte 0 ## EOM(3)
+ .byte 1 ## Abbreviation Code
+ .byte 17 ## DW_TAG_compile_unit
+ .byte 1 ## DW_CHILDREN_yes
+ .byte 37 ## DW_AT_producer
+ .byte 14 ## DW_FORM_strp
+ .byte 19 ## DW_AT_language
+ .byte 5 ## DW_FORM_data2
+ .byte 3 ## DW_AT_name
+ .byte 14 ## DW_FORM_strp
+ .ascii "\202|" ## DW_AT_LLVM_sysroot
+ .byte 14 ## DW_FORM_strp
+ .byte 16 ## DW_AT_stmt_list
+ .byte 23 ## DW_FORM_sec_offset
+ .byte 27 ## DW_AT_comp_dir
+ .byte 14 ## DW_FORM_strp
+ .ascii "\345\177" ## DW_AT_APPLE_major_runtime_vers
+ .byte 11 ## DW_FORM_data1
+ .byte 17 ## DW_AT_low_pc
+ .byte 1 ## DW_FORM_addr
+ .byte 18 ## DW_AT_high_pc
+ .byte 6 ## DW_FORM_data4
+ .byte 0 ## EOM(1)
+ .byte 0 ## EOM(2)
+ .byte 2 ## Abbreviation Code
+ .byte 30 ## DW_TAG_module
+ .byte 1 ## DW_CHILDREN_yes
+ .byte 3 ## DW_AT_name
+ .byte 14 ## DW_FORM_strp
+ .ascii "\200|" ## DW_AT_LLVM_include_path
+ .byte 14 ## DW_FORM_strp
+ .byte 0 ## EOM(1)
+ .byte 0 ## EOM(2)
+ .byte 3 ## Abbreviation Code
+ .byte 46 ## DW_TAG_subprogram
+ .byte 0 ## DW_CHILDREN_no
+ .byte 17 ## DW_AT_low_pc
+ .byte 1 ## DW_FORM_addr
+ .byte 18 ## DW_AT_high_pc
+ .byte 6 ## DW_FORM_data4
+ .ascii "\347\177" ## DW_AT_APPLE_omit_frame_ptr
+ .byte 25 ## DW_FORM_flag_present
+ .byte 64 ## DW_AT_frame_base
+ .byte 24 ## DW_FORM_exprloc
+ .byte 110 ## DW_AT_linkage_name
+ .byte 14 ## DW_FORM_strp
+ .byte 3 ## DW_AT_name
+ .byte 14 ## DW_FORM_strp
+ .byte 58 ## DW_AT_decl_file
+ .byte 11 ## DW_FORM_data1
+ .byte 59 ## DW_AT_decl_line
+ .byte 11 ## DW_FORM_data1
+ .byte 63 ## DW_AT_external
+ .byte 25 ## DW_FORM_flag_present
+ .byte 0 ## EOM(1)
+ .byte 0 ## EOM(2)
+ .byte 4 ## Abbreviation Code
+ .byte 58 ## DW_TAG_imported_module
+ .byte 0 ## DW_CHILDREN_no
+ .byte 24 ## DW_AT_import
+ .byte 19 ## DW_FORM_ref4
+ .byte 0 ## EOM(1)
+ .byte 0 ## EOM(2)
+ .byte 5 ## Abbreviation Code
+ .byte 30 ## DW_TAG_module
+ .byte 0 ## DW_CHILDREN_no
+ .byte 3 ## DW_AT_name
+ .byte 14 ## DW_FORM_strp
+ .ascii "\200|" ## DW_AT_LLVM_include_path
+ .byte 14 ## DW_FORM_strp
+ .byte 0 ## EOM(1)
+ .byte 0 ## EOM(2)
+ .byte 0 ## EOM(3)
.section __DWARF,__debug_info,regular,debug
Lsection_info:
Lcu_begin0:
.set Lset0, Ldebug_info_end0-Ldebug_info_start0 ## Length of Unit
.long Lset0
Ldebug_info_start0:
- .short 4 ## DWARF version number
+ .short 4 ## DWARF version number
.set Lset1, Lsection_abbrev-Lsection_abbrev ## Offset Into Abbrev. Section
.long Lset1
- .byte 8 ## Address Size (in bytes)
- .byte 1 ## Abbrev [1] 0xb:0x5b DW_TAG_compile_unit
- .long 0 ## DW_AT_producer
- .short 30 ## DW_AT_language
- .long 1 ## DW_AT_name
- .long 117 ## DW_AT_name
+ .byte 8 ## Address Size (in bytes)
+ .byte 1 ## Abbrev [1] 0xb:0x60 DW_TAG_compile_unit
+ .long 0 ## DW_AT_producer
+ .short 30 ## DW_AT_language
+ .long 1 ## DW_AT_name
+ .long 33 ## DW_AT_LLVM_sysroot
.set Lset2, Lline_table_start0-Lsection_line ## DW_AT_stmt_list
.long Lset2
- .long 33 ## DW_AT_comp_dir
- .byte 5 ## DW_AT_APPLE_major_runtime_vers
- .quad Lfunc_begin0 ## DW_AT_low_pc
+ .long 38 ## DW_AT_comp_dir
+ .byte 5 ## DW_AT_APPLE_major_runtime_vers
+ .quad Lfunc_begin0 ## DW_AT_low_pc
.set Lset3, Lfunc_end0-Lfunc_begin0 ## DW_AT_high_pc
.long Lset3
- .byte 2 ## Abbrev [2] 0x2b:0x23 DW_TAG_module
- .long 35 ## DW_AT_name
- .long 39 ## DW_AT_LLVM_include_path
- .byte 3 ## Abbrev [3] 0x34:0x19 DW_TAG_subprogram
- .quad Lfunc_begin0 ## DW_AT_low_pc
+ .byte 2 ## Abbrev [2] 0x2f:0x23 DW_TAG_module
+ .long 40 ## DW_AT_name
+ .long 44 ## DW_AT_LLVM_include_path
+ .byte 3 ## Abbrev [3] 0x38:0x19 DW_TAG_subprogram
+ .quad Lfunc_begin0 ## DW_AT_low_pc
.set Lset4, Lfunc_end0-Lfunc_begin0 ## DW_AT_high_pc
.long Lset4
## DW_AT_APPLE_omit_frame_ptr
- .byte 1 ## DW_AT_frame_base
+ .byte 1 ## DW_AT_frame_base
.byte 87
- .long 122 ## DW_AT_linkage_name
- .long 122 ## DW_AT_name
- .byte 1 ## DW_AT_decl_file
- .byte 1 ## DW_AT_decl_line
+ .long 122 ## DW_AT_linkage_name
+ .long 122 ## DW_AT_name
+ .byte 1 ## DW_AT_decl_file
+ .byte 1 ## DW_AT_decl_line
## DW_AT_external
- .byte 0 ## End Of Children Mark
- .byte 4 ## Abbrev [4] 0x4e:0x5 DW_TAG_imported_module
- .long 47 ## DW_AT_import
- .byte 5 ## Abbrev [5] 0x53:0xd DW_TAG_module
- .long 66 ## DW_AT_name
- .long 72 ## DW_AT_LLVM_include_path
- .long 117 ## DW_AT_LLVM_sysroot
- .byte 4 ## Abbrev [4] 0x60:0x5 DW_TAG_imported_module
- .long 105 ## DW_AT_import
- .byte 2 ## Abbrev [2] 0x2b:0x23 DW_TAG_module
- .long 127 ## DW_AT_name
- .long 138 ## DW_AT_LLVM_include_path
- .byte 0 ## End Of Children Mark
- .byte 0 ## End Of Children Mark
+ .byte 0 ## End Of Children Mark
+ .byte 4 ## Abbrev [4] 0x52:0x5 DW_TAG_imported_module
+ .long 47 ## DW_AT_import
+ .byte 5 ## Abbrev [5] 0x57:0x9 DW_TAG_module
+ .long 71 ## DW_AT_name
+ .long 77 ## DW_AT_LLVM_include_path
+ .byte 4 ## Abbrev [4] 0x60:0x5 DW_TAG_imported_module
+ .long 87 ## DW_AT_import
+ .byte 4 ## Abbrev [4] 0x65:0x5 DW_TAG_imported_module
+ .long 87 ## DW_AT_import
+ .byte 0 ## End Of Children Mark
Ldebug_info_end0:
+ .section __DWARF,__debug_str,regular,debug
+Linfo_string:
+ .byte 0 ## string offset=0
+ .asciz "ParseableInterfaceImports.swift" ## string offset=1
+ .asciz "/SDK" ## string offset=33
+ .asciz "/" ## string offset=38
+ .asciz "Foo" ## string offset=40
+ .asciz "/Foo/x86_64.swiftinterface" ## string offset=44
+ .asciz "Swift" ## string offset=71
+ .asciz "/SDK/Swift.swiftmodule/x86_64.swiftinterface" ## string offset=77
+ .asciz "main" ## string offset=122
+ .section __DWARF,__apple_names,regular,debug
+Lnames_begin:
+ .long 1212240712 ## Header Magic
+ .short 1 ## Header Version
+ .short 0 ## Header Hash Function
+ .long 1 ## Header Bucket Count
+ .long 1 ## Header Hash Count
+ .long 12 ## Header Data Length
+ .long 0 ## HeaderData Die Offset Base
+ .long 1 ## HeaderData Atom Count
+ .short 1 ## DW_ATOM_die_offset
+ .short 6 ## DW_FORM_data4
+ .long 0 ## Bucket 0
+ .long 2090499946 ## Hash in Bucket 0
+.set Lset5, LNames0-Lnames_begin ## Offset in Bucket 0
+ .long Lset5
+LNames0:
+ .long 122 ## main
+ .long 1 ## Num DIEs
+ .long 56
+ .long 0
+ .section __DWARF,__apple_objc,regular,debug
+Lobjc_begin:
+ .long 1212240712 ## Header Magic
+ .short 1 ## Header Version
+ .short 0 ## Header Hash Function
+ .long 1 ## Header Bucket Count
+ .long 0 ## Header Hash Count
+ .long 12 ## Header Data Length
+ .long 0 ## HeaderData Die Offset Base
+ .long 1 ## HeaderData Atom Count
+ .short 1 ## DW_ATOM_die_offset
+ .short 6 ## DW_FORM_data4
+ .long -1 ## Bucket 0
+ .section __DWARF,__apple_namespac,regular,debug
+Lnamespac_begin:
+ .long 1212240712 ## Header Magic
+ .short 1 ## Header Version
+ .short 0 ## Header Hash Function
+ .long 1 ## Header Bucket Count
+ .long 0 ## Header Hash Count
+ .long 12 ## Header Data Length
+ .long 0 ## HeaderData Die Offset Base
+ .long 1 ## HeaderData Atom Count
+ .short 1 ## DW_ATOM_die_offset
+ .short 6 ## DW_FORM_data4
+ .long -1 ## Bucket 0
+ .section __DWARF,__apple_types,regular,debug
+Ltypes_begin:
+ .long 1212240712 ## Header Magic
+ .short 1 ## Header Version
+ .short 0 ## Header Hash Function
+ .long 1 ## Header Bucket Count
+ .long 0 ## Header Hash Count
+ .long 20 ## Header Data Length
+ .long 0 ## HeaderData Die Offset Base
+ .long 3 ## HeaderData Atom Count
+ .short 1 ## DW_ATOM_die_offset
+ .short 6 ## DW_FORM_data4
+ .short 3 ## DW_ATOM_die_tag
+ .short 5 ## DW_FORM_data2
+ .short 4 ## DW_ATOM_type_flags
+ .short 11 ## DW_FORM_data1
+ .long -1 ## Bucket 0
.subsections_via_symbols
.section __DWARF,__debug_line,regular,debug
Lsection_line:
diff --git a/llvm/test/tools/dsymutil/X86/empty-CU.test b/llvm/test/tools/dsymutil/X86/empty-CU.test
index bd3a54491ae6a..7b06607a74cbc 100644
--- a/llvm/test/tools/dsymutil/X86/empty-CU.test
+++ b/llvm/test/tools/dsymutil/X86/empty-CU.test
@@ -1,4 +1,5 @@
-RUN: dsymutil --update -f %p/../Inputs/empty-CU.o -o - | llvm-dwarfdump -v - -debug-info | FileCheck %s
+RUN: llvm-mc %p/../Inputs/empty-CU.s -filetype obj -triple x86_64-apple-darwin -o %t.o
+RUN: dsymutil --update -f %t.o -o - | llvm-dwarfdump -v - -debug-info | FileCheck %s
CHECK: .debug_info contents:
CHECK: 0x00000000: Compile Unit: length = 0x00000008, format = DWARF32, version = 0x0003, abbr_offset = 0x0000, addr_size = 0x04 (next unit at 0x0000000c)
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-abbrev.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-abbrev.s
index 04e0845d9300a..f9fccc9fee8bd 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/debug-abbrev.s
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug-abbrev.s
@@ -79,7 +79,7 @@
.byte 0x02 ## Invalid children encoding (interpreted as DW_CHILDREN_no).
.byte 0, 0 ## End of attributes.
- .byte 0 ## End of abbrevs.
+ .byte 0 ## End of first abbreviation set.
## Second .debug_abbrev set.
.byte 0x42 ## Abbreviation Code (duplicate in
diff erent unit)
@@ -88,3 +88,5 @@
.byte 0x66 ## DW_AT_elemental
.byte 0x19 ## DW_FORM_flag_present
.byte 0, 0 ## End of attributes.
+
+ .byte 0 # End of second abbreviation set.
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/no_debug_addr.s b/llvm/test/tools/llvm-dwarfdump/X86/no_debug_addr.s
index bf660679837be..288589129bdb5 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/no_debug_addr.s
+++ b/llvm/test/tools/llvm-dwarfdump/X86/no_debug_addr.s
@@ -28,6 +28,7 @@
.byte 35 # DW_FORM_rnglistx
.byte 0 # EOM(1)
.byte 0 # EOM(2)
+ .byte 0 # EOM(3)
.section .debug_rnglists.dwo,"e", at progbits
.long .Ldebug_rnglist_table_end1-.Ldebug_rnglist_table_start1 # Length
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/verify_strings.s b/llvm/test/tools/llvm-dwarfdump/X86/verify_strings.s
index 9beb7a1873ed6..b8666f963a3ce 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/verify_strings.s
+++ b/llvm/test/tools/llvm-dwarfdump/X86/verify_strings.s
@@ -35,6 +35,7 @@ str_producer:
.byte 0x17 # DW_FORM_sec_offset
.byte 0x00 # EOM(1)
.byte 0x00 # EOM(2)
+ .byte 0x00 # EOM(3)
.section .debug_info,"", at progbits
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/verify_unit_header_chain.s b/llvm/test/tools/llvm-dwarfdump/X86/verify_unit_header_chain.s
index baee5d86a24ed..5921f75643273 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/verify_unit_header_chain.s
+++ b/llvm/test/tools/llvm-dwarfdump/X86/verify_unit_header_chain.s
@@ -28,6 +28,7 @@ Linfo_string:
Lsection_abbrev:
.byte 1 ## Abbreviation Code
.byte 17 ## DW_TAG_compile_unit
+ .byte 0 ## DW_CHILDREN_no
.byte 0 ## EOM(1)
.byte 0 ## EOM(2)
.byte 0 ## EOM(3)
diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugAbbrevTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugAbbrevTest.cpp
index 62627ae6956ff..7ba22d2eefff7 100644
--- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugAbbrevTest.cpp
+++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugAbbrevTest.cpp
@@ -20,8 +20,8 @@ using namespace dwarf;
enum OrderKind : bool { InOrder, OutOfOrder };
-void writeAbbreviationDeclarations(raw_ostream &OS, uint32_t FirstCode,
- OrderKind Order) {
+void writeValidAbbreviationDeclarations(raw_ostream &OS, uint32_t FirstCode,
+ OrderKind Order) {
encodeULEB128(FirstCode, OS);
encodeULEB128(DW_TAG_compile_unit, OS);
OS << static_cast<uint8_t>(DW_CHILDREN_yes);
@@ -57,14 +57,13 @@ TEST(DWARFDebugAbbrevTest, DWARFAbbrevDeclSetExtractSuccess) {
raw_svector_ostream OS(RawData);
uint32_t FirstCode = 5;
- writeAbbreviationDeclarations(OS, FirstCode, InOrder);
+ writeValidAbbreviationDeclarations(OS, FirstCode, InOrder);
encodeULEB128(0, OS);
uint64_t Offset = 0;
DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
DWARFAbbreviationDeclarationSet AbbrevSet;
- const bool DataWasExtracted = AbbrevSet.extract(Data, &Offset);
- EXPECT_TRUE(DataWasExtracted);
+ ASSERT_THAT_ERROR(AbbrevSet.extract(Data, &Offset), Succeeded());
// The Abbreviation Declarations are in order and contiguous, so we want to
// make sure that FirstAbbrCode was correctly set.
EXPECT_EQ(AbbrevSet.getFirstAbbrCode(), FirstCode);
@@ -89,14 +88,13 @@ TEST(DWARFDebugAbbrevTest, DWARFAbbrevDeclSetExtractSuccessOutOfOrder) {
raw_svector_ostream OS(RawData);
uint32_t FirstCode = 2;
- writeAbbreviationDeclarations(OS, FirstCode, OutOfOrder);
+ writeValidAbbreviationDeclarations(OS, FirstCode, OutOfOrder);
encodeULEB128(0, OS);
uint64_t Offset = 0;
DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
DWARFAbbreviationDeclarationSet AbbrevSet;
- const bool DataWasExtracted = AbbrevSet.extract(Data, &Offset);
- EXPECT_TRUE(DataWasExtracted);
+ ASSERT_THAT_ERROR(AbbrevSet.extract(Data, &Offset), Succeeded());
// The declarations are out of order, ensure that FirstAbbrCode is UINT32_MAX.
EXPECT_EQ(AbbrevSet.getFirstAbbrCode(), UINT32_MAX);
@@ -126,7 +124,10 @@ TEST(DWARFDebugAbbrevTest, DWARFAbbreviationDeclSetCodeExtractionError) {
uint64_t Offset = 0;
DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
DWARFAbbreviationDeclarationSet AbbrevSet;
- EXPECT_FALSE(AbbrevSet.extract(Data, &Offset));
+ ASSERT_THAT_ERROR(
+ AbbrevSet.extract(Data, &Offset),
+ FailedWithMessage("unable to decode LEB128 at offset 0x00000000: "
+ "malformed uleb128, extends past end"));
EXPECT_EQ(Offset, 0u);
}
@@ -139,7 +140,10 @@ TEST(DWARFDebugAbbrevTest, DWARFAbbreviationDeclSetCodeExtractionError) {
uint64_t Offset = 0;
DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
DWARFAbbreviationDeclarationSet AbbrevSet;
- EXPECT_FALSE(AbbrevSet.extract(Data, &Offset));
+ ASSERT_THAT_ERROR(
+ AbbrevSet.extract(Data, &Offset),
+ FailedWithMessage("unable to decode LEB128 at offset 0x00000000: "
+ "uleb128 too big for uint64"));
EXPECT_EQ(Offset, 0u);
}
}
@@ -157,7 +161,10 @@ TEST(DWARFDebugAbbrevTest, DWARFAbbreviationDeclSetTagExtractionError) {
uint64_t Offset = 0;
DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
DWARFAbbreviationDeclarationSet AbbrevSet;
- EXPECT_TRUE(AbbrevSet.extract(Data, &Offset));
+ ASSERT_THAT_ERROR(
+ AbbrevSet.extract(Data, &Offset),
+ FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
+ "malformed uleb128, extends past end"));
// Only the code was extracted correctly.
EXPECT_EQ(Offset, 1u);
}
@@ -172,13 +179,16 @@ TEST(DWARFDebugAbbrevTest, DWARFAbbreviationDeclSetTagExtractionError) {
uint64_t Offset = 0;
DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
DWARFAbbreviationDeclarationSet AbbrevSet;
- EXPECT_TRUE(AbbrevSet.extract(Data, &Offset));
+ ASSERT_THAT_ERROR(
+ AbbrevSet.extract(Data, &Offset),
+ FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
+ "uleb128 too big for uint64"));
// Only the code was extracted correctly.
EXPECT_EQ(Offset, 1u);
}
}
-TEST(DWARFDebugAbbrevTest, DWARFAbbreviatioDeclSetChildExtractionError) {
+TEST(DWARFDebugAbbrevTest, DWARFAbbreviationDeclSetChildExtractionError) {
SmallString<64> RawData;
const uint32_t Code = 1;
const dwarf::Tag Tag = DW_TAG_compile_unit;
@@ -188,11 +198,13 @@ TEST(DWARFDebugAbbrevTest, DWARFAbbreviatioDeclSetChildExtractionError) {
raw_svector_ostream OS(RawData);
encodeULEB128(Code, OS);
encodeULEB128(Tag, OS);
-
uint64_t Offset = 0;
DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
DWARFAbbreviationDeclarationSet AbbrevSet;
- EXPECT_TRUE(AbbrevSet.extract(Data, &Offset));
+ ASSERT_THAT_ERROR(
+ AbbrevSet.extract(Data, &Offset),
+ FailedWithMessage(
+ "unexpected end of data at offset 0x2 while reading [0x2, 0x3)"));
// The code and the tag were extracted correctly.
EXPECT_EQ(Offset, 2u);
}
@@ -214,7 +226,10 @@ TEST(DWARFDebugAbbrevTest, DWARFAbbreviationDeclSetAttributeExtractionError) {
uint64_t Offset = 0;
DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
DWARFAbbreviationDeclarationSet AbbrevSet;
- EXPECT_TRUE(AbbrevSet.extract(Data, &Offset));
+ ASSERT_THAT_ERROR(
+ AbbrevSet.extract(Data, &Offset),
+ FailedWithMessage("unable to decode LEB128 at offset 0x00000003: "
+ "malformed uleb128, extends past end"));
// The code, tag, and child byte were extracted correctly.
EXPECT_EQ(Offset, 3u);
}
@@ -231,7 +246,10 @@ TEST(DWARFDebugAbbrevTest, DWARFAbbreviationDeclSetAttributeExtractionError) {
uint64_t Offset = 0;
DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
DWARFAbbreviationDeclarationSet AbbrevSet;
- EXPECT_TRUE(AbbrevSet.extract(Data, &Offset));
+ ASSERT_THAT_ERROR(
+ AbbrevSet.extract(Data, &Offset),
+ FailedWithMessage("unable to decode LEB128 at offset 0x00000003: "
+ "uleb128 too big for uint64"));
// The code, tag, and child byte were extracted correctly.
EXPECT_EQ(Offset, 3u);
}
@@ -256,7 +274,10 @@ TEST(DWARFDebugAbbrevTest, DWARFAbbreviationDeclSetFormExtractionError) {
uint64_t Offset = 0;
DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
DWARFAbbreviationDeclarationSet AbbrevSet;
- EXPECT_TRUE(AbbrevSet.extract(Data, &Offset));
+ ASSERT_THAT_ERROR(
+ AbbrevSet.extract(Data, &Offset),
+ FailedWithMessage("unable to decode LEB128 at offset 0x00000004: "
+ "malformed uleb128, extends past end"));
// The code, tag, child byte, and first attribute were extracted correctly.
EXPECT_EQ(Offset, 4u);
}
@@ -274,8 +295,120 @@ TEST(DWARFDebugAbbrevTest, DWARFAbbreviationDeclSetFormExtractionError) {
uint64_t Offset = 0;
DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
DWARFAbbreviationDeclarationSet AbbrevSet;
- EXPECT_TRUE(AbbrevSet.extract(Data, &Offset));
+ ASSERT_THAT_ERROR(
+ AbbrevSet.extract(Data, &Offset),
+ FailedWithMessage("unable to decode LEB128 at offset 0x00000004: "
+ "uleb128 too big for uint64"));
// The code, tag, child byte, and first attribute were extracted correctly.
EXPECT_EQ(Offset, 4u);
}
}
+
+TEST(DWARFDebugAbbrevTest, DWARFAbbrevDeclSetInvalidTag) {
+ SmallString<64> RawData;
+ raw_svector_ostream OS(RawData);
+ uint32_t FirstCode = 1;
+ // First, we're going to manually add good data.
+ writeValidAbbreviationDeclarations(OS, FirstCode, InOrder);
+
+ // Afterwards, we're going to write an Abbreviation Decl manually with an
+ // invalid tag.
+ encodeULEB128(FirstCode + 2, OS);
+ encodeULEB128(0, OS); // Invalid Tag
+ OS << static_cast<uint8_t>(DW_CHILDREN_no);
+ encodeULEB128(DW_AT_name, OS);
+ encodeULEB128(DW_FORM_strp, OS);
+ encodeULEB128(0, OS);
+ encodeULEB128(0, OS);
+
+ encodeULEB128(0, OS);
+ uint64_t Offset = 0;
+ DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
+ DWARFAbbreviationDeclarationSet AbbrevSet;
+ EXPECT_THAT_ERROR(
+ AbbrevSet.extract(Data, &Offset),
+ FailedWithMessage("abbreviation declaration requires a non-null tag"));
+}
+
+TEST(DWARFDebugAbbrevTest, DWARFAbbrevDeclSetInvalidAttrValidForm) {
+ SmallString<64> RawData;
+ raw_svector_ostream OS(RawData);
+ uint32_t FirstCode = 120;
+ // First, we're going to manually add good data.
+ writeValidAbbreviationDeclarations(OS, FirstCode, InOrder);
+
+ // Afterwards, we're going to write an Abbreviation Decl manually with an
+ // invalid attribute but valid form.
+ encodeULEB128(FirstCode - 5, OS);
+ encodeULEB128(DW_TAG_compile_unit, OS);
+ OS << static_cast<uint8_t>(DW_CHILDREN_no);
+ encodeULEB128(0, OS); // Invalid attribute followed by an invalid form.
+ encodeULEB128(DW_FORM_strp, OS);
+ encodeULEB128(0, OS);
+ encodeULEB128(0, OS);
+
+ encodeULEB128(0, OS);
+
+ uint64_t Offset = 0;
+ DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
+ DWARFAbbreviationDeclarationSet AbbrevSet;
+ EXPECT_THAT_ERROR(
+ AbbrevSet.extract(Data, &Offset),
+ FailedWithMessage(
+ "malformed abbreviation declaration attribute. Either the "
+ "attribute or the form is zero while the other is not"));
+}
+
+TEST(DWARFDebugAbbrevTest, DWARFAbbrevDeclSetValidAttrInvalidForm) {
+ SmallString<64> RawData;
+ raw_svector_ostream OS(RawData);
+ uint32_t FirstCode = 120;
+ // First, we're going to manually add good data.
+ writeValidAbbreviationDeclarations(OS, FirstCode, InOrder);
+
+ // Afterwards, we're going to write an Abbreviation Decl manually with a
+ // valid attribute but invalid form.
+ encodeULEB128(FirstCode - 5, OS);
+ encodeULEB128(DW_TAG_compile_unit, OS);
+ OS << static_cast<uint8_t>(DW_CHILDREN_no);
+ encodeULEB128(DW_AT_name, OS);
+ encodeULEB128(0, OS); // Invalid form after a valid attribute.
+ encodeULEB128(0, OS);
+ encodeULEB128(0, OS);
+
+ encodeULEB128(0, OS);
+
+ uint64_t Offset = 0;
+ DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
+ DWARFAbbreviationDeclarationSet AbbrevSet;
+ EXPECT_THAT_ERROR(
+ AbbrevSet.extract(Data, &Offset),
+ FailedWithMessage(
+ "malformed abbreviation declaration attribute. Either the "
+ "attribute or the form is zero while the other is not"));
+}
+
+TEST(DWARFDebugAbbrevTest, DWARFAbbrevDeclSetMissingTerminator) {
+ SmallString<64> RawData;
+ raw_svector_ostream OS(RawData);
+ uint32_t FirstCode = 120;
+ // First, we're going to manually add good data.
+ writeValidAbbreviationDeclarations(OS, FirstCode, InOrder);
+
+ // Afterwards, we're going to write an Abbreviation Decl manually without a
+ // termintating sequence.
+ encodeULEB128(FirstCode + 7, OS);
+ encodeULEB128(DW_TAG_compile_unit, OS);
+ OS << static_cast<uint8_t>(DW_CHILDREN_no);
+ encodeULEB128(DW_AT_name, OS);
+ encodeULEB128(DW_FORM_strp, OS);
+
+ uint64_t Offset = 0;
+ DataExtractor Data(RawData, sys::IsLittleEndianHost, sizeof(uint64_t));
+ DWARFAbbreviationDeclarationSet AbbrevSet;
+ EXPECT_THAT_ERROR(
+ AbbrevSet.extract(Data, &Offset),
+ FailedWithMessage(
+ "abbreviation declaration attribute list was not terminated with a "
+ "null entry"));
+}
More information about the llvm-commits
mailing list