<div dir="ltr">Just out of curiosity why does this feature need support in MC? (the DWARF equivalent doesn't, for example - so just trying to understand the differences in architecture/implementation here)</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Feb 4, 2016 at 5:55 PM, David Majnemer via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: majnemer<br>
Date: Thu Feb  4 19:55:49 2016<br>
New Revision: 259868<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=259868&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=259868&view=rev</a><br>
Log:<br>
[MC] Add support for encoding CodeView variable definition ranges<br>
<br>
CodeView, like most other debug formats, represents the live range of a<br>
variable so that debuggers might print them out.<br>
<br>
They use a variety of records to represent how a particular variable<br>
might be available (in a register, in a frame pointer, etc.) along with<br>
a set of ranges where this debug information is relevant.<br>
<br>
However, the format only allows us to use ranges which are limited to a<br>
maximum of 0xF000 in size.  This means that we need to split our debug<br>
information into chunks of 0xF000.<br>
<br>
Because the layout of code is not known until *very* late, we must use a<br>
new fragment to record the information we need until we can know<br>
*exactly* what the range is.<br>
<br>
Added:<br>
    llvm/trunk/test/MC/COFF/cv-def-range.s<br>
Modified:<br>
    llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h<br>
    llvm/trunk/include/llvm/MC/MCAssembler.h<br>
    llvm/trunk/include/llvm/MC/MCCodeView.h<br>
    llvm/trunk/include/llvm/MC/MCFragment.h<br>
    llvm/trunk/include/llvm/MC/MCObjectStreamer.h<br>
    llvm/trunk/include/llvm/MC/MCStreamer.h<br>
    llvm/trunk/lib/MC/MCAsmStreamer.cpp<br>
    llvm/trunk/lib/MC/MCAssembler.cpp<br>
    llvm/trunk/lib/MC/MCCodeView.cpp<br>
    llvm/trunk/lib/MC/MCFragment.cpp<br>
    llvm/trunk/lib/MC/MCObjectStreamer.cpp<br>
    llvm/trunk/lib/MC/MCParser/AsmParser.cpp<br>
    llvm/trunk/lib/MC/MCStreamer.cpp<br>
    llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp<br>
    llvm/trunk/test/MC/X86/reloc-directive.s<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h?rev=259868&r1=259867&r2=259868&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h?rev=259868&r1=259867&r2=259868&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolRecord.h Thu Feb  4 19:55:49 2016<br>
@@ -123,6 +123,8 @@ struct LocalVariableAddrGap {<br>
   ulittle16_t Range;<br>
 };<br>
<br>
+enum : uint16_t { MaxDefRange = 0xf000 };<br>
+<br>
 // S_DEFRANGE<br>
 struct DefRangeSym {<br>
   ulittle32_t Program;<br>
<br>
Modified: llvm/trunk/include/llvm/MC/MCAssembler.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=259868&r1=259867&r2=259868&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=259868&r1=259867&r2=259868&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/MC/MCAssembler.h (original)<br>
+++ llvm/trunk/include/llvm/MC/MCAssembler.h Thu Feb  4 19:55:49 2016<br>
@@ -191,6 +191,7 @@ private:<br>
                                    MCDwarfCallFrameFragment &DF);<br>
   bool relaxCVInlineLineTable(MCAsmLayout &Layout,<br>
                               MCCVInlineLineTableFragment &DF);<br>
+  bool relaxCVDefRange(MCAsmLayout &Layout, MCCVDefRangeFragment &DF);<br>
<br>
   /// finishLayout - Finalize a layout, including fragment lowering.<br>
   void finishLayout(MCAsmLayout &Layout);<br>
<br>
Modified: llvm/trunk/include/llvm/MC/MCCodeView.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCCodeView.h?rev=259868&r1=259867&r2=259868&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCCodeView.h?rev=259868&r1=259867&r2=259868&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/MC/MCCodeView.h (original)<br>
+++ llvm/trunk/include/llvm/MC/MCCodeView.h Thu Feb  4 19:55:49 2016<br>
@@ -166,6 +166,13 @@ public:<br>
   void encodeInlineLineTable(MCAsmLayout &Layout,<br>
                              MCCVInlineLineTableFragment &F);<br>
<br>
+  void<br>
+  emitDefRange(MCObjectStreamer &OS,<br>
+               ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,<br>
+               StringRef FixedSizePortion);<br>
+<br>
+  void encodeDefRange(MCAsmLayout &Layout, MCCVDefRangeFragment &F);<br>
+<br>
   /// Emits the string table substream.<br>
   void emitStringTable(MCObjectStreamer &OS);<br>
<br>
<br>
Modified: llvm/trunk/include/llvm/MC/MCFragment.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCFragment.h?rev=259868&r1=259867&r2=259868&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCFragment.h?rev=259868&r1=259867&r2=259868&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/MC/MCFragment.h (original)<br>
+++ llvm/trunk/include/llvm/MC/MCFragment.h Thu Feb  4 19:55:49 2016<br>
@@ -41,6 +41,7 @@ public:<br>
     FT_LEB,<br>
     FT_SafeSEH,<br>
     FT_CVInlineLines,<br>
+    FT_CVDefRange,<br>
     FT_Dummy<br>
   };<br>
