diff --git a/llvm/test/tools/llvm-dwp/X86/info-v5.s b/llvm/test/tools/llvm-dwp/X86/info-v5.s new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-dwp/X86/info-v5.s @@ -0,0 +1,86 @@ +# this checks llvm-dwp handling of DWARFv5 Info section header. + +# RUN: llvm-mc --filetype=obj --split-dwarf-file=%t.dwo -dwarf-version=5 %s -o %t.o + +# RUN: llvm-dwp %t.dwo -o %t.dwp +# RUN: llvm-dwarfdump -v %t.dwp | FileCheck %s + +#CHECK-DAG: .debug_info.dwo contents: +#CHECK: 0x00000000: Compile Unit: length = 0x00000050 version = 0x0005 unit_type = DW_UT_split_compile abbr_offset = 0x0000 addr_size = 0x08 DWO_id = [[DWOID:.*]] (next unit at 0x00000054) + +# CHECK-DAG: .debug_cu_index contents: +# CHECK: version = 2 slots = 2 +# CHECK: Index Signature INFO ABBREV +# CHECK: 1 [[DWOID]] [0x00000000, 0x00000054) [0x00000000, 0x0000002a) + + .section .debug_info.dwo,"e",@progbits + .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit +.Ldebug_info_dwo_start0: + .short 5 # DWARF version number + .byte 5 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long 0 # Offset Into Abbrev. Section + .quad -1173350285159172090 + .byte 1 # Abbrev [1] 0x14:0x16 DW_TAG_compile_unit + .asciz "clang version 11.0.0" # DW_AT_producer + .short 12 # DW_AT_language + .asciz "int.c" # DW_AT_name + .asciz "int.dwo" # DW_AT_dwo_name + .byte 2 # Abbrev [2] 0x1a:0xb DW_TAG_variable + .asciz "integer" # DW_AT_name + .long 37 # DW_AT_type + # DW_AT_external + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 2 # DW_AT_location + .byte 161 + .byte 0 + .byte 3 # Abbrev [3] 0x25:0x4 DW_TAG_base_type + .asciz "int" # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_dwo_end0: + .section .debug_abbrev.dwo,"e",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 8 # DW_FORM_string + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 8 # DW_FORM_string + .byte 118 # DW_AT_dwo_name + .byte 8 # DW_FORM_string + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 8 # DW_FORM_string + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 8 # DW_FORM_string + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) diff --git a/llvm/test/tools/llvm-dwp/X86/wrong-unit-type-info-v5.s b/llvm/test/tools/llvm-dwp/X86/wrong-unit-type-info-v5.s new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-dwp/X86/wrong-unit-type-info-v5.s @@ -0,0 +1,33 @@ +# RUN: llvm-mc --filetype=obj --split-dwarf-file=%t.dwo -dwarf-version=5 %s -o %t.o +# RUN: not llvm-dwp %t.dwo -o /dev/null 2>&1 | FileCheck %s + +# CHECK: error: {{.*}}: unit type DW_UT_split_compile type not found in debug_info header. Unexpected unit type 0x12 found + .section .debug_info.dwo,"e",@progbits + .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit +.Ldebug_info_dwo_start0: + .short 5 # DWARF version number + .byte 12 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long 0 # Offset Into Abbrev. Section + .quad -1173350285159172090 + .byte 1 # Abbrev [1] 0x14:0x16 DW_TAG_compile_unit + .asciz "clang version 11.0.0" # DW_AT_producer + .short 12 # DW_AT_language + .asciz "int.c" # DW_AT_name + .asciz "int.dwo" # DW_AT_dwo_name + .byte 0 # End Of Children Mark +.Ldebug_info_dwo_end0: + .section .debug_abbrev.dwo,"e",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 8 # DW_FORM_string + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 8 # DW_FORM_string + .byte 118 # DW_AT_dwo_name + .byte 8 # DW_FORM_string + .byte 0 # EOM(1) + .byte 0 # EOM(2) diff --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp --- a/llvm/tools/llvm-dwp/llvm-dwp.cpp +++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp @@ -140,6 +140,8 @@ DataExtractor InfoData(Info, true, 0); dwarf::DwarfFormat Format = dwarf::DwarfFormat::DWARF32; uint64_t Length = InfoData.getU32(&Offset); + CompileUnitIdentifiers ID; + Optional Signature = None; // If the length is 0xffffffff, then this indictes that this is a DWARF 64 // stream and the length is actually encoded into a 64 bit value that follows. if (Length == 0xffffffffU) { @@ -147,9 +149,18 @@ Length = InfoData.getU64(&Offset); } uint16_t Version = InfoData.getU16(&Offset); + if (Version >= 5) { + auto UnitType = InfoData.getU8(&Offset); + if (UnitType != dwarf::DW_UT_split_compile) + return make_error( + std::string("unit type DW_UT_split_compile type not found in " + "debug_info header. Unexpected unit type 0x" + + utostr(UnitType) + " found!")); + } InfoData.getU32(&Offset); // Abbrev offset (should be zero) uint8_t AddrSize = InfoData.getU8(&Offset); - + if (Version >= 5) + Signature = InfoData.getU64(&Offset); uint32_t AbbrCode = InfoData.getULEB128(&Offset); DataExtractor AbbrevData(Abbrev, true, 0); @@ -161,8 +172,6 @@ AbbrevData.getU8(&AbbrevOffset); uint32_t Name; dwarf::Form Form; - CompileUnitIdentifiers ID; - Optional Signature = None; while ((Name = AbbrevData.getULEB128(&AbbrevOffset)) | (Form = static_cast(AbbrevData.getULEB128(&AbbrevOffset))) && (Name != 0 || Form != 0)) { @@ -175,7 +184,8 @@ ID.Name = *EName; break; } - case dwarf::DW_AT_GNU_dwo_name: { + case dwarf::DW_AT_GNU_dwo_name: + case dwarf::DW_AT_dwo_name: { Expected EName = getIndexedString(Form, InfoData, Offset, StrOffsets, Str); if (!EName)