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/Support/Endian.h"
18 #include "llvm/Support/LEB128.h"
22 /// This parses a yaml stream that represents a Wasm object file.
23 /// See docs/yaml2obj for the yaml scheema.
26 WasmWriter(WasmYAML::Object
&Obj
) : Obj(Obj
) {}
27 int writeWasm(raw_ostream
&OS
);
30 int writeRelocSection(raw_ostream
&OS
, WasmYAML::Section
&Sec
,
31 uint32_t SectionIndex
);
33 int writeSectionContent(raw_ostream
&OS
, WasmYAML::CustomSection
&Section
);
34 int writeSectionContent(raw_ostream
&OS
, WasmYAML::TypeSection
&Section
);
35 int writeSectionContent(raw_ostream
&OS
, WasmYAML::ImportSection
&Section
);
36 int writeSectionContent(raw_ostream
&OS
, WasmYAML::FunctionSection
&Section
);
37 int writeSectionContent(raw_ostream
&OS
, WasmYAML::TableSection
&Section
);
38 int writeSectionContent(raw_ostream
&OS
, WasmYAML::MemorySection
&Section
);
39 int writeSectionContent(raw_ostream
&OS
, WasmYAML::GlobalSection
&Section
);
40 int writeSectionContent(raw_ostream
&OS
, WasmYAML::EventSection
&Section
);
41 int writeSectionContent(raw_ostream
&OS
, WasmYAML::ExportSection
&Section
);
42 int writeSectionContent(raw_ostream
&OS
, WasmYAML::StartSection
&Section
);
43 int writeSectionContent(raw_ostream
&OS
, WasmYAML::ElemSection
&Section
);
44 int writeSectionContent(raw_ostream
&OS
, WasmYAML::CodeSection
&Section
);
45 int writeSectionContent(raw_ostream
&OS
, WasmYAML::DataSection
&Section
);
47 // Custom section types
48 int writeSectionContent(raw_ostream
&OS
, WasmYAML::DylinkSection
&Section
);
49 int writeSectionContent(raw_ostream
&OS
, WasmYAML::NameSection
&Section
);
50 int writeSectionContent(raw_ostream
&OS
, WasmYAML::LinkingSection
&Section
);
51 int writeSectionContent(raw_ostream
&OS
, WasmYAML::ProducersSection
&Section
);
52 WasmYAML::Object
&Obj
;
53 uint32_t NumImportedFunctions
= 0;
54 uint32_t NumImportedGlobals
= 0;
55 uint32_t NumImportedEvents
= 0;
58 static int writeUint64(raw_ostream
&OS
, uint64_t Value
) {
59 char Data
[sizeof(Value
)];
60 support::endian::write64le(Data
, Value
);
61 OS
.write(Data
, sizeof(Data
));
65 static int writeUint32(raw_ostream
&OS
, uint32_t Value
) {
66 char Data
[sizeof(Value
)];
67 support::endian::write32le(Data
, Value
);
68 OS
.write(Data
, sizeof(Data
));
72 static int writeUint8(raw_ostream
&OS
, uint8_t Value
) {
73 char Data
[sizeof(Value
)];
74 memcpy(Data
, &Value
, sizeof(Data
));
75 OS
.write(Data
, sizeof(Data
));
79 static int writeStringRef(const StringRef
&Str
, raw_ostream
&OS
) {
80 encodeULEB128(Str
.size(), OS
);
85 static int writeLimits(const WasmYAML::Limits
&Lim
, raw_ostream
&OS
) {
86 writeUint8(OS
, Lim
.Flags
);
87 encodeULEB128(Lim
.Initial
, OS
);
88 if (Lim
.Flags
& wasm::WASM_LIMITS_FLAG_HAS_MAX
)
89 encodeULEB128(Lim
.Maximum
, OS
);
93 static int writeInitExpr(const wasm::WasmInitExpr
&InitExpr
, raw_ostream
&OS
) {
94 writeUint8(OS
, InitExpr
.Opcode
);
95 switch (InitExpr
.Opcode
) {
96 case wasm::WASM_OPCODE_I32_CONST
:
97 encodeSLEB128(InitExpr
.Value
.Int32
, OS
);
99 case wasm::WASM_OPCODE_I64_CONST
:
100 encodeSLEB128(InitExpr
.Value
.Int64
, OS
);
102 case wasm::WASM_OPCODE_F32_CONST
:
103 writeUint32(OS
, InitExpr
.Value
.Float32
);
105 case wasm::WASM_OPCODE_F64_CONST
:
106 writeUint64(OS
, InitExpr
.Value
.Float64
);
108 case wasm::WASM_OPCODE_GLOBAL_GET
:
109 encodeULEB128(InitExpr
.Value
.Global
, OS
);
112 errs() << "Unknown opcode in init_expr: " << InitExpr
.Opcode
<< "\n";
115 writeUint8(OS
, wasm::WASM_OPCODE_END
);
119 class SubSectionWriter
{
121 std::string OutString
;
122 raw_string_ostream StringStream
;
125 SubSectionWriter(raw_ostream
&OS
) : OS(OS
), StringStream(OutString
) {}
128 StringStream
.flush();
129 encodeULEB128(OutString
.size(), OS
);
134 raw_ostream
&GetStream() { return StringStream
; }
137 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
138 WasmYAML::DylinkSection
&Section
) {
139 writeStringRef(Section
.Name
, OS
);
140 encodeULEB128(Section
.MemorySize
, OS
);
141 encodeULEB128(Section
.MemoryAlignment
, OS
);
142 encodeULEB128(Section
.TableSize
, OS
);
143 encodeULEB128(Section
.TableAlignment
, OS
);
144 encodeULEB128(Section
.Needed
.size(), OS
);
145 for (StringRef Needed
: Section
.Needed
) {
146 writeStringRef(Needed
, OS
);
151 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
152 WasmYAML::LinkingSection
&Section
) {
153 writeStringRef(Section
.Name
, OS
);
154 encodeULEB128(Section
.Version
, OS
);
156 SubSectionWriter
SubSection(OS
);
158 // SYMBOL_TABLE subsection
159 if (Section
.SymbolTable
.size()) {
160 writeUint8(OS
, wasm::WASM_SYMBOL_TABLE
);
162 encodeULEB128(Section
.SymbolTable
.size(), SubSection
.GetStream());
164 uint32_t SymbolIndex
= 0;
166 for (const WasmYAML::SymbolInfo
&Info
: Section
.SymbolTable
) {
167 assert(Info
.Index
== SymbolIndex
++);
168 writeUint8(SubSection
.GetStream(), Info
.Kind
);
169 encodeULEB128(Info
.Flags
, SubSection
.GetStream());
171 case wasm::WASM_SYMBOL_TYPE_FUNCTION
:
172 case wasm::WASM_SYMBOL_TYPE_GLOBAL
:
173 case wasm::WASM_SYMBOL_TYPE_EVENT
:
174 encodeULEB128(Info
.ElementIndex
, SubSection
.GetStream());
175 if ((Info
.Flags
& wasm::WASM_SYMBOL_UNDEFINED
) == 0)
176 writeStringRef(Info
.Name
, SubSection
.GetStream());
178 case wasm::WASM_SYMBOL_TYPE_DATA
:
179 writeStringRef(Info
.Name
, SubSection
.GetStream());
180 if ((Info
.Flags
& wasm::WASM_SYMBOL_UNDEFINED
) == 0) {
181 encodeULEB128(Info
.DataRef
.Segment
, SubSection
.GetStream());
182 encodeULEB128(Info
.DataRef
.Offset
, SubSection
.GetStream());
183 encodeULEB128(Info
.DataRef
.Size
, SubSection
.GetStream());
186 case wasm::WASM_SYMBOL_TYPE_SECTION
:
187 encodeULEB128(Info
.ElementIndex
, SubSection
.GetStream());
190 llvm_unreachable("unexpected kind");
197 // SEGMENT_NAMES subsection
198 if (Section
.SegmentInfos
.size()) {
199 writeUint8(OS
, wasm::WASM_SEGMENT_INFO
);
200 encodeULEB128(Section
.SegmentInfos
.size(), SubSection
.GetStream());
201 for (const WasmYAML::SegmentInfo
&SegmentInfo
: Section
.SegmentInfos
) {
202 writeStringRef(SegmentInfo
.Name
, SubSection
.GetStream());
203 encodeULEB128(SegmentInfo
.Alignment
, SubSection
.GetStream());
204 encodeULEB128(SegmentInfo
.Flags
, SubSection
.GetStream());
209 // INIT_FUNCS subsection
210 if (Section
.InitFunctions
.size()) {
211 writeUint8(OS
, wasm::WASM_INIT_FUNCS
);
212 encodeULEB128(Section
.InitFunctions
.size(), SubSection
.GetStream());
213 for (const WasmYAML::InitFunction
&Func
: Section
.InitFunctions
) {
214 encodeULEB128(Func
.Priority
, SubSection
.GetStream());
215 encodeULEB128(Func
.Symbol
, SubSection
.GetStream());
220 // COMDAT_INFO subsection
221 if (Section
.Comdats
.size()) {
222 writeUint8(OS
, wasm::WASM_COMDAT_INFO
);
223 encodeULEB128(Section
.Comdats
.size(), SubSection
.GetStream());
224 for (const auto &C
: Section
.Comdats
) {
225 writeStringRef(C
.Name
, SubSection
.GetStream());
226 encodeULEB128(0, SubSection
.GetStream()); // flags for future use
227 encodeULEB128(C
.Entries
.size(), SubSection
.GetStream());
228 for (const WasmYAML::ComdatEntry
&Entry
: C
.Entries
) {
229 writeUint8(SubSection
.GetStream(), Entry
.Kind
);
230 encodeULEB128(Entry
.Index
, SubSection
.GetStream());
239 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
240 WasmYAML::NameSection
&Section
) {
241 writeStringRef(Section
.Name
, OS
);
242 if (Section
.FunctionNames
.size()) {
243 writeUint8(OS
, wasm::WASM_NAMES_FUNCTION
);
245 SubSectionWriter
SubSection(OS
);
247 encodeULEB128(Section
.FunctionNames
.size(), SubSection
.GetStream());
248 for (const WasmYAML::NameEntry
&NameEntry
: Section
.FunctionNames
) {
249 encodeULEB128(NameEntry
.Index
, SubSection
.GetStream());
250 writeStringRef(NameEntry
.Name
, SubSection
.GetStream());
258 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
259 WasmYAML::ProducersSection
&Section
) {
260 writeStringRef(Section
.Name
, OS
);
261 int Fields
= int(!Section
.Languages
.empty()) + int(!Section
.Tools
.empty()) +
262 int(!Section
.SDKs
.empty());
265 encodeULEB128(Fields
, OS
);
266 for (auto &Field
: {std::make_pair(StringRef("language"), &Section
.Languages
),
267 std::make_pair(StringRef("processed-by"), &Section
.Tools
),
268 std::make_pair(StringRef("sdk"), &Section
.SDKs
)}) {
269 if (Field
.second
->empty())
271 writeStringRef(Field
.first
, OS
);
272 encodeULEB128(Field
.second
->size(), OS
);
273 for (auto &Entry
: *Field
.second
) {
274 writeStringRef(Entry
.Name
, OS
);
275 writeStringRef(Entry
.Version
, OS
);
281 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
282 WasmYAML::CustomSection
&Section
) {
283 if (auto S
= dyn_cast
<WasmYAML::DylinkSection
>(&Section
)) {
284 if (auto Err
= writeSectionContent(OS
, *S
))
286 } else if (auto S
= dyn_cast
<WasmYAML::NameSection
>(&Section
)) {
287 if (auto Err
= writeSectionContent(OS
, *S
))
289 } else if (auto S
= dyn_cast
<WasmYAML::LinkingSection
>(&Section
)) {
290 if (auto Err
= writeSectionContent(OS
, *S
))
292 } else if (auto S
= dyn_cast
<WasmYAML::ProducersSection
>(&Section
)) {
293 if (auto Err
= writeSectionContent(OS
, *S
))
296 writeStringRef(Section
.Name
, OS
);
297 Section
.Payload
.writeAsBinary(OS
);
302 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
303 WasmYAML::TypeSection
&Section
) {
304 encodeULEB128(Section
.Signatures
.size(), OS
);
305 uint32_t ExpectedIndex
= 0;
306 for (const WasmYAML::Signature
&Sig
: Section
.Signatures
) {
307 if (Sig
.Index
!= ExpectedIndex
) {
308 errs() << "Unexpected type index: " << Sig
.Index
<< "\n";
312 writeUint8(OS
, Sig
.Form
);
313 encodeULEB128(Sig
.ParamTypes
.size(), OS
);
314 for (auto ParamType
: Sig
.ParamTypes
)
315 writeUint8(OS
, ParamType
);
316 if (Sig
.ReturnType
== wasm::WASM_TYPE_NORESULT
) {
317 encodeULEB128(0, OS
);
319 encodeULEB128(1, OS
);
320 writeUint8(OS
, Sig
.ReturnType
);
326 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
327 WasmYAML::ImportSection
&Section
) {
328 encodeULEB128(Section
.Imports
.size(), OS
);
329 for (const WasmYAML::Import
&Import
: Section
.Imports
) {
330 writeStringRef(Import
.Module
, OS
);
331 writeStringRef(Import
.Field
, OS
);
332 writeUint8(OS
, Import
.Kind
);
333 switch (Import
.Kind
) {
334 case wasm::WASM_EXTERNAL_FUNCTION
:
335 encodeULEB128(Import
.SigIndex
, OS
);
336 NumImportedFunctions
++;
338 case wasm::WASM_EXTERNAL_GLOBAL
:
339 writeUint8(OS
, Import
.GlobalImport
.Type
);
340 writeUint8(OS
, Import
.GlobalImport
.Mutable
);
341 NumImportedGlobals
++;
343 case wasm::WASM_EXTERNAL_EVENT
:
344 writeUint32(OS
, Import
.EventImport
.Attribute
);
345 writeUint32(OS
, Import
.EventImport
.SigIndex
);
346 NumImportedGlobals
++;
348 case wasm::WASM_EXTERNAL_MEMORY
:
349 writeLimits(Import
.Memory
, OS
);
351 case wasm::WASM_EXTERNAL_TABLE
:
352 writeUint8(OS
, Import
.TableImport
.ElemType
);
353 writeLimits(Import
.TableImport
.TableLimits
, OS
);
356 errs() << "Unknown import type: " << Import
.Kind
<< "\n";
363 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
364 WasmYAML::FunctionSection
&Section
) {
365 encodeULEB128(Section
.FunctionTypes
.size(), OS
);
366 for (uint32_t FuncType
: Section
.FunctionTypes
) {
367 encodeULEB128(FuncType
, OS
);
372 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
373 WasmYAML::ExportSection
&Section
) {
374 encodeULEB128(Section
.Exports
.size(), OS
);
375 for (const WasmYAML::Export
&Export
: Section
.Exports
) {
376 writeStringRef(Export
.Name
, OS
);
377 writeUint8(OS
, Export
.Kind
);
378 encodeULEB128(Export
.Index
, OS
);
383 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
384 WasmYAML::StartSection
&Section
) {
385 encodeULEB128(Section
.StartFunction
, OS
);
389 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
390 WasmYAML::TableSection
&Section
) {
391 encodeULEB128(Section
.Tables
.size(), OS
);
392 for (auto &Table
: Section
.Tables
) {
393 writeUint8(OS
, Table
.ElemType
);
394 writeLimits(Table
.TableLimits
, OS
);
399 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
400 WasmYAML::MemorySection
&Section
) {
401 encodeULEB128(Section
.Memories
.size(), OS
);
402 for (const WasmYAML::Limits
&Mem
: Section
.Memories
) {
403 writeLimits(Mem
, OS
);
408 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
409 WasmYAML::GlobalSection
&Section
) {
410 encodeULEB128(Section
.Globals
.size(), OS
);
411 uint32_t ExpectedIndex
= NumImportedGlobals
;
412 for (auto &Global
: Section
.Globals
) {
413 if (Global
.Index
!= ExpectedIndex
) {
414 errs() << "Unexpected global index: " << Global
.Index
<< "\n";
418 writeUint8(OS
, Global
.Type
);
419 writeUint8(OS
, Global
.Mutable
);
420 writeInitExpr(Global
.InitExpr
, OS
);
425 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
426 WasmYAML::EventSection
&Section
) {
427 encodeULEB128(Section
.Events
.size(), OS
);
428 uint32_t ExpectedIndex
= NumImportedEvents
;
429 for (auto &Event
: Section
.Events
) {
430 if (Event
.Index
!= ExpectedIndex
) {
431 errs() << "Unexpected event index: " << Event
.Index
<< "\n";
435 encodeULEB128(Event
.Attribute
, OS
);
436 encodeULEB128(Event
.SigIndex
, OS
);
441 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
442 WasmYAML::ElemSection
&Section
) {
443 encodeULEB128(Section
.Segments
.size(), OS
);
444 for (auto &Segment
: Section
.Segments
) {
445 encodeULEB128(Segment
.TableIndex
, OS
);
446 writeInitExpr(Segment
.Offset
, OS
);
448 encodeULEB128(Segment
.Functions
.size(), OS
);
449 for (auto &Function
: Segment
.Functions
) {
450 encodeULEB128(Function
, OS
);
456 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
457 WasmYAML::CodeSection
&Section
) {
458 encodeULEB128(Section
.Functions
.size(), OS
);
459 uint32_t ExpectedIndex
= NumImportedFunctions
;
460 for (auto &Func
: Section
.Functions
) {
461 std::string OutString
;
462 raw_string_ostream
StringStream(OutString
);
463 if (Func
.Index
!= ExpectedIndex
) {
464 errs() << "Unexpected function index: " << Func
.Index
<< "\n";
469 encodeULEB128(Func
.Locals
.size(), StringStream
);
470 for (auto &LocalDecl
: Func
.Locals
) {
471 encodeULEB128(LocalDecl
.Count
, StringStream
);
472 writeUint8(StringStream
, LocalDecl
.Type
);
475 Func
.Body
.writeAsBinary(StringStream
);
477 // Write the section size followed by the content
478 StringStream
.flush();
479 encodeULEB128(OutString
.size(), OS
);
485 int WasmWriter::writeSectionContent(raw_ostream
&OS
,
486 WasmYAML::DataSection
&Section
) {
487 encodeULEB128(Section
.Segments
.size(), OS
);
488 for (auto &Segment
: Section
.Segments
) {
489 encodeULEB128(Segment
.MemoryIndex
, OS
);
490 writeInitExpr(Segment
.Offset
, OS
);
491 encodeULEB128(Segment
.Content
.binary_size(), OS
);
492 Segment
.Content
.writeAsBinary(OS
);
497 int WasmWriter::writeRelocSection(raw_ostream
&OS
, WasmYAML::Section
&Sec
,
498 uint32_t SectionIndex
) {
500 case wasm::WASM_SEC_CODE
:
501 writeStringRef("reloc.CODE", OS
);
503 case wasm::WASM_SEC_DATA
:
504 writeStringRef("reloc.DATA", OS
);
506 case wasm::WASM_SEC_CUSTOM
: {
507 auto CustomSection
= dyn_cast
<WasmYAML::CustomSection
>(&Sec
);
508 if (!CustomSection
->Name
.startswith(".debug_")) {
509 llvm_unreachable("not yet implemented (only for debug sections)");
513 writeStringRef(("reloc." + CustomSection
->Name
).str(), OS
);
517 llvm_unreachable("not yet implemented");
521 encodeULEB128(SectionIndex
, OS
);
522 encodeULEB128(Sec
.Relocations
.size(), OS
);
524 for (auto Reloc
: Sec
.Relocations
) {
525 writeUint8(OS
, Reloc
.Type
);
526 encodeULEB128(Reloc
.Offset
, OS
);
527 encodeULEB128(Reloc
.Index
, OS
);
528 switch (Reloc
.Type
) {
529 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB
:
530 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB
:
531 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32
:
532 case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32
:
533 case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32
:
534 encodeULEB128(Reloc
.Addend
, OS
);
540 int WasmWriter::writeWasm(raw_ostream
&OS
) {
542 OS
.write(wasm::WasmMagic
, sizeof(wasm::WasmMagic
));
543 writeUint32(OS
, Obj
.Header
.Version
);
545 // Write each section
546 llvm::object::WasmSectionOrderChecker Checker
;
547 for (const std::unique_ptr
<WasmYAML::Section
> &Sec
: Obj
.Sections
) {
548 StringRef SecName
= "";
549 if (auto S
= dyn_cast
<WasmYAML::CustomSection
>(Sec
.get()))
551 if (!Checker
.isValidSectionOrder(Sec
->Type
, SecName
)) {
552 errs() << "Out of order section type: " << Sec
->Type
<< "\n";
555 encodeULEB128(Sec
->Type
, OS
);
556 std::string OutString
;
557 raw_string_ostream
StringStream(OutString
);
558 if (auto S
= dyn_cast
<WasmYAML::CustomSection
>(Sec
.get())) {
559 if (auto Err
= writeSectionContent(StringStream
, *S
))
561 } else if (auto S
= dyn_cast
<WasmYAML::TypeSection
>(Sec
.get())) {
562 if (auto Err
= writeSectionContent(StringStream
, *S
))
564 } else if (auto S
= dyn_cast
<WasmYAML::ImportSection
>(Sec
.get())) {
565 if (auto Err
= writeSectionContent(StringStream
, *S
))
567 } else if (auto S
= dyn_cast
<WasmYAML::FunctionSection
>(Sec
.get())) {
568 if (auto Err
= writeSectionContent(StringStream
, *S
))
570 } else if (auto S
= dyn_cast
<WasmYAML::TableSection
>(Sec
.get())) {
571 if (auto Err
= writeSectionContent(StringStream
, *S
))
573 } else if (auto S
= dyn_cast
<WasmYAML::MemorySection
>(Sec
.get())) {
574 if (auto Err
= writeSectionContent(StringStream
, *S
))
576 } else if (auto S
= dyn_cast
<WasmYAML::GlobalSection
>(Sec
.get())) {
577 if (auto Err
= writeSectionContent(StringStream
, *S
))
579 } else if (auto S
= dyn_cast
<WasmYAML::EventSection
>(Sec
.get())) {
580 if (auto Err
= writeSectionContent(StringStream
, *S
))
582 } else if (auto S
= dyn_cast
<WasmYAML::ExportSection
>(Sec
.get())) {
583 if (auto Err
= writeSectionContent(StringStream
, *S
))
585 } else if (auto S
= dyn_cast
<WasmYAML::StartSection
>(Sec
.get())) {
586 if (auto Err
= writeSectionContent(StringStream
, *S
))
588 } else if (auto S
= dyn_cast
<WasmYAML::ElemSection
>(Sec
.get())) {
589 if (auto Err
= writeSectionContent(StringStream
, *S
))
591 } else if (auto S
= dyn_cast
<WasmYAML::CodeSection
>(Sec
.get())) {
592 if (auto Err
= writeSectionContent(StringStream
, *S
))
594 } else if (auto S
= dyn_cast
<WasmYAML::DataSection
>(Sec
.get())) {
595 if (auto Err
= writeSectionContent(StringStream
, *S
))
598 errs() << "Unknown section type: " << Sec
->Type
<< "\n";
601 StringStream
.flush();
603 // Write the section size followed by the content
604 encodeULEB128(OutString
.size(), OS
);
608 // write reloc sections for any section that have relocations
609 uint32_t SectionIndex
= 0;
610 for (const std::unique_ptr
<WasmYAML::Section
> &Sec
: Obj
.Sections
) {
611 if (Sec
->Relocations
.empty()) {
616 writeUint8(OS
, wasm::WASM_SEC_CUSTOM
);
617 std::string OutString
;
618 raw_string_ostream
StringStream(OutString
);
619 writeRelocSection(StringStream
, *Sec
, SectionIndex
++);
620 StringStream
.flush();
622 encodeULEB128(OutString
.size(), OS
);
629 int yaml2wasm(llvm::WasmYAML::Object
&Doc
, raw_ostream
&Out
) {
630 WasmWriter
Writer(Doc
);
632 return Writer
.writeWasm(Out
);