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