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
) : Obj(Obj
) {}
29 int writeWasm(raw_ostream
&OS
);
32 int writeRelocSection(raw_ostream
&OS
, WasmYAML::Section
&Sec
,
33 uint32_t SectionIndex
);
35 int writeSectionContent(raw_ostream
&OS
, WasmYAML::CustomSection
&Section
);
36 int writeSectionContent(raw_ostream
&OS
, WasmYAML::TypeSection
&Section
);
37 int writeSectionContent(raw_ostream
&OS
, WasmYAML::ImportSection
&Section
);
38 int writeSectionContent(raw_ostream
&OS
, WasmYAML::FunctionSection
&Section
);
39 int writeSectionContent(raw_ostream
&OS
, WasmYAML::TableSection
&Section
);
40 int writeSectionContent(raw_ostream
&OS
, WasmYAML::MemorySection
&Section
);
41 int writeSectionContent(raw_ostream
&OS
, WasmYAML::GlobalSection
&Section
);
42 int writeSectionContent(raw_ostream
&OS
, WasmYAML::EventSection
&Section
);
43 int writeSectionContent(raw_ostream
&OS
, WasmYAML::ExportSection
&Section
);
44 int writeSectionContent(raw_ostream
&OS
, WasmYAML::StartSection
&Section
);
45 int writeSectionContent(raw_ostream
&OS
, WasmYAML::ElemSection
&Section
);
46 int writeSectionContent(raw_ostream
&OS
, WasmYAML::CodeSection
&Section
);
47 int writeSectionContent(raw_ostream
&OS
, WasmYAML::DataSection
&Section
);
48 int writeSectionContent(raw_ostream
&OS
, WasmYAML::DataCountSection
&Section
);
50 // Custom section types
51 int writeSectionContent(raw_ostream
&OS
, WasmYAML::DylinkSection
&Section
);
52 int writeSectionContent(raw_ostream
&OS
, WasmYAML::NameSection
&Section
);
53 int writeSectionContent(raw_ostream
&OS
, WasmYAML::LinkingSection
&Section
);
54 int writeSectionContent(raw_ostream
&OS
, WasmYAML::ProducersSection
&Section
);
55 int writeSectionContent(raw_ostream
&OS
,
56 WasmYAML::TargetFeaturesSection
&Section
);
57 WasmYAML::Object
&Obj
;
58 uint32_t NumImportedFunctions
= 0;
59 uint32_t NumImportedGlobals
= 0;
60 uint32_t NumImportedEvents
= 0;
63 class SubSectionWriter
{
65 std::string OutString
;
66 raw_string_ostream StringStream
;
69 SubSectionWriter(raw_ostream
&OS
) : OS(OS
), StringStream(OutString
) {}
73 encodeULEB128(OutString
.size(), OS
);
78 raw_ostream
&getStream() { return StringStream
; }
81 } // end anonymous namespace
83 static int writeUint64(raw_ostream
&OS
, uint64_t Value
) {
84 char Data
[sizeof(Value
)];
85 support::endian::write64le(Data
, Value
);
86 OS
.write(Data
, sizeof(Data
));
90 static int writeUint32(raw_ostream
&OS
, uint32_t Value
) {
91 char Data
[sizeof(Value
)];
92 support::endian::write32le(Data
, Value
);
93 OS
.write(Data
, sizeof(Data
));
97 static int writeUint8(raw_ostream
&OS
, uint8_t Value
) {
98 char Data
[sizeof(Value
)];
99 memcpy(Data
, &Value
, sizeof(Data
));
100 OS
.write(Data
, sizeof(Data
));
104 static int writeStringRef(const StringRef
&Str
, raw_ostream
&OS
) {
105 encodeULEB128(Str
.size(), OS
);
110 static int writeLimits(const WasmYAML::Limits
&Lim
, raw_ostream
&OS
) {
111 writeUint8(OS
, Lim
.Flags
);
112 encodeULEB128(Lim
.Initial
, OS
);
113 if (Lim
.Flags
& wasm::WASM_LIMITS_FLAG_HAS_MAX
)
114 encodeULEB128(Lim
.Maximum
, OS
);
118 static int writeInitExpr(const wasm::WasmInitExpr
&InitExpr
, raw_ostream
&OS
) {
119 writeUint8(OS
, InitExpr
.Opcode
);
120 switch (InitExpr
.Opcode
) {
121 case wasm::WASM_OPCODE_I32_CONST
:
122 encodeSLEB128(InitExpr
.Value
.Int32
, OS
);
124 case wasm::WASM_OPCODE_I64_CONST
:
125 encodeSLEB128(InitExpr
.Value
.Int64
, OS
);
127 case wasm::WASM_OPCODE_F32_CONST
:
128 writeUint32(OS
, InitExpr
.Value
.Float32
);
130 case wasm::WASM_OPCODE_F64_CONST
:
131 writeUint64(OS
, InitExpr
.Value
.Float64
);
133 case wasm::WASM_OPCODE_GLOBAL_GET
:
134 encodeULEB128(InitExpr
.Value
.Global
, OS
);
137 errs() << "Unknown opcode in init_expr: " << InitExpr
.Opcode
<< "\n";
140 writeUint8(OS
, wasm::WASM_OPCODE_END
);
144 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
145 WasmYAML::DylinkSection
&Section
) {
146 writeStringRef(Section
.Name
, OS
);
147 encodeULEB128(Section
.MemorySize
, OS
);
148 encodeULEB128(Section
.MemoryAlignment
, OS
);
149 encodeULEB128(Section
.TableSize
, OS
);
150 encodeULEB128(Section
.TableAlignment
, OS
);
151 encodeULEB128(Section
.Needed
.size(), OS
);
152 for (StringRef Needed
: Section
.Needed
) {
153 writeStringRef(Needed
, OS
);
158 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
159 WasmYAML::LinkingSection
&Section
) {
160 writeStringRef(Section
.Name
, OS
);
161 encodeULEB128(Section
.Version
, OS
);
163 SubSectionWriter
SubSection(OS
);
165 // SYMBOL_TABLE subsection
166 if (Section
.SymbolTable
.size()) {
167 writeUint8(OS
, wasm::WASM_SYMBOL_TABLE
);
169 encodeULEB128(Section
.SymbolTable
.size(), SubSection
.getStream());
171 uint32_t SymbolIndex
= 0;
173 for (const WasmYAML::SymbolInfo
&Info
: Section
.SymbolTable
) {
174 assert(Info
.Index
== SymbolIndex
++);
175 writeUint8(SubSection
.getStream(), Info
.Kind
);
176 encodeULEB128(Info
.Flags
, SubSection
.getStream());
178 case wasm::WASM_SYMBOL_TYPE_FUNCTION
:
179 case wasm::WASM_SYMBOL_TYPE_GLOBAL
:
180 case wasm::WASM_SYMBOL_TYPE_EVENT
:
181 encodeULEB128(Info
.ElementIndex
, SubSection
.getStream());
182 if ((Info
.Flags
& wasm::WASM_SYMBOL_UNDEFINED
) == 0 ||
183 (Info
.Flags
& wasm::WASM_SYMBOL_EXPLICIT_NAME
) != 0)
184 writeStringRef(Info
.Name
, SubSection
.getStream());
186 case wasm::WASM_SYMBOL_TYPE_DATA
:
187 writeStringRef(Info
.Name
, SubSection
.getStream());
188 if ((Info
.Flags
& wasm::WASM_SYMBOL_UNDEFINED
) == 0) {
189 encodeULEB128(Info
.DataRef
.Segment
, SubSection
.getStream());
190 encodeULEB128(Info
.DataRef
.Offset
, SubSection
.getStream());
191 encodeULEB128(Info
.DataRef
.Size
, SubSection
.getStream());
194 case wasm::WASM_SYMBOL_TYPE_SECTION
:
195 encodeULEB128(Info
.ElementIndex
, SubSection
.getStream());
198 llvm_unreachable("unexpected kind");
205 // SEGMENT_NAMES subsection
206 if (Section
.SegmentInfos
.size()) {
207 writeUint8(OS
, wasm::WASM_SEGMENT_INFO
);
208 encodeULEB128(Section
.SegmentInfos
.size(), SubSection
.getStream());
209 for (const WasmYAML::SegmentInfo
&SegmentInfo
: Section
.SegmentInfos
) {
210 writeStringRef(SegmentInfo
.Name
, SubSection
.getStream());
211 encodeULEB128(SegmentInfo
.Alignment
, SubSection
.getStream());
212 encodeULEB128(SegmentInfo
.Flags
, SubSection
.getStream());
217 // INIT_FUNCS subsection
218 if (Section
.InitFunctions
.size()) {
219 writeUint8(OS
, wasm::WASM_INIT_FUNCS
);
220 encodeULEB128(Section
.InitFunctions
.size(), SubSection
.getStream());
221 for (const WasmYAML::InitFunction
&Func
: Section
.InitFunctions
) {
222 encodeULEB128(Func
.Priority
, SubSection
.getStream());
223 encodeULEB128(Func
.Symbol
, SubSection
.getStream());
228 // COMDAT_INFO subsection
229 if (Section
.Comdats
.size()) {
230 writeUint8(OS
, wasm::WASM_COMDAT_INFO
);
231 encodeULEB128(Section
.Comdats
.size(), SubSection
.getStream());
232 for (const auto &C
: Section
.Comdats
) {
233 writeStringRef(C
.Name
, SubSection
.getStream());
234 encodeULEB128(0, SubSection
.getStream()); // flags for future use
235 encodeULEB128(C
.Entries
.size(), SubSection
.getStream());
236 for (const WasmYAML::ComdatEntry
&Entry
: C
.Entries
) {
237 writeUint8(SubSection
.getStream(), Entry
.Kind
);
238 encodeULEB128(Entry
.Index
, SubSection
.getStream());
247 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
248 WasmYAML::NameSection
&Section
) {
249 writeStringRef(Section
.Name
, OS
);
250 if (Section
.FunctionNames
.size()) {
251 writeUint8(OS
, wasm::WASM_NAMES_FUNCTION
);
253 SubSectionWriter
SubSection(OS
);
255 encodeULEB128(Section
.FunctionNames
.size(), SubSection
.getStream());
256 for (const WasmYAML::NameEntry
&NameEntry
: Section
.FunctionNames
) {
257 encodeULEB128(NameEntry
.Index
, SubSection
.getStream());
258 writeStringRef(NameEntry
.Name
, SubSection
.getStream());
266 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
267 WasmYAML::ProducersSection
&Section
) {
268 writeStringRef(Section
.Name
, OS
);
269 int Fields
= int(!Section
.Languages
.empty()) + int(!Section
.Tools
.empty()) +
270 int(!Section
.SDKs
.empty());
273 encodeULEB128(Fields
, OS
);
274 for (auto &Field
: {std::make_pair(StringRef("language"), &Section
.Languages
),
275 std::make_pair(StringRef("processed-by"), &Section
.Tools
),
276 std::make_pair(StringRef("sdk"), &Section
.SDKs
)}) {
277 if (Field
.second
->empty())
279 writeStringRef(Field
.first
, OS
);
280 encodeULEB128(Field
.second
->size(), OS
);
281 for (auto &Entry
: *Field
.second
) {
282 writeStringRef(Entry
.Name
, OS
);
283 writeStringRef(Entry
.Version
, OS
);
289 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
290 WasmYAML::TargetFeaturesSection
&Section
) {
291 writeStringRef(Section
.Name
, OS
);
292 encodeULEB128(Section
.Features
.size(), OS
);
293 for (auto &E
: Section
.Features
) {
294 writeUint8(OS
, E
.Prefix
);
295 writeStringRef(E
.Name
, OS
);
300 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
301 WasmYAML::CustomSection
&Section
) {
302 if (auto S
= dyn_cast
<WasmYAML::DylinkSection
>(&Section
)) {
303 if (auto Err
= writeSectionContent(OS
, *S
))
305 } else if (auto S
= dyn_cast
<WasmYAML::NameSection
>(&Section
)) {
306 if (auto Err
= writeSectionContent(OS
, *S
))
308 } else if (auto S
= dyn_cast
<WasmYAML::LinkingSection
>(&Section
)) {
309 if (auto Err
= writeSectionContent(OS
, *S
))
311 } else if (auto S
= dyn_cast
<WasmYAML::ProducersSection
>(&Section
)) {
312 if (auto Err
= writeSectionContent(OS
, *S
))
314 } else if (auto S
= dyn_cast
<WasmYAML::TargetFeaturesSection
>(&Section
)) {
315 if (auto Err
= writeSectionContent(OS
, *S
))
318 writeStringRef(Section
.Name
, OS
);
319 Section
.Payload
.writeAsBinary(OS
);
324 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
325 WasmYAML::TypeSection
&Section
) {
326 encodeULEB128(Section
.Signatures
.size(), OS
);
327 uint32_t ExpectedIndex
= 0;
328 for (const WasmYAML::Signature
&Sig
: Section
.Signatures
) {
329 if (Sig
.Index
!= ExpectedIndex
) {
330 errs() << "Unexpected type index: " << Sig
.Index
<< "\n";
334 writeUint8(OS
, Sig
.Form
);
335 encodeULEB128(Sig
.ParamTypes
.size(), OS
);
336 for (auto ParamType
: Sig
.ParamTypes
)
337 writeUint8(OS
, ParamType
);
338 if (Sig
.ReturnType
== wasm::WASM_TYPE_NORESULT
) {
339 encodeULEB128(0, OS
);
341 encodeULEB128(1, OS
);
342 writeUint8(OS
, Sig
.ReturnType
);
348 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
349 WasmYAML::ImportSection
&Section
) {
350 encodeULEB128(Section
.Imports
.size(), OS
);
351 for (const WasmYAML::Import
&Import
: Section
.Imports
) {
352 writeStringRef(Import
.Module
, OS
);
353 writeStringRef(Import
.Field
, OS
);
354 writeUint8(OS
, Import
.Kind
);
355 switch (Import
.Kind
) {
356 case wasm::WASM_EXTERNAL_FUNCTION
:
357 encodeULEB128(Import
.SigIndex
, OS
);
358 NumImportedFunctions
++;
360 case wasm::WASM_EXTERNAL_GLOBAL
:
361 writeUint8(OS
, Import
.GlobalImport
.Type
);
362 writeUint8(OS
, Import
.GlobalImport
.Mutable
);
363 NumImportedGlobals
++;
365 case wasm::WASM_EXTERNAL_EVENT
:
366 writeUint32(OS
, Import
.EventImport
.Attribute
);
367 writeUint32(OS
, Import
.EventImport
.SigIndex
);
368 NumImportedGlobals
++;
370 case wasm::WASM_EXTERNAL_MEMORY
:
371 writeLimits(Import
.Memory
, OS
);
373 case wasm::WASM_EXTERNAL_TABLE
:
374 writeUint8(OS
, Import
.TableImport
.ElemType
);
375 writeLimits(Import
.TableImport
.TableLimits
, OS
);
378 errs() << "Unknown import type: " << Import
.Kind
<< "\n";
385 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
386 WasmYAML::FunctionSection
&Section
) {
387 encodeULEB128(Section
.FunctionTypes
.size(), OS
);
388 for (uint32_t FuncType
: Section
.FunctionTypes
) {
389 encodeULEB128(FuncType
, OS
);
394 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
395 WasmYAML::ExportSection
&Section
) {
396 encodeULEB128(Section
.Exports
.size(), OS
);
397 for (const WasmYAML::Export
&Export
: Section
.Exports
) {
398 writeStringRef(Export
.Name
, OS
);
399 writeUint8(OS
, Export
.Kind
);
400 encodeULEB128(Export
.Index
, OS
);
405 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
406 WasmYAML::StartSection
&Section
) {
407 encodeULEB128(Section
.StartFunction
, OS
);
411 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
412 WasmYAML::TableSection
&Section
) {
413 encodeULEB128(Section
.Tables
.size(), OS
);
414 for (auto &Table
: Section
.Tables
) {
415 writeUint8(OS
, Table
.ElemType
);
416 writeLimits(Table
.TableLimits
, OS
);
421 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
422 WasmYAML::MemorySection
&Section
) {
423 encodeULEB128(Section
.Memories
.size(), OS
);
424 for (const WasmYAML::Limits
&Mem
: Section
.Memories
) {
425 writeLimits(Mem
, OS
);
430 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
431 WasmYAML::GlobalSection
&Section
) {
432 encodeULEB128(Section
.Globals
.size(), OS
);
433 uint32_t ExpectedIndex
= NumImportedGlobals
;
434 for (auto &Global
: Section
.Globals
) {
435 if (Global
.Index
!= ExpectedIndex
) {
436 errs() << "Unexpected global index: " << Global
.Index
<< "\n";
440 writeUint8(OS
, Global
.Type
);
441 writeUint8(OS
, Global
.Mutable
);
442 writeInitExpr(Global
.InitExpr
, OS
);
447 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
448 WasmYAML::EventSection
&Section
) {
449 encodeULEB128(Section
.Events
.size(), OS
);
450 uint32_t ExpectedIndex
= NumImportedEvents
;
451 for (auto &Event
: Section
.Events
) {
452 if (Event
.Index
!= ExpectedIndex
) {
453 errs() << "Unexpected event index: " << Event
.Index
<< "\n";
457 encodeULEB128(Event
.Attribute
, OS
);
458 encodeULEB128(Event
.SigIndex
, OS
);
463 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
464 WasmYAML::ElemSection
&Section
) {
465 encodeULEB128(Section
.Segments
.size(), OS
);
466 for (auto &Segment
: Section
.Segments
) {
467 encodeULEB128(Segment
.TableIndex
, OS
);
468 writeInitExpr(Segment
.Offset
, OS
);
470 encodeULEB128(Segment
.Functions
.size(), OS
);
471 for (auto &Function
: Segment
.Functions
) {
472 encodeULEB128(Function
, OS
);
478 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
479 WasmYAML::CodeSection
&Section
) {
480 encodeULEB128(Section
.Functions
.size(), OS
);
481 uint32_t ExpectedIndex
= NumImportedFunctions
;
482 for (auto &Func
: Section
.Functions
) {
483 std::string OutString
;
484 raw_string_ostream
StringStream(OutString
);
485 if (Func
.Index
!= ExpectedIndex
) {
486 errs() << "Unexpected function index: " << Func
.Index
<< "\n";
491 encodeULEB128(Func
.Locals
.size(), StringStream
);
492 for (auto &LocalDecl
: Func
.Locals
) {
493 encodeULEB128(LocalDecl
.Count
, StringStream
);
494 writeUint8(StringStream
, LocalDecl
.Type
);
497 Func
.Body
.writeAsBinary(StringStream
);
499 // Write the section size followed by the content
500 StringStream
.flush();
501 encodeULEB128(OutString
.size(), OS
);
507 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
508 WasmYAML::DataSection
&Section
) {
509 encodeULEB128(Section
.Segments
.size(), OS
);
510 for (auto &Segment
: Section
.Segments
) {
511 encodeULEB128(Segment
.InitFlags
, OS
);
512 if (Segment
.InitFlags
& wasm::WASM_SEGMENT_HAS_MEMINDEX
)
513 encodeULEB128(Segment
.MemoryIndex
, OS
);
514 if ((Segment
.InitFlags
& wasm::WASM_SEGMENT_IS_PASSIVE
) == 0)
515 writeInitExpr(Segment
.Offset
, OS
);
516 encodeULEB128(Segment
.Content
.binary_size(), OS
);
517 Segment
.Content
.writeAsBinary(OS
);
522 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
523 WasmYAML::DataCountSection
&Section
) {
524 encodeULEB128(Section
.Count
, OS
);
528 int WasmWriter::writeRelocSection(raw_ostream
&OS
, WasmYAML::Section
&Sec
,
529 uint32_t SectionIndex
) {
531 case wasm::WASM_SEC_CODE
:
532 writeStringRef("reloc.CODE", OS
);
534 case wasm::WASM_SEC_DATA
:
535 writeStringRef("reloc.DATA", OS
);
537 case wasm::WASM_SEC_CUSTOM
: {
538 auto CustomSection
= dyn_cast
<WasmYAML::CustomSection
>(&Sec
);
539 writeStringRef(("reloc." + CustomSection
->Name
).str(), OS
);
543 llvm_unreachable("not yet implemented");
547 encodeULEB128(SectionIndex
, OS
);
548 encodeULEB128(Sec
.Relocations
.size(), OS
);
550 for (auto Reloc
: Sec
.Relocations
) {
551 writeUint8(OS
, Reloc
.Type
);
552 encodeULEB128(Reloc
.Offset
, OS
);
553 encodeULEB128(Reloc
.Index
, OS
);
554 switch (Reloc
.Type
) {
555 case wasm::R_WASM_MEMORY_ADDR_LEB
:
556 case wasm::R_WASM_MEMORY_ADDR_SLEB
:
557 case wasm::R_WASM_MEMORY_ADDR_I32
:
558 case wasm::R_WASM_FUNCTION_OFFSET_I32
:
559 case wasm::R_WASM_SECTION_OFFSET_I32
:
560 encodeULEB128(Reloc
.Addend
, OS
);
566 int WasmWriter::writeWasm(raw_ostream
&OS
) {
568 OS
.write(wasm::WasmMagic
, sizeof(wasm::WasmMagic
));
569 writeUint32(OS
, Obj
.Header
.Version
);
571 // Write each section
572 llvm::object::WasmSectionOrderChecker Checker
;
573 for (const std::unique_ptr
<WasmYAML::Section
> &Sec
: Obj
.Sections
) {
574 StringRef SecName
= "";
575 if (auto S
= dyn_cast
<WasmYAML::CustomSection
>(Sec
.get()))
577 if (!Checker
.isValidSectionOrder(Sec
->Type
, SecName
)) {
578 errs() << "Out of order section type: " << Sec
->Type
<< "\n";
581 encodeULEB128(Sec
->Type
, OS
);
582 std::string OutString
;
583 raw_string_ostream
StringStream(OutString
);
584 if (auto S
= dyn_cast
<WasmYAML::CustomSection
>(Sec
.get())) {
585 if (auto Err
= writeSectionContent(StringStream
, *S
))
587 } else if (auto S
= dyn_cast
<WasmYAML::TypeSection
>(Sec
.get())) {
588 if (auto Err
= writeSectionContent(StringStream
, *S
))
590 } else if (auto S
= dyn_cast
<WasmYAML::ImportSection
>(Sec
.get())) {
591 if (auto Err
= writeSectionContent(StringStream
, *S
))
593 } else if (auto S
= dyn_cast
<WasmYAML::FunctionSection
>(Sec
.get())) {
594 if (auto Err
= writeSectionContent(StringStream
, *S
))
596 } else if (auto S
= dyn_cast
<WasmYAML::TableSection
>(Sec
.get())) {
597 if (auto Err
= writeSectionContent(StringStream
, *S
))
599 } else if (auto S
= dyn_cast
<WasmYAML::MemorySection
>(Sec
.get())) {
600 if (auto Err
= writeSectionContent(StringStream
, *S
))
602 } else if (auto S
= dyn_cast
<WasmYAML::GlobalSection
>(Sec
.get())) {
603 if (auto Err
= writeSectionContent(StringStream
, *S
))
605 } else if (auto S
= dyn_cast
<WasmYAML::EventSection
>(Sec
.get())) {
606 if (auto Err
= writeSectionContent(StringStream
, *S
))
608 } else if (auto S
= dyn_cast
<WasmYAML::ExportSection
>(Sec
.get())) {
609 if (auto Err
= writeSectionContent(StringStream
, *S
))
611 } else if (auto S
= dyn_cast
<WasmYAML::StartSection
>(Sec
.get())) {
612 if (auto Err
= writeSectionContent(StringStream
, *S
))
614 } else if (auto S
= dyn_cast
<WasmYAML::ElemSection
>(Sec
.get())) {
615 if (auto Err
= writeSectionContent(StringStream
, *S
))
617 } else if (auto S
= dyn_cast
<WasmYAML::CodeSection
>(Sec
.get())) {
618 if (auto Err
= writeSectionContent(StringStream
, *S
))
620 } else if (auto S
= dyn_cast
<WasmYAML::DataSection
>(Sec
.get())) {
621 if (auto Err
= writeSectionContent(StringStream
, *S
))
623 } else if (auto S
= dyn_cast
<WasmYAML::DataCountSection
>(Sec
.get())) {
624 if (auto Err
= writeSectionContent(StringStream
, *S
))
627 errs() << "Unknown section type: " << Sec
->Type
<< "\n";
630 StringStream
.flush();
632 // Write the section size followed by the content
633 encodeULEB128(OutString
.size(), OS
);
637 // write reloc sections for any section that have relocations
638 uint32_t SectionIndex
= 0;
639 for (const std::unique_ptr
<WasmYAML::Section
> &Sec
: Obj
.Sections
) {
640 if (Sec
->Relocations
.empty()) {
645 writeUint8(OS
, wasm::WASM_SEC_CUSTOM
);
646 std::string OutString
;
647 raw_string_ostream
StringStream(OutString
);
648 writeRelocSection(StringStream
, *Sec
, SectionIndex
++);
649 StringStream
.flush();
651 encodeULEB128(OutString
.size(), OS
);
661 int yaml2wasm(WasmYAML::Object
&Doc
, raw_ostream
&Out
) {
662 WasmWriter
Writer(Doc
);
664 return Writer
.writeWasm(Out
);