[llvm] r334710 - [DWARFv5] Tolerate files not all having an MD5 checksum.

Paul Robinson via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 14 06:38:21 PDT 2018


Author: probinson
Date: Thu Jun 14 06:38:20 2018
New Revision: 334710

URL: http://llvm.org/viewvc/llvm-project?rev=334710&view=rev
Log:
[DWARFv5] Tolerate files not all having an MD5 checksum.

In some cases, for example when compiling a preprocessed file, the
front-end is not able to provide an MD5 checksum for all files. When
that happens, omit the MD5 checksums from the final DWARF, because
DWARF doesn't have a way to indicate that some but not all files have
a checksum.

When assembling a .s file, and some but not all .file directives
provide an MD5 checksum, issue a warning and don't emit MD5 into the
DWARF.

Fixes PR37623.

Differential Revision: https://reviews.llvm.org/D48135

Added:
    llvm/trunk/test/MC/ELF/debug-mixed-md5.ll
Modified:
    llvm/trunk/include/llvm/MC/MCContext.h
    llvm/trunk/include/llvm/MC/MCDwarf.h
    llvm/trunk/lib/MC/MCAsmStreamer.cpp
    llvm/trunk/lib/MC/MCDwarf.cpp
    llvm/trunk/lib/MC/MCParser/AsmParser.cpp
    llvm/trunk/test/CodeGen/Generic/dwarf-md5.ll
    llvm/trunk/test/CodeGen/Generic/dwarf-source.ll
    llvm/trunk/test/MC/ELF/debug-md5-err.s

Modified: llvm/trunk/include/llvm/MC/MCContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCContext.h?rev=334710&r1=334709&r2=334710&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCContext.h (original)
+++ llvm/trunk/include/llvm/MC/MCContext.h Thu Jun 14 06:38:20 2018
@@ -550,6 +550,11 @@ namespace llvm {
                                             Source);
     }
 
+    /// Reports whether MD5 checksum usage is consistent (all-or-none).
+    bool isDwarfMD5UsageConsistent(unsigned CUID) const {
+      return getMCDwarfLineTable(CUID).isMD5UsageConsistent();
+    }
+
     /// Saves the information from the currently parsed dwarf .loc directive
     /// and sets DwarfLocSeen.  When the next instruction is assembled an entry
     /// in the line number table with this information and the address of the

Modified: llvm/trunk/include/llvm/MC/MCDwarf.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDwarf.h?rev=334710&r1=334709&r2=334710&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCDwarf.h (original)
+++ llvm/trunk/include/llvm/MC/MCDwarf.h Thu Jun 14 06:38:20 2018
@@ -215,9 +215,12 @@ struct MCDwarfLineTableHeader {
   StringMap<unsigned> SourceIdMap;
   StringRef CompilationDir;
   MCDwarfFile RootFile;
-  bool HasMD5 = false;
   bool HasSource = false;
+private:
+  bool HasAllMD5 = true;
+  bool HasAnyMD5 = false;
 
+public:
   MCDwarfLineTableHeader() = default;
 
   Expected<unsigned> tryGetFile(StringRef &Directory, StringRef &FileName,
@@ -231,6 +234,17 @@ struct MCDwarfLineTableHeader {
   Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params,
        ArrayRef<char> SpecialOpcodeLengths,
        Optional<MCDwarfLineStr> &LineStr) const;
+  void resetMD5Usage() {
+    HasAllMD5 = true;
+    HasAnyMD5 = false;
+  }
+  void trackMD5Usage(bool MD5Used) {
+    HasAllMD5 &= MD5Used;
+    HasAnyMD5 |= MD5Used;
+  }
+  bool isMD5UsageConsistent() const {
+    return MCDwarfFiles.empty() || (HasAllMD5 == HasAnyMD5);
+  }
 
 private:
   void emitV2FileDirTables(MCStreamer *MCOS) const;
@@ -251,7 +265,7 @@ public:
     Header.RootFile.DirIndex = 0;
     Header.RootFile.Checksum = Checksum;
     Header.RootFile.Source = Source;
-    Header.HasMD5 = (Checksum != nullptr);
+    Header.trackMD5Usage(Checksum);
     Header.HasSource = Source.hasValue();
   }
 
@@ -294,10 +308,19 @@ public:
     Header.RootFile.DirIndex = 0;
     Header.RootFile.Checksum = Checksum;
     Header.RootFile.Source = Source;
-    Header.HasMD5 = (Checksum != nullptr);
+    Header.trackMD5Usage(Checksum);
     Header.HasSource = Source.hasValue();
   }
 
