[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