aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCAssembler.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-02-05 01:55:49 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-02-05 01:55:49 +0000
commit408b5e660300f96d9a231ba0e18e75d8e69d17bb (patch)
treee9209cea4a29570a15cbcdb349cf6413b453e3aa /llvm/lib/MC/MCAssembler.cpp
parentadc2376375f32b96daa8c548b11237738945f623 (diff)
downloadllvm-408b5e660300f96d9a231ba0e18e75d8e69d17bb.zip
llvm-408b5e660300f96d9a231ba0e18e75d8e69d17bb.tar.gz
llvm-408b5e660300f96d9a231ba0e18e75d8e69d17bb.tar.bz2
[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. llvm-svn: 259868
Diffstat (limited to 'llvm/lib/MC/MCAssembler.cpp')
-rw-r--r--llvm/lib/MC/MCAssembler.cpp32
1 files changed, 27 insertions, 5 deletions
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 9a55ef3..ca8ccb4 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -303,6 +303,8 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
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 MCAssembler &Asm, const MCAsmLayout &Layout,
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 &Layout) {
// 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 &Layout) {
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(MCAsmLayout &Layout,
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(MCAsmLayout &Layout, MCSection &Sec) {
RelaxedFrag =
relaxCVInlineLineTable(Layout, *cast<MCCVInlineLineTableFragment>(I));
break;
+ case MCFragment::FT_CVDefRange:
+ RelaxedFrag = relaxCVDefRange(Layout, *cast<MCCVDefRangeFragment>(I));
+ break;
}
if (RelaxedFrag && !FirstRelaxedFragment)
FirstRelaxedFragment = &*I;