blob: 5c3b2b996baea9600792e7be5ab4afbc62ea8840 [file] [log] [blame]
Derek Schuffd3d84fd2017-03-30 19:44:09 +00001//===- yaml2wasm - Convert YAML to a Wasm object file --------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief The Wasm component of yaml2obj.
12///
13//===----------------------------------------------------------------------===//
14//
Derek Schuffd3d84fd2017-03-30 19:44:09 +000015#include "llvm/ObjectYAML/ObjectYAML.h"
16#include "llvm/Support/Endian.h"
17#include "llvm/Support/LEB128.h"
18
19using namespace llvm;
20
21/// This parses a yaml stream that represents a Wasm object file.
22/// See docs/yaml2obj for the yaml scheema.
23class WasmWriter {
24public:
25 WasmWriter(WasmYAML::Object &Obj) : Obj(Obj) {}
26 int writeWasm(raw_ostream &OS);
Sam Cleggb7787fd2017-06-20 04:04:59 +000027
28private:
Derek Schuffd3d84fd2017-03-30 19:44:09 +000029 int writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec);
Sam Clegg03cdd122017-05-05 18:12:34 +000030
Derek Schuffd3d84fd2017-03-30 19:44:09 +000031 int writeSectionContent(raw_ostream &OS, WasmYAML::CustomSection &Section);
32 int writeSectionContent(raw_ostream &OS, WasmYAML::TypeSection &Section);
33 int writeSectionContent(raw_ostream &OS, WasmYAML::ImportSection &Section);
34 int writeSectionContent(raw_ostream &OS, WasmYAML::FunctionSection &Section);
35 int writeSectionContent(raw_ostream &OS, WasmYAML::TableSection &Section);
36 int writeSectionContent(raw_ostream &OS, WasmYAML::MemorySection &Section);
37 int writeSectionContent(raw_ostream &OS, WasmYAML::GlobalSection &Section);
38 int writeSectionContent(raw_ostream &OS, WasmYAML::ExportSection &Section);
39 int writeSectionContent(raw_ostream &OS, WasmYAML::StartSection &Section);
40 int writeSectionContent(raw_ostream &OS, WasmYAML::ElemSection &Section);
41 int writeSectionContent(raw_ostream &OS, WasmYAML::CodeSection &Section);
42 int writeSectionContent(raw_ostream &OS, WasmYAML::DataSection &Section);
43
Sam Cleggb7787fd2017-06-20 04:04:59 +000044 // Custom section types
45 int writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section);
46 int writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section);
Derek Schuffd3d84fd2017-03-30 19:44:09 +000047 WasmYAML::Object &Obj;
Sam Clegge53af7f2018-01-09 21:38:53 +000048 uint32_t NumImportedFunctions = 0;
49 uint32_t NumImportedGlobals = 0;
Derek Schuffd3d84fd2017-03-30 19:44:09 +000050};
51
52static int writeUint64(raw_ostream &OS, uint64_t Value) {
53 char Data[sizeof(Value)];
54 support::endian::write64le(Data, Value);
55 OS.write(Data, sizeof(Data));
56 return 0;
57}
58
59static int writeUint32(raw_ostream &OS, uint32_t Value) {
60 char Data[sizeof(Value)];
61 support::endian::write32le(Data, Value);
62 OS.write(Data, sizeof(Data));
63 return 0;
64}
65
66static int writeUint8(raw_ostream &OS, uint8_t Value) {
67 char Data[sizeof(Value)];
68 memcpy(Data, &Value, sizeof(Data));
69 OS.write(Data, sizeof(Data));
70 return 0;
71}
72
Sam Clegg03cdd122017-05-05 18:12:34 +000073static int writeStringRef(const StringRef &Str, raw_ostream &OS) {
Derek Schuffd3d84fd2017-03-30 19:44:09 +000074 encodeULEB128(Str.size(), OS);
75 OS << Str;
76 return 0;
77}
78
Sam Clegg03cdd122017-05-05 18:12:34 +000079static int writeLimits(const WasmYAML::Limits &Lim, raw_ostream &OS) {
Derek Schuffd3d84fd2017-03-30 19:44:09 +000080 encodeULEB128(Lim.Flags, OS);
81 encodeULEB128(Lim.Initial, OS);
82 if (Lim.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
83 encodeULEB128(Lim.Maximum, OS);
84 return 0;
85}
86
Sam Clegg03cdd122017-05-05 18:12:34 +000087static int writeInitExpr(const wasm::WasmInitExpr &InitExpr, raw_ostream &OS) {
Derek Schuffd3d84fd2017-03-30 19:44:09 +000088 writeUint8(OS, InitExpr.Opcode);
89 switch (InitExpr.Opcode) {
90 case wasm::WASM_OPCODE_I32_CONST:
91 encodeSLEB128(InitExpr.Value.Int32, OS);
92 break;
93 case wasm::WASM_OPCODE_I64_CONST:
94 encodeSLEB128(InitExpr.Value.Int64, OS);
95 break;
96 case wasm::WASM_OPCODE_F32_CONST:
97 writeUint32(OS, InitExpr.Value.Float32);
98 break;
99 case wasm::WASM_OPCODE_F64_CONST:
100 writeUint64(OS, InitExpr.Value.Float64);
101 break;
102 case wasm::WASM_OPCODE_GET_GLOBAL:
103 encodeULEB128(InitExpr.Value.Global, OS);
104 break;
105 default:
Sam Clegge53af7f2018-01-09 21:38:53 +0000106 errs() << "Unknown opcode in init_expr: " << InitExpr.Opcode << "\n";
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000107 return 1;
108 }
109 writeUint8(OS, wasm::WASM_OPCODE_END);
110 return 0;
111}
112
Sam Clegg9e1ade92017-06-27 20:27:59 +0000113class SubSectionWriter {
114 raw_ostream &OS;
115 std::string OutString;
116 raw_string_ostream StringStream;
Sam Cleggb7787fd2017-06-20 04:04:59 +0000117
Sam Clegg9e1ade92017-06-27 20:27:59 +0000118public:
119 SubSectionWriter(raw_ostream &OS) : OS(OS), StringStream(OutString) {}
Sam Cleggb7787fd2017-06-20 04:04:59 +0000120
Sam Clegg9e1ade92017-06-27 20:27:59 +0000121 void Done() {
Sam Cleggb7787fd2017-06-20 04:04:59 +0000122 StringStream.flush();
123 encodeULEB128(OutString.size(), OS);
124 OS << OutString;
Sam Clegg9e1ade92017-06-27 20:27:59 +0000125 OutString.clear();
126 }
127
128 raw_ostream& GetStream() {
129 return StringStream;
130 }
131};
132
133int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section) {
134 writeStringRef(Section.Name, OS);
135
136 SubSectionWriter SubSection(OS);
137
138 // DATA_SIZE subsection
139 encodeULEB128(wasm::WASM_DATA_SIZE, OS);
140 encodeULEB128(Section.DataSize, SubSection.GetStream());
141 SubSection.Done();
142
Sam Clegg9e1ade92017-06-27 20:27:59 +0000143 // SYMBOL_INFO subsection
144 if (Section.SymbolInfos.size()) {
145 encodeULEB128(wasm::WASM_SYMBOL_INFO, OS);
146
147 encodeULEB128(Section.SymbolInfos.size(), SubSection.GetStream());
148 for (const WasmYAML::SymbolInfo &Info : Section.SymbolInfos) {
149 writeStringRef(Info.Name, SubSection.GetStream());
150 encodeULEB128(Info.Flags, SubSection.GetStream());
151 }
152
153 SubSection.Done();
Sam Cleggb7787fd2017-06-20 04:04:59 +0000154 }
Sam Cleggd95ed952017-09-20 19:03:35 +0000155
156 // SEGMENT_NAMES subsection
Sam Clegg63ebb812017-09-29 16:50:08 +0000157 if (Section.SegmentInfos.size()) {
158 encodeULEB128(wasm::WASM_SEGMENT_INFO, OS);
159 encodeULEB128(Section.SegmentInfos.size(), SubSection.GetStream());
160 for (const WasmYAML::SegmentInfo &SegmentInfo : Section.SegmentInfos) {
Sam Clegg63ebb812017-09-29 16:50:08 +0000161 writeStringRef(SegmentInfo.Name, SubSection.GetStream());
162 encodeULEB128(SegmentInfo.Alignment, SubSection.GetStream());
163 encodeULEB128(SegmentInfo.Flags, SubSection.GetStream());
Sam Cleggd95ed952017-09-20 19:03:35 +0000164 }
165 SubSection.Done();
166 }
Sam Clegg42739982017-12-14 21:10:03 +0000167
168 // INIT_FUNCS subsection
169 if (Section.InitFunctions.size()) {
170 encodeULEB128(wasm::WASM_INIT_FUNCS, OS);
171 encodeULEB128(Section.InitFunctions.size(), SubSection.GetStream());
172 for (const WasmYAML::InitFunction &Func : Section.InitFunctions) {
173 encodeULEB128(Func.Priority, SubSection.GetStream());
174 encodeULEB128(Func.FunctionIndex, SubSection.GetStream());
175 }
176 SubSection.Done();
177 }
Sam Cleggea7cace2018-01-09 23:43:14 +0000178
179 // COMDAT_INFO subsection
180 if (Section.Comdats.size()) {
181 encodeULEB128(wasm::WASM_COMDAT_INFO, OS);
182 encodeULEB128(Section.Comdats.size(), SubSection.GetStream());
183 for (const auto &C : Section.Comdats) {
184 writeStringRef(C.Name, SubSection.GetStream());
185 encodeULEB128(0, SubSection.GetStream()); // flags for future use
186 encodeULEB128(C.Entries.size(), SubSection.GetStream());
187 for (const WasmYAML::ComdatEntry &Entry : C.Entries) {
188 encodeULEB128(Entry.Kind, SubSection.GetStream());
189 encodeULEB128(Entry.Index, SubSection.GetStream());
190 }
191 }
192 SubSection.Done();
193 }
194
Sam Cleggb7787fd2017-06-20 04:04:59 +0000195 return 0;
196}
197
198int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section) {
Sam Clegg03cdd122017-05-05 18:12:34 +0000199 writeStringRef(Section.Name, OS);
200 if (Section.FunctionNames.size()) {
201 encodeULEB128(wasm::WASM_NAMES_FUNCTION, OS);
Sam Clegg03cdd122017-05-05 18:12:34 +0000202
Sam Clegg9e1ade92017-06-27 20:27:59 +0000203 SubSectionWriter SubSection(OS);
204
205 encodeULEB128(Section.FunctionNames.size(), SubSection.GetStream());
Sam Clegg03cdd122017-05-05 18:12:34 +0000206 for (const WasmYAML::NameEntry &NameEntry : Section.FunctionNames) {
Sam Clegg9e1ade92017-06-27 20:27:59 +0000207 encodeULEB128(NameEntry.Index, SubSection.GetStream());
208 writeStringRef(NameEntry.Name, SubSection.GetStream());
Sam Clegg03cdd122017-05-05 18:12:34 +0000209 }
210
Sam Clegg9e1ade92017-06-27 20:27:59 +0000211 SubSection.Done();
Sam Clegg03cdd122017-05-05 18:12:34 +0000212 }
213 return 0;
214}
215
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000216int WasmWriter::writeSectionContent(raw_ostream &OS,
217 WasmYAML::CustomSection &Section) {
Sam Cleggb7787fd2017-06-20 04:04:59 +0000218 if (auto S = dyn_cast<WasmYAML::NameSection>(&Section)) {
219 if (auto Err = writeSectionContent(OS, *S))
220 return Err;
221 } else if (auto S = dyn_cast<WasmYAML::LinkingSection>(&Section)) {
222 if (auto Err = writeSectionContent(OS, *S))
223 return Err;
Sam Clegg03cdd122017-05-05 18:12:34 +0000224 } else {
225 Section.Payload.writeAsBinary(OS);
226 }
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000227 return 0;
228}
229
230int WasmWriter::writeSectionContent(raw_ostream &OS,
231 WasmYAML::TypeSection &Section) {
232 encodeULEB128(Section.Signatures.size(), OS);
Sam Clegge53af7f2018-01-09 21:38:53 +0000233 uint32_t ExpectedIndex = 0;
Sam Clegg03cdd122017-05-05 18:12:34 +0000234 for (const WasmYAML::Signature &Sig : Section.Signatures) {
Sam Clegge53af7f2018-01-09 21:38:53 +0000235 if (Sig.Index != ExpectedIndex) {
236 errs() << "Unexpected type index: " << Sig.Index << "\n";
237 return 1;
238 }
239 ++ExpectedIndex;
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000240 encodeSLEB128(Sig.Form, OS);
241 encodeULEB128(Sig.ParamTypes.size(), OS);
242 for (auto ParamType : Sig.ParamTypes)
243 encodeSLEB128(ParamType, OS);
244 if (Sig.ReturnType == wasm::WASM_TYPE_NORESULT) {
245 encodeSLEB128(0, OS);
246 } else {
247 encodeULEB128(1, OS);
248 encodeSLEB128(Sig.ReturnType, OS);
249 }
250 }
251 return 0;
252}
253
254int WasmWriter::writeSectionContent(raw_ostream &OS,
255 WasmYAML::ImportSection &Section) {
256 encodeULEB128(Section.Imports.size(), OS);
Sam Clegg03cdd122017-05-05 18:12:34 +0000257 for (const WasmYAML::Import &Import : Section.Imports) {
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000258 writeStringRef(Import.Module, OS);
259 writeStringRef(Import.Field, OS);
260 encodeULEB128(Import.Kind, OS);
261 switch (Import.Kind) {
262 case wasm::WASM_EXTERNAL_FUNCTION:
263 encodeULEB128(Import.SigIndex, OS);
Sam Clegge53af7f2018-01-09 21:38:53 +0000264 NumImportedFunctions++;
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000265 break;
266 case wasm::WASM_EXTERNAL_GLOBAL:
Sam Clegg41db5192017-05-10 00:14:04 +0000267 encodeSLEB128(Import.GlobalImport.Type, OS);
268 writeUint8(OS, Import.GlobalImport.Mutable);
Sam Clegge53af7f2018-01-09 21:38:53 +0000269 NumImportedGlobals++;
Sam Clegg2ffff5a2017-05-09 23:48:41 +0000270 break;
271 case wasm::WASM_EXTERNAL_MEMORY:
272 writeLimits(Import.Memory, OS);
273 break;
274 case wasm::WASM_EXTERNAL_TABLE:
Sam Clegg41db5192017-05-10 00:14:04 +0000275 encodeSLEB128(Import.TableImport.ElemType, OS);
276 writeLimits(Import.TableImport.TableLimits, OS);
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000277 break;
278 default:
Sam Clegge53af7f2018-01-09 21:38:53 +0000279 errs() << "Unknown import type: " << Import.Kind << "\n";
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000280 return 1;
281 }
282 }
283 return 0;
284}
285
286int WasmWriter::writeSectionContent(raw_ostream &OS,
287 WasmYAML::FunctionSection &Section) {
288 encodeULEB128(Section.FunctionTypes.size(), OS);
289 for (uint32_t FuncType : Section.FunctionTypes) {
290 encodeULEB128(FuncType, OS);
291 }
292 return 0;
293}
294
295int WasmWriter::writeSectionContent(raw_ostream &OS,
296 WasmYAML::ExportSection &Section) {
297 encodeULEB128(Section.Exports.size(), OS);
Sam Clegg03cdd122017-05-05 18:12:34 +0000298 for (const WasmYAML::Export &Export : Section.Exports) {
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000299 writeStringRef(Export.Name, OS);
300 encodeULEB128(Export.Kind, OS);
301 encodeULEB128(Export.Index, OS);
302 }
303 return 0;
304}
305
306int WasmWriter::writeSectionContent(raw_ostream &OS,
307 WasmYAML::StartSection &Section) {
308 encodeULEB128(Section.StartFunction, OS);
309 return 0;
310}
311
312int WasmWriter::writeSectionContent(raw_ostream &OS,
313 WasmYAML::TableSection &Section) {
314 encodeULEB128(Section.Tables.size(), OS);
315 for (auto &Table : Section.Tables) {
316 encodeSLEB128(Table.ElemType, OS);
317 writeLimits(Table.TableLimits, OS);
318 }
319 return 0;
320}
321
322int WasmWriter::writeSectionContent(raw_ostream &OS,
323 WasmYAML::MemorySection &Section) {
324 encodeULEB128(Section.Memories.size(), OS);
Sam Clegg03cdd122017-05-05 18:12:34 +0000325 for (const WasmYAML::Limits &Mem : Section.Memories) {
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000326 writeLimits(Mem, OS);
327 }
328 return 0;
329}
330
331int WasmWriter::writeSectionContent(raw_ostream &OS,
332 WasmYAML::GlobalSection &Section) {
333 encodeULEB128(Section.Globals.size(), OS);
Sam Clegge53af7f2018-01-09 21:38:53 +0000334 uint32_t ExpectedIndex = NumImportedGlobals;
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000335 for (auto &Global : Section.Globals) {
Sam Clegge53af7f2018-01-09 21:38:53 +0000336 if (Global.Index != ExpectedIndex) {
337 errs() << "Unexpected global index: " << Global.Index << "\n";
338 return 1;
339 }
340 ++ExpectedIndex;
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000341 encodeSLEB128(Global.Type, OS);
342 writeUint8(OS, Global.Mutable);
343 writeInitExpr(Global.InitExpr, OS);
344 }
345 return 0;
346}
347
348int WasmWriter::writeSectionContent(raw_ostream &OS,
349 WasmYAML::ElemSection &Section) {
350 encodeULEB128(Section.Segments.size(), OS);
351 for (auto &Segment : Section.Segments) {
352 encodeULEB128(Segment.TableIndex, OS);
353 writeInitExpr(Segment.Offset, OS);
354
355 encodeULEB128(Segment.Functions.size(), OS);
356 for (auto &Function : Segment.Functions) {
357 encodeULEB128(Function, OS);
358 }
359 }
360 return 0;
361}
362
363int WasmWriter::writeSectionContent(raw_ostream &OS,
364 WasmYAML::CodeSection &Section) {
365 encodeULEB128(Section.Functions.size(), OS);
Sam Clegge53af7f2018-01-09 21:38:53 +0000366 uint32_t ExpectedIndex = NumImportedFunctions;
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000367 for (auto &Func : Section.Functions) {
368 std::string OutString;
369 raw_string_ostream StringStream(OutString);
Sam Clegge53af7f2018-01-09 21:38:53 +0000370 if (Func.Index != ExpectedIndex) {
371 errs() << "Unexpected function index: " << Func.Index << "\n";
372 return 1;
373 }
374 ++ExpectedIndex;
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000375
376 encodeULEB128(Func.Locals.size(), StringStream);
377 for (auto &LocalDecl : Func.Locals) {
378 encodeULEB128(LocalDecl.Count, StringStream);
379 encodeSLEB128(LocalDecl.Type, StringStream);
380 }
381
382 Func.Body.writeAsBinary(StringStream);
383
384 // Write the section size followed by the content
385 StringStream.flush();
386 encodeULEB128(OutString.size(), OS);
387 OS << OutString;
388 }
389 return 0;
390}
391
392int WasmWriter::writeSectionContent(raw_ostream &OS,
393 WasmYAML::DataSection &Section) {
394 encodeULEB128(Section.Segments.size(), OS);
395 for (auto &Segment : Section.Segments) {
Sam Clegg9c07f942017-07-12 00:24:54 +0000396 encodeULEB128(Segment.MemoryIndex, OS);
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000397 writeInitExpr(Segment.Offset, OS);
398 encodeULEB128(Segment.Content.binary_size(), OS);
399 Segment.Content.writeAsBinary(OS);
400 }
401 return 0;
402}
403
404int WasmWriter::writeRelocSection(raw_ostream &OS,
405 WasmYAML::Section &Sec) {
406 StringRef Name;
407 switch (Sec.Type) {
408 case wasm::WASM_SEC_CODE:
409 Name = "reloc.CODE";
410 break;
411 case wasm::WASM_SEC_DATA:
412 Name = "reloc.DATA";
413 break;
414 default:
415 llvm_unreachable("not yet implemented");
416 return 1;
417 }
418
419 writeStringRef(Name, OS);
420 encodeULEB128(Sec.Type, OS);
421 encodeULEB128(Sec.Relocations.size(), OS);
422
423 for (auto Reloc: Sec.Relocations) {
424 encodeULEB128(Reloc.Type, OS);
425 encodeULEB128(Reloc.Offset, OS);
426 encodeULEB128(Reloc.Index, OS);
427 switch (Reloc.Type) {
Sam Clegg13a2e892017-09-01 17:32:01 +0000428 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
429 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
430 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000431 encodeULEB128(Reloc.Addend, OS);
432 }
433 }
434 return 0;
435}
436
437
438int WasmWriter::writeWasm(raw_ostream &OS) {
439 // Write headers
440 OS.write(wasm::WasmMagic, sizeof(wasm::WasmMagic));
441 writeUint32(OS, Obj.Header.Version);
442
443 // Write each section
Sam Clegge53af7f2018-01-09 21:38:53 +0000444 uint32_t LastType = 0;
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000445 for (const std::unique_ptr<WasmYAML::Section> &Sec : Obj.Sections) {
Sam Clegge53af7f2018-01-09 21:38:53 +0000446 uint32_t Type = Sec->Type;
447 if (Type != wasm::WASM_SEC_CUSTOM) {
448 if (Type < LastType) {
449 errs() << "Out of order section type: " << Type << "\n";
450 return 1;
451 }
452 LastType = Type;
453 }
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000454
Sam Clegge53af7f2018-01-09 21:38:53 +0000455 encodeULEB128(Sec->Type, OS);
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000456 std::string OutString;
457 raw_string_ostream StringStream(OutString);
458 if (auto S = dyn_cast<WasmYAML::CustomSection>(Sec.get())) {
459 if (auto Err = writeSectionContent(StringStream, *S))
460 return Err;
461 } else if (auto S = dyn_cast<WasmYAML::TypeSection>(Sec.get())) {
462 if (auto Err = writeSectionContent(StringStream, *S))
463 return Err;
464 } else if (auto S = dyn_cast<WasmYAML::ImportSection>(Sec.get())) {
465 if (auto Err = writeSectionContent(StringStream, *S))
466 return Err;
467 } else if (auto S = dyn_cast<WasmYAML::FunctionSection>(Sec.get())) {
468 if (auto Err = writeSectionContent(StringStream, *S))
469 return Err;
470 } else if (auto S = dyn_cast<WasmYAML::TableSection>(Sec.get())) {
471 if (auto Err = writeSectionContent(StringStream, *S))
472 return Err;
473 } else if (auto S = dyn_cast<WasmYAML::MemorySection>(Sec.get())) {
474 if (auto Err = writeSectionContent(StringStream, *S))
475 return Err;
476 } else if (auto S = dyn_cast<WasmYAML::GlobalSection>(Sec.get())) {
477 if (auto Err = writeSectionContent(StringStream, *S))
478 return Err;
479 } else if (auto S = dyn_cast<WasmYAML::ExportSection>(Sec.get())) {
480 if (auto Err = writeSectionContent(StringStream, *S))
481 return Err;
482 } else if (auto S = dyn_cast<WasmYAML::StartSection>(Sec.get())) {
483 if (auto Err = writeSectionContent(StringStream, *S))
484 return Err;
485 } else if (auto S = dyn_cast<WasmYAML::ElemSection>(Sec.get())) {
486 if (auto Err = writeSectionContent(StringStream, *S))
487 return Err;
488 } else if (auto S = dyn_cast<WasmYAML::CodeSection>(Sec.get())) {
489 if (auto Err = writeSectionContent(StringStream, *S))
490 return Err;
491 } else if (auto S = dyn_cast<WasmYAML::DataSection>(Sec.get())) {
492 if (auto Err = writeSectionContent(StringStream, *S))
493 return Err;
494 } else {
495 errs() << "Unknown section type: " << Sec->Type << "\n";
496 return 1;
497 }
498 StringStream.flush();
499
500 // Write the section size followed by the content
501 encodeULEB128(OutString.size(), OS);
502 OS << OutString;
503 }
504
505 // write reloc sections for any section that have relocations
506 for (const std::unique_ptr<WasmYAML::Section> &Sec : Obj.Sections) {
507 if (Sec->Relocations.empty())
508 continue;
509
510 encodeULEB128(wasm::WASM_SEC_CUSTOM, OS);
511 std::string OutString;
512 raw_string_ostream StringStream(OutString);
513 writeRelocSection(StringStream, *Sec);
514 StringStream.flush();
515
516 encodeULEB128(OutString.size(), OS);
517 OS << OutString;
518 }
519
520 return 0;
521}
522
523int yaml2wasm(llvm::WasmYAML::Object &Doc, raw_ostream &Out) {
524 WasmWriter Writer(Doc);
525
526 return Writer.writeWasm(Out);
527}