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

Eric Beckmann via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 15 14:23:03 PDT 2017


I'm sorry are you referring to a particular part of the patch?  Do you mean
we shouldn't give the ChecksumKind enum explicit values but rather save
those for the assembler to give?

On Fri, Sep 15, 2017 at 2:11 PM, David Majnemer <david.majnemer at gmail.com>
wrote:

>
>
> On Fri, Sep 15, 2017 at 11:20 AM, Eric Beckmann via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>> 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.
>>
>
> This seems weird. Shouldn't we separate this from what we actually encode
> and translate it to the codeview specific CHKSUM_TYPE_MD5/CHKSUM_TYPE_
> SHA1?
>
> I know that the conversion would be trivial but this seems like a bit of a
> layering violation, especially considering that we encode the ChecksumKind
> in the bitcode itself...
>
>
>>    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>(Checksum
>> Kind));
>>      (void)Success;
>>      assert(Success && ".cv_file directive failed");
>>    }
>> @@ -681,8 +684,10 @@ void CodeViewDebug::emitInlineeLinesSubs
>>    OS.AddComment("Inlinee lines subsection");
>>    MCSymbol *InlineEnd = beginCVSubsection(DebugSubsect
>> ionKind::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/DebugI
>> nfoMetadata.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/MCAsmS
>> treamer.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/MCCode
>> View.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()->getC
>> ontents();
>>    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->getVaria
>> bleValue())
>> +                                ->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/MCObje
>> ctStreamer.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/MCPars
>> er/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>(Checksum
>> Kind)))
>>      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/MCStre
>> amer.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/DebugInf
>> o/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/DebugInf
>> o/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/DebugInf
>> o/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/AArch
>> 64/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();
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170915/ce30fd11/attachment-0001.html>


More information about the llvm-commits mailing list