[llvm] r259868 - [MC] Add support for encoding CodeView variable definition ranges

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 4 18:57:30 PST 2016


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)

On Thu, Feb 4, 2016 at 5:55 PM, David Majnemer via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

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


More information about the llvm-commits mailing list