Index: llvm/trunk/include/llvm/MC/MCObjectWriter.h =================================================================== --- llvm/trunk/include/llvm/MC/MCObjectWriter.h +++ llvm/trunk/include/llvm/MC/MCObjectWriter.h @@ -40,14 +40,14 @@ MCObjectWriter(const MCObjectWriter &) = delete; void operator=(const MCObjectWriter &) = delete; -protected: - raw_pwrite_stream &OS; + raw_pwrite_stream *OS; +protected: unsigned IsLittleEndian : 1; protected: // Can only create subclasses. MCObjectWriter(raw_pwrite_stream &OS, bool IsLittleEndian) - : OS(OS), IsLittleEndian(IsLittleEndian) {} + : OS(&OS), IsLittleEndian(IsLittleEndian) {} public: virtual ~MCObjectWriter(); @@ -57,7 +57,8 @@ bool isLittleEndian() const { return IsLittleEndian; } - raw_ostream &getStream() { return OS; } + raw_pwrite_stream &getStream() { return *OS; } + void setStream(raw_pwrite_stream &NewOS) { OS = &NewOS; } /// \name High-Level API /// @{ @@ -113,30 +114,30 @@ /// \name Binary Output /// @{ - void write8(uint8_t Value) { OS << char(Value); } + void write8(uint8_t Value) { *OS << char(Value); } void writeLE16(uint16_t Value) { - support::endian::Writer(OS).write(Value); + support::endian::Writer(*OS).write(Value); } void writeLE32(uint32_t Value) { - support::endian::Writer(OS).write(Value); + support::endian::Writer(*OS).write(Value); } void writeLE64(uint64_t Value) { - support::endian::Writer(OS).write(Value); + support::endian::Writer(*OS).write(Value); } void writeBE16(uint16_t Value) { - support::endian::Writer(OS).write(Value); + support::endian::Writer(*OS).write(Value); } void writeBE32(uint32_t Value) { - support::endian::Writer(OS).write(Value); + support::endian::Writer(*OS).write(Value); } void writeBE64(uint64_t Value) { - support::endian::Writer(OS).write(Value); + support::endian::Writer(*OS).write(Value); } void write16(uint16_t Value) { @@ -164,9 +165,9 @@ const char Zeros[16] = {0}; for (unsigned i = 0, e = N / 16; i != e; ++i) - OS << StringRef(Zeros, 16); + *OS << StringRef(Zeros, 16); - OS << StringRef(Zeros, N % 16); + *OS << StringRef(Zeros, N % 16); } void writeBytes(const SmallVectorImpl &ByteVec, @@ -180,7 +181,7 @@ assert( (ZeroFillSize == 0 || Str.size() <= ZeroFillSize) && "data size greater than fill size, unexpected large write will occur"); - OS << Str; + *OS << Str; if (ZeroFillSize) WriteZeros(ZeroFillSize - Str.size()); } Index: llvm/trunk/lib/MC/ELFObjectWriter.cpp =================================================================== --- llvm/trunk/lib/MC/ELFObjectWriter.cpp +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp @@ -157,9 +157,9 @@ template void write(T Val) { if (IsLittleEndian) - support::endian::Writer(OS).write(Val); + support::endian::Writer(getStream()).write(Val); else - support::endian::Writer(OS).write(Val); + support::endian::Writer(getStream()).write(Val); } void writeHeader(const MCAssembler &Asm); @@ -232,7 +232,7 @@ } void ELFObjectWriter::align(unsigned Alignment) { - uint64_t Padding = OffsetToAlignment(OS.tell(), Alignment); + uint64_t Padding = OffsetToAlignment(getStream().tell(), Alignment); WriteZeros(Padding); } @@ -764,7 +764,7 @@ SymbolTableIndex = addToSectionTable(SymtabSection); align(SymtabSection->getAlignment()); - uint64_t SecStart = OS.tell(); + uint64_t SecStart = getStream().tell(); // The first entry is the undefined symbol entry. Writer.writeSymbol(0, 0, 0, 0, 0, 0, false); @@ -911,7 +911,7 @@ assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL); } - uint64_t SecEnd = OS.tell(); + uint64_t SecEnd = getStream().tell(); SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd); ArrayRef ShndxIndexes = Writer.getShndxIndexes(); @@ -921,12 +921,12 @@ } assert(SymtabShndxSectionIndex != 0); - SecStart = OS.tell(); + SecStart = getStream().tell(); const MCSectionELF *SymtabShndxSection = SectionTable[SymtabShndxSectionIndex - 1]; for (uint32_t Index : ShndxIndexes) write(Index); - SecEnd = OS.tell(); + SecEnd = getStream().tell(); SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd); } @@ -957,31 +957,6 @@ return RelaSection; } -static SmallVector -getUncompressedData(const MCAsmLayout &Layout, - const MCSection::FragmentListType &Fragments) { - SmallVector UncompressedData; - for (const MCFragment &F : Fragments) { - const SmallVectorImpl *Contents; - switch (F.getKind()) { - case MCFragment::FT_Data: - Contents = &cast(F).getContents(); - break; - case MCFragment::FT_Dwarf: - Contents = &cast(F).getContents(); - break; - case MCFragment::FT_DwarfFrame: - Contents = &cast(F).getContents(); - break; - default: - llvm_unreachable( - "Not expecting any other fragment types in a debug_* section"); - } - UncompressedData.append(Contents->begin(), Contents->end()); - } - return UncompressedData; -} - // Include the debug info compression header: // "ZLIB" followed by 8 bytes representing the uncompressed size of the section, // useful for consumers to preallocate a buffer to decompress into. @@ -1016,27 +991,29 @@ return; } - // Gather the uncompressed data from all the fragments. - const MCSection::FragmentListType &Fragments = Section.getFragmentList(); - SmallVector UncompressedData = - getUncompressedData(Layout, Fragments); + SmallVector UncompressedData; + raw_svector_ostream VecOS(UncompressedData); + raw_pwrite_stream &OldStream = getStream(); + setStream(VecOS); + Asm.writeSectionData(&Section, Layout); + setStream(OldStream); SmallVector CompressedContents; zlib::Status Success = zlib::compress( StringRef(UncompressedData.data(), UncompressedData.size()), CompressedContents); if (Success != zlib::StatusOK) { - Asm.writeSectionData(&Section, Layout); + getStream() << UncompressedData; return; } if (!prependCompressionHeader(UncompressedData.size(), CompressedContents)) { - Asm.writeSectionData(&Section, Layout); + getStream() << UncompressedData; return; } Asm.getContext().renameELFSection(&Section, (".z" + SectionName.drop_front(1)).str()); - OS << CompressedContents; + getStream() << CompressedContents; } void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, @@ -1100,7 +1077,7 @@ const MCSectionELF *ELFObjectWriter::createStringTable(MCContext &Ctx) { const MCSectionELF *StrtabSection = SectionTable[StringTableIndex - 1]; - OS << StrTabBuilder.data(); + getStream() << StrTabBuilder.data(); return StrtabSection; } @@ -1209,12 +1186,12 @@ align(Section.getAlignment()); // Remember the offset into the file for this section. - uint64_t SecStart = OS.tell(); + uint64_t SecStart = getStream().tell(); const MCSymbolELF *SignatureSymbol = Section.getGroup(); writeSectionData(Asm, Section, Layout); - uint64_t SecEnd = OS.tell(); + uint64_t SecEnd = getStream().tell(); SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd); MCSectionELF *RelSection = createRelocationSection(Ctx, Section); @@ -1246,7 +1223,7 @@ align(Group->getAlignment()); // Remember the offset into the file for this section. - uint64_t SecStart = OS.tell(); + uint64_t SecStart = getStream().tell(); const MCSymbol *SignatureSymbol = Group->getGroup(); assert(SignatureSymbol); @@ -1256,7 +1233,7 @@ write(SecIndex); } - uint64_t SecEnd = OS.tell(); + uint64_t SecEnd = getStream().tell(); SectionOffsets[Group] = std::make_pair(SecStart, SecEnd); } @@ -1267,25 +1244,25 @@ align(RelSection->getAlignment()); // Remember the offset into the file for this section. - uint64_t SecStart = OS.tell(); + uint64_t SecStart = getStream().tell(); writeRelocations(Asm, *RelSection->getAssociatedSection()); - uint64_t SecEnd = OS.tell(); + uint64_t SecEnd = getStream().tell(); SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd); } { - uint64_t SecStart = OS.tell(); + uint64_t SecStart = getStream().tell(); const MCSectionELF *Sec = createStringTable(Ctx); - uint64_t SecEnd = OS.tell(); + uint64_t SecEnd = getStream().tell(); SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd); } uint64_t NaturalAlignment = is64Bit() ? 8 : 4; align(NaturalAlignment); - const unsigned SectionHeaderOffset = OS.tell(); + const unsigned SectionHeaderOffset = getStream().tell(); // ... then the section header table ... writeSectionHeader(Layout, SectionIndexMap, SectionOffsets); @@ -1301,19 +1278,19 @@ uint64_t Val = SectionHeaderOffset; if (sys::IsLittleEndianHost != IsLittleEndian) sys::swapByteOrder(Val); - OS.pwrite(reinterpret_cast(&Val), sizeof(Val), - offsetof(ELF::Elf64_Ehdr, e_shoff)); + getStream().pwrite(reinterpret_cast(&Val), sizeof(Val), + offsetof(ELF::Elf64_Ehdr, e_shoff)); NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum); } else { uint32_t Val = SectionHeaderOffset; if (sys::IsLittleEndianHost != IsLittleEndian) sys::swapByteOrder(Val); - OS.pwrite(reinterpret_cast(&Val), sizeof(Val), - offsetof(ELF::Elf32_Ehdr, e_shoff)); + getStream().pwrite(reinterpret_cast(&Val), sizeof(Val), + offsetof(ELF::Elf32_Ehdr, e_shoff)); NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum); } - OS.pwrite(reinterpret_cast(&NumSections), sizeof(NumSections), - NumSectionsOffset); + getStream().pwrite(reinterpret_cast(&NumSections), + sizeof(NumSections), NumSectionsOffset); } bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl( Index: llvm/trunk/lib/MC/MachObjectWriter.cpp =================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp +++ llvm/trunk/lib/MC/MachObjectWriter.cpp @@ -129,7 +129,7 @@ // struct mach_header (28 bytes) or // struct mach_header_64 (32 bytes) - uint64_t Start = OS.tell(); + uint64_t Start = getStream().tell(); (void) Start; write32(is64Bit() ? MachO::MH_MAGIC_64 : MachO::MH_MAGIC); @@ -144,8 +144,9 @@ if (is64Bit()) write32(0); // reserved - assert(OS.tell() - Start == - (is64Bit()?sizeof(MachO::mach_header_64): sizeof(MachO::mach_header))); + assert( + getStream().tell() - Start == + (is64Bit() ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header))); } /// writeSegmentLoadCommand - Write a segment load command. @@ -159,7 +160,7 @@ // struct segment_command (56 bytes) or // struct segment_command_64 (72 bytes) - uint64_t Start = OS.tell(); + uint64_t Start = getStream().tell(); (void) Start; unsigned SegmentLoadCommandSize = @@ -190,7 +191,7 @@ write32(NumSections); write32(0); // flags - assert(OS.tell() - Start == SegmentLoadCommandSize); + assert(getStream().tell() - Start == SegmentLoadCommandSize); } void MachObjectWriter::writeSection(const MCAsmLayout &Layout, @@ -210,7 +211,7 @@ // struct section (68 bytes) or // struct section_64 (80 bytes) - uint64_t Start = OS.tell(); + uint64_t Start = getStream().tell(); (void) Start; writeBytes(Section.getSectionName(), 16); @@ -234,8 +235,8 @@ if (is64Bit()) write32(0); // reserved3 - assert(OS.tell() - Start == (is64Bit() ? sizeof(MachO::section_64) : - sizeof(MachO::section))); + assert(getStream().tell() - Start == + (is64Bit() ? sizeof(MachO::section_64) : sizeof(MachO::section))); } void MachObjectWriter::writeSymtabLoadCommand(uint32_t SymbolOffset, @@ -244,7 +245,7 @@ uint32_t StringTableSize) { // struct symtab_command (24 bytes) - uint64_t Start = OS.tell(); + uint64_t Start = getStream().tell(); (void) Start; write32(MachO::LC_SYMTAB); @@ -254,7 +255,7 @@ write32(StringTableOffset); write32(StringTableSize); - assert(OS.tell() - Start == sizeof(MachO::symtab_command)); + assert(getStream().tell() - Start == sizeof(MachO::symtab_command)); } void MachObjectWriter::writeDysymtabLoadCommand(uint32_t FirstLocalSymbol, @@ -267,7 +268,7 @@ uint32_t NumIndirectSymbols) { // struct dysymtab_command (80 bytes) - uint64_t Start = OS.tell(); + uint64_t Start = getStream().tell(); (void) Start; write32(MachO::LC_DYSYMTAB); @@ -291,7 +292,7 @@ write32(0); // locreloff write32(0); // nlocrel - assert(OS.tell() - Start == sizeof(MachO::dysymtab_command)); + assert(getStream().tell() - Start == sizeof(MachO::dysymtab_command)); } MachObjectWriter::MachSymbolData * @@ -387,7 +388,7 @@ void MachObjectWriter::writeLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, uint32_t DataSize) { - uint64_t Start = OS.tell(); + uint64_t Start = getStream().tell(); (void) Start; write32(Type); @@ -395,7 +396,7 @@ write32(DataOffset); write32(DataSize); - assert(OS.tell() - Start == sizeof(MachO::linkedit_data_command)); + assert(getStream().tell() - Start == sizeof(MachO::linkedit_data_command)); } static unsigned ComputeLinkerOptionsLoadCommandSize( @@ -411,7 +412,7 @@ const std::vector &Options) { unsigned Size = ComputeLinkerOptionsLoadCommandSize(Options, is64Bit()); - uint64_t Start = OS.tell(); + uint64_t Start = getStream().tell(); (void) Start; write32(MachO::LC_LINKER_OPTION); @@ -427,7 +428,7 @@ // Pad to a multiple of the pointer size. writeBytes("", OffsetToAlignment(BytesWritten, is64Bit() ? 8 : 4)); - assert(OS.tell() - Start == Size); + assert(getStream().tell() - Start == Size); } void MachObjectWriter::recordRelocation(MCAssembler &Asm, @@ -906,12 +907,12 @@ // Write out the loh commands, if there is one. if (LOHSize) { #ifndef NDEBUG - unsigned Start = OS.tell(); + unsigned Start = getStream().tell(); #endif Asm.getLOHContainer().emit(*this, Layout); // Pad to a multiple of the pointer size. writeBytes("", OffsetToAlignment(LOHRawSize, is64Bit() ? 8 : 4)); - assert(OS.tell() - Start == LOHSize); + assert(getStream().tell() - Start == LOHSize); } // Write the symbol table data, if used. @@ -947,7 +948,7 @@ writeNlist(Entry, Layout); // Write the string table. - OS << StringTable.data(); + getStream() << StringTable.data(); } } Index: llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp =================================================================== --- llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp +++ llvm/trunk/lib/MC/WinCOFFObjectWriter.cpp @@ -1037,10 +1037,11 @@ continue; if ((*i)->Header.PointerToRawData != 0) { - assert(OS.tell() <= (*i)->Header.PointerToRawData && + assert(getStream().tell() <= (*i)->Header.PointerToRawData && "Section::PointerToRawData is insane!"); - unsigned SectionDataPadding = (*i)->Header.PointerToRawData - OS.tell(); + unsigned SectionDataPadding = + (*i)->Header.PointerToRawData - getStream().tell(); assert(SectionDataPadding < 4 && "Should only need at most three bytes of padding!"); @@ -1050,7 +1051,7 @@ } if ((*i)->Relocations.size() > 0) { - assert(OS.tell() == (*i)->Header.PointerToRelocations && + assert(getStream().tell() == (*i)->Header.PointerToRelocations && "Section::PointerToRelocations is insane!"); if ((*i)->Relocations.size() >= 0xffff) { @@ -1071,14 +1072,14 @@ } } - assert(OS.tell() == Header.PointerToSymbolTable && + assert(getStream().tell() == Header.PointerToSymbolTable && "Header::PointerToSymbolTable is insane!"); for (auto &Symbol : Symbols) if (Symbol->getIndex() != -1) WriteSymbol(*Symbol); - OS.write(Strings.data().data(), Strings.data().size()); + getStream().write(Strings.data().data(), Strings.data().size()); } MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_)