kromanova created this revision. kromanova added reviewers: dblaikie, echristo, probinson. kromanova added a subscriber: cfe-commits. kromanova set the repository for this revision to rL LLVM.
Hello, The compiler always emits .debug_line version 2, though some opcodes from DWARF 3 (e.g. DW_LNS_set_prologue_end, DW_LNS_set_epilogue_begin or DW_LNS_set_isa) and from DWARF 4 could be emitted by the compiler. That's not exactly right. This patch changes version information of .debug_line to exactly match the DWARF version (which is 4 by default). For .debug_line version 4, a new field maximum_operations_per_instruction is emitted. I'm not exactly sure how to set this field correctly for VLIW architectures. Hopefully, there are some experts in the community that could help out (any Hexagon debuginfo developers out there?). I’ve tried a few tools to check if they could handle .debug_line version 4. On a simple testcase, I verified that GDB debugger 7.7 understands .debug_line version 4. Sony’s proprietary debugger can understand it too. I don't have LLDB built, so I haven’t tried it. GCC (older version 4.8.2) still emits version 2 for the .debug_line section, even though the DWARF version is set to 4. I'm not sure about the latest GCC. GNU's readelf (version 2.24) can handle .debug_line version 4. I added 3 new tests debug-line-version2.ll, debug-line-version3.ll and debug-line-version4.ll. The IR is generated from one source using different options (-gdwarf-2, -gdwarf-3 and –gdwarf-4). Any idea how to merge these three tests into one? Let me know what do you think about the patch. Repository: rL LLVM http://reviews.llvm.org/D16697 Files: lib/MC/MCDwarf.cpp test/DebugInfo/AArch64/line-header.ll test/DebugInfo/Generic/debug-line-version2.ll test/DebugInfo/Generic/debug-line-version3.ll test/DebugInfo/Generic/debug-line-version4.ll test/DebugInfo/Generic/empty.ll test/DebugInfo/X86/empty.ll test/DebugInfo/X86/stmt-list-multiple-compile-units.ll test/MC/ELF/debug-line.s test/MC/ELF/debug-line2.s test/MC/ELF/debug-loc.s test/MC/ELF/discriminator.s test/MC/ELF/empty-dwarf-lines.s test/MC/MachO/file.s test/MC/MachO/gen-dwarf.s test/MC/MachO/loc.s
Index: test/MC/MachO/loc.s =================================================================== --- test/MC/MachO/loc.s +++ test/MC/MachO/loc.s @@ -9,27 +9,27 @@ // CHECK: Name: __debug_line (5F 5F 64 65 62 75 67 5F 6C 69 6E 65 00 00 00 00) // CHECK: Segment: __DWARF (5F 5F 44 57 41 52 46 00 00 00 00 00 00 00 00 00) // CHECK: Address: 0x1 -// CHECK: Size: 0x33 +// CHECK: Size: 0x34 // CHECK: Offset: 237 // CHECK: Alignment: 0 -// CHECK: RelocationOffset: 0x120 +// CHECK: RelocationOffset: 0x124 // CHECK: RelocationCount: 1 // CHECK: Type: 0x0 // CHECK: Attributes [ (0x20000) // CHECK: Debug (0x20000) // CHECK: ] // CHECK: Reserved1: 0x0 // CHECK: Reserved2: 0x0 // CHECK: SectionData ( -// CHECK: 0000: 2F000000 02001A00 00000101 FB0E0D00 |/...............| -// CHECK: 0010: 01010101 00000001 00000100 666F6F00 |............foo.| -// CHECK: 0020: 00000000 00050200 00000003 3F010201 |............?...| -// CHECK: 0030: 000101 |...| +// CHECK: 0000: 30000000 04001B00 00000101 01FB0E0D |0...............| +// CHECK: 0010: 00010101 01000000 01000001 00666F6F |.............foo| +// CHECK: 0020: 00000000 00000502 00000000 033F0102 |.............?..| +// CHECK: 0030: 01000101 // CHECK: ) // CHECK: } // CHECK: ] // CHECK: Relocations [ // CHECK: Section __debug_line { -// CHECK: 0x27 0 2 0 GENERIC_RELOC_VANILLA 0 __text +// CHECK: 0x28 0 2 0 GENERIC_RELOC_VANILLA 0 __text // CHECK: } // CHECK: ] Index: test/MC/MachO/gen-dwarf.s =================================================================== --- test/MC/MachO/gen-dwarf.s +++ test/MC/MachO/gen-dwarf.s @@ -89,7 +89,7 @@ // CHECK: .debug_line contents: // CHECK: Line table prologue: // We don't check the total_length as it includes lengths of temp paths -// CHECK: version: 2 +// CHECK: version: 4 // We don't check the prologue_length as it too includes lengths of temp paths // CHECK: min_inst_length: 1 // CHECK: default_is_stmt: 1 Index: test/MC/MachO/file.s =================================================================== --- test/MC/MachO/file.s +++ test/MC/MachO/file.s @@ -8,7 +8,7 @@ // CHECK-NEXT: Name: __debug_line // CHECK-NEXT: Segment: __DWARF // CHECK-NEXT: Address: 0x1 -// CHECK-NEXT: Size: 0x28 +// CHECK-NEXT: Size: 0x29 // CHECK-NEXT: Offset: 237 // CHECK-NEXT: Alignment: 0 // CHECK-NEXT: RelocationOffset: 0x0 @@ -20,8 +20,8 @@ // CHECK-NEXT: Reserved1: 0x0 // CHECK-NEXT: Reserved2: 0x0 // CHECK-NEXT: SectionData ( -// CHECK-NEXT: 0000: 24000000 02001E00 00000101 FB0E0D00 -// CHECK-NEXT: 0010: 01010101 00000001 00000164 69720000 -// CHECK-NEXT: 0020: 666F6F00 01000000 +// CHECK-NEXT: 0000: 25000000 04001F00 00000101 01FB0E0D |%...............| +// CHECK-NEXT: 0010: 00010101 01000000 01000001 64697200 |............dir.| +// CHECK-NEXT: 0020: 00666F6F 00010000 00 |.foo.....| // CHECK-NEXT: ) // CHECK-NEXT: } Index: test/MC/ELF/empty-dwarf-lines.s =================================================================== --- test/MC/ELF/empty-dwarf-lines.s +++ test/MC/ELF/empty-dwarf-lines.s @@ -15,7 +15,7 @@ // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 // CHECK-NEXT: Offset: 0x44 -// CHECK-NEXT: Size: 39 +// CHECK-NEXT: Size: 40 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 1 Index: test/MC/ELF/discriminator.s =================================================================== --- test/MC/ELF/discriminator.s +++ test/MC/ELF/discriminator.s @@ -53,7 +53,7 @@ # CHECK: Relocations [ # CHECK: Section ({{[^ ]+}}) .rel.debug_line { -# CHECK-NEXT: 0x2D R_386_32 .text 0x0 +# CHECK-NEXT: 0x2E R_386_32 .text 0x0 # CHECK-NEXT: } # DWARF-DUMP: Address Line Column File ISA Discriminator Flags Index: test/MC/ELF/debug-loc.s =================================================================== --- test/MC/ELF/debug-loc.s +++ test/MC/ELF/debug-loc.s @@ -15,7 +15,7 @@ // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 // CHECK-NEXT: Offset: -// CHECK-NEXT: Size: 61 +// CHECK-NEXT: Size: 62 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 1 Index: test/MC/ELF/debug-line2.s =================================================================== --- test/MC/ELF/debug-line2.s +++ test/MC/ELF/debug-line2.s @@ -10,16 +10,16 @@ // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 // CHECK-NEXT: Offset: -// CHECK-NEXT: Size: 56 +// CHECK-NEXT: Size: 57 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 1 // CHECK-NEXT: EntrySize: 0 // CHECK-NEXT: SectionData ( -// CHECK-NEXT: 0000: 34000000 02001C00 00000101 FB0E0D00 -// CHECK-NEXT: 0010: 01010101 00000001 00000100 666F6F2E -// CHECK-NEXT: 0020: 63000000 00000009 02000000 00000000 -// CHECK-NEXT: 0030: 00011302 01000101 +// CHECK-NEXT: 0000: 35000000 04001D00 00000101 01FB0E0D |5...............| +// CHECK-NEXT: 0010: 00010101 01000000 01000001 00666F6F |.............foo| +// CHECK-NEXT: 0020: 2E630000 00000000 09020000 00000000 |.c..............| +// CHECK-NEXT: 0030: 00000113 02010001 01 |.........| // CHECK-NEXT: ) // CHECK-NEXT: } Index: test/MC/ELF/debug-line.s =================================================================== --- test/MC/ELF/debug-line.s +++ test/MC/ELF/debug-line.s @@ -18,17 +18,17 @@ // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 // CHECK-NEXT: Offset: -// CHECK-NEXT: Size: 57 +// CHECK-NEXT: Size: 58 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 1 // CHECK-NEXT: EntrySize: 0 // CHECK-NEXT: SectionData ( -// CHECK-NEXT: 0000: 35000000 02001C00 00000101 FB0E0D00 -// CHECK-NEXT: 0010: 01010101 00000001 00000100 666F6F2E -// CHECK-NEXT: 0020: 63000000 00000009 02000000 00000000 -// CHECK-NEXT: 0030: 00154B21 02080001 01 +// CHECK-NEXT: 0000: 36000000 04001D00 00000101 01FB0E0D +// CHECK-NEXT: 0010: 00010101 01000000 01000001 00666F6F +// CHECK-NEXT: 0020: 2E630000 00000000 09020000 00000000 +// CHECK-NEXT: 0030: 0000154B 21020800 0101 // CHECK-NEXT: ) // CHECK-NEXT: } Index: test/DebugInfo/X86/stmt-list-multiple-compile-units.ll =================================================================== --- test/DebugInfo/X86/stmt-list-multiple-compile-units.ll +++ test/DebugInfo/X86/stmt-list-multiple-compile-units.ll @@ -15,7 +15,7 @@ ; CHECK: DW_AT_high_pc [DW_FORM_data4] (0x00000010) ; CHECK: DW_TAG_compile_unit -; CHECK: DW_AT_stmt_list [DW_FORM_sec_offset] (0x0000003c) +; CHECK: DW_AT_stmt_list [DW_FORM_sec_offset] (0x0000003d) ; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000010) ; CHECK: DW_AT_high_pc [DW_FORM_data4] (0x00000009) ; CHECK: DW_TAG_subprogram @@ -25,10 +25,10 @@ ; CHECK: .debug_line contents: ; CHECK-NEXT: Line table prologue: -; CHECK-NEXT: total_length: 0x00000038 +; CHECK-NEXT: total_length: 0x00000039 ; CHECK: file_names[ 1] 0 0x00000000 0x00000000 simple.c ; CHECK: Line table prologue: -; CHECK-NEXT: total_length: 0x00000039 +; CHECK-NEXT: total_length: 0x0000003a ; CHECK: file_names[ 1] 0 0x00000000 0x00000000 simple2.c ; CHECK-NOT: file_names Index: test/DebugInfo/X86/empty.ll =================================================================== --- test/DebugInfo/X86/empty.ll +++ test/DebugInfo/X86/empty.ll @@ -4,7 +4,7 @@ ; Expect no line table entry since there are no functions and file references in this compile unit ; CHECK: .debug_line contents: ; CHECK: Line table prologue: -; CHECK: total_length: 0x00000019 +; CHECK: total_length: 0x0000001a ; CHECK-NOT: file_names[ ; CHECK: .debug_pubnames contents: Index: test/DebugInfo/Generic/empty.ll =================================================================== --- test/DebugInfo/Generic/empty.ll +++ test/DebugInfo/Generic/empty.ll @@ -9,7 +9,7 @@ ; Expect no line table entry since there are no functions and file references in this compile unit ; CHECK: .debug_line contents: ; CHECK: Line table prologue: -; CHECK: total_length: 0x00000019 +; CHECK: total_length: 0x0000001a ; CHECK-NOT: file_names[ ; CHECK: .debug_pubnames contents: Index: test/DebugInfo/Generic/debug-line-version4.ll =================================================================== --- test/DebugInfo/Generic/debug-line-version4.ll +++ test/DebugInfo/Generic/debug-line-version4.ll @@ -0,0 +1,41 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s > %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; IR generated from clang -S -emit-llvm -g -gdwarf-4 and the following testcase: + +; void foo(){ +; } + +; Make sure that when we are generating DWARF version 4, we also generate +; .debug_line section version 4. Additionally check that generate +; max_ops_per_inst in .debug_line section header +; CHECK: Compile Unit: length = {{.*}} version = 0x0004 +; CHECK: Line table prologue: +; CHECK-NEXT: total_length: 0x0000003b +; CHECK-NEXT: version: 4 +; CHECK-NEXT: prologue_length: 0x00000020 +; CHECK: max_ops_per_inst: 1 + +; Function Attrs: nounwind uwtable +define void @_Z3foov() #0 !dbg !4 { +entry: + ret void, !dbg !10 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.9.0 (trunk 258459)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3) +!1 = !DIFile(filename: "test.cpp", directory: "/home/kromanova/ngh/ToT_commit/llvm/test/DebugInfo/Generic") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{null} +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{!"clang version 3.9.0 (trunk 258459)"} +!10 = !DILocation(line: 2, column: 1, scope: !4) Index: test/DebugInfo/Generic/debug-line-version3.ll =================================================================== --- test/DebugInfo/Generic/debug-line-version3.ll +++ test/DebugInfo/Generic/debug-line-version3.ll @@ -0,0 +1,42 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s > %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; IR generated from clang -S -emit-llvm -g -gdwarf-3 and the following testcase: + +; void foo(){ +; } + +; Make sure that when we are generating DWARF version 3, we also generate +; .debug_line section version 3. Additionally check that we don't generate +; max_ops_per_inst in .debug_line section header (since it's only supported +; in DWARF-4 and later). +; CHECK: Compile Unit: length = {{.*}} version = 0x0003 +; CHECK: Line table prologue: +; CHECK-NEXT: total_length: 0x0000003a +; CHECK-NEXT: version: 3 +; CHECK-NEXT: prologue_length: 0x0000001f +; CHECK-NOT: max_ops_per_inst: 1 + +; Function Attrs: nounwind uwtable +define void @_Z3foov() #0 !dbg !4 { +entry: + ret void, !dbg !10 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.9.0 (trunk 258459)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3) +!1 = !DIFile(filename: "test.cpp", directory: "/home/kromanova/ngh/ToT_commit/llvm/test/DebugInfo/Generic") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{null} +!7 = !{i32 2, !"Dwarf Version", i32 3} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{!"clang version 3.9.0 (trunk 258459)"} +!10 = !DILocation(line: 2, column: 1, scope: !4) Index: test/DebugInfo/Generic/debug-line-version2.ll =================================================================== --- test/DebugInfo/Generic/debug-line-version2.ll +++ test/DebugInfo/Generic/debug-line-version2.ll @@ -0,0 +1,42 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s > %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; IR generated from clang -S -emit-llvm -g -gdwarf-2 and the following testcase: + +; void foo(){ +; } + +; Make sure that when we are generating DWARF version 2, we also generate +; .debug_line section version 2. Additionally check that we don't generate +; max_ops_per_inst in .debug_line section header (it's only supported +; in DWARF-4 and later). +; CHECK: Compile Unit: length = {{.*}} version = 0x0002 +; CHECK: Line table prologue: +; CHECK-NEXT: total_length: 0x0000003a +; CHECK-NEXT: version: 2 +; CHECK-NEXT: prologue_length: 0x0000001f +; CHECK-NOT: max_ops_per_inst: 1 + +; Function Attrs: nounwind uwtable +define void @_Z3foov() #0 !dbg !4 { +entry: + ret void, !dbg !10 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.9.0 (trunk 258459)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3) +!1 = !DIFile(filename: "test.cpp", directory: "/home/kromanova/ngh/ToT_commit/llvm/test/DebugInfo/Generic") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, variables: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{null} +!7 = !{i32 2, !"Dwarf Version", i32 2} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{!"clang version 3.9.0 (trunk 258459)"} +!10 = !DILocation(line: 2, column: 1, scope: !4) Index: test/DebugInfo/AArch64/line-header.ll =================================================================== --- test/DebugInfo/AArch64/line-header.ll +++ test/DebugInfo/AArch64/line-header.ll @@ -3,4 +3,4 @@ ; check line table length is correctly calculated for both big and little endian CHECK_LABEL: .debug_line contents: -CHECK: total_length: 0x0000003c +CHECK: total_length: 0x0000003d Index: lib/MC/MCDwarf.cpp =================================================================== --- lib/MC/MCDwarf.cpp +++ lib/MC/MCDwarf.cpp @@ -262,8 +262,8 @@ emitAbsValue(*MCOS, MakeStartMinusEndExpr(*MCOS, *LineStartSym, *LineEndSym, 4), 4); - // Next 2 bytes is the Version, which is Dwarf 2. - MCOS->EmitIntValue(2, 2); + // Next 2 bytes is the Version. + MCOS->EmitIntValue(context.getDwarfVersion(), 2); // Create a symbol for the end of the prologue (to be set when we get there). MCSymbol *ProEndSym = context.createTempSymbol(); // Lprologue_end @@ -278,6 +278,8 @@ // Parameters of the state machine, are next. MCOS->EmitIntValue(context.getAsmInfo()->getMinInstAlignment(), 1); + if (context.getDwarfVersion() >= 4) + MCOS->EmitIntValue(1, 1); MCOS->EmitIntValue(DWARF2_LINE_DEFAULT_IS_STMT, 1); MCOS->EmitIntValue(Params.DWARF2LineBase, 1); MCOS->EmitIntValue(Params.DWARF2LineRange, 1);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits