Index: ELF/InputFiles.h =================================================================== --- ELF/InputFiles.h +++ ELF/InputFiles.h @@ -201,6 +201,9 @@ // single object file, so we cache debugging information in order to // parse it only once for each object file we link. std::unique_ptr DwarfLine; + + // Containing the working directory of the compilation command. + llvm::Optional CompilationDir; }; // LazyObjectFile is analogous to ArchiveFile in the sense that Index: ELF/InputFiles.cpp =================================================================== --- ELF/InputFiles.cpp +++ ELF/InputFiles.cpp @@ -41,11 +41,12 @@ // .text sections (when using -ffunction-section or comdat group) then // LLVM DWARF parser will not be able to parse .debug_line correctly, unless // we assign each section some unique address. This callback method assigns -// each section an address equal to its offset in ELF object file. +// each allocatable section an address equal to its offset in ELF object file. class ObjectInfo : public LoadedObjectInfo { public: uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const override { - return static_cast(Sec).getOffset(); + auto &S = static_cast(Sec); + return (S.getFlags() & ELF::SHF_ALLOC) ? S.getOffset() : 0; } std::unique_ptr clone() const override { return std::unique_ptr(); @@ -69,6 +70,9 @@ // for compilation unit (CU) of interest. We have only one // CU (object file), so offset is always 0. DwarfLine->getOrParseLineTable(LineData, 0); + + if (Dwarf.getNumCompileUnits()) + CompilationDir = Dwarf.getCompileUnitAtIndex(0)->getCompilationDir(); } // Returns source line information for a given offset @@ -88,7 +92,7 @@ // section. See comments for ObjectInfo class. DILineInfo Info; Tbl->getFileLineInfoForAddress( - S->Offset + Offset, nullptr, + S->Offset + Offset, CompilationDir ? CompilationDir->c_str() : nullptr, DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, Info); if (Info.Line == 0) return ""; Index: test/ELF/conflict2.s =================================================================== --- test/ELF/conflict2.s +++ test/ELF/conflict2.s @@ -0,0 +1,120 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o +# RUN: not ld.lld %t1.o %t1.o -o %t2 2>&1 | FileCheck %s + +# CHECK: /home/bar/some_path/foo/1.cpp:1: duplicate symbol 'main' +# CHECK-NEXT: /home/bar/some_path/foo/1.cpp:1: previous definition was here + +# The file below was generated with the following command line: +# clang foo/1.cpp -g -S -o asm.s, called from working directory "/home/bar/some_path". +# asm.s then was reduced manually. +# 1.cpp is a one line file: "int main() { return 0; }" +# That way the linker can extract current working directory of a compilation +# command from DW_AT_comp_dir attribute for providing full path when reporting errors. + +.text +.globl main +main: +.file 1 "foo" "1.cpp" +.loc 1 1 0 + +.section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 4.0.0 (trunk 289927)" +.Linfo_string1: + .asciz "foo/1.cpp" +.Linfo_string2: + .asciz "/home/bar/some_path" +.Linfo_string3: + .asciz "main" +.Linfo_string4: + .asciz "int" + +.section .debug_abbrev,"",@progbits +.Lsection_abbrev: + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 14 # DW_FORM_strp + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 14 # DW_FORM_strp + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 0 # DW_CHILDREN_no + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .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 14 # DW_FORM_strp + .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) + +.section .debug_info,"",@progbits +.Lsection_info: +.Lcu_begin0: + .long 71 # Length of Unit + .short 4 # DWARF version number + .long .Lsection_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x40 DW_TAG_compile_unit + .long .Linfo_string0 # DW_AT_producer + .short 4 # DW_AT_language + .long .Linfo_string1 # DW_AT_name + .long .Lline_table_start0 # DW_AT_stmt_list + .long .Linfo_string2 # DW_AT_comp_dir + .quad 0 # DW_AT_low_pc + .long 0 # DW_AT_high_pc + .byte 2 # Abbrev [2] 0x2a:0x19 DW_TAG_subprogram + .quad 0 # DW_AT_low_pc + .long 0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .long .Linfo_string3 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .long 67 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x43:0x7 DW_TAG_base_type + .long .Linfo_string4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark + +.Lline_table_start0: