Index: lib/MC/WasmObjectWriter.cpp =================================================================== --- lib/MC/WasmObjectWriter.cpp +++ lib/MC/WasmObjectWriter.cpp @@ -224,6 +224,7 @@ // Stores output data (index, relocations, content offset) for custom // section. std::vector CustomSections; + std::unique_ptr ProducerSection; // Relocations for fixing up references in the custom sections. DenseMap> CustomSectionsRelocations; @@ -265,6 +266,8 @@ WasmIndices.clear(); TableIndices.clear(); DataLocations.clear(); + CustomSections.clear(); + ProducerSection.reset(); CustomSectionsRelocations.clear(); SignatureIndices.clear(); Signatures.clear(); @@ -311,7 +314,8 @@ ArrayRef SymbolInfos, ArrayRef> InitFuncs, const std::map> &Comdats); - void writeCustomSections(const MCAssembler &Asm, const MCAsmLayout &Layout); + void writeCustomSection(WasmCustomSection &CustomSection, + const MCAssembler &Asm, const MCAsmLayout &Layout); void writeCustomRelocSections(); void updateCustomSectionRelocations(const SmallVector &Functions, @@ -1045,25 +1049,24 @@ endSection(Section); } -void WasmObjectWriter::writeCustomSections(const MCAssembler &Asm, - const MCAsmLayout &Layout) { - for (auto &CustomSection : CustomSections) { - SectionBookkeeping Section; - auto *Sec = CustomSection.Section; - startCustomSection(Section, CustomSection.Name); +void WasmObjectWriter::writeCustomSection(WasmCustomSection &CustomSection, + const MCAssembler &Asm, + const MCAsmLayout &Layout) { + SectionBookkeeping Section; + 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; + CustomSection.OutputContentsOffset = Section.ContentsOffset; + CustomSection.OutputIndex = Section.Index; - endSection(Section); + endSection(Section); - // Apply fixups. - auto &Relocations = CustomSectionsRelocations[CustomSection.Section]; - applyRelocations(Relocations, CustomSection.OutputContentsOffset); - } + // Apply fixups. + auto &Relocations = CustomSectionsRelocations[CustomSection.Section]; + applyRelocations(Relocations, CustomSection.OutputContentsOffset); } uint32_t WasmObjectWriter::getFunctionType(const MCSymbolWasm &Symbol) { @@ -1282,6 +1285,13 @@ report_fatal_error("section name and begin symbol should match: " + Twine(SectionName)); } + + // Separate out the producers section + if (Name == "producers") { + ProducerSection = llvm::make_unique(Name, &Section); + continue; + } + CustomSections.emplace_back(Name, &Section); } } @@ -1570,11 +1580,14 @@ writeElemSection(TableElems); writeCodeSection(Asm, Layout, Functions); writeDataSection(); - writeCustomSections(Asm, Layout); + for (auto &CustomSection : CustomSections) + writeCustomSection(CustomSection, Asm, Layout); writeLinkingMetaDataSection(SymbolInfos, InitFuncs, Comdats); writeRelocSection(CodeSectionIndex, "CODE", CodeRelocations); writeRelocSection(DataSectionIndex, "DATA", DataRelocations); writeCustomRelocSections(); + if (ProducerSection) + writeCustomSection(*ProducerSection, Asm, Layout); // TODO: Translate the .comment section to the output. return W.OS.tell() - StartOffset; Index: lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp =================================================================== --- lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -146,6 +146,32 @@ OutStreamer->PopSection(); } } + + if (const NamedMDNode *Ident = M.getNamedMetadata("llvm.ident")) { + llvm::SmallVector, 1> Tools; + for (size_t i = 0, e = Ident->getNumOperands(); i < e; ++i) { + const auto *S = cast(Ident->getOperand(i)->getOperand(0)); + std::pair Field = S->getString().split("version"); + Field.first = Field.first.trim(); + Field.second = Field.second.trim(); + Tools.push_back(Field); + } + MCSectionWasm *Producers = OutContext.getWasmSection( + ".custom_section.producers", SectionKind::getMetadata()); + OutStreamer->PushSection(); + OutStreamer->SwitchSection(Producers); + OutStreamer->EmitULEB128IntValue(1); + OutStreamer->EmitULEB128IntValue(strlen("processed-by")); + OutStreamer->EmitBytes("processed-by"); + OutStreamer->EmitULEB128IntValue(Tools.size()); + for (auto &Tool : Tools) { + OutStreamer->EmitULEB128IntValue(Tool.first.size()); + OutStreamer->EmitBytes(Tool.first); + OutStreamer->EmitULEB128IntValue(Tool.second.size()); + OutStreamer->EmitBytes(Tool.second); + } + OutStreamer->PopSection(); + } } void WebAssemblyAsmPrinter::EmitConstantPool() { Index: test/CodeGen/WebAssembly/custom-sections.ll =================================================================== --- test/CodeGen/WebAssembly/custom-sections.ll +++ test/CodeGen/WebAssembly/custom-sections.ll @@ -10,6 +10,9 @@ !2 = !{ !"green", !"qux" } !wasm.custom_sections = !{ !0, !1, !2 } +!llvm.ident = !{!3} +!3 = !{!"clang version 123"} + ; CHECK: .section .custom_section.red,"",@ ; CHECK-NEXT: .ascii "foo" @@ -18,3 +21,13 @@ ; CHECK: .section .custom_section.green,"",@ ; CHECK-NEXT: .ascii "qux" + +; CHECK: .section .custom_section.producers,"",@ +; CHECK-NEXT: .int8 1 +; CHECK-NEXT: .int8 12 +; CHECK-NEXT: .ascii "processed-by" +; CHECK-NEXT: .int8 1 +; CHECK-NEXT: .int8 5 +; CHECK-NEXT: .ascii "clang" +; CHECK-NEXT: .int8 3 +; CHECK-NEXT: .ascii "123" Index: test/MC/WebAssembly/custom-sections.ll =================================================================== --- test/MC/WebAssembly/custom-sections.ll +++ test/MC/WebAssembly/custom-sections.ll @@ -9,6 +9,9 @@ !2 = !{ !"green", !"qux" } !wasm.custom_sections = !{ !0, !1, !2 } +!3 = !{ !"clang version 123"} +!llvm.ident = !{!3} + ; CHECK: Section { ; CHECK: Type: CUSTOM (0x0) ; CHECK: Size: 3 @@ -21,3 +24,9 @@ ; CHECK: Offset: 85 ; CHECK: Name: green ; CHECK: } +; CHECK: Section { +; CHECK: Type: CUSTOM (0x0) +; CHECK: Size: 25 +; CHECK: Offset: 118 +; CHECK: Name: producers +; CHECK: } Index: test/MC/WebAssembly/debug-info.ll =================================================================== --- test/MC/WebAssembly/debug-info.ll +++ test/MC/WebAssembly/debug-info.ll @@ -124,6 +124,12 @@ ; CHECK-NEXT: Offset: 991 ; CHECK-NEXT: Name: reloc..debug_line ; CHECK-NEXT: } +; CHECK-NEXT: Section { +; CHECK-NEXT: Type: CUSTOM (0x0) +; CHECK-NEXT: Size: 62 +; CHECK-NEXT: Offset: 1021 +; CHECK-NEXT: Name: producers +; CHECK-NEXT: } ; CHECK-NEXT:] ; CHECK-NEXT:Relocations [ ; CHECK-NEXT: Section (6) DATA {