<br>
@@ -211,7 +212,8 @@ public:<br>
<br>
   static bool classof(const MCFragment *F) {<br>
     MCFragment::FragmentType Kind = F->getKind();<br>
-    return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data;<br>
+    return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data ||<br>
+           Kind == MCFragment::FT_CVDefRange;<br>
   }<br>
 };<br>
<br>
@@ -509,9 +511,7 @@ public:<br>
       : MCFragment(FT_CVInlineLines, false, 0, Sec), SiteFuncId(SiteFuncId),<br>
         StartFileId(StartFileId), StartLineNum(StartLineNum),<br>
         FnStartSym(FnStartSym), FnEndSym(FnEndSym),<br>
-        SecondaryFuncs(SecondaryFuncs.begin(), SecondaryFuncs.end()) {<br>
-    Contents.push_back(0);<br>
-  }<br>
+        SecondaryFuncs(SecondaryFuncs.begin(), SecondaryFuncs.end()) {}<br>
<br>
   /// \name Accessors<br>
   /// @{<br>
@@ -529,6 +529,37 @@ public:<br>
   }<br>
 };<br>
<br>
+/// Fragment representing the .cv_def_range directive.<br>
+class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups<32, 4> {<br>
+  SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 2> Ranges;<br>
+  SmallString<32> FixedSizePortion;<br>
+<br>
+  /// CodeViewContext has the real knowledge about this format, so let it access<br>
+  /// our members.<br>
+  friend class CodeViewContext;<br>
+<br>
+public:<br>
+  MCCVDefRangeFragment(<br>
+      ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,<br>
+      StringRef FixedSizePortion, MCSection *Sec = nullptr)<br>
+      : MCEncodedFragmentWithFixups<32, 4>(FT_CVDefRange, false, Sec),<br>
+        Ranges(Ranges.begin(), Ranges.end()),<br>
+        FixedSizePortion(FixedSizePortion) {}<br>
+<br>
+  /// \name Accessors<br>
+  /// @{<br>
+  ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> getRanges() const {<br>
+    return Ranges;<br>
+  }<br>
+<br>
+  StringRef getFixedSizePortion() const { return FixedSizePortion; }<br>
+  /// @}<br>
+<br>
+  static bool classof(const MCFragment *F) {<br>
+    return F->getKind() == MCFragment::FT_CVDefRange;<br>
+  }<br>
+};<br>
+<br>
 } // end namespace llvm<br>
<br>
 #endif<br>
<br>
Modified: llvm/trunk/include/llvm/MC/MCObjectStreamer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectStreamer.h?rev=259868&r1=259867&r2=259868&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectStreamer.h?rev=259868&r1=259867&r2=259868&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/MC/MCObjectStreamer.h (original)<br>
+++ llvm/trunk/include/llvm/MC/MCObjectStreamer.h Thu Feb  4 19:55:49 2016<br>
@@ -131,6 +131,9 @@ public:<br>
       unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,<br>
       const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,<br>
       ArrayRef<unsigned> SecondaryFunctionIds) override;<br>
+  void EmitCVDefRangeDirective(<br>
+      ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,<br>
+      StringRef FixedSizePortion) override;<br>
   void EmitCVStringTableDirective() override;<br>
   void EmitCVFileChecksumsDirective() override;<br>
   void EmitGPRel32Value(const MCExpr *Value) override;<br>
<br>
Modified: llvm/trunk/include/llvm/MC/MCStreamer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=259868&r1=259867&r2=259868&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=259868&r1=259867&r2=259868&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)<br>
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Thu Feb  4 19:55:49 2016<br>
@@ -662,6 +662,12 @@ public:<br>
       const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,<br>
       ArrayRef<unsigned> SecondaryFunctionIds);<br>
<br>
+  /// \brief This implements the CodeView '.cv_def_range' assembler<br>
+  /// directive.<br>
+  virtual void EmitCVDefRangeDirective(<br>
+      ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,<br>
+      StringRef FixedSizePortion);<br>
+<br>
   /// \brief This implements the CodeView '.cv_stringtable' assembler directive.<br>
   virtual void EmitCVStringTableDirective() {}<br>
