diff options
Diffstat (limited to 'llvm/lib/MC/MCAssembler.cpp')
-rw-r--r-- | llvm/lib/MC/MCAssembler.cpp | 83 |
1 files changed, 42 insertions, 41 deletions
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index 40f1ab4312d..f72c3fda8f0 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -450,8 +450,8 @@ void MCAssembler::registerSymbol(const MCSymbol &Symbol, bool *Created) { } } -void MCAssembler::writeFragmentPadding(const MCFragment &F, uint64_t FSize, - MCObjectWriter *OW) const { +void MCAssembler::writeFragmentPadding(raw_ostream &OS, const MCFragment &F, + uint64_t FSize) const { assert(getBackendPtr() && "Expected assembler backend"); // Should NOP padding be written out before this fragment? unsigned BundlePadding = F.getBundlePadding(); @@ -472,31 +472,30 @@ void MCAssembler::writeFragmentPadding(const MCFragment &F, uint64_t FSize, // ---------------------------- // ^-------------------^ <- TotalLength unsigned DistanceToBoundary = TotalLength - getBundleAlignSize(); - if (!getBackend().writeNopData(OW->getStream(), DistanceToBoundary)) + if (!getBackend().writeNopData(OS, DistanceToBoundary)) report_fatal_error("unable to write NOP sequence of " + Twine(DistanceToBoundary) + " bytes"); BundlePadding -= DistanceToBoundary; } - if (!getBackend().writeNopData(OW->getStream(), BundlePadding)) + if (!getBackend().writeNopData(OS, BundlePadding)) report_fatal_error("unable to write NOP sequence of " + Twine(BundlePadding) + " bytes"); } } /// Write the fragment \p F to the output file. -static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment &F) { - MCObjectWriter *OW = Asm.getWriterPtr(); - assert(OW && "Need ObjectWriter to write fragment"); - +static void writeFragment(raw_ostream &OS, const MCAssembler &Asm, + const MCAsmLayout &Layout, const MCFragment &F) { // FIXME: Embed in fragments instead? uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F); - Asm.writeFragmentPadding(F, FragmentSize, OW); + support::endianness Endian = Asm.getBackend().Endian; + + Asm.writeFragmentPadding(OS, F, FragmentSize); // This variable (and its dummy usage) is to participate in the assert at // the end of the function. - uint64_t Start = OW->getStream().tell(); + uint64_t Start = OS.tell(); (void) Start; ++stats::EmittedFragments; @@ -523,7 +522,7 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, // bytes left to fill use the Value and ValueSize to fill the rest. // If we are aligning with nops, ask that target to emit the right data. if (AF.hasEmitNops()) { - if (!Asm.getBackend().writeNopData(OW->getStream(), Count)) + if (!Asm.getBackend().writeNopData(OS, Count)) report_fatal_error("unable to write nop sequence of " + Twine(Count) + " bytes"); break; @@ -533,10 +532,16 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, for (uint64_t i = 0; i != Count; ++i) { switch (AF.getValueSize()) { default: llvm_unreachable("Invalid size!"); - case 1: OW->write8 (uint8_t (AF.getValue())); break; - case 2: OW->write16(uint16_t(AF.getValue())); break; - case 4: OW->write32(uint32_t(AF.getValue())); break; - case 8: OW->write64(uint64_t(AF.getValue())); break; + case 1: OS << char(AF.getValue()); break; + case 2: + support::endian::write<uint16_t>(OS, AF.getValue(), Endian); + break; + case 4: + support::endian::write<uint32_t>(OS, AF.getValue(), Endian); + break; + case 8: + support::endian::write<uint64_t>(OS, AF.getValue(), Endian); + break; } } break; @@ -544,17 +549,17 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, case MCFragment::FT_Data: ++stats::EmittedDataFragments; - OW->writeBytes(cast<MCDataFragment>(F).getContents()); + OS << cast<MCDataFragment>(F).getContents(); break; case MCFragment::FT_Relaxable: ++stats::EmittedRelaxableFragments; - OW->writeBytes(cast<MCRelaxableFragment>(F).getContents()); + OS << cast<MCRelaxableFragment>(F).getContents(); break; case MCFragment::FT_CompactEncodedInst: ++stats::EmittedCompactEncodedInstFragments; - OW->writeBytes(cast<MCCompactEncodedInstFragment>(F).getContents()); + OS << cast<MCCompactEncodedInstFragment>(F).getContents(); break; case MCFragment::FT_Fill: { @@ -565,10 +570,9 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, const unsigned MaxChunkSize = 16; char Data[MaxChunkSize]; // Duplicate V into Data as byte vector to reduce number of - // writes done. As such, do endian conversion here, not in OW. - const bool isLittleEndian = Asm.getContext().getAsmInfo()->isLittleEndian(); + // writes done. As such, do endian conversion here. for (unsigned I = 0; I != VSize; ++I) { - unsigned index = isLittleEndian ? I : (VSize - I - 1); + unsigned index = Endian == support::little ? I : (VSize - I - 1); Data[I] = uint8_t(V >> (index * 8)); } for (unsigned I = VSize; I < MaxChunkSize; ++I) @@ -582,25 +586,23 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, // Do copies by chunk. StringRef Ref(Data, ChunkSize); for (uint64_t I = 0, E = FragmentSize / ChunkSize; I != E; ++I) - OW->writeBytes(Ref); + OS << Ref; // do remainder if needed. unsigned TrailingCount = FragmentSize % ChunkSize; - if (TrailingCount) { - StringRef RefTail(Data, TrailingCount); - OW->writeBytes(RefTail); - } + if (TrailingCount) + OS.write(Data, TrailingCount); break; } case MCFragment::FT_LEB: { const MCLEBFragment &LF = cast<MCLEBFragment>(F); - OW->writeBytes(LF.getContents()); + OS << LF.getContents(); break; } case MCFragment::FT_Padding: { - if (!Asm.getBackend().writeNopData(OW->getStream(), FragmentSize)) + if (!Asm.getBackend().writeNopData(OS, FragmentSize)) report_fatal_error("unable to write nop sequence of " + Twine(FragmentSize) + " bytes"); break; @@ -608,7 +610,7 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, case MCFragment::FT_SymbolId: { const MCSymbolIdFragment &SF = cast<MCSymbolIdFragment>(F); - OW->write32(SF.getSymbol()->getIndex()); + support::endian::write<uint32_t>(OS, SF.getSymbol()->getIndex(), Endian); break; } @@ -617,40 +619,40 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCOrgFragment &OF = cast<MCOrgFragment>(F); for (uint64_t i = 0, e = FragmentSize; i != e; ++i) - OW->write8(uint8_t(OF.getValue())); + OS << char(OF.getValue()); break; } case MCFragment::FT_Dwarf: { const MCDwarfLineAddrFragment &OF = cast<MCDwarfLineAddrFragment>(F); - OW->writeBytes(OF.getContents()); + OS << OF.getContents(); break; } case MCFragment::FT_DwarfFrame: { const MCDwarfCallFrameFragment &CF = cast<MCDwarfCallFrameFragment>(F); - OW->writeBytes(CF.getContents()); + OS << CF.getContents(); break; } case MCFragment::FT_CVInlineLines: { const auto &OF = cast<MCCVInlineLineTableFragment>(F); - OW->writeBytes(OF.getContents()); + OS << OF.getContents(); break; } case MCFragment::FT_CVDefRange: { const auto &DRF = cast<MCCVDefRangeFragment>(F); - OW->writeBytes(DRF.getContents()); + OS << DRF.getContents(); break; } case MCFragment::FT_Dummy: llvm_unreachable("Should not have been added"); } - assert(OW->getStream().tell() - Start == FragmentSize && + assert(OS.tell() - Start == FragmentSize && "The stream should advance by fragment size"); } -void MCAssembler::writeSectionData(const MCSection *Sec, +void MCAssembler::writeSectionData(raw_ostream &OS, const MCSection *Sec, const MCAsmLayout &Layout) const { assert(getBackendPtr() && "Expected assembler backend"); @@ -696,14 +698,13 @@ void MCAssembler::writeSectionData(const MCSection *Sec, return; } - uint64_t Start = getWriter().getStream().tell(); + uint64_t Start = OS.tell(); (void)Start; for (const MCFragment &F : *Sec) - writeFragment(*this, Layout, F); + writeFragment(OS, *this, Layout, F); - assert(getWriter().getStream().tell() - Start == - Layout.getSectionAddressSize(Sec)); + assert(OS.tell() - Start == Layout.getSectionAddressSize(Sec)); } std::tuple<MCValue, uint64_t, bool> |