1 //===- WasmYAML.h - Wasm YAMLIO implementation ------------------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file declares classes for handling the YAML representation
11 /// of wasm binaries.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_OBJECTYAML_WASMYAML_H
16 #define LLVM_OBJECTYAML_WASMYAML_H
17
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/BinaryFormat/Wasm.h"
20 #include "llvm/ObjectYAML/YAML.h"
21 #include "llvm/Support/Casting.h"
22 #include <cstdint>
23 #include <memory>
24 #include <vector>
25
26 namespace llvm {
27 namespace WasmYAML {
28
29 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SectionType)
30 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ValueType)
31 LLVM_YAML_STRONG_TYPEDEF(uint32_t, TableType)
32 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SignatureForm)
33 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ExportKind)
34 LLVM_YAML_STRONG_TYPEDEF(uint32_t, Opcode)
35 LLVM_YAML_STRONG_TYPEDEF(uint32_t, RelocType)
36 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SymbolFlags)
37 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SymbolKind)
38 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SegmentFlags)
39 LLVM_YAML_STRONG_TYPEDEF(uint32_t, LimitFlags)
40 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ComdatKind)
41 LLVM_YAML_STRONG_TYPEDEF(uint32_t, FeaturePolicyPrefix)
42
43 struct FileHeader {
44 yaml::Hex32 Version;
45 };
46
47 struct Limits {
48 LimitFlags Flags;
49 yaml::Hex32 Minimum;
50 yaml::Hex32 Maximum;
51 };
52
53 struct Table {
54 TableType ElemType;
55 Limits TableLimits;
56 uint32_t Index;
57 };
58
59 struct Export {
60 StringRef Name;
61 ExportKind Kind;
62 uint32_t Index;
63 };
64
65 struct InitExpr {
InitExprInitExpr66 InitExpr() {}
67 bool Extended;
68 union {
69 wasm::WasmInitExprMVP Inst;
70 yaml::BinaryRef Body;
71 };
72 };
73
74 struct ElemSegment {
75 uint32_t Flags;
76 uint32_t TableNumber;
77 ValueType ElemKind;
78 InitExpr Offset;
79 std::vector<uint32_t> Functions;
80 };
81
82 struct Global {
83 uint32_t Index;
84 ValueType Type;
85 bool Mutable;
86 InitExpr Init;
87 };
88
89 struct Import {
ImportImport90 Import() {}
91 StringRef Module;
92 StringRef Field;
93 ExportKind Kind;
94 union {
95 uint32_t SigIndex;
96 Table TableImport;
97 Limits Memory;
98 uint32_t TagIndex;
99 Global GlobalImport;
100 };
101 };
102
103 struct LocalDecl {
104 ValueType Type;
105 uint32_t Count;
106 };
107
108 struct Function {
109 uint32_t Index;
110 std::vector<LocalDecl> Locals;
111 yaml::BinaryRef Body;
112 };
113
114 struct Relocation {
115 RelocType Type;
116 uint32_t Index;
117 // TODO(wvo): this would strictly be better as Hex64, but that will change
118 // all existing obj2yaml output.
119 yaml::Hex32 Offset;
120 int64_t Addend;
121 };
122
123 struct DataSegment {
124 uint32_t SectionOffset;
125 uint32_t InitFlags;
126 uint32_t MemoryIndex;
127 InitExpr Offset;
128 yaml::BinaryRef Content;
129 };
130
131 struct NameEntry {
132 uint32_t Index;
133 StringRef Name;
134 };
135
136 struct ProducerEntry {
137 std::string Name;
138 std::string Version;
139 };
140
141 struct FeatureEntry {
142 FeaturePolicyPrefix Prefix;
143 std::string Name;
144 };
145
146 struct SegmentInfo {
147 uint32_t Index;
148 StringRef Name;
149 uint32_t Alignment;
150 SegmentFlags Flags;
151 };
152
153 struct Signature {
154 uint32_t Index;
155 SignatureForm Form = wasm::WASM_TYPE_FUNC;
156 std::vector<ValueType> ParamTypes;
157 std::vector<ValueType> ReturnTypes;
158 };
159
160 struct SymbolInfo {
161 uint32_t Index;
162 StringRef Name;
163 SymbolKind Kind;
164 SymbolFlags Flags;
165 union {
166 uint32_t ElementIndex;
167 wasm::WasmDataReference DataRef;
168 };
169 };
170
171 struct InitFunction {
172 uint32_t Priority;
173 uint32_t Symbol;
174 };
175
176 struct ComdatEntry {
177 ComdatKind Kind;
178 uint32_t Index;
179 };
180
181 struct Comdat {
182 StringRef Name;
183 std::vector<ComdatEntry> Entries;
184 };
185
186 struct Section {
SectionSection187 explicit Section(SectionType SecType) : Type(SecType) {}
188 virtual ~Section();
189
190 SectionType Type;
191 std::vector<Relocation> Relocations;
192 };
193
194 struct CustomSection : Section {
CustomSectionCustomSection195 explicit CustomSection(StringRef Name)
196 : Section(wasm::WASM_SEC_CUSTOM), Name(Name) {}
197
classofCustomSection198 static bool classof(const Section *S) {
199 return S->Type == wasm::WASM_SEC_CUSTOM;
200 }
201
202 StringRef Name;
203 yaml::BinaryRef Payload;
204 };
205
206 struct DylinkImportInfo {
207 StringRef Module;
208 StringRef Field;
209 SymbolFlags Flags;
210 };
211
212 struct DylinkExportInfo {
213 StringRef Name;
214 SymbolFlags Flags;
215 };
216
217 struct DylinkSection : CustomSection {
DylinkSectionDylinkSection218 DylinkSection() : CustomSection("dylink.0") {}
219
classofDylinkSection220 static bool classof(const Section *S) {
221 auto C = dyn_cast<CustomSection>(S);
222 return C && C->Name == "dylink.0";
223 }
224
225 uint32_t MemorySize;
226 uint32_t MemoryAlignment;
227 uint32_t TableSize;
228 uint32_t TableAlignment;
229 std::vector<StringRef> Needed;
230 std::vector<DylinkImportInfo> ImportInfo;
231 std::vector<DylinkExportInfo> ExportInfo;
232 };
233
234 struct NameSection : CustomSection {
NameSectionNameSection235 NameSection() : CustomSection("name") {}
236
classofNameSection237 static bool classof(const Section *S) {
238 auto C = dyn_cast<CustomSection>(S);
239 return C && C->Name == "name";
240 }
241
242 std::vector<NameEntry> FunctionNames;
243 std::vector<NameEntry> GlobalNames;
244 std::vector<NameEntry> DataSegmentNames;
245 };
246
247 struct LinkingSection : CustomSection {
LinkingSectionLinkingSection248 LinkingSection() : CustomSection("linking") {}
249
classofLinkingSection250 static bool classof(const Section *S) {
251 auto C = dyn_cast<CustomSection>(S);
252 return C && C->Name == "linking";
253 }
254
255 uint32_t Version;
256 std::vector<SymbolInfo> SymbolTable;
257 std::vector<SegmentInfo> SegmentInfos;
258 std::vector<InitFunction> InitFunctions;
259 std::vector<Comdat> Comdats;
260 };
261
262 struct ProducersSection : CustomSection {
ProducersSectionProducersSection263 ProducersSection() : CustomSection("producers") {}
264
classofProducersSection265 static bool classof(const Section *S) {
266 auto C = dyn_cast<CustomSection>(S);
267 return C && C->Name == "producers";
268 }
269
270 std::vector<ProducerEntry> Languages;
271 std::vector<ProducerEntry> Tools;
272 std::vector<ProducerEntry> SDKs;
273 };
274
275 struct TargetFeaturesSection : CustomSection {
TargetFeaturesSectionTargetFeaturesSection276 TargetFeaturesSection() : CustomSection("target_features") {}
277
classofTargetFeaturesSection278 static bool classof(const Section *S) {
279 auto C = dyn_cast<CustomSection>(S);
280 return C && C->Name == "target_features";
281 }
282
283 std::vector<FeatureEntry> Features;
284 };
285
286 struct TypeSection : Section {
TypeSectionTypeSection287 TypeSection() : Section(wasm::WASM_SEC_TYPE) {}
288
classofTypeSection289 static bool classof(const Section *S) {
290 return S->Type == wasm::WASM_SEC_TYPE;
291 }
292
293 std::vector<Signature> Signatures;
294 };
295
296 struct ImportSection : Section {
ImportSectionImportSection297 ImportSection() : Section(wasm::WASM_SEC_IMPORT) {}
298
classofImportSection299 static bool classof(const Section *S) {
300 return S->Type == wasm::WASM_SEC_IMPORT;
301 }
302
303 std::vector<Import> Imports;
304 };
305
306 struct FunctionSection : Section {
FunctionSectionFunctionSection307 FunctionSection() : Section(wasm::WASM_SEC_FUNCTION) {}
308
classofFunctionSection309 static bool classof(const Section *S) {
310 return S->Type == wasm::WASM_SEC_FUNCTION;
311 }
312
313 std::vector<uint32_t> FunctionTypes;
314 };
315
316 struct TableSection : Section {
TableSectionTableSection317 TableSection() : Section(wasm::WASM_SEC_TABLE) {}
318
classofTableSection319 static bool classof(const Section *S) {
320 return S->Type == wasm::WASM_SEC_TABLE;
321 }
322
323 std::vector<Table> Tables;
324 };
325
326 struct MemorySection : Section {
MemorySectionMemorySection327 MemorySection() : Section(wasm::WASM_SEC_MEMORY) {}
328
classofMemorySection329 static bool classof(const Section *S) {
330 return S->Type == wasm::WASM_SEC_MEMORY;
331 }
332
333 std::vector<Limits> Memories;
334 };
335
336 struct TagSection : Section {
TagSectionTagSection337 TagSection() : Section(wasm::WASM_SEC_TAG) {}
338
classofTagSection339 static bool classof(const Section *S) {
340 return S->Type == wasm::WASM_SEC_TAG;
341 }
342
343 std::vector<uint32_t> TagTypes;
344 };
345
346 struct GlobalSection : Section {
GlobalSectionGlobalSection347 GlobalSection() : Section(wasm::WASM_SEC_GLOBAL) {}
348
classofGlobalSection349 static bool classof(const Section *S) {
350 return S->Type == wasm::WASM_SEC_GLOBAL;
351 }
352
353 std::vector<Global> Globals;
354 };
355
356 struct ExportSection : Section {
ExportSectionExportSection357 ExportSection() : Section(wasm::WASM_SEC_EXPORT) {}
358
classofExportSection359 static bool classof(const Section *S) {
360 return S->Type == wasm::WASM_SEC_EXPORT;
361 }
362
363 std::vector<Export> Exports;
364 };
365
366 struct StartSection : Section {
StartSectionStartSection367 StartSection() : Section(wasm::WASM_SEC_START) {}
368
classofStartSection369 static bool classof(const Section *S) {
370 return S->Type == wasm::WASM_SEC_START;
371 }
372
373 uint32_t StartFunction;
374 };
375
376 struct ElemSection : Section {
ElemSectionElemSection377 ElemSection() : Section(wasm::WASM_SEC_ELEM) {}
378
classofElemSection379 static bool classof(const Section *S) {
380 return S->Type == wasm::WASM_SEC_ELEM;
381 }
382
383 std::vector<ElemSegment> Segments;
384 };
385
386 struct CodeSection : Section {
CodeSectionCodeSection387 CodeSection() : Section(wasm::WASM_SEC_CODE) {}
388
classofCodeSection389 static bool classof(const Section *S) {
390 return S->Type == wasm::WASM_SEC_CODE;
391 }
392
393 std::vector<Function> Functions;
394 };
395
396 struct DataSection : Section {
DataSectionDataSection397 DataSection() : Section(wasm::WASM_SEC_DATA) {}
398
classofDataSection399 static bool classof(const Section *S) {
400 return S->Type == wasm::WASM_SEC_DATA;
401 }
402
403 std::vector<DataSegment> Segments;
404 };
405
406 struct DataCountSection : Section {
DataCountSectionDataCountSection407 DataCountSection() : Section(wasm::WASM_SEC_DATACOUNT) {}
408
classofDataCountSection409 static bool classof(const Section *S) {
410 return S->Type == wasm::WASM_SEC_DATACOUNT;
411 }
412
413 uint32_t Count;
414 };
415
416 struct Object {
417 FileHeader Header;
418 std::vector<std::unique_ptr<Section>> Sections;
419 };
420
421 } // end namespace WasmYAML
422 } // end namespace llvm
423
424 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::WasmYAML::Section>)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature)425 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature)
426 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ValueType)
427 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Table)
428 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Import)
429 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Export)
430 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ElemSegment)
431 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Limits)
432 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DataSegment)
433 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Global)
434 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function)
435 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl)
436 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
437 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
438 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ProducerEntry)
439 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::FeatureEntry)
440 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo)
441 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
442 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction)
443 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ComdatEntry)
444 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Comdat)
445 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DylinkImportInfo)
446 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DylinkExportInfo)
447
448 namespace llvm {
449 namespace yaml {
450
451 template <> struct MappingTraits<WasmYAML::FileHeader> {
452 static void mapping(IO &IO, WasmYAML::FileHeader &FileHdr);
453 };
454
455 template <> struct MappingTraits<std::unique_ptr<WasmYAML::Section>> {
456 static void mapping(IO &IO, std::unique_ptr<WasmYAML::Section> &Section);
457 };
458
459 template <> struct MappingTraits<WasmYAML::Object> {
460 static void mapping(IO &IO, WasmYAML::Object &Object);
461 };
462
463 template <> struct MappingTraits<WasmYAML::Import> {
464 static void mapping(IO &IO, WasmYAML::Import &Import);
465 };
466
467 template <> struct MappingTraits<WasmYAML::Export> {
468 static void mapping(IO &IO, WasmYAML::Export &Export);
469 };
470
471 template <> struct MappingTraits<WasmYAML::Global> {
472 static void mapping(IO &IO, WasmYAML::Global &Global);
473 };
474
475 template <> struct ScalarBitSetTraits<WasmYAML::LimitFlags> {
476 static void bitset(IO &IO, WasmYAML::LimitFlags &Value);
477 };
478
479 template <> struct ScalarBitSetTraits<WasmYAML::SymbolFlags> {
480 static void bitset(IO &IO, WasmYAML::SymbolFlags &Value);
481 };
482
483 template <> struct ScalarEnumerationTraits<WasmYAML::SymbolKind> {
484 static void enumeration(IO &IO, WasmYAML::SymbolKind &Kind);
485 };
486
487 template <> struct ScalarBitSetTraits<WasmYAML::SegmentFlags> {
488 static void bitset(IO &IO, WasmYAML::SegmentFlags &Value);
489 };
490
491 template <> struct ScalarEnumerationTraits<WasmYAML::SectionType> {
492 static void enumeration(IO &IO, WasmYAML::SectionType &Type);
493 };
494
495 template <> struct MappingTraits<WasmYAML::Signature> {
496 static void mapping(IO &IO, WasmYAML::Signature &Signature);
497 };
498
499 template <> struct MappingTraits<WasmYAML::Table> {
500 static void mapping(IO &IO, WasmYAML::Table &Table);
501 };
502
503 template <> struct MappingTraits<WasmYAML::Limits> {
504 static void mapping(IO &IO, WasmYAML::Limits &Limits);
505 };
506
507 template <> struct MappingTraits<WasmYAML::Function> {
508 static void mapping(IO &IO, WasmYAML::Function &Function);
509 };
510
511 template <> struct MappingTraits<WasmYAML::Relocation> {
512 static void mapping(IO &IO, WasmYAML::Relocation &Relocation);
513 };
514
515 template <> struct MappingTraits<WasmYAML::NameEntry> {
516 static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry);
517 };
518
519 template <> struct MappingTraits<WasmYAML::ProducerEntry> {
520 static void mapping(IO &IO, WasmYAML::ProducerEntry &ProducerEntry);
521 };
522
523 template <> struct ScalarEnumerationTraits<WasmYAML::FeaturePolicyPrefix> {
524 static void enumeration(IO &IO, WasmYAML::FeaturePolicyPrefix &Prefix);
525 };
526
527 template <> struct MappingTraits<WasmYAML::FeatureEntry> {
528 static void mapping(IO &IO, WasmYAML::FeatureEntry &FeatureEntry);
529 };
530
531 template <> struct MappingTraits<WasmYAML::SegmentInfo> {
532 static void mapping(IO &IO, WasmYAML::SegmentInfo &SegmentInfo);
533 };
534
535 template <> struct MappingTraits<WasmYAML::LocalDecl> {
536 static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl);
537 };
538
539 template <> struct MappingTraits<WasmYAML::InitExpr> {
540 static void mapping(IO &IO, WasmYAML::InitExpr &Expr);
541 };
542
543 template <> struct MappingTraits<WasmYAML::DataSegment> {
544 static void mapping(IO &IO, WasmYAML::DataSegment &Segment);
545 };
546
547 template <> struct MappingTraits<WasmYAML::ElemSegment> {
548 static void mapping(IO &IO, WasmYAML::ElemSegment &Segment);
549 };
550
551 template <> struct MappingTraits<WasmYAML::SymbolInfo> {
552 static void mapping(IO &IO, WasmYAML::SymbolInfo &Info);
553 };
554
555 template <> struct MappingTraits<WasmYAML::InitFunction> {
556 static void mapping(IO &IO, WasmYAML::InitFunction &Init);
557 };
558
559 template <> struct ScalarEnumerationTraits<WasmYAML::ComdatKind> {
560 static void enumeration(IO &IO, WasmYAML::ComdatKind &Kind);
561 };
562
563 template <> struct MappingTraits<WasmYAML::ComdatEntry> {
564 static void mapping(IO &IO, WasmYAML::ComdatEntry &ComdatEntry);
565 };
566
567 template <> struct MappingTraits<WasmYAML::Comdat> {
568 static void mapping(IO &IO, WasmYAML::Comdat &Comdat);
569 };
570
571 template <> struct ScalarEnumerationTraits<WasmYAML::ValueType> {
572 static void enumeration(IO &IO, WasmYAML::ValueType &Type);
573 };
574
575 template <> struct ScalarEnumerationTraits<WasmYAML::ExportKind> {
576 static void enumeration(IO &IO, WasmYAML::ExportKind &Kind);
577 };
578
579 template <> struct ScalarEnumerationTraits<WasmYAML::TableType> {
580 static void enumeration(IO &IO, WasmYAML::TableType &Type);
581 };
582
583 template <> struct ScalarEnumerationTraits<WasmYAML::Opcode> {
584 static void enumeration(IO &IO, WasmYAML::Opcode &Opcode);
585 };
586
587 template <> struct ScalarEnumerationTraits<WasmYAML::RelocType> {
588 static void enumeration(IO &IO, WasmYAML::RelocType &Kind);
589 };
590
591 template <> struct MappingTraits<WasmYAML::DylinkImportInfo> {
592 static void mapping(IO &IO, WasmYAML::DylinkImportInfo &Info);
593 };
594
595 template <> struct MappingTraits<WasmYAML::DylinkExportInfo> {
596 static void mapping(IO &IO, WasmYAML::DylinkExportInfo &Info);
597 };
598
599 } // end namespace yaml
600 } // end namespace llvm
601
602 #endif // LLVM_OBJECTYAML_WASMYAML_H
603