+  void resetRootFile() {
+    assert(Header.MCDwarfFiles.empty());
+    Header.resetMD5Usage();
+    Header.HasSource = false;
+  }
+
+  // Report whether MD5 usage has been consistent (all-or-none).
+  bool isMD5UsageConsistent() const { return Header.isMD5UsageConsistent(); }
+
   MCSymbol *getLabel() const {
     return Header.Label;
   }

Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=334710&r1=334709&r2=334710&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Thu Jun 14 06:38:20 2018
@@ -1171,6 +1171,9 @@ void MCAsmStreamer::emitDwarfFile0Direct
   // .file 0 is new for DWARF v5.
   if (getContext().getDwarfVersion() < 5)
     return;
+  // Inform MCDwarf about the root file.
+  getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
+                                      Source);
 
   SmallString<128> Str;
   raw_svector_ostream OS1(Str);

Modified: llvm/trunk/lib/MC/MCDwarf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=334710&r1=334709&r2=334710&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCDwarf.cpp (original)
+++ llvm/trunk/lib/MC/MCDwarf.cpp Thu Jun 14 06:38:20 2018
@@ -350,7 +350,7 @@ void MCDwarfLineTableHeader::emitV2FileD
 }
 
 static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile,
-                               bool HasMD5, bool HasSource,
+                               bool EmitMD5, bool HasSource,
                                Optional<MCDwarfLineStr> &LineStr) {
   assert(!DwarfFile.Name.empty());
   if (LineStr)
@@ -360,7 +360,7 @@ static void emitOneV5FileEntry(MCStreame
     MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator.
   }
   MCOS->EmitULEB128IntValue(DwarfFile.DirIndex); // Directory number.
-  if (HasMD5) {
+  if (EmitMD5) {
     MD5::MD5Result *Cksum = DwarfFile.Checksum;
     MCOS->EmitBinaryData(
         StringRef(reinterpret_cast<const char *>(Cksum->Bytes.data()),
@@ -410,7 +410,7 @@ void MCDwarfLineTableHeader::emitV5FileD
   // directory index.  We don't track file size/timestamp so don't emit them
   // in the v5 table.  Emit MD5 checksums and source if we have them.
   uint64_t Entries = 2;
-  if (HasMD5)
+  if (HasAllMD5)
     Entries += 1;
   if (HasSource)
     Entries += 1;
@@ -420,7 +420,7 @@ void MCDwarfLineTableHeader::emitV5FileD
                                     : dwarf::DW_FORM_string);
   MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_directory_index);
   MCOS->EmitULEB128IntValue(dwarf::DW_FORM_udata);
-  if (HasMD5) {
+  if (HasAllMD5) {
     MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_MD5);
     MCOS->EmitULEB128IntValue(dwarf::DW_FORM_data16);
   }
@@ -435,9 +435,9 @@ void MCDwarfLineTableHeader::emitV5FileD
   // explicitly, replicate file #1.
   MCOS->EmitULEB128IntValue(MCDwarfFiles.size());
   emitOneV5FileEntry(MCOS, RootFile.Name.empty() ? MCDwarfFiles[1] : RootFile,
-                     HasMD5, HasSource, LineStr);
+                     HasAllMD5, HasSource, LineStr);
   for (unsigned i = 1; i < MCDwarfFiles.size(); ++i)
-    emitOneV5FileEntry(MCOS, MCDwarfFiles[i], HasMD5, HasSource, LineStr);
+    emitOneV5FileEntry(MCOS, MCDwarfFiles[i], HasAllMD5, HasSource, LineStr);
 }
 
 std::pair<MCSymbol *, MCSymbol *>
@@ -554,9 +554,10 @@ MCDwarfLineTableHeader::tryGetFile(Strin
     Directory = "";
   }
   assert(!FileName.empty());
-  // If any files have an MD5 checksum or embedded source, they all must.
+  // Keep track of whether any or all files have an MD5 checksum.
+  // If any files have embedded source, they all must.
   if (MCDwarfFiles.empty()) {
-    HasMD5 = (Checksum != nullptr);
+    trackMD5Usage(Checksum);
     HasSource = (Source != None);
   }
   if (FileNumber == 0) {
@@ -582,10 +583,6 @@ MCDwarfLineTableHeader::tryGetFile(Strin
     return make_error<StringError>("file number already allocated",
                                    inconvertibleErrorCode());
 
-  // If any files have an MD5 checksum, they all must.
-  if (HasMD5 != (Checksum != nullptr))
-    return make_error<StringError>("inconsistent use of MD5 checksums",
-                                   inconvertibleErrorCode());
   // If any files have embedded source, they all must.
   if (HasSource != (Source != None))
     return make_error<StringError>("inconsistent use of embedded source",
@@ -625,8 +622,7 @@ MCDwarfLineTableHeader::tryGetFile(Strin
   File.Name = FileName;
   File.DirIndex = DirIndex;
   File.Checksum = Checksum;
-  if (Checksum)
-    HasMD5 = true;
+  trackMD5Usage(Checksum);
   File.Source = Source;
   if (Source)
     HasSource = true;

Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=334710&r1=334709&r2=334710&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Thu Jun 14 06:38:20 2018
@@ -177,6 +177,9 @@ private:
   /// Are we parsing ms-style inline assembly?
   bool ParsingInlineAsm = false;
 
+  /// Did we already inform the user about inconsistent MD5 usage?
+  bool ReportedInconsistentMD5 = false;
+
 public:
   AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
             const MCAsmInfo &MAI, unsigned CB);
@@ -3337,7 +3340,11 @@ bool AsmParser::parseDirectiveFile(SMLoc
 
   // In case there is a -g option as well as debug info from directive .file,
   // we turn off the -g option, directly use the existing debug info instead.
-  getContext().setGenDwarfForAssembly(false);
+  // Also reset any implicit ".file 0" for the assembler source.
+  if (Ctx.getGenDwarfForAssembly()) {
+    Ctx.getMCDwarfLineTable(0).resetRootFile();
+    Ctx.setGenDwarfForAssembly(false);
+  }
 
   if (FileNumber == -1)
     getStreamer().EmitFileDirective(Filename);
@@ -3364,6 +3371,12 @@ bool AsmParser::parseDirectiveFile(SMLoc
         return Error(DirectiveLoc, toString(FileNumOrErr.takeError()));
       FileNumber = FileNumOrErr.get();
     }
+    // Alert the user if there are some .file directives with MD5 and some not.
+    // But only do that once.
+    if (!ReportedInconsistentMD5 && !Ctx.isDwarfMD5UsageConsistent(0)) {
+      ReportedInconsistentMD5 = true;
+      return Warning(DirectiveLoc, "inconsistent use of MD5 checksums");
+    }
   }
 
   return false;

Modified: llvm/trunk/test/CodeGen/Generic/dwarf-md5.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/dwarf-md5.ll?rev=334710&r1=334709&r2=334710&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Generic/dwarf-md5.ll (original)
+++ llvm/trunk/test/CodeGen/Generic/dwarf-md5.ll Thu Jun 14 06:38:20 2018
@@ -5,21 +5,21 @@
 ; XFAIL: darwin
 
 ; REQUIRES: object-emission
-; RUN: %llc_dwarf -dwarf-version 4 -filetype=asm -o - %s | FileCheck %s --check-prefixes=ASM,ASM-4
-; RUN: %llc_dwarf -dwarf-version 5 -filetype=asm -o - %s | FileCheck %s --check-prefixes=ASM,ASM-5
+; RUN: %llc_dwarf -dwarf-version 4 -filetype=asm -o - %s | FileCheck %s --check-prefix=ASM-4
+; RUN: %llc_dwarf -dwarf-version 5 -filetype=asm -o - %s | FileCheck %s --check-prefix=ASM-5
 ; RUN: %llc_dwarf -dwarf-version 4 -filetype=obj -o %t4.o %s
 ; RUN: llvm-dwarfdump -debug-line %t4.o | FileCheck %s --check-prefix=OBJ
 ; RUN: %llc_dwarf -dwarf-version 5 -filetype=obj -o %t5.o %s
 ; RUN: llvm-dwarfdump -debug-line %t5.o | FileCheck %s --check-prefixes=OBJ,OBJ-5
 
 ; ASM-4-NOT: .file 0
-; ASM-5: .file 0 "/scratch{{.*[/\\]}}t.c" md5 0x00000000000000000000000000000000
-; ASM: .file 1 "/scratch{{.*[/\\]}}t1.h"
+; ASM-4: .file 1 "/scratch{{.*[/\\]}}t1.h"
 ; ASM-4-NOT:  md5
-; ASM-5-SAME: md5 0x11111111111111111111111111111111
-; ASM: .file 2 "/scratch{{.*[/\\]}}t2.h"
+; ASM-4: .file 2 "/scratch{{.*[/\\]}}t2.h"
 ; ASM-4-NOT:  md5
-; ASM-5-SAME: md5 0x22222222222222222222222222222222
+; ASM-5: .file 0 "/scratch{{.*[/\\]}}t.c" md5 0x00000000000000000000000000000000
+; ASM-5: .file 1 "t1.h" md5 0x11111111111111111111111111111111
+; ASM-5: .file 2 "t2.h" md5 0x22222222222222222222222222222222
 
 ; OBJ-5: file_names[ 0]:
 ; OBJ-5-NEXT: name: "t.c"

Modified: llvm/trunk/test/CodeGen/Generic/dwarf-source.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/dwarf-source.ll?rev=334710&r1=334709&r2=334710&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Generic/dwarf-source.ll (original)
+++ llvm/trunk/test/CodeGen/Generic/dwarf-source.ll Thu Jun 14 06:38:20 2018
@@ -5,16 +5,18 @@
 ; XFAIL: darwin
 
 ; REQUIRES: object-emission
-; RUN: %llc_dwarf -dwarf-version 4 -filetype=asm -o - %s | FileCheck %s --check-prefix=ASM
-; RUN: %llc_dwarf -dwarf-version 5 -filetype=asm -o - %s | FileCheck %s --check-prefixes=ASM,ASM-5
+; RUN: %llc_dwarf -dwarf-version 4 -filetype=asm -o - %s | FileCheck %s --check-prefix=ASM-4
+; RUN: %llc_dwarf -dwarf-version 5 -filetype=asm -o - %s | FileCheck %s --check-prefix=ASM-5
 ; RUN: %llc_dwarf -dwarf-version 4 -filetype=obj -o %t4.o %s
 ; RUN: llvm-dwarfdump -debug-line %t4.o | FileCheck %s --check-prefixes=OBJ,OBJ-4
 ; RUN: %llc_dwarf -dwarf-version 5 -filetype=obj -o %t5.o %s
 ; RUN: llvm-dwarfdump -debug-line %t5.o | FileCheck %s --check-prefixes=OBJ,OBJ-5
 
+; ASM-4: .file 1 "/test{{.*[/\\]}}t1.h" source "11111111111111111111111111111111"
+; ASM-4: .file 2 "/test{{.*[/\\]}}t2.h" source "22222222222222222222222222222222"
 ; ASM-5: .file 0 "/test{{.*[/\\]}}t.c" source "00000000000000000000000000000000"
-; ASM: .file 1 "/test{{.*[/\\]}}t1.h" source "11111111111111111111111111111111"
-; ASM: .file 2 "/test{{.*[/\\]}}t2.h" source "22222222222222222222222222222222"
+; ASM-5: .file 1 "t1.h" source "11111111111111111111111111111111"
+; ASM-5: .file 2 "t2.h" source "22222222222222222222222222222222"
 
 ; OBJ-5: file_names[ 0]:
 ; OBJ-5-NEXT: name: "t.c"

Modified: llvm/trunk/test/MC/ELF/debug-md5-err.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/debug-md5-err.s?rev=334710&r1=334709&r2=334710&view=diff
==============================================================================
--- llvm/trunk/test/MC/ELF/debug-md5-err.s (original)
+++ llvm/trunk/test/MC/ELF/debug-md5-err.s Thu Jun 14 06:38:20 2018
@@ -22,5 +22,5 @@
         .file "baz" md5 0xffeeddccbbaa99887766554433221100
 
 # Inconsistent use of MD5 option. Note: .file 1 did not supply one.
-# CHECK: [[@LINE+1]]:{{[0-9]+}}: error: inconsistent use of MD5 checksums
+# CHECK: [[@LINE+1]]:{{[0-9]+}}: warning: inconsistent use of MD5 checksums
         .file 5 "bax" md5 0xffeeddccbbaa99887766554433221100

Added: llvm/trunk/test/MC/ELF/debug-mixed-md5.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/debug-mixed-md5.ll?rev=334710&view=auto
==============================================================================
--- llvm/trunk/test/MC/ELF/debug-mixed-md5.ll (added)
+++ llvm/trunk/test/MC/ELF/debug-mixed-md5.ll Thu Jun 14 06:38:20 2018
@@ -0,0 +1,44 @@
+; 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-NOT: md5
+; OBJ: file_names[ 0]:
+; OBJ-NOT: md5
+;
+; Generated from this source (see PR37623):
+;
+; #define a(...) template __VA_ARGS__;
+; template <class> class b {};
+; a(class b<int>)
+; # 1 ""
+; int c;
+
+; ModuleID = 't1.cpp'
+source_filename = "t1.cpp"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+ at c = global i32 0, align 4, !dbg !0
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!12, !13, !14}
+!llvm.ident = !{!15}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "c", scope: !2, file: !3, line: 1, type: !10, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 7.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !11)
+!3 = !DIFile(filename: "<stdin>", directory: "/home/probinson/projects/scratch", checksumkind: CSK_MD5, checksum: "9252ff18ee25a08c2b4216b21b5d66d4")
+!4 = !{}
+!5 = !{!6}
+!6 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "b<int>", file: !7, line: 3, size: 8, flags: DIFlagTypePassByValue, elements: !4, templateParams: !8, identifier: "_ZTS1bIiE")
+!7 = !DIFile(filename: "t1.cpp", directory: "/home/probinson/projects/scratch")
+!8 = !{!9}
+!9 = !DITemplateTypeParameter(type: !10)
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!0}
+!12 = !{i32 2, !"Dwarf Version", i32 5}
+!13 = !{i32 2, !"Debug Info Version", i32 3}
+!14 = !{i32 1, !"wchar_size", i32 4}
+!15 = !{!"clang version 7.0.0 "}




More information about the llvm-commits mailing list