<br>
<br>
Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=259868&r1=259867&r2=259868&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=259868&r1=259867&r2=259868&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)<br>
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Thu Feb  4 19:55:49 2016<br>
@@ -209,6 +209,9 @@ public:<br>
       unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,<br>
       const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,<br>
       ArrayRef<unsigned> SecondaryFunctionIds) override;<br>
+  void EmitCVDefRangeDirective(<br>
+      ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,<br>
+      StringRef FixedSizePortion) override;<br>
   void EmitCVStringTableDirective() override;<br>
   void EmitCVFileChecksumsDirective() override;<br>
<br>
@@ -1038,6 +1041,22 @@ void MCAsmStreamer::EmitCVInlineLinetabl<br>
       SecondaryFunctionIds);<br>
 }<br>
<br>
+void MCAsmStreamer::EmitCVDefRangeDirective(<br>
+    ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,<br>
+    StringRef FixedSizePortion) {<br>
+  OS << "\t.cv_def_range\t";<br>
+  for (std::pair<const MCSymbol *, const MCSymbol *> Range : Ranges) {<br>
+    OS << ' ';<br>
+    Range.first->print(OS, MAI);<br>
+    OS << ' ';<br>
+    Range.second->print(OS, MAI);<br>
+  }<br>
+  OS << ", ";<br>
+  PrintQuotedString(FixedSizePortion, OS);<br>
+  EmitEOL();<br>
+  this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);<br>
+}<br>
+<br>
 void MCAsmStreamer::EmitCVStringTableDirective() {<br>
   OS << "\t.cv_stringtable";<br>
   EmitEOL();<br>
<br>
Modified: llvm/trunk/lib/MC/MCAssembler.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=259868&r1=259867&r2=259868&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=259868&r1=259867&r2=259868&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)<br>
+++ llvm/trunk/lib/MC/MCAssembler.cpp Thu Feb  4 19:55:49 2016<br>
@@ -303,6 +303,8 @@ uint64_t MCAssembler::computeFragmentSiz<br>
     return cast<MCDwarfCallFrameFragment>(F).getContents().size();<br>
   case MCFragment::FT_CVInlineLines:<br>
     return cast<MCCVInlineLineTableFragment>(F).getContents().size();<br>
+  case MCFragment::FT_CVDefRange:<br>
+    return cast<MCCVDefRangeFragment>(F).getContents().size();<br>
   case MCFragment::FT_Dummy:<br>
     llvm_unreachable("Should not have been added");<br>
   }<br>
@@ -545,6 +547,11 @@ static void writeFragment(const MCAssemb<br>
     OW->writeBytes(OF.getContents());<br>
     break;<br>
   }<br>
+  case MCFragment::FT_CVDefRange: {<br>
+    const auto &DRF = cast<MCCVDefRangeFragment>(F);<br>
+    OW->writeBytes(DRF.getContents());<br>
+    break;<br>
+  }<br>
   case MCFragment::FT_Dummy:<br>
     llvm_unreachable("Should not have been added");<br>
   }<br>
