[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 17:55:50 PST 2016
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
More information about the llvm-commits
mailing list