diff options
Diffstat (limited to 'llvm/lib/MC/WasmObjectWriter.cpp')
-rw-r--r-- | llvm/lib/MC/WasmObjectWriter.cpp | 179 |
1 files changed, 90 insertions, 89 deletions
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp index daefd5d2b54..cbb12cab71e 100644 --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -196,6 +196,8 @@ raw_ostream &operator<<(raw_ostream &OS, const WasmRelocationEntry &Rel) { #endif class WasmObjectWriter : public MCObjectWriter { + support::endian::Writer W; + /// The target specific Wasm writer instance. std::unique_ptr<MCWasmObjectTargetWriter> TargetObjectWriter; @@ -250,7 +252,7 @@ class WasmObjectWriter : public MCObjectWriter { public: WasmObjectWriter(std::unique_ptr<MCWasmObjectTargetWriter> 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 @@ private: 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<uint8_t>(Ty)); + W.OS << static_cast<char>(Ty); } void writeTypeSection(ArrayRef<WasmFunctionType> FunctionTypes); @@ -333,17 +335,17 @@ WasmObjectWriter::~WasmObjectWriter() {} 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 @@ void WasmObjectWriter::startCustomSection(SectionBookkeeping &Section, 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 @@ void WasmObjectWriter::endSection(SectionBookkeeping &Section) { uint8_t Buffer[16]; unsigned SizeLen = encodeULEB128(Size, Buffer, 5); assert(SizeLen == 5); - getStream().pwrite((char *)Buffer, SizeLen, Section.SizeOffset); + static_cast<raw_pwrite_stream &>(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<uint32_t>(wasm::WasmVersion); } void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm, @@ -662,7 +665,7 @@ WasmObjectWriter::getRelocationIndexValue(const WasmRelocationEntry &RelEntry) { // directly. void WasmObjectWriter::applyRelocations( ArrayRef<WasmRelocationEntry> Relocations, uint64_t ContentsOffset) { - raw_pwrite_stream &Stream = getStream(); + auto &Stream = static_cast<raw_pwrite_stream &>(W.OS); for (const WasmRelocationEntry &RelEntry : Relocations) { uint64_t Offset = ContentsOffset + RelEntry.FixupSection->getSectionOffset() + @@ -702,14 +705,14 @@ void WasmObjectWriter::writeTypeSection( 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 @@ void WasmObjectWriter::writeImportSection(ArrayRef<wasm::WasmImport> Imports, 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 @@ void WasmObjectWriter::writeFunctionSection(ArrayRef<WasmFunction> Functions) { 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 @@ void WasmObjectWriter::writeGlobalSection() { 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<wasm::ValType>(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 @@ void WasmObjectWriter::writeExportSection(ArrayRef<wasm::WasmExport> Exports) { 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 @@ void WasmObjectWriter::writeElemSection(ArrayRef<uint32_t> TableElems) { 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 @@ void WasmObjectWriter::writeCodeSection(const MCAssembler &Asm, 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<MCSectionWasm &>(Func.Sym->getSection()); @@ -851,9 +854,9 @@ void WasmObjectWriter::writeCodeSection(const MCAssembler &Asm, 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 @@ void WasmObjectWriter::writeDataSection() { 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 @@ void WasmObjectWriter::writeRelocSection( 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 @@ void WasmObjectWriter::writeLinkingMetaDataSection( const std::map<StringRef, std::vector<WasmComdatEntry>> &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 @@ void WasmObjectWriter::writeLinkingMetaDataSection( 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 @@ void WasmObjectWriter::writeCustomSections(const MCAssembler &Asm, 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; |