From a81909135b7da7710b97124af7d9a49a5746b317 Mon Sep 17 00:00:00 2001 From: Ali Tamur Date: Mon, 25 Mar 2019 21:09:07 +0000 Subject: [PATCH] Revert "[llvm] Prevent duplicate files in debug line header in dwarf 5." This reverts commit 312ab05887d0e2caa29aaf843cefe39379a98d36. My commit broke the build; I will revert and find out what happened. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@356951 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/DebugInfo/DWARF/DWARFDebugLine.h | 2 -- include/llvm/MC/MCContext.h | 2 +- include/llvm/MC/MCDwarf.h | 18 +--------------- lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 1 - lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 1 - lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 1 + lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 20 +++--------------- lib/MC/MCContext.cpp | 5 ++--- lib/MC/MCDwarf.cpp | 11 ---------- test/MC/ARM/dwarf-asm-multiple-sections.s | 17 ++++++--------- test/MC/ELF/debug-mixed-md5.ll | 3 ++- test/MC/ELF/dwarf-file0.s | 6 ++++-- .../tools/llvm-objdump/Inputs/embedded-source | Bin 9528 -> 9936 bytes .../X86/function-sections-line-numbers.s | 9 ++++---- 14 files changed, 26 insertions(+), 70 deletions(-) diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index 6247c31d717..1f36e0daed0 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -275,8 +275,6 @@ 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/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 6beb6463964..c87df5a82ce 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -521,7 +521,7 @@ namespace llvm { } MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) { - return MCDwarfLineTablesCUMap.emplace(CUID, DwarfVersion).first->second; + return MCDwarfLineTablesCUMap[CUID]; } const MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) const { diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 70624d0a4df..991ad525f89 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -218,11 +218,9 @@ struct MCDwarfLineTableHeader { private: bool HasAllMD5 = true; bool HasAnyMD5 = false; - unsigned DwarfVersion; public: - explicit MCDwarfLineTableHeader(unsigned DwarfVersion) : - DwarfVersion(DwarfVersion) {} + MCDwarfLineTableHeader() = default; Expected tryGetFile(StringRef &Directory, StringRef &FileName, MD5::MD5Result *Checksum, @@ -247,17 +245,6 @@ 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, @@ -268,8 +255,6 @@ 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()) @@ -297,7 +282,6 @@ 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/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 683d3245e56..d9addb52376 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -101,7 +101,6 @@ 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/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 226014cf0bb..0e0a5b24864 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -319,7 +319,6 @@ 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/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 5d8e236a6b3..6e547469c24 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -397,6 +397,7 @@ 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/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp index 6ad06a8553e..53420187773 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -1017,28 +1017,14 @@ bool DWARFDebugLine::LineTable::lookupAddressRangeImpl( } bool DWARFDebugLine::LineTable::hasFileAtIndex(uint64_t FileIndex) const { - 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]; + return FileIndex != 0 && FileIndex <= Prologue.FileNames.size(); } Optional DWARFDebugLine::LineTable::getSourceByIndex(uint64_t FileIndex, FileLineInfoKind Kind) const { if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex)) return None; - const FileNameEntry &Entry = getFileNameEntry(FileIndex); + const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1]; if (Optional source = Entry.Source.getAsCString()) return StringRef(*source); return None; @@ -1058,7 +1044,7 @@ bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, std::string &Result) const { if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex)) return false; - const FileNameEntry &Entry = getFileNameEntry(FileIndex); + const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1]; StringRef FileName = Entry.Name.getAsCString().getValue(); if (Kind != FileLineInfoKind::AbsoluteFilePath || isPathAbsoluteOnWindowsOrPosix(FileName)) { diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index 348436f4bd0..49fad131a2c 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -603,8 +603,7 @@ Expected MCContext::getDwarfFile(StringRef Directory, MD5::MD5Result *Checksum, Optional Source, unsigned CUID) { - MCDwarfLineTable &Table = - MCDwarfLineTablesCUMap.emplace(CUID, DwarfVersion).first->second; + MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID]; return Table.tryGetFile(Directory, FileName, Checksum, Source, FileNumber); } @@ -613,7 +612,7 @@ Expected MCContext::getDwarfFile(StringRef Directory, bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) { const MCDwarfLineTable &LineTable = getMCDwarfLineTable(CUID); if (FileNumber == 0) - return getDwarfVersion() >= 5; + return getDwarfVersion() >= 5 && LineTable.hasRootFile(); if (FileNumber >= LineTable.getMCDwarfFiles().size()) return false; diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 73b4d4bcd19..83b6b4f1aa3 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -542,15 +542,6 @@ 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, @@ -570,8 +561,6 @@ 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/test/MC/ARM/dwarf-asm-multiple-sections.s b/test/MC/ARM/dwarf-asm-multiple-sections.s index 39c69c9f7d2..cff8f000731 100644 --- a/test/MC/ARM/dwarf-asm-multiple-sections.s +++ b/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 -dwarf-version 4 -fdebug-compilation-dir=/tmp +// RUN: llvm-mc < %s -triple=armv7-linux-gnueabi -filetype=obj -o %t -g -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 -check-prefix DWARF-DL-4 -DDWVER=4 -DDWFILE=1 %s +// RUN: llvm-dwarfdump --debug-line %t | FileCheck -check-prefix DWARF-DL -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,14 +57,11 @@ b: // DWARF-DL-5: include_directories[ 0] = "/tmp" // DWARF-DL: file_names[ [[DWFILE]]]: // DWARF-DL: name: "{{(|-)}}" -// 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-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: .debug_ranges contents: // DWARF: 00000000 ffffffff 00000000 diff --git a/test/MC/ELF/debug-mixed-md5.ll b/test/MC/ELF/debug-mixed-md5.ll index d48e42c8d12..2ec8141325f 100644 --- a/test/MC/ELF/debug-mixed-md5.ll +++ b/test/MC/ELF/debug-mixed-md5.ll @@ -1,7 +1,8 @@ ; 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 "t1.cpp" +; ASM: .file 1 "{{.+}}" md5 +; ASM: .file 2 "t1.cpp" ; ASM-NOT: md5 ; OBJ: file_names[ 0]: ; OBJ-NOT: md5 diff --git a/test/MC/ELF/dwarf-file0.s b/test/MC/ELF/dwarf-file0.s index f98fdcc2b40..1a3afb6875f 100644 --- a/test/MC/ELF/dwarf-file0.s +++ b/test/MC/ELF/dwarf-file0.s @@ -19,14 +19,16 @@ # CHECK: file_names[ 1]: # CHECK-NEXT: name: "header.h" # CHECK-NEXT: dir_index: 1 -# CHECK-4: file_names[ 2]: -# CHECK-4-NEXT: name: "root.cpp" +# CHECK: file_names[ 2]: +# CHECK-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/test/tools/llvm-objdump/Inputs/embedded-source b/test/tools/llvm-objdump/Inputs/embedded-source index e0f6fea608416f5e5f4887ee9d9fd10bf362f9e4..072b5a90c5c83aadeb6396d0523f57962d6f586e 100644 GIT binary patch literal 9936 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 literal 9528 zcmeHMYit}>6+ScLUE8&@cH)${4I~p9w~naSYuAr;pR;}>V{qCubxNS5UswbC{tIC>{!$7!`nU)^_e@p6-SCgim0U_SDqr>?zfF22;X41MoRF1>cY zx%7K;@eeCUrYA4FsN+m9FPwk2fyjl2kgQ#OJ;MIhws#!hx$gEEFmI!$*YOBPN>rM1Md#PrmYU0-h2;h6bk57B!jm)@IP`t{U- zi()L#zpq_-=E~Zd`N%t--uGL^Pc6MYwe;RNdRW`}hPk+`m?LkN-=?v???mEri4%$Y z6V~$C_4d8Hj3Y?zM!XGrmntZ`wOhKeiS+H|unHV@n8IFrNFPM{O{ABRzJYWnW=hHf zM?qO=S9Z5HHl0-(+euGrn~wNTkbz9~?R{Iae--U-AlpQw{ZVynTR4dhQKUB9iuo-p zcaXwpr2QM}Xr%M&+C)TuvSBpR{Y1!yWsk@#Zc;fUcz;)zHs5$PU{=xB%bqmd>t zpJ`?^Vf(A+C%N28TO+VF0$U@nH3C~Bur&f(BS0fCkMSoZLsE`)nYM~jfX6gLaNDH3 zU!G^Kkusmdc1xLJ8cNst1WbAEq8Nx0ms1QzX+brJz~8T|6^Wiz4I-7Z;;L$pD9&<3 zpH&SaaFuxCIaE?QM^NhY30y5HlSauLm;K>(#H1b%0U|LT!!gmGxU|QxO2|AuD^iZh zatZ&?2%lsBQ-z1d#%|WT$DL%>F6i-|{#ai;*54QJ={umuqp@h8&KkYjS(ta+Y~Cq& zcJ6?FpXZhfU(j9WWVVzo7WDqX;olfc~LCXQ}L0(L8rfeQBY`1_#pv z$$?mWXk_RBq_AfpP{eyupjC3HRE3ISX%*F%~ z9e3cA*FvC5)no_y9;gvR`$6lvy`=@`Vz>>+0BouUC;c!|MN$44*+zsW5oToe5(}EL zS8WUJQOFAHw?6yb_aA>_{5va|orxa~KaXEZvr5NBN=hhvRnxvuLpjv^R7efqs^Y0e z`LJGzlTSM7w3F^B70YhQiKd{pTylGJ#gv`v%@m87oYOm3%saiFoiDq+>+`8MU7pWn zQ?}<=v)P;j;;^1AcwoDk6g^HtYR+~c3;3e_0pkvL3z@nOFo*d8%s?^hU9eCe2Q>_xb1|7inI@N_5o$~R1C73kaJv!^^KLT{$5=My6i-H|y6A zgr7FpA2!%Uh1T=)oG5MIFb`=RQt(DII1hg%?St*SDD)e@i&f!gpDibHx{y%?Yj0U3xhEC6wJDI-m%iVNKjQZdnMgfuzA2|ID3r z4j#N`V%nNcj809ES8)ZODwRd!!E(~JXR~_!X5KJruja|hznVwentOU2nNrc3vkPgA z6RgR*&?=oRSmly~O_v|E6&-LjXa~OI!?mR>b zMbC*QMkjkbI|I>7p&XsFOLGuSpDG~Or=IJV$cVQ_u&~T^ay9`VD%uqFoCOb}^eVBe zD25~I%*mHGmqr9jKEi*CK7x64XXmpitgDE=@DZKQA>%v4J_AMA6sV)lNtQGCZfA?k z+sPyb?JVJ69*24CKC^i{Rf9=W!+c+8Wff;VVIoeV#%%DNR- z4V2dZCkA&kvaL?nq0oq#*FBE6_>mI(->wAGvilP z10}$?P>{-b*q3}C%oF_-W;)9}kx^c#ePf%Lem30>gs!FG@WB^W-==Ch&Q@BxcwZrbW0$&lkMejun2D=N4i)=<1>tZKA>kj(?4Q4^VO!m zll9a0U7doqf5pO}j_l3tK8pU-SEmiOsMw%Gz%vr>RD+QZ+O|r3u>Y;{gM4KZJp0)t z@c}dVjl{DZmj~tRH^ILy@p2d$zM=j7o8T`=eDM1Z);}Tf!T#^;@T;7x)a)~iuco~A zRGZF7e5d^I_F*CIl{_E$yP)-v=WaEAK^}>}&lSnSfQV;@`uKhFh