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

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 15 14:24:35 PDT 2017


On Fri, Sep 15, 2017 at 2:23 PM, Eric Beckmann <ecbeckmann at google.com>
wrote:

> 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?
>

I think its fine for ChecksumKind to have explicit values. I just don't
think its great that they are dependent on the encoding used by CodeView.
The assembler should translate the LLVM-internal CSK_MD5 to the CodeView
specific CHKSUM_TYPE_MD5.


>
> 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_SH
>> A1?
>>
>> 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/A
>>> smPrinter/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/c8845ecd/attachment.html>


More information about the llvm-commits mailing list