[llvm] r313374 - Fix Bug 30978 by emitting cv file checksums.

Eric Beckmann via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 15 11:20:28 PDT 2017


Author: ecbeckmann
Date: Fri Sep 15 11:20:28 2017
New Revision: 313374

URL: http://llvm.org/viewvc/llvm-project?rev=313374&view=rev
Log:
Fix Bug 30978 by emitting cv file checksums.

Summary:
The checksums had already been placed in the IR, this patch allows
MCCodeView to actually write it out to an MCStreamer.

Subscribers: llvm-commits, hiraditya

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

Modified:
    llvm/trunk/include/llvm/IR/DebugInfoMetadata.h
    llvm/trunk/include/llvm/MC/MCCodeView.h
    llvm/trunk/include/llvm/MC/MCObjectStreamer.h
    llvm/trunk/include/llvm/MC/MCStreamer.h
    llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
    llvm/trunk/lib/IR/DebugInfoMetadata.cpp
    llvm/trunk/lib/MC/MCAsmStreamer.cpp
    llvm/trunk/lib/MC/MCCodeView.cpp
    llvm/trunk/lib/MC/MCObjectStreamer.cpp
    llvm/trunk/lib/MC/MCParser/AsmParser.cpp
    llvm/trunk/lib/MC/MCStreamer.cpp
    llvm/trunk/test/DebugInfo/COFF/inlining.ll
    llvm/trunk/test/DebugInfo/COFF/multifile.ll
    llvm/trunk/test/DebugInfo/COFF/simple.ll
    llvm/trunk/test/MC/AArch64/coff-debug.ll
    llvm/trunk/unittests/IR/MetadataTest.cpp

Modified: llvm/trunk/include/llvm/IR/DebugInfoMetadata.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DebugInfoMetadata.h?rev=313374&r1=313373&r2=313374&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DebugInfoMetadata.h (original)
+++ llvm/trunk/include/llvm/IR/DebugInfoMetadata.h Fri Sep 15 11:20:28 2017
@@ -473,10 +473,12 @@ class DIFile : public DIScope {
   friend class MDNode;
 
 public:
+  // These values must be explictly set, as they end up in the final object
+  // file.
   enum ChecksumKind {
-    CSK_None,
-    CSK_MD5,
-    CSK_SHA1,
+    CSK_None = 0,
+    CSK_MD5 = 1,
+    CSK_SHA1 = 2,
     CSK_Last = CSK_SHA1 // Should be last enumeration.
   };
 
@@ -510,7 +512,7 @@ public:
                              ChecksumKind CSK = CSK_None,
                              StringRef CS = StringRef()),
                     (Filename, Directory, CSK, CS))
-  DEFINE_MDNODE_GET(DIFile, (MDString *Filename, MDString *Directory,
+  DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory,
                              ChecksumKind CSK = CSK_None,
                              MDString *CS = nullptr),
                     (Filename, Directory, CSK, CS))

Modified: llvm/trunk/include/llvm/MC/MCCodeView.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCCodeView.h?rev=313374&r1=313373&r2=313374&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCCodeView.h (original)
+++ llvm/trunk/include/llvm/MC/MCCodeView.h Fri Sep 15 11:20:28 2017
@@ -161,8 +161,8 @@ public:
   ~CodeViewContext();
 
   bool isValidFileNumber(unsigned FileNumber) const;
-  bool addFile(unsigned FileNumber, StringRef Filename);
-  ArrayRef<StringRef> getFilenames() { return Filenames; }
+  bool addFile(MCStreamer &OS, unsigned FileNumber, StringRef Filename,
+               StringRef Checksum, uint8_t ChecksumKind);
 
   /// Records the function id of a normal function. Returns false if the
   /// function id has already been used, and true otherwise.
@@ -273,6 +273,9 @@ public:
   /// Emits the file checksum substream.
   void emitFileChecksums(MCObjectStreamer &OS);
 
+  /// Emits the offset into the checksum table of the given file number.
+  void emitFileChecksumOffset(MCObjectStreamer &OS, unsigned FileNo);
+
 private:
   /// The current CodeView line information from the last .cv_loc directive.
   MCCVLoc CurrentCVLoc = MCCVLoc(0, 0, 0, 0, false, true);
@@ -287,14 +290,30 @@ private:
 
   MCDataFragment *getStringTableFragment();
 
-  /// Add something to the string table.
-  StringRef addToStringTable(StringRef S);
+  /// Add something to the string table.  Returns the final string as well as
+  /// offset into the string table.
+  std::pair<StringRef, unsigned> addToStringTable(StringRef S);
 
   /// Get a string table offset.
   unsigned getStringTableOffset(StringRef S);
 
-  /// An array of absolute paths. Eventually this may include the file checksum.
-  SmallVector<StringRef, 4> Filenames;
+  struct FileInfo {
+    unsigned StringTableOffset;
+
+    // Checksum offset stored as a symbol because it might be requested
+    // before it has been calculated, so a fixup may be needed.
+    MCSymbol *ChecksumTableOffset;
+
+    // Indicates if this FileInfo corresponds to an actual file, or hasn't been
+    // set yet.
+    bool Assigned = false;
+
+    std::string Checksum;
+    uint8_t ChecksumKind;
+  };
+
+  /// Array storing added file information.
+  SmallVector<FileInfo, 4> Files;
 
   /// The offset of the first and last .cv_loc directive for a given function
   /// id.
