Index: llvm/trunk/include/llvm/MC/MCMachObjectWriter.h =================================================================== --- llvm/trunk/include/llvm/MC/MCMachObjectWriter.h +++ llvm/trunk/include/llvm/MC/MCMachObjectWriter.h @@ -116,11 +116,16 @@ MachSymbolData *findSymbolData(const MCSymbol &Sym); + void writeWithPadding(StringRef Str, uint64_t Size); + public: MachObjectWriter(std::unique_ptr MOTW, raw_pwrite_stream &OS, bool IsLittleEndian) : MCObjectWriter(OS, IsLittleEndian), - TargetObjectWriter(std::move(MOTW)) {} + TargetObjectWriter(std::move(MOTW)), + W(OS, IsLittleEndian ? support::little : support::big) {} + + support::endian::Writer W; const MCSymbol &findAliasedSymbol(const MCSymbol &Sym) const; Index: llvm/trunk/lib/MC/ELFObjectWriter.cpp =================================================================== --- llvm/trunk/lib/MC/ELFObjectWriter.cpp +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp @@ -160,10 +160,12 @@ bool ZLibStyle, unsigned Alignment); public: + support::endian::Writer W; + ELFObjectWriter(std::unique_ptr MOTW, raw_pwrite_stream &OS, bool IsLittleEndian) - : MCObjectWriter(OS, IsLittleEndian), - TargetObjectWriter(std::move(MOTW)) {} + : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(std::move(MOTW)), + W(OS, IsLittleEndian ? support::little : support::big) {} ~ELFObjectWriter() override = default; @@ -175,16 +177,15 @@ MCObjectWriter::reset(); } - void WriteWord(uint64_t W) { + void WriteWord(uint64_t Word) { if (is64Bit()) - write64(W); + W.write(Word); else - write32(W); + W.write(Word); } template void write(T Val) { - support::endian::write(getStream(), Val, - IsLittleEndian ? support::little : support::big); + W.write(Val); } void writeHeader(const MCAssembler &Asm); @@ -255,8 +256,8 @@ } // end anonymous namespace void ELFObjectWriter::align(unsigned Alignment) { - uint64_t Padding = OffsetToAlignment(getStream().tell(), Alignment); - WriteZeros(Padding); + uint64_t Padding = OffsetToAlignment(W.OS.tell(), Alignment); + W.OS.write_zeros(Padding); } unsigned ELFObjectWriter::addToSectionTable(const MCSectionELF *Sec) { @@ -325,47 +326,50 @@ // emitWord method behaves differently for ELF32 and ELF64, writing // 4 bytes in the former and 8 in the latter. - writeBytes(ELF::ElfMagic); // e_ident[EI_MAG0] to e_ident[EI_MAG3] + W.OS << ELF::ElfMagic; // e_ident[EI_MAG0] to e_ident[EI_MAG3] - write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] + W.OS << char(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] // e_ident[EI_DATA] - write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); + W.OS << char(W.Endian == support::little ? ELF::ELFDATA2LSB + : ELF::ELFDATA2MSB); - write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] + W.OS << char(ELF::EV_CURRENT); // e_ident[EI_VERSION] // e_ident[EI_OSABI] - write8(TargetObjectWriter->getOSABI()); - write8(0); // e_ident[EI_ABIVERSION] + W.OS << char(TargetObjectWriter->getOSABI()); + W.OS << char(0); // e_ident[EI_ABIVERSION] - WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD); + W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD); - write16(ELF::ET_REL); // e_type + W.write(ELF::ET_REL); // e_type - write16(TargetObjectWriter->getEMachine()); // e_machine = target + W.write(TargetObjectWriter->getEMachine()); // e_machine = target - write32(ELF::EV_CURRENT); // e_version + W.write(ELF::EV_CURRENT); // e_version WriteWord(0); // e_entry, no entry point in .o file WriteWord(0); // e_phoff, no program header for .o WriteWord(0); // e_shoff = sec hdr table off in bytes // e_flags = whatever the target wants - write32(Asm.getELFHeaderEFlags()); + W.write(Asm.getELFHeaderEFlags()); // e_ehsize = ELF header size - write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr)); + W.write(is64Bit() ? sizeof(ELF::Elf64_Ehdr) + : sizeof(ELF::Elf32_Ehdr)); - write16(0); // e_phentsize = prog header entry size - write16(0); // e_phnum = # prog header entries = 0 + W.write(0); // e_phentsize = prog header entry size + W.write(0); // e_phnum = # prog header entries = 0 // e_shentsize = Section header entry size - write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr)); + W.write(is64Bit() ? sizeof(ELF::Elf64_Shdr) + : sizeof(ELF::Elf32_Shdr)); // e_shnum = # of section header ents - write16(0); + W.write(0); // e_shstrndx = Section # of '.shstrtab' assert(StringTableIndex < ELF::SHN_LORESERVE); - write16(StringTableIndex); + W.write(StringTableIndex); } uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym, @@ -784,7 +788,7 @@ SymbolTableIndex = addToSectionTable(SymtabSection); align(SymtabSection->getAlignment()); - uint64_t SecStart = getStream().tell(); + uint64_t SecStart = W.OS.tell(); // The first entry is the undefined symbol entry. Writer.writeSymbol(0, 0, 0, 0, 0, 0, false); @@ -900,7 +904,7 @@ assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL); } - uint64_t SecEnd = getStream().tell(); + uint64_t SecEnd = W.OS.tell(); SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd); ArrayRef ShndxIndexes = Writer.getShndxIndexes(); @@ -910,12 +914,12 @@ } assert(SymtabShndxSectionIndex != 0); - SecStart = getStream().tell(); + SecStart = W.OS.tell(); const MCSectionELF *SymtabShndxSection = SectionTable[SymtabShndxSectionIndex - 1]; for (uint32_t Index : ShndxIndexes) write(Index); - SecEnd = getStream().tell(); + SecEnd = W.OS.tell(); SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd); } @@ -976,8 +980,8 @@ const StringRef Magic = "ZLIB"; if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size()) return false; - write(ArrayRef(Magic.begin(), Magic.size())); - writeBE64(Size); + W.OS << Magic; + support::endian::write(W.OS, Size, support::big); return true; } @@ -996,7 +1000,7 @@ MAI->compressDebugSections() != DebugCompressionType::None; if (!CompressionEnabled || !SectionName.startswith(".debug_") || SectionName == ".debug_frame") { - Asm.writeSectionData(getStream(), &Section, Layout); + Asm.writeSectionData(W.OS, &Section, Layout); return; } @@ -1013,14 +1017,14 @@ StringRef(UncompressedData.data(), UncompressedData.size()), CompressedContents)) { consumeError(std::move(E)); - getStream() << UncompressedData; + W.OS << UncompressedData; return; } bool ZlibStyle = MAI->compressDebugSections() == DebugCompressionType::Z; if (!maybeWriteCompression(UncompressedData.size(), CompressedContents, ZlibStyle, Sec.getAlignment())) { - getStream() << UncompressedData; + W.OS << UncompressedData; return; } @@ -1030,7 +1034,7 @@ else // Add "z" prefix to section name. This is zlib-gnu style. MC.renameELFSection(&Section, (".z" + SectionName.drop_front(1)).str()); - getStream() << CompressedContents; + W.OS << CompressedContents; } void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, @@ -1039,14 +1043,14 @@ uint32_t Link, uint32_t Info, uint64_t Alignment, uint64_t EntrySize) { - write32(Name); // sh_name: index into string table - write32(Type); // sh_type + W.write(Name); // sh_name: index into string table + W.write(Type); // sh_type WriteWord(Flags); // sh_flags WriteWord(Address); // sh_addr WriteWord(Offset); // sh_offset WriteWord(Size); // sh_size - write32(Link); // sh_link - write32(Info); // sh_info + W.write(Link); // sh_link + W.write(Info); // sh_info WriteWord(Alignment); // sh_addralign WriteWord(EntrySize); // sh_entsize } @@ -1116,7 +1120,7 @@ const MCSectionELF *ELFObjectWriter::createStringTable(MCContext &Ctx) { const MCSectionELF *StrtabSection = SectionTable[StringTableIndex - 1]; - StrTabBuilder.write(getStream()); + StrTabBuilder.write(W.OS); return StrtabSection; } @@ -1226,12 +1230,12 @@ align(Section.getAlignment()); // Remember the offset into the file for this section. - uint64_t SecStart = getStream().tell(); + uint64_t SecStart = W.OS.tell(); const MCSymbolELF *SignatureSymbol = Section.getGroup(); writeSectionData(Asm, Section, Layout); - uint64_t SecEnd = getStream().tell(); + uint64_t SecEnd = W.OS.tell(); SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd); MCSectionELF *RelSection = createRelocationSection(Ctx, Section); @@ -1263,7 +1267,7 @@ align(Group->getAlignment()); // Remember the offset into the file for this section. - uint64_t SecStart = getStream().tell(); + uint64_t SecStart = W.OS.tell(); const MCSymbol *SignatureSymbol = Group->getGroup(); assert(SignatureSymbol); @@ -1273,7 +1277,7 @@ write(SecIndex); } - uint64_t SecEnd = getStream().tell(); + uint64_t SecEnd = W.OS.tell(); SectionOffsets[Group] = std::make_pair(SecStart, SecEnd); } @@ -1284,54 +1288,52 @@ align(RelSection->getAlignment()); // Remember the offset into the file for this section. - uint64_t SecStart = getStream().tell(); + uint64_t SecStart = W.OS.tell(); writeRelocations(Asm, cast(*RelSection->getAssociatedSection())); - uint64_t SecEnd = getStream().tell(); + uint64_t SecEnd = W.OS.tell(); SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd); } { - uint64_t SecStart = getStream().tell(); + uint64_t SecStart = W.OS.tell(); const MCSectionELF *Sec = createStringTable(Ctx); - uint64_t SecEnd = getStream().tell(); + uint64_t SecEnd = W.OS.tell(); SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd); } uint64_t NaturalAlignment = is64Bit() ? 8 : 4; align(NaturalAlignment); - const uint64_t SectionHeaderOffset = getStream().tell(); + const uint64_t SectionHeaderOffset = W.OS.tell(); // ... then the section header table ... writeSectionHeader(Layout, SectionIndexMap, SectionOffsets); - uint16_t NumSections = (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) - ? (uint16_t)ELF::SHN_UNDEF - : SectionTable.size() + 1; - if (sys::IsLittleEndianHost != IsLittleEndian) - sys::swapByteOrder(NumSections); + uint16_t NumSections = support::endian::byte_swap( + (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF + : SectionTable.size() + 1, + W.Endian); unsigned NumSectionsOffset; + auto &Stream = static_cast(W.OS); if (is64Bit()) { - uint64_t Val = SectionHeaderOffset; - if (sys::IsLittleEndianHost != IsLittleEndian) - sys::swapByteOrder(Val); - getStream().pwrite(reinterpret_cast(&Val), sizeof(Val), - offsetof(ELF::Elf64_Ehdr, e_shoff)); + uint64_t Val = + support::endian::byte_swap(SectionHeaderOffset, W.Endian); + Stream.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); - getStream().pwrite(reinterpret_cast(&Val), sizeof(Val), - offsetof(ELF::Elf32_Ehdr, e_shoff)); + uint32_t Val = + support::endian::byte_swap(SectionHeaderOffset, W.Endian); + Stream.pwrite(reinterpret_cast(&Val), sizeof(Val), + offsetof(ELF::Elf32_Ehdr, e_shoff)); NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum); } - getStream().pwrite(reinterpret_cast(&NumSections), - sizeof(NumSections), NumSectionsOffset); + Stream.pwrite(reinterpret_cast(&NumSections), sizeof(NumSections), + NumSectionsOffset); } bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl( Index: llvm/trunk/lib/MC/MCLinkerOptimizationHint.cpp =================================================================== --- llvm/trunk/lib/MC/MCLinkerOptimizationHint.cpp +++ llvm/trunk/lib/MC/MCLinkerOptimizationHint.cpp @@ -36,7 +36,7 @@ void MCLOHDirective::emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { - raw_ostream &OutStream = ObjWriter.getStream(); + raw_ostream &OutStream = ObjWriter.W.OS; emit_impl(OutStream, ObjWriter, Layout); } Index: llvm/trunk/lib/MC/MachObjectWriter.cpp =================================================================== --- llvm/trunk/lib/MC/MachObjectWriter.cpp +++ llvm/trunk/lib/MC/MachObjectWriter.cpp @@ -141,24 +141,29 @@ // struct mach_header (28 bytes) or // struct mach_header_64 (32 bytes) - uint64_t Start = getStream().tell(); + uint64_t Start = W.OS.tell(); (void) Start; - write32(is64Bit() ? MachO::MH_MAGIC_64 : MachO::MH_MAGIC); + W.write(is64Bit() ? MachO::MH_MAGIC_64 : MachO::MH_MAGIC); - write32(TargetObjectWriter->getCPUType()); - write32(TargetObjectWriter->getCPUSubtype()); + W.write(TargetObjectWriter->getCPUType()); + W.write(TargetObjectWriter->getCPUSubtype()); - write32(Type); - write32(NumLoadCommands); - write32(LoadCommandsSize); - write32(Flags); + W.write(Type); + W.write(NumLoadCommands); + W.write(LoadCommandsSize); + W.write(Flags); if (is64Bit()) - write32(0); // reserved + W.write(0); // reserved - assert( - getStream().tell() - Start == - (is64Bit() ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header))); + assert(W.OS.tell() - Start == (is64Bit() ? sizeof(MachO::mach_header_64) + : sizeof(MachO::mach_header))); +} + +void MachObjectWriter::writeWithPadding(StringRef Str, uint64_t Size) { + assert(Size >= Str.size()); + W.OS << Str; + W.OS.write_zeros(Size - Str.size()); } /// writeSegmentLoadCommand - Write a segment load command. @@ -172,38 +177,37 @@ // struct segment_command (56 bytes) or // struct segment_command_64 (72 bytes) - uint64_t Start = getStream().tell(); + uint64_t Start = W.OS.tell(); (void) Start; unsigned SegmentLoadCommandSize = is64Bit() ? sizeof(MachO::segment_command_64): sizeof(MachO::segment_command); - write32(is64Bit() ? MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT); - write32(SegmentLoadCommandSize + + W.write(is64Bit() ? MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT); + W.write(SegmentLoadCommandSize + NumSections * (is64Bit() ? sizeof(MachO::section_64) : sizeof(MachO::section))); - assert(Name.size() <= 16); - writeBytes(Name, 16); + writeWithPadding(Name, 16); if (is64Bit()) { - write64(VMAddr); // vmaddr - write64(VMSize); // vmsize - write64(SectionDataStartOffset); // file offset - write64(SectionDataSize); // file size + W.write(VMAddr); // vmaddr + W.write(VMSize); // vmsize + W.write(SectionDataStartOffset); // file offset + W.write(SectionDataSize); // file size } else { - write32(VMAddr); // vmaddr - write32(VMSize); // vmsize - write32(SectionDataStartOffset); // file offset - write32(SectionDataSize); // file size + W.write(VMAddr); // vmaddr + W.write(VMSize); // vmsize + W.write(SectionDataStartOffset); // file offset + W.write(SectionDataSize); // file size } // maxprot - write32(MaxProt); + W.write(MaxProt); // initprot - write32(InitProt); - write32(NumSections); - write32(0); // flags + W.write(InitProt); + W.write(NumSections); + W.write(0); // flags - assert(getStream().tell() - Start == SegmentLoadCommandSize); + assert(W.OS.tell() - Start == SegmentLoadCommandSize); } void MachObjectWriter::writeSection(const MCAsmLayout &Layout, @@ -223,31 +227,31 @@ // struct section (68 bytes) or // struct section_64 (80 bytes) - uint64_t Start = getStream().tell(); + uint64_t Start = W.OS.tell(); (void) Start; - writeBytes(Section.getSectionName(), 16); - writeBytes(Section.getSegmentName(), 16); + writeWithPadding(Section.getSectionName(), 16); + writeWithPadding(Section.getSegmentName(), 16); if (is64Bit()) { - write64(VMAddr); // address - write64(SectionSize); // size + W.write(VMAddr); // address + W.write(SectionSize); // size } else { - write32(VMAddr); // address - write32(SectionSize); // size + W.write(VMAddr); // address + W.write(SectionSize); // size } - write32(FileOffset); + W.write(FileOffset); assert(isPowerOf2_32(Section.getAlignment()) && "Invalid alignment!"); - write32(Log2_32(Section.getAlignment())); - write32(NumRelocations ? RelocationsStart : 0); - write32(NumRelocations); - write32(Flags); - write32(IndirectSymBase.lookup(&Sec)); // reserved1 - write32(Section.getStubSize()); // reserved2 + W.write(Log2_32(Section.getAlignment())); + W.write(NumRelocations ? RelocationsStart : 0); + W.write(NumRelocations); + W.write(Flags); + W.write(IndirectSymBase.lookup(&Sec)); // reserved1 + W.write(Section.getStubSize()); // reserved2 if (is64Bit()) - write32(0); // reserved3 + W.write(0); // reserved3 - assert(getStream().tell() - Start == + assert(W.OS.tell() - Start == (is64Bit() ? sizeof(MachO::section_64) : sizeof(MachO::section))); } @@ -257,17 +261,17 @@ uint32_t StringTableSize) { // struct symtab_command (24 bytes) - uint64_t Start = getStream().tell(); + uint64_t Start = W.OS.tell(); (void) Start; - write32(MachO::LC_SYMTAB); - write32(sizeof(MachO::symtab_command)); - write32(SymbolOffset); - write32(NumSymbols); - write32(StringTableOffset); - write32(StringTableSize); + W.write(MachO::LC_SYMTAB); + W.write(sizeof(MachO::symtab_command)); + W.write(SymbolOffset); + W.write(NumSymbols); + W.write(StringTableOffset); + W.write(StringTableSize); - assert(getStream().tell() - Start == sizeof(MachO::symtab_command)); + assert(W.OS.tell() - Start == sizeof(MachO::symtab_command)); } void MachObjectWriter::writeDysymtabLoadCommand(uint32_t FirstLocalSymbol, @@ -280,31 +284,31 @@ uint32_t NumIndirectSymbols) { // struct dysymtab_command (80 bytes) - uint64_t Start = getStream().tell(); + uint64_t Start = W.OS.tell(); (void) Start; - write32(MachO::LC_DYSYMTAB); - write32(sizeof(MachO::dysymtab_command)); - write32(FirstLocalSymbol); - write32(NumLocalSymbols); - write32(FirstExternalSymbol); - write32(NumExternalSymbols); - write32(FirstUndefinedSymbol); - write32(NumUndefinedSymbols); - write32(0); // tocoff - write32(0); // ntoc - write32(0); // modtaboff - write32(0); // nmodtab - write32(0); // extrefsymoff - write32(0); // nextrefsyms - write32(IndirectSymbolOffset); - write32(NumIndirectSymbols); - write32(0); // extreloff - write32(0); // nextrel - write32(0); // locreloff - write32(0); // nlocrel + W.write(MachO::LC_DYSYMTAB); + W.write(sizeof(MachO::dysymtab_command)); + W.write(FirstLocalSymbol); + W.write(NumLocalSymbols); + W.write(FirstExternalSymbol); + W.write(NumExternalSymbols); + W.write(FirstUndefinedSymbol); + W.write(NumUndefinedSymbols); + W.write(0); // tocoff + W.write(0); // ntoc + W.write(0); // modtaboff + W.write(0); // nmodtab + W.write(0); // extrefsymoff + W.write(0); // nextrefsyms + W.write(IndirectSymbolOffset); + W.write(NumIndirectSymbols); + W.write(0); // extreloff + W.write(0); // nextrel + W.write(0); // locreloff + W.write(0); // nlocrel - assert(getStream().tell() - Start == sizeof(MachO::dysymtab_command)); + assert(W.OS.tell() - Start == sizeof(MachO::dysymtab_command)); } MachObjectWriter::MachSymbolData * @@ -384,33 +388,33 @@ // struct nlist (12 bytes) - write32(MSD.StringIndex); - write8(Type); - write8(SectionIndex); + W.write(MSD.StringIndex); + W.OS << char(Type); + W.OS << char(SectionIndex); // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc' // value. bool EncodeAsAltEntry = IsAlias && cast(OrigSymbol).isAltEntry(); - write16(cast(Symbol)->getEncodedFlags(EncodeAsAltEntry)); + W.write(cast(Symbol)->getEncodedFlags(EncodeAsAltEntry)); if (is64Bit()) - write64(Address); + W.write(Address); else - write32(Address); + W.write(Address); } void MachObjectWriter::writeLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, uint32_t DataSize) { - uint64_t Start = getStream().tell(); + uint64_t Start = W.OS.tell(); (void) Start; - write32(Type); - write32(sizeof(MachO::linkedit_data_command)); - write32(DataOffset); - write32(DataSize); + W.write(Type); + W.write(sizeof(MachO::linkedit_data_command)); + W.write(DataOffset); + W.write(DataSize); - assert(getStream().tell() - Start == sizeof(MachO::linkedit_data_command)); + assert(W.OS.tell() - Start == sizeof(MachO::linkedit_data_command)); } static unsigned ComputeLinkerOptionsLoadCommandSize( @@ -426,23 +430,23 @@ const std::vector &Options) { unsigned Size = ComputeLinkerOptionsLoadCommandSize(Options, is64Bit()); - uint64_t Start = getStream().tell(); + uint64_t Start = W.OS.tell(); (void) Start; - write32(MachO::LC_LINKER_OPTION); - write32(Size); - write32(Options.size()); + W.write(MachO::LC_LINKER_OPTION); + W.write(Size); + W.write(Options.size()); uint64_t BytesWritten = sizeof(MachO::linker_option_command); for (const std::string &Option : Options) { // Write each string, including the null byte. - writeBytes(Option, Option.size() + 1); + W.OS << Option << '\0'; BytesWritten += Option.size() + 1; } // Pad to a multiple of the pointer size. - writeBytes("", OffsetToAlignment(BytesWritten, is64Bit() ? 8 : 4)); + W.OS.write_zeros(OffsetToAlignment(BytesWritten, is64Bit() ? 8 : 4)); - assert(getStream().tell() - Start == Size); + assert(W.OS.tell() - Start == Size); } void MachObjectWriter::recordRelocation(MCAssembler &Asm, @@ -611,7 +615,7 @@ // Set the Index and the IsExtern bit. unsigned Index = Rel.Sym->getIndex(); assert(isInt<24>(Index)); - if (IsLittleEndian) + if (W.Endian == support::little) Rel.MRE.r_word1 = (Rel.MRE.r_word1 & (~0U << 24)) | Index | (1 << 27); else Rel.MRE.r_word1 = (Rel.MRE.r_word1 & 0xff) | Index << 8 | (1 << 4); @@ -847,19 +851,19 @@ (VersionInfo.Major << 16); if (VersionInfo.EmitBuildVersion) { // FIXME: Currently empty tools. Add clang version in the future. - write32(MachO::LC_BUILD_VERSION); - write32(sizeof(MachO::build_version_command)); - write32(VersionInfo.TypeOrPlatform.Platform); - write32(EncodedVersion); - write32(0); // SDK version. - write32(0); // Empty tools list. + W.write(MachO::LC_BUILD_VERSION); + W.write(sizeof(MachO::build_version_command)); + W.write(VersionInfo.TypeOrPlatform.Platform); + W.write(EncodedVersion); + W.write(0); // SDK version. + W.write(0); // Empty tools list. } else { MachO::LoadCommandType LCType = getLCFromMCVM(VersionInfo.TypeOrPlatform.Type); - write32(LCType); - write32(sizeof(MachO::version_min_command)); - write32(EncodedVersion); - write32(0); // reserved. + W.write(LCType); + W.write(sizeof(MachO::version_min_command)); + W.write(EncodedVersion); + W.write(0); // reserved. } } @@ -919,14 +923,14 @@ // Write the actual section data. for (const MCSection &Sec : Asm) { - Asm.writeSectionData(getStream(), &Sec, Layout); + Asm.writeSectionData(W.OS, &Sec, Layout); uint64_t Pad = getPaddingSize(&Sec, Layout); - WriteZeros(Pad); + W.OS.write_zeros(Pad); } // Write the extra padding. - WriteZeros(SectionDataPadding); + W.OS.write_zeros(SectionDataPadding); // Write the relocation entries. for (const MCSection &Sec : Asm) { @@ -934,8 +938,8 @@ // (approximately, the exact algorithm is more complicated than this). std::vector &Relocs = Relocations[&Sec]; for (const RelAndSymbol &Rel : make_range(Relocs.rbegin(), Relocs.rend())) { - write32(Rel.MRE.r_word0); - write32(Rel.MRE.r_word1); + W.write(Rel.MRE.r_word0); + W.write(Rel.MRE.r_word1); } } @@ -956,20 +960,20 @@ << ")" << " end: " << End << "(" << Data->End->getName() << ")" << " size: " << End - Start << "\n"); - write32(Start); - write16(End - Start); - write16(Data->Kind); + W.write(Start); + W.write(End - Start); + W.write(Data->Kind); } // Write out the loh commands, if there is one. if (LOHSize) { #ifndef NDEBUG - unsigned Start = getStream().tell(); + unsigned Start = W.OS.tell(); #endif Asm.getLOHContainer().emit(*this, Layout); // Pad to a multiple of the pointer size. - writeBytes("", OffsetToAlignment(LOHRawSize, is64Bit() ? 8 : 4)); - assert(getStream().tell() - Start == LOHSize); + W.OS.write_zeros(OffsetToAlignment(LOHRawSize, is64Bit() ? 8 : 4)); + assert(W.OS.tell() - Start == LOHSize); } // Write the symbol table data, if used. @@ -988,12 +992,12 @@ uint32_t Flags = MachO::INDIRECT_SYMBOL_LOCAL; if (it->Symbol->isAbsolute()) Flags |= MachO::INDIRECT_SYMBOL_ABS; - write32(Flags); + W.write(Flags); continue; } } - write32(it->Symbol->getIndex()); + W.write(it->Symbol->getIndex()); } // FIXME: Check that offsets match computed ones. @@ -1005,7 +1009,7 @@ writeNlist(Entry, Layout); // Write the string table. - StringTable.write(getStream()); + StringTable.write(W.OS); } } Index: llvm/trunk/lib/MC/WasmObjectWriter.cpp =================================================================== --- llvm/trunk/lib/MC/WasmObjectWriter.cpp +++ llvm/trunk/lib/MC/WasmObjectWriter.cpp @@ -196,6 +196,8 @@ #endif class WasmObjectWriter : public MCObjectWriter { + support::endian::Writer W; + /// The target specific Wasm writer instance. std::unique_ptr TargetObjectWriter; @@ -250,7 +252,7 @@ public: WasmObjectWriter(std::unique_ptr MOTW, raw_pwrite_stream &OS) - : MCObjectWriter(OS, /*IsLittleEndian=*/true), + : MCObjectWriter(OS, /*IsLittleEndian=*/true), W(OS, support::little), TargetObjectWriter(std::move(MOTW)) {} ~WasmObjectWriter() override; @@ -286,12 +288,12 @@ void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; void writeString(const StringRef Str) { - encodeULEB128(Str.size(), getStream()); - writeBytes(Str); + encodeULEB128(Str.size(), W.OS); + W.OS << Str; } void writeValueType(wasm::ValType Ty) { - write8(static_cast(Ty)); + W.OS << static_cast(Ty); } void writeTypeSection(ArrayRef FunctionTypes); @@ -333,17 +335,17 @@ void WasmObjectWriter::startSection(SectionBookkeeping &Section, unsigned SectionId) { LLVM_DEBUG(dbgs() << "startSection " << SectionId << "\n"); - write8(SectionId); + W.OS << char(SectionId); - Section.SizeOffset = getStream().tell(); + Section.SizeOffset = W.OS.tell(); // The section size. We don't know the size yet, so reserve enough space // for any 32-bit value; we'll patch it later. - encodeULEB128(UINT32_MAX, getStream()); + encodeULEB128(UINT32_MAX, W.OS); // The position where the section starts, for measuring its size. - Section.ContentsOffset = getStream().tell(); - Section.PayloadOffset = getStream().tell(); + Section.ContentsOffset = W.OS.tell(); + Section.PayloadOffset = W.OS.tell(); Section.Index = SectionCount++; } @@ -353,19 +355,19 @@ startSection(Section, wasm::WASM_SEC_CUSTOM); // The position where the section header ends, for measuring its size. - Section.PayloadOffset = getStream().tell(); + Section.PayloadOffset = W.OS.tell(); // Custom sections in wasm also have a string identifier. writeString(Name); // The position where the custom section starts. - Section.ContentsOffset = getStream().tell(); + Section.ContentsOffset = W.OS.tell(); } // Now that the section is complete and we know how big it is, patch up the // section size field at the start of the section. void WasmObjectWriter::endSection(SectionBookkeeping &Section) { - uint64_t Size = getStream().tell() - Section.PayloadOffset; + uint64_t Size = W.OS.tell() - Section.PayloadOffset; if (uint32_t(Size) != Size) report_fatal_error("section size does not fit in a uint32_t"); @@ -376,13 +378,14 @@ uint8_t Buffer[16]; unsigned SizeLen = encodeULEB128(Size, Buffer, 5); assert(SizeLen == 5); - getStream().pwrite((char *)Buffer, SizeLen, Section.SizeOffset); + static_cast(W.OS).pwrite((char *)Buffer, SizeLen, + Section.SizeOffset); } // Emit the Wasm header. void WasmObjectWriter::writeHeader(const MCAssembler &Asm) { - writeBytes(StringRef(wasm::WasmMagic, sizeof(wasm::WasmMagic))); - writeLE32(wasm::WasmVersion); + W.OS.write(wasm::WasmMagic, sizeof(wasm::WasmMagic)); + W.write(wasm::WasmVersion); } void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm, @@ -662,7 +665,7 @@ // directly. void WasmObjectWriter::applyRelocations( ArrayRef Relocations, uint64_t ContentsOffset) { - raw_pwrite_stream &Stream = getStream(); + auto &Stream = static_cast(W.OS); for (const WasmRelocationEntry &RelEntry : Relocations) { uint64_t Offset = ContentsOffset + RelEntry.FixupSection->getSectionOffset() + @@ -702,14 +705,14 @@ SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_TYPE); - encodeULEB128(FunctionTypes.size(), getStream()); + encodeULEB128(FunctionTypes.size(), W.OS); for (const WasmFunctionType &FuncTy : FunctionTypes) { - write8(wasm::WASM_TYPE_FUNC); - encodeULEB128(FuncTy.Params.size(), getStream()); + W.OS << char(wasm::WASM_TYPE_FUNC); + encodeULEB128(FuncTy.Params.size(), W.OS); for (wasm::ValType Ty : FuncTy.Params) writeValueType(Ty); - encodeULEB128(FuncTy.Returns.size(), getStream()); + encodeULEB128(FuncTy.Returns.size(), W.OS); for (wasm::ValType Ty : FuncTy.Returns) writeValueType(Ty); } @@ -728,28 +731,28 @@ SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_IMPORT); - encodeULEB128(Imports.size(), getStream()); + encodeULEB128(Imports.size(), W.OS); for (const wasm::WasmImport &Import : Imports) { writeString(Import.Module); writeString(Import.Field); - write8(Import.Kind); + W.OS << char(Import.Kind); switch (Import.Kind) { case wasm::WASM_EXTERNAL_FUNCTION: - encodeULEB128(Import.SigIndex, getStream()); + encodeULEB128(Import.SigIndex, W.OS); break; case wasm::WASM_EXTERNAL_GLOBAL: - write8(Import.Global.Type); - write8(Import.Global.Mutable ? 1 : 0); + W.OS << char(Import.Global.Type); + W.OS << char(Import.Global.Mutable ? 1 : 0); break; case wasm::WASM_EXTERNAL_MEMORY: - encodeULEB128(0, getStream()); // flags - encodeULEB128(NumPages, getStream()); // initial + encodeULEB128(0, W.OS); // flags + encodeULEB128(NumPages, W.OS); // initial break; case wasm::WASM_EXTERNAL_TABLE: - write8(Import.Table.ElemType); - encodeULEB128(0, getStream()); // flags - encodeULEB128(NumElements, getStream()); // initial + W.OS << char(Import.Table.ElemType); + encodeULEB128(0, W.OS); // flags + encodeULEB128(NumElements, W.OS); // initial break; default: llvm_unreachable("unsupported import kind"); @@ -766,9 +769,9 @@ SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_FUNCTION); - encodeULEB128(Functions.size(), getStream()); + encodeULEB128(Functions.size(), W.OS); for (const WasmFunction &Func : Functions) - encodeULEB128(Func.Type, getStream()); + encodeULEB128(Func.Type, W.OS); endSection(Section); } @@ -780,14 +783,14 @@ SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_GLOBAL); - encodeULEB128(Globals.size(), getStream()); + encodeULEB128(Globals.size(), W.OS); for (const WasmGlobal &Global : Globals) { writeValueType(static_cast(Global.Type.Type)); - write8(Global.Type.Mutable); + W.OS << char(Global.Type.Mutable); - write8(wasm::WASM_OPCODE_I32_CONST); - encodeSLEB128(Global.InitialValue, getStream()); - write8(wasm::WASM_OPCODE_END); + W.OS << char(wasm::WASM_OPCODE_I32_CONST); + encodeSLEB128(Global.InitialValue, W.OS); + W.OS << char(wasm::WASM_OPCODE_END); } endSection(Section); @@ -800,11 +803,11 @@ SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_EXPORT); - encodeULEB128(Exports.size(), getStream()); + encodeULEB128(Exports.size(), W.OS); for (const wasm::WasmExport &Export : Exports) { writeString(Export.Name); - write8(Export.Kind); - encodeULEB128(Export.Index, getStream()); + W.OS << char(Export.Kind); + encodeULEB128(Export.Index, W.OS); } endSection(Section); @@ -817,17 +820,17 @@ SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_ELEM); - encodeULEB128(1, getStream()); // number of "segments" - encodeULEB128(0, getStream()); // the table index + encodeULEB128(1, W.OS); // number of "segments" + encodeULEB128(0, W.OS); // the table index // init expr for starting offset - write8(wasm::WASM_OPCODE_I32_CONST); - encodeSLEB128(kInitialTableOffset, getStream()); - write8(wasm::WASM_OPCODE_END); + W.OS << char(wasm::WASM_OPCODE_I32_CONST); + encodeSLEB128(kInitialTableOffset, W.OS); + W.OS << char(wasm::WASM_OPCODE_END); - encodeULEB128(TableElems.size(), getStream()); + encodeULEB128(TableElems.size(), W.OS); for (uint32_t Elem : TableElems) - encodeULEB128(Elem, getStream()); + encodeULEB128(Elem, W.OS); endSection(Section); } @@ -842,7 +845,7 @@ startSection(Section, wasm::WASM_SEC_CODE); CodeSectionIndex = Section.Index; - encodeULEB128(Functions.size(), getStream()); + encodeULEB128(Functions.size(), W.OS); for (const WasmFunction &Func : Functions) { auto &FuncSection = static_cast(Func.Sym->getSection()); @@ -851,9 +854,9 @@ if (!Func.Sym->getSize()->evaluateAsAbsolute(Size, Layout)) report_fatal_error(".size expression must be evaluatable"); - encodeULEB128(Size, getStream()); - FuncSection.setSectionOffset(getStream().tell() - Section.ContentsOffset); - Asm.writeSectionData(getStream(), &FuncSection, Layout); + encodeULEB128(Size, W.OS); + FuncSection.setSectionOffset(W.OS.tell() - Section.ContentsOffset); + Asm.writeSectionData(W.OS, &FuncSection, Layout); } // Apply fixups. @@ -870,16 +873,16 @@ startSection(Section, wasm::WASM_SEC_DATA); DataSectionIndex = Section.Index; - encodeULEB128(DataSegments.size(), getStream()); // count + encodeULEB128(DataSegments.size(), W.OS); // count for (const WasmDataSegment &Segment : DataSegments) { - encodeULEB128(0, getStream()); // memory index - write8(wasm::WASM_OPCODE_I32_CONST); - encodeSLEB128(Segment.Offset, getStream()); // offset - write8(wasm::WASM_OPCODE_END); - encodeULEB128(Segment.Data.size(), getStream()); // size - Segment.Section->setSectionOffset(getStream().tell() - Section.ContentsOffset); - writeBytes(Segment.Data); // data + encodeULEB128(0, W.OS); // memory index + W.OS << char(wasm::WASM_OPCODE_I32_CONST); + encodeSLEB128(Segment.Offset, W.OS); // offset + W.OS << char(wasm::WASM_OPCODE_END); + encodeULEB128(Segment.Data.size(), W.OS); // size + Segment.Section->setSectionOffset(W.OS.tell() - Section.ContentsOffset); + W.OS << Segment.Data; // data } // Apply fixups. @@ -900,20 +903,18 @@ SectionBookkeeping Section; startCustomSection(Section, std::string("reloc.") + Name.str()); - raw_pwrite_stream &Stream = getStream(); - - encodeULEB128(SectionIndex, Stream); - encodeULEB128(Relocations.size(), Stream); + encodeULEB128(SectionIndex, W.OS); + encodeULEB128(Relocations.size(), W.OS); for (const WasmRelocationEntry& RelEntry : Relocations) { uint64_t Offset = RelEntry.Offset + RelEntry.FixupSection->getSectionOffset(); uint32_t Index = getRelocationIndexValue(RelEntry); - write8(RelEntry.Type); - encodeULEB128(Offset, Stream); - encodeULEB128(Index, Stream); + W.OS << char(RelEntry.Type); + encodeULEB128(Offset, W.OS); + encodeULEB128(Index, W.OS); if (RelEntry.hasAddend()) - encodeSLEB128(RelEntry.Addend, Stream); + encodeSLEB128(RelEntry.Addend, W.OS); } endSection(Section); @@ -932,34 +933,34 @@ const std::map> &Comdats) { SectionBookkeeping Section; startCustomSection(Section, "linking"); - encodeULEB128(wasm::WasmMetadataVersion, getStream()); + encodeULEB128(wasm::WasmMetadataVersion, W.OS); SectionBookkeeping SubSection; if (SymbolInfos.size() != 0) { startSection(SubSection, wasm::WASM_SYMBOL_TABLE); - encodeULEB128(SymbolInfos.size(), getStream()); + encodeULEB128(SymbolInfos.size(), W.OS); for (const wasm::WasmSymbolInfo &Sym : SymbolInfos) { - encodeULEB128(Sym.Kind, getStream()); - encodeULEB128(Sym.Flags, getStream()); + encodeULEB128(Sym.Kind, W.OS); + encodeULEB128(Sym.Flags, W.OS); switch (Sym.Kind) { case wasm::WASM_SYMBOL_TYPE_FUNCTION: case wasm::WASM_SYMBOL_TYPE_GLOBAL: - encodeULEB128(Sym.ElementIndex, getStream()); + encodeULEB128(Sym.ElementIndex, W.OS); if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) writeString(Sym.Name); break; case wasm::WASM_SYMBOL_TYPE_DATA: writeString(Sym.Name); if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) { - encodeULEB128(Sym.DataRef.Segment, getStream()); - encodeULEB128(Sym.DataRef.Offset, getStream()); - encodeULEB128(Sym.DataRef.Size, getStream()); + encodeULEB128(Sym.DataRef.Segment, W.OS); + encodeULEB128(Sym.DataRef.Offset, W.OS); + encodeULEB128(Sym.DataRef.Size, W.OS); } break; case wasm::WASM_SYMBOL_TYPE_SECTION: { const uint32_t SectionIndex = CustomSections[Sym.ElementIndex].OutputIndex; - encodeULEB128(SectionIndex, getStream()); + encodeULEB128(SectionIndex, W.OS); break; } default: @@ -971,35 +972,35 @@ if (DataSegments.size()) { startSection(SubSection, wasm::WASM_SEGMENT_INFO); - encodeULEB128(DataSegments.size(), getStream()); + encodeULEB128(DataSegments.size(), W.OS); for (const WasmDataSegment &Segment : DataSegments) { writeString(Segment.Name); - encodeULEB128(Segment.Alignment, getStream()); - encodeULEB128(Segment.Flags, getStream()); + encodeULEB128(Segment.Alignment, W.OS); + encodeULEB128(Segment.Flags, W.OS); } endSection(SubSection); } if (!InitFuncs.empty()) { startSection(SubSection, wasm::WASM_INIT_FUNCS); - encodeULEB128(InitFuncs.size(), getStream()); + encodeULEB128(InitFuncs.size(), W.OS); for (auto &StartFunc : InitFuncs) { - encodeULEB128(StartFunc.first, getStream()); // priority - encodeULEB128(StartFunc.second, getStream()); // function index + encodeULEB128(StartFunc.first, W.OS); // priority + encodeULEB128(StartFunc.second, W.OS); // function index } endSection(SubSection); } if (Comdats.size()) { startSection(SubSection, wasm::WASM_COMDAT_INFO); - encodeULEB128(Comdats.size(), getStream()); + encodeULEB128(Comdats.size(), W.OS); for (const auto &C : Comdats) { writeString(C.first); - encodeULEB128(0, getStream()); // flags for future use - encodeULEB128(C.second.size(), getStream()); + encodeULEB128(0, W.OS); // flags for future use + encodeULEB128(C.second.size(), W.OS); for (const WasmComdatEntry &Entry : C.second) { - encodeULEB128(Entry.Kind, getStream()); - encodeULEB128(Entry.Index, getStream()); + encodeULEB128(Entry.Kind, W.OS); + encodeULEB128(Entry.Index, W.OS); } } endSection(SubSection); @@ -1015,8 +1016,8 @@ auto *Sec = CustomSection.Section; startCustomSection(Section, CustomSection.Name); - Sec->setSectionOffset(getStream().tell() - Section.ContentsOffset); - Asm.writeSectionData(getStream(), Sec, Layout); + Sec->setSectionOffset(W.OS.tell() - Section.ContentsOffset); + Asm.writeSectionData(W.OS, 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 @@ -125,6 +125,8 @@ class WinCOFFObjectWriter : public MCObjectWriter { public: + support::endian::Writer W; + using symbols = std::vector>; using sections = std::vector>; @@ -225,7 +227,8 @@ WinCOFFObjectWriter::WinCOFFObjectWriter( std::unique_ptr MOTW, raw_pwrite_stream &OS) - : MCObjectWriter(OS, true), TargetObjectWriter(std::move(MOTW)) { + : MCObjectWriter(OS, true), W(OS, support::little), + TargetObjectWriter(std::move(MOTW)) { Header.Machine = TargetObjectWriter->getMachine(); } @@ -472,40 +475,40 @@ void WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) { if (UseBigObj) { - writeLE16(COFF::IMAGE_FILE_MACHINE_UNKNOWN); - writeLE16(0xFFFF); - writeLE16(COFF::BigObjHeader::MinBigObjectVersion); - writeLE16(Header.Machine); - writeLE32(Header.TimeDateStamp); - writeBytes(StringRef(COFF::BigObjMagic, sizeof(COFF::BigObjMagic))); - writeLE32(0); - writeLE32(0); - writeLE32(0); - writeLE32(0); - writeLE32(Header.NumberOfSections); - writeLE32(Header.PointerToSymbolTable); - writeLE32(Header.NumberOfSymbols); + W.write(COFF::IMAGE_FILE_MACHINE_UNKNOWN); + W.write(0xFFFF); + W.write(COFF::BigObjHeader::MinBigObjectVersion); + W.write(Header.Machine); + W.write(Header.TimeDateStamp); + W.OS.write(COFF::BigObjMagic, sizeof(COFF::BigObjMagic)); + W.write(0); + W.write(0); + W.write(0); + W.write(0); + W.write(Header.NumberOfSections); + W.write(Header.PointerToSymbolTable); + W.write(Header.NumberOfSymbols); } else { - writeLE16(Header.Machine); - writeLE16(static_cast(Header.NumberOfSections)); - writeLE32(Header.TimeDateStamp); - writeLE32(Header.PointerToSymbolTable); - writeLE32(Header.NumberOfSymbols); - writeLE16(Header.SizeOfOptionalHeader); - writeLE16(Header.Characteristics); + W.write(Header.Machine); + W.write(static_cast(Header.NumberOfSections)); + W.write(Header.TimeDateStamp); + W.write(Header.PointerToSymbolTable); + W.write(Header.NumberOfSymbols); + W.write(Header.SizeOfOptionalHeader); + W.write(Header.Characteristics); } } void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol &S) { - writeBytes(StringRef(S.Data.Name, COFF::NameSize)); - writeLE32(S.Data.Value); + W.OS.write(S.Data.Name, COFF::NameSize); + W.write(S.Data.Value); if (UseBigObj) - writeLE32(S.Data.SectionNumber); + W.write(S.Data.SectionNumber); else - writeLE16(static_cast(S.Data.SectionNumber)); - writeLE16(S.Data.Type); - write8(S.Data.StorageClass); - write8(S.Data.NumberOfAuxSymbols); + W.write(static_cast(S.Data.SectionNumber)); + W.write(S.Data.Type); + W.OS << char(S.Data.StorageClass); + W.OS << char(S.Data.NumberOfAuxSymbols); WriteAuxiliarySymbols(S.Aux); } @@ -514,46 +517,45 @@ for (const AuxSymbol &i : S) { switch (i.AuxType) { case ATFunctionDefinition: - writeLE32(i.Aux.FunctionDefinition.TagIndex); - writeLE32(i.Aux.FunctionDefinition.TotalSize); - writeLE32(i.Aux.FunctionDefinition.PointerToLinenumber); - writeLE32(i.Aux.FunctionDefinition.PointerToNextFunction); - WriteZeros(sizeof(i.Aux.FunctionDefinition.unused)); + W.write(i.Aux.FunctionDefinition.TagIndex); + W.write(i.Aux.FunctionDefinition.TotalSize); + W.write(i.Aux.FunctionDefinition.PointerToLinenumber); + W.write(i.Aux.FunctionDefinition.PointerToNextFunction); + W.OS.write_zeros(sizeof(i.Aux.FunctionDefinition.unused)); if (UseBigObj) - WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size); + W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size); break; case ATbfAndefSymbol: - WriteZeros(sizeof(i.Aux.bfAndefSymbol.unused1)); - writeLE16(i.Aux.bfAndefSymbol.Linenumber); - WriteZeros(sizeof(i.Aux.bfAndefSymbol.unused2)); - writeLE32(i.Aux.bfAndefSymbol.PointerToNextFunction); - WriteZeros(sizeof(i.Aux.bfAndefSymbol.unused3)); + W.OS.write_zeros(sizeof(i.Aux.bfAndefSymbol.unused1)); + W.write(i.Aux.bfAndefSymbol.Linenumber); + W.OS.write_zeros(sizeof(i.Aux.bfAndefSymbol.unused2)); + W.write(i.Aux.bfAndefSymbol.PointerToNextFunction); + W.OS.write_zeros(sizeof(i.Aux.bfAndefSymbol.unused3)); if (UseBigObj) - WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size); + W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size); break; case ATWeakExternal: - writeLE32(i.Aux.WeakExternal.TagIndex); - writeLE32(i.Aux.WeakExternal.Characteristics); - WriteZeros(sizeof(i.Aux.WeakExternal.unused)); + W.write(i.Aux.WeakExternal.TagIndex); + W.write(i.Aux.WeakExternal.Characteristics); + W.OS.write_zeros(sizeof(i.Aux.WeakExternal.unused)); if (UseBigObj) - WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size); + W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size); break; case ATFile: - writeBytes( - StringRef(reinterpret_cast(&i.Aux), - UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size)); + W.OS.write(reinterpret_cast(&i.Aux), + UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size); break; case ATSectionDefinition: - writeLE32(i.Aux.SectionDefinition.Length); - writeLE16(i.Aux.SectionDefinition.NumberOfRelocations); - writeLE16(i.Aux.SectionDefinition.NumberOfLinenumbers); - writeLE32(i.Aux.SectionDefinition.CheckSum); - writeLE16(static_cast(i.Aux.SectionDefinition.Number)); - write8(i.Aux.SectionDefinition.Selection); - WriteZeros(sizeof(i.Aux.SectionDefinition.unused)); - writeLE16(static_cast(i.Aux.SectionDefinition.Number >> 16)); + W.write(i.Aux.SectionDefinition.Length); + W.write(i.Aux.SectionDefinition.NumberOfRelocations); + W.write(i.Aux.SectionDefinition.NumberOfLinenumbers); + W.write(i.Aux.SectionDefinition.CheckSum); + W.write(static_cast(i.Aux.SectionDefinition.Number)); + W.OS << char(i.Aux.SectionDefinition.Selection); + W.OS.write_zeros(sizeof(i.Aux.SectionDefinition.unused)); + W.write(static_cast(i.Aux.SectionDefinition.Number >> 16)); if (UseBigObj) - WriteZeros(COFF::Symbol32Size - COFF::Symbol16Size); + W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size); break; } } @@ -579,23 +581,23 @@ COFF::section &S = Section->Header; if (Section->Relocations.size() >= 0xffff) S.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL; - writeBytes(StringRef(S.Name, COFF::NameSize)); - writeLE32(S.VirtualSize); - writeLE32(S.VirtualAddress); - writeLE32(S.SizeOfRawData); - writeLE32(S.PointerToRawData); - writeLE32(S.PointerToRelocations); - writeLE32(S.PointerToLineNumbers); - writeLE16(S.NumberOfRelocations); - writeLE16(S.NumberOfLineNumbers); - writeLE32(S.Characteristics); + W.OS.write(S.Name, COFF::NameSize); + W.write(S.VirtualSize); + W.write(S.VirtualAddress); + W.write(S.SizeOfRawData); + W.write(S.PointerToRawData); + W.write(S.PointerToRelocations); + W.write(S.PointerToLineNumbers); + W.write(S.NumberOfRelocations); + W.write(S.NumberOfLineNumbers); + W.write(S.Characteristics); } } void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) { - writeLE32(R.VirtualAddress); - writeLE32(R.SymbolTableIndex); - writeLE16(R.Type); + W.write(R.VirtualAddress); + W.write(R.SymbolTableIndex); + W.write(R.Type); } // Write MCSec's contents. What this function does is essentially @@ -611,7 +613,7 @@ Asm.writeSectionData(VecOS, &MCSec, Layout); // Write the section contents to the object file. - getStream() << Buf; + W.OS << Buf; // Calculate our CRC with an initial value of '0', this is not how // JamCRC is specified but it aligns with the expected output. @@ -629,13 +631,13 @@ // Write the section contents. if (Sec.Header.PointerToRawData != 0) { - assert(getStream().tell() <= Sec.Header.PointerToRawData && + assert(W.OS.tell() <= Sec.Header.PointerToRawData && "Section::PointerToRawData is insane!"); - unsigned PaddingSize = Sec.Header.PointerToRawData - getStream().tell(); + unsigned PaddingSize = Sec.Header.PointerToRawData - W.OS.tell(); assert(PaddingSize < 4 && "Should only need at most three bytes of padding!"); - WriteZeros(PaddingSize); + W.OS.write_zeros(PaddingSize); uint32_t CRC = writeSectionContents(Asm, Layout, MCSec); @@ -654,7 +656,7 @@ return; } - assert(getStream().tell() == Sec.Header.PointerToRelocations && + assert(W.OS.tell() == Sec.Header.PointerToRelocations && "Section::PointerToRelocations is insane!"); if (Sec.Relocations.size() >= 0xffff) { @@ -900,7 +902,7 @@ // Assign file offsets to COFF object file structures. void WinCOFFObjectWriter::assignFileOffsets(MCAssembler &Asm, const MCAsmLayout &Layout) { - unsigned Offset = getInitialOffset(); + unsigned Offset = W.OS.tell(); Offset += UseBigObj ? COFF::Header32Size : COFF::Header16Size; Offset += COFF::SectionSize * Header.NumberOfSections; @@ -1058,7 +1060,7 @@ for (; I != IE && J != JE; ++I, ++J) writeSection(Asm, Layout, **I, *J); - assert(getStream().tell() == Header.PointerToSymbolTable && + assert(W.OS.tell() == Header.PointerToSymbolTable && "Header::PointerToSymbolTable is insane!"); // Write a symbol table. @@ -1067,7 +1069,7 @@ WriteSymbol(*Symbol); // Write a string table, which completes the entire COFF file. - Strings.write(getStream()); + Strings.write(W.OS); } MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_) Index: llvm/trunk/tools/dsymutil/MachOUtils.cpp =================================================================== --- llvm/trunk/tools/dsymutil/MachOUtils.cpp +++ llvm/trunk/tools/dsymutil/MachOUtils.cpp @@ -225,7 +225,7 @@ template static void transferSegmentAndSections( const object::MachOObjectFile::LoadCommandInfo &LCI, SegmentTy Segment, - const object::MachOObjectFile &Obj, MCObjectWriter &Writer, + const object::MachOObjectFile &Obj, MachObjectWriter &Writer, uint64_t LinkeditOffset, uint64_t LinkeditSize, uint64_t DwarfSegmentSize, uint64_t &GapForDwarf, uint64_t &EndAddress) { if (StringRef("__DWARF") == Segment.segname) @@ -255,14 +255,13 @@ unsigned nsects = Segment.nsects; if (Obj.isLittleEndian() != sys::IsLittleEndianHost) MachO::swapStruct(Segment); - Writer.writeBytes( - StringRef(reinterpret_cast(&Segment), sizeof(Segment))); + Writer.W.OS.write(reinterpret_cast(&Segment), sizeof(Segment)); for (unsigned i = 0; i < nsects; ++i) { auto Sect = getSection(Obj, Segment, LCI, i); Sect.offset = Sect.reloff = Sect.nreloc = 0; if (Obj.isLittleEndian() != sys::IsLittleEndianHost) MachO::swapStruct(Sect); - Writer.writeBytes(StringRef(reinterpret_cast(&Sect), sizeof(Sect))); + Writer.W.OS.write(reinterpret_cast(&Sect), sizeof(Sect)); } } @@ -429,10 +428,9 @@ // Write the load commands. assert(OutFile.tell() == HeaderSize); if (UUIDCmd.cmd != 0) { - Writer.write32(UUIDCmd.cmd); - Writer.write32(UUIDCmd.cmdsize); - Writer.writeBytes( - StringRef(reinterpret_cast(UUIDCmd.uuid), 16)); + Writer.W.write(UUIDCmd.cmd); + Writer.W.write(UUIDCmd.cmdsize); + OutFile.write(reinterpret_cast(UUIDCmd.uuid), 16); assert(OutFile.tell() == HeaderSize + sizeof(UUIDCmd)); } @@ -479,12 +477,12 @@ NumDwarfSections, Layout, Writer); assert(OutFile.tell() == LoadCommandSize + HeaderSize); - Writer.WriteZeros(SymtabStart - (LoadCommandSize + HeaderSize)); + OutFile.write_zeros(SymtabStart - (LoadCommandSize + HeaderSize)); assert(OutFile.tell() == SymtabStart); // Transfer symbols. if (ShouldEmitSymtab) { - Writer.writeBytes(NewSymtab.str()); + OutFile << NewSymtab.str(); assert(OutFile.tell() == StringStart); // Transfer string table. @@ -492,21 +490,20 @@ // dsymutil-classic starts the reconstructed string table with 2 of these. // Reproduce that behavior for now (there is corresponding code in // transferSymbol). - Writer.WriteZeros(1); + OutFile << '\0'; std::vector Strings = NewStrings.getEntries(); for (auto EntryRef : Strings) { if (EntryRef.getIndex() == -1U) break; - StringRef ZeroTerminated(EntryRef.getString().data(), - EntryRef.getString().size() + 1); - Writer.writeBytes(ZeroTerminated); + OutFile.write(EntryRef.getString().data(), + EntryRef.getString().size() + 1); } } assert(OutFile.tell() == StringStart + NewStringsSize); // Pad till the Dwarf segment start. - Writer.WriteZeros(DwarfSegmentStart - (StringStart + NewStringsSize)); + OutFile.write_zeros(DwarfSegmentStart - (StringStart + NewStringsSize)); assert(OutFile.tell() == DwarfSegmentStart); // Emit the Dwarf sections contents. @@ -515,7 +512,7 @@ continue; uint64_t Pos = OutFile.tell(); - Writer.WriteZeros(alignTo(Pos, Sec.getAlignment()) - Pos); + OutFile.write_zeros(alignTo(Pos, Sec.getAlignment()) - Pos); MCAsm.writeSectionData(OutFile, &Sec, Layout); }