diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index 1f36e0daed0c..6247c31d7176 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -275,6 +275,8 @@ public: SequenceVector Sequences; private: + const llvm::DWARFDebugLine::FileNameEntry & + getFileNameEntry(uint64_t Index) const; uint32_t findRowInSeq(const DWARFDebugLine::Sequence &Seq, object::SectionedAddress Address) const; Optional diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h index c87df5a82ce2..6beb64639645 100644 --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -521,7 +521,7 @@ namespace llvm { } MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) { - return MCDwarfLineTablesCUMap[CUID]; + return MCDwarfLineTablesCUMap.emplace(CUID, DwarfVersion).first->second; } const MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) const { diff --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h index 991ad525f89c..70624d0a4df5 100644 --- a/llvm/include/llvm/MC/MCDwarf.h +++ b/llvm/include/llvm/MC/MCDwarf.h @@ -218,9 +218,11 @@ struct MCDwarfLineTableHeader { private: bool HasAllMD5 = true; bool HasAnyMD5 = false; + unsigned DwarfVersion; public: - MCDwarfLineTableHeader() = default; + explicit MCDwarfLineTableHeader(unsigned DwarfVersion) : + DwarfVersion(DwarfVersion) {} Expected tryGetFile(StringRef &Directory, StringRef &FileName, MD5::MD5Result *Checksum, @@ -245,6 +247,17 @@ public: return MCDwarfFiles.empty() || (HasAllMD5 == HasAnyMD5); } + void setRootFile(StringRef Directory, StringRef FileName, + MD5::MD5Result *Checksum, Optional Source) { + CompilationDir = Directory; + RootFile.Name = FileName; + RootFile.DirIndex = 0; + RootFile.Checksum = Checksum; + RootFile.Source = Source; + trackMD5Usage(Checksum); + HasSource = Source.hasValue(); + } + private: void emitV2FileDirTables(MCStreamer *MCOS) const; void emitV5FileDirTables(MCStreamer *MCOS, Optional &LineStr, @@ -255,6 +268,8 @@ class MCDwarfDwoLineTable { MCDwarfLineTableHeader Header; public: + MCDwarfDwoLineTable(unsigned DwarfVersion) : Header(DwarfVersion) {} + void maybeSetRootFile(StringRef Directory, StringRef FileName, MD5::MD5Result *Checksum, Optional Source) { if (!Header.RootFile.Name.empty()) @@ -282,6 +297,7 @@ class MCDwarfLineTable { MCLineSection MCLineSections; public: + MCDwarfLineTable(unsigned DwarfVersion) : Header(DwarfVersion) {} // This emits the Dwarf file and the line tables for all Compile Units. static void Emit(MCObjectStreamer *MCOS, MCDwarfLineTableParams Params); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index d9addb52376a..683d3245e560 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -101,6 +101,7 @@ class DwarfCompileUnit final : public DwarfUnit { } public: + unsigned getDwarfVersion() const { return DD->getDwarfVersion(); } DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 0e0a5b248647..226014cf0bb4 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -319,6 +319,7 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) : DebugHandlerBase(A), DebugLocs(A->OutStreamer->isVerboseAsm()), InfoHolder(A, "info_string", DIEValueAllocator), SkeletonHolder(A, "skel_string", DIEValueAllocator), + SplitTypeUnitFileTable(A->getDwarfVersion()), IsDarwin(A->TM.getTargetTriple().isOSDarwin()) { const Triple &TT = Asm->TM.getTargetTriple(); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 6e547469c24c..5d8e236a6b36 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -397,7 +397,6 @@ void DwarfUnit::addSourceLine(DIE &Die, unsigned Line, const DIFile *File) { return; unsigned FileID = getOrCreateSourceID(File); - assert(FileID && "Invalid file id"); addUInt(Die, dwarf::DW_AT_decl_file, None, FileID); addUInt(Die, dwarf::DW_AT_decl_line, None, Line); } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp index 534201877730..6ad06a8553ea 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -1017,14 +1017,28 @@ bool DWARFDebugLine::LineTable::lookupAddressRangeImpl( } bool DWARFDebugLine::LineTable::hasFileAtIndex(uint64_t FileIndex) const { - return FileIndex != 0 && FileIndex <= Prologue.FileNames.size(); + uint16_t DwarfVersion = Prologue.getVersion(); + assert(DwarfVersion != 0 && "LineTable has no dwarf version information"); + if (DwarfVersion >= 5) + return FileIndex < Prologue.FileNames.size(); + else + return FileIndex != 0 && FileIndex <= Prologue.FileNames.size(); +} +const llvm::DWARFDebugLine::FileNameEntry & +DWARFDebugLine::LineTable::getFileNameEntry(uint64_t Index) const { + uint16_t DwarfVersion = Prologue.getVersion(); + assert(DwarfVersion != 0 && "LineTable has no dwarf version information"); + if (DwarfVersion >= 5) + return Prologue.FileNames[Index]; + else + return Prologue.FileNames[Index - 1]; } Optional DWARFDebugLine::LineTable::getSourceByIndex(uint64_t FileIndex, FileLineInfoKind Kind) const { if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex)) return None; - const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1]; + const FileNameEntry &Entry = getFileNameEntry(FileIndex); if (Optional source = Entry.Source.getAsCString()) return StringRef(*source); return None; @@ -1044,7 +1058,7 @@ bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, std::string &Result) const { if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex)) return false; - const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1]; + const FileNameEntry &Entry = getFileNameEntry(FileIndex); StringRef FileName = Entry.Name.getAsCString().getValue(); if (Kind != FileLineInfoKind::AbsoluteFilePath || isPathAbsoluteOnWindowsOrPosix(FileName)) { diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp index 49fad131a2c7..348436f4bd08 100644 --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -603,7 +603,8 @@ Expected MCContext::getDwarfFile(StringRef Directory, MD5::MD5Result *Checksum, Optional Source, unsigned CUID) { - MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID]; + MCDwarfLineTable &Table = + MCDwarfLineTablesCUMap.emplace(CUID, DwarfVersion).first->second; return Table.tryGetFile(Directory, FileName, Checksum, Source, FileNumber); } @@ -612,7 +613,7 @@ Expected MCContext::getDwarfFile(StringRef Directory, bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) { const MCDwarfLineTable &LineTable = getMCDwarfLineTable(CUID); if (FileNumber == 0) - return getDwarfVersion() >= 5 && LineTable.hasRootFile(); + return getDwarfVersion() >= 5; if (FileNumber >= LineTable.getMCDwarfFiles().size()) return false; diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index 83b6b4f1aa3c..73b4d4bcd198 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -542,6 +542,15 @@ Expected MCDwarfLineTable::tryGetFile(StringRef &Directory, return Header.tryGetFile(Directory, FileName, Checksum, Source, FileNumber); } +bool isRootFile(const MCDwarfFile &RootFile, StringRef &Directory, + StringRef &FileName, MD5::MD5Result *Checksum) { + if (RootFile.Name.empty() || RootFile.Name != FileName.data()) + return false; + if (!RootFile.Checksum) + return !Checksum; + return *RootFile.Checksum == *Checksum; +} + Expected MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, StringRef &FileName, @@ -561,6 +570,8 @@ MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, trackMD5Usage(Checksum); HasSource = (Source != None); } + if (isRootFile(RootFile, Directory, FileName, Checksum) && DwarfVersion >= 5) + return 0; if (FileNumber == 0) { // File numbers start with 1 and/or after any file numbers // allocated by inline-assembler .file directives. diff --git a/llvm/test/MC/ARM/dwarf-asm-multiple-sections.s b/llvm/test/MC/ARM/dwarf-asm-multiple-sections.s index cff8f0007311..39c69c9f7d23 100644 --- a/llvm/test/MC/ARM/dwarf-asm-multiple-sections.s +++ b/llvm/test/MC/ARM/dwarf-asm-multiple-sections.s @@ -2,9 +2,9 @@ // RUN: llvm-dwarfdump -v %t | FileCheck -check-prefix DWARF -check-prefix DWARF45 %s // RUN: llvm-dwarfdump --debug-line %t | FileCheck -check-prefix DWARF-DL -check-prefix DWARF-DL-5 -DDWVER=5 -DDWFILE=0 %s // RUN: llvm-objdump -r %t | FileCheck -check-prefix RELOC -check-prefix RELOC5 %s -// RUN: llvm-mc < %s -triple=armv7-linux-gnueabi -filetype=obj -o %t -g -fdebug-compilation-dir=/tmp +// RUN: llvm-mc < %s -triple=armv7-linux-gnueabi -filetype=obj -o %t -g -dwarf-version 4 -fdebug-compilation-dir=/tmp // RUN: llvm-dwarfdump -v %t | FileCheck -check-prefix DWARF -check-prefix DWARF45 %s -// RUN: llvm-dwarfdump --debug-line %t | FileCheck -check-prefix DWARF-DL -DDWVER=4 -DDWFILE=1 %s +// RUN: llvm-dwarfdump --debug-line %t | FileCheck -check-prefix DWARF-DL -check-prefix DWARF-DL-4 -DDWVER=4 -DDWFILE=1 %s // RUN: llvm-objdump -r %t | FileCheck -check-prefix RELOC -check-prefix RELOC4 %s // RUN: llvm-mc < %s -triple=armv7-linux-gnueabi -filetype=obj -o %t -g -dwarf-version 3 -fdebug-compilation-dir=/tmp // RUN: llvm-dwarfdump -v %t | FileCheck -check-prefix DWARF -check-prefix DWARF3 %s @@ -57,11 +57,14 @@ b: // DWARF-DL-5: include_directories[ 0] = "/tmp" // DWARF-DL: file_names[ [[DWFILE]]]: // DWARF-DL: name: "{{(|-)}}" -// DWARF-DL: 0x0000000000000000 17 0 1 0 0 is_stmt -// DWARF-DL-NEXT: 0x0000000000000004 17 0 1 0 0 is_stmt end_sequence -// DWARF-DL-NEXT: 0x0000000000000000 21 0 1 0 0 is_stmt -// DWARF-DL-NEXT: 0x0000000000000004 21 0 1 0 0 is_stmt end_sequence - +// DWARF-DL-5: 0x0000000000000000 17 0 0 0 0 is_stmt +// DWARF-DL-5-NEXT: 0x0000000000000004 17 0 0 0 0 is_stmt end_sequence +// DWARF-DL-5-NEXT: 0x0000000000000000 21 0 0 0 0 is_stmt +// DWARF-DL-5-NEXT: 0x0000000000000004 21 0 0 0 0 is_stmt end_sequence +// DWARF-DL-4: 0x0000000000000000 17 0 1 0 0 is_stmt +// DWARF-DL-4-NEXT: 0x0000000000000004 17 0 1 0 0 is_stmt end_sequence +// DWARF-DL-4-NEXT: 0x0000000000000000 21 0 1 0 0 is_stmt +// DWARF-DL-4-NEXT: 0x0000000000000004 21 0 1 0 0 is_stmt end_sequence // DWARF: .debug_ranges contents: // DWARF: 00000000 ffffffff 00000000 diff --git a/llvm/test/MC/ELF/debug-mixed-md5.ll b/llvm/test/MC/ELF/debug-mixed-md5.ll index 2ec8141325f8..d48e42c8d121 100644 --- a/llvm/test/MC/ELF/debug-mixed-md5.ll +++ b/llvm/test/MC/ELF/debug-mixed-md5.ll @@ -1,8 +1,7 @@ ; RUN: %llc_dwarf -filetype=asm -dwarf-version=5 %s -o - | FileCheck %s -check-prefix=ASM ; RUN: %llc_dwarf -filetype=obj -dwarf-version=5 %s -o - | llvm-dwarfdump -debug-line - | FileCheck %s -check-prefix=OBJ ; ASM: .file 0 "{{.+}}" md5 -; ASM: .file 1 "{{.+}}" md5 -; ASM: .file 2 "t1.cpp" +; ASM: .file 1 "t1.cpp" ; ASM-NOT: md5 ; OBJ: file_names[ 0]: ; OBJ-NOT: md5 diff --git a/llvm/test/MC/ELF/dwarf-file0.s b/llvm/test/MC/ELF/dwarf-file0.s index 1a3afb6875fd..f98fdcc2b40d 100644 --- a/llvm/test/MC/ELF/dwarf-file0.s +++ b/llvm/test/MC/ELF/dwarf-file0.s @@ -19,16 +19,14 @@ # CHECK: file_names[ 1]: # CHECK-NEXT: name: "header.h" # CHECK-NEXT: dir_index: 1 -# CHECK: file_names[ 2]: -# CHECK-NEXT: name: "root.cpp" +# CHECK-4: file_names[ 2]: +# CHECK-4-NEXT: name: "root.cpp" # CHECK-4-NEXT: dir_index: 2 -# CHECK-5-NEXT: dir_index: 0 # ASM-NOT: .file # ASM-5: .file 0 "/test" "root.cpp" # ASM: .file 1 "/include" "header.h" # ASM-4: .file 2 "/test" "root.cpp" -# ASM-5: .file 2 "root.cpp" # ASM-NOT: .file # WARN: file 0 not supported prior to DWARF-5 diff --git a/llvm/test/tools/llvm-objdump/Inputs/embedded-source b/llvm/test/tools/llvm-objdump/Inputs/embedded-source index 072b5a90c5c8..e0f6fea60841 100644 Binary files a/llvm/test/tools/llvm-objdump/Inputs/embedded-source and b/llvm/test/tools/llvm-objdump/Inputs/embedded-source differ diff --git a/llvm/test/tools/llvm-objdump/X86/function-sections-line-numbers.s b/llvm/test/tools/llvm-objdump/X86/function-sections-line-numbers.s index b932a5d3f32f..46607440cb9b 100644 --- a/llvm/test/tools/llvm-objdump/X86/function-sections-line-numbers.s +++ b/llvm/test/tools/llvm-objdump/X86/function-sections-line-numbers.s @@ -30,8 +30,7 @@ _Z2f1v: # @_Z2f1v .Lfunc_begin0: .file 0 "/home/avl" "test.cpp" md5 0xefae234cc05b45384d782316d3a5d338 - .file 1 "test.cpp" md5 0xefae234cc05b45384d782316d3a5d338 - .loc 1 1 0 # test.cpp:1:0 + .loc 0 1 0 # test.cpp:1:0 .cfi_startproc # %bb.0: # %entry pushq %rbp @@ -40,7 +39,7 @@ _Z2f1v: # @_Z2f1v movq %rsp, %rbp .cfi_def_cfa_register %rbp .Ltmp0: - .loc 1 1 12 prologue_end # test.cpp:1:12 + .loc 0 1 12 prologue_end # test.cpp:1:12 popq %rbp .cfi_def_cfa %rsp, 8 retq @@ -55,7 +54,7 @@ _Z2f1v: # @_Z2f1v .type _Z2f2v,@function _Z2f2v: # @_Z2f2v .Lfunc_begin1: - .loc 1 2 0 # test.cpp:2:0 + .loc 0 2 0 # test.cpp:2:0 .cfi_startproc # %bb.0: # %entry pushq %rbp @@ -64,7 +63,7 @@ _Z2f2v: # @_Z2f2v movq %rsp, %rbp .cfi_def_cfa_register %rbp .Ltmp2: - .loc 1 2 12 prologue_end # test.cpp:2:12 + .loc 0 2 12 prologue_end # test.cpp:2:12 popq %rbp .cfi_def_cfa %rsp, 8 retq