@@ -673,19 +680,24 @@ void MCAssembler::layout(MCAsmLayout &La<br>
   // Evaluate and apply the fixups, generating relocation entries as necessary.<br>
   for (MCSection &Sec : *this) {<br>
     for (MCFragment &Frag : Sec) {<br>
-      MCEncodedFragment *F = dyn_cast<MCEncodedFragment>(&Frag);<br>
       // Data and relaxable fragments both have fixups.  So only process<br>
       // those here.<br>
       // FIXME: Is there a better way to do this?  MCEncodedFragmentWithFixups<br>
       // being templated makes this tricky.<br>
-      if (!F || isa<MCCompactEncodedInstFragment>(F))<br>
+      if (isa<MCEncodedFragment>(&Frag) &&<br>
+          isa<MCCompactEncodedInstFragment>(&Frag))<br>
+        continue;<br>
+      if (!isa<MCEncodedFragment>(&Frag) && !isa<MCCVDefRangeFragment>(&Frag))<br>
         continue;<br>
       ArrayRef<MCFixup> Fixups;<br>
       MutableArrayRef<char> Contents;<br>
-      if (auto *FragWithFixups = dyn_cast<MCDataFragment>(F)) {<br>
+      if (auto *FragWithFixups = dyn_cast<MCDataFragment>(&Frag)) {<br>
+        Fixups = FragWithFixups->getFixups();<br>
+        Contents = FragWithFixups->getContents();<br>
+      } else if (auto *FragWithFixups = dyn_cast<MCRelaxableFragment>(&Frag)) {<br>
         Fixups = FragWithFixups->getFixups();<br>
         Contents = FragWithFixups->getContents();<br>
-      } else if (auto *FragWithFixups = dyn_cast<MCRelaxableFragment>(F)) {<br>
+      } else if (auto *FragWithFixups = dyn_cast<MCCVDefRangeFragment>(&Frag)) {<br>
         Fixups = FragWithFixups->getFixups();<br>
         Contents = FragWithFixups->getContents();<br>
       } else<br>
@@ -693,7 +705,7 @@ void MCAssembler::layout(MCAsmLayout &La<br>
       for (const MCFixup &Fixup : Fixups) {<br>
         uint64_t FixedValue;<br>
         bool IsPCRel;<br>
-        std::tie(FixedValue, IsPCRel) = handleFixup(Layout, *F, Fixup);<br>
+        std::tie(FixedValue, IsPCRel) = handleFixup(Layout, Frag, Fixup);<br>
         getBackend().applyFixup(Fixup, Contents.data(),<br>
                                 Contents.size(), FixedValue, IsPCRel);<br>
       }<br>
@@ -828,6 +840,13 @@ bool MCAssembler::relaxCVInlineLineTable<br>
   return OldSize != F.getContents().size();<br>
 }<br>
<br>
+bool MCAssembler::relaxCVDefRange(MCAsmLayout &Layout,<br>
+                                  MCCVDefRangeFragment &F) {<br>
+  unsigned OldSize = F.getContents().size();<br>
+  getContext().getCVContext().encodeDefRange(Layout, F);<br>
+  return OldSize != F.getContents().size();<br>
+}<br>
+<br>
 bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSection &Sec) {<br>
   // Holds the first fragment which needed relaxing during this layout. It will<br>
   // remain NULL if none were relaxed.<br>
@@ -863,6 +882,9 @@ bool MCAssembler::layoutSectionOnce(MCAs<br>
       RelaxedFrag =<br>
           relaxCVInlineLineTable(Layout, *cast<MCCVInlineLineTableFragment>(I));<br>
       break;<br>
+    case MCFragment::FT_CVDefRange:<br>
+      RelaxedFrag = relaxCVDefRange(Layout, *cast<MCCVDefRangeFragment>(I));<br>
+      break;<br>
     }<br>
     if (RelaxedFrag && !FirstRelaxedFragment)<br>
       FirstRelaxedFragment = &*I;<br>
<br>
Modified: llvm/trunk/lib/MC/MCCodeView.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCCodeView.cpp?rev=259868&r1=259867&r2=259868&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCCodeView.cpp?rev=259868&r1=259867&r2=259868&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/MC/MCCodeView.cpp (original)<br>
+++ llvm/trunk/lib/MC/MCCodeView.cpp Thu Feb  4 19:55:49 2016<br>
@@ -19,6 +19,7 @@<br>
 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"<br>
 #include "llvm/MC/MCContext.h"<br>
 #include "llvm/MC/MCObjectStreamer.h"<br>
+#include "llvm/MC/MCValue.h"<br>
 #include "llvm/Support/COFF.h"<br>
<br>
 using namespace llvm;<br>
@@ -236,6 +237,16 @@ void CodeViewContext::emitInlineLineTabl<br>
       SecondaryFunctionIds, OS.getCurrentSectionOnly());<br>
 }<br>
<br>
+void CodeViewContext::emitDefRange(<br>
+    MCObjectStreamer &OS,<br>
+    ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,<br>
+    StringRef FixedSizePortion) {<br>
+  // Create and insert a fragment into the current section that will be encoded<br>
+  // later.<br>
+  new MCCVDefRangeFragment(Ranges, FixedSizePortion,<br>
+                           OS.getCurrentSectionOnly());<br>
+}<br>
+<br>
 static unsigned computeLabelDiff(MCAsmLayout &Layout, const MCSymbol *Begin,<br>
                                  const MCSymbol *End) {<br>
   MCContext &Ctx = Layout.getAssembler().getContext();<br>
@@ -352,6 +363,58 @@ void CodeViewContext::encodeInlineLineTa<br>
   compressAnnotation(std::min(EndSymLength, LocAfterLength), Buffer);<br>
 }<br>
<br>
+void CodeViewContext::encodeDefRange(MCAsmLayout &Layout,<br>
+                                     MCCVDefRangeFragment &Frag) {<br>
+  MCContext &Ctx = Layout.getAssembler().getContext();<br>
+  SmallVectorImpl<char> &Contents = Frag.getContents();<br>
+  Contents.clear();<br>
+  SmallVectorImpl<MCFixup> &Fixups = Frag.getFixups();<br>
+  Fixups.clear();<br>
+  raw_svector_ostream OS(Contents);<br>
+<br>
+  // Write down each range where the variable is defined.<br>
+  for (std::pair<const MCSymbol *, const MCSymbol *> Range : Frag.getRanges()) {<br>
+    unsigned RangeSize = computeLabelDiff(Layout, Range.first, Range.second);<br>
+    unsigned Bias = 0;<br>
+    // We must split the range into chunks of MaxDefRange, this is a fundamental<br>
+    // limitation of the file format.<br>
+    do {<br>
+      uint16_t Chunk = std::min((uint32_t)MaxDefRange, RangeSize);<br>
+<br>
+      const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(Range.first, Ctx);<br>
+      const MCBinaryExpr *BE =<br>
+          MCBinaryExpr::createAdd(SRE, MCConstantExpr::create(Bias, Ctx), Ctx);<br>
+      MCValue Res;<br>
+      BE->evaluateAsRelocatable(Res, &Layout, /*Fixup=*/nullptr);<br>
+<br>
+      // Each record begins with a 2-byte number indicating how large the record<br>
+      // is.<br>
+      StringRef FixedSizePortion = Frag.getFixedSizePortion();<br>
+      // Our record is a fixed sized prefix and a LocalVariableAddrRange that we<br>
+      // are artificially constructing.<br>
+      size_t RecordSize =<br>
+          FixedSizePortion.size() + sizeof(LocalVariableAddrRange);<br>
+      // Write out the recrod size.<br>
+      support::endian::Writer<support::little>(OS).write<uint16_t>(RecordSize);<br>
+      // Write out the fixed size prefix.<br>
+      OS << FixedSizePortion;<br>
+      // Make space for a fixup that will eventually have a section relative<br>
+      // relocation pointing at the offset where the variable becomes live.<br>
+      Fixups.push_back(MCFixup::create(Contents.size(), BE, FK_SecRel_4));<br>
+      Contents.resize(Contents.size() + 4); // Fixup for code start.<br>
+      // Make space for a fixup that will record the section index for the code.<br>
+      Fixups.push_back(MCFixup::create(Contents.size(), BE, FK_SecRel_2));<br>
+      Contents.resize(Contents.size() + 2); // Fixup for section index.<br>
+      // Write down the range's extent.<br>
+      support::endian::Writer<support::little>(OS).write<uint16_t>(Chunk);<br>
+<br>
+      // Move on to the next range.<br>
+      Bias += Chunk;<br>
+      RangeSize -= Chunk;<br>
+    } while (RangeSize > 0);<br>
+  }<br>
+}<br>
+<br>
 //<br>
 // This is called when an instruction is assembled into the specified section<br>
 // and if there is information from the last .cv_loc directive that has yet to have<br>
<br>
Modified: llvm/trunk/lib/MC/MCFragment.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCFragment.cpp?rev=259868&r1=259867&r2=259868&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCFragment.cpp?rev=259868&r1=259867&r2=259868&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/MC/MCFragment.cpp (original)<br>
+++ llvm/trunk/lib/MC/MCFragment.cpp Thu Feb  4 19:55:49 2016<br>
@@ -292,6 +292,9 @@ void MCFragment::destroy() {<br>
     case FT_CVInlineLines:<br>
       delete cast<MCCVInlineLineTableFragment>(this);<br>
       return;<br>
+    case FT_CVDefRange:<br>
+      delete cast<MCCVDefRangeFragment>(this);<br>
+      return;<br>
     case FT_Dummy:<br>
       delete cast<MCDummyFragment>(this);<br>
       return;<br>
@@ -331,6 +334,7 @@ LLVM_DUMP_METHOD void MCFragment::dump()<br>
   case MCFragment::FT_LEB:   OS << "MCLEBFragment"; break;<br>
   case MCFragment::FT_SafeSEH:    OS << "MCSafeSEHFragment"; break;<br>
   case MCFragment::FT_CVInlineLines: OS << "MCCVInlineLineTableFragment"; break;<br>
+  case MCFragment::FT_CVDefRange: OS << "MCCVDefRangeTableFragment"; break;<br>
   case MCFragment::FT_Dummy: OS << "MCDummyFragment"; break;<br>
   }<br>
<br>
@@ -435,6 +439,16 @@ LLVM_DUMP_METHOD void MCFragment::dump()<br>
     OS << " Sym:" << *F->getFnStartSym();<br>
     break;<br>
   }<br>
+  case MCFragment::FT_CVDefRange: {<br>
+    const auto *F = cast<MCCVDefRangeFragment>(this);<br>
+    OS << "\n       ";<br>
+    for (std::pair<const MCSymbol *, const MCSymbol *> RangeStartEnd :<br>
+         F->getRanges()) {<br>
+      OS << " RangeStart:" << RangeStartEnd.first;<br>
+      OS << " RangeEnd:" << RangeStartEnd.second;<br>
+    }<br>
+    break;<br>
+  }<br>
   case MCFragment::FT_Dummy:<br>
     break;<br>
   }<br>
<br>
Modified: llvm/trunk/lib/MC/MCObjectStreamer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectStreamer.cpp?rev=259868&r1=259867&r2=259868&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectStreamer.cpp?rev=259868&r1=259867&r2=259868&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/MC/MCObjectStreamer.cpp (original)<br>
+++ llvm/trunk/lib/MC/MCObjectStreamer.cpp Thu Feb  4 19:55:49 2016<br>
@@ -396,6 +396,13 @@ void MCObjectStreamer::EmitCVInlineLinet<br>
       SecondaryFunctionIds);<br>
 }<br>
<br>
+void MCObjectStreamer::EmitCVDefRangeDirective(<br>
+    ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,<br>
+    StringRef FixedSizePortion) {<br>
+  getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);<br>
+  this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);<br>
+}<br>
+<br>
 void MCObjectStreamer::EmitCVStringTableDirective() {<br>
   getContext().getCVContext().emitStringTable(*this);<br>
 }<br>
<br>
Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=259868&r1=259867&r2=259868&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=259868&r1=259867&r2=259868&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)<br>
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Thu Feb  4 19:55:49 2016<br>
@@ -358,7 +358,7 @@ private:<br>
     DK_IFNOTDEF, DK_ELSEIF, DK_ELSE, DK_ENDIF,<br>
     DK_SPACE, DK_SKIP, DK_FILE, DK_LINE, DK_LOC, DK_STABS,<br>
     DK_CV_FILE, DK_CV_LOC, DK_CV_LINETABLE, DK_CV_INLINE_LINETABLE,<br>
-    DK_CV_STRINGTABLE, DK_CV_FILECHECKSUMS,<br>
+    DK_CV_DEF_RANGE, DK_CV_STRINGTABLE, DK_CV_FILECHECKSUMS,<br>
     DK_CFI_SECTIONS, DK_CFI_STARTPROC, DK_CFI_ENDPROC, DK_CFI_DEF_CFA,<br>
     DK_CFI_DEF_CFA_OFFSET, DK_CFI_ADJUST_CFA_OFFSET, DK_CFI_DEF_CFA_REGISTER,<br>
     DK_CFI_OFFSET, DK_CFI_REL_OFFSET, DK_CFI_PERSONALITY, DK_CFI_LSDA,<br>
@@ -396,11 +396,13 @@ private:<br>
   bool parseDirectiveLoc();<br>
   bool parseDirectiveStabs();<br>
<br>
-  // ".cv_file", ".cv_loc", ".cv_linetable", "cv_inline_linetable"<br>
+  // ".cv_file", ".cv_loc", ".cv_linetable", "cv_inline_linetable",<br>
+  // ".cv_def_range"<br>
   bool parseDirectiveCVFile();<br>
   bool parseDirectiveCVLoc();<br>
   bool parseDirectiveCVLinetable();<br>
   bool parseDirectiveCVInlineLinetable();<br>
+  bool parseDirectiveCVDefRange();<br>
   bool parseDirectiveCVStringTable();<br>
   bool parseDirectiveCVFileChecksums();<br>
<br>
@@ -1656,6 +1658,8 @@ bool AsmParser::parseStatement(ParseStat<br>
       return parseDirectiveCVLinetable();<br>
     case DK_CV_INLINE_LINETABLE:<br>
       return parseDirectiveCVInlineLinetable();<br>
+    case DK_CV_DEF_RANGE:<br>
+      return parseDirectiveCVDefRange();<br>
     case DK_CV_STRINGTABLE:<br>
       return parseDirectiveCVStringTable();<br>
     case DK_CV_FILECHECKSUMS:<br>
@@ -3286,6 +3290,40 @@ bool AsmParser::parseDirectiveCVInlineLi<br>
   return false;<br>
 }<br>
