blob: abd1d427b76218a138d66ccadfb39a85e42117b4 [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//
Sam Clegg6c899ba2018-02-23 05:08:34 +000015
Derek Schuffd3d84fd2017-03-30 19:44:09 +000016#include "llvm/ObjectYAML/ObjectYAML.h"
17#include "llvm/Support/Endian.h"
18#include "llvm/Support/LEB128.h"
19
20using namespace llvm;
21
22/// This parses a yaml stream that represents a Wasm object file.
23/// See docs/yaml2obj for the yaml scheema.
24class WasmWriter {
25public:
26 WasmWriter(WasmYAML::Object &Obj) : Obj(Obj) {}
27 int writeWasm(raw_ostream &OS);
Sam Cleggb7787fd2017-06-20 04:04:59 +000028
29private:
Derek Schuffd3d84fd2017-03-30 19:44:09 +000030 int writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec);
Sam Clegg03cdd122017-05-05 18:12:34 +000031
Derek Schuffd3d84fd2017-03-30 19:44:09 +000032 int writeSectionContent(raw_ostream &OS, WasmYAML::CustomSection &Section);
33 int writeSectionContent(raw_ostream &OS, WasmYAML::TypeSection &Section);
34 int writeSectionContent(raw_ostream &OS, WasmYAML::ImportSection &Section);
35 int writeSectionContent(raw_ostream &OS, WasmYAML::FunctionSection &Section);
36 int writeSectionContent(raw_ostream &OS, WasmYAML::TableSection &Section);
37 int writeSectionContent(raw_ostream &OS, WasmYAML::MemorySection &Section);
38 int writeSectionContent(raw_ostream &OS, WasmYAML::GlobalSection &Section);
39 int writeSectionContent(raw_ostream &OS, WasmYAML::ExportSection &Section);
40 int writeSectionContent(raw_ostream &OS, WasmYAML::StartSection &Section);
41 int writeSectionContent(raw_ostream &OS, WasmYAML::ElemSection &Section);
42 int writeSectionContent(raw_ostream &OS, WasmYAML::CodeSection &Section);
43 int writeSectionContent(raw_ostream &OS, WasmYAML::DataSection &Section);
44
Sam Cleggb7787fd2017-06-20 04:04:59 +000045 // Custom section types
46 int writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section);
47 int writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section);
Derek Schuffd3d84fd2017-03-30 19:44:09 +000048 WasmYAML::Object &Obj;
Sam Clegge53af7f2018-01-09 21:38:53 +000049 uint32_t NumImportedFunctions = 0;
50 uint32_t NumImportedGlobals = 0;
Derek Schuffd3d84fd2017-03-30 19:44:09 +000051};
52
53static int writeUint64(raw_ostream &OS, uint64_t Value) {
54 char Data[sizeof(Value)];
55 support::endian::write64le(Data, Value);
56 OS.write(Data, sizeof(Data));
57 return 0;
58}
59
60static int writeUint32(raw_ostream &OS, uint32_t Value) {
61 char Data[sizeof(Value)];
62 support::endian::write32le(Data, Value);
63 OS.write(Data, sizeof(Data));
64 return 0;
65}
66
67static int writeUint8(raw_ostream &OS, uint8_t Value) {
68 char Data[sizeof(Value)];
69 memcpy(Data, &Value, sizeof(Data));
70 OS.write(Data, sizeof(Data));
71 return 0;
72}
73
Sam Clegg03cdd122017-05-05 18:12:34 +000074static int writeStringRef(const StringRef &Str, raw_ostream &OS) {
Derek Schuffd3d84fd2017-03-30 19:44:09 +000075 encodeULEB128(Str.size(), OS);
76 OS << Str;
77 return 0;
78}
79
Sam Clegg03cdd122017-05-05 18:12:34 +000080static int writeLimits(const WasmYAML::Limits &Lim, raw_ostream &OS) {
Derek Schuffd3d84fd2017-03-30 19:44:09 +000081 encodeULEB128(Lim.Flags, OS);
82 encodeULEB128(Lim.Initial, OS);
83 if (Lim.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
84 encodeULEB128(Lim.Maximum, OS);
85 return 0;
86}
87
Sam Clegg03cdd122017-05-05 18:12:34 +000088static int writeInitExpr(const wasm::WasmInitExpr &InitExpr, raw_ostream &OS) {
Derek Schuffd3d84fd2017-03-30 19:44:09 +000089 writeUint8(OS, InitExpr.Opcode);
90 switch (InitExpr.Opcode) {
91 case wasm::WASM_OPCODE_I32_CONST:
92 encodeSLEB128(InitExpr.Value.Int32, OS);
93 break;
94 case wasm::WASM_OPCODE_I64_CONST:
95 encodeSLEB128(InitExpr.Value.Int64, OS);
96 break;
97 case wasm::WASM_OPCODE_F32_CONST:
98 writeUint32(OS, InitExpr.Value.Float32);
99 break;
100 case wasm::WASM_OPCODE_F64_CONST:
101 writeUint64(OS, InitExpr.Value.Float64);
102 break;
103 case wasm::WASM_OPCODE_GET_GLOBAL:
104 encodeULEB128(InitExpr.Value.Global, OS);
105 break;
106 default:
Sam Clegge53af7f2018-01-09 21:38:53 +0000107 errs() << "Unknown opcode in init_expr: " << InitExpr.Opcode << "\n";
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000108 return 1;
109 }
110 writeUint8(OS, wasm::WASM_OPCODE_END);
111 return 0;
112}
113
Sam Clegg9e1ade92017-06-27 20:27:59 +0000114class SubSectionWriter {
115 raw_ostream &OS;
116 std::string OutString;
117 raw_string_ostream StringStream;
Sam Cleggb7787fd2017-06-20 04:04:59 +0000118
Sam Clegg9e1ade92017-06-27 20:27:59 +0000119public:
120 SubSectionWriter(raw_ostream &OS) : OS(OS), StringStream(OutString) {}
Sam Cleggb7787fd2017-06-20 04:04:59 +0000121
Sam Clegg9e1ade92017-06-27 20:27:59 +0000122 void Done() {
Sam Cleggb7787fd2017-06-20 04:04:59 +0000123 StringStream.flush();
124 encodeULEB128(OutString.size(), OS);
125 OS << OutString;
Sam Clegg9e1ade92017-06-27 20:27:59 +0000126 OutString.clear();
127 }
128
129 raw_ostream& GetStream() {
130 return StringStream;
131 }
132};
133
134int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section) {
135 writeStringRef(Section.Name, OS);
136
137 SubSectionWriter SubSection(OS);
138
139 // DATA_SIZE subsection
140 encodeULEB128(wasm::WASM_DATA_SIZE, OS);
141 encodeULEB128(Section.DataSize, SubSection.GetStream());
142 SubSection.Done();
143
Sam Clegg6c899ba2018-02-23 05:08:34 +0000144 // SYMBOL_TABLE subsection
145 if (Section.SymbolTable.size()) {
146 encodeULEB128(wasm::WASM_SYMBOL_TABLE, OS);
Sam Clegg9e1ade92017-06-27 20:27:59 +0000147
Sam Clegg6c899ba2018-02-23 05:08:34 +0000148 encodeULEB128(Section.SymbolTable.size(), SubSection.GetStream());
Benjamin Kramer8d71fdc2018-02-23 12:20:18 +0000149#ifndef NDEBUG
Sam Clegg6c899ba2018-02-23 05:08:34 +0000150 uint32_t SymbolIndex = 0;
151#endif
152 for (const WasmYAML::SymbolInfo &Info : Section.SymbolTable) {
153 assert(Info.Index == SymbolIndex++);
154 encodeULEB128(Info.Kind, SubSection.GetStream());
Sam Clegg9e1ade92017-06-27 20:27:59 +0000155 encodeULEB128(Info.Flags, SubSection.GetStream());
Sam Clegg6c899ba2018-02-23 05:08:34 +0000156 switch (Info.Kind) {
157 case wasm::WASM_SYMBOL_TYPE_FUNCTION:
158 case wasm::WASM_SYMBOL_TYPE_GLOBAL:
159 encodeULEB128(Info.ElementIndex, SubSection.GetStream());
160 if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0)
161 writeStringRef(Info.Name, SubSection.GetStream());
162 break;
163 case wasm::WASM_SYMBOL_TYPE_DATA:
164 writeStringRef(Info.Name, SubSection.GetStream());
165 if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
166 encodeULEB128(Info.DataRef.Segment, SubSection.GetStream());
167 encodeULEB128(Info.DataRef.Offset, SubSection.GetStream());
168 encodeULEB128(Info.DataRef.Size, SubSection.GetStream());
169 }
170 break;
171 default:
172 llvm_unreachable("unexpected kind");
173 }
Sam Clegg9e1ade92017-06-27 20:27:59 +0000174 }
175
176 SubSection.Done();
Sam Cleggb7787fd2017-06-20 04:04:59 +0000177 }
Sam Cleggd95ed952017-09-20 19:03:35 +0000178
179 // SEGMENT_NAMES subsection
Sam Clegg63ebb812017-09-29 16:50:08 +0000180 if (Section.SegmentInfos.size()) {
181 encodeULEB128(wasm::WASM_SEGMENT_INFO, OS);
182 encodeULEB128(Section.SegmentInfos.size(), SubSection.GetStream());
183 for (const WasmYAML::SegmentInfo &SegmentInfo : Section.SegmentInfos) {
Sam Clegg63ebb812017-09-29 16:50:08 +0000184 writeStringRef(SegmentInfo.Name, SubSection.GetStream());
185 encodeULEB128(SegmentInfo.Alignment, SubSection.GetStream());
186 encodeULEB128(SegmentInfo.Flags, SubSection.GetStream());
Sam Cleggd95ed952017-09-20 19:03:35 +0000187 }
188 SubSection.Done();
189 }
Sam Clegg42739982017-12-14 21:10:03 +0000190
191 // INIT_FUNCS subsection
192 if (Section.InitFunctions.size()) {
193 encodeULEB128(wasm::WASM_INIT_FUNCS, OS);
194 encodeULEB128(Section.InitFunctions.size(), SubSection.GetStream());
195 for (const WasmYAML::InitFunction &Func : Section.InitFunctions) {
196 encodeULEB128(Func.Priority, SubSection.GetStream());
Sam Clegg6c899ba2018-02-23 05:08:34 +0000197 encodeULEB128(Func.Symbol, SubSection.GetStream());
Sam Clegg42739982017-12-14 21:10:03 +0000198 }
199 SubSection.Done();
200 }
Sam Cleggea7cace2018-01-09 23:43:14 +0000201
202 // COMDAT_INFO subsection
203 if (Section.Comdats.size()) {
204 encodeULEB128(wasm::WASM_COMDAT_INFO, OS);
205 encodeULEB128(Section.Comdats.size(), SubSection.GetStream());
206 for (const auto &C : Section.Comdats) {
207 writeStringRef(C.Name, SubSection.GetStream());
208 encodeULEB128(0, SubSection.GetStream()); // flags for future use
209 encodeULEB128(C.Entries.size(), SubSection.GetStream());
210 for (const WasmYAML::ComdatEntry &Entry : C.Entries) {
211 encodeULEB128(Entry.Kind, SubSection.GetStream());
212 encodeULEB128(Entry.Index, SubSection.GetStream());
213 }
214 }
215 SubSection.Done();
216 }
217
Sam Cleggb7787fd2017-06-20 04:04:59 +0000218 return 0;
219}
220
221int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section) {
Sam Clegg03cdd122017-05-05 18:12:34 +0000222 writeStringRef(Section.Name, OS);
223 if (Section.FunctionNames.size()) {
224 encodeULEB128(wasm::WASM_NAMES_FUNCTION, OS);
Sam Clegg03cdd122017-05-05 18:12:34 +0000225
Sam Clegg9e1ade92017-06-27 20:27:59 +0000226 SubSectionWriter SubSection(OS);
227
228 encodeULEB128(Section.FunctionNames.size(), SubSection.GetStream());
Sam Clegg03cdd122017-05-05 18:12:34 +0000229 for (const WasmYAML::NameEntry &NameEntry : Section.FunctionNames) {
Sam Clegg9e1ade92017-06-27 20:27:59 +0000230 encodeULEB128(NameEntry.Index, SubSection.GetStream());
231 writeStringRef(NameEntry.Name, SubSection.GetStream());
Sam Clegg03cdd122017-05-05 18:12:34 +0000232 }
233
Sam Clegg9e1ade92017-06-27 20:27:59 +0000234 SubSection.Done();
Sam Clegg03cdd122017-05-05 18:12:34 +0000235 }
236 return 0;
237}
238
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000239int WasmWriter::writeSectionContent(raw_ostream &OS,
240 WasmYAML::CustomSection &Section) {
Sam Cleggb7787fd2017-06-20 04:04:59 +0000241 if (auto S = dyn_cast<WasmYAML::NameSection>(&Section)) {
242 if (auto Err = writeSectionContent(OS, *S))
243 return Err;
244 } else if (auto S = dyn_cast<WasmYAML::LinkingSection>(&Section)) {
245 if (auto Err = writeSectionContent(OS, *S))
246 return Err;
Sam Clegg03cdd122017-05-05 18:12:34 +0000247 } else {
248 Section.Payload.writeAsBinary(OS);
249 }
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000250 return 0;
251}
252
253int WasmWriter::writeSectionContent(raw_ostream &OS,
254 WasmYAML::TypeSection &Section) {
255 encodeULEB128(Section.Signatures.size(), OS);
Sam Clegge53af7f2018-01-09 21:38:53 +0000256 uint32_t ExpectedIndex = 0;
Sam Clegg03cdd122017-05-05 18:12:34 +0000257 for (const WasmYAML::Signature &Sig : Section.Signatures) {
Sam Clegge53af7f2018-01-09 21:38:53 +0000258 if (Sig.Index != ExpectedIndex) {
259 errs() << "Unexpected type index: " << Sig.Index << "\n";
260 return 1;
261 }
262 ++ExpectedIndex;
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000263 encodeSLEB128(Sig.Form, OS);
264 encodeULEB128(Sig.ParamTypes.size(), OS);
265 for (auto ParamType : Sig.ParamTypes)
266 encodeSLEB128(ParamType, OS);
267 if (Sig.ReturnType == wasm::WASM_TYPE_NORESULT) {
268 encodeSLEB128(0, OS);
269 } else {
270 encodeULEB128(1, OS);
271 encodeSLEB128(Sig.ReturnType, OS);
272 }
273 }
274 return 0;
275}
276
277int WasmWriter::writeSectionContent(raw_ostream &OS,
278 WasmYAML::ImportSection &Section) {
279 encodeULEB128(Section.Imports.size(), OS);
Sam Clegg03cdd122017-05-05 18:12:34 +0000280 for (const WasmYAML::Import &Import : Section.Imports) {
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000281 writeStringRef(Import.Module, OS);
282 writeStringRef(Import.Field, OS);
283 encodeULEB128(Import.Kind, OS);
284 switch (Import.Kind) {
285 case wasm::WASM_EXTERNAL_FUNCTION:
286 encodeULEB128(Import.SigIndex, OS);
Sam Clegge53af7f2018-01-09 21:38:53 +0000287 NumImportedFunctions++;
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000288 break;
289 case wasm::WASM_EXTERNAL_GLOBAL:
Sam Clegg41db5192017-05-10 00:14:04 +0000290 encodeSLEB128(Import.GlobalImport.Type, OS);
291 writeUint8(OS, Import.GlobalImport.Mutable);
Sam Clegge53af7f2018-01-09 21:38:53 +0000292 NumImportedGlobals++;
Sam Clegg2ffff5a2017-05-09 23:48:41 +0000293 break;
294 case wasm::WASM_EXTERNAL_MEMORY:
295 writeLimits(Import.Memory, OS);
296 break;
297 case wasm::WASM_EXTERNAL_TABLE:
Sam Clegg41db5192017-05-10 00:14:04 +0000298 encodeSLEB128(Import.TableImport.ElemType, OS);
299 writeLimits(Import.TableImport.TableLimits, OS);
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000300 break;
301 default:
Sam Clegge53af7f2018-01-09 21:38:53 +0000302 errs() << "Unknown import type: " << Import.Kind << "\n";
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000303 return 1;
304 }
305 }
306 return 0;
307}
308
309int WasmWriter::writeSectionContent(raw_ostream &OS,
310 WasmYAML::FunctionSection &Section) {
311 encodeULEB128(Section.FunctionTypes.size(), OS);
312 for (uint32_t FuncType : Section.FunctionTypes) {
313 encodeULEB128(FuncType, OS);
314 }
315 return 0;
316}
317
318int WasmWriter::writeSectionContent(raw_ostream &OS,
319 WasmYAML::ExportSection &Section) {
320 encodeULEB128(Section.Exports.size(), OS);
Sam Clegg03cdd122017-05-05 18:12:34 +0000321 for (const WasmYAML::Export &Export : Section.Exports) {
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000322 writeStringRef(Export.Name, OS);
323 encodeULEB128(Export.Kind, OS);
324 encodeULEB128(Export.Index, OS);
325 }
326 return 0;
327}
328
329int WasmWriter::writeSectionContent(raw_ostream &OS,
330 WasmYAML::StartSection &Section) {
331 encodeULEB128(Section.StartFunction, OS);
332 return 0;
333}
334
335int WasmWriter::writeSectionContent(raw_ostream &OS,
336 WasmYAML::TableSection &Section) {
337 encodeULEB128(Section.Tables.size(), OS);
338 for (auto &Table : Section.Tables) {
339 encodeSLEB128(Table.ElemType, OS);
340 writeLimits(Table.TableLimits, OS);
341 }
342 return 0;
343}
344
345int WasmWriter::writeSectionContent(raw_ostream &OS,
346 WasmYAML::MemorySection &Section) {
347 encodeULEB128(Section.Memories.size(), OS);
Sam Clegg03cdd122017-05-05 18:12:34 +0000348 for (const WasmYAML::Limits &Mem : Section.Memories) {
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000349 writeLimits(Mem, OS);
350 }
351 return 0;
352}
353
354int WasmWriter::writeSectionContent(raw_ostream &OS,
355 WasmYAML::GlobalSection &Section) {
356 encodeULEB128(Section.Globals.size(), OS);
Sam Clegge53af7f2018-01-09 21:38:53 +0000357 uint32_t ExpectedIndex = NumImportedGlobals;
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000358 for (auto &Global : Section.Globals) {
Sam Clegge53af7f2018-01-09 21:38:53 +0000359 if (Global.Index != ExpectedIndex) {
360 errs() << "Unexpected global index: " << Global.Index << "\n";
361 return 1;
362 }
363 ++ExpectedIndex;
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000364 encodeSLEB128(Global.Type, OS);
365 writeUint8(OS, Global.Mutable);
366 writeInitExpr(Global.InitExpr, OS);
367 }
368 return 0;
369}
370
371int WasmWriter::writeSectionContent(raw_ostream &OS,
372 WasmYAML::ElemSection &Section) {
373 encodeULEB128(Section.Segments.size(), OS);
374 for (auto &Segment : Section.Segments) {
375 encodeULEB128(Segment.TableIndex, OS);
376 writeInitExpr(Segment.Offset, OS);
377
378 encodeULEB128(Segment.Functions.size(), OS);
379 for (auto &Function : Segment.Functions) {
380 encodeULEB128(Function, OS);
381 }
382 }
383 return 0;
384}
385
386int WasmWriter::writeSectionContent(raw_ostream &OS,
387 WasmYAML::CodeSection &Section) {
388 encodeULEB128(Section.Functions.size(), OS);
Sam Clegge53af7f2018-01-09 21:38:53 +0000389 uint32_t ExpectedIndex = NumImportedFunctions;
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000390 for (auto &Func : Section.Functions) {
391 std::string OutString;
392 raw_string_ostream StringStream(OutString);
Sam Clegge53af7f2018-01-09 21:38:53 +0000393 if (Func.Index != ExpectedIndex) {
394 errs() << "Unexpected function index: " << Func.Index << "\n";
395 return 1;
396 }
397 ++ExpectedIndex;
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000398
399 encodeULEB128(Func.Locals.size(), StringStream);
400 for (auto &LocalDecl : Func.Locals) {
401 encodeULEB128(LocalDecl.Count, StringStream);
402 encodeSLEB128(LocalDecl.Type, StringStream);
403 }
404
405 Func.Body.writeAsBinary(StringStream);
406
407 // Write the section size followed by the content
408 StringStream.flush();
409 encodeULEB128(OutString.size(), OS);
410 OS << OutString;
411 }
412 return 0;
413}
414
415int WasmWriter::writeSectionContent(raw_ostream &OS,
416 WasmYAML::DataSection &Section) {
417 encodeULEB128(Section.Segments.size(), OS);
418 for (auto &Segment : Section.Segments) {
Sam Clegg9c07f942017-07-12 00:24:54 +0000419 encodeULEB128(Segment.MemoryIndex, OS);
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000420 writeInitExpr(Segment.Offset, OS);
421 encodeULEB128(Segment.Content.binary_size(), OS);
422 Segment.Content.writeAsBinary(OS);
423 }
424 return 0;
425}
426
427int WasmWriter::writeRelocSection(raw_ostream &OS,
428 WasmYAML::Section &Sec) {
429 StringRef Name;
430 switch (Sec.Type) {
431 case wasm::WASM_SEC_CODE:
432 Name = "reloc.CODE";
433 break;
434 case wasm::WASM_SEC_DATA:
435 Name = "reloc.DATA";
436 break;
437 default:
438 llvm_unreachable("not yet implemented");
439 return 1;
440 }
441
442 writeStringRef(Name, OS);
443 encodeULEB128(Sec.Type, OS);
444 encodeULEB128(Sec.Relocations.size(), OS);
445
446 for (auto Reloc: Sec.Relocations) {
447 encodeULEB128(Reloc.Type, OS);
448 encodeULEB128(Reloc.Offset, OS);
449 encodeULEB128(Reloc.Index, OS);
450 switch (Reloc.Type) {
Sam Clegg13a2e892017-09-01 17:32:01 +0000451 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
452 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
453 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000454 encodeULEB128(Reloc.Addend, OS);
455 }
456 }
457 return 0;
458}
459
460
461int WasmWriter::writeWasm(raw_ostream &OS) {
462 // Write headers
463 OS.write(wasm::WasmMagic, sizeof(wasm::WasmMagic));
464 writeUint32(OS, Obj.Header.Version);
465
466 // Write each section
Sam Clegge53af7f2018-01-09 21:38:53 +0000467 uint32_t LastType = 0;
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000468 for (const std::unique_ptr<WasmYAML::Section> &Sec : Obj.Sections) {
Sam Clegge53af7f2018-01-09 21:38:53 +0000469 uint32_t Type = Sec->Type;
470 if (Type != wasm::WASM_SEC_CUSTOM) {
471 if (Type < LastType) {
472 errs() << "Out of order section type: " << Type << "\n";
473 return 1;
474 }
475 LastType = Type;
476 }
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000477
Sam Clegge53af7f2018-01-09 21:38:53 +0000478 encodeULEB128(Sec->Type, OS);
Derek Schuffd3d84fd2017-03-30 19:44:09 +0000479 std::string OutString;
480 raw_string_ostream StringStream(OutString);
481 if (auto S = dyn_cast<WasmYAML::CustomSection>(Sec.get())) {
482 if (auto Err = writeSectionContent(StringStream, *S))
483 return Err;
484 } else if (auto S = dyn_cast<WasmYAML::TypeSection>(Sec.get())) {
485 if (auto Err = writeSectionContent(StringStream, *S))
486 return Err;
487 } else if (auto S = dyn_cast<WasmYAML::ImportSection>(Sec.get())) {
488 if (auto Err = writeSectionContent(StringStream, *S))
489 return Err;
490 } else if (auto S = dyn_cast<WasmYAML::FunctionSection>(Sec.get())) {
491 if (auto Err = writeSectionContent(StringStream, *S))
492 return Err;
493 } else if (auto S = dyn_cast<WasmYAML::TableSection>(Sec.get())) {
494 if (auto Err = writeSectionContent(StringStream, *S))
495 return Err;
496 } else if (auto S = dyn_cast<WasmYAML::MemorySection>(Sec.get())) {
497 if (auto Err = writeSectionContent(StringStream, *S))
498 return Err;
499 } else if (auto S = dyn_cast<WasmYAML::GlobalSection>(Sec.get())) {
500 if (auto Err = writeSectionContent(StringStream, *S))
501 return Err;
502 } else if (auto S = dyn_cast<WasmYAML::ExportSection>(Sec.get())) {
503 if (auto Err = writeSectionContent(StringStream, *S))
504 return Err;
505 } else if (auto S = dyn_cast<WasmYAML::StartSection>(Sec.get())) {
506 if (auto Err = writeSectionContent(StringStream, *S))
507 return Err;
508 } else if (auto S = dyn_cast<WasmYAML::ElemSection>(Sec.get())) {
509 if (auto Err = writeSectionContent(StringStream, *S))
510 return Err;
511 } else if (auto S = dyn_cast<WasmYAML::CodeSection>(Sec.get())) {
512 if (auto Err = writeSectionContent(StringStream, *S))
513 return Err;
514 } else if (auto S = dyn_cast<WasmYAML::DataSection>(Sec.get())) {
515 if (auto Err = writeSectionContent(StringStream, *S))
516 return Err;
517 } else {
518 errs() << "Unknown section type: " << Sec->Type << "\n";
519 return 1;
520 }
521 StringStream.flush();
522
523 // Write the section size followed by the content
524 encodeULEB128(OutString.size(), OS);
525 OS << OutString;
526 }
527
528 // write reloc sections for any section that have relocations
529 for (const std::unique_ptr<WasmYAML::Section> &Sec : Obj.Sections) {
530 if (Sec->Relocations.empty())
531 continue;
532
533 encodeULEB128(wasm::WASM_SEC_CUSTOM, OS);
534 std::string OutString;
535 raw_string_ostream StringStream(OutString);
536 writeRelocSection(StringStream, *Sec);
537 StringStream.flush();
538
539 encodeULEB128(OutString.size(), OS);
540 OS << OutString;
541 }
542
543 return 0;
544}
545
546int yaml2wasm(llvm::WasmYAML::Object &Doc, raw_ostream &Out) {
547 WasmWriter Writer(Doc);
548
549 return Writer.writeWasm(Out);
550}