18bcb0991SDimitry Andric //===- yaml2wasm - Convert YAML to a Wasm object file --------------------===// 28bcb0991SDimitry Andric // 38bcb0991SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 48bcb0991SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 58bcb0991SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 68bcb0991SDimitry Andric // 78bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 88bcb0991SDimitry Andric /// 98bcb0991SDimitry Andric /// \file 108bcb0991SDimitry Andric /// The Wasm component of yaml2obj. 118bcb0991SDimitry Andric /// 128bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 138bcb0991SDimitry Andric // 148bcb0991SDimitry Andric 158bcb0991SDimitry Andric #include "llvm/Object/Wasm.h" 168bcb0991SDimitry Andric #include "llvm/ObjectYAML/ObjectYAML.h" 178bcb0991SDimitry Andric #include "llvm/ObjectYAML/yaml2obj.h" 188bcb0991SDimitry Andric #include "llvm/Support/Endian.h" 198bcb0991SDimitry Andric #include "llvm/Support/LEB128.h" 208bcb0991SDimitry Andric 218bcb0991SDimitry Andric using namespace llvm; 228bcb0991SDimitry Andric 238bcb0991SDimitry Andric namespace { 248bcb0991SDimitry Andric /// This parses a yaml stream that represents a Wasm object file. 258bcb0991SDimitry Andric /// See docs/yaml2obj for the yaml scheema. 268bcb0991SDimitry Andric class WasmWriter { 278bcb0991SDimitry Andric public: 288bcb0991SDimitry Andric WasmWriter(WasmYAML::Object &Obj, yaml::ErrorHandler EH) 298bcb0991SDimitry Andric : Obj(Obj), ErrHandler(EH) {} 308bcb0991SDimitry Andric bool writeWasm(raw_ostream &OS); 318bcb0991SDimitry Andric 328bcb0991SDimitry Andric private: 338bcb0991SDimitry Andric void writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec, 348bcb0991SDimitry Andric uint32_t SectionIndex); 358bcb0991SDimitry Andric 36*81ad6265SDimitry Andric void writeInitExpr(raw_ostream &OS, const WasmYAML::InitExpr &InitExpr); 378bcb0991SDimitry Andric 388bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::CustomSection &Section); 398bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::TypeSection &Section); 408bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::ImportSection &Section); 418bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::FunctionSection &Section); 428bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::TableSection &Section); 438bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::MemorySection &Section); 44fe6060f1SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::TagSection &Section); 455ffd83dbSDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::GlobalSection &Section); 468bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::ExportSection &Section); 478bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::StartSection &Section); 488bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::ElemSection &Section); 498bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::CodeSection &Section); 508bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::DataSection &Section); 518bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::DataCountSection &Section); 528bcb0991SDimitry Andric 538bcb0991SDimitry Andric // Custom section types 548bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::DylinkSection &Section); 558bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section); 568bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section); 578bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, WasmYAML::ProducersSection &Section); 588bcb0991SDimitry Andric void writeSectionContent(raw_ostream &OS, 598bcb0991SDimitry Andric WasmYAML::TargetFeaturesSection &Section); 608bcb0991SDimitry Andric WasmYAML::Object &Obj; 618bcb0991SDimitry Andric uint32_t NumImportedFunctions = 0; 628bcb0991SDimitry Andric uint32_t NumImportedGlobals = 0; 63e8d8bef9SDimitry Andric uint32_t NumImportedTables = 0; 64fe6060f1SDimitry Andric uint32_t NumImportedTags = 0; 658bcb0991SDimitry Andric 668bcb0991SDimitry Andric bool HasError = false; 678bcb0991SDimitry Andric yaml::ErrorHandler ErrHandler; 688bcb0991SDimitry Andric void reportError(const Twine &Msg); 698bcb0991SDimitry Andric }; 708bcb0991SDimitry Andric 718bcb0991SDimitry Andric class SubSectionWriter { 728bcb0991SDimitry Andric raw_ostream &OS; 738bcb0991SDimitry Andric std::string OutString; 748bcb0991SDimitry Andric raw_string_ostream StringStream; 758bcb0991SDimitry Andric 768bcb0991SDimitry Andric public: 778bcb0991SDimitry Andric SubSectionWriter(raw_ostream &OS) : OS(OS), StringStream(OutString) {} 788bcb0991SDimitry Andric 798bcb0991SDimitry Andric void done() { 808bcb0991SDimitry Andric StringStream.flush(); 818bcb0991SDimitry Andric encodeULEB128(OutString.size(), OS); 828bcb0991SDimitry Andric OS << OutString; 838bcb0991SDimitry Andric OutString.clear(); 848bcb0991SDimitry Andric } 858bcb0991SDimitry Andric 868bcb0991SDimitry Andric raw_ostream &getStream() { return StringStream; } 878bcb0991SDimitry Andric }; 888bcb0991SDimitry Andric 898bcb0991SDimitry Andric } // end anonymous namespace 908bcb0991SDimitry Andric 918bcb0991SDimitry Andric static int writeUint64(raw_ostream &OS, uint64_t Value) { 928bcb0991SDimitry Andric char Data[sizeof(Value)]; 938bcb0991SDimitry Andric support::endian::write64le(Data, Value); 948bcb0991SDimitry Andric OS.write(Data, sizeof(Data)); 958bcb0991SDimitry Andric return 0; 968bcb0991SDimitry Andric } 978bcb0991SDimitry Andric 988bcb0991SDimitry Andric static int writeUint32(raw_ostream &OS, uint32_t Value) { 998bcb0991SDimitry Andric char Data[sizeof(Value)]; 1008bcb0991SDimitry Andric support::endian::write32le(Data, Value); 1018bcb0991SDimitry Andric OS.write(Data, sizeof(Data)); 1028bcb0991SDimitry Andric return 0; 1038bcb0991SDimitry Andric } 1048bcb0991SDimitry Andric 1058bcb0991SDimitry Andric static int writeUint8(raw_ostream &OS, uint8_t Value) { 1068bcb0991SDimitry Andric char Data[sizeof(Value)]; 1078bcb0991SDimitry Andric memcpy(Data, &Value, sizeof(Data)); 1088bcb0991SDimitry Andric OS.write(Data, sizeof(Data)); 1098bcb0991SDimitry Andric return 0; 1108bcb0991SDimitry Andric } 1118bcb0991SDimitry Andric 1128bcb0991SDimitry Andric static int writeStringRef(const StringRef &Str, raw_ostream &OS) { 1138bcb0991SDimitry Andric encodeULEB128(Str.size(), OS); 1148bcb0991SDimitry Andric OS << Str; 1158bcb0991SDimitry Andric return 0; 1168bcb0991SDimitry Andric } 1178bcb0991SDimitry Andric 1188bcb0991SDimitry Andric static int writeLimits(const WasmYAML::Limits &Lim, raw_ostream &OS) { 1198bcb0991SDimitry Andric writeUint8(OS, Lim.Flags); 120fe6060f1SDimitry Andric encodeULEB128(Lim.Minimum, OS); 1218bcb0991SDimitry Andric if (Lim.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX) 1228bcb0991SDimitry Andric encodeULEB128(Lim.Maximum, OS); 1238bcb0991SDimitry Andric return 0; 1248bcb0991SDimitry Andric } 1258bcb0991SDimitry Andric 1268bcb0991SDimitry Andric void WasmWriter::reportError(const Twine &Msg) { 1278bcb0991SDimitry Andric ErrHandler(Msg); 1288bcb0991SDimitry Andric HasError = true; 1298bcb0991SDimitry Andric } 1308bcb0991SDimitry Andric 1318bcb0991SDimitry Andric void WasmWriter::writeInitExpr(raw_ostream &OS, 132*81ad6265SDimitry Andric const WasmYAML::InitExpr &InitExpr) { 133*81ad6265SDimitry Andric if (InitExpr.Extended) { 134*81ad6265SDimitry Andric InitExpr.Body.writeAsBinary(OS); 135*81ad6265SDimitry Andric } else { 136*81ad6265SDimitry Andric writeUint8(OS, InitExpr.Inst.Opcode); 137*81ad6265SDimitry Andric switch (InitExpr.Inst.Opcode) { 1388bcb0991SDimitry Andric case wasm::WASM_OPCODE_I32_CONST: 139*81ad6265SDimitry Andric encodeSLEB128(InitExpr.Inst.Value.Int32, OS); 1408bcb0991SDimitry Andric break; 1418bcb0991SDimitry Andric case wasm::WASM_OPCODE_I64_CONST: 142*81ad6265SDimitry Andric encodeSLEB128(InitExpr.Inst.Value.Int64, OS); 1438bcb0991SDimitry Andric break; 1448bcb0991SDimitry Andric case wasm::WASM_OPCODE_F32_CONST: 145*81ad6265SDimitry Andric writeUint32(OS, InitExpr.Inst.Value.Float32); 1468bcb0991SDimitry Andric break; 1478bcb0991SDimitry Andric case wasm::WASM_OPCODE_F64_CONST: 148*81ad6265SDimitry Andric writeUint64(OS, InitExpr.Inst.Value.Float64); 1498bcb0991SDimitry Andric break; 1508bcb0991SDimitry Andric case wasm::WASM_OPCODE_GLOBAL_GET: 151*81ad6265SDimitry Andric encodeULEB128(InitExpr.Inst.Value.Global, OS); 1528bcb0991SDimitry Andric break; 1538bcb0991SDimitry Andric default: 154*81ad6265SDimitry Andric reportError("unknown opcode in init_expr: " + 155*81ad6265SDimitry Andric Twine(InitExpr.Inst.Opcode)); 1568bcb0991SDimitry Andric return; 1578bcb0991SDimitry Andric } 1588bcb0991SDimitry Andric writeUint8(OS, wasm::WASM_OPCODE_END); 1598bcb0991SDimitry Andric } 160*81ad6265SDimitry Andric } 1618bcb0991SDimitry Andric 1628bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 1638bcb0991SDimitry Andric WasmYAML::DylinkSection &Section) { 1648bcb0991SDimitry Andric writeStringRef(Section.Name, OS); 165349cc55cSDimitry Andric 166349cc55cSDimitry Andric writeUint8(OS, wasm::WASM_DYLINK_MEM_INFO); 167349cc55cSDimitry Andric SubSectionWriter SubSection(OS); 168349cc55cSDimitry Andric raw_ostream &SubOS = SubSection.getStream(); 169349cc55cSDimitry Andric encodeULEB128(Section.MemorySize, SubOS); 170349cc55cSDimitry Andric encodeULEB128(Section.MemoryAlignment, SubOS); 171349cc55cSDimitry Andric encodeULEB128(Section.TableSize, SubOS); 172349cc55cSDimitry Andric encodeULEB128(Section.TableAlignment, SubOS); 173349cc55cSDimitry Andric SubSection.done(); 174349cc55cSDimitry Andric 175349cc55cSDimitry Andric if (Section.Needed.size()) { 176349cc55cSDimitry Andric writeUint8(OS, wasm::WASM_DYLINK_NEEDED); 177349cc55cSDimitry Andric raw_ostream &SubOS = SubSection.getStream(); 178349cc55cSDimitry Andric encodeULEB128(Section.Needed.size(), SubOS); 1798bcb0991SDimitry Andric for (StringRef Needed : Section.Needed) 180349cc55cSDimitry Andric writeStringRef(Needed, SubOS); 181349cc55cSDimitry Andric SubSection.done(); 182349cc55cSDimitry Andric } 1838bcb0991SDimitry Andric } 1848bcb0991SDimitry Andric 1858bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 1868bcb0991SDimitry Andric WasmYAML::LinkingSection &Section) { 1878bcb0991SDimitry Andric writeStringRef(Section.Name, OS); 1888bcb0991SDimitry Andric encodeULEB128(Section.Version, OS); 1898bcb0991SDimitry Andric 1908bcb0991SDimitry Andric SubSectionWriter SubSection(OS); 1918bcb0991SDimitry Andric 1928bcb0991SDimitry Andric // SYMBOL_TABLE subsection 1938bcb0991SDimitry Andric if (Section.SymbolTable.size()) { 1948bcb0991SDimitry Andric writeUint8(OS, wasm::WASM_SYMBOL_TABLE); 1958bcb0991SDimitry Andric encodeULEB128(Section.SymbolTable.size(), SubSection.getStream()); 196*81ad6265SDimitry Andric for (auto Sym : llvm::enumerate(Section.SymbolTable)) { 197*81ad6265SDimitry Andric const WasmYAML::SymbolInfo &Info = Sym.value(); 198*81ad6265SDimitry Andric assert(Info.Index == Sym.index()); 1998bcb0991SDimitry Andric writeUint8(SubSection.getStream(), Info.Kind); 2008bcb0991SDimitry Andric encodeULEB128(Info.Flags, SubSection.getStream()); 2018bcb0991SDimitry Andric switch (Info.Kind) { 2028bcb0991SDimitry Andric case wasm::WASM_SYMBOL_TYPE_FUNCTION: 2038bcb0991SDimitry Andric case wasm::WASM_SYMBOL_TYPE_GLOBAL: 204e8d8bef9SDimitry Andric case wasm::WASM_SYMBOL_TYPE_TABLE: 205fe6060f1SDimitry Andric case wasm::WASM_SYMBOL_TYPE_TAG: 2068bcb0991SDimitry Andric encodeULEB128(Info.ElementIndex, SubSection.getStream()); 2078bcb0991SDimitry Andric if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 || 2088bcb0991SDimitry Andric (Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) 2098bcb0991SDimitry Andric writeStringRef(Info.Name, SubSection.getStream()); 2108bcb0991SDimitry Andric break; 2118bcb0991SDimitry Andric case wasm::WASM_SYMBOL_TYPE_DATA: 2128bcb0991SDimitry Andric writeStringRef(Info.Name, SubSection.getStream()); 2138bcb0991SDimitry Andric if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) { 2148bcb0991SDimitry Andric encodeULEB128(Info.DataRef.Segment, SubSection.getStream()); 2158bcb0991SDimitry Andric encodeULEB128(Info.DataRef.Offset, SubSection.getStream()); 2168bcb0991SDimitry Andric encodeULEB128(Info.DataRef.Size, SubSection.getStream()); 2178bcb0991SDimitry Andric } 2188bcb0991SDimitry Andric break; 2198bcb0991SDimitry Andric case wasm::WASM_SYMBOL_TYPE_SECTION: 2208bcb0991SDimitry Andric encodeULEB128(Info.ElementIndex, SubSection.getStream()); 2218bcb0991SDimitry Andric break; 2228bcb0991SDimitry Andric default: 2238bcb0991SDimitry Andric llvm_unreachable("unexpected kind"); 2248bcb0991SDimitry Andric } 2258bcb0991SDimitry Andric } 2268bcb0991SDimitry Andric 2278bcb0991SDimitry Andric SubSection.done(); 2288bcb0991SDimitry Andric } 2298bcb0991SDimitry Andric 2308bcb0991SDimitry Andric // SEGMENT_NAMES subsection 2318bcb0991SDimitry Andric if (Section.SegmentInfos.size()) { 2328bcb0991SDimitry Andric writeUint8(OS, wasm::WASM_SEGMENT_INFO); 2338bcb0991SDimitry Andric encodeULEB128(Section.SegmentInfos.size(), SubSection.getStream()); 2348bcb0991SDimitry Andric for (const WasmYAML::SegmentInfo &SegmentInfo : Section.SegmentInfos) { 2358bcb0991SDimitry Andric writeStringRef(SegmentInfo.Name, SubSection.getStream()); 2368bcb0991SDimitry Andric encodeULEB128(SegmentInfo.Alignment, SubSection.getStream()); 2378bcb0991SDimitry Andric encodeULEB128(SegmentInfo.Flags, SubSection.getStream()); 2388bcb0991SDimitry Andric } 2398bcb0991SDimitry Andric SubSection.done(); 2408bcb0991SDimitry Andric } 2418bcb0991SDimitry Andric 2428bcb0991SDimitry Andric // INIT_FUNCS subsection 2438bcb0991SDimitry Andric if (Section.InitFunctions.size()) { 2448bcb0991SDimitry Andric writeUint8(OS, wasm::WASM_INIT_FUNCS); 2458bcb0991SDimitry Andric encodeULEB128(Section.InitFunctions.size(), SubSection.getStream()); 2468bcb0991SDimitry Andric for (const WasmYAML::InitFunction &Func : Section.InitFunctions) { 2478bcb0991SDimitry Andric encodeULEB128(Func.Priority, SubSection.getStream()); 2488bcb0991SDimitry Andric encodeULEB128(Func.Symbol, SubSection.getStream()); 2498bcb0991SDimitry Andric } 2508bcb0991SDimitry Andric SubSection.done(); 2518bcb0991SDimitry Andric } 2528bcb0991SDimitry Andric 2538bcb0991SDimitry Andric // COMDAT_INFO subsection 2548bcb0991SDimitry Andric if (Section.Comdats.size()) { 2558bcb0991SDimitry Andric writeUint8(OS, wasm::WASM_COMDAT_INFO); 2568bcb0991SDimitry Andric encodeULEB128(Section.Comdats.size(), SubSection.getStream()); 2578bcb0991SDimitry Andric for (const auto &C : Section.Comdats) { 2588bcb0991SDimitry Andric writeStringRef(C.Name, SubSection.getStream()); 2598bcb0991SDimitry Andric encodeULEB128(0, SubSection.getStream()); // flags for future use 2608bcb0991SDimitry Andric encodeULEB128(C.Entries.size(), SubSection.getStream()); 2618bcb0991SDimitry Andric for (const WasmYAML::ComdatEntry &Entry : C.Entries) { 2628bcb0991SDimitry Andric writeUint8(SubSection.getStream(), Entry.Kind); 2638bcb0991SDimitry Andric encodeULEB128(Entry.Index, SubSection.getStream()); 2648bcb0991SDimitry Andric } 2658bcb0991SDimitry Andric } 2668bcb0991SDimitry Andric SubSection.done(); 2678bcb0991SDimitry Andric } 2688bcb0991SDimitry Andric } 2698bcb0991SDimitry Andric 2708bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 2718bcb0991SDimitry Andric WasmYAML::NameSection &Section) { 2728bcb0991SDimitry Andric writeStringRef(Section.Name, OS); 2738bcb0991SDimitry Andric if (Section.FunctionNames.size()) { 2748bcb0991SDimitry Andric writeUint8(OS, wasm::WASM_NAMES_FUNCTION); 2758bcb0991SDimitry Andric 2768bcb0991SDimitry Andric SubSectionWriter SubSection(OS); 2778bcb0991SDimitry Andric 2788bcb0991SDimitry Andric encodeULEB128(Section.FunctionNames.size(), SubSection.getStream()); 2798bcb0991SDimitry Andric for (const WasmYAML::NameEntry &NameEntry : Section.FunctionNames) { 2808bcb0991SDimitry Andric encodeULEB128(NameEntry.Index, SubSection.getStream()); 2818bcb0991SDimitry Andric writeStringRef(NameEntry.Name, SubSection.getStream()); 2828bcb0991SDimitry Andric } 2838bcb0991SDimitry Andric 2848bcb0991SDimitry Andric SubSection.done(); 2858bcb0991SDimitry Andric } 286e8d8bef9SDimitry Andric if (Section.GlobalNames.size()) { 287e8d8bef9SDimitry Andric writeUint8(OS, wasm::WASM_NAMES_GLOBAL); 288e8d8bef9SDimitry Andric 289e8d8bef9SDimitry Andric SubSectionWriter SubSection(OS); 290e8d8bef9SDimitry Andric 291e8d8bef9SDimitry Andric encodeULEB128(Section.GlobalNames.size(), SubSection.getStream()); 292e8d8bef9SDimitry Andric for (const WasmYAML::NameEntry &NameEntry : Section.GlobalNames) { 293e8d8bef9SDimitry Andric encodeULEB128(NameEntry.Index, SubSection.getStream()); 294e8d8bef9SDimitry Andric writeStringRef(NameEntry.Name, SubSection.getStream()); 295e8d8bef9SDimitry Andric } 296e8d8bef9SDimitry Andric 297e8d8bef9SDimitry Andric SubSection.done(); 298e8d8bef9SDimitry Andric } 299e8d8bef9SDimitry Andric if (Section.DataSegmentNames.size()) { 300e8d8bef9SDimitry Andric writeUint8(OS, wasm::WASM_NAMES_DATA_SEGMENT); 301e8d8bef9SDimitry Andric 302e8d8bef9SDimitry Andric SubSectionWriter SubSection(OS); 303e8d8bef9SDimitry Andric 304e8d8bef9SDimitry Andric encodeULEB128(Section.DataSegmentNames.size(), SubSection.getStream()); 305e8d8bef9SDimitry Andric for (const WasmYAML::NameEntry &NameEntry : Section.DataSegmentNames) { 306e8d8bef9SDimitry Andric encodeULEB128(NameEntry.Index, SubSection.getStream()); 307e8d8bef9SDimitry Andric writeStringRef(NameEntry.Name, SubSection.getStream()); 308e8d8bef9SDimitry Andric } 309e8d8bef9SDimitry Andric 310e8d8bef9SDimitry Andric SubSection.done(); 311e8d8bef9SDimitry Andric } 3128bcb0991SDimitry Andric } 3138bcb0991SDimitry Andric 3148bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 3158bcb0991SDimitry Andric WasmYAML::ProducersSection &Section) { 3168bcb0991SDimitry Andric writeStringRef(Section.Name, OS); 3178bcb0991SDimitry Andric int Fields = int(!Section.Languages.empty()) + int(!Section.Tools.empty()) + 3188bcb0991SDimitry Andric int(!Section.SDKs.empty()); 3198bcb0991SDimitry Andric if (Fields == 0) 3208bcb0991SDimitry Andric return; 3218bcb0991SDimitry Andric encodeULEB128(Fields, OS); 3228bcb0991SDimitry Andric for (auto &Field : {std::make_pair(StringRef("language"), &Section.Languages), 3238bcb0991SDimitry Andric std::make_pair(StringRef("processed-by"), &Section.Tools), 3248bcb0991SDimitry Andric std::make_pair(StringRef("sdk"), &Section.SDKs)}) { 3258bcb0991SDimitry Andric if (Field.second->empty()) 3268bcb0991SDimitry Andric continue; 3278bcb0991SDimitry Andric writeStringRef(Field.first, OS); 3288bcb0991SDimitry Andric encodeULEB128(Field.second->size(), OS); 3298bcb0991SDimitry Andric for (auto &Entry : *Field.second) { 3308bcb0991SDimitry Andric writeStringRef(Entry.Name, OS); 3318bcb0991SDimitry Andric writeStringRef(Entry.Version, OS); 3328bcb0991SDimitry Andric } 3338bcb0991SDimitry Andric } 3348bcb0991SDimitry Andric } 3358bcb0991SDimitry Andric 3368bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 3378bcb0991SDimitry Andric WasmYAML::TargetFeaturesSection &Section) { 3388bcb0991SDimitry Andric writeStringRef(Section.Name, OS); 3398bcb0991SDimitry Andric encodeULEB128(Section.Features.size(), OS); 3408bcb0991SDimitry Andric for (auto &E : Section.Features) { 3418bcb0991SDimitry Andric writeUint8(OS, E.Prefix); 3428bcb0991SDimitry Andric writeStringRef(E.Name, OS); 3438bcb0991SDimitry Andric } 3448bcb0991SDimitry Andric } 3458bcb0991SDimitry Andric 3468bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 3478bcb0991SDimitry Andric WasmYAML::CustomSection &Section) { 3488bcb0991SDimitry Andric if (auto S = dyn_cast<WasmYAML::DylinkSection>(&Section)) { 3498bcb0991SDimitry Andric writeSectionContent(OS, *S); 3508bcb0991SDimitry Andric } else if (auto S = dyn_cast<WasmYAML::NameSection>(&Section)) { 3518bcb0991SDimitry Andric writeSectionContent(OS, *S); 3528bcb0991SDimitry Andric } else if (auto S = dyn_cast<WasmYAML::LinkingSection>(&Section)) { 3538bcb0991SDimitry Andric writeSectionContent(OS, *S); 3548bcb0991SDimitry Andric } else if (auto S = dyn_cast<WasmYAML::ProducersSection>(&Section)) { 3558bcb0991SDimitry Andric writeSectionContent(OS, *S); 3568bcb0991SDimitry Andric } else if (auto S = dyn_cast<WasmYAML::TargetFeaturesSection>(&Section)) { 3578bcb0991SDimitry Andric writeSectionContent(OS, *S); 3588bcb0991SDimitry Andric } else { 3598bcb0991SDimitry Andric writeStringRef(Section.Name, OS); 3608bcb0991SDimitry Andric Section.Payload.writeAsBinary(OS); 3618bcb0991SDimitry Andric } 3628bcb0991SDimitry Andric } 3638bcb0991SDimitry Andric 3648bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 3658bcb0991SDimitry Andric WasmYAML::TypeSection &Section) { 3668bcb0991SDimitry Andric encodeULEB128(Section.Signatures.size(), OS); 3678bcb0991SDimitry Andric uint32_t ExpectedIndex = 0; 3688bcb0991SDimitry Andric for (const WasmYAML::Signature &Sig : Section.Signatures) { 3698bcb0991SDimitry Andric if (Sig.Index != ExpectedIndex) { 3708bcb0991SDimitry Andric reportError("unexpected type index: " + Twine(Sig.Index)); 3718bcb0991SDimitry Andric return; 3728bcb0991SDimitry Andric } 3738bcb0991SDimitry Andric ++ExpectedIndex; 3748bcb0991SDimitry Andric writeUint8(OS, Sig.Form); 3758bcb0991SDimitry Andric encodeULEB128(Sig.ParamTypes.size(), OS); 3768bcb0991SDimitry Andric for (auto ParamType : Sig.ParamTypes) 3778bcb0991SDimitry Andric writeUint8(OS, ParamType); 3788bcb0991SDimitry Andric encodeULEB128(Sig.ReturnTypes.size(), OS); 3798bcb0991SDimitry Andric for (auto ReturnType : Sig.ReturnTypes) 3808bcb0991SDimitry Andric writeUint8(OS, ReturnType); 3818bcb0991SDimitry Andric } 3828bcb0991SDimitry Andric } 3838bcb0991SDimitry Andric 3848bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 3858bcb0991SDimitry Andric WasmYAML::ImportSection &Section) { 3868bcb0991SDimitry Andric encodeULEB128(Section.Imports.size(), OS); 3878bcb0991SDimitry Andric for (const WasmYAML::Import &Import : Section.Imports) { 3888bcb0991SDimitry Andric writeStringRef(Import.Module, OS); 3898bcb0991SDimitry Andric writeStringRef(Import.Field, OS); 3908bcb0991SDimitry Andric writeUint8(OS, Import.Kind); 3918bcb0991SDimitry Andric switch (Import.Kind) { 3928bcb0991SDimitry Andric case wasm::WASM_EXTERNAL_FUNCTION: 3938bcb0991SDimitry Andric encodeULEB128(Import.SigIndex, OS); 3948bcb0991SDimitry Andric NumImportedFunctions++; 3958bcb0991SDimitry Andric break; 3968bcb0991SDimitry Andric case wasm::WASM_EXTERNAL_GLOBAL: 3978bcb0991SDimitry Andric writeUint8(OS, Import.GlobalImport.Type); 3988bcb0991SDimitry Andric writeUint8(OS, Import.GlobalImport.Mutable); 3998bcb0991SDimitry Andric NumImportedGlobals++; 4008bcb0991SDimitry Andric break; 401fe6060f1SDimitry Andric case wasm::WASM_EXTERNAL_TAG: 402349cc55cSDimitry Andric writeUint8(OS, 0); // Reserved 'attribute' field 403349cc55cSDimitry Andric encodeULEB128(Import.SigIndex, OS); 404fe6060f1SDimitry Andric NumImportedTags++; 4058bcb0991SDimitry Andric break; 4068bcb0991SDimitry Andric case wasm::WASM_EXTERNAL_MEMORY: 4078bcb0991SDimitry Andric writeLimits(Import.Memory, OS); 4088bcb0991SDimitry Andric break; 4098bcb0991SDimitry Andric case wasm::WASM_EXTERNAL_TABLE: 4108bcb0991SDimitry Andric writeUint8(OS, Import.TableImport.ElemType); 4118bcb0991SDimitry Andric writeLimits(Import.TableImport.TableLimits, OS); 412e8d8bef9SDimitry Andric NumImportedTables++; 4138bcb0991SDimitry Andric break; 4148bcb0991SDimitry Andric default: 4158bcb0991SDimitry Andric reportError("unknown import type: " +Twine(Import.Kind)); 4168bcb0991SDimitry Andric return; 4178bcb0991SDimitry Andric } 4188bcb0991SDimitry Andric } 4198bcb0991SDimitry Andric } 4208bcb0991SDimitry Andric 4218bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 4228bcb0991SDimitry Andric WasmYAML::FunctionSection &Section) { 4238bcb0991SDimitry Andric encodeULEB128(Section.FunctionTypes.size(), OS); 4248bcb0991SDimitry Andric for (uint32_t FuncType : Section.FunctionTypes) 4258bcb0991SDimitry Andric encodeULEB128(FuncType, OS); 4268bcb0991SDimitry Andric } 4278bcb0991SDimitry Andric 4288bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 4298bcb0991SDimitry Andric WasmYAML::ExportSection &Section) { 4308bcb0991SDimitry Andric encodeULEB128(Section.Exports.size(), OS); 4318bcb0991SDimitry Andric for (const WasmYAML::Export &Export : Section.Exports) { 4328bcb0991SDimitry Andric writeStringRef(Export.Name, OS); 4338bcb0991SDimitry Andric writeUint8(OS, Export.Kind); 4348bcb0991SDimitry Andric encodeULEB128(Export.Index, OS); 4358bcb0991SDimitry Andric } 4368bcb0991SDimitry Andric } 4378bcb0991SDimitry Andric 4388bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 4398bcb0991SDimitry Andric WasmYAML::StartSection &Section) { 4408bcb0991SDimitry Andric encodeULEB128(Section.StartFunction, OS); 4418bcb0991SDimitry Andric } 4428bcb0991SDimitry Andric 4438bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 4448bcb0991SDimitry Andric WasmYAML::TableSection &Section) { 4458bcb0991SDimitry Andric encodeULEB128(Section.Tables.size(), OS); 446e8d8bef9SDimitry Andric uint32_t ExpectedIndex = NumImportedTables; 4478bcb0991SDimitry Andric for (auto &Table : Section.Tables) { 448e8d8bef9SDimitry Andric if (Table.Index != ExpectedIndex) { 449e8d8bef9SDimitry Andric reportError("unexpected table index: " + Twine(Table.Index)); 450e8d8bef9SDimitry Andric return; 451e8d8bef9SDimitry Andric } 452e8d8bef9SDimitry Andric ++ExpectedIndex; 4538bcb0991SDimitry Andric writeUint8(OS, Table.ElemType); 4548bcb0991SDimitry Andric writeLimits(Table.TableLimits, OS); 4558bcb0991SDimitry Andric } 4568bcb0991SDimitry Andric } 4578bcb0991SDimitry Andric 4588bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 4598bcb0991SDimitry Andric WasmYAML::MemorySection &Section) { 4608bcb0991SDimitry Andric encodeULEB128(Section.Memories.size(), OS); 4618bcb0991SDimitry Andric for (const WasmYAML::Limits &Mem : Section.Memories) 4628bcb0991SDimitry Andric writeLimits(Mem, OS); 4638bcb0991SDimitry Andric } 4648bcb0991SDimitry Andric 4658bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 466fe6060f1SDimitry Andric WasmYAML::TagSection &Section) { 467349cc55cSDimitry Andric encodeULEB128(Section.TagTypes.size(), OS); 468349cc55cSDimitry Andric for (uint32_t TagType : Section.TagTypes) { 469349cc55cSDimitry Andric writeUint8(OS, 0); // Reserved 'attribute' field 470349cc55cSDimitry Andric encodeULEB128(TagType, OS); 4715ffd83dbSDimitry Andric } 4725ffd83dbSDimitry Andric } 4735ffd83dbSDimitry Andric 4745ffd83dbSDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 4758bcb0991SDimitry Andric WasmYAML::GlobalSection &Section) { 4768bcb0991SDimitry Andric encodeULEB128(Section.Globals.size(), OS); 4778bcb0991SDimitry Andric uint32_t ExpectedIndex = NumImportedGlobals; 4788bcb0991SDimitry Andric for (auto &Global : Section.Globals) { 4798bcb0991SDimitry Andric if (Global.Index != ExpectedIndex) { 4808bcb0991SDimitry Andric reportError("unexpected global index: " + Twine(Global.Index)); 4818bcb0991SDimitry Andric return; 4828bcb0991SDimitry Andric } 4838bcb0991SDimitry Andric ++ExpectedIndex; 4848bcb0991SDimitry Andric writeUint8(OS, Global.Type); 4858bcb0991SDimitry Andric writeUint8(OS, Global.Mutable); 486*81ad6265SDimitry Andric writeInitExpr(OS, Global.Init); 4878bcb0991SDimitry Andric } 4888bcb0991SDimitry Andric } 4898bcb0991SDimitry Andric 4908bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 4918bcb0991SDimitry Andric WasmYAML::ElemSection &Section) { 4928bcb0991SDimitry Andric encodeULEB128(Section.Segments.size(), OS); 4938bcb0991SDimitry Andric for (auto &Segment : Section.Segments) { 494fe6060f1SDimitry Andric encodeULEB128(Segment.Flags, OS); 495fe6060f1SDimitry Andric if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER) 496fe6060f1SDimitry Andric encodeULEB128(Segment.TableNumber, OS); 497fe6060f1SDimitry Andric 4988bcb0991SDimitry Andric writeInitExpr(OS, Segment.Offset); 4998bcb0991SDimitry Andric 500fe6060f1SDimitry Andric if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND) { 501fe6060f1SDimitry Andric // We only support active function table initializers, for which the elem 502fe6060f1SDimitry Andric // kind is specified to be written as 0x00 and interpreted to mean 503fe6060f1SDimitry Andric // "funcref". 504fe6060f1SDimitry Andric if (Segment.ElemKind != uint32_t(wasm::ValType::FUNCREF)) { 505fe6060f1SDimitry Andric reportError("unexpected elemkind: " + Twine(Segment.ElemKind)); 506fe6060f1SDimitry Andric return; 507fe6060f1SDimitry Andric } 508fe6060f1SDimitry Andric const uint8_t ElemKind = 0; 509fe6060f1SDimitry Andric writeUint8(OS, ElemKind); 510fe6060f1SDimitry Andric } 511fe6060f1SDimitry Andric 5128bcb0991SDimitry Andric encodeULEB128(Segment.Functions.size(), OS); 5138bcb0991SDimitry Andric for (auto &Function : Segment.Functions) 5148bcb0991SDimitry Andric encodeULEB128(Function, OS); 5158bcb0991SDimitry Andric } 5168bcb0991SDimitry Andric } 5178bcb0991SDimitry Andric 5188bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 5198bcb0991SDimitry Andric WasmYAML::CodeSection &Section) { 5208bcb0991SDimitry Andric encodeULEB128(Section.Functions.size(), OS); 5218bcb0991SDimitry Andric uint32_t ExpectedIndex = NumImportedFunctions; 5228bcb0991SDimitry Andric for (auto &Func : Section.Functions) { 5238bcb0991SDimitry Andric std::string OutString; 5248bcb0991SDimitry Andric raw_string_ostream StringStream(OutString); 5258bcb0991SDimitry Andric if (Func.Index != ExpectedIndex) { 5268bcb0991SDimitry Andric reportError("unexpected function index: " + Twine(Func.Index)); 5278bcb0991SDimitry Andric return; 5288bcb0991SDimitry Andric } 5298bcb0991SDimitry Andric ++ExpectedIndex; 5308bcb0991SDimitry Andric 5318bcb0991SDimitry Andric encodeULEB128(Func.Locals.size(), StringStream); 5328bcb0991SDimitry Andric for (auto &LocalDecl : Func.Locals) { 5338bcb0991SDimitry Andric encodeULEB128(LocalDecl.Count, StringStream); 5348bcb0991SDimitry Andric writeUint8(StringStream, LocalDecl.Type); 5358bcb0991SDimitry Andric } 5368bcb0991SDimitry Andric 5378bcb0991SDimitry Andric Func.Body.writeAsBinary(StringStream); 5388bcb0991SDimitry Andric 5398bcb0991SDimitry Andric // Write the section size followed by the content 5408bcb0991SDimitry Andric StringStream.flush(); 5418bcb0991SDimitry Andric encodeULEB128(OutString.size(), OS); 5428bcb0991SDimitry Andric OS << OutString; 5438bcb0991SDimitry Andric } 5448bcb0991SDimitry Andric } 5458bcb0991SDimitry Andric 5468bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 5478bcb0991SDimitry Andric WasmYAML::DataSection &Section) { 5488bcb0991SDimitry Andric encodeULEB128(Section.Segments.size(), OS); 5498bcb0991SDimitry Andric for (auto &Segment : Section.Segments) { 5508bcb0991SDimitry Andric encodeULEB128(Segment.InitFlags, OS); 551e8d8bef9SDimitry Andric if (Segment.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX) 5528bcb0991SDimitry Andric encodeULEB128(Segment.MemoryIndex, OS); 553e8d8bef9SDimitry Andric if ((Segment.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) 5548bcb0991SDimitry Andric writeInitExpr(OS, Segment.Offset); 5558bcb0991SDimitry Andric encodeULEB128(Segment.Content.binary_size(), OS); 5568bcb0991SDimitry Andric Segment.Content.writeAsBinary(OS); 5578bcb0991SDimitry Andric } 5588bcb0991SDimitry Andric } 5598bcb0991SDimitry Andric 5608bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 5618bcb0991SDimitry Andric WasmYAML::DataCountSection &Section) { 5628bcb0991SDimitry Andric encodeULEB128(Section.Count, OS); 5638bcb0991SDimitry Andric } 5648bcb0991SDimitry Andric 5658bcb0991SDimitry Andric void WasmWriter::writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec, 5668bcb0991SDimitry Andric uint32_t SectionIndex) { 5678bcb0991SDimitry Andric switch (Sec.Type) { 5688bcb0991SDimitry Andric case wasm::WASM_SEC_CODE: 5698bcb0991SDimitry Andric writeStringRef("reloc.CODE", OS); 5708bcb0991SDimitry Andric break; 5718bcb0991SDimitry Andric case wasm::WASM_SEC_DATA: 5728bcb0991SDimitry Andric writeStringRef("reloc.DATA", OS); 5738bcb0991SDimitry Andric break; 5748bcb0991SDimitry Andric case wasm::WASM_SEC_CUSTOM: { 5758bcb0991SDimitry Andric auto *CustomSection = cast<WasmYAML::CustomSection>(&Sec); 5768bcb0991SDimitry Andric writeStringRef(("reloc." + CustomSection->Name).str(), OS); 5778bcb0991SDimitry Andric break; 5788bcb0991SDimitry Andric } 5798bcb0991SDimitry Andric default: 5808bcb0991SDimitry Andric llvm_unreachable("not yet implemented"); 5818bcb0991SDimitry Andric } 5828bcb0991SDimitry Andric 5838bcb0991SDimitry Andric encodeULEB128(SectionIndex, OS); 5848bcb0991SDimitry Andric encodeULEB128(Sec.Relocations.size(), OS); 5858bcb0991SDimitry Andric 5868bcb0991SDimitry Andric for (auto Reloc : Sec.Relocations) { 5878bcb0991SDimitry Andric writeUint8(OS, Reloc.Type); 5888bcb0991SDimitry Andric encodeULEB128(Reloc.Offset, OS); 5898bcb0991SDimitry Andric encodeULEB128(Reloc.Index, OS); 5901fd87a68SDimitry Andric if (wasm::relocTypeHasAddend(Reloc.Type)) 591fe6060f1SDimitry Andric encodeSLEB128(Reloc.Addend, OS); 5928bcb0991SDimitry Andric } 5938bcb0991SDimitry Andric } 5948bcb0991SDimitry Andric 5958bcb0991SDimitry Andric bool WasmWriter::writeWasm(raw_ostream &OS) { 5968bcb0991SDimitry Andric // Write headers 5978bcb0991SDimitry Andric OS.write(wasm::WasmMagic, sizeof(wasm::WasmMagic)); 5988bcb0991SDimitry Andric writeUint32(OS, Obj.Header.Version); 5998bcb0991SDimitry Andric 6008bcb0991SDimitry Andric // Write each section 6018bcb0991SDimitry Andric llvm::object::WasmSectionOrderChecker Checker; 6028bcb0991SDimitry Andric for (const std::unique_ptr<WasmYAML::Section> &Sec : Obj.Sections) { 6038bcb0991SDimitry Andric StringRef SecName = ""; 6048bcb0991SDimitry Andric if (auto S = dyn_cast<WasmYAML::CustomSection>(Sec.get())) 6058bcb0991SDimitry Andric SecName = S->Name; 6068bcb0991SDimitry Andric if (!Checker.isValidSectionOrder(Sec->Type, SecName)) { 6078bcb0991SDimitry Andric reportError("out of order section type: " + Twine(Sec->Type)); 6088bcb0991SDimitry Andric return false; 6098bcb0991SDimitry Andric } 6108bcb0991SDimitry Andric encodeULEB128(Sec->Type, OS); 6118bcb0991SDimitry Andric std::string OutString; 6128bcb0991SDimitry Andric raw_string_ostream StringStream(OutString); 6138bcb0991SDimitry Andric if (auto S = dyn_cast<WasmYAML::CustomSection>(Sec.get())) 6148bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6158bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::TypeSection>(Sec.get())) 6168bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6178bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::ImportSection>(Sec.get())) 6188bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6198bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::FunctionSection>(Sec.get())) 6208bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6218bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::TableSection>(Sec.get())) 6228bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6238bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::MemorySection>(Sec.get())) 6248bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 625fe6060f1SDimitry Andric else if (auto S = dyn_cast<WasmYAML::TagSection>(Sec.get())) 6268bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6275ffd83dbSDimitry Andric else if (auto S = dyn_cast<WasmYAML::GlobalSection>(Sec.get())) 6285ffd83dbSDimitry Andric writeSectionContent(StringStream, *S); 6298bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::ExportSection>(Sec.get())) 6308bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6318bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::StartSection>(Sec.get())) 6328bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6338bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::ElemSection>(Sec.get())) 6348bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6358bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::CodeSection>(Sec.get())) 6368bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6378bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::DataSection>(Sec.get())) 6388bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6398bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::DataCountSection>(Sec.get())) 6408bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6418bcb0991SDimitry Andric else 6428bcb0991SDimitry Andric reportError("unknown section type: " + Twine(Sec->Type)); 6438bcb0991SDimitry Andric 6448bcb0991SDimitry Andric if (HasError) 6458bcb0991SDimitry Andric return false; 6468bcb0991SDimitry Andric 6478bcb0991SDimitry Andric StringStream.flush(); 6488bcb0991SDimitry Andric 6498bcb0991SDimitry Andric // Write the section size followed by the content 6508bcb0991SDimitry Andric encodeULEB128(OutString.size(), OS); 6518bcb0991SDimitry Andric OS << OutString; 6528bcb0991SDimitry Andric } 6538bcb0991SDimitry Andric 6548bcb0991SDimitry Andric // write reloc sections for any section that have relocations 6558bcb0991SDimitry Andric uint32_t SectionIndex = 0; 6568bcb0991SDimitry Andric for (const std::unique_ptr<WasmYAML::Section> &Sec : Obj.Sections) { 6578bcb0991SDimitry Andric if (Sec->Relocations.empty()) { 6588bcb0991SDimitry Andric SectionIndex++; 6598bcb0991SDimitry Andric continue; 6608bcb0991SDimitry Andric } 6618bcb0991SDimitry Andric 6628bcb0991SDimitry Andric writeUint8(OS, wasm::WASM_SEC_CUSTOM); 6638bcb0991SDimitry Andric std::string OutString; 6648bcb0991SDimitry Andric raw_string_ostream StringStream(OutString); 6658bcb0991SDimitry Andric writeRelocSection(StringStream, *Sec, SectionIndex++); 6668bcb0991SDimitry Andric StringStream.flush(); 6678bcb0991SDimitry Andric 6688bcb0991SDimitry Andric encodeULEB128(OutString.size(), OS); 6698bcb0991SDimitry Andric OS << OutString; 6708bcb0991SDimitry Andric } 6718bcb0991SDimitry Andric 6728bcb0991SDimitry Andric return true; 6738bcb0991SDimitry Andric } 6748bcb0991SDimitry Andric 6758bcb0991SDimitry Andric namespace llvm { 6768bcb0991SDimitry Andric namespace yaml { 6778bcb0991SDimitry Andric 6788bcb0991SDimitry Andric bool yaml2wasm(WasmYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH) { 6798bcb0991SDimitry Andric WasmWriter Writer(Doc, EH); 6808bcb0991SDimitry Andric return Writer.writeWasm(Out); 6818bcb0991SDimitry Andric } 6828bcb0991SDimitry Andric 6838bcb0991SDimitry Andric } // namespace yaml 6848bcb0991SDimitry Andric } // namespace llvm 685