@@ -305,6 +324,10 @@ private:
 
   /// All known functions and inlined call sites, indexed by function id.
   std::vector<MCCVFunctionInfo> Functions;
+
+  /// Indicate whether we have already laid out the checksum table addresses or
+  /// not.
+  bool ChecksumOffsetsAssigned = false;
 };
 
 } // end namespace llvm

Modified: llvm/trunk/include/llvm/MC/MCObjectStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectStreamer.h?rev=313374&r1=313373&r2=313374&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCObjectStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCObjectStreamer.h Fri Sep 15 11:20:28 2017
@@ -140,6 +140,7 @@ public:
       StringRef FixedSizePortion) override;
   void EmitCVStringTableDirective() override;
   void EmitCVFileChecksumsDirective() override;
+  void EmitCVFileChecksumOffsetDirective(unsigned FileNo) override;
   void EmitDTPRel32Value(const MCExpr *Value) override;
   void EmitDTPRel64Value(const MCExpr *Value) override;
   void EmitTPRel32Value(const MCExpr *Value) override;

Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=313374&r1=313373&r2=313374&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Fri Sep 15 11:20:28 2017
@@ -729,10 +729,11 @@ public:
                                      unsigned Isa, unsigned Discriminator,
                                      StringRef FileName);
 
-  /// \brief Associate a filename with a specified logical file number.  This
-  /// implements the '.cv_file 4 "foo.c"' assembler directive. Returns true on
-  /// success.
-  virtual bool EmitCVFileDirective(unsigned FileNo, StringRef Filename);
+  /// Associate a filename with a specified logical file number, and also
+  /// specify that file's checksum information.  This implements the '.cv_file 4
+  /// "foo.c"' assembler directive. Returns true on success.
+  virtual bool EmitCVFileDirective(unsigned FileNo, StringRef Filename,
+                                   StringRef Checksum, unsigned ChecksumKind);
 
   /// \brief Introduces a function id for use with .cv_loc.
   virtual bool EmitCVFuncIdDirective(unsigned FunctionId);
@@ -774,6 +775,10 @@ public:
   /// \brief This implements the CodeView '.cv_filechecksums' assembler directive.
   virtual void EmitCVFileChecksumsDirective() {}
 
+  /// This implements the CodeView '.cv_filechecksumoffset' assembler
+  /// directive.
+  virtual void EmitCVFileChecksumOffsetDirective(unsigned FileNo) {}
+
   /// Emit the absolute difference between two symbols.
   ///
   /// \pre Offset of \c Hi is greater than the offset \c Lo.

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=313374&r1=313373&r2=313374&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Fri Sep 15 11:20:28 2017
@@ -159,7 +159,10 @@ unsigned CodeViewDebug::maybeRecordFile(
   if (Insertion.second) {
     // We have to compute the full filepath and emit a .cv_file directive.
     StringRef FullPath = getFullFilepath(F);
-    bool Success = OS.EmitCVFileDirective(NextId, FullPath);
+    StringRef Checksum = F->getChecksum();
+    DIFile::ChecksumKind ChecksumKind = F->getChecksumKind();
+    bool Success = OS.EmitCVFileDirective(NextId, FullPath, Checksum,
+                                          static_cast<unsigned>(ChecksumKind));
     (void)Success;
     assert(Success && ".cv_file directive failed");
   }
@@ -681,8 +684,10 @@ void CodeViewDebug::emitInlineeLinesSubs
   OS.AddComment("Inlinee lines subsection");
   MCSymbol *InlineEnd = beginCVSubsection(DebugSubsectionKind::InlineeLines);
 
-  // We don't provide any extra file info.
-  // FIXME: Find out if debuggers use this info.
+  // We emit the checksum info for files.  This is used by debuggers to
+  // determine if a pdb matches the source before loading it.  Visual Studio,
+  // for instance, will display a warning that the breakpoints are not valid if
+  // the pdb does not match the source.
   OS.AddComment("Inlinee lines signature");
   OS.EmitIntValue(unsigned(InlineeLinesSignature::Normal), 4);
 
@@ -695,13 +700,10 @@ void CodeViewDebug::emitInlineeLinesSubs
     OS.AddComment("Inlined function " + SP->getName() + " starts at " +
                   SP->getFilename() + Twine(':') + Twine(SP->getLine()));
     OS.AddBlankLine();
-    // The filechecksum table uses 8 byte entries for now, and file ids start at
-    // 1.
-    unsigned FileOffset = (FileId - 1) * 8;
     OS.AddComment("Type index of inlined function");
     OS.EmitIntValue(InlineeIdx.getIndex(), 4);
     OS.AddComment("Offset into filechecksum table");
-    OS.EmitIntValue(FileOffset, 4);
+    OS.EmitCVFileChecksumOffsetDirective(FileId);
     OS.AddComment("Starting line number");
     OS.EmitIntValue(SP->getLine(), 4);
   }

Modified: llvm/trunk/lib/IR/DebugInfoMetadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DebugInfoMetadata.cpp?rev=313374&r1=313373&r2=313374&view=diff
==============================================================================
--- llvm/trunk/lib/IR/DebugInfoMetadata.cpp (original)
+++ llvm/trunk/lib/IR/DebugInfoMetadata.cpp Fri Sep 15 11:20:28 2017
@@ -354,6 +354,8 @@ DISubroutineType *DISubroutineType::getI
   DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops);
 }
 
