diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4765,7 +4765,8 @@ // Add the split debug info name to the command lines here so we // can propagate it to the backend. bool SplitDWARF = (DwarfFission != DwarfFissionKind::None) && - TC.getTriple().isOSBinFormatELF() && + (TC.getTriple().isOSBinFormatELF() || + TC.getTriple().isOSBinFormatWasm()) && (isa(JA) || isa(JA) || isa(JA)); if (SplitDWARF) { diff --git a/llvm/include/llvm/MC/MCWasmObjectWriter.h b/llvm/include/llvm/MC/MCWasmObjectWriter.h --- a/llvm/include/llvm/MC/MCWasmObjectWriter.h +++ b/llvm/include/llvm/MC/MCWasmObjectWriter.h @@ -51,6 +51,9 @@ std::unique_ptr createWasmObjectWriter(std::unique_ptr MOTW, raw_pwrite_stream &OS); +std::unique_ptr +createWasmDwoObjectWriter(std::unique_ptr MOTW, + raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS); } // namespace llvm diff --git a/llvm/lib/MC/MCAsmBackend.cpp b/llvm/lib/MC/MCAsmBackend.cpp --- a/llvm/lib/MC/MCAsmBackend.cpp +++ b/llvm/lib/MC/MCAsmBackend.cpp @@ -54,10 +54,17 @@ MCAsmBackend::createDwoObjectWriter(raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS) const { auto TW = createObjectTargetWriter(); - if (TW->getFormat() != Triple::ELF) + switch (TW->getFormat()) { + case Triple::ELF: + return createELFDwoObjectWriter( + cast(std::move(TW)), OS, DwoOS, + Endian == support::little); + case Triple::Wasm: + return createWasmDwoObjectWriter( + cast(std::move(TW)), OS, DwoOS); + default: report_fatal_error("dwo only supported with ELF"); - return createELFDwoObjectWriter(cast(std::move(TW)), - OS, DwoOS, Endian == support::little); + } } Optional MCAsmBackend::getFixupKind(StringRef Name) const { diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -796,6 +796,10 @@ DwarfFrameSection = Ctx->getWasmSection(".debug_frame", SectionKind::getMetadata()); DwarfPubNamesSection = Ctx->getWasmSection(".debug_pubnames", SectionKind::getMetadata()); DwarfPubTypesSection = Ctx->getWasmSection(".debug_pubtypes", SectionKind::getMetadata()); + DwarfGnuPubNamesSection = + Ctx->getWasmSection(".debug_gnu_pubnames", SectionKind::getMetadata()); + DwarfGnuPubTypesSection = + Ctx->getWasmSection(".debug_gnu_pubtypes", SectionKind::getMetadata()); DwarfDebugNamesSection = Ctx->getWasmSection(".debug_names", SectionKind::getMetadata()); @@ -808,6 +812,38 @@ DwarfLoclistsSection = Ctx->getWasmSection(".debug_loclists", SectionKind::getMetadata()); + // Fission Sections + DwarfInfoDWOSection = + Ctx->getWasmSection(".debug_info.dwo", SectionKind::getMetadata()); + DwarfTypesDWOSection = + Ctx->getWasmSection(".debug_types.dwo", SectionKind::getMetadata()); + DwarfAbbrevDWOSection = + Ctx->getWasmSection(".debug_abbrev.dwo", SectionKind::getMetadata()); + DwarfStrDWOSection = + Ctx->getWasmSection(".debug_str.dwo", SectionKind::getMetadata()); + // ELF::SHF_MERGE | ELF::SHF_STRINGS | ELF::SHF_EXCLUDE, 1, ""); + DwarfLineDWOSection = + Ctx->getWasmSection(".debug_line.dwo", SectionKind::getMetadata()); + DwarfLocDWOSection = + Ctx->getWasmSection(".debug_loc.dwo", SectionKind::getMetadata()); + DwarfStrOffDWOSection = + Ctx->getWasmSection(".debug_str_offsets.dwo", SectionKind::getMetadata()); + DwarfRnglistsDWOSection = + Ctx->getWasmSection(".debug_rnglists.dwo", SectionKind::getMetadata()); + DwarfMacinfoDWOSection = + Ctx->getWasmSection(".debug_macinfo.dwo", SectionKind::getMetadata()); + DwarfMacroDWOSection = + Ctx->getWasmSection(".debug_macro.dwo", SectionKind::getMetadata()); + + DwarfLoclistsDWOSection = + Ctx->getWasmSection(".debug_loclists.dwo", SectionKind::getMetadata()); + + // DWP Sections + DwarfCUIndexSection = + Ctx->getWasmSection(".debug_cu_index", SectionKind::getMetadata(), 0); + DwarfTUIndexSection = + Ctx->getWasmSection(".debug_tu_index", SectionKind::getMetadata(), 0); + // Wasm use data section for LSDA. // TODO Consider putting each function's exception table in a separate // section, as in -function-sections, to facilitate lld's --gc-section. diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -216,8 +216,12 @@ Stream.pwrite((char *)Buffer, sizeof(Buffer), Offset); } +bool isDwoSection(const MCSection &Sec) { + return Sec.getName().endswith(".dwo"); +} + class WasmObjectWriter : public MCObjectWriter { - support::endian::Writer W; + support::endian::Writer *W; /// The target specific Wasm writer instance. std::unique_ptr TargetObjectWriter; @@ -260,7 +264,16 @@ unsigned NumEventImports = 0; uint32_t SectionCount = 0; - // TargetObjectWriter wrappers. + enum class DwoMode { + AllSections, + NonDwoOnly, + DwoOnly, + }; + bool IsSplitDwarf = false; + raw_pwrite_stream *OS = nullptr; + raw_pwrite_stream *DwoOS = nullptr; + + // TargetObjectWriter wranppers. bool is64Bit() const { return TargetObjectWriter->is64Bit(); } bool isEmscripten() const { return TargetObjectWriter->isEmscripten(); } @@ -270,8 +283,12 @@ public: WasmObjectWriter(std::unique_ptr MOTW, - raw_pwrite_stream &OS) - : W(OS, support::little), TargetObjectWriter(std::move(MOTW)) {} + raw_pwrite_stream &OS_) + : TargetObjectWriter(std::move(MOTW)), OS(&OS_) {} + WasmObjectWriter(std::unique_ptr MOTW, + raw_pwrite_stream &OS_, raw_pwrite_stream &DwoOS_) + : TargetObjectWriter(std::move(MOTW)), IsSplitDwarf(true), OS(&OS_), + DwoOS(&DwoOS_) {} private: void reset() override { @@ -306,24 +323,27 @@ uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; + uint64_t writeOneObject(MCAssembler &Asm, const MCAsmLayout &Layout, + DwoMode Mode); + void writeString(const StringRef Str) { - encodeULEB128(Str.size(), W.OS); - W.OS << Str; + encodeULEB128(Str.size(), W->OS); + W->OS << Str; } void writeI32(int32_t val) { char Buffer[4]; support::endian::write32le(Buffer, val); - W.OS.write(Buffer, sizeof(Buffer)); + W->OS.write(Buffer, sizeof(Buffer)); } void writeI64(int64_t val) { char Buffer[8]; support::endian::write64le(Buffer, val); - W.OS.write(Buffer, sizeof(Buffer)); + W->OS.write(Buffer, sizeof(Buffer)); } - void writeValueType(wasm::ValType Ty) { W.OS << static_cast(Ty); } + void writeValueType(wasm::ValType Ty) { W->OS << static_cast(Ty); } void writeTypeSection(ArrayRef Signatures); void writeImportSection(ArrayRef Imports, uint64_t DataSize, @@ -368,17 +388,17 @@ void WasmObjectWriter::startSection(SectionBookkeeping &Section, unsigned SectionId) { LLVM_DEBUG(dbgs() << "startSection " << SectionId << "\n"); - W.OS << char(SectionId); + W->OS << char(SectionId); - Section.SizeOffset = W.OS.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(0, W.OS, 5); + encodeULEB128(0, W->OS, 5); // The position where the section starts, for measuring its size. - Section.ContentsOffset = W.OS.tell(); - Section.PayloadOffset = W.OS.tell(); + Section.ContentsOffset = W->OS.tell(); + Section.PayloadOffset = W->OS.tell(); Section.Index = SectionCount++; } @@ -388,19 +408,19 @@ startSection(Section, wasm::WASM_SEC_CUSTOM); // The position where the section header ends, for measuring its size. - Section.PayloadOffset = W.OS.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 = W.OS.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 = W.OS.tell(); + uint64_t Size = W->OS.tell(); // /dev/null doesn't support seek/tell and can report offset of 0. // Simply skip this patching in that case. if (!Size) @@ -414,14 +434,14 @@ // Write the final section size to the payload_len field, which follows // the section id byte. - writePatchableLEB<5>(static_cast(W.OS), Size, + writePatchableLEB<5>(static_cast(W->OS), Size, Section.SizeOffset); } // Emit the Wasm header. void WasmObjectWriter::writeHeader(const MCAssembler &Asm) { - W.OS.write(wasm::WasmMagic, sizeof(wasm::WasmMagic)); - W.write(wasm::WasmVersion); + W->OS.write(wasm::WasmMagic, sizeof(wasm::WasmMagic)); + W->write(wasm::WasmVersion); } void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm, @@ -663,7 +683,7 @@ void WasmObjectWriter::applyRelocations( ArrayRef Relocations, uint64_t ContentsOffset, const MCAsmLayout &Layout) { - auto &Stream = static_cast(W.OS); + auto &Stream = static_cast(W->OS); for (const WasmRelocationEntry &RelEntry : Relocations) { uint64_t Offset = ContentsOffset + RelEntry.FixupSection->getSectionOffset() + @@ -718,14 +738,14 @@ SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_TYPE); - encodeULEB128(Signatures.size(), W.OS); + encodeULEB128(Signatures.size(), W->OS); for (const WasmSignature &Sig : Signatures) { - W.OS << char(wasm::WASM_TYPE_FUNC); - encodeULEB128(Sig.Params.size(), W.OS); + W->OS << char(wasm::WASM_TYPE_FUNC); + encodeULEB128(Sig.Params.size(), W->OS); for (wasm::ValType Ty : Sig.Params) writeValueType(Ty); - encodeULEB128(Sig.Returns.size(), W.OS); + encodeULEB128(Sig.Returns.size(), W->OS); for (wasm::ValType Ty : Sig.Returns) writeValueType(Ty); } @@ -744,32 +764,32 @@ SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_IMPORT); - encodeULEB128(Imports.size(), W.OS); + encodeULEB128(Imports.size(), W->OS); for (const wasm::WasmImport &Import : Imports) { writeString(Import.Module); writeString(Import.Field); - W.OS << char(Import.Kind); + W->OS << char(Import.Kind); switch (Import.Kind) { case wasm::WASM_EXTERNAL_FUNCTION: - encodeULEB128(Import.SigIndex, W.OS); + encodeULEB128(Import.SigIndex, W->OS); break; case wasm::WASM_EXTERNAL_GLOBAL: - W.OS << char(Import.Global.Type); - W.OS << char(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(Import.Memory.Flags, W.OS); - encodeULEB128(NumPages, W.OS); // initial + encodeULEB128(Import.Memory.Flags, W->OS); + encodeULEB128(NumPages, W->OS); // initial break; case wasm::WASM_EXTERNAL_TABLE: - W.OS << char(Import.Table.ElemType); - encodeULEB128(0, W.OS); // flags - encodeULEB128(NumElements, W.OS); // initial + W->OS << char(Import.Table.ElemType); + encodeULEB128(0, W->OS); // flags + encodeULEB128(NumElements, W->OS); // initial break; case wasm::WASM_EXTERNAL_EVENT: - encodeULEB128(Import.Event.Attribute, W.OS); - encodeULEB128(Import.Event.SigIndex, W.OS); + encodeULEB128(Import.Event.Attribute, W->OS); + encodeULEB128(Import.Event.SigIndex, W->OS); break; default: llvm_unreachable("unsupported import kind"); @@ -786,9 +806,9 @@ SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_FUNCTION); - encodeULEB128(Functions.size(), W.OS); + encodeULEB128(Functions.size(), W->OS); for (const WasmFunction &Func : Functions) - encodeULEB128(Func.SigIndex, W.OS); + encodeULEB128(Func.SigIndex, W->OS); endSection(Section); } @@ -800,10 +820,10 @@ SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_EVENT); - encodeULEB128(Events.size(), W.OS); + encodeULEB128(Events.size(), W->OS); for (const wasm::WasmEventType &Event : Events) { - encodeULEB128(Event.Attribute, W.OS); - encodeULEB128(Event.SigIndex, W.OS); + encodeULEB128(Event.Attribute, W->OS); + encodeULEB128(Event.SigIndex, W->OS); } endSection(Section); @@ -816,17 +836,17 @@ SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_GLOBAL); - encodeULEB128(Globals.size(), W.OS); + encodeULEB128(Globals.size(), W->OS); for (const wasm::WasmGlobal &Global : Globals) { - encodeULEB128(Global.Type.Type, W.OS); - W.OS << char(Global.Type.Mutable); - W.OS << char(Global.InitExpr.Opcode); + encodeULEB128(Global.Type.Type, W->OS); + W->OS << char(Global.Type.Mutable); + W->OS << char(Global.InitExpr.Opcode); switch (Global.Type.Type) { case wasm::WASM_TYPE_I32: - encodeSLEB128(0, W.OS); + encodeSLEB128(0, W->OS); break; case wasm::WASM_TYPE_I64: - encodeSLEB128(0, W.OS); + encodeSLEB128(0, W->OS); break; case wasm::WASM_TYPE_F32: writeI32(0); @@ -840,7 +860,7 @@ default: llvm_unreachable("unexpected type"); } - W.OS << char(wasm::WASM_OPCODE_END); + W->OS << char(wasm::WASM_OPCODE_END); } endSection(Section); @@ -853,11 +873,11 @@ SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_EXPORT); - encodeULEB128(Exports.size(), W.OS); + encodeULEB128(Exports.size(), W->OS); for (const wasm::WasmExport &Export : Exports) { writeString(Export.Name); - W.OS << char(Export.Kind); - encodeULEB128(Export.Index, W.OS); + W->OS << char(Export.Kind); + encodeULEB128(Export.Index, W->OS); } endSection(Section); @@ -870,17 +890,17 @@ SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_ELEM); - encodeULEB128(1, W.OS); // number of "segments" - encodeULEB128(0, W.OS); // the table index + encodeULEB128(1, W->OS); // number of "segments" + encodeULEB128(0, W->OS); // the table index // init expr for starting offset - W.OS << char(wasm::WASM_OPCODE_I32_CONST); - encodeSLEB128(InitialTableOffset, W.OS); - W.OS << char(wasm::WASM_OPCODE_END); + W->OS << char(wasm::WASM_OPCODE_I32_CONST); + encodeSLEB128(InitialTableOffset, W->OS); + W->OS << char(wasm::WASM_OPCODE_END); - encodeULEB128(TableElems.size(), W.OS); + encodeULEB128(TableElems.size(), W->OS); for (uint32_t Elem : TableElems) - encodeULEB128(Elem, W.OS); + encodeULEB128(Elem, W->OS); endSection(Section); } @@ -891,7 +911,7 @@ SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_DATACOUNT); - encodeULEB128(DataSegments.size(), W.OS); + encodeULEB128(DataSegments.size(), W->OS); endSection(Section); } @@ -904,7 +924,7 @@ SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_CODE); - encodeULEB128(Functions.size(), W.OS); + encodeULEB128(Functions.size(), W->OS); for (const WasmFunction &Func : Functions) { auto &FuncSection = static_cast(Func.Sym->getSection()); @@ -913,9 +933,9 @@ if (!Func.Sym->getSize()->evaluateAsAbsolute(Size, Layout)) report_fatal_error(".size expression must be evaluatable"); - encodeULEB128(Size, W.OS); - FuncSection.setSectionOffset(W.OS.tell() - Section.ContentsOffset); - Asm.writeSectionData(W.OS, &FuncSection, Layout); + encodeULEB128(Size, W->OS); + FuncSection.setSectionOffset(W->OS.tell() - Section.ContentsOffset); + Asm.writeSectionData(W->OS, &FuncSection, Layout); } // Apply fixups. @@ -932,22 +952,22 @@ SectionBookkeeping Section; startSection(Section, wasm::WASM_SEC_DATA); - encodeULEB128(DataSegments.size(), W.OS); // count + encodeULEB128(DataSegments.size(), W->OS); // count for (const WasmDataSegment &Segment : DataSegments) { - encodeULEB128(Segment.InitFlags, W.OS); // flags + encodeULEB128(Segment.InitFlags, W->OS); // flags if (Segment.InitFlags & wasm::WASM_SEGMENT_HAS_MEMINDEX) - encodeULEB128(0, W.OS); // memory index + encodeULEB128(0, W->OS); // memory index if ((Segment.InitFlags & wasm::WASM_SEGMENT_IS_PASSIVE) == 0) { - W.OS << char(Segment.Offset > std::numeric_limits().max() - ? wasm::WASM_OPCODE_I64_CONST - : wasm::WASM_OPCODE_I32_CONST); - encodeSLEB128(Segment.Offset, W.OS); // offset - W.OS << char(wasm::WASM_OPCODE_END); + W->OS << char(Segment.Offset > std::numeric_limits().max() + ? wasm::WASM_OPCODE_I64_CONST + : 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 + encodeULEB128(Segment.Data.size(), W->OS); // size + Segment.Section->setSectionOffset(W->OS.tell() - Section.ContentsOffset); + W->OS << Segment.Data; // data } // Apply fixups. @@ -980,18 +1000,18 @@ SectionBookkeeping Section; startCustomSection(Section, std::string("reloc.") + Name.str()); - encodeULEB128(SectionIndex, W.OS); - encodeULEB128(Relocs.size(), W.OS); + encodeULEB128(SectionIndex, W->OS); + encodeULEB128(Relocs.size(), W->OS); for (const WasmRelocationEntry &RelEntry : Relocs) { uint64_t Offset = RelEntry.Offset + RelEntry.FixupSection->getSectionOffset(); uint32_t Index = getRelocationIndexValue(RelEntry); - W.OS << char(RelEntry.Type); - encodeULEB128(Offset, W.OS); - encodeULEB128(Index, W.OS); + W->OS << char(RelEntry.Type); + encodeULEB128(Offset, W->OS); + encodeULEB128(Index, W->OS); if (RelEntry.hasAddend()) - encodeSLEB128(RelEntry.Addend, W.OS); + encodeSLEB128(RelEntry.Addend, W->OS); } endSection(Section); @@ -1010,20 +1030,20 @@ const std::map> &Comdats) { SectionBookkeeping Section; startCustomSection(Section, "linking"); - encodeULEB128(wasm::WasmMetadataVersion, W.OS); + encodeULEB128(wasm::WasmMetadataVersion, W->OS); SectionBookkeeping SubSection; if (SymbolInfos.size() != 0) { startSection(SubSection, wasm::WASM_SYMBOL_TABLE); - encodeULEB128(SymbolInfos.size(), W.OS); + encodeULEB128(SymbolInfos.size(), W->OS); for (const wasm::WasmSymbolInfo &Sym : SymbolInfos) { - encodeULEB128(Sym.Kind, W.OS); - encodeULEB128(Sym.Flags, W.OS); + 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: case wasm::WASM_SYMBOL_TYPE_EVENT: - encodeULEB128(Sym.ElementIndex, W.OS); + encodeULEB128(Sym.ElementIndex, W->OS); if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 || (Sym.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) writeString(Sym.Name); @@ -1031,15 +1051,15 @@ case wasm::WASM_SYMBOL_TYPE_DATA: writeString(Sym.Name); if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) { - encodeULEB128(Sym.DataRef.Segment, W.OS); - encodeULEB128(Sym.DataRef.Offset, W.OS); - encodeULEB128(Sym.DataRef.Size, W.OS); + 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, W.OS); + encodeULEB128(SectionIndex, W->OS); break; } default: @@ -1051,35 +1071,35 @@ if (DataSegments.size()) { startSection(SubSection, wasm::WASM_SEGMENT_INFO); - encodeULEB128(DataSegments.size(), W.OS); + encodeULEB128(DataSegments.size(), W->OS); for (const WasmDataSegment &Segment : DataSegments) { writeString(Segment.Name); - encodeULEB128(Segment.Alignment, W.OS); - encodeULEB128(Segment.LinkerFlags, W.OS); + encodeULEB128(Segment.Alignment, W->OS); + encodeULEB128(Segment.LinkerFlags, W->OS); } endSection(SubSection); } if (!InitFuncs.empty()) { startSection(SubSection, wasm::WASM_INIT_FUNCS); - encodeULEB128(InitFuncs.size(), W.OS); + encodeULEB128(InitFuncs.size(), W->OS); for (auto &StartFunc : InitFuncs) { - encodeULEB128(StartFunc.first, W.OS); // priority - encodeULEB128(StartFunc.second, W.OS); // 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(), W.OS); + encodeULEB128(Comdats.size(), W->OS); for (const auto &C : Comdats) { writeString(C.first); - encodeULEB128(0, W.OS); // flags for future use - encodeULEB128(C.second.size(), W.OS); + encodeULEB128(0, W->OS); // flags for future use + encodeULEB128(C.second.size(), W->OS); for (const WasmComdatEntry &Entry : C.second) { - encodeULEB128(Entry.Kind, W.OS); - encodeULEB128(Entry.Index, W.OS); + encodeULEB128(Entry.Kind, W->OS); + encodeULEB128(Entry.Index, W->OS); } } endSection(SubSection); @@ -1095,8 +1115,8 @@ auto *Sec = CustomSection.Section; startCustomSection(Section, CustomSection.Name); - Sec->setSectionOffset(W.OS.tell() - Section.ContentsOffset); - Asm.writeSectionData(W.OS, Sec, Layout); + Sec->setSectionOffset(W->OS.tell() - Section.ContentsOffset); + Asm.writeSectionData(W->OS, Sec, Layout); CustomSection.OutputContentsOffset = Section.ContentsOffset; CustomSection.OutputIndex = Section.Index; @@ -1179,7 +1199,22 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) { - uint64_t StartOffset = W.OS.tell(); + support::endian::Writer MainWriter(*OS, support::little); + W = &MainWriter; + if (IsSplitDwarf) { + uint64_t TotalSize = writeOneObject(Asm, Layout, DwoMode::NonDwoOnly); + assert(DwoOS); + support::endian::Writer DwoWriter(*DwoOS, support::little); + W = &DwoWriter; + return TotalSize + writeOneObject(Asm, Layout, DwoMode::DwoOnly); + } + return writeOneObject(Asm, Layout, DwoMode::AllSections); +} + +uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, + const MCAsmLayout &Layout, + DwoMode Mode) { + uint64_t StartOffset = W->OS.tell(); LLVM_DEBUG(dbgs() << "WasmObjectWriter::writeObject\n"); @@ -1299,6 +1334,11 @@ auto &Section = static_cast(Sec); StringRef SectionName = Section.getName(); + if (Mode == DwoMode::NonDwoOnly && isDwoSection(Sec)) + continue; + if (Mode == DwoMode::DwoOnly && isDwoSection(Sec)) + continue; + // .init_array sections are handled specially elsewhere. if (SectionName.startswith(".init_array")) continue; @@ -1719,7 +1759,7 @@ writeCustomSection(*TargetFeaturesSection, Asm, Layout); // TODO: Translate the .comment section to the output. - return W.OS.tell() - StartOffset; + return W->OS.tell() - StartOffset; } std::unique_ptr @@ -1727,3 +1767,10 @@ raw_pwrite_stream &OS) { return std::make_unique(std::move(MOTW), OS); } + +std::unique_ptr +llvm::createWasmDwoObjectWriter(std::unique_ptr MOTW, + raw_pwrite_stream &OS, + raw_pwrite_stream &DwoOS) { + return std::make_unique(std::move(MOTW), OS); +}