diff options
author | Daniel Dunbar <daniel@zuster.org> | 2010-05-14 00:37:21 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2010-05-14 00:37:21 +0000 |
commit | 9005d45a990ef46f06800bd6bd6a7d1298a33645 (patch) | |
tree | 08945cb3abfe39553b3e85635477f14b81a38532 /lib/MC | |
parent | 11c411151643e80b9da0acf16f8bb3ec9c6d2754 (diff) | |
download | external_llvm-9005d45a990ef46f06800bd6bd6a7d1298a33645.zip external_llvm-9005d45a990ef46f06800bd6bd6a7d1298a33645.tar.gz external_llvm-9005d45a990ef46f06800bd6bd6a7d1298a33645.tar.bz2 |
MC: Extend MCAsmLayout to explicitly track which fragments have been layed out, and enforce several invariants to LayoutFragment to ensure we only do layout in a sensible order.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103753 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r-- | lib/MC/MCAssembler.cpp | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 92bdc0c..411c6d9 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -47,7 +47,9 @@ STATISTIC(SectionLayouts, "Number of section layouts"); /* *** */ -MCAsmLayout::MCAsmLayout(MCAssembler &Asm) : Assembler(Asm) { +MCAsmLayout::MCAsmLayout(MCAssembler &Asm) + : Assembler(Asm), LastValidFragment(0) + { // Compute the section layout order. Virtual sections must go last. for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) if (!Asm.getBackend().isVirtualSection(it->getSection())) @@ -57,6 +59,23 @@ MCAsmLayout::MCAsmLayout(MCAssembler &Asm) : Assembler(Asm) { SectionOrder.push_back(&*it); } +bool MCAsmLayout::isSectionUpToDate(const MCSectionData *SD) const { + // The first section is always up-to-date. + unsigned Index = SD->getLayoutOrder(); + if (!Index) + return true; + + // Otherwise, sections are always implicitly computed when the preceeding + // fragment is layed out. + const MCSectionData *Prev = getSectionOrder()[Index - 1]; + return isFragmentUpToDate(&(Prev->getFragmentList().back())); +} + +bool MCAsmLayout::isFragmentUpToDate(const MCFragment *F) const { + return (LastValidFragment && + F->getLayoutOrder() <= LastValidFragment->getLayoutOrder()); +} + void MCAsmLayout::UpdateForSlide(MCFragment *F, int SlideAmount) { // We shouldn't have to do anything special to support negative slides, and it // is a perfectly valid thing to do as long as other parts of the system can @@ -73,6 +92,9 @@ void MCAsmLayout::UpdateForSlide(MCFragment *F, int SlideAmount) { } void MCAsmLayout::FragmentReplaced(MCFragment *Src, MCFragment *Dst) { + if (LastValidFragment == Src) + LastValidFragment = Dst; + Dst->Offset = Src->Offset; Dst->EffectiveSize = Src->EffectiveSize; } @@ -414,7 +436,8 @@ uint64_t MCAssembler::ComputeFragmentSize(MCAsmLayout &Layout, } void MCAsmLayout::LayoutFile() { - // Initialize the first section. + // Initialize the first section and set the valid fragment layout point. + LastValidFragment = 0; if (!getSectionOrder().empty()) getSectionOrder().front()->Address = 0; @@ -428,21 +451,32 @@ void MCAsmLayout::LayoutFile() { } void MCAsmLayout::LayoutFragment(MCFragment *F) { - uint64_t StartAddress = getSectionAddress(F->getParent()); - - // Get the fragment start address. - uint64_t Address = StartAddress; - MCSectionData::iterator it = F; - if (MCFragment *Prev = F->getPrevNode()) - Address = (StartAddress + getFragmentOffset(Prev) + - getFragmentEffectiveSize(Prev)); + MCFragment *Prev = F->getPrevNode(); + + // We should never try to recompute something which is up-to-date. + assert(!isFragmentUpToDate(F) && "Attempt to recompute up-to-date fragment!"); + // We should never try to compute the fragment layout if the section isn't + // up-to-date. + assert(isSectionUpToDate(F->getParent()) && + "Attempt to compute fragment before it's section!"); + // We should never try to compute the fragment layout if it's predecessor + // isn't up-to-date. + assert((!Prev || isFragmentUpToDate(Prev)) && + "Attempt to compute fragment before it's predecessor!"); ++stats::FragmentLayouts; + // Compute the fragment start address. + uint64_t StartAddress = F->getParent()->Address; + uint64_t Address = StartAddress; + if (Prev) + Address += Prev->Offset + Prev->EffectiveSize; + // Compute fragment offset and size. F->Offset = Address - StartAddress; F->EffectiveSize = getAssembler().ComputeFragmentSize(*this, *F, StartAddress, F->Offset); + LastValidFragment = F; // If this is the last fragment in a section, update the next section address. if (!F->getNextNode()) { |