diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h @@ -34,7 +34,7 @@ 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 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp @@ -25,21 +25,18 @@ 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 ES = + Expected 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 @@ 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 @@ ++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 @@ 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 --- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -299,20 +299,27 @@ } 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 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 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/tools/dsymutil/Inputs/swift-interface.s b/llvm/test/tools/dsymutil/Inputs/swift-interface.s --- 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: "", 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 @@ .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/unittests/DebugInfo/DWARF/DWARFDebugAbbrevTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugAbbrevTest.cpp --- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugAbbrevTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugAbbrevTest.cpp @@ -20,8 +20,8 @@ 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(DW_CHILDREN_yes); @@ -47,14 +47,13 @@ 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); @@ -79,14 +78,13 @@ 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); @@ -104,3 +102,113 @@ EXPECT_FALSE(Abbrev1->hasChildren()); EXPECT_EQ(Abbrev1->getNumAttributes(), 1u); } + +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(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(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(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(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")); +}