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 encodeULEB128(Sig
.ReturnTypes
.size(), OS
);
338 for (auto ReturnType
: Sig
.ReturnTypes
)
339 writeUint8(OS
, ReturnType
);
343 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
344 WasmYAML::ImportSection
&Section
) {
345 encodeULEB128(Section
.Imports
.size(), OS
);
346 for (const WasmYAML::Import
&Import
: Section
.Imports
) {
347 writeStringRef(Import
.Module
, OS
);
348 writeStringRef(Import
.Field
, OS
);
349 writeUint8(OS
, Import
.Kind
);
350 switch (Import
.Kind
) {
351 case wasm::WASM_EXTERNAL_FUNCTION
:
352 encodeULEB128(Import
.SigIndex
, OS
);
353 NumImportedFunctions
++;
355 case wasm::WASM_EXTERNAL_GLOBAL
:
356 writeUint8(OS
, Import
.GlobalImport
.Type
);
357 writeUint8(OS
, Import
.GlobalImport
.Mutable
);
358 NumImportedGlobals
++;
360 case wasm::WASM_EXTERNAL_EVENT
:
361 writeUint32(OS
, Import
.EventImport
.Attribute
);
362 writeUint32(OS
, Import
.EventImport
.SigIndex
);
363 NumImportedGlobals
++;
365 case wasm::WASM_EXTERNAL_MEMORY
:
366 writeLimits(Import
.Memory
, OS
);
368 case wasm::WASM_EXTERNAL_TABLE
:
369 writeUint8(OS
, Import
.TableImport
.ElemType
);
370 writeLimits(Import
.TableImport
.TableLimits
, OS
);
373 reportError("unknown import type: " +Twine(Import
.Kind
));
379 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
380 WasmYAML::FunctionSection
&Section
) {
381 encodeULEB128(Section
.FunctionTypes
.size(), OS
);
382 for (uint32_t FuncType
: Section
.FunctionTypes
)
383 encodeULEB128(FuncType
, OS
);
386 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
387 WasmYAML::ExportSection
&Section
) {
388 encodeULEB128(Section
.Exports
.size(), OS
);
389 for (const WasmYAML::Export
&Export
: Section
.Exports
) {
390 writeStringRef(Export
.Name
, OS
);
391 writeUint8(OS
, Export
.Kind
);
392 encodeULEB128(Export
.Index
, OS
);
396 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
397 WasmYAML::StartSection
&Section
) {
398 encodeULEB128(Section
.StartFunction
, OS
);
401 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
402 WasmYAML::TableSection
&Section
) {
403 encodeULEB128(Section
.Tables
.size(), OS
);
404 for (auto &Table
: Section
.Tables
) {
405 writeUint8(OS
, Table
.ElemType
);
406 writeLimits(Table
.TableLimits
, OS
);
410 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
411 WasmYAML::MemorySection
&Section
) {
412 encodeULEB128(Section
.Memories
.size(), OS
);
413 for (const WasmYAML::Limits
&Mem
: Section
.Memories
)
414 writeLimits(Mem
, OS
);
417 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
418 WasmYAML::GlobalSection
&Section
) {
419 encodeULEB128(Section
.Globals
.size(), OS
);
420 uint32_t ExpectedIndex
= NumImportedGlobals
;
421 for (auto &Global
: Section
.Globals
) {
422 if (Global
.Index
!= ExpectedIndex
) {
423 reportError("unexpected global index: " + Twine(Global
.Index
));
427 writeUint8(OS
, Global
.Type
);
428 writeUint8(OS
, Global
.Mutable
);
429 writeInitExpr(OS
, Global
.InitExpr
);
433 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
434 WasmYAML::EventSection
&Section
) {
435 encodeULEB128(Section
.Events
.size(), OS
);
436 uint32_t ExpectedIndex
= NumImportedEvents
;
437 for (auto &Event
: Section
.Events
) {
438 if (Event
.Index
!= ExpectedIndex
) {
439 reportError("unexpected event index: " + Twine(Event
.Index
));
443 encodeULEB128(Event
.Attribute
, OS
);
444 encodeULEB128(Event
.SigIndex
, OS
);
448 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
449 WasmYAML::ElemSection
&Section
) {
450 encodeULEB128(Section
.Segments
.size(), OS
);
451 for (auto &Segment
: Section
.Segments
) {
452 encodeULEB128(Segment
.TableIndex
, OS
);
453 writeInitExpr(OS
, Segment
.Offset
);
455 encodeULEB128(Segment
.Functions
.size(), OS
);
456 for (auto &Function
: Segment
.Functions
)
457 encodeULEB128(Function
, OS
);
461 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
462 WasmYAML::CodeSection
&Section
) {
463 encodeULEB128(Section
.Functions
.size(), OS
);
464 uint32_t ExpectedIndex
= NumImportedFunctions
;
465 for (auto &Func
: Section
.Functions
) {
466 std::string OutString
;
467 raw_string_ostream
StringStream(OutString
);
468 if (Func
.Index
!= ExpectedIndex
) {
469 reportError("unexpected function index: " + Twine(Func
.Index
));
474 encodeULEB128(Func
.Locals
.size(), StringStream
);
475 for (auto &LocalDecl
: Func
.Locals
) {
476 encodeULEB128(LocalDecl
.Count
, StringStream
);
477 writeUint8(StringStream
, LocalDecl
.Type
);
480 Func
.Body
.writeAsBinary(StringStream
);
482 // Write the section size followed by the content
483 StringStream
.flush();
484 encodeULEB128(OutString
.size(), OS
);
489 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
490 WasmYAML::DataSection
&Section
) {
491 encodeULEB128(Section
.Segments
.size(), OS
);
492 for (auto &Segment
: Section
.Segments
) {
493 encodeULEB128(Segment
.InitFlags
, OS
);
494 if (Segment
.InitFlags
& wasm::WASM_SEGMENT_HAS_MEMINDEX
)
495 encodeULEB128(Segment
.MemoryIndex
, OS
);
496 if ((Segment
.InitFlags
& wasm::WASM_SEGMENT_IS_PASSIVE
) == 0)
497 writeInitExpr(OS
, Segment
.Offset
);
498 encodeULEB128(Segment
.Content
.binary_size(), OS
);
499 Segment
.Content
.writeAsBinary(OS
);
503 void WasmWriter::writeSectionContent(raw_ostream
&OS
,
504 WasmYAML::DataCountSection
&Section
) {
505 encodeULEB128(Section
.Count
, OS
);
508 void WasmWriter::writeRelocSection(raw_ostream
&OS
, WasmYAML::Section
&Sec
,
509 uint32_t SectionIndex
) {
511 case wasm::WASM_SEC_CODE
:
512 writeStringRef("reloc.CODE", OS
);
514 case wasm::WASM_SEC_DATA
:
515 writeStringRef("reloc.DATA", OS
);
517 case wasm::WASM_SEC_CUSTOM
: {
518 auto *CustomSection
= cast
<WasmYAML::CustomSection
>(&Sec
);
519 writeStringRef(("reloc." + CustomSection
->Name
).str(), OS
);
523 llvm_unreachable("not yet implemented");
526 encodeULEB128(SectionIndex
, OS
);
527 encodeULEB128(Sec
.Relocations
.size(), OS
);
529 for (auto Reloc
: Sec
.Relocations
) {
530 writeUint8(OS
, Reloc
.Type
);
531 encodeULEB128(Reloc
.Offset
, OS
);
532 encodeULEB128(Reloc
.Index
, OS
);
533 switch (Reloc
.Type
) {
534 case wasm::R_WASM_MEMORY_ADDR_LEB
:
535 case wasm::R_WASM_MEMORY_ADDR_SLEB
:
536 case wasm::R_WASM_MEMORY_ADDR_I32
:
537 case wasm::R_WASM_FUNCTION_OFFSET_I32
:
538 case wasm::R_WASM_SECTION_OFFSET_I32
:
539 encodeULEB128(Reloc
.Addend
, OS
);
544 bool WasmWriter::writeWasm(raw_ostream
&OS
) {
546 OS
.write(wasm::WasmMagic
, sizeof(wasm::WasmMagic
));
547 writeUint32(OS
, Obj
.Header
.Version
);
549 // Write each section
550 llvm::object::WasmSectionOrderChecker Checker
;
551 for (const std::unique_ptr
<WasmYAML::Section
> &Sec
: Obj
.Sections
) {
552 StringRef SecName
= "";
553 if (auto S
= dyn_cast
<WasmYAML::CustomSection
>(Sec
.get()))
555 if (!Checker
.isValidSectionOrder(Sec
->Type
, SecName
)) {
556 reportError("out of order section type: " + Twine(Sec
->Type
));
559 encodeULEB128(Sec
->Type
, OS
);
560 std::string OutString
;
561 raw_string_ostream
StringStream(OutString
);
562 if (auto S
= dyn_cast
<WasmYAML::CustomSection
>(Sec
.get()))
563 writeSectionContent(StringStream
, *S
);
564 else if (auto S
= dyn_cast
<WasmYAML::TypeSection
>(Sec
.get()))
565 writeSectionContent(StringStream
, *S
);
566 else if (auto S
= dyn_cast
<WasmYAML::ImportSection
>(Sec
.get()))
567 writeSectionContent(StringStream
, *S
);
568 else if (auto S
= dyn_cast
<WasmYAML::FunctionSection
>(Sec
.get()))
569 writeSectionContent(StringStream
, *S
);
570 else if (auto S
= dyn_cast
<WasmYAML::TableSection
>(Sec
.get()))
571 writeSectionContent(StringStream
, *S
);
572 else if (auto S
= dyn_cast
<WasmYAML::MemorySection
>(Sec
.get()))
573 writeSectionContent(StringStream
, *S
);
574 else if (auto S
= dyn_cast
<WasmYAML::GlobalSection
>(Sec
.get()))
575 writeSectionContent(StringStream
, *S
);
576 else if (auto S
= dyn_cast
<WasmYAML::EventSection
>(Sec
.get()))
577 writeSectionContent(StringStream
, *S
);
578 else if (auto S
= dyn_cast
<WasmYAML::ExportSection
>(Sec
.get()))
579 writeSectionContent(StringStream
, *S
);
580 else if (auto S
= dyn_cast
<WasmYAML::StartSection
>(Sec
.get()))
581 writeSectionContent(StringStream
, *S
);
582 else if (auto S
= dyn_cast
<WasmYAML::ElemSection
>(Sec
.get()))
583 writeSectionContent(StringStream
, *S
);
584 else if (auto S
= dyn_cast
<WasmYAML::CodeSection
>(Sec
.get()))
585 writeSectionContent(StringStream
, *S
);
586 else if (auto S
= dyn_cast
<WasmYAML::DataSection
>(Sec
.get()))
587 writeSectionContent(StringStream
, *S
);
588 else if (auto S
= dyn_cast
<WasmYAML::DataCountSection
>(Sec
.get()))
589 writeSectionContent(StringStream
, *S
);
591 reportError("unknown section type: " + Twine(Sec
->Type
));
596 StringStream
.flush();
598 // Write the section size followed by the content
599 encodeULEB128(OutString
.size(), OS
);
603 // write reloc sections for any section that have relocations
604 uint32_t SectionIndex
= 0;
605 for (const std::unique_ptr
<WasmYAML::Section
> &Sec
: Obj
.Sections
) {
606 if (Sec
->Relocations
.empty()) {
611 writeUint8(OS
, wasm::WASM_SEC_CUSTOM
);
612 std::string OutString
;
613 raw_string_ostream
StringStream(OutString
);
614 writeRelocSection(StringStream
, *Sec
, SectionIndex
++);
615 StringStream
.flush();
617 encodeULEB128(OutString
.size(), OS
);
627 bool yaml2wasm(WasmYAML::Object
&Doc
, raw_ostream
&Out
, ErrorHandler EH
) {
628 WasmWriter
Writer(Doc
, EH
);
629 return Writer
.writeWasm(Out
);