1 //===- yaml2wasm - Convert YAML to a Wasm object file --------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// The Wasm component of yaml2obj.
12 //===----------------------------------------------------------------------===//
15 #include "llvm/Object/Wasm.h"
16 #include "llvm/ObjectYAML/ObjectYAML.h"
17 #include "llvm/ObjectYAML/yaml2obj.h"
18 #include "llvm/Support/Endian.h"
19 #include "llvm/Support/LEB128.h"
24 /// This parses a yaml stream that represents a Wasm object file.
25 /// See docs/yaml2obj for the yaml scheema.
28 WasmWriter(WasmYAML::Object
&Obj
, yaml::ErrorHandler EH
)
29 : Obj(Obj
), ErrHandler(EH
) {}
30 bool writeWasm(raw_ostream
&OS
);
33 void writeRelocSection(raw_ostream
&OS
, WasmYAML::Section
&Sec
,
34 uint32_t SectionIndex
);
36 void writeInitExpr(raw_ostream
&OS
, const wasm::WasmInitExpr
&InitExpr
);
38 void writeSectionContent(raw_ostream
&OS
, WasmYAML::CustomSection
&Section
);
39 void writeSectionContent(raw_ostream
&OS
, WasmYAML::TypeSection
&Section
);
40 void writeSectionContent(raw_ostream
&OS
, WasmYAML::ImportSection
&Section
);
41 void writeSectionContent(raw_ostream
&OS
, WasmYAML::FunctionSection
&Section
);
42 void writeSectionContent(raw_ostream
&OS
, WasmYAML::TableSection
&Section
);
43 void writeSectionContent(raw_ostream
&OS
, WasmYAML::MemorySection
&Section
);
44 void writeSectionContent(raw_ostream
&OS
, WasmYAML::GlobalSection
&Section
);
45 void writeSectionContent(raw_ostream
&OS
, WasmYAML::EventSection
&Section
);
46 void writeSectionContent(raw_ostream
&OS
, WasmYAML::ExportSection
&Section
);
47 void writeSectionContent(raw_ostream
&OS
, WasmYAML::StartSection
&Section
);
48 void writeSectionContent(raw_ostream
&OS
, WasmYAML::ElemSection
&Section
);
49 void writeSectionContent(raw_ostream
&OS
, WasmYAML::CodeSection
&Section
);
50 void writeSectionContent(raw_ostream
&OS
, WasmYAML::DataSection
&Section
);
51 void writeSectionContent(raw_ostream
&OS
, WasmYAML::DataCountSection
&Section
);
53 // Custom section types
54 void writeSectionContent(raw_ostream
&OS
, WasmYAML::DylinkSection
&Section
);
55 void writeSectionContent(raw_ostream
&OS
, WasmYAML::NameSection
&Section
);
56 void writeSectionContent(raw_ostream
&OS
, WasmYAML::LinkingSection
&Section
);
57 void writeSectionContent(raw_ostream
&OS
, WasmYAML::ProducersSection
&Section
);
58 void writeSectionContent(raw_ostream
&OS
,
59 WasmYAML::TargetFeaturesSection
&Section
);
60 WasmYAML::Object
&Obj
;
61 uint32_t NumImportedFunctions
= 0;
62 uint32_t NumImportedGlobals
= 0;
63 uint32_t NumImportedEvents
= 0;
65 bool HasError
= false;
66 yaml::ErrorHandler ErrHandler
;
67 void reportError(const Twine
&Msg
);
70 class SubSectionWriter
{
72 std::string OutString
;
73 raw_string_ostream StringStream
;
76 SubSectionWriter(raw_ostream
&OS
) : OS(OS
), StringStream(OutString
) {}
80 encodeULEB128(OutString
.size(), OS
);
85 raw_ostream
&getStream() { return StringStream
; }
88 } // end anonymous namespace
90 static int writeUint64(raw_ostream
&OS
, uint64_t Value
) {
91 char Data
[sizeof(Value
)];
92 support::endian::write64le(Data
, Value
);
93 OS
.write(Data
, sizeof(Data
));
97 static int writeUint32(raw_ostream
&OS
, uint32_t Value
) {
98 char Data
[sizeof(Value
)];
99 support::endian::write32le(Data
, Value
);
100 OS
.write(Data
, sizeof(Data
));
104 static int writeUint8(raw_ostream
&OS
, uint8_t Value
) {
105 char Data
[sizeof(Value
)];
106 memcpy(Data
, &Value
, sizeof(Data
));
107 OS
.write(Data
, sizeof(Data
));
111 static int writeStringRef(const StringRef
&Str
, raw_ostream
&OS
) {
112 encodeULEB128(Str
.size(), OS
);
117 static int writeLimits(const WasmYAML::Limits
&Lim
, raw_ostream
&OS
) {
118 writeUint8(OS
, Lim
.Flags
);
119 encodeULEB128(Lim
.Initial
, OS
);
120 if (Lim
.Flags
& wasm::WASM_LIMITS_FLAG_HAS_MAX
)
121 encodeULEB128(Lim
.Maximum
, OS
);
125 void WasmWriter::reportError(const Twine
&Msg
) {
130 void WasmWriter::writeInitExpr(raw_ostream
&OS
,
131 const wasm::WasmInitExpr
&InitExpr
) {
132 writeUint8(OS
, InitExpr
.Opcode
);
133 switch (InitExpr
.Opcode
) {
134 case wasm::WASM_OPCODE_I32_CONST
:
135 encodeSLEB128(InitExpr
.Value
.Int32
, OS
);
137 case wasm::WASM_OPCODE_I64_CONST
:
138 encodeSLEB128(InitExpr
.Value
.Int64
, OS
);
140 case wasm::WASM_OPCODE_F32_CONST
:
141 writeUint32(OS
, InitExpr
.Value
.Float32
);
143 case wasm::WASM_OPCODE_F64_CONST
:
144 writeUint64(OS
, InitExpr
.Value
.Float64
);
146 case wasm::WASM_OPCODE_GLOBAL_GET
:
147 encodeULEB128(InitExpr
.Value
.Global
, OS
);
150 reportError("unknown opcode in init_expr: " + Twine(InitExpr
.Opcode
));
153 writeUint8(OS
, wasm::WASM_OPCODE_END
);
156 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
157 WasmYAML::DylinkSection
&Section
) {
158 writeStringRef(Section
.Name
, OS
);
159 encodeULEB128(Section
.MemorySize
, OS
);
160 encodeULEB128(Section
.MemoryAlignment
, OS
);
161 encodeULEB128(Section
.TableSize
, OS
);
162 encodeULEB128(Section
.TableAlignment
, OS
);
163 encodeULEB128(Section
.Needed
.size(), OS
);
164 for (StringRef Needed
: Section
.Needed
)
165 writeStringRef(Needed
, OS
);
168 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
169 WasmYAML::LinkingSection
&Section
) {
170 writeStringRef(Section
.Name
, OS
);
171 encodeULEB128(Section
.Version
, OS
);
173 SubSectionWriter
SubSection(OS
);
175 // SYMBOL_TABLE subsection
176 if (Section
.SymbolTable
.size()) {
177 writeUint8(OS
, wasm::WASM_SYMBOL_TABLE
);
179 encodeULEB128(Section
.SymbolTable
.size(), SubSection
.getStream());
181 uint32_t SymbolIndex
= 0;
183 for (const WasmYAML::SymbolInfo
&Info
: Section
.SymbolTable
) {
184 assert(Info
.Index
== SymbolIndex
++);
185 writeUint8(SubSection
.getStream(), Info
.Kind
);
186 encodeULEB128(Info
.Flags
, SubSection
.getStream());
188 case wasm::WASM_SYMBOL_TYPE_FUNCTION
:
189 case wasm::WASM_SYMBOL_TYPE_GLOBAL
:
190 case wasm::WASM_SYMBOL_TYPE_EVENT
:
191 encodeULEB128(Info
.ElementIndex
, SubSection
.getStream());
192 if ((Info
.Flags
& wasm::WASM_SYMBOL_UNDEFINED
) == 0 ||
193 (Info
.Flags
& wasm::WASM_SYMBOL_EXPLICIT_NAME
) != 0)
194 writeStringRef(Info
.Name
, SubSection
.getStream());
196 case wasm::WASM_SYMBOL_TYPE_DATA
:
197 writeStringRef(Info
.Name
, SubSection
.getStream());
198 if ((Info
.Flags
& wasm::WASM_SYMBOL_UNDEFINED
) == 0) {
199 encodeULEB128(Info
.DataRef
.Segment
, SubSection
.getStream());
200 encodeULEB128(Info
.DataRef
.Offset
, SubSection
.getStream());
201 encodeULEB128(Info
.DataRef
.Size
, SubSection
.getStream());
204 case wasm::WASM_SYMBOL_TYPE_SECTION
:
205 encodeULEB128(Info
.ElementIndex
, SubSection
.getStream());
208 llvm_unreachable("unexpected kind");
215 // SEGMENT_NAMES subsection
216 if (Section
.SegmentInfos
.size()) {
217 writeUint8(OS
, wasm::WASM_SEGMENT_INFO
);
218 encodeULEB128(Section
.SegmentInfos
.size(), SubSection
.getStream());
219 for (const WasmYAML::SegmentInfo
&SegmentInfo
: Section
.SegmentInfos
) {
220 writeStringRef(SegmentInfo
.Name
, SubSection
.getStream());
221 encodeULEB128(SegmentInfo
.Alignment
, SubSection
.getStream());
222 encodeULEB128(SegmentInfo
.Flags
, SubSection
.getStream());
227 // INIT_FUNCS subsection
228 if (Section
.InitFunctions
.size()) {
229 writeUint8(OS
, wasm::WASM_INIT_FUNCS
);
230 encodeULEB128(Section
.InitFunctions
.size(), SubSection
.getStream());
231 for (const WasmYAML::InitFunction
&Func
: Section
.InitFunctions
) {
232 encodeULEB128(Func
.Priority
, SubSection
.getStream());
233 encodeULEB128(Func
.Symbol
, SubSection
.getStream());
238 // COMDAT_INFO subsection
239 if (Section
.Comdats
.size()) {
240 writeUint8(OS
, wasm::WASM_COMDAT_INFO
);
241 encodeULEB128(Section
.Comdats
.size(), SubSection
.getStream());
242 for (const auto &C
: Section
.Comdats
) {
243 writeStringRef(C
.Name
, SubSection
.getStream());
244 encodeULEB128(0, SubSection
.getStream()); // flags for future use
245 encodeULEB128(C
.Entries
.size(), SubSection
.getStream());
246 for (const WasmYAML::ComdatEntry
&Entry
: C
.Entries
) {
247 writeUint8(SubSection
.getStream(), Entry
.Kind
);
248 encodeULEB128(Entry
.Index
, SubSection
.getStream());
255 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
256 WasmYAML::NameSection
&Section
) {
257 writeStringRef(Section
.Name
, OS
);
258 if (Section
.FunctionNames
.size()) {
259 writeUint8(OS
, wasm::WASM_NAMES_FUNCTION
);
261 SubSectionWriter
SubSection(OS
);
263 encodeULEB128(Section
.FunctionNames
.size(), SubSection
.getStream());
264 for (const WasmYAML::NameEntry
&NameEntry
: Section
.FunctionNames
) {
265 encodeULEB128(NameEntry
.Index
, SubSection
.getStream());
266 writeStringRef(NameEntry
.Name
, SubSection
.getStream());
273 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
274 WasmYAML::ProducersSection
&Section
) {
275 writeStringRef(Section
.Name
, OS
);
276 int Fields
= int(!Section
.Languages
.empty()) + int(!Section
.Tools
.empty()) +
277 int(!Section
.SDKs
.empty());
280 encodeULEB128(Fields
, OS
);
281 for (auto &Field
: {std::make_pair(StringRef("language"), &Section
.Languages
),
282 std::make_pair(StringRef("processed-by"), &Section
.Tools
),
283 std::make_pair(StringRef("sdk"), &Section
.SDKs
)}) {
284 if (Field
.second
->empty())
286 writeStringRef(Field
.first
, OS
);
287 encodeULEB128(Field
.second
->size(), OS
);
288 for (auto &Entry
: *Field
.second
) {
289 writeStringRef(Entry
.Name
, OS
);
290 writeStringRef(Entry
.Version
, OS
);
295 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
296 WasmYAML::TargetFeaturesSection
&Section
) {
297 writeStringRef(Section
.Name
, OS
);
298 encodeULEB128(Section
.Features
.size(), OS
);
299 for (auto &E
: Section
.Features
) {
300 writeUint8(OS
, E
.Prefix
);
301 writeStringRef(E
.Name
, OS
);
305 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
306 WasmYAML::CustomSection
&Section
) {
307 if (auto S
= dyn_cast
<WasmYAML::DylinkSection
>(&Section
)) {
308 writeSectionContent(OS
, *S
);
309 } else if (auto S
= dyn_cast
<WasmYAML::NameSection
>(&Section
)) {
310 writeSectionContent(OS
, *S
);
311 } else if (auto S
= dyn_cast
<WasmYAML::LinkingSection
>(&Section
)) {
312 writeSectionContent(OS
, *S
);
313 } else if (auto S
= dyn_cast
<WasmYAML::ProducersSection
>(&Section
)) {
314 writeSectionContent(OS
, *S
);
315 } else if (auto S
= dyn_cast
<WasmYAML::TargetFeaturesSection
>(&Section
)) {
316 writeSectionContent(OS
, *S
);
318 writeStringRef(Section
.Name
, OS
);
319 Section
.Payload
.writeAsBinary(OS
);
323 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
324 WasmYAML::TypeSection
&Section
) {
325 encodeULEB128(Section
.Signatures
.size(), OS
);
326 uint32_t ExpectedIndex
= 0;
327 for (const WasmYAML::Signature
&Sig
: Section
.Signatures
) {
328 if (Sig
.Index
!= ExpectedIndex
) {
329 reportError("unexpected type index: " + Twine(Sig
.Index
));
333 writeUint8(OS
, Sig
.Form
);
334 encodeULEB128(Sig
.ParamTypes
.size(), OS
);
335 for (auto ParamType
: Sig
.ParamTypes
)
336 writeUint8(OS
, ParamType
);
337 if (Sig
.ReturnType
== wasm::WASM_TYPE_NORESULT
) {
338 encodeULEB128(0, OS
);
340 encodeULEB128(1, OS
);
341 writeUint8(OS
, Sig
.ReturnType
);
346 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
347 WasmYAML::ImportSection
&Section
) {
348 encodeULEB128(Section
.Imports
.size(), OS
);
349 for (const WasmYAML::Import
&Import
: Section
.Imports
) {
350 writeStringRef(Import
.Module
, OS
);
351 writeStringRef(Import
.Field
, OS
);
352 writeUint8(OS
, Import
.Kind
);
353 switch (Import
.Kind
) {
354 case wasm::WASM_EXTERNAL_FUNCTION
:
355 encodeULEB128(Import
.SigIndex
, OS
);
356 NumImportedFunctions
++;
358 case wasm::WASM_EXTERNAL_GLOBAL
:
359 writeUint8(OS
, Import
.GlobalImport
.Type
);
360 writeUint8(OS
, Import
.GlobalImport
.Mutable
);
361 NumImportedGlobals
++;
363 case wasm::WASM_EXTERNAL_EVENT
:
364 writeUint32(OS
, Import
.EventImport
.Attribute
);
365 writeUint32(OS
, Import
.EventImport
.SigIndex
);
366 NumImportedGlobals
++;
368 case wasm::WASM_EXTERNAL_MEMORY
:
369 writeLimits(Import
.Memory
, OS
);
371 case wasm::WASM_EXTERNAL_TABLE
:
372 writeUint8(OS
, Import
.TableImport
.ElemType
);
373 writeLimits(Import
.TableImport
.TableLimits
, OS
);
376 reportError("unknown import type: " +Twine(Import
.Kind
));
382 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
383 WasmYAML::FunctionSection
&Section
) {
384 encodeULEB128(Section
.FunctionTypes
.size(), OS
);
385 for (uint32_t FuncType
: Section
.FunctionTypes
)
386 encodeULEB128(FuncType
, OS
);
389 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
390 WasmYAML::ExportSection
&Section
) {
391 encodeULEB128(Section
.Exports
.size(), OS
);
392 for (const WasmYAML::Export
&Export
: Section
.Exports
) {
393 writeStringRef(Export
.Name
, OS
);
394 writeUint8(OS
, Export
.Kind
);
395 encodeULEB128(Export
.Index
, OS
);
399 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
400 WasmYAML::StartSection
&Section
) {
401 encodeULEB128(Section
.StartFunction
, OS
);
404 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
405 WasmYAML::TableSection
&Section
) {
406 encodeULEB128(Section
.Tables
.size(), OS
);
407 for (auto &Table
: Section
.Tables
) {
408 writeUint8(OS
, Table
.ElemType
);
409 writeLimits(Table
.TableLimits
, OS
);
413 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
414 WasmYAML::MemorySection
&Section
) {
415 encodeULEB128(Section
.Memories
.size(), OS
);
416 for (const WasmYAML::Limits
&Mem
: Section
.Memories
)
417 writeLimits(Mem
, OS
);
420 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
421 WasmYAML::GlobalSection
&Section
) {
422 encodeULEB128(Section
.Globals
.size(), OS
);
423 uint32_t ExpectedIndex
= NumImportedGlobals
;
424 for (auto &Global
: Section
.Globals
) {
425 if (Global
.Index
!= ExpectedIndex
) {
426 reportError("unexpected global index: " + Twine(Global
.Index
));
430 writeUint8(OS
, Global
.Type
);
431 writeUint8(OS
, Global
.Mutable
);
432 writeInitExpr(OS
, Global
.InitExpr
);
436 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
437 WasmYAML::EventSection
&Section
) {
438 encodeULEB128(Section
.Events
.size(), OS
);
439 uint32_t ExpectedIndex
= NumImportedEvents
;
440 for (auto &Event
: Section
.Events
) {
441 if (Event
.Index
!= ExpectedIndex
) {
442 reportError("unexpected event index: " + Twine(Event
.Index
));
446 encodeULEB128(Event
.Attribute
, OS
);
447 encodeULEB128(Event
.SigIndex
, OS
);
451 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
452 WasmYAML::ElemSection
&Section
) {
453 encodeULEB128(Section
.Segments
.size(), OS
);
454 for (auto &Segment
: Section
.Segments
) {
455 encodeULEB128(Segment
.TableIndex
, OS
);
456 writeInitExpr(OS
, Segment
.Offset
);
458 encodeULEB128(Segment
.Functions
.size(), OS
);
459 for (auto &Function
: Segment
.Functions
)
460 encodeULEB128(Function
, OS
);
464 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
465 WasmYAML::CodeSection
&Section
) {
466 encodeULEB128(Section
.Functions
.size(), OS
);
467 uint32_t ExpectedIndex
= NumImportedFunctions
;
468 for (auto &Func
: Section
.Functions
) {
469 std::string OutString
;
470 raw_string_ostream
StringStream(OutString
);
471 if (Func
.Index
!= ExpectedIndex
) {
472 reportError("unexpected function index: " + Twine(Func
.Index
));
477 encodeULEB128(Func
.Locals
.size(), StringStream
);
478 for (auto &LocalDecl
: Func
.Locals
) {
479 encodeULEB128(LocalDecl
.Count
, StringStream
);
480 writeUint8(StringStream
, LocalDecl
.Type
);
483 Func
.Body
.writeAsBinary(StringStream
);
485 // Write the section size followed by the content
486 StringStream
.flush();
487 encodeULEB128(OutString
.size(), OS
);
492 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
493 WasmYAML::DataSection
&Section
) {
494 encodeULEB128(Section
.Segments
.size(), OS
);
495 for (auto &Segment
: Section
.Segments
) {
496 encodeULEB128(Segment
.InitFlags
, OS
);
497 if (Segment
.InitFlags
& wasm::WASM_SEGMENT_HAS_MEMINDEX
)
498 encodeULEB128(Segment
.MemoryIndex
, OS
);
499 if ((Segment
.InitFlags
& wasm::WASM_SEGMENT_IS_PASSIVE
) == 0)
500 writeInitExpr(OS
, Segment
.Offset
);
501 encodeULEB128(Segment
.Content
.binary_size(), OS
);
502 Segment
.Content
.writeAsBinary(OS
);
506 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
507 WasmYAML::DataCountSection
&Section
) {
508 encodeULEB128(Section
.Count
, OS
);
511 void WasmWriter::writeRelocSection(raw_ostream
&OS
, WasmYAML::Section
&Sec
,
512 uint32_t SectionIndex
) {
514 case wasm::WASM_SEC_CODE
:
515 writeStringRef("reloc.CODE", OS
);
517 case wasm::WASM_SEC_DATA
:
518 writeStringRef("reloc.DATA", OS
);
520 case wasm::WASM_SEC_CUSTOM
: {
521 auto *CustomSection
= cast
<WasmYAML::CustomSection
>(&Sec
);
522 writeStringRef(("reloc." + CustomSection
->Name
).str(), OS
);
526 llvm_unreachable("not yet implemented");
529 encodeULEB128(SectionIndex
, OS
);
530 encodeULEB128(Sec
.Relocations
.size(), OS
);
532 for (auto Reloc
: Sec
.Relocations
) {
533 writeUint8(OS
, Reloc
.Type
);
534 encodeULEB128(Reloc
.Offset
, OS
);
535 encodeULEB128(Reloc
.Index
, OS
);
536 switch (Reloc
.Type
) {
537 case wasm::R_WASM_MEMORY_ADDR_LEB
:
538 case wasm::R_WASM_MEMORY_ADDR_SLEB
:
539 case wasm::R_WASM_MEMORY_ADDR_I32
:
540 case wasm::R_WASM_FUNCTION_OFFSET_I32
:
541 case wasm::R_WASM_SECTION_OFFSET_I32
:
542 encodeULEB128(Reloc
.Addend
, OS
);
547 bool WasmWriter::writeWasm(raw_ostream
&OS
) {
549 OS
.write(wasm::WasmMagic
, sizeof(wasm::WasmMagic
));
550 writeUint32(OS
, Obj
.Header
.Version
);
552 // Write each section
553 llvm::object::WasmSectionOrderChecker Checker
;
554 for (const std::unique_ptr
<WasmYAML::Section
> &Sec
: Obj
.Sections
) {
555 StringRef SecName
= "";
556 if (auto S
= dyn_cast
<WasmYAML::CustomSection
>(Sec
.get()))
558 if (!Checker
.isValidSectionOrder(Sec
->Type
, SecName
)) {
559 reportError("out of order section type: " + Twine(Sec
->Type
));
562 encodeULEB128(Sec
->Type
, OS
);
563 std::string OutString
;
564 raw_string_ostream
StringStream(OutString
);
565 if (auto S
= dyn_cast
<WasmYAML::CustomSection
>(Sec
.get()))
566 writeSectionContent(StringStream
, *S
);
567 else if (auto S
= dyn_cast
<WasmYAML::TypeSection
>(Sec
.get()))
568 writeSectionContent(StringStream
, *S
);
569 else if (auto S
= dyn_cast
<WasmYAML::ImportSection
>(Sec
.get()))
570 writeSectionContent(StringStream
, *S
);
571 else if (auto S
= dyn_cast
<WasmYAML::FunctionSection
>(Sec
.get()))
572 writeSectionContent(StringStream
, *S
);
573 else if (auto S
= dyn_cast
<WasmYAML::TableSection
>(Sec
.get()))
574 writeSectionContent(StringStream
, *S
);
575 else if (auto S
= dyn_cast
<WasmYAML::MemorySection
>(Sec
.get()))
576 writeSectionContent(StringStream
, *S
);
577 else if (auto S
= dyn_cast
<WasmYAML::GlobalSection
>(Sec
.get()))
578 writeSectionContent(StringStream
, *S
);
579 else if (auto S
= dyn_cast
<WasmYAML::EventSection
>(Sec
.get()))
580 writeSectionContent(StringStream
, *S
);
581 else if (auto S
= dyn_cast
<WasmYAML::ExportSection
>(Sec
.get()))
582 writeSectionContent(StringStream
, *S
);
583 else if (auto S
= dyn_cast
<WasmYAML::StartSection
>(Sec
.get()))
584 writeSectionContent(StringStream
, *S
);
585 else if (auto S
= dyn_cast
<WasmYAML::ElemSection
>(Sec
.get()))
586 writeSectionContent(StringStream
, *S
);
587 else if (auto S
= dyn_cast
<WasmYAML::CodeSection
>(Sec
.get()))
588 writeSectionContent(StringStream
, *S
);
589 else if (auto S
= dyn_cast
<WasmYAML::DataSection
>(Sec
.get()))
590 writeSectionContent(StringStream
, *S
);
591 else if (auto S
= dyn_cast
<WasmYAML::DataCountSection
>(Sec
.get()))
592 writeSectionContent(StringStream
, *S
);
594 reportError("unknown section type: " + Twine(Sec
->Type
));
599 StringStream
.flush();
601 // Write the section size followed by the content
602 encodeULEB128(OutString
.size(), OS
);
606 // write reloc sections for any section that have relocations
607 uint32_t SectionIndex
= 0;
608 for (const std::unique_ptr
<WasmYAML::Section
> &Sec
: Obj
.Sections
) {
609 if (Sec
->Relocations
.empty()) {
614 writeUint8(OS
, wasm::WASM_SEC_CUSTOM
);
615 std::string OutString
;
616 raw_string_ostream
StringStream(OutString
);
617 writeRelocSection(StringStream
, *Sec
, SectionIndex
++);
618 StringStream
.flush();
620 encodeULEB128(OutString
.size(), OS
);
630 bool yaml2wasm(WasmYAML::Object
&Doc
, raw_ostream
&Out
, ErrorHandler EH
) {
631 WasmWriter
Writer(Doc
, EH
);
632 return Writer
.writeWasm(Out
);