[llvm] r322134 - [DWARFv5] MC support for MD5 file checksums

Paul Robinson via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 9 15:31:48 PST 2018


Author: probinson
Date: Tue Jan  9 15:31:48 2018
New Revision: 322134

URL: http://llvm.org/viewvc/llvm-project?rev=322134&view=rev
Log:
[DWARFv5] MC support for MD5 file checksums

Extend .file directive syntax to allow specifying an MD5 checksum for
the source file.  Emit the checksums in DWARF v5 line tables.

Added:
    llvm/trunk/test/MC/ELF/debug-md5-err.s
    llvm/trunk/test/MC/ELF/debug-md5.s
Modified:
    llvm/trunk/include/llvm/MC/MCContext.h
    llvm/trunk/include/llvm/MC/MCDwarf.h
    llvm/trunk/include/llvm/MC/MCStreamer.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h
    llvm/trunk/lib/MC/MCAsmStreamer.cpp
    llvm/trunk/lib/MC/MCContext.cpp
    llvm/trunk/lib/MC/MCDwarf.cpp
    llvm/trunk/lib/MC/MCParser/AsmParser.cpp
    llvm/trunk/lib/MC/MCStreamer.cpp

Modified: llvm/trunk/include/llvm/MC/MCContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCContext.h?rev=322134&r1=322133&r2=322134&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCContext.h (original)
+++ llvm/trunk/include/llvm/MC/MCContext.h Tue Jan  9 15:31:48 2018
@@ -23,6 +23,7 @@
 #include "llvm/MC/SectionKind.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/MD5.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cassert>
@@ -489,7 +490,8 @@ namespace llvm {
 
     /// Creates an entry in the dwarf file and directory tables.
     unsigned getDwarfFile(StringRef Directory, StringRef FileName,
-                          unsigned FileNumber, unsigned CUID);
+                          unsigned FileNumber, MD5::MD5Result *Checksum,
+                          unsigned CUID);
 
     bool isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID = 0);
 

Modified: llvm/trunk/include/llvm/MC/MCDwarf.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDwarf.h?rev=322134&r1=322133&r2=322134&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCDwarf.h (original)
+++ llvm/trunk/include/llvm/MC/MCDwarf.h Tue Jan  9 15:31:48 2018
@@ -20,6 +20,7 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/MC/MCSection.h"
+#include "llvm/Support/MD5.h"
 #include <cassert>
 #include <cstdint>
 #include <string>
@@ -50,6 +51,10 @@ struct MCDwarfFile {
 
   // \brief The index into the list of directory names for this file name.
   unsigned DirIndex;
+
+  /// The MD5 checksum, if there is one. Non-owning pointer to data allocated
+  /// in MCContext.
+  MD5::MD5Result *Checksum = nullptr;
 };
 
 /// \brief Instances of this class represent the information from a
@@ -203,11 +208,12 @@ struct MCDwarfLineTableHeader {
   SmallVector<MCDwarfFile, 3> MCDwarfFiles;
   StringMap<unsigned> SourceIdMap;
   StringRef CompilationDir;
+  bool HasMD5 = false;
 
   MCDwarfLineTableHeader() = default;
 
   unsigned getFile(StringRef &Directory, StringRef &FileName,
-                   unsigned FileNumber = 0);
+                   MD5::MD5Result *Checksum, unsigned FileNumber = 0);
   std::pair<MCSymbol *, MCSymbol *> Emit(MCStreamer *MCOS,
                                          MCDwarfLineTableParams Params) const;
   std::pair<MCSymbol *, MCSymbol *>
@@ -223,8 +229,9 @@ public:
     Header.CompilationDir = CompilationDir;
   }
 
-  unsigned getFile(StringRef Directory, StringRef FileName) {
-    return Header.getFile(Directory, FileName);
+  unsigned getFile(StringRef Directory, StringRef FileName,
+                   MD5::MD5Result *Checksum) {
+    return Header.getFile(Directory, FileName, Checksum);
   }
 
   void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params) const;
