Index: llvm/trunk/include/llvm/MC/MCAssembler.h =================================================================== --- llvm/trunk/include/llvm/MC/MCAssembler.h +++ llvm/trunk/include/llvm/MC/MCAssembler.h @@ -238,8 +238,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. @@ -433,10 +433,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/trunk/lib/MC/ELFObjectWriter.cpp =================================================================== --- llvm/trunk/lib/MC/ELFObjectWriter.cpp +++ llvm/trunk/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/trunk/lib/MC/MCAssembler.cpp =================================================================== --- llvm/trunk/lib/MC/MCAssembler.cpp +++ llvm/trunk/lib/MC/MCAssembler.cpp @@ -450,8 +450,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(); @@ -472,31 +472,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; @@ -523,7 +522,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; @@ -533,10 +532,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; @@ -544,17 +549,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: { @@ -565,10 +570,9 @@ 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 @@ // 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(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 @@ case MCFragment::FT_SymbolId: { const MCSymbolIdFragment &SF = cast(F); - OW->write32(SF.getSymbol()->getIndex()); + support::endian::write(OS, SF.getSymbol()->getIndex(), Endian); break; } @@ -617,40 +619,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"); @@ -696,14 +698,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/trunk/lib/MC/MCELFStreamer.cpp =================================================================== --- llvm/trunk/lib/MC/MCELFStreamer.cpp +++ llvm/trunk/lib/MC/MCELFStreamer.cpp @@ -69,13 +69,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/trunk/lib/MC/MachObjectWriter.cpp =================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp +++ llvm/trunk/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/trunk/lib/MC/WasmObjectWriter.cpp =================================================================== --- llvm/trunk/lib/MC/WasmObjectWriter.cpp +++ llvm/trunk/lib/MC/WasmObjectWriter.cpp @@ -853,7 +853,7 @@ encodeULEB128(Size, getStream()); FuncSection.setSectionOffset(getStream().tell() - Section.ContentsOffset); - Asm.writeSectionData(&FuncSection, Layout); + Asm.writeSectionData(getStream(), &FuncSection, Layout); } // Apply fixups. @@ -1016,7 +1016,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/trunk/lib/MC/WinCOFFObjectWriter.cpp =================================================================== --- llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp +++ llvm/trunk/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/trunk/tools/dsymutil/MachOUtils.cpp =================================================================== --- llvm/trunk/tools/dsymutil/MachOUtils.cpp +++ llvm/trunk/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;