diff options
author | Daniel Dunbar <daniel@zuster.org> | 2010-05-12 21:35:25 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2010-05-12 21:35:25 +0000 |
commit | f0d17d2461a6458568672f611ba4a590d26b1e1a (patch) | |
tree | d79ffc96da2f0f99e46f518051e91335790ffeaf /lib/MC/MCAssembler.cpp | |
parent | 2d891a20e665136a603cc0a076ed1ebbd4703f47 (diff) |
MC: Factor out MCAssembler::LayoutFragment
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103649 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCAssembler.cpp')
-rw-r--r-- | lib/MC/MCAssembler.cpp | 152 |
1 files changed, 78 insertions, 74 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 44e4cc9ea5..106a0ed666 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -362,6 +362,82 @@ bool MCAssembler::EvaluateFixup(const MCAsmLayout &Layout, return IsResolved; } +void MCAssembler::LayoutFragment(MCAsmLayout &Layout, MCFragment &F) { + uint64_t StartAddress = Layout.getSectionAddress(F.getParent()); + + // Get the fragment start address. + uint64_t Address = StartAddress; + MCSectionData::iterator it = &F; + if (MCFragment *Prev = F.getPrevNode()) + Address = (StartAddress + Layout.getFragmentOffset(Prev) + + Layout.getFragmentEffectiveSize(Prev)); + + ++stats::FragmentLayouts; + + uint64_t FragmentOffset = Address - StartAddress; + Layout.setFragmentOffset(&F, FragmentOffset); + + // Evaluate fragment size. + uint64_t EffectiveSize = 0; + switch (F.getKind()) { + case MCFragment::FT_Align: { + MCAlignFragment &AF = cast<MCAlignFragment>(F); + + EffectiveSize = OffsetToAlignment(Address, AF.getAlignment()); + if (EffectiveSize > AF.getMaxBytesToEmit()) + EffectiveSize = 0; + break; + } + + case MCFragment::FT_Data: + EffectiveSize = cast<MCDataFragment>(F).getContents().size(); + break; + + case MCFragment::FT_Fill: { + MCFillFragment &FF = cast<MCFillFragment>(F); + EffectiveSize = FF.getValueSize() * FF.getCount(); + break; + } + + case MCFragment::FT_Inst: + EffectiveSize = cast<MCInstFragment>(F).getInstSize(); + break; + + case MCFragment::FT_Org: { + MCOrgFragment &OF = cast<MCOrgFragment>(F); + + int64_t TargetLocation; + if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, &Layout)) + report_fatal_error("expected assembly-time absolute expression"); + + // FIXME: We need a way to communicate this error. + int64_t Offset = TargetLocation - FragmentOffset; + if (Offset < 0) + report_fatal_error("invalid .org offset '" + Twine(TargetLocation) + + "' (at offset '" + Twine(FragmentOffset) + "'"); + + EffectiveSize = Offset; + break; + } + + case MCFragment::FT_ZeroFill: { + MCZeroFillFragment &ZFF = cast<MCZeroFillFragment>(F); + + // Align the fragment offset; it is safe to adjust the offset freely since + // this is only in virtual sections. + // + // FIXME: We shouldn't be doing this here. + Address = RoundUpToAlignment(Address, ZFF.getAlignment()); + Layout.setFragmentOffset(&F, Address - StartAddress); + + EffectiveSize = ZFF.getSize(); + break; + } + } + + Layout.setFragmentEffectiveSize(&F, EffectiveSize); +} + void MCAssembler::LayoutSection(MCAsmLayout &Layout, unsigned SectionOrderIndex) { MCSectionData &SD = *Layout.getSectionOrder()[SectionOrderIndex]; @@ -396,80 +472,8 @@ void MCAssembler::LayoutSection(MCAsmLayout &Layout, // Set the aligned section address. Layout.setSectionAddress(&SD, StartAddress); - for (MCSectionData::iterator it = SD.begin(), ie = SD.end(); it != ie; ++it) { - MCFragment &F = *it; - - // Compute the fragment start address. - uint64_t Address = StartAddress; - if (MCFragment *Prev = F.getPrevNode()) - Address = (Layout.getFragmentAddress(Prev) + - Layout.getFragmentEffectiveSize(Prev)); - - ++stats::FragmentLayouts; - - uint64_t FragmentOffset = Address - StartAddress; - Layout.setFragmentOffset(&F, FragmentOffset); - - // Evaluate fragment size. - uint64_t EffectiveSize = 0; - switch (F.getKind()) { - case MCFragment::FT_Align: { - MCAlignFragment &AF = cast<MCAlignFragment>(F); - - EffectiveSize = OffsetToAlignment(Address, AF.getAlignment()); - if (EffectiveSize > AF.getMaxBytesToEmit()) - EffectiveSize = 0; - break; - } - - case MCFragment::FT_Data: - EffectiveSize = cast<MCDataFragment>(F).getContents().size(); - break; - - case MCFragment::FT_Fill: { - MCFillFragment &FF = cast<MCFillFragment>(F); - EffectiveSize = FF.getValueSize() * FF.getCount(); - break; - } - - case MCFragment::FT_Inst: - EffectiveSize = cast<MCInstFragment>(F).getInstSize(); - break; - - case MCFragment::FT_Org: { - MCOrgFragment &OF = cast<MCOrgFragment>(F); - - int64_t TargetLocation; - if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, &Layout)) - report_fatal_error("expected assembly-time absolute expression"); - - // FIXME: We need a way to communicate this error. - int64_t Offset = TargetLocation - FragmentOffset; - if (Offset < 0) - report_fatal_error("invalid .org offset '" + Twine(TargetLocation) + - "' (at offset '" + Twine(FragmentOffset) + "'"); - - EffectiveSize = Offset; - break; - } - - case MCFragment::FT_ZeroFill: { - MCZeroFillFragment &ZFF = cast<MCZeroFillFragment>(F); - - // Align the fragment offset; it is safe to adjust the offset freely since - // this is only in virtual sections. - // - // FIXME: We shouldn't be doing this here. - Address = RoundUpToAlignment(Address, ZFF.getAlignment()); - Layout.setFragmentOffset(&F, Address - StartAddress); - - EffectiveSize = ZFF.getSize(); - break; - } - } - - Layout.setFragmentEffectiveSize(&F, EffectiveSize); - } + for (MCSectionData::iterator it = SD.begin(), ie = SD.end(); it != ie; ++it) + LayoutFragment(Layout, *it); // Set the section sizes. uint64_t Size = 0; |