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

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 4 23:00:19 PST 2016


On Thu, Feb 4, 2016 at 6:57 PM, David Blaikie <dblaikie at gmail.com> wrote:

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

Our DWARF implementation does the following:
        .byte   3                       # Abbrev [3] 0x3f:0x1c
DW_TAG_lexical_block
        .quad   .Ltmp3                  # DW_AT_low_pc
        .long   .Ltmp4-.Ltmp3           # DW_AT_high_pc

This comes from `DwarfUnit::addLabelDelta`, it assumes that the delta can
fit in at most four bytes as it uses a DW_FORM_data4.
Outside of the large code model, this will pretty much always work.

However, things are not so simple for CodeView.  The closest analog would
be our record for 'defined ranges' which contain some fixed amount of data
describing how the value is materialized (in a register, in a stack slot
relative to the stack pointer, etc.), a relocation pointing to the start of
the range (similar to DW_AT_low_pc), a relocation holding the code
section's section-index, and a 16-bit range which can be as large as 0xf000.

While targets which use CodeView do not have a large code model, we have a
problem which is quite similar: our label differences can, at most, be
0xf000.  This means that if we want to represent a rather large range, we
will need several records describing the complete range.  The exact number
of records will be (size of the range + 0xefff) / 0xf000.  The DWARF side
of things side-steps this by using a full, four byte, label difference.


>
> 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/7d0f2cf6/attachment.html>


More information about the llvm-commits mailing list