@@ -242,7 +249,7 @@ public:
   void EmitCU(MCObjectStreamer *MCOS, MCDwarfLineTableParams Params) const;
 
   unsigned getFile(StringRef &Directory, StringRef &FileName,
-                   unsigned FileNumber = 0);
+                   MD5::MD5Result *Checksum, unsigned FileNumber = 0);
 
   MCSymbol *getLabel() const {
     return Header.Label;

Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=322134&r1=322133&r2=322134&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Tue Jan  9 15:31:48 2018
@@ -23,6 +23,7 @@
 #include "llvm/MC/MCLinkerOptimizationHint.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/MC/MCWinEH.h"
+#include "llvm/Support/MD5.h"
 #include "llvm/Support/SMLoc.h"
 #include "llvm/Support/TargetParser.h"
 #include <cassert>
@@ -754,6 +755,7 @@ public:
   /// implements the DWARF2 '.file 4 "foo.c"' assembler directive.
   virtual unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
                                           StringRef Filename,
+                                          MD5::MD5Result *Checksum = nullptr,
                                           unsigned CUID = 0);
 
   /// \brief This implements the DWARF2 '.loc fileno lineno ...' assembler

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp?rev=322134&r1=322133&r2=322134&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Tue Jan  9 15:31:48 2018
@@ -95,14 +95,15 @@ void DwarfCompileUnit::addLocalLabelAddr
 }
 
 unsigned DwarfCompileUnit::getOrCreateSourceID(StringRef FileName,
-                                               StringRef DirName) {
+                                               StringRef DirName,
+                                               MD5::MD5Result *Checksum) {
   // If we print assembly, we can't separate .file entries according to
   // compile units. Thus all files will belong to the default compile unit.
 
   // FIXME: add a better feature test than hasRawTextSupport. Even better,
   // extend .file to support this.
   return Asm->OutStreamer->EmitDwarfFileDirective(
-      0, DirName, FileName,
+      0, DirName, FileName, Checksum,
       Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID());
 }
 
@@ -443,7 +444,7 @@ DIE *DwarfCompileUnit::constructInlinedS
   // Add the call site information to the DIE.
   const DILocation *IA = Scope->getInlinedAt();
   addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None,
-          getOrCreateSourceID(IA->getFilename(), IA->getDirectory()));
+          getOrCreateSourceID(IA->getFilename(), IA->getDirectory(), nullptr));
   addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, IA->getLine());
   if (IA->getDiscriminator() && DD->getDwarfVersion() >= 4)
     addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, None,

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h?rev=322134&r1=322133&r2=322134&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h Tue Jan  9 15:31:48 2018
@@ -141,7 +141,8 @@ public:
 
   DwarfCompileUnit &getCU() override { return *this; }
 
-  unsigned getOrCreateSourceID(StringRef FileName, StringRef DirName) override;
+  unsigned getOrCreateSourceID(StringRef FileName, StringRef DirName,
+                               MD5::MD5Result *Checksum) override;
 
   void addImportedEntity(const DIImportedEntity* IE) {
     DIScope *Scope = IE->getScope();

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=322134&r1=322133&r2=322134&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Jan  9 15:31:48 2018
@@ -1378,7 +1378,7 @@ void DwarfDebug::recordSourceLine(unsign
 
     unsigned CUID = Asm->OutStreamer->getContext().getDwarfCompileUnitID();
     Src = static_cast<DwarfCompileUnit &>(*InfoHolder.getUnits()[CUID])
-              .getOrCreateSourceID(Fn, Dir);
+              .getOrCreateSourceID(Fn, Dir, nullptr);
   }
   Asm->OutStreamer->EmitDwarfLocDirective(Src, Line, Col, Flags, 0,
                                           Discriminator, Fn);
@@ -1975,7 +1975,8 @@ void DwarfDebug::emitMacroFile(DIMacroFi
   Asm->EmitULEB128(F.getLine());
   DIFile *File = F.getFile();
   unsigned FID =
-      U.getOrCreateSourceID(File->getFilename(), File->getDirectory());
+      U.getOrCreateSourceID(File->getFilename(), File->getDirectory(),
+                            nullptr); // FIXME: MD5?
   Asm->EmitULEB128(FID);
   handleMacroNodes(F.getElements(), U);
   Asm->EmitULEB128(dwarf::DW_MACINFO_end_file);

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp?rev=322134&r1=322133&r2=322134&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp Tue Jan  9 15:31:48 2018
@@ -263,9 +263,12 @@ void DwarfUnit::addSectionOffset(DIE &Di
     addUInt(Die, Attribute, dwarf::DW_FORM_data4, Integer);
 }
 
-unsigned DwarfTypeUnit::getOrCreateSourceID(StringRef FileName, StringRef DirName) {
-  return SplitLineTable ? SplitLineTable->getFile(DirName, FileName)
-                        : getCU().getOrCreateSourceID(FileName, DirName);
+unsigned DwarfTypeUnit::getOrCreateSourceID(StringRef FileName,
+                                            StringRef DirName,
+                                            MD5::MD5Result *Checksum) {
+  return SplitLineTable
+             ? SplitLineTable->getFile(DirName, FileName, Checksum)
+             : getCU().getOrCreateSourceID(FileName, DirName, Checksum);
 }
 
 void DwarfUnit::addOpAddress(DIELoc &Die, const MCSymbol *Sym) {
@@ -340,7 +343,7 @@ void DwarfUnit::addSourceLine(DIE &Die,
   if (Line == 0)
     return;
 
-  unsigned FileID = getOrCreateSourceID(File, Directory);
+  unsigned FileID = getOrCreateSourceID(File, Directory, nullptr);
   assert(FileID && "Invalid file id");
   addUInt(Die, dwarf::DW_AT_decl_file, None, FileID);
   addUInt(Die, dwarf::DW_AT_decl_line, None, Line);
@@ -1161,9 +1164,10 @@ bool DwarfUnit::applySubprogramDefinitio
     // Look at the Decl's linkage name only if we emitted it.
     if (DD->useAllLinkageNames())
       DeclLinkageName = SPDecl->getLinkageName();
-    unsigned DeclID =
-        getOrCreateSourceID(SPDecl->getFilename(), SPDecl->getDirectory());
-    unsigned DefID = getOrCreateSourceID(SP->getFilename(), SP->getDirectory());
+    unsigned DeclID = getOrCreateSourceID(SPDecl->getFilename(),
+                                          SPDecl->getDirectory(), nullptr);
+    unsigned DefID =
+        getOrCreateSourceID(SP->getFilename(), SP->getDirectory(), nullptr);
     if (DeclID != DefID)
       addUInt(SPDie, dwarf::DW_AT_decl_file, None, DefID);
 

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h?rev=322134&r1=322133&r2=322134&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h Tue Jan  9 15:31:48 2018
@@ -308,7 +308,8 @@ protected:
 
   /// Look up the source ID with the given directory and source file names. If
   /// none currently exists, create a new ID and insert it in the line table.
-  virtual unsigned getOrCreateSourceID(StringRef File, StringRef Directory) = 0;
+  virtual unsigned getOrCreateSourceID(StringRef File, StringRef Directory,
+                                       MD5::MD5Result *Checksum) = 0;
 
   /// Look in the DwarfDebug map for the MDNode that corresponds to the
   /// reference.
@@ -358,7 +359,8 @@ class DwarfTypeUnit final : public Dwarf
   DwarfCompileUnit &CU;
   MCDwarfDwoLineTable *SplitLineTable;
 
-  unsigned getOrCreateSourceID(StringRef File, StringRef Directory) override;
+  unsigned getOrCreateSourceID(StringRef File, StringRef Directory,
+                               MD5::MD5Result *Checksum) override;
   bool isDwoUnit() const override;
 
 public:

Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=322134&r1=322133&r2=322134&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Tue Jan  9 15:31:48 2018
@@ -212,6 +212,7 @@ public:
   void EmitFileDirective(StringRef Filename) override;
   unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
                                   StringRef Filename,
+                                  MD5::MD5Result *Checksum = 0,
                                   unsigned CUID = 0) override;
   void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
                              unsigned Column, unsigned Flags,
@@ -1068,12 +1069,13 @@ void MCAsmStreamer::EmitFileDirective(St
 unsigned MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo,
                                                StringRef Directory,
                                                StringRef Filename,
+                                               MD5::MD5Result *Checksum,
                                                unsigned CUID) {
   assert(CUID == 0);
 
   MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
   unsigned NumFiles = Table.getMCDwarfFiles().size();
-  FileNo = Table.getFile(Directory, Filename, FileNo);
+  FileNo = Table.getFile(Directory, Filename, Checksum, FileNo);
   if (FileNo == 0)
     return 0;
   if (NumFiles == Table.getMCDwarfFiles().size())

Modified: llvm/trunk/lib/MC/MCContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCContext.cpp?rev=322134&r1=322133&r2=322134&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCContext.cpp (original)
+++ llvm/trunk/lib/MC/MCContext.cpp Tue Jan  9 15:31:48 2018
@@ -535,9 +535,10 @@ MCSubtargetInfo &MCContext::getSubtarget
 /// error and zero is returned and the client reports the error, else the
 /// allocated file number is returned.  The file numbers may be in any order.
 unsigned MCContext::getDwarfFile(StringRef Directory, StringRef FileName,
-                                 unsigned FileNumber, unsigned CUID) {
+                                 unsigned FileNumber, MD5::MD5Result *Checksum,
+                                 unsigned CUID) {
   MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID];
-  return Table.getFile(Directory, FileName, FileNumber);
+  return Table.getFile(Directory, FileName, Checksum, FileNumber);
 }
 
 /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it

Modified: llvm/trunk/lib/MC/MCDwarf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=322134&r1=322133&r2=322134&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCDwarf.cpp (original)
+++ llvm/trunk/lib/MC/MCDwarf.cpp Tue Jan  9 15:31:48 2018
@@ -284,7 +284,7 @@ static void
 emitV5FileDirTables(MCStreamer *MCOS,
                     const SmallVectorImpl<std::string> &MCDwarfDirs,
                     const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles,
-                    StringRef CompilationDir) {
+                    StringRef CompilationDir, bool HasMD5) {
   // The directory format, which is just inline null-terminated strings.
   MCOS->EmitIntValue(1, 1);
   MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_path);
@@ -300,20 +300,29 @@ emitV5FileDirTables(MCStreamer *MCOS,
 
   // The file format, which is the inline null-terminated filename and a
   // directory index.  We don't track file size/timestamp so don't emit them
-  // in the v5 table.
-  // FIXME: Arrange to emit MD5 signatures for the source files.
-  MCOS->EmitIntValue(2, 1);
+  // in the v5 table.  Emit MD5 checksums if we have them.
+  MCOS->EmitIntValue(HasMD5 ? 3 : 2, 1);
   MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_path);
   MCOS->EmitULEB128IntValue(dwarf::DW_FORM_string);
   MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_directory_index);
   MCOS->EmitULEB128IntValue(dwarf::DW_FORM_udata);
-  // Then the list of file names. These start at 1 for some reason.
+  if (HasMD5) {
+    MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_MD5);
+    MCOS->EmitULEB128IntValue(dwarf::DW_FORM_data16);
+  }
+  // Then the list of file names. These start at 1.
   MCOS->EmitULEB128IntValue(MCDwarfFiles.size() - 1);
   for (unsigned i = 1; i < MCDwarfFiles.size(); ++i) {
     assert(!MCDwarfFiles[i].Name.empty());
     MCOS->EmitBytes(MCDwarfFiles[i].Name); // FileName and...
     MCOS->EmitBytes(StringRef("\0", 1));   // its null terminator.
     MCOS->EmitULEB128IntValue(MCDwarfFiles[i].DirIndex); // Directory number.
+    if (HasMD5) {
+      MD5::MD5Result *Cksum = MCDwarfFiles[i].Checksum;
+      MCOS->EmitBinaryData(
+          StringRef(reinterpret_cast<const char *>(Cksum->Bytes.data()),
+                    Cksum->Bytes.size()));
+    }
   }
 }
 
@@ -384,7 +393,8 @@ MCDwarfLineTableHeader::Emit(MCStreamer
   // Put out the directory and file tables.  The formats vary depending on
   // the version.
   if (LineTableVersion >= 5)
-    emitV5FileDirTables(MCOS, MCDwarfDirs, MCDwarfFiles, CompilationDir);
+    emitV5FileDirTables(MCOS, MCDwarfDirs, MCDwarfFiles, CompilationDir,
+                        HasMD5);
   else
     emitV2FileDirTables(MCOS, MCDwarfDirs, MCDwarfFiles);
 
@@ -409,12 +419,14 @@ void MCDwarfLineTable::EmitCU(MCObjectSt
 }
 
 unsigned MCDwarfLineTable::getFile(StringRef &Directory, StringRef &FileName,
+                                   MD5::MD5Result *Checksum,
                                    unsigned FileNumber) {
-  return Header.getFile(Directory, FileName, FileNumber);
+  return Header.getFile(Directory, FileName, Checksum, FileNumber);
 }
 
 unsigned MCDwarfLineTableHeader::getFile(StringRef &Directory,
                                          StringRef &FileName,
+                                         MD5::MD5Result *Checksum,
                                          unsigned FileNumber) {
   if (Directory == CompilationDir)
     Directory = "";
@@ -445,6 +457,10 @@ unsigned MCDwarfLineTableHeader::getFile
   if (!File.Name.empty())
     return 0;
 
+  // If any files have an MD5 checksum, they all must.
+  if (FileNumber > 1)
+    assert(HasMD5 == (Checksum != nullptr));
+
   if (Directory.empty()) {
     // Separate the directory part from the basename of the FileName.
     StringRef tFileName = sys::path::filename(FileName);
@@ -478,6 +494,9 @@ unsigned MCDwarfLineTableHeader::getFile
 
   File.Name = FileName;
   File.DirIndex = DirIndex;
+  File.Checksum = Checksum;
+  if (Checksum)
+    HasMD5 = true;
 
   // return the allocated FileNumber.
   return FileNumber;

Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=322134&r1=322133&r2=322134&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Tue Jan  9 15:31:48 2018
@@ -50,6 +50,7 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MD5.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/SMLoc.h"
@@ -3294,8 +3295,8 @@ bool AsmParser::parseDirectiveAlign(bool
 }
 
 /// parseDirectiveFile
-/// ::= .file [number] filename
-/// ::= .file number directory filename
+/// ::= .file filename
+/// ::= .file number [directory] filename [md5 checksum]
 bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
   // FIXME: I'm not sure what this is.
   int64_t FileNumber = -1;
@@ -3331,19 +3332,43 @@ bool AsmParser::parseDirectiveFile(SMLoc
     Filename = Path;
   }
 
-  if (parseToken(AsmToken::EndOfStatement,
-                 "unexpected token in '.file' directive"))
-    return true;
+  std::string Checksum;
+  if (!parseOptionalToken(AsmToken::EndOfStatement)) {
+    StringRef Keyword;
+    if (check(getTok().isNot(AsmToken::Identifier),
+              "unexpected token in '.file' directive") ||
+        parseIdentifier(Keyword) ||
+        check(Keyword != "md5", "unexpected token in '.file' directive"))
+      return true;
+    if (getLexer().is(AsmToken::String) &&
+        check(FileNumber == -1, "MD5 checksum specified, but no file number"))
+      return true;
+    if (check(getTok().isNot(AsmToken::String),
+              "unexpected token in '.file' directive") ||
+        parseEscapedString(Checksum) ||
+        check(Checksum.size() != 32, "invalid MD5 checksum specified") ||
+        parseToken(AsmToken::EndOfStatement,
+                   "unexpected token in '.file' directive"))
+      return true;
+  }
 
   if (FileNumber == -1)
     getStreamer().EmitFileDirective(Filename);
   else {
+    MD5::MD5Result *CKMem = nullptr;
+    if (!Checksum.empty()) {
+      Checksum = fromHex(Checksum);
+      if (check(Checksum.size() != 16, "invalid MD5 checksum specified"))
+        return true;
+      CKMem = (MD5::MD5Result *)Ctx.allocate(sizeof(MD5::MD5Result), 1);
+      memcpy(&CKMem->Bytes, Checksum.data(), 16);
+    }
     // If there is -g option as well as debug info from directive file,
     // we turn off -g option, directly use the existing debug info instead.
     if (getContext().getGenDwarfForAssembly())
       getContext().setGenDwarfForAssembly(false);
-    else if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename) ==
-        0)
+    else if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory,
+                                                  Filename, CKMem) == 0)
       return Error(FileNumberLoc, "file number already allocated");
   }
 

Modified: llvm/trunk/lib/MC/MCStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=322134&r1=322133&r2=322134&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCStreamer.cpp Tue Jan  9 15:31:48 2018
@@ -194,8 +194,10 @@ void MCStreamer::EmitZeros(uint64_t NumB
 
 unsigned MCStreamer::EmitDwarfFileDirective(unsigned FileNo,
                                             StringRef Directory,
-                                            StringRef Filename, unsigned CUID) {
-  return getContext().getDwarfFile(Directory, Filename, FileNo, CUID);
+                                            StringRef Filename,
+                                            MD5::MD5Result *Checksum,
+                                            unsigned CUID) {
+  return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum, CUID);
 }
 
 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,

Added: 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=322134&view=auto
==============================================================================
--- llvm/trunk/test/MC/ELF/debug-md5-err.s (added)
+++ llvm/trunk/test/MC/ELF/debug-md5-err.s Tue Jan  9 15:31:48 2018
@@ -0,0 +1,21 @@
+# RUN: not llvm-mc -triple x86_64-unknown-unknown -dwarf-version 5 -filetype=asm %s -o /dev/null 2>&1 | FileCheck %s
+
+# This is syntactically legal, looks like no checksum provided.
+# CHECK-NOT: [[@LINE+1]]:{{[0-9]+}}: error:
+        .file 1 "dir1/foo" "00112233445566778899aabbccddeeff"
+
+# Missing md5 keyword.
+# CHECK: [[@LINE+1]]:{{[0-9]+}}: error: unexpected token in '.file' directive
+        .file 2 "dir1" "foo" "00112233445566778899aabbccddeeff"
+
+# Bad length.
+# CHECK: [[@LINE+1]]:{{[0-9]+}}: error: invalid MD5 checksum specified
+        .file 3 "dir2" "bar" md5 "ff"
+
+# Not a string.
+# CHECK: [[@LINE+1]]:{{[0-9]+}}: error: unexpected token in '.file' directive
+        .file 4 "dir3" "foo" md5 ffeeddccbbaa99887766554433221100
+
+# Non-DWARF .file syntax with checksum.
+# CHECK: [[@LINE+1]]:{{[0-9]+}}: error: MD5 checksum specified, but no file number
+        .file "baz" md5 "ffeeddccbbaa998877665544332211gg"

Added: llvm/trunk/test/MC/ELF/debug-md5.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/debug-md5.s?rev=322134&view=auto
==============================================================================
--- llvm/trunk/test/MC/ELF/debug-md5.s (added)
+++ llvm/trunk/test/MC/ELF/debug-md5.s Tue Jan  9 15:31:48 2018
@@ -0,0 +1,18 @@
+// RUN: llvm-mc -triple x86_64-unknown-unknown -dwarf-version 5 -filetype=obj %s -o -| llvm-dwarfdump --debug-line - | FileCheck %s
+
+        .file 1 "dir1/foo"   md5 "00112233445566778899aabbccddeeff"
+        .file 2 "dir2" "bar" md5 "ffeeddccbbaa99887766554433221100"
+        .loc 1 1 0
+        nop
+        .loc 2 1 0
+        nop
+
+# CHECK: debug_line[0x00000000]
+# CHECK: version: 5
+# CHECK: include_directories[ 1] = ''
+# CHECK: include_directories[ 2] = 'dir1'
+# CHECK: include_directories[ 3] = 'dir2'
+# CHECK-NOT: include_directories
+# CHECK: Dir MD5 Checksum File Name
+# CHECK: file_names[ 1] 1 00112233445566778899aabbccddeeff foo
+# CHECK: file_names[ 2] 2 ffeeddccbbaa99887766554433221100 bar




More information about the llvm-commits mailing list