From e74197bc12f68c4e7940574bec5f983297db56f8 Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Thu, 28 Jul 2022 19:20:58 +0300 Subject: [PATCH] [Reland][Debuginfo][llvm-dwarfutil] Add check for unsupported debug sections. Current DWARFLinker implementation does not support some debug sections (mainly DWARF v5 sections). This patch adds diagnostic for such sections. The warning would be displayed for critical(such that could not be removed) sections and the source file would be skipped. Other unsupported sections would be removed and warning message should be displayed. The zero exit status would be returned for both cases. Reviewed By: JDevlieghere Differential Revision: https://reviews.llvm.org/D123623 --- llvm/include/llvm/DWARFLinker/DWARFLinker.h | 2 +- llvm/lib/DWARFLinker/DWARFLinker.cpp | 56 +++++++++++++++- .../ELF/X86/Inputs/type-units.o | Bin 0 -> 3928 bytes .../ELF/X86/warning-skipped-cu-index.test | 54 +++++++++++++++ .../ELF/X86/warning-skipped-gdb-index.test | 54 +++++++++++++++ .../ELF/X86/warning-skipped-gnu-pubnames.test | 54 +++++++++++++++ .../ELF/X86/warning-skipped-gnu-pubtypes.test | 54 +++++++++++++++ .../ELF/X86/warning-skipped-loclists.test | 54 +++++++++++++++ .../ELF/X86/warning-skipped-macinfo.test | 62 ++++++++++++++++++ .../ELF/X86/warning-skipped-macro.test | 54 +++++++++++++++ .../ELF/X86/warning-skipped-names.test | 54 +++++++++++++++ .../ELF/X86/warning-skipped-pubnames.test | 54 +++++++++++++++ .../ELF/X86/warning-skipped-pubtypes.test | 54 +++++++++++++++ .../ELF/X86/warning-skipped-rnglists.test | 54 +++++++++++++++ .../ELF/X86/warning-skipped-types.test | 6 ++ llvm/tools/dsymutil/DwarfLinkerForBinary.cpp | 3 +- llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp | 49 ++++++++++++-- llvm/tools/llvm-dwarfutil/DebugInfoLinker.h | 4 +- llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp | 14 ++-- 19 files changed, 716 insertions(+), 20 deletions(-) create mode 100644 llvm/test/tools/llvm-dwarfutil/ELF/X86/Inputs/type-units.o create mode 100644 llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-cu-index.test create mode 100644 llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-gdb-index.test create mode 100644 llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-gnu-pubnames.test create mode 100644 llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-gnu-pubtypes.test create mode 100644 llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-loclists.test create mode 100644 llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-macinfo.test create mode 100644 llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-macro.test create mode 100644 llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-names.test create mode 100644 llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-pubnames.test create mode 100644 llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-pubtypes.test create mode 100644 llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-rnglists.test create mode 100644 llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-types.test diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/DWARFLinker.h index 3961100e00e1..4729e5f806d8 100644 --- a/llvm/include/llvm/DWARFLinker/DWARFLinker.h +++ b/llvm/include/llvm/DWARFLinker/DWARFLinker.h @@ -245,7 +245,7 @@ public: /// Link debug info for added objFiles. Object /// files are linked all together. - bool link(); + Error link(); /// A number of methods setting various linking options: diff --git a/llvm/lib/DWARFLinker/DWARFLinker.cpp b/llvm/lib/DWARFLinker/DWARFLinker.cpp index 62b7f629f403..495a582d825f 100644 --- a/llvm/lib/DWARFLinker/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/DWARFLinker.cpp @@ -2343,7 +2343,7 @@ void DWARFLinker::addObjectFile(DWARFFile &File) { updateAccelKind(*ObjectContexts.back().File.Dwarf); } -bool DWARFLinker::link() { +Error DWARFLinker::link() { assert(Options.NoOutput || TheDwarfEmitter); // A unique ID that identifies each compile unit. @@ -2410,6 +2410,58 @@ bool DWARFLinker::link() { if (!OptContext.File.Dwarf) continue; + // Check whether type units are presented. + if (!OptContext.File.Dwarf->types_section_units().empty()) { + reportWarning("type units are not currently supported: file will " + "be skipped", + OptContext.File); + OptContext.Skip = true; + continue; + } + + // Check for unsupported sections. Following sections can be referenced + // from .debug_info section. Current DWARFLinker implementation does not + // support or update references to these tables. Thus we report warning + // and skip corresponding object file. + if (!OptContext.File.Dwarf->getDWARFObj() + .getRnglistsSection() + .Data.empty()) { + reportWarning("'.debug_rnglists' is not currently supported: file " + "will be skipped", + OptContext.File); + OptContext.Skip = true; + continue; + } + + if (!OptContext.File.Dwarf->getDWARFObj() + .getLoclistsSection() + .Data.empty()) { + reportWarning("'.debug_loclists' is not currently supported: file " + "will be skipped", + OptContext.File); + OptContext.Skip = true; + continue; + } + + if (!OptContext.File.Dwarf->getDWARFObj().getMacroSection().Data.empty()) { + reportWarning("'.debug_macro' is not currently supported: file " + "will be skipped", + OptContext.File); + OptContext.Skip = true; + continue; + } + + if (OptContext.File.Dwarf->getDWARFObj().getMacinfoSection().size() > 0) { + if (OptContext.File.Dwarf->getDWARFObj().getMacinfoSection().find_if( + [](char Sym) { return Sym != 0; }) != StringRef::npos) { + reportWarning("'.debug_macinfo' is not currently supported: file " + "will be skipped", + OptContext.File); + OptContext.Skip = true; + continue; + } + } + // In a first phase, just read in the debug info and load all clang modules. OptContext.CompileUnits.reserve( OptContext.File.Dwarf->getNumCompileUnits()); @@ -2660,7 +2712,7 @@ bool DWARFLinker::link() { "---------------\n\n"; } - return true; + return Error::success(); } bool DWARFLinker::verify(const DWARFFile &File) { diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/Inputs/type-units.o b/llvm/test/tools/llvm-dwarfutil/ELF/X86/Inputs/type-units.o new file mode 100644 index 0000000000000000000000000000000000000000..064b4f06764e930a7988d192e5c86e3fcf27121d GIT binary patch literal 3928 zcmb_fUuauZ7(XXBZ8Ec_|D3i~Fv6zWy4-bL8|$RCTbYYcXDJk6K3s2-lQdg%6O!95 z^}!)dSs#Yoiz4{ogOB?|8$L((=5GWy&D&r){d*X%1>ec9`0TiK1z ze?wE?|0VuI1b&Z`_~oY{wpu*i+y5v#+QryWkfUhB;@9jVyYtIS7Y~8Jqd$Fc`%dM` zn;WQ#PdPZ6ot5vY(>{XCdY}rk~qluyu#K0(( zJo>T*k($4aC=?sekQ%#-jCWBPksHk?nhz#kKNIV_A9@*N zRy>h7m3Sh-nAOh@B?l8$awOT$2c$k~^CyR`BX=^`X=uYNdk&+~Y7rSPFhQ|2x@((}pVx4`=>*O*HI$tp)(l zz924e2d;knQ5;M=2ItN%rRGLQQxo=-eIk{v_^Y0nE(uT6%XtvpdVYDjIh9FgCQ|8A zDqSpy+-fN;{nHJR_sdm}9rr7>=mo5;+A3l&dtr8N*#vaM}o+Z`#~%Ph`+cn zzsPvAFD94P8rdI8 zxVA5vKC=t1?=m~rXfV5!&pV=-7d77j`xU`#X(wB8WGmYc*@hix-CV9N*0!nLy6cq$ zgw=wqls$+VxIit;&Q~iH0UOBns=lyc9?}ip&0kVZV%aIy-3qvr>eW@XO4Qz7$8W%~ zKg4-fVKjfkASdCG^Q(=!`Da7?do@3blL8EPU^hHEEhxd<$mB=1Bfyv#>asn71=WG| z? zbz`#CusPt(o>0B1=5I{d;{0Ks=KSrJ|EBWWYyMjy`SJT>=Dz@#IVYHU3x9y*_atED zuW7pkXjuP$sQf=DU+f>(!pvU;%#4XHs|vh`f<~t8I_OLc&3{%P%|C@OZQ*MZTK^Y# zSb@kN>&NqF)_)x^GbTW+SM8^16f`nzuYoRX{{B+=>6~GHe9xHq-vSI{Qk}p`npgQ> zP%;gapT>7V5$6A%@*f~aHIg5V?<;@9jNLTO6Y0s1QEE%ei`X~4kV8Z6F z4;KrF{Bi#7gNOWSUU5#%cMm`;uE6h5(8#PGWwUlPe+Lg6(5zBE0Q|l1nECes7MB06 zdU4_T(8vSINqU_I>juCH#X2d$$cQ!JWqqXDf5~wW(m#Yx6+Ffo}TJjCB9Ye{I zU&b(8Eux{aLch2e2X1{KWU&JwDB9zW*iLZC1ll>v4@o?1r7@0LY-!W^vE+((Wa6xl z_^7i&cG5|}2S7ta-}5N|`UupZrR=XeYh%p0FwrP`mloETv*cYadj)4vG*;op z)u|O{5NG|LRzP$=HStlfK|&n<1+?wyo}+)u(C%UU0YY3~jsMG@?hzOp_Xy>{_XiT; zfdqGc#Sng8$@m^Z!X2jXrXv#FSwDUMDbDlC4%Z*ajPq;&w{d#k=<}eTTG~TqoU{=~ aiR}}H^-zzfJFE<_C%rG)uV}BoUH${Q(Invj literal 0 HcmV?d00001 diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-cu-index.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-cu-index.test new file mode 100644 index 000000000000..04f827878d72 --- /dev/null +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-cu-index.test @@ -0,0 +1,54 @@ +## This test checks the warning message displayed if input file +## contains .debug_cu_index section. + +# RUN: yaml2obj %s -o %t.o + +# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o + +# CHECK: [[FILE]]: warning: '.debug_cu_index' is not currently supported: section will be skipped + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x0000000000000010 + Content: "FFFFFFFF" + - Name: .debug_cu_index + Type: SHT_PROGBITS + Flags: [ ] + Content: "0000" +DWARF: + debug_abbrev: + - Table: + - Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_string + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + debug_info: + - Version: 4 + Entries: + - AbbrCode: 1 + Values: + - CStr: by_hand + - Value: 0x04 + - CStr: CU1 + - Value: 0x1000 + - Value: 0x4 + - AbbrCode: 0 +... diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-gdb-index.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-gdb-index.test new file mode 100644 index 000000000000..81d489cb758d --- /dev/null +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-gdb-index.test @@ -0,0 +1,54 @@ +## This test checks the warning message displayed if input file +## contains .gdb_index section. + +# RUN: yaml2obj %s -o %t.o + +# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o + +# CHECK: [[FILE]]: warning: '.gdb_index' is not currently supported: section will be skipped + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x0000000000000010 + Content: "FFFFFFFF" + - Name: .gdb_index + Type: SHT_PROGBITS + Flags: [ ] + Content: "0000" +DWARF: + debug_abbrev: + - Table: + - Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_string + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + debug_info: + - Version: 4 + Entries: + - AbbrCode: 1 + Values: + - CStr: by_hand + - Value: 0x04 + - CStr: CU1 + - Value: 0x1000 + - Value: 0x4 + - AbbrCode: 0 +... diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-gnu-pubnames.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-gnu-pubnames.test new file mode 100644 index 000000000000..b34fb9a67a73 --- /dev/null +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-gnu-pubnames.test @@ -0,0 +1,54 @@ +## This test checks the warning message displayed if input file +## contains .debug_pubnames section. + +# RUN: yaml2obj %s -o %t.o + +# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o + +# CHECK: [[FILE]]: warning: '.debug_gnu_pubnames' is not currently supported: section will be skipped + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x0000000000000010 + Content: "FFFFFFFF" + - Name: .debug_gnu_pubnames + Type: SHT_PROGBITS + Flags: [ ] + Content: "0000" +DWARF: + debug_abbrev: + - Table: + - Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_string + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + debug_info: + - Version: 4 + Entries: + - AbbrCode: 1 + Values: + - CStr: by_hand + - Value: 0x04 + - CStr: CU1 + - Value: 0x1000 + - Value: 0x4 + - AbbrCode: 0 +... diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-gnu-pubtypes.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-gnu-pubtypes.test new file mode 100644 index 000000000000..f8050f746e28 --- /dev/null +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-gnu-pubtypes.test @@ -0,0 +1,54 @@ +## This test checks the warning message displayed if input file +## contains .debug_gnu_pubtypes section. + +# RUN: yaml2obj %s -o %t.o + +# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o + +# CHECK: [[FILE]]: warning: '.debug_gnu_pubtypes' is not currently supported: section will be skipped + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x0000000000000010 + Content: "FFFFFFFF" + - Name: .debug_gnu_pubtypes + Type: SHT_PROGBITS + Flags: [ ] + Content: "0000" +DWARF: + debug_abbrev: + - Table: + - Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_string + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + debug_info: + - Version: 4 + Entries: + - AbbrCode: 1 + Values: + - CStr: by_hand + - Value: 0x04 + - CStr: CU1 + - Value: 0x1000 + - Value: 0x4 + - AbbrCode: 0 +... diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-loclists.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-loclists.test new file mode 100644 index 000000000000..09e2cea4993d --- /dev/null +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-loclists.test @@ -0,0 +1,54 @@ +## This test checks the warning message displayed if input file +## contains .debug_loclists section. + +# RUN: yaml2obj %s -o %t.o + +# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o + +# CHECK: [[FILE]]: warning: '.debug_loclists' is not currently supported: file will be skipped + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x0000000000000010 + Content: "FFFFFFFF" + - Name: .debug_loclists + Type: SHT_PROGBITS + Flags: [ ] + Content: "0000000000000000000000" +DWARF: + debug_abbrev: + - Table: + - Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_string + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + debug_info: + - Version: 4 + Entries: + - AbbrCode: 1 + Values: + - CStr: by_hand + - Value: 0x04 + - CStr: CU1 + - Value: 0x1000 + - Value: 0x4 + - AbbrCode: 0 +... diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-macinfo.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-macinfo.test new file mode 100644 index 000000000000..be895cfc6066 --- /dev/null +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-macinfo.test @@ -0,0 +1,62 @@ +## This test checks the warning message displayed if input file +## contains non-empty .debug_macinfo section. Warning message +## should not be displayed if .debug_macinfo is empty. + +# RUN: yaml2obj -D MACINFO_CONTENT="0000" %s -o %t.o + +# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 \ +# RUN: | FileCheck %s -DFILE=%t.o --check-prefix=NOWARN --allow-empty + +# RUN: yaml2obj -D MACINFO_CONTENT="0001" %s -o %t.o + +# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 \ +# RUN: | FileCheck %s -DFILE=%t.o --check-prefix=WARN + +# WARN: [[FILE]]: warning: '.debug_macinfo' is not currently supported: file will be skipped +# NOWARN-NOT: warning + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x0000000000000010 + Content: "FFFFFFFF" + - Name: .debug_macinfo + Type: SHT_PROGBITS + Flags: [ ] + Content: [[MACINFO_CONTENT]] +DWARF: + debug_abbrev: + - Table: + - Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_string + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + debug_info: + - Version: 4 + Entries: + - AbbrCode: 1 + Values: + - CStr: by_hand + - Value: 0x04 + - CStr: CU1 + - Value: 0x1000 + - Value: 0x4 + - AbbrCode: 0 +... diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-macro.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-macro.test new file mode 100644 index 000000000000..4e960217fe8a --- /dev/null +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-macro.test @@ -0,0 +1,54 @@ +## This test checks the warning message displayed if input file +## contains .debug_macro section. + +# RUN: yaml2obj %s -o %t.o + +# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o + +# CHECK: [[FILE]]: warning: '.debug_macro' is not currently supported: file will be skipped + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x0000000000000010 + Content: "FFFFFFFF" + - Name: .debug_macro + Type: SHT_PROGBITS + Flags: [ ] + Content: "0000" +DWARF: + debug_abbrev: + - Table: + - Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_string + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + debug_info: + - Version: 4 + Entries: + - AbbrCode: 1 + Values: + - CStr: by_hand + - Value: 0x04 + - CStr: CU1 + - Value: 0x1000 + - Value: 0x4 + - AbbrCode: 0 +... diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-names.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-names.test new file mode 100644 index 000000000000..a68855294edb --- /dev/null +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-names.test @@ -0,0 +1,54 @@ +## This test checks the warning message displayed if input file +## contains .debug_names section. + +# RUN: yaml2obj %s -o %t.o + +# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o + +# CHECK: [[FILE]]: warning: '.debug_names' is not currently supported: section will be skipped + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x0000000000000010 + Content: "FFFFFFFF" + - Name: .debug_names + Type: SHT_PROGBITS + Flags: [ ] + Content: "0000" +DWARF: + debug_abbrev: + - Table: + - Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_string + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + debug_info: + - Version: 4 + Entries: + - AbbrCode: 1 + Values: + - CStr: by_hand + - Value: 0x04 + - CStr: CU1 + - Value: 0x1000 + - Value: 0x4 + - AbbrCode: 0 +... diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-pubnames.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-pubnames.test new file mode 100644 index 000000000000..3aa42a843aac --- /dev/null +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-pubnames.test @@ -0,0 +1,54 @@ +## This test checks the warning message displayed if input file +## contains .debug_pubnames section. + +# RUN: yaml2obj %s -o %t.o + +# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o + +# CHECK: [[FILE]]: warning: '.debug_pubnames' is not currently supported: section will be skipped + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x0000000000000010 + Content: "FFFFFFFF" + - Name: .debug_pubnames + Type: SHT_PROGBITS + Flags: [ ] + Content: "0000" +DWARF: + debug_abbrev: + - Table: + - Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_string + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + debug_info: + - Version: 4 + Entries: + - AbbrCode: 1 + Values: + - CStr: by_hand + - Value: 0x04 + - CStr: CU1 + - Value: 0x1000 + - Value: 0x4 + - AbbrCode: 0 +... diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-pubtypes.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-pubtypes.test new file mode 100644 index 000000000000..4134349f014f --- /dev/null +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-pubtypes.test @@ -0,0 +1,54 @@ +## This test checks the warning message displayed if input file +## contains .debug_pubtypes section. + +# RUN: yaml2obj %s -o %t.o + +# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o + +# CHECK: [[FILE]]: warning: '.debug_pubtypes' is not currently supported: section will be skipped + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x0000000000000010 + Content: "FFFFFFFF" + - Name: .debug_pubtypes + Type: SHT_PROGBITS + Flags: [ ] + Content: "0000" +DWARF: + debug_abbrev: + - Table: + - Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_string + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + debug_info: + - Version: 4 + Entries: + - AbbrCode: 1 + Values: + - CStr: by_hand + - Value: 0x04 + - CStr: CU1 + - Value: 0x1000 + - Value: 0x4 + - AbbrCode: 0 +... diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-rnglists.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-rnglists.test new file mode 100644 index 000000000000..deea90ffc934 --- /dev/null +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-rnglists.test @@ -0,0 +1,54 @@ +## This test checks the warning message displayed if input file +## contains .debug_rnglists section. + +# RUN: yaml2obj %s -o %t.o + +# RUN: llvm-dwarfutil --garbage-collection %t.o %t1 2>&1 | FileCheck %s -DFILE=%t.o + +# CHECK: [[FILE]]: warning: '.debug_rnglists' is not currently supported: file will be skipped + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x0000000000000010 + Content: "FFFFFFFF" + - Name: .debug_rnglists + Type: SHT_PROGBITS + Flags: [ ] + Content: "0000" +DWARF: + debug_abbrev: + - Table: + - Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_string + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + debug_info: + - Version: 4 + Entries: + - AbbrCode: 1 + Values: + - CStr: by_hand + - Value: 0x04 + - CStr: CU1 + - Value: 0x1000 + - Value: 0x4 + - AbbrCode: 0 +... diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-types.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-types.test new file mode 100644 index 000000000000..ca0a5e2dd17c --- /dev/null +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/warning-skipped-types.test @@ -0,0 +1,6 @@ +## This test checks the warning message displayed if input file +## contains type units. + +# RUN: llvm-dwarfutil --garbage-collection --tombstone=maxpc %p/Inputs/type-units.o %t1 2>&1 | FileCheck %s -DFILE=%p/Inputs/type-units.o + +# CHECK: [[FILE]]: warning: type units are not currently supported: file will be skipped diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp index d5e6f82e1778..5f43680ba498 100644 --- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp +++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp @@ -713,7 +713,8 @@ bool DwarfLinkerForBinary::link(const DebugMap &Map) { } // link debug info for loaded object files. - GeneralLinker.link(); + if (Error E = GeneralLinker.link()) + return error(toString(std::move(E))); StringRef ArchName = Map.getTriple().getArchName(); if (Error E = emitRemarks(Options, Map.getBinaryPath(), ArchName, RL)) diff --git a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp index 458a58c12ca7..3e70f460bc58 100644 --- a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp +++ b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.cpp @@ -8,6 +8,7 @@ #include "DebugInfoLinker.h" #include "Error.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/DWARFLinker/DWARFLinker.h" #include "llvm/DWARFLinker/DWARFStreamer.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" @@ -210,8 +211,29 @@ private: const Options &Opts; }; -bool linkDebugInfo(object::ObjectFile &File, const Options &Options, - raw_pwrite_stream &OutStream) { +static bool knownByDWARFUtil(StringRef SecName) { + return llvm::StringSwitch(SecName) + .Case(".debug_info", true) + .Case(".debug_types", true) + .Case(".debug_abbrev", true) + .Case(".debug_loc", true) + .Case(".debug_loclists", true) + .Case(".debug_frame", true) + .Case(".debug_aranges", true) + .Case(".debug_ranges", true) + .Case(".debug_rnglists", true) + .Case(".debug_line", true) + .Case(".debug_line_str", true) + .Case(".debug_addr", true) + .Case(".debug_macro", true) + .Case(".debug_macinfo", true) + .Case(".debug_str", true) + .Case(".debug_str_offsets", true) + .Default(false); +} + +Error linkDebugInfo(object::ObjectFile &File, const Options &Options, + raw_pwrite_stream &OutStream) { auto ReportWarn = [&](const Twine &Message, StringRef Context, const DWARFDie *Die) { @@ -235,8 +257,11 @@ bool linkDebugInfo(object::ObjectFile &File, const Options &Options, // Create output streamer. DwarfStreamer OutStreamer(OutputFileType::Object, OutStream, nullptr, ReportWarn, ReportWarn); - if (!OutStreamer.init(File.makeTriple(), "")) - return false; + Triple TargetTriple = File.makeTriple(); + if (!OutStreamer.init(TargetTriple, formatv("cannot create a stream for {0}", + TargetTriple.getTriple()) + .str())) + return createStringError(std::errc::invalid_argument, ""); // Create DWARF linker. DWARFLinker DebugInfoLinker(&OutStreamer, DwarfLinkerClient::LLD); @@ -256,6 +281,16 @@ bool linkDebugInfo(object::ObjectFile &File, const Options &Options, std::unique_ptr Context = DWARFContext::create(File); + // Unknown debug sections would be removed. Display warning + // for such sections. + for (SectionName Sec : Context->getDWARFObj().getSectionNames()) { + if (isDebugSection(Sec.Name) && !knownByDWARFUtil(Sec.Name)) + warning( + formatv("'{0}' is not currently supported: section will be skipped", + Sec.Name), + Options.InputFileName); + } + // Add object files to the DWARFLinker. AddresssMapForLinking[0] = std::make_unique(*Context, Options, File); @@ -268,9 +303,11 @@ bool linkDebugInfo(object::ObjectFile &File, const Options &Options, DebugInfoLinker.addObjectFile(*ObjectsForLinking[I]); // Link debug info. - DebugInfoLinker.link(); + if (Error Err = DebugInfoLinker.link()) + return Err; + OutStreamer.finish(); - return true; + return Error::success(); } } // end of namespace dwarfutil diff --git a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.h b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.h index e95c83cb9609..d9d99ffc8747 100644 --- a/llvm/tools/llvm-dwarfutil/DebugInfoLinker.h +++ b/llvm/tools/llvm-dwarfutil/DebugInfoLinker.h @@ -22,8 +22,8 @@ inline bool isDebugSection(StringRef SecName) { SecName == ".gdb_index"; } -bool linkDebugInfo(object::ObjectFile &file, const Options &Options, - raw_pwrite_stream &OutStream); +Error linkDebugInfo(object::ObjectFile &file, const Options &Options, + raw_pwrite_stream &OutStream); } // end of namespace dwarfutil } // end of namespace llvm diff --git a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp index c91674426bbb..a6466be37513 100644 --- a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp +++ b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp @@ -426,16 +426,14 @@ static Error applyCLOptions(const struct Options &Opts, ObjectFile &InputFile) { DebugInfoBits LinkedDebugInfo; raw_svector_ostream OutStream(LinkedDebugInfo); - if (linkDebugInfo(InputFile, Opts, OutStream)) { - if (Error Err = - saveLinkedDebugInfo(Opts, InputFile, std::move(LinkedDebugInfo))) - return Err; + if (Error Err = linkDebugInfo(InputFile, Opts, OutStream)) + return Err; - return Error::success(); - } + if (Error Err = + saveLinkedDebugInfo(Opts, InputFile, std::move(LinkedDebugInfo))) + return Err; - return createStringError(std::errc::invalid_argument, - "possible broken debug info"); + return Error::success(); } else if (Opts.BuildSeparateDebugFile) { if (Error Err = splitDebugIntoSeparateFile(Opts, InputFile)) return Err;