<br>
+/// parseDirectiveCVDefRange<br>
+/// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes*<br>
+bool AsmParser::parseDirectiveCVDefRange() {<br>
+  SMLoc Loc;<br>
+  std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;<br>
+  while (getLexer().is(AsmToken::Identifier)) {<br>
+    Loc = getLexer().getLoc();<br>
+    StringRef GapStartName;<br>
+    if (parseIdentifier(GapStartName))<br>
+      return Error(Loc, "expected identifier in directive");<br>
+    MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);<br>
+<br>
+    Loc = getLexer().getLoc();<br>
+    StringRef GapEndName;<br>
+    if (parseIdentifier(GapEndName))<br>
+      return Error(Loc, "expected identifier in directive");<br>
+    MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);<br>
+<br>
+    Ranges.push_back({GapStartSym, GapEndSym});<br>
+  }<br>
+<br>
+  if (getLexer().isNot(AsmToken::Comma))<br>
+    return TokError("unexpected token in directive");<br>
+  Lex();<br>
+<br>
+  std::string FixedSizePortion;<br>
+  if (parseEscapedString(FixedSizePortion))<br>
+    return true;<br>
+  Lex();<br>
+<br>
+  getStreamer().EmitCVDefRangeDirective(Ranges, FixedSizePortion);<br>
+  return false;<br>
+}<br>
+<br>
 /// parseDirectiveCVStringTable<br>
 /// ::= .cv_stringtable<br>
 bool AsmParser::parseDirectiveCVStringTable() {<br>
@@ -4615,6 +4653,7 @@ void AsmParser::initializeDirectiveKindM<br>
   DirectiveKindMap[".cv_loc"] = DK_CV_LOC;<br>
   DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE;<br>
   DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;<br>
+  DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;<br>
   DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;<br>
   DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;<br>
   DirectiveKindMap[".sleb128"] = DK_SLEB128;<br>
<br>
Modified: llvm/trunk/lib/MC/MCStreamer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=259868&r1=259867&r2=259868&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=259868&r1=259867&r2=259868&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/MC/MCStreamer.cpp (original)<br>
+++ llvm/trunk/lib/MC/MCStreamer.cpp Thu Feb  4 19:55:49 2016<br>
@@ -201,6 +201,10 @@ void MCStreamer::EmitCVInlineLinetableDi<br>
     const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,<br>
     ArrayRef<unsigned> SecondaryFunctionIds) {}<br>
<br>
+void MCStreamer::EmitCVDefRangeDirective(<br>
+    ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,<br>
+    StringRef FixedSizePortion) {}<br>
+<br>
 void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,<br>
                                      MCSymbol *EHSymbol) {<br>
 }<br>
<br>
Modified: llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp?rev=259868&r1=259867&r2=259868&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp?rev=259868&r1=259867&r2=259868&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp (original)<br>
+++ llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp Thu Feb  4 19:55:49 2016<br>
@@ -785,6 +785,10 @@ void WinCOFFObjectWriter::recordRelocati<br>
     }<br>
   }<br>
<br>
+  // The fixed value never makes sense for section indicies, ignore it.<br>
+  if (Fixup.getKind() == FK_SecRel_2)<br>
+    FixedValue = 0;<br>
+<br>
   if (TargetObjectWriter->recordRelocation(Fixup))<br>
     coff_section->Relocations.push_back(Reloc);<br>
 }<br>
