From cb4c19f3157b02e6d0169949626767f9051c76b6 Mon Sep 17 00:00:00 2001 From: James Henderson Date: Wed, 7 Mar 2018 15:22:58 +0000 Subject: [PATCH] [ELF] Prevent crash when reporting errors if debug line cannot be parsed LLD uses the debug info and debug line sections to determine the location of e.g. references to undefined symbols, when producing error messages. In the event that debug info was present, but debug line parsing failed for some reason, then a nullptr would end up being dereferenced by the location-lookup code. Differential Revision: https://reviews.llvm.org/D44205 Reviewers: grimar llvm-svn: 326899 --- lld/ELF/InputFiles.cpp | 2 ++ lld/test/ELF/Inputs/undef-bad-debug.s | 44 +++++++++++++++++++++++++++ lld/test/ELF/undef.s | 8 +++-- 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 lld/test/ELF/Inputs/undef-bad-debug.s diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 04034aee4fa4..3b1448ab8cc9 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -126,6 +126,8 @@ template void ObjFile::initializeDwarf() { // CU (object file), so offset is always 0. const DWARFDebugLine::LineTable *LT = DwarfLine->getOrParseLineTable(LineData, 0, Dwarf, nullptr); + if (!LT) + return; // Return if there is no debug information about CU available. if (!Dwarf.getNumCompileUnits()) diff --git a/lld/test/ELF/Inputs/undef-bad-debug.s b/lld/test/ELF/Inputs/undef-bad-debug.s new file mode 100644 index 000000000000..c887b28ab335 --- /dev/null +++ b/lld/test/ELF/Inputs/undef-bad-debug.s @@ -0,0 +1,44 @@ +.section .text,"ax" +sym: + .quad zed6 + +.section .debug_info,"",@progbits + .long .Lcu_end - .Lcu_start # Length of Unit +.Lcu_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 + .byte 2 # Abbrev [2] 0x2a:0x15 DW_TAG_variable + .long .Linfo_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 +.Lcu_end: + +.section .debug_abbrev,"",@progbits +.Lsection_abbrev: + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .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 14 # DW_FORM_strp + .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 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + +.section .debug_str,"MS",@progbits,1 +.Linfo_string: + .asciz "sym" diff --git a/lld/test/ELF/undef.s b/lld/test/ELF/undef.s index 49f84108f64a..aabcbbc08216 100644 --- a/lld/test/ELF/undef.s +++ b/lld/test/ELF/undef.s @@ -2,9 +2,10 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef.s -o %t2.o # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef-debug.s -o %t3.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef-bad-debug.s -o %t4.o # RUN: llvm-ar rc %t2.a %t2.o -# RUN: not ld.lld %t.o %t2.a %t3.o -o %t.exe 2>&1 | FileCheck %s -# RUN: not ld.lld -pie %t.o %t2.a %t3.o -o %t.exe 2>&1 | FileCheck %s +# RUN: not ld.lld %t.o %t2.a %t3.o %t4.o -o %t.exe 2>&1 | FileCheck %s +# RUN: not ld.lld -pie %t.o %t2.a %t3.o %t4.o -o %t.exe 2>&1 | FileCheck %s # CHECK: error: undefined symbol: foo # CHECK: >>> referenced by undef.s @@ -33,6 +34,9 @@ # CHECK: >>> referenced by undef-debug.s:11 (dir{{/|\\}}undef-debug.s:11) # CHECK: >>> {{.*}}.o:(.text.2+0x0) +# CHECK: error: undefined symbol: zed6 +# CHECK: >>> referenced by {{.*}}tmp4.o:(.text+0x0) + # 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