Index: llvm/include/llvm/MC/MCAssembler.h =================================================================== --- llvm/include/llvm/MC/MCAssembler.h +++ llvm/include/llvm/MC/MCAssembler.h @@ -236,8 +236,8 @@ /// defining a separate atom. bool isSymbolLinkerVisible(const MCSymbol &SD) const; - /// Emit the section contents using the given object writer. - void writeSectionData(const MCSection *Section, + /// Emit the section contents to \p OS. + void writeSectionData(raw_ostream &OS, const MCSection *Section, const MCAsmLayout &Layout) const; /// Check whether a given symbol has been flagged with .thumb_func. @@ -431,10 +431,10 @@ FileNames.push_back(FileName); } - /// Write the necessary bundle padding to the given object writer. + /// Write the necessary bundle padding to \p OS. /// Expects a fragment \p F containing instructions and its size \p FSize. - void writeFragmentPadding(const MCFragment &F, uint64_t FSize, - MCObjectWriter *OW) const; + void writeFragmentPadding(raw_ostream &OS, const MCFragment &F, + uint64_t FSize) const; /// @} Index: llvm/lib/MC/ELFObjectWriter.cpp =================================================================== --- llvm/lib/MC/ELFObjectWriter.cpp +++ llvm/lib/MC/ELFObjectWriter.cpp @@ -996,7 +996,7 @@ MAI->compressDebugSections() != DebugCompressionType::None; if (!CompressionEnabled || !SectionName.startswith(".debug_") || SectionName == ".debug_frame") { - Asm.writeSectionData(&Section, Layout); + Asm.writeSectionData(getStream(), &Section, Layout); return; } @@ -1006,10 +1006,7 @@ SmallVector UncompressedData; raw_svector_ostream VecOS(UncompressedData); - raw_pwrite_stream &OldStream = getStream(); - setStream(VecOS); - Asm.writeSectionData(&Section, Layout); - setStream(OldStream); + Asm.writeSectionData(VecOS, &Section, Layout); SmallVector CompressedContents; if (Error E = zlib::compress( Index: llvm/lib/MC/MCAssembler.cpp =================================================================== --- llvm/lib/MC/MCAssembler.cpp +++ llvm/lib/MC/MCAssembler.cpp @@ -443,8 +443,8 @@ } } -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(); @@ -465,31 +465,30 @@ // ---------------------------- // ^-------------------^ <- 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; @@ -516,7 +515,7 @@ // 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; @@ -526,10 +525,16 @@ 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(OS, AF.getValue(), Endian); + break; + case 4: + support::endian::write(OS, AF.getValue(), Endian); + break; + case 8: + support::endian::write(OS, AF.getValue(), Endian); + break; } } break; @@ -537,17 +542,17 @@ case MCFragment::FT_Data: ++stats::EmittedDataFragments; - OW->writeBytes(cast(F).getContents()); + OS << cast(F).getContents(); break; case MCFragment::FT_Relaxable: ++stats::EmittedRelaxableFragments; - OW->writeBytes(cast(F).getContents()); + OS << cast(F).getContents(); break; case MCFragment::FT_CompactEncodedInst: ++stats::EmittedCompactEncodedInstFragments; - OW->writeBytes(cast(F).getContents()); + OS << cast(F).getContents(); break; case MCFragment::FT_Fill: { @@ -564,7 +569,7 @@ for (unsigned ChunkSize = MaxChunkSize; ChunkSize; ChunkSize /= 2) { StringRef Ref(Data, ChunkSize); for (uint64_t I = 0, E = Size / ChunkSize; I != E; ++I) - OW->writeBytes(Ref); + OS << Ref; Size = Size % ChunkSize; } break; @@ -572,12 +577,12 @@ case MCFragment::FT_LEB: { const MCLEBFragment &LF = cast(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; @@ -585,7 +590,7 @@ case MCFragment::FT_SymbolId: { const MCSymbolIdFragment &SF = cast(F); - OW->write32(SF.getSymbol()->getIndex()); + support::endian::write(OS, SF.getSymbol()->getIndex(), Endian); break; } @@ -594,40 +599,40 @@ const MCOrgFragment &OF = cast(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(F); - OW->writeBytes(OF.getContents()); + OS << OF.getContents(); break; } case MCFragment::FT_DwarfFrame: { const MCDwarfCallFrameFragment &CF = cast(F); - OW->writeBytes(CF.getContents()); + OS << CF.getContents(); break; } case MCFragment::FT_CVInlineLines: { const auto &OF = cast(F); - OW->writeBytes(OF.getContents()); + OS << OF.getContents(); break; } case MCFragment::FT_CVDefRange: { const auto &DRF = cast(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"); @@ -673,14 +678,13 @@ 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 Index: llvm/lib/MC/MCELFStreamer.cpp =================================================================== --- llvm/lib/MC/MCELFStreamer.cpp +++ llvm/lib/MC/MCELFStreamer.cpp @@ -68,13 +68,8 @@ if (RequiredBundlePadding > 0) { SmallString<256> Code; raw_svector_ostream VecOS(Code); - { - auto OW = Assembler.getBackend().createObjectWriter(VecOS); - - EF->setBundlePadding(static_cast(RequiredBundlePadding)); - - Assembler.writeFragmentPadding(*EF, FSize, OW.get()); - } + EF->setBundlePadding(static_cast(RequiredBundlePadding)); + Assembler.writeFragmentPadding(VecOS, *EF, FSize); DF->getContents().append(Code.begin(), Code.end()); } Index: llvm/lib/MC/MachObjectWriter.cpp =================================================================== --- llvm/lib/MC/MachObjectWriter.cpp +++ llvm/lib/MC/MachObjectWriter.cpp @@ -919,7 +919,7 @@ // Write the actual section data. for (const MCSection &Sec : Asm) { - Asm.writeSectionData(&Sec, Layout); + Asm.writeSectionData(getStream(), &Sec, Layout); uint64_t Pad = getPaddingSize(&Sec, Layout); WriteZeros(Pad); Index: llvm/lib/MC/WasmObjectWriter.cpp =================================================================== --- llvm/lib/MC/WasmObjectWriter.cpp +++ llvm/lib/MC/WasmObjectWriter.cpp @@ -852,7 +852,7 @@ encodeULEB128(Size, getStream()); FuncSection.setSectionOffset(getStream().tell() - Section.ContentsOffset); - Asm.writeSectionData(&FuncSection, Layout); + Asm.writeSectionData(getStream(), &FuncSection, Layout); } // Apply fixups. @@ -1015,7 +1015,7 @@ startCustomSection(Section, CustomSection.Name); Sec->setSectionOffset(getStream().tell() - Section.ContentsOffset); - Asm.writeSectionData(Sec, Layout); + Asm.writeSectionData(getStream(), Sec, Layout); CustomSection.OutputContentsOffset = Section.ContentsOffset; CustomSection.OutputIndex = Section.Index; Index: llvm/lib/MC/WinCOFFObjectWriter.cpp =================================================================== --- llvm/lib/MC/WinCOFFObjectWriter.cpp +++ llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -608,15 +608,7 @@ // to CRC the data before we dump it into the object file. SmallVector Buf; raw_svector_ostream VecOS(Buf); - raw_pwrite_stream &OldStream = getStream(); - - // Redirect the output stream to our buffer and fill our buffer with - // the section data. - setStream(VecOS); - Asm.writeSectionData(&MCSec, Layout); - - // Reset the stream back to what it was before. - setStream(OldStream); + Asm.writeSectionData(VecOS, &MCSec, Layout); // Write the section contents to the object file. getStream() << Buf; Index: llvm/tools/dsymutil/MachOUtils.cpp =================================================================== --- llvm/tools/dsymutil/MachOUtils.cpp +++ llvm/tools/dsymutil/MachOUtils.cpp @@ -516,7 +516,7 @@ uint64_t Pos = OutFile.tell(); Writer.WriteZeros(alignTo(Pos, Sec.getAlignment()) - Pos); - MCAsm.writeSectionData(&Sec, Layout); + MCAsm.writeSectionData(OutFile, &Sec, Layout); } return true;