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 368bcb0991SDimitry Andric void writeInitExpr(raw_ostream &OS, const wasm::WasmInitExpr &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, 1328bcb0991SDimitry Andric const wasm::WasmInitExpr &InitExpr) { 1338bcb0991SDimitry Andric writeUint8(OS, InitExpr.Opcode); 1348bcb0991SDimitry Andric switch (InitExpr.Opcode) { 1358bcb0991SDimitry Andric case wasm::WASM_OPCODE_I32_CONST: 1368bcb0991SDimitry Andric encodeSLEB128(InitExpr.Value.Int32, OS); 1378bcb0991SDimitry Andric break; 1388bcb0991SDimitry Andric case wasm::WASM_OPCODE_I64_CONST: 1398bcb0991SDimitry Andric encodeSLEB128(InitExpr.Value.Int64, OS); 1408bcb0991SDimitry Andric break; 1418bcb0991SDimitry Andric case wasm::WASM_OPCODE_F32_CONST: 1428bcb0991SDimitry Andric writeUint32(OS, InitExpr.Value.Float32); 1438bcb0991SDimitry Andric break; 1448bcb0991SDimitry Andric case wasm::WASM_OPCODE_F64_CONST: 1458bcb0991SDimitry Andric writeUint64(OS, InitExpr.Value.Float64); 1468bcb0991SDimitry Andric break; 1478bcb0991SDimitry Andric case wasm::WASM_OPCODE_GLOBAL_GET: 1488bcb0991SDimitry Andric encodeULEB128(InitExpr.Value.Global, OS); 1498bcb0991SDimitry Andric break; 1508bcb0991SDimitry Andric default: 1518bcb0991SDimitry Andric reportError("unknown opcode in init_expr: " + Twine(InitExpr.Opcode)); 1528bcb0991SDimitry Andric return; 1538bcb0991SDimitry Andric } 1548bcb0991SDimitry Andric writeUint8(OS, wasm::WASM_OPCODE_END); 1558bcb0991SDimitry Andric } 1568bcb0991SDimitry Andric 1578bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 1588bcb0991SDimitry Andric WasmYAML::DylinkSection &Section) { 1598bcb0991SDimitry Andric writeStringRef(Section.Name, OS); 160*349cc55cSDimitry Andric 161*349cc55cSDimitry Andric writeUint8(OS, wasm::WASM_DYLINK_MEM_INFO); 162*349cc55cSDimitry Andric SubSectionWriter SubSection(OS); 163*349cc55cSDimitry Andric raw_ostream &SubOS = SubSection.getStream(); 164*349cc55cSDimitry Andric encodeULEB128(Section.MemorySize, SubOS); 165*349cc55cSDimitry Andric encodeULEB128(Section.MemoryAlignment, SubOS); 166*349cc55cSDimitry Andric encodeULEB128(Section.TableSize, SubOS); 167*349cc55cSDimitry Andric encodeULEB128(Section.TableAlignment, SubOS); 168*349cc55cSDimitry Andric SubSection.done(); 169*349cc55cSDimitry Andric 170*349cc55cSDimitry Andric if (Section.Needed.size()) { 171*349cc55cSDimitry Andric writeUint8(OS, wasm::WASM_DYLINK_NEEDED); 172*349cc55cSDimitry Andric raw_ostream &SubOS = SubSection.getStream(); 173*349cc55cSDimitry Andric encodeULEB128(Section.Needed.size(), SubOS); 1748bcb0991SDimitry Andric for (StringRef Needed : Section.Needed) 175*349cc55cSDimitry Andric writeStringRef(Needed, SubOS); 176*349cc55cSDimitry Andric SubSection.done(); 177*349cc55cSDimitry Andric } 1788bcb0991SDimitry Andric } 1798bcb0991SDimitry Andric 1808bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 1818bcb0991SDimitry Andric WasmYAML::LinkingSection &Section) { 1828bcb0991SDimitry Andric writeStringRef(Section.Name, OS); 1838bcb0991SDimitry Andric encodeULEB128(Section.Version, OS); 1848bcb0991SDimitry Andric 1858bcb0991SDimitry Andric SubSectionWriter SubSection(OS); 1868bcb0991SDimitry Andric 1878bcb0991SDimitry Andric // SYMBOL_TABLE subsection 1888bcb0991SDimitry Andric if (Section.SymbolTable.size()) { 1898bcb0991SDimitry Andric writeUint8(OS, wasm::WASM_SYMBOL_TABLE); 1908bcb0991SDimitry Andric 1918bcb0991SDimitry Andric encodeULEB128(Section.SymbolTable.size(), SubSection.getStream()); 1928bcb0991SDimitry Andric #ifndef NDEBUG 1938bcb0991SDimitry Andric uint32_t SymbolIndex = 0; 1948bcb0991SDimitry Andric #endif 1958bcb0991SDimitry Andric for (const WasmYAML::SymbolInfo &Info : Section.SymbolTable) { 1968bcb0991SDimitry Andric assert(Info.Index == SymbolIndex++); 1978bcb0991SDimitry Andric writeUint8(SubSection.getStream(), Info.Kind); 1988bcb0991SDimitry Andric encodeULEB128(Info.Flags, SubSection.getStream()); 1998bcb0991SDimitry Andric switch (Info.Kind) { 2008bcb0991SDimitry Andric case wasm::WASM_SYMBOL_TYPE_FUNCTION: 2018bcb0991SDimitry Andric case wasm::WASM_SYMBOL_TYPE_GLOBAL: 202e8d8bef9SDimitry Andric case wasm::WASM_SYMBOL_TYPE_TABLE: 203fe6060f1SDimitry Andric case wasm::WASM_SYMBOL_TYPE_TAG: 2048bcb0991SDimitry Andric encodeULEB128(Info.ElementIndex, SubSection.getStream()); 2058bcb0991SDimitry Andric if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 || 2068bcb0991SDimitry Andric (Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) 2078bcb0991SDimitry Andric writeStringRef(Info.Name, SubSection.getStream()); 2088bcb0991SDimitry Andric break; 2098bcb0991SDimitry Andric case wasm::WASM_SYMBOL_TYPE_DATA: 2108bcb0991SDimitry Andric writeStringRef(Info.Name, SubSection.getStream()); 2118bcb0991SDimitry Andric if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) { 2128bcb0991SDimitry Andric encodeULEB128(Info.DataRef.Segment, SubSection.getStream()); 2138bcb0991SDimitry Andric encodeULEB128(Info.DataRef.Offset, SubSection.getStream()); 2148bcb0991SDimitry Andric encodeULEB128(Info.DataRef.Size, SubSection.getStream()); 2158bcb0991SDimitry Andric } 2168bcb0991SDimitry Andric break; 2178bcb0991SDimitry Andric case wasm::WASM_SYMBOL_TYPE_SECTION: 2188bcb0991SDimitry Andric encodeULEB128(Info.ElementIndex, SubSection.getStream()); 2198bcb0991SDimitry Andric break; 2208bcb0991SDimitry Andric default: 2218bcb0991SDimitry Andric llvm_unreachable("unexpected kind"); 2228bcb0991SDimitry Andric } 2238bcb0991SDimitry Andric } 2248bcb0991SDimitry Andric 2258bcb0991SDimitry Andric SubSection.done(); 2268bcb0991SDimitry Andric } 2278bcb0991SDimitry Andric 2288bcb0991SDimitry Andric // SEGMENT_NAMES subsection 2298bcb0991SDimitry Andric if (Section.SegmentInfos.size()) { 2308bcb0991SDimitry Andric writeUint8(OS, wasm::WASM_SEGMENT_INFO); 2318bcb0991SDimitry Andric encodeULEB128(Section.SegmentInfos.size(), SubSection.getStream()); 2328bcb0991SDimitry Andric for (const WasmYAML::SegmentInfo &SegmentInfo : Section.SegmentInfos) { 2338bcb0991SDimitry Andric writeStringRef(SegmentInfo.Name, SubSection.getStream()); 2348bcb0991SDimitry Andric encodeULEB128(SegmentInfo.Alignment, SubSection.getStream()); 2358bcb0991SDimitry Andric encodeULEB128(SegmentInfo.Flags, SubSection.getStream()); 2368bcb0991SDimitry Andric } 2378bcb0991SDimitry Andric SubSection.done(); 2388bcb0991SDimitry Andric } 2398bcb0991SDimitry Andric 2408bcb0991SDimitry Andric // INIT_FUNCS subsection 2418bcb0991SDimitry Andric if (Section.InitFunctions.size()) { 2428bcb0991SDimitry Andric writeUint8(OS, wasm::WASM_INIT_FUNCS); 2438bcb0991SDimitry Andric encodeULEB128(Section.InitFunctions.size(), SubSection.getStream()); 2448bcb0991SDimitry Andric for (const WasmYAML::InitFunction &Func : Section.InitFunctions) { 2458bcb0991SDimitry Andric encodeULEB128(Func.Priority, SubSection.getStream()); 2468bcb0991SDimitry Andric encodeULEB128(Func.Symbol, SubSection.getStream()); 2478bcb0991SDimitry Andric } 2488bcb0991SDimitry Andric SubSection.done(); 2498bcb0991SDimitry Andric } 2508bcb0991SDimitry Andric 2518bcb0991SDimitry Andric // COMDAT_INFO subsection 2528bcb0991SDimitry Andric if (Section.Comdats.size()) { 2538bcb0991SDimitry Andric writeUint8(OS, wasm::WASM_COMDAT_INFO); 2548bcb0991SDimitry Andric encodeULEB128(Section.Comdats.size(), SubSection.getStream()); 2558bcb0991SDimitry Andric for (const auto &C : Section.Comdats) { 2568bcb0991SDimitry Andric writeStringRef(C.Name, SubSection.getStream()); 2578bcb0991SDimitry Andric encodeULEB128(0, SubSection.getStream()); // flags for future use 2588bcb0991SDimitry Andric encodeULEB128(C.Entries.size(), SubSection.getStream()); 2598bcb0991SDimitry Andric for (const WasmYAML::ComdatEntry &Entry : C.Entries) { 2608bcb0991SDimitry Andric writeUint8(SubSection.getStream(), Entry.Kind); 2618bcb0991SDimitry Andric encodeULEB128(Entry.Index, SubSection.getStream()); 2628bcb0991SDimitry Andric } 2638bcb0991SDimitry Andric } 2648bcb0991SDimitry Andric SubSection.done(); 2658bcb0991SDimitry Andric } 2668bcb0991SDimitry Andric } 2678bcb0991SDimitry Andric 2688bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 2698bcb0991SDimitry Andric WasmYAML::NameSection &Section) { 2708bcb0991SDimitry Andric writeStringRef(Section.Name, OS); 2718bcb0991SDimitry Andric if (Section.FunctionNames.size()) { 2728bcb0991SDimitry Andric writeUint8(OS, wasm::WASM_NAMES_FUNCTION); 2738bcb0991SDimitry Andric 2748bcb0991SDimitry Andric SubSectionWriter SubSection(OS); 2758bcb0991SDimitry Andric 2768bcb0991SDimitry Andric encodeULEB128(Section.FunctionNames.size(), SubSection.getStream()); 2778bcb0991SDimitry Andric for (const WasmYAML::NameEntry &NameEntry : Section.FunctionNames) { 2788bcb0991SDimitry Andric encodeULEB128(NameEntry.Index, SubSection.getStream()); 2798bcb0991SDimitry Andric writeStringRef(NameEntry.Name, SubSection.getStream()); 2808bcb0991SDimitry Andric } 2818bcb0991SDimitry Andric 2828bcb0991SDimitry Andric SubSection.done(); 2838bcb0991SDimitry Andric } 284e8d8bef9SDimitry Andric if (Section.GlobalNames.size()) { 285e8d8bef9SDimitry Andric writeUint8(OS, wasm::WASM_NAMES_GLOBAL); 286e8d8bef9SDimitry Andric 287e8d8bef9SDimitry Andric SubSectionWriter SubSection(OS); 288e8d8bef9SDimitry Andric 289e8d8bef9SDimitry Andric encodeULEB128(Section.GlobalNames.size(), SubSection.getStream()); 290e8d8bef9SDimitry Andric for (const WasmYAML::NameEntry &NameEntry : Section.GlobalNames) { 291e8d8bef9SDimitry Andric encodeULEB128(NameEntry.Index, SubSection.getStream()); 292e8d8bef9SDimitry Andric writeStringRef(NameEntry.Name, SubSection.getStream()); 293e8d8bef9SDimitry Andric } 294e8d8bef9SDimitry Andric 295e8d8bef9SDimitry Andric SubSection.done(); 296e8d8bef9SDimitry Andric } 297e8d8bef9SDimitry Andric if (Section.DataSegmentNames.size()) { 298e8d8bef9SDimitry Andric writeUint8(OS, wasm::WASM_NAMES_DATA_SEGMENT); 299e8d8bef9SDimitry Andric 300e8d8bef9SDimitry Andric SubSectionWriter SubSection(OS); 301e8d8bef9SDimitry Andric 302e8d8bef9SDimitry Andric encodeULEB128(Section.DataSegmentNames.size(), SubSection.getStream()); 303e8d8bef9SDimitry Andric for (const WasmYAML::NameEntry &NameEntry : Section.DataSegmentNames) { 304e8d8bef9SDimitry Andric encodeULEB128(NameEntry.Index, SubSection.getStream()); 305e8d8bef9SDimitry Andric writeStringRef(NameEntry.Name, SubSection.getStream()); 306e8d8bef9SDimitry Andric } 307e8d8bef9SDimitry Andric 308e8d8bef9SDimitry Andric SubSection.done(); 309e8d8bef9SDimitry Andric } 3108bcb0991SDimitry Andric } 3118bcb0991SDimitry Andric 3128bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 3138bcb0991SDimitry Andric WasmYAML::ProducersSection &Section) { 3148bcb0991SDimitry Andric writeStringRef(Section.Name, OS); 3158bcb0991SDimitry Andric int Fields = int(!Section.Languages.empty()) + int(!Section.Tools.empty()) + 3168bcb0991SDimitry Andric int(!Section.SDKs.empty()); 3178bcb0991SDimitry Andric if (Fields == 0) 3188bcb0991SDimitry Andric return; 3198bcb0991SDimitry Andric encodeULEB128(Fields, OS); 3208bcb0991SDimitry Andric for (auto &Field : {std::make_pair(StringRef("language"), &Section.Languages), 3218bcb0991SDimitry Andric std::make_pair(StringRef("processed-by"), &Section.Tools), 3228bcb0991SDimitry Andric std::make_pair(StringRef("sdk"), &Section.SDKs)}) { 3238bcb0991SDimitry Andric if (Field.second->empty()) 3248bcb0991SDimitry Andric continue; 3258bcb0991SDimitry Andric writeStringRef(Field.first, OS); 3268bcb0991SDimitry Andric encodeULEB128(Field.second->size(), OS); 3278bcb0991SDimitry Andric for (auto &Entry : *Field.second) { 3288bcb0991SDimitry Andric writeStringRef(Entry.Name, OS); 3298bcb0991SDimitry Andric writeStringRef(Entry.Version, OS); 3308bcb0991SDimitry Andric } 3318bcb0991SDimitry Andric } 3328bcb0991SDimitry Andric } 3338bcb0991SDimitry Andric 3348bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 3358bcb0991SDimitry Andric WasmYAML::TargetFeaturesSection &Section) { 3368bcb0991SDimitry Andric writeStringRef(Section.Name, OS); 3378bcb0991SDimitry Andric encodeULEB128(Section.Features.size(), OS); 3388bcb0991SDimitry Andric for (auto &E : Section.Features) { 3398bcb0991SDimitry Andric writeUint8(OS, E.Prefix); 3408bcb0991SDimitry Andric writeStringRef(E.Name, OS); 3418bcb0991SDimitry Andric } 3428bcb0991SDimitry Andric } 3438bcb0991SDimitry Andric 3448bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 3458bcb0991SDimitry Andric WasmYAML::CustomSection &Section) { 3468bcb0991SDimitry Andric if (auto S = dyn_cast<WasmYAML::DylinkSection>(&Section)) { 3478bcb0991SDimitry Andric writeSectionContent(OS, *S); 3488bcb0991SDimitry Andric } else if (auto S = dyn_cast<WasmYAML::NameSection>(&Section)) { 3498bcb0991SDimitry Andric writeSectionContent(OS, *S); 3508bcb0991SDimitry Andric } else if (auto S = dyn_cast<WasmYAML::LinkingSection>(&Section)) { 3518bcb0991SDimitry Andric writeSectionContent(OS, *S); 3528bcb0991SDimitry Andric } else if (auto S = dyn_cast<WasmYAML::ProducersSection>(&Section)) { 3538bcb0991SDimitry Andric writeSectionContent(OS, *S); 3548bcb0991SDimitry Andric } else if (auto S = dyn_cast<WasmYAML::TargetFeaturesSection>(&Section)) { 3558bcb0991SDimitry Andric writeSectionContent(OS, *S); 3568bcb0991SDimitry Andric } else { 3578bcb0991SDimitry Andric writeStringRef(Section.Name, OS); 3588bcb0991SDimitry Andric Section.Payload.writeAsBinary(OS); 3598bcb0991SDimitry Andric } 3608bcb0991SDimitry Andric } 3618bcb0991SDimitry Andric 3628bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 3638bcb0991SDimitry Andric WasmYAML::TypeSection &Section) { 3648bcb0991SDimitry Andric encodeULEB128(Section.Signatures.size(), OS); 3658bcb0991SDimitry Andric uint32_t ExpectedIndex = 0; 3668bcb0991SDimitry Andric for (const WasmYAML::Signature &Sig : Section.Signatures) { 3678bcb0991SDimitry Andric if (Sig.Index != ExpectedIndex) { 3688bcb0991SDimitry Andric reportError("unexpected type index: " + Twine(Sig.Index)); 3698bcb0991SDimitry Andric return; 3708bcb0991SDimitry Andric } 3718bcb0991SDimitry Andric ++ExpectedIndex; 3728bcb0991SDimitry Andric writeUint8(OS, Sig.Form); 3738bcb0991SDimitry Andric encodeULEB128(Sig.ParamTypes.size(), OS); 3748bcb0991SDimitry Andric for (auto ParamType : Sig.ParamTypes) 3758bcb0991SDimitry Andric writeUint8(OS, ParamType); 3768bcb0991SDimitry Andric encodeULEB128(Sig.ReturnTypes.size(), OS); 3778bcb0991SDimitry Andric for (auto ReturnType : Sig.ReturnTypes) 3788bcb0991SDimitry Andric writeUint8(OS, ReturnType); 3798bcb0991SDimitry Andric } 3808bcb0991SDimitry Andric } 3818bcb0991SDimitry Andric 3828bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 3838bcb0991SDimitry Andric WasmYAML::ImportSection &Section) { 3848bcb0991SDimitry Andric encodeULEB128(Section.Imports.size(), OS); 3858bcb0991SDimitry Andric for (const WasmYAML::Import &Import : Section.Imports) { 3868bcb0991SDimitry Andric writeStringRef(Import.Module, OS); 3878bcb0991SDimitry Andric writeStringRef(Import.Field, OS); 3888bcb0991SDimitry Andric writeUint8(OS, Import.Kind); 3898bcb0991SDimitry Andric switch (Import.Kind) { 3908bcb0991SDimitry Andric case wasm::WASM_EXTERNAL_FUNCTION: 3918bcb0991SDimitry Andric encodeULEB128(Import.SigIndex, OS); 3928bcb0991SDimitry Andric NumImportedFunctions++; 3938bcb0991SDimitry Andric break; 3948bcb0991SDimitry Andric case wasm::WASM_EXTERNAL_GLOBAL: 3958bcb0991SDimitry Andric writeUint8(OS, Import.GlobalImport.Type); 3968bcb0991SDimitry Andric writeUint8(OS, Import.GlobalImport.Mutable); 3978bcb0991SDimitry Andric NumImportedGlobals++; 3988bcb0991SDimitry Andric break; 399fe6060f1SDimitry Andric case wasm::WASM_EXTERNAL_TAG: 400*349cc55cSDimitry Andric writeUint8(OS, 0); // Reserved 'attribute' field 401*349cc55cSDimitry Andric encodeULEB128(Import.SigIndex, OS); 402fe6060f1SDimitry Andric NumImportedTags++; 4038bcb0991SDimitry Andric break; 4048bcb0991SDimitry Andric case wasm::WASM_EXTERNAL_MEMORY: 4058bcb0991SDimitry Andric writeLimits(Import.Memory, OS); 4068bcb0991SDimitry Andric break; 4078bcb0991SDimitry Andric case wasm::WASM_EXTERNAL_TABLE: 4088bcb0991SDimitry Andric writeUint8(OS, Import.TableImport.ElemType); 4098bcb0991SDimitry Andric writeLimits(Import.TableImport.TableLimits, OS); 410e8d8bef9SDimitry Andric NumImportedTables++; 4118bcb0991SDimitry Andric break; 4128bcb0991SDimitry Andric default: 4138bcb0991SDimitry Andric reportError("unknown import type: " +Twine(Import.Kind)); 4148bcb0991SDimitry Andric return; 4158bcb0991SDimitry Andric } 4168bcb0991SDimitry Andric } 4178bcb0991SDimitry Andric } 4188bcb0991SDimitry Andric 4198bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 4208bcb0991SDimitry Andric WasmYAML::FunctionSection &Section) { 4218bcb0991SDimitry Andric encodeULEB128(Section.FunctionTypes.size(), OS); 4228bcb0991SDimitry Andric for (uint32_t FuncType : Section.FunctionTypes) 4238bcb0991SDimitry Andric encodeULEB128(FuncType, OS); 4248bcb0991SDimitry Andric } 4258bcb0991SDimitry Andric 4268bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 4278bcb0991SDimitry Andric WasmYAML::ExportSection &Section) { 4288bcb0991SDimitry Andric encodeULEB128(Section.Exports.size(), OS); 4298bcb0991SDimitry Andric for (const WasmYAML::Export &Export : Section.Exports) { 4308bcb0991SDimitry Andric writeStringRef(Export.Name, OS); 4318bcb0991SDimitry Andric writeUint8(OS, Export.Kind); 4328bcb0991SDimitry Andric encodeULEB128(Export.Index, OS); 4338bcb0991SDimitry Andric } 4348bcb0991SDimitry Andric } 4358bcb0991SDimitry Andric 4368bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 4378bcb0991SDimitry Andric WasmYAML::StartSection &Section) { 4388bcb0991SDimitry Andric encodeULEB128(Section.StartFunction, OS); 4398bcb0991SDimitry Andric } 4408bcb0991SDimitry Andric 4418bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 4428bcb0991SDimitry Andric WasmYAML::TableSection &Section) { 4438bcb0991SDimitry Andric encodeULEB128(Section.Tables.size(), OS); 444e8d8bef9SDimitry Andric uint32_t ExpectedIndex = NumImportedTables; 4458bcb0991SDimitry Andric for (auto &Table : Section.Tables) { 446e8d8bef9SDimitry Andric if (Table.Index != ExpectedIndex) { 447e8d8bef9SDimitry Andric reportError("unexpected table index: " + Twine(Table.Index)); 448e8d8bef9SDimitry Andric return; 449e8d8bef9SDimitry Andric } 450e8d8bef9SDimitry Andric ++ExpectedIndex; 4518bcb0991SDimitry Andric writeUint8(OS, Table.ElemType); 4528bcb0991SDimitry Andric writeLimits(Table.TableLimits, OS); 4538bcb0991SDimitry Andric } 4548bcb0991SDimitry Andric } 4558bcb0991SDimitry Andric 4568bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 4578bcb0991SDimitry Andric WasmYAML::MemorySection &Section) { 4588bcb0991SDimitry Andric encodeULEB128(Section.Memories.size(), OS); 4598bcb0991SDimitry Andric for (const WasmYAML::Limits &Mem : Section.Memories) 4608bcb0991SDimitry Andric writeLimits(Mem, OS); 4618bcb0991SDimitry Andric } 4628bcb0991SDimitry Andric 4638bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 464fe6060f1SDimitry Andric WasmYAML::TagSection &Section) { 465*349cc55cSDimitry Andric encodeULEB128(Section.TagTypes.size(), OS); 466*349cc55cSDimitry Andric for (uint32_t TagType : Section.TagTypes) { 467*349cc55cSDimitry Andric writeUint8(OS, 0); // Reserved 'attribute' field 468*349cc55cSDimitry Andric encodeULEB128(TagType, OS); 4695ffd83dbSDimitry Andric } 4705ffd83dbSDimitry Andric } 4715ffd83dbSDimitry Andric 4725ffd83dbSDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 4738bcb0991SDimitry Andric WasmYAML::GlobalSection &Section) { 4748bcb0991SDimitry Andric encodeULEB128(Section.Globals.size(), OS); 4758bcb0991SDimitry Andric uint32_t ExpectedIndex = NumImportedGlobals; 4768bcb0991SDimitry Andric for (auto &Global : Section.Globals) { 4778bcb0991SDimitry Andric if (Global.Index != ExpectedIndex) { 4788bcb0991SDimitry Andric reportError("unexpected global index: " + Twine(Global.Index)); 4798bcb0991SDimitry Andric return; 4808bcb0991SDimitry Andric } 4818bcb0991SDimitry Andric ++ExpectedIndex; 4828bcb0991SDimitry Andric writeUint8(OS, Global.Type); 4838bcb0991SDimitry Andric writeUint8(OS, Global.Mutable); 4848bcb0991SDimitry Andric writeInitExpr(OS, Global.InitExpr); 4858bcb0991SDimitry Andric } 4868bcb0991SDimitry Andric } 4878bcb0991SDimitry Andric 4888bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 4898bcb0991SDimitry Andric WasmYAML::ElemSection &Section) { 4908bcb0991SDimitry Andric encodeULEB128(Section.Segments.size(), OS); 4918bcb0991SDimitry Andric for (auto &Segment : Section.Segments) { 492fe6060f1SDimitry Andric encodeULEB128(Segment.Flags, OS); 493fe6060f1SDimitry Andric if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER) 494fe6060f1SDimitry Andric encodeULEB128(Segment.TableNumber, OS); 495fe6060f1SDimitry Andric 4968bcb0991SDimitry Andric writeInitExpr(OS, Segment.Offset); 4978bcb0991SDimitry Andric 498fe6060f1SDimitry Andric if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND) { 499fe6060f1SDimitry Andric // We only support active function table initializers, for which the elem 500fe6060f1SDimitry Andric // kind is specified to be written as 0x00 and interpreted to mean 501fe6060f1SDimitry Andric // "funcref". 502fe6060f1SDimitry Andric if (Segment.ElemKind != uint32_t(wasm::ValType::FUNCREF)) { 503fe6060f1SDimitry Andric reportError("unexpected elemkind: " + Twine(Segment.ElemKind)); 504fe6060f1SDimitry Andric return; 505fe6060f1SDimitry Andric } 506fe6060f1SDimitry Andric const uint8_t ElemKind = 0; 507fe6060f1SDimitry Andric writeUint8(OS, ElemKind); 508fe6060f1SDimitry Andric } 509fe6060f1SDimitry Andric 5108bcb0991SDimitry Andric encodeULEB128(Segment.Functions.size(), OS); 5118bcb0991SDimitry Andric for (auto &Function : Segment.Functions) 5128bcb0991SDimitry Andric encodeULEB128(Function, OS); 5138bcb0991SDimitry Andric } 5148bcb0991SDimitry Andric } 5158bcb0991SDimitry Andric 5168bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 5178bcb0991SDimitry Andric WasmYAML::CodeSection &Section) { 5188bcb0991SDimitry Andric encodeULEB128(Section.Functions.size(), OS); 5198bcb0991SDimitry Andric uint32_t ExpectedIndex = NumImportedFunctions; 5208bcb0991SDimitry Andric for (auto &Func : Section.Functions) { 5218bcb0991SDimitry Andric std::string OutString; 5228bcb0991SDimitry Andric raw_string_ostream StringStream(OutString); 5238bcb0991SDimitry Andric if (Func.Index != ExpectedIndex) { 5248bcb0991SDimitry Andric reportError("unexpected function index: " + Twine(Func.Index)); 5258bcb0991SDimitry Andric return; 5268bcb0991SDimitry Andric } 5278bcb0991SDimitry Andric ++ExpectedIndex; 5288bcb0991SDimitry Andric 5298bcb0991SDimitry Andric encodeULEB128(Func.Locals.size(), StringStream); 5308bcb0991SDimitry Andric for (auto &LocalDecl : Func.Locals) { 5318bcb0991SDimitry Andric encodeULEB128(LocalDecl.Count, StringStream); 5328bcb0991SDimitry Andric writeUint8(StringStream, LocalDecl.Type); 5338bcb0991SDimitry Andric } 5348bcb0991SDimitry Andric 5358bcb0991SDimitry Andric Func.Body.writeAsBinary(StringStream); 5368bcb0991SDimitry Andric 5378bcb0991SDimitry Andric // Write the section size followed by the content 5388bcb0991SDimitry Andric StringStream.flush(); 5398bcb0991SDimitry Andric encodeULEB128(OutString.size(), OS); 5408bcb0991SDimitry Andric OS << OutString; 5418bcb0991SDimitry Andric } 5428bcb0991SDimitry Andric } 5438bcb0991SDimitry Andric 5448bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 5458bcb0991SDimitry Andric WasmYAML::DataSection &Section) { 5468bcb0991SDimitry Andric encodeULEB128(Section.Segments.size(), OS); 5478bcb0991SDimitry Andric for (auto &Segment : Section.Segments) { 5488bcb0991SDimitry Andric encodeULEB128(Segment.InitFlags, OS); 549e8d8bef9SDimitry Andric if (Segment.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX) 5508bcb0991SDimitry Andric encodeULEB128(Segment.MemoryIndex, OS); 551e8d8bef9SDimitry Andric if ((Segment.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) 5528bcb0991SDimitry Andric writeInitExpr(OS, Segment.Offset); 5538bcb0991SDimitry Andric encodeULEB128(Segment.Content.binary_size(), OS); 5548bcb0991SDimitry Andric Segment.Content.writeAsBinary(OS); 5558bcb0991SDimitry Andric } 5568bcb0991SDimitry Andric } 5578bcb0991SDimitry Andric 5588bcb0991SDimitry Andric void WasmWriter::writeSectionContent(raw_ostream &OS, 5598bcb0991SDimitry Andric WasmYAML::DataCountSection &Section) { 5608bcb0991SDimitry Andric encodeULEB128(Section.Count, OS); 5618bcb0991SDimitry Andric } 5628bcb0991SDimitry Andric 5638bcb0991SDimitry Andric void WasmWriter::writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec, 5648bcb0991SDimitry Andric uint32_t SectionIndex) { 5658bcb0991SDimitry Andric switch (Sec.Type) { 5668bcb0991SDimitry Andric case wasm::WASM_SEC_CODE: 5678bcb0991SDimitry Andric writeStringRef("reloc.CODE", OS); 5688bcb0991SDimitry Andric break; 5698bcb0991SDimitry Andric case wasm::WASM_SEC_DATA: 5708bcb0991SDimitry Andric writeStringRef("reloc.DATA", OS); 5718bcb0991SDimitry Andric break; 5728bcb0991SDimitry Andric case wasm::WASM_SEC_CUSTOM: { 5738bcb0991SDimitry Andric auto *CustomSection = cast<WasmYAML::CustomSection>(&Sec); 5748bcb0991SDimitry Andric writeStringRef(("reloc." + CustomSection->Name).str(), OS); 5758bcb0991SDimitry Andric break; 5768bcb0991SDimitry Andric } 5778bcb0991SDimitry Andric default: 5788bcb0991SDimitry Andric llvm_unreachable("not yet implemented"); 5798bcb0991SDimitry Andric } 5808bcb0991SDimitry Andric 5818bcb0991SDimitry Andric encodeULEB128(SectionIndex, OS); 5828bcb0991SDimitry Andric encodeULEB128(Sec.Relocations.size(), OS); 5838bcb0991SDimitry Andric 5848bcb0991SDimitry Andric for (auto Reloc : Sec.Relocations) { 5858bcb0991SDimitry Andric writeUint8(OS, Reloc.Type); 5868bcb0991SDimitry Andric encodeULEB128(Reloc.Offset, OS); 5878bcb0991SDimitry Andric encodeULEB128(Reloc.Index, OS); 5888bcb0991SDimitry Andric switch (Reloc.Type) { 5898bcb0991SDimitry Andric case wasm::R_WASM_MEMORY_ADDR_LEB: 5905ffd83dbSDimitry Andric case wasm::R_WASM_MEMORY_ADDR_LEB64: 5918bcb0991SDimitry Andric case wasm::R_WASM_MEMORY_ADDR_SLEB: 5925ffd83dbSDimitry Andric case wasm::R_WASM_MEMORY_ADDR_SLEB64: 5938bcb0991SDimitry Andric case wasm::R_WASM_MEMORY_ADDR_I32: 5945ffd83dbSDimitry Andric case wasm::R_WASM_MEMORY_ADDR_I64: 5958bcb0991SDimitry Andric case wasm::R_WASM_FUNCTION_OFFSET_I32: 596e8d8bef9SDimitry Andric case wasm::R_WASM_FUNCTION_OFFSET_I64: 5978bcb0991SDimitry Andric case wasm::R_WASM_SECTION_OFFSET_I32: 598fe6060f1SDimitry Andric encodeSLEB128(Reloc.Addend, OS); 599fe6060f1SDimitry Andric break; 6008bcb0991SDimitry Andric } 6018bcb0991SDimitry Andric } 6028bcb0991SDimitry Andric } 6038bcb0991SDimitry Andric 6048bcb0991SDimitry Andric bool WasmWriter::writeWasm(raw_ostream &OS) { 6058bcb0991SDimitry Andric // Write headers 6068bcb0991SDimitry Andric OS.write(wasm::WasmMagic, sizeof(wasm::WasmMagic)); 6078bcb0991SDimitry Andric writeUint32(OS, Obj.Header.Version); 6088bcb0991SDimitry Andric 6098bcb0991SDimitry Andric // Write each section 6108bcb0991SDimitry Andric llvm::object::WasmSectionOrderChecker Checker; 6118bcb0991SDimitry Andric for (const std::unique_ptr<WasmYAML::Section> &Sec : Obj.Sections) { 6128bcb0991SDimitry Andric StringRef SecName = ""; 6138bcb0991SDimitry Andric if (auto S = dyn_cast<WasmYAML::CustomSection>(Sec.get())) 6148bcb0991SDimitry Andric SecName = S->Name; 6158bcb0991SDimitry Andric if (!Checker.isValidSectionOrder(Sec->Type, SecName)) { 6168bcb0991SDimitry Andric reportError("out of order section type: " + Twine(Sec->Type)); 6178bcb0991SDimitry Andric return false; 6188bcb0991SDimitry Andric } 6198bcb0991SDimitry Andric encodeULEB128(Sec->Type, OS); 6208bcb0991SDimitry Andric std::string OutString; 6218bcb0991SDimitry Andric raw_string_ostream StringStream(OutString); 6228bcb0991SDimitry Andric if (auto S = dyn_cast<WasmYAML::CustomSection>(Sec.get())) 6238bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6248bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::TypeSection>(Sec.get())) 6258bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6268bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::ImportSection>(Sec.get())) 6278bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6288bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::FunctionSection>(Sec.get())) 6298bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6308bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::TableSection>(Sec.get())) 6318bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6328bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::MemorySection>(Sec.get())) 6338bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 634fe6060f1SDimitry Andric else if (auto S = dyn_cast<WasmYAML::TagSection>(Sec.get())) 6358bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6365ffd83dbSDimitry Andric else if (auto S = dyn_cast<WasmYAML::GlobalSection>(Sec.get())) 6375ffd83dbSDimitry Andric writeSectionContent(StringStream, *S); 6388bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::ExportSection>(Sec.get())) 6398bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6408bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::StartSection>(Sec.get())) 6418bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6428bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::ElemSection>(Sec.get())) 6438bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6448bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::CodeSection>(Sec.get())) 6458bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6468bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::DataSection>(Sec.get())) 6478bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6488bcb0991SDimitry Andric else if (auto S = dyn_cast<WasmYAML::DataCountSection>(Sec.get())) 6498bcb0991SDimitry Andric writeSectionContent(StringStream, *S); 6508bcb0991SDimitry Andric else 6518bcb0991SDimitry Andric reportError("unknown section type: " + Twine(Sec->Type)); 6528bcb0991SDimitry Andric 6538bcb0991SDimitry Andric if (HasError) 6548bcb0991SDimitry Andric return false; 6558bcb0991SDimitry Andric 6568bcb0991SDimitry Andric StringStream.flush(); 6578bcb0991SDimitry Andric 6588bcb0991SDimitry Andric // Write the section size followed by the content 6598bcb0991SDimitry Andric encodeULEB128(OutString.size(), OS); 6608bcb0991SDimitry Andric OS << OutString; 6618bcb0991SDimitry Andric } 6628bcb0991SDimitry Andric 6638bcb0991SDimitry Andric // write reloc sections for any section that have relocations 6648bcb0991SDimitry Andric uint32_t SectionIndex = 0; 6658bcb0991SDimitry Andric for (const std::unique_ptr<WasmYAML::Section> &Sec : Obj.Sections) { 6668bcb0991SDimitry Andric if (Sec->Relocations.empty()) { 6678bcb0991SDimitry Andric SectionIndex++; 6688bcb0991SDimitry Andric continue; 6698bcb0991SDimitry Andric } 6708bcb0991SDimitry Andric 6718bcb0991SDimitry Andric writeUint8(OS, wasm::WASM_SEC_CUSTOM); 6728bcb0991SDimitry Andric std::string OutString; 6738bcb0991SDimitry Andric raw_string_ostream StringStream(OutString); 6748bcb0991SDimitry Andric writeRelocSection(StringStream, *Sec, SectionIndex++); 6758bcb0991SDimitry Andric StringStream.flush(); 6768bcb0991SDimitry Andric 6778bcb0991SDimitry Andric encodeULEB128(OutString.size(), OS); 6788bcb0991SDimitry Andric OS << OutString; 6798bcb0991SDimitry Andric } 6808bcb0991SDimitry Andric 6818bcb0991SDimitry Andric return true; 6828bcb0991SDimitry Andric } 6838bcb0991SDimitry Andric 6848bcb0991SDimitry Andric namespace llvm { 6858bcb0991SDimitry Andric namespace yaml { 6868bcb0991SDimitry Andric 6878bcb0991SDimitry Andric bool yaml2wasm(WasmYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH) { 6888bcb0991SDimitry Andric WasmWriter Writer(Doc, EH); 6898bcb0991SDimitry Andric return Writer.writeWasm(Out); 6908bcb0991SDimitry Andric } 6918bcb0991SDimitry Andric 6928bcb0991SDimitry Andric } // namespace yaml 6938bcb0991SDimitry Andric } // namespace llvm 694