Index: lld/trunk/ELF/InputFiles.cpp =================================================================== --- lld/trunk/ELF/InputFiles.cpp +++ lld/trunk/ELF/InputFiles.cpp @@ -131,7 +131,14 @@ Config->Wordsize); for (std::unique_ptr &CU : Dwarf->compile_units()) { - const DWARFDebugLine::LineTable *LT = Dwarf->getLineTableForUnit(CU.get()); + Expected ExpectedLT = + Dwarf->getLineTableForUnit(CU.get(), warn); + const DWARFDebugLine::LineTable *LT = nullptr; + if (ExpectedLT) + LT = *ExpectedLT; + else + handleAllErrors(ExpectedLT.takeError(), + [](ErrorInfoBase &Err) { warn(Err.message()); }); if (!LT) continue; LineTables.push_back(LT); Index: lld/trunk/test/ELF/Inputs/undef-bad-debug.s =================================================================== --- lld/trunk/test/ELF/Inputs/undef-bad-debug.s +++ lld/trunk/test/ELF/Inputs/undef-bad-debug.s @@ -1,7 +1,77 @@ .section .text,"ax" sym: .quad zed6 - +sym2: + .quad zed7 + +.section .debug_line,"",@progbits +.Lunit: + .long .Lunit_end - .Lunit_start # unit length +.Lunit_start: + .short 4 # version + .long .Lprologue_end - .Lprologue_start # prologue length +.Lprologue_start: + .byte 1 # minimum instruction length + .byte 1 # maximum operatiosn per instruction + .byte 1 # default is_stmt + .byte -5 # line base + .byte 14 # line range + .byte 13 # opcode base + .byte 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 # standard opcode lengths + .asciz "dir" # include directories + .byte 0 + .asciz "undef-bad-debug.s" # file names + .byte 1, 0, 0 + .byte 0 + .byte 0 # extraneous byte +.Lprologue_end: + .byte 0, 9, 2 # DW_LNE_set_address + .quad sym + .byte 3 # DW_LNS_advance_line + .byte 10 + .byte 1 # DW_LNS_copy + .byte 2 # DW_LNS_advance_pc + .byte 8 + .byte 0, 1, 1 # DW_LNE_end_sequence +.Lunit_end: + +.Lunit2: + .long .Lunit2_end - .Lunit2_start # unit length +.Lunit2_start: + .short 4 # version + .long .Lprologue2_end - .Lprologue2_start # prologue length +.Lprologue2_start: + .byte 1 # minimum instruction length + .byte 1 # maximum operatiosn per instruction + .byte 1 # default is_stmt + .byte -5 # line base + .byte 14 # line range + .byte 13 # opcode base + .byte 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 # standard opcode lengths + .asciz "dir2" # include directories + .byte 0 + .asciz "undef-bad-debug2.s" # file names + .byte 1, 0, 0 + .byte 0 +.Lprologue2_end: + .byte 0, 9, 2 # DW_LNE_set_address + .quad sym2 + .byte 3 # DW_LNS_advance_line + .byte 10 + .byte 1 # DW_LNS_copy + .byte 2 # DW_LNS_advance_pc + .byte 8 + .byte 0, 1, 1 # DW_LNE_end_sequence + .byte 0, 9, 2 # DW_LNE_set_address + .quad 0x0badbeef + .byte 3 # DW_LNS_advance_line + .byte 99 + .byte 1 # DW_LNS_copy + .byte 99 # DW_LNS_advance_pc + .byte 119 + # Missing end of sequence. +.Lunit2_end: + .section .debug_info,"",@progbits .long .Lcu_end - .Lcu_start # Length of Unit .Lcu_start: @@ -9,6 +79,7 @@ .long .Lsection_abbrev # Offset Into Abbrev. Section .byte 8 # Address Size (in bytes) .byte 1 # Abbrev [1] 0xb:0x79 DW_TAG_compile_unit + .long .Lunit # DW_AT_stmt_list .byte 2 # Abbrev [2] 0x2a:0x15 DW_TAG_variable .long .Linfo_string # DW_AT_name # DW_AT_external @@ -17,11 +88,28 @@ .byte 0 # End Of Children Mark .Lcu_end: + .long .Lcu2_end - .Lcu2_start # Length of Unit +.Lcu2_start: + .short 4 # DWARF version number + .long .Lsection_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x79 DW_TAG_compile_unit + .long .Lunit2 # DW_AT_stmt_list + .byte 2 # Abbrev [2] 0x2a:0x15 DW_TAG_variable + .long .Linfo2_string # DW_AT_name + # DW_AT_external + .byte 1 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .byte 0 # End Of Children Mark +.Lcu2_end: + .section .debug_abbrev,"",@progbits .Lsection_abbrev: .byte 1 # Abbreviation Code .byte 17 # DW_TAG_compile_unit .byte 1 # DW_CHILDREN_yes + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset .byte 0 # EOM(1) .byte 0 # EOM(2) .byte 2 # Abbreviation Code @@ -42,3 +130,5 @@ .section .debug_str,"MS",@progbits,1 .Linfo_string: .asciz "sym" +.Linfo2_string: + .asciz "sym2" Index: lld/trunk/test/ELF/no-line-parser-errors-if-empty-section.s =================================================================== --- lld/trunk/test/ELF/no-line-parser-errors-if-empty-section.s +++ lld/trunk/test/ELF/no-line-parser-errors-if-empty-section.s @@ -0,0 +1,21 @@ +# REQUIRES: x86 + +# LLD uses the debug data to get information for error messages, if possible. +# However, if the debug line section is empty, we should not attempt to parse +# it, as that would result in errors from the parser. + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: not ld.lld %t.o -o %t.elf 2>&1 | FileCheck %s + +# CHECK-NOT: warning: +# CHECK-NOT: error: +# CHECK: error: undefined symbol: undefined +# CHECK-NEXT: {{.*}}.o:(.text+0x1) +# CHECK-NOT: warning: +# CHECK-NOT: error: + +.globl _start +_start: + callq undefined + +.section .debug_line,"",@progbits Index: lld/trunk/test/ELF/no-line-parser-errors-if-no-section.s =================================================================== --- lld/trunk/test/ELF/no-line-parser-errors-if-no-section.s +++ lld/trunk/test/ELF/no-line-parser-errors-if-no-section.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 + +# LLD uses the debug data to get information for error messages, if possible. +# However, if there is no debug line section, we should not attempt to parse +# it, as that would result in errors from the parser. + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: not ld.lld %t.o -o %t.elf 2>&1 | FileCheck %s + +# CHECK-NOT: warning: +# CHECK-NOT: error: +# CHECK: error: undefined symbol: undefined +# CHECK-NEXT: {{.*}}.o:(.text+0x1) +# CHECK-NOT: warning: +# CHECK-NOT: error: + +.globl _start +_start: + callq undefined Index: lld/trunk/test/ELF/undef.s =================================================================== --- lld/trunk/test/ELF/undef.s +++ lld/trunk/test/ELF/undef.s @@ -34,9 +34,19 @@ # CHECK: >>> referenced by undef-debug.s:11 (dir{{/|\\}}undef-debug.s:11) # CHECK: >>> {{.*}}.o:(.text.2+0x0) +# Show that all line table problems are mentioned as soon as the object's line information +# is requested, even if that particular part of the line information is not currently required. +# CHECK: warning: parsing line table prologue at 0x00000000 should have ended at 0x00000038 but it ended at 0x00000037 +# CHECK: warning: last sequence in debug line table is not terminated! # CHECK: error: undefined symbol: zed6 # CHECK: >>> referenced by {{.*}}tmp4.o:(.text+0x0) +# Show that a problem with one line table's information doesn't affect getting information from +# a different one in the same object. +# CHECK: error: undefined symbol: zed7 +# CHECK: >>> referenced by undef-bad-debug2.s:11 (dir2{{/|\\}}undef-bad-debug2.s:11) +# CHECK: >>> {{.*}}tmp4.o:(.text+0x8) + # RUN: not ld.lld %t.o %t2.a -o %t.exe -no-demangle 2>&1 | \ # RUN: FileCheck -check-prefix=NO-DEMANGLE %s # NO-DEMANGLE: error: undefined symbol: _Z3fooi