<br>
Added: llvm/trunk/test/MC/COFF/cv-def-range.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/cv-def-range.s?rev=259868&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/cv-def-range.s?rev=259868&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/MC/COFF/cv-def-range.s (added)<br>
+++ llvm/trunk/test/MC/COFF/cv-def-range.s Thu Feb  4 19:55:49 2016<br>
@@ -0,0 +1,97 @@<br>
+# RUN: llvm-mc -triple=i686-pc-win32 -filetype=obj < %s | llvm-readobj -codeview -codeview-subsection-bytes | FileCheck %s<br>
+       .text<br>
+       .def     @feat.00;<br>
+       .scl    3;<br>
+       .type   0;<br>
+       .endef<br>
+       .globl  @feat.00<br>
+@feat.00 = 1<br>
+       .def     _g;<br>
+       .scl    2;<br>
+       .type   32;<br>
+       .endef<br>
+       .globl  _g<br>
+       .p2align        4, 0x90<br>
+_g:                                     # @g<br>
+Lfunc_begin0:<br>
+       .cv_file        1 "\\usr\\local\\google\\home\\majnemer\\llvm\\src\\<stdin>"<br>
+       .cv_loc 0 1 3 0 is_stmt 0       # <stdin>:3:0<br>
+# BB#0:                                 # %entry<br>
+       pushl   %ebp<br>
+       movl    %esp, %ebp<br>
+       subl    $8, %esp<br>
+       leal    -4(%ebp), %eax<br>
+Lvar_begin0:<br>
+       #DEBUG_VALUE: g:x <- %EAX<br>
+       .cv_loc 0 1 4 7                 # <stdin>:4:7<br>
+       movl    $0, -4(%ebp)<br>
+       .cv_loc 0 1 5 3                 # <stdin>:5:3<br>
+       movl    %eax, (%esp)<br>
+       calll   _f<br>
+       .cv_loc 0 1 6 1                 # <stdin>:6:1<br>
+Lvar_end0:<br>
+       addl    $8, %esp<br>
+       popl    %ebp<br>
+       retl<br>
+Lfunc_end0:<br>
+<br>
+       .section        .debug$T,"dr"<br>
+       .long   4                       # Debug section magic<br>
+       .short  6                       # Type record length<br>
+       .short  4609                    # Leaf type: LF_ARGLIST<br>
+       .long   0                       # Number of arguments<br>
+       .short  14                      # Type record length<br>
+       .short  4104                    # Leaf type: LF_PROCEDURE<br>
+       .long   3                       # Return type index<br>
+       .byte   0                       # Calling convention<br>
+       .byte   0                       # Function options<br>
+       .short  0                       # # of parameters<br>
+       .long   4096                    # Argument list type index<br>
+       .short  12                      # Type record length<br>
+       .short  5633                    # Leaf type: LF_FUNC_ID<br>
+       .long   0                       # Scope type index<br>
+       .long   4097                    # Function type<br>
+       .asciz  "g"                     # Function name<br>
+       .section        .debug$S,"dr"<br>
+       .long   4                       # Debug section magic<br>
+       .long   241                     # Symbol subsection for g<br>
+       .long   Ltmp1-Ltmp0             # Subsection size<br>
+Ltmp0:<br>
+       .short  Ltmp3-Ltmp2             # Record length<br>
+Ltmp2:<br>
+       .short  4423                    # Record kind: S_GPROC32_ID<br>
+       .long   0                       # PtrParent<br>
+       .long   0                       # PtrEnd<br>
+       .long   0                       # PtrNext<br>
+       .long   Lfunc_end0-_g           # Code size<br>
+       .long   0                       # Offset after prologue<br>
+       .long   0                       # Offset before epilogue<br>
+       .long   0                       # Function type index<br>
+       .secrel32       _g              # Function section relative address<br>
+       .secidx _g                      # Function section index<br>
+       .byte   0                       # Flags<br>
+       .asciz  "g"                     # Function name<br>
+Ltmp3:<br>
+       .short  2                       # Record length<br>
+       .short  4431                    # Record kind: S_PROC_ID_END<br>
+       .cv_def_range   Lvar_begin0 Lvar_end0, "\102\021\374\377\377\377"<br>
+<br>
+# CHECK:    DefRangeFramePointerRel {<br>
+# CHECK:      Offset: -4<br>
+# CHECK:      LocalVariableAddrRange {<br>
+# CHECK:        OffsetStart: .text+0x9<br>
+# CHECK:        ISectStart: 0x0<br>
+# CHECK:        Range: 15<br>
+# CHECK:      }<br>
+# CHECK:    }<br>
+# CHECK:    BlockRelocations [<br>
+# CHECK:      0x4 IMAGE_REL_I386_SECREL .text<br>
+# CHECK:      0x8 IMAGE_REL_I386_SECTION .text<br>
+# CHECK:    ]<br>
+<br>
+Ltmp1:<br>
+       .p2align        2<br>
+       .cv_linetable   0, _g, Lfunc_end0<br>
+       .cv_filechecksums               # File index to string table offset subsection<br>
+       .cv_stringtable                 # String table<br>
+<br>
<br>
Modified: llvm/trunk/test/MC/X86/reloc-directive.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/reloc-directive.s?rev=259868&r1=259867&r2=259868&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/reloc-directive.s?rev=259868&r1=259867&r2=259868&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/MC/X86/reloc-directive.s (original)<br>
+++ llvm/trunk/test/MC/X86/reloc-directive.s Thu Feb  4 19:55:49 2016<br>
@@ -20,7 +20,7 @@ foo:<br>
        .reloc 16, dir32,   foo@imgrel   # ASM: .reloc 16, dir32, foo@IMGREL<br>
<br>
 # OBJ-32-LABEL: Name: .text<br>
-# OBJ-32:       0000: 04000000 00000000 08000000<br>
+# OBJ-32:       0000: 04000000 00000000 00000000<br>
 # OBJ-32-LABEL: }<br>
 # OBJ-32-LABEL: Relocations [<br>
 # OBJ-32:       0x4  IMAGE_REL_I386_DIR32   foo<br>
@@ -30,7 +30,7 @@ foo:<br>
 # OBJ-32:       0x10 IMAGE_REL_I386_DIR32NB foo<br>
<br>
 # OBJ-64-LABEL: Name: .text<br>
-# OBJ-64:       0000: 04000000 00000000 08000000<br>
+# OBJ-64:       0000: 04000000 00000000 00000000<br>
 # OBJ-64-LABEL: }<br>
 # OBJ-64-LABEL: Relocations [<br>
 # OBJ-64:       0x4  IMAGE_REL_AMD64_ADDR32   foo<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>