+// FIXME: Implement this string-enum correspondence with a .def file and macros,
+// so that the association is explicit rather than implied.
 static const char *ChecksumKindName[DIFile::CSK_Last + 1] = {
   "CSK_None",
   "CSK_MD5",

Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=313374&r1=313373&r2=313374&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Fri Sep 15 11:20:28 2017
@@ -225,7 +225,8 @@ public:
                              StringRef FileName) override;
   MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
 
-  bool EmitCVFileDirective(unsigned FileNo, StringRef Filename) override;
+  bool EmitCVFileDirective(unsigned FileNo, StringRef Filename,
+                           StringRef Checksum, unsigned ChecksumKind) override;
   bool EmitCVFuncIdDirective(unsigned FuncId) override;
   bool EmitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc,
                                    unsigned IAFile, unsigned IALine,
@@ -245,6 +246,7 @@ public:
       StringRef FixedSizePortion) override;
   void EmitCVStringTableDirective() override;
   void EmitCVFileChecksumsDirective() override;
+  void EmitCVFileChecksumOffsetDirective(unsigned FileNo) override;
 
   void EmitIdent(StringRef IdentString) override;
   void EmitCFISections(bool EH, bool Debug) override;
@@ -1120,13 +1122,25 @@ MCSymbol *MCAsmStreamer::getDwarfLineTab
   return MCStreamer::getDwarfLineTableSymbol(0);
 }
 
-bool MCAsmStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename) {
-  if (!getContext().getCVContext().addFile(FileNo, Filename))
+bool MCAsmStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
+                                        StringRef Checksum,
+                                        unsigned ChecksumKind) {
+  if (!getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
+                                           ChecksumKind))
     return false;
 
   OS << "\t.cv_file\t" << FileNo << ' ';
-
   PrintQuotedString(Filename, OS);
+
+  if (!ChecksumKind) {
+    EmitEOL();
+    return true;
+  }
+
+  OS << ' ';
+  PrintQuotedString(Checksum, OS);
+  OS << ' ' << ChecksumKind;
+
   EmitEOL();
   return true;
 }
@@ -1228,6 +1242,11 @@ void MCAsmStreamer::EmitCVFileChecksumsD
   EmitEOL();
 }
 
+void MCAsmStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
+  OS << "\t.cv_filechecksumoffset\t" << FileNo;
+  EmitEOL();
+}
+
 void MCAsmStreamer::EmitIdent(StringRef IdentString) {
   assert(MAI->hasIdentDirective() && ".ident directive not supported");
   OS << "\t.ident\t";

Modified: llvm/trunk/lib/MC/MCCodeView.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCCodeView.cpp?rev=313374&r1=313373&r2=313374&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCCodeView.cpp (original)
+++ llvm/trunk/lib/MC/MCCodeView.cpp Fri Sep 15 11:20:28 2017
@@ -39,29 +39,39 @@ CodeViewContext::~CodeViewContext() {
 /// for it.
 bool CodeViewContext::isValidFileNumber(unsigned FileNumber) const {
   unsigned Idx = FileNumber - 1;
-  if (Idx < Filenames.size())
-    return !Filenames[Idx].empty();
+  if (Idx < Files.size())
+    return Files[Idx].Assigned;
   return false;
 }
 
-bool CodeViewContext::addFile(unsigned FileNumber, StringRef Filename) {
+bool CodeViewContext::addFile(MCStreamer &OS, unsigned FileNumber,
+                              StringRef Filename, StringRef Checksum,
+                              uint8_t ChecksumKind) {
   assert(FileNumber > 0);
-  Filename = addToStringTable(Filename);
+  auto FilenameOffset = addToStringTable(Filename);
+  Filename = FilenameOffset.first;
   unsigned Idx = FileNumber - 1;
-  if (Idx >= Filenames.size())
-    Filenames.resize(Idx + 1);
+  if (Idx >= Files.size())
+    Files.resize(Idx + 1);
 
   if (Filename.empty())
     Filename = "<stdin>";
 
-  if (!Filenames[Idx].empty())
+  if (Files[Idx].Assigned)
     return false;
 
-  // FIXME: We should store the string table offset of the filename, rather than
-  // the filename itself for efficiency.
-  Filename = addToStringTable(Filename);
+  FilenameOffset = addToStringTable(Filename);
+  Filename = FilenameOffset.first;
+  unsigned Offset = FilenameOffset.second;
+
+  auto ChecksumOffsetSymbol =
+      OS.getContext().createTempSymbol("checksum_offset", false);
+  Files[Idx].StringTableOffset = Offset;
+  Files[Idx].ChecksumTableOffset = ChecksumOffsetSymbol;
+  Files[Idx].Assigned = true;
+  Files[Idx].Checksum = Checksum.str();
+  Files[Idx].ChecksumKind = ChecksumKind;
 
-  Filenames[Idx] = Filename;
   return true;
 }
 
@@ -118,17 +128,18 @@ MCDataFragment *CodeViewContext::getStri
   return StrTabFragment;
 }
 
-StringRef CodeViewContext::addToStringTable(StringRef S) {
+std::pair<StringRef, unsigned> CodeViewContext::addToStringTable(StringRef S) {
   SmallVectorImpl<char> &Contents = getStringTableFragment()->getContents();
   auto Insertion =
       StringTable.insert(std::make_pair(S, unsigned(Contents.size())));
   // Return the string from the table, since it is stable.
-  S = Insertion.first->first();
+  std::pair<StringRef, unsigned> Ret =
+      std::make_pair(Insertion.first->first(), Insertion.first->second);
   if (Insertion.second) {
     // The string map key is always null terminated.
-    Contents.append(S.begin(), S.end() + 1);
+    Contents.append(Ret.first.begin(), Ret.first.end() + 1);
   }
-  return S;
+  return Ret;
 }
 
 unsigned CodeViewContext::getStringTableOffset(StringRef S) {
@@ -165,7 +176,7 @@ void CodeViewContext::emitStringTable(MC
 void CodeViewContext::emitFileChecksums(MCObjectStreamer &OS) {
   // Do nothing if there are no file checksums. Microsoft's linker rejects empty
   // CodeView substreams.
-  if (Filenames.empty())
+  if (Files.empty())
     return;
 
   MCContext &Ctx = OS.getContext();
@@ -176,17 +187,63 @@ void CodeViewContext::emitFileChecksums(
   OS.emitAbsoluteSymbolDiff(FileEnd, FileBegin, 4);
   OS.EmitLabel(FileBegin);
 
+  unsigned CurrentOffset = 0;
+
   // Emit an array of FileChecksum entries. We index into this table using the
-  // user-provided file number. Each entry is currently 8 bytes, as we don't
-  // emit checksums.
-  for (StringRef Filename : Filenames) {
-    OS.EmitIntValue(getStringTableOffset(Filename), 4);
-    // Zero the next two fields and align back to 4 bytes. This indicates that
-    // no checksum is present.
-    OS.EmitIntValue(0, 4);
+  // user-provided file number.  Each entry may be a variable number of bytes
+  // determined by the checksum kind and size.
+  for (auto File : Files) {
+    OS.EmitAssignment(File.ChecksumTableOffset,
+                      MCConstantExpr::create(CurrentOffset, Ctx));
+    CurrentOffset += 4; // String table offset.
+    if (!File.ChecksumKind) {
+      CurrentOffset +=
+          4; // One byte each for checksum size and kind, then align to 4 bytes.
+    } else {
+      CurrentOffset += 2; // One byte each for checksum size and kind.
+      CurrentOffset += File.Checksum.size();
+      CurrentOffset = alignTo(CurrentOffset, 4);
+    }
+
+    OS.EmitIntValue(File.StringTableOffset, 4);
+
+    if (!File.ChecksumKind) {
+      // There is no checksum.  Therefore zero the next two fields and align
+      // back to 4 bytes.
+      OS.EmitIntValue(0, 4);
+      continue;
+    }
+    OS.EmitIntValue(static_cast<uint8_t>(File.Checksum.size()), 1);
+    OS.EmitIntValue(File.ChecksumKind, 1);
+    OS.EmitBytes(File.Checksum);
+    OS.EmitValueToAlignment(4);
   }
 
   OS.EmitLabel(FileEnd);
+
+  ChecksumOffsetsAssigned = true;
+}
+
+// Output checksum table offset of the given file number.  It is possible that
+// not all files have been registered yet, and so the offset cannot be
+// calculated.  In this case a symbol representing the offset is emitted, and
+// the value of this symbol will be fixed up at a later time.
+void CodeViewContext::emitFileChecksumOffset(MCObjectStreamer &OS,
+                                             unsigned FileNo) {
+  unsigned Idx = FileNo - 1;
+
+  if (Idx >= Files.size())
+    Files.resize(Idx + 1);
+
+  if (ChecksumOffsetsAssigned) {
+    OS.EmitSymbolValue(Files[Idx].ChecksumTableOffset, 4);
+    return;
+  }
+
+  const MCSymbolRefExpr *SRE =
+      MCSymbolRefExpr::create(Files[Idx].ChecksumTableOffset, OS.getContext());
+
+  OS.EmitValueImpl(SRE, 4);
 }
 
 void CodeViewContext::emitLineTableForFunction(MCObjectStreamer &OS,
@@ -219,9 +276,12 @@ void CodeViewContext::emitLineTableForFu
           return Loc.getFileNum() != CurFileNum;
         });
     unsigned EntryCount = FileSegEnd - I;
-    OS.AddComment("Segment for file '" + Twine(Filenames[CurFileNum - 1]) +
-                  "' begins");
-    OS.EmitIntValue(8 * (CurFileNum - 1), 4);
+    OS.AddComment(
+        "Segment for file '" +
+        Twine(getStringTableFragment()
+                  ->getContents()[Files[CurFileNum - 1].StringTableOffset]) +
+        "' begins");
+    OS.EmitCVFileChecksumOffsetDirective(CurFileNum);
     OS.EmitIntValue(EntryCount, 4);
     uint32_t SegmentSize = 12;
     SegmentSize += 8 * EntryCount;
@@ -401,9 +461,10 @@ void CodeViewContext::encodeInlineLineTa
     HaveOpenRange = true;
 
     if (CurSourceLoc.File != LastSourceLoc.File) {
-      // File ids are 1 based, and each file checksum table entry is 8 bytes
-      // long. See emitFileChecksums above.
-      unsigned FileOffset = 8 * (CurSourceLoc.File - 1);
+      unsigned FileOffset = static_cast<const MCConstantExpr *>(
+                                Files[CurSourceLoc.File - 1]
+                                    .ChecksumTableOffset->getVariableValue())
+                                ->getValue();
       compressAnnotation(BinaryAnnotationsOpCode::ChangeFile, Buffer);
       compressAnnotation(FileOffset, Buffer);
     }

Modified: llvm/trunk/lib/MC/MCObjectStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectStreamer.cpp?rev=313374&r1=313373&r2=313374&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCObjectStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCObjectStreamer.cpp Fri Sep 15 11:20:28 2017
@@ -426,6 +426,9 @@ void MCObjectStreamer::EmitCVFileChecksu
   getContext().getCVContext().emitFileChecksums(*this);
 }
 
+void MCObjectStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
+  getContext().getCVContext().emitFileChecksumOffset(*this, FileNo);
+}
 
 void MCObjectStreamer::EmitBytes(StringRef Data) {
   MCCVLineEntry::Make(this);

Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=313374&r1=313373&r2=313374&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Fri Sep 15 11:20:28 2017
@@ -501,6 +501,7 @@ private:
     DK_CV_DEF_RANGE,
     DK_CV_STRINGTABLE,
     DK_CV_FILECHECKSUMS,
+    DK_CV_FILECHECKSUM_OFFSET,
     DK_CFI_SECTIONS,
     DK_CFI_STARTPROC,
     DK_CFI_ENDPROC,
@@ -576,6 +577,7 @@ private:
   bool parseDirectiveCVDefRange();
   bool parseDirectiveCVStringTable();
   bool parseDirectiveCVFileChecksums();
+  bool parseDirectiveCVFileChecksumOffset();
 
   // .cfi directives
   bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
@@ -2030,6 +2032,8 @@ bool AsmParser::parseStatement(ParseStat
       return parseDirectiveCVStringTable();
     case DK_CV_FILECHECKSUMS:
       return parseDirectiveCVFileChecksums();
+    case DK_CV_FILECHECKSUM_OFFSET:
+      return parseDirectiveCVFileChecksumOffset();
     case DK_CFI_SECTIONS:
       return parseDirectiveCFISections();
     case DK_CFI_STARTPROC:
@@ -3457,25 +3461,34 @@ bool AsmParser::parseDirectiveStabs() {
 }
 
 /// parseDirectiveCVFile
-/// ::= .cv_file number filename
+/// ::= .cv_file number filename [checksum] [checksumkind]
 bool AsmParser::parseDirectiveCVFile() {
   SMLoc FileNumberLoc = getTok().getLoc();
   int64_t FileNumber;
   std::string Filename;
+  std::string Checksum;
+  int64_t ChecksumKind = 0;
 
   if (parseIntToken(FileNumber,
                     "expected file number in '.cv_file' directive") ||
       check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
       check(getTok().isNot(AsmToken::String),
             "unexpected token in '.cv_file' directive") ||
-      // Usually directory and filename are together, otherwise just
-      // directory. Allow the strings to have escaped octal character sequence.
-      parseEscapedString(Filename) ||
-      parseToken(AsmToken::EndOfStatement,
-                 "unexpected token in '.cv_file' directive"))
+      parseEscapedString(Filename))
     return true;
+  if (!parseOptionalToken(AsmToken::EndOfStatement)) {
+    if (check(getTok().isNot(AsmToken::String),
+              "unexpected token in '.cv_file' directive") ||
+        parseEscapedString(Checksum) ||
+        parseIntToken(ChecksumKind,
+                      "expected checksum kind in '.cv_file' directive") ||
+        parseToken(AsmToken::EndOfStatement,
+                   "unexpected token in '.cv_file' directive"))
+      return true;
+  }
 
-  if (!getStreamer().EmitCVFileDirective(FileNumber, Filename))
+  if (!getStreamer().EmitCVFileDirective(FileNumber, Filename, Checksum,
+                                         static_cast<uint8_t>(ChecksumKind)))
     return Error(FileNumberLoc, "file number already allocated");
 
   return false;
@@ -3754,6 +3767,18 @@ bool AsmParser::parseDirectiveCVFileChec
   return false;
 }
 
+/// parseDirectiveCVFileChecksumOffset
+/// ::= .cv_filechecksumoffset fileno
+bool AsmParser::parseDirectiveCVFileChecksumOffset() {
+  int64_t FileNo;
+  if (parseIntToken(FileNo, "expected identifier in directive"))
+    return true;
+  if (parseToken(AsmToken::EndOfStatement, "Expected End of Statement"))
+    return true;
+  getStreamer().EmitCVFileChecksumOffsetDirective(FileNo);
+  return false;
+}
+
 /// parseDirectiveCFISections
 /// ::= .cfi_sections section [, section]
 bool AsmParser::parseDirectiveCFISections() {
@@ -5136,6 +5161,7 @@ void AsmParser::initializeDirectiveKindM
   DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
   DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
   DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
+  DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
   DirectiveKindMap[".sleb128"] = DK_SLEB128;
   DirectiveKindMap[".uleb128"] = DK_ULEB128;
   DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;

Modified: llvm/trunk/lib/MC/MCStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=313374&r1=313373&r2=313374&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCStreamer.cpp Fri Sep 15 11:20:28 2017
@@ -224,8 +224,11 @@ void MCStreamer::EnsureValidDwarfFrame()
     report_fatal_error("No open frame");
 }
 
-bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename) {
-  return getContext().getCVContext().addFile(FileNo, Filename);
+bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
+                                     StringRef Checksum,
+                                     unsigned ChecksumKind) {
+  return getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
+                                             ChecksumKind);
 }
 
 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId) {

Modified: llvm/trunk/test/DebugInfo/COFF/inlining.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/inlining.ll?rev=313374&r1=313373&r2=313374&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/inlining.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/inlining.ll Fri Sep 15 11:20:28 2017
@@ -49,11 +49,11 @@
 ; ASM: .long   0
 ; ASM: # Inlined function bar starts at t.cpp:8
 ; ASM: .long   4098                    # Type index of inlined function
-; ASM: .long   0                       # Offset into filechecksum table
+; ASM: .cv_filechecksumoffset 1        # Offset into filechecksum table
 ; ASM: .long   8                       # Starting line number
 ; ASM: # Inlined function foo starts at t.cpp:2
 ; ASM: .long   4099
-; ASM: .long   0
+; ASM: .cv_filechecksumoffset 1        # Offset into filechecksum table
 ; ASM: .long   2
 ; ASM: [[inline_end]]:
 
@@ -72,6 +72,8 @@
 ; ASM: .short  4430
 ; ASM: .short  4430
 
+; ASM: .cv_filechecksums
+
 ; ASM: .section .debug$T,"dr"
 ; ASM: .long 4 # Debug section magic
 ; ASM: # ArgList (0x1000) {

Modified: llvm/trunk/test/DebugInfo/COFF/multifile.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/multifile.ll?rev=313374&r1=313373&r2=313374&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/multifile.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/multifile.ll Fri Sep 15 11:20:28 2017
@@ -18,10 +18,10 @@
 
 ; X86-LABEL: _f:
 ; X86:      # BB
-; X86:      .cv_file 1 "D:\\one.c"
+; X86:      .cv_file 1 "D:\\one.c" "70b51f534d80639d033ae92c6a856af6" 1
 ; X86:      .cv_loc 0 1 1 0 is_stmt 0 # one.c:1:0
 ; X86:      calll   _g
-; X86:      .cv_file 2 "D:\\two.c"
+; X86:      .cv_file 2 "D:\\two.c" "70b51f534d80639d033ae92c6a856af6" 1
 ; X86:      .cv_loc 0 2 2 0 # two.c:2:0
 ; X86:      calll   _g
 ; X86:      .cv_loc 0 1 7 0 # one.c:7:0
@@ -51,6 +51,28 @@
 ; OBJ32-NEXT:   ProcEnd {
 ; OBJ32:        }
 ; OBJ32-NEXT: ]
+; OBJ32:	  Subsection [
+; OBJ32:        SubSectionType: FileChecksums (0xF4)
+; OBJ32-NEXT:   SubSectionSize: 0x50
+; OBJ32-NEXT:   FileChecksum {
+; OBJ32-NEXT:     Filename: D:\one.c (0x1)
+; OBJ32-NEXT:     ChecksumSize: 0x20
+; OBJ32-NEXT:     ChecksumKind: MD5 (0x1)
+; OBJ32-NEXT:     ChecksumBytes (
+; OBJ32-NEXT:       0000: 37306235 31663533 34643830 36333964  |70b51f534d80639d|
+; OBJ32-NEXT:       0010: 30333361 65393263 36613835 36616636  |033ae92c6a856af6|
+; OBJ32-NEXT:     )
+; OBJ32-NEXT:   }
+; OBJ32-NEXT:   FileChecksum {
+; OBJ32-NEXT:     Filename: D:\two.c (0xA)
+; OBJ32-NEXT:     ChecksumSize: 0x20
+; OBJ32-NEXT:     ChecksumKind: MD5 (0x1)
+; OBJ32-NEXT:     ChecksumBytes (
+; OBJ32-NEXT:       0000: 37306235 31663533 34643830 36333964  |70b51f534d80639d|
+; OBJ32-NEXT:       0010: 30333361 65393263 36613835 36616636  |033ae92c6a856af6|
+; OBJ32-NEXT:     )
+; OBJ32-NEXT:   }
+; OBJ32-NEXT:  ]
 ; OBJ32:      FunctionLineTable [
 ; OBJ32-NEXT:   Name: _f
 ; OBJ32-NEXT:   Flags: 0x0
@@ -88,14 +110,14 @@
 
 ; X64-LABEL: f:
 ; X64-NEXT: .L{{.*}}:{{$}}
-; X64:      .cv_file 1 "D:\\input.c"
+; X64:      .cv_file 1 "D:\\input.c" "70b51f534d80639d033ae92c6a856af6" 1
 ; X64:      .cv_loc 0 1 3 0 is_stmt 0 # input.c:3:0
 ; X64:      # BB
 ; X64:      subq    $40, %rsp
-; X64:      .cv_file 2 "D:\\one.c"
+; X64:      .cv_file 2 "D:\\one.c" "70b51f534d80639d033ae92c6a856af6" 1
 ; X64:      .cv_loc 0 2 1 0 # one.c:1:0
 ; X64:      callq   g
-; X64:      .cv_file 3 "D:\\two.c"
+; X64:      .cv_file 3 "D:\\two.c" "70b51f534d80639d033ae92c6a856af6" 1
 ; X64:      .cv_loc 0 3 2 0 # two.c:2:0
 ; X64:      callq   g
 ; X64:      .cv_loc 0 2 7 0 # one.c:7:0
@@ -123,6 +145,37 @@
 ; OBJ64-NEXT:   ProcEnd {
 ; OBJ64:        }
 ; OBJ64-NEXT: ]
+; OBJ64:	  Subsection [
+; OBJ64:        SubSectionType: FileChecksums (0xF4)
+; OBJ64-NEXT:   SubSectionSize: 0x78
+; OBJ64-NEXT:   FileChecksum {
+; OBJ64-NEXT:     Filename: D:\input.c (0x1)
+; OBJ64-NEXT:     ChecksumSize: 0x20
+; OBJ64-NEXT:     ChecksumKind: MD5 (0x1)
+; OBJ64-NEXT:     ChecksumBytes (
+; OBJ64-NEXT:       0000: 37306235 31663533 34643830 36333964  |70b51f534d80639d|
+; OBJ64-NEXT:       0010: 30333361 65393263 36613835 36616636  |033ae92c6a856af6|
+; OBJ64-NEXT:     )
+; OBJ64-NEXT:   }
+; OBJ64-NEXT:   FileChecksum {
+; OBJ64-NEXT:     Filename: D:\one.c (0xC)
+; OBJ64-NEXT:     ChecksumSize: 0x20
+; OBJ64-NEXT:     ChecksumKind: MD5 (0x1)
+; OBJ64-NEXT:     ChecksumBytes (
+; OBJ64-NEXT:       0000: 37306235 31663533 34643830 36333964  |70b51f534d80639d|
+; OBJ64-NEXT:       0010: 30333361 65393263 36613835 36616636  |033ae92c6a856af6|
+; OBJ64-NEXT:     )
+; OBJ64-NEXT:   }
+; OBJ64-NEXT:   FileChecksum {
+; OBJ64-NEXT:     Filename: D:\two.c (0x15)
+; OBJ64-NEXT:     ChecksumSize: 0x20
+; OBJ64-NEXT:     ChecksumKind: MD5 (0x1)
+; OBJ64-NEXT:     ChecksumBytes (
+; OBJ64-NEXT:       0000: 37306235 31663533 34643830 36333964  |70b51f534d80639d|
+; OBJ64-NEXT:       0010: 30333361 65393263 36613835 36616636  |033ae92c6a856af6|
+; OBJ64-NEXT:     )
+; OBJ64-NEXT:   }
+; OBJ64-NEXT:  ]
 ; OBJ64:      FunctionLineTable [
 ; OBJ64-NEXT:   Name: f
 ; OBJ64-NEXT:   Flags: 0x0
@@ -185,11 +238,11 @@ attributes #1 = { "less-precise-fpmad"="
 !llvm.ident = !{!11}
 
 !0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.5 ", isOptimized: false, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
-!1 = !DIFile(filename: "<unknown>", directory: "D:\5C")
+!1 = !DIFile(filename: "<unknown>", directory: "D:\5C", checksumkind: CSK_MD5, checksum:"70b51f534d80639d033ae92c6a856af6")
 !2 = !{}
 !4 = distinct !DISubprogram(name: "f", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 3, file: !5, scope: !6, type: !7, variables: !2)
-!5 = !DIFile(filename: "input.c", directory: "D:\5C")
-!6 = !DIFile(filename: "input.c", directory: "D:C")
+!5 = !DIFile(filename: "input.c", directory: "D:\5C", checksumkind: CSK_MD5, checksum:"70b51f534d80639d033ae92c6a856af6")
+!6 = !DIFile(filename: "input.c", directory: "D:C", checksumkind: CSK_MD5, checksum:"70b51f534d80639d033ae92c6a856af6")
 !7 = !DISubroutineType(types: !8)
 !8 = !{null}
 !9 = !{i32 2, !"CodeView", i32 1}
@@ -197,9 +250,9 @@ attributes #1 = { "less-precise-fpmad"="
 !11 = !{!"clang version 3.5 "}
 !12 = !DILocation(line: 1, scope: !13)
 !13 = !DILexicalBlockFile(discriminator: 0, file: !14, scope: !4)
-!14 = !DIFile(filename: "one.c", directory: "D:\5C")
+!14 = !DIFile(filename: "one.c", directory: "D:\5C", checksumkind: CSK_MD5, checksum:"70b51f534d80639d033ae92c6a856af6")
 !15 = !DILocation(line: 2, scope: !16)
 !16 = !DILexicalBlockFile(discriminator: 0, file: !17, scope: !4)
-!17 = !DIFile(filename: "two.c", directory: "D:\5C")
+!17 = !DIFile(filename: "two.c", directory: "D:\5C", checksumkind: CSK_MD5, checksum:"70b51f534d80639d033ae92c6a856af6")
 !18 = !DILocation(line: 7, scope: !13)
 !19 = !DILocation(line: 8, scope: !13)

Modified: llvm/trunk/test/DebugInfo/COFF/simple.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/simple.ll?rev=313374&r1=313373&r2=313374&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/simple.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/simple.ll Fri Sep 15 11:20:28 2017
@@ -17,7 +17,7 @@
 
 ; X86-LABEL: _f:
 ; X86:      # BB
-; X86:      .cv_file 1 "D:\\test.c"
+; X86:      .cv_file 1 "D:\\test.c" "f310ab26998ca831cbdf169e4eecacfa" 1
 ; X86:      .cv_loc 0 1 4 2 is_stmt 0 # test.c:4:2
 ; X86:      calll   _g
 ; X86:      .cv_loc 0 1 5 0 # test.c:5:0
@@ -85,6 +85,19 @@
 ; OBJ32-NEXT:   ProcEnd {
 ; OBJ32:        }
 ; OBJ32-NEXT: ]
+; OBJ32:       Subsection [
+; OBJ32:         SubSectionType: FileChecksums (0xF4)
+; OBJ32-NEXT:    SubSectionSize: 0x28
+; OBJ32-NEXT:    FileChecksum {
+; OBJ32-NEXT:      Filename: D:\test.c (0x1)
+; OBJ32-NEXT:      ChecksumSize: 0x20
+; OBJ32-NEXT:      ChecksumKind: MD5 (0x1)
+; OBJ32-NEXT:      ChecksumBytes (
+; OBJ32-NEXT:        0000: 66333130 61623236 39393863 61383331  |f310ab26998ca831|
+; OBJ32-NEXT:        0010: 63626466 31363965 34656563 61636661  |cbdf169e4eecacfa|
+; OBJ32-NEXT:      )
+; OBJ32-NEXT:    }
+; OBJ32-NEXT:  ]
 ; OBJ32:      FunctionLineTable [
 ; OBJ32-NEXT:   Name: _f
 ; OBJ32-NEXT:   Flags: 0x1
@@ -110,7 +123,7 @@
 
 ; X64-LABEL: f:
 ; X64-NEXT: .L{{.*}}:{{$}}
-; X64:      .cv_file 1 "D:\\test.c"
+; X64:      .cv_file 1 "D:\\test.c" "f310ab26998ca831cbdf169e4eecacfa" 1
 ; X64:      .cv_loc 0 1 3 0 is_stmt 0 # test.c:3:0
 ; X64:      # BB
 ; X64:      subq    $40, %rsp
@@ -182,6 +195,19 @@
 ; OBJ64-NEXT:   ProcEnd {
 ; OBJ64:        }
 ; OBJ64-NEXT: ]
+; OBJ64:       Subsection [
+; OBJ64:         SubSectionType: FileChecksums (0xF4)
+; OBJ64-NEXT:    SubSectionSize: 0x28
+; OBJ64-NEXT:    FileChecksum {
+; OBJ64-NEXT:      Filename: D:\test.c (0x1)
+; OBJ64-NEXT:      ChecksumSize: 0x20
+; OBJ64-NEXT:      ChecksumKind: MD5 (0x1)
+; OBJ64-NEXT:      ChecksumBytes (
+; OBJ64-NEXT:        0000: 66333130 61623236 39393863 61383331  |f310ab26998ca831|
+; OBJ64-NEXT:        0010: 63626466 31363965 34656563 61636661  |cbdf169e4eecacfa|
+; OBJ64-NEXT:      )
+; OBJ64-NEXT:    }
+; OBJ64-NEXT:  ]
 ; OBJ64:      FunctionLineTable [
 ; OBJ64-NEXT:   Name: f
 ; OBJ64-NEXT:   Flags: 0x1
@@ -232,8 +258,8 @@ attributes #1 = { "less-precise-fpmad"="
 !1 = !DIFile(filename: "<unknown>", directory: "D:\5C")
 !2 = !{}
 !4 = distinct !DISubprogram(name: "f", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 3, file: !5, scope: !6, type: !7, variables: !2)
-!5 = !DIFile(filename: "test.c", directory: "D:\5C")
-!6 = !DIFile(filename: "test.c", directory: "D:C")
+!5 = !DIFile(filename: "test.c", directory: "D:\5C", checksumkind: CSK_MD5, checksum: "f310ab26998ca831cbdf169e4eecacfa")
+!6 = !DIFile(filename: "test.c", directory: "D:C", checksumkind: CSK_MD5, checksum: "f310ab26998ca831cbdf169e4eecacfa")
 !7 = !DISubroutineType(types: !8)
 !8 = !{null}
 !9 = !{i32 2, !"CodeView", i32 1}

Modified: llvm/trunk/test/MC/AArch64/coff-debug.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/coff-debug.ll?rev=313374&r1=313373&r2=313374&view=diff
==============================================================================
--- llvm/trunk/test/MC/AArch64/coff-debug.ll (original)
+++ llvm/trunk/test/MC/AArch64/coff-debug.ll Fri Sep 15 11:20:28 2017
@@ -103,7 +103,7 @@ attributes #0 = { noinline nounwind optn
 ; CHECK:     SubSectionType: FileChecksums (0xF4)
 ; CHECK:     FileChecksum {
 ; CHECK:       ChecksumSize: 0x0
-; CHECK:       ChecksumKind: None (0x0)
+; CHECK:       ChecksumKind: MD5 (0x1)
 ; CHECK:       ChecksumBytes: ()
 ; CHECK:     }
 ; CHECK:   ]

Modified: llvm/trunk/unittests/IR/MetadataTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/MetadataTest.cpp?rev=313374&r1=313373&r2=313374&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/MetadataTest.cpp (original)
+++ llvm/trunk/unittests/IR/MetadataTest.cpp Fri Sep 15 11:20:28 2017
@@ -1383,7 +1383,8 @@ TEST_F(DIFileTest, get) {
 
   EXPECT_NE(N, DIFile::get(Context, "other", Directory, CSKind, Checksum));
   EXPECT_NE(N, DIFile::get(Context, Filename, "other", CSKind, Checksum));
-  EXPECT_NE(N, DIFile::get(Context, Filename, Directory, DIFile::CSK_SHA1, Checksum));
+  EXPECT_NE(
+      N, DIFile::get(Context, Filename, Directory, DIFile::CSK_SHA1, Checksum));
   EXPECT_NE(N, DIFile::get(Context, Filename, Directory));
 
   TempDIFile Temp = N->clone();




More information about the llvm-commits mailing list