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 std::optional<uint8_t> HeaderSecSizeEncodingLen;
193 };
194
195 struct CustomSection : Section {
CustomSectionCustomSection196 explicit CustomSection(StringRef Name)
197 : Section(wasm::WASM_SEC_CUSTOM), Name(Name) {}
198
classofCustomSection199 static bool classof(const Section *S) {
200 return S->Type == wasm::WASM_SEC_CUSTOM;
201 }
202
203 StringRef Name;
204 yaml::BinaryRef Payload;
205 };
206
207 struct DylinkImportInfo {
208 StringRef Module;
209 StringRef Field;
210 SymbolFlags Flags;
211 };
212
213 struct DylinkExportInfo {
214 StringRef Name;
215 SymbolFlags Flags;
216 };
217
218 struct DylinkSection : CustomSection {
DylinkSectionDylinkSection219 DylinkSection() : CustomSection("dylink.0") {}
220
classofDylinkSection221 static bool classof(const Section *S) {
222 auto C = dyn_cast<CustomSection>(S);
223 return C && C->Name == "dylink.0";
224 }
225
226 uint32_t MemorySize;
227 uint32_t MemoryAlignment;
228 uint32_t TableSize;
229 uint32_t TableAlignment;
230 std::vector<StringRef> Needed;
231 std::vector<DylinkImportInfo> ImportInfo;
232 std::vector<DylinkExportInfo> ExportInfo;
233 };
234
235 struct NameSection : CustomSection {
NameSectionNameSection236 NameSection() : CustomSection("name") {}
237
classofNameSection238 static bool classof(const Section *S) {
239 auto C = dyn_cast<CustomSection>(S);
240 return C && C->Name == "name";
241 }
242
243 std::vector<NameEntry> FunctionNames;
244 std::vector<NameEntry> GlobalNames;
245 std::vector<NameEntry> DataSegmentNames;
246 };
247
248 struct LinkingSection : CustomSection {
LinkingSectionLinkingSection249 LinkingSection() : CustomSection("linking") {}
250
classofLinkingSection251 static bool classof(const Section *S) {
252 auto C = dyn_cast<CustomSection>(S);
253 return C && C->Name == "linking";
254 }
255
256 uint32_t Version;
257 std::vector<SymbolInfo> SymbolTable;
258 std::vector<SegmentInfo> SegmentInfos;
259 std::vector<InitFunction> InitFunctions;
260 std::vector<Comdat> Comdats;
261 };
262
263 struct ProducersSection : CustomSection {
ProducersSectionProducersSection264 ProducersSection() : CustomSection("producers") {}
265
classofProducersSection266 static bool classof(const Section *S) {
267 auto C = dyn_cast<CustomSection>(S);
268 return C && C->Name == "producers";
269 }
270
271 std::vector<ProducerEntry> Languages;
272 std::vector<ProducerEntry> Tools;
273 std::vector<ProducerEntry> SDKs;
274 };
275
276 struct TargetFeaturesSection : CustomSection {
TargetFeaturesSectionTargetFeaturesSection277 TargetFeaturesSection() : CustomSection("target_features") {}
278
classofTargetFeaturesSection279 static bool classof(const Section *S) {
280 auto C = dyn_cast<CustomSection>(S);
281 return C && C->Name == "target_features";
282 }
283
284 std::vector<FeatureEntry> Features;
285 };
286
287 struct TypeSection : Section {
TypeSectionTypeSection288 TypeSection() : Section(wasm::WASM_SEC_TYPE) {}
289
classofTypeSection290 static bool classof(const Section *S) {
291 return S->Type == wasm::WASM_SEC_TYPE;
292 }
293
294 std::vector<Signature> Signatures;
295 };
296
297 struct ImportSection : Section {
ImportSectionImportSection298 ImportSection() : Section(wasm::WASM_SEC_IMPORT) {}
299
classofImportSection300 static bool classof(const Section *S) {
301 return S->Type == wasm::WASM_SEC_IMPORT;
302 }
303
304 std::vector<Import> Imports;
305 };
306
307 struct FunctionSection : Section {
FunctionSectionFunctionSection308 FunctionSection() : Section(wasm::WASM_SEC_FUNCTION) {}
309
classofFunctionSection310 static bool classof(const Section *S) {
311 return S->Type == wasm::WASM_SEC_FUNCTION;
312 }
313
314 std::vector<uint32_t> FunctionTypes;
315 };
316
317 struct TableSection : Section {
TableSectionTableSection318 TableSection() : Section(wasm::WASM_SEC_TABLE) {}
319
classofTableSection320 static bool classof(const Section *S) {
321 return S->Type == wasm::WASM_SEC_TABLE;
322 }
323
324 std::vector<Table> Tables;
325 };
326
327 struct MemorySection : Section {
MemorySectionMemorySection328 MemorySection() : Section(wasm::WASM_SEC_MEMORY) {}
329
classofMemorySection330 static bool classof(const Section *S) {
331 return S->Type == wasm::WASM_SEC_MEMORY;
332 }
333
334 std::vector<Limits> Memories;
335 };
336
337 struct TagSection : Section {
TagSectionTagSection338 TagSection() : Section(wasm::WASM_SEC_TAG) {}
339
classofTagSection340 static bool classof(const Section *S) {
341 return S->Type == wasm::WASM_SEC_TAG;
342 }
343
344 std::vector<uint32_t> TagTypes;
345 };
346
347 struct GlobalSection : Section {
GlobalSectionGlobalSection348 GlobalSection() : Section(wasm::WASM_SEC_GLOBAL) {}
349
classofGlobalSection350 static bool classof(const Section *S) {
351 return S->Type == wasm::WASM_SEC_GLOBAL;
352 }
353
354 std::vector<Global> Globals;
355 };
356
357 struct ExportSection : Section {
ExportSectionExportSection358 ExportSection() : Section(wasm::WASM_SEC_EXPORT) {}
359
classofExportSection360 static bool classof(const Section *S) {
361 return S->Type == wasm::WASM_SEC_EXPORT;
362 }
363
364 std::vector<Export> Exports;
365 };
366
367 struct StartSection : Section {
StartSectionStartSection368 StartSection() : Section(wasm::WASM_SEC_START) {}
369
classofStartSection370 static bool classof(const Section *S) {
371 return S->Type == wasm::WASM_SEC_START;
372 }
373
374 uint32_t StartFunction;
375 };
376
377 struct ElemSection : Section {
ElemSectionElemSection378 ElemSection() : Section(wasm::WASM_SEC_ELEM) {}
379
classofElemSection380 static bool classof(const Section *S) {
381 return S->Type == wasm::WASM_SEC_ELEM;
382 }
383
384 std::vector<ElemSegment> Segments;
385 };
386
387 struct CodeSection : Section {
CodeSectionCodeSection388 CodeSection() : Section(wasm::WASM_SEC_CODE) {}
389
classofCodeSection390 static bool classof(const Section *S) {
391 return S->Type == wasm::WASM_SEC_CODE;
392 }
393
394 std::vector<Function> Functions;
395 };
396
397 struct DataSection : Section {
DataSectionDataSection398 DataSection() : Section(wasm::WASM_SEC_DATA) {}
399
classofDataSection400 static bool classof(const Section *S) {
401 return S->Type == wasm::WASM_SEC_DATA;
402 }
403
404 std::vector<DataSegment> Segments;
405 };
406
407 struct DataCountSection : Section {
DataCountSectionDataCountSection408 DataCountSection() : Section(wasm::WASM_SEC_DATACOUNT) {}
409
classofDataCountSection410 static bool classof(const Section *S) {
411 return S->Type == wasm::WASM_SEC_DATACOUNT;
412 }
413
414 uint32_t Count;
415 };
416
417 struct Object {
418 FileHeader Header;
419 std::vector<std::unique_ptr<Section>> Sections;
420 };
421
422 } // end namespace WasmYAML
423 } // end namespace llvm
424
425 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::WasmYAML::Section>)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature)426 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature)
427 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ValueType)
428 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Table)
429 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Import)
430 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Export)
431 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ElemSegment)
432 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Limits)
433 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DataSegment)
434 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Global)
435 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function)
436 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl)
437 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
438 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
439 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ProducerEntry)
440 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::FeatureEntry)
441 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo)
442 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
443 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction)
444 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ComdatEntry)
445 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Comdat)
446 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DylinkImportInfo)
447 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DylinkExportInfo)
448
449 namespace llvm {
450 namespace yaml {
451
452 template <> struct MappingTraits<WasmYAML::FileHeader> {
453 static void mapping(IO &IO, WasmYAML::FileHeader &FileHdr);
454 };
455
456 template <> struct MappingTraits<std::unique_ptr<WasmYAML::Section>> {
457 static void mapping(IO &IO, std::unique_ptr<WasmYAML::Section> &Section);
458 };
459
460 template <> struct MappingTraits<WasmYAML::Object> {
461 static void mapping(IO &IO, WasmYAML::Object &Object);
462 };
463
464 template <> struct MappingTraits<WasmYAML::Import> {
465 static void mapping(IO &IO, WasmYAML::Import &Import);
466 };
467
468 template <> struct MappingTraits<WasmYAML::Export> {
469 static void mapping(IO &IO, WasmYAML::Export &Export);
470 };
471
472 template <> struct MappingTraits<WasmYAML::Global> {
473 static void mapping(IO &IO, WasmYAML::Global &Global);
474 };
475
476 template <> struct ScalarBitSetTraits<WasmYAML::LimitFlags> {
477 static void bitset(IO &IO, WasmYAML::LimitFlags &Value);
478 };
479
480 template <> struct ScalarBitSetTraits<WasmYAML::SymbolFlags> {
481 static void bitset(IO &IO, WasmYAML::SymbolFlags &Value);
482 };
483
484 template <> struct ScalarEnumerationTraits<WasmYAML::SymbolKind> {
485 static void enumeration(IO &IO, WasmYAML::SymbolKind &Kind);
486 };
487
488 template <> struct ScalarBitSetTraits<WasmYAML::SegmentFlags> {
489 static void bitset(IO &IO, WasmYAML::SegmentFlags &Value);
490 };
491
492 template <> struct ScalarEnumerationTraits<WasmYAML::SectionType> {
493 static void enumeration(IO &IO, WasmYAML::SectionType &Type);
494 };
495
496 template <> struct MappingTraits<WasmYAML::Signature> {
497 static void mapping(IO &IO, WasmYAML::Signature &Signature);
498 };
499
500 template <> struct MappingTraits<WasmYAML::Table> {
501 static void mapping(IO &IO, WasmYAML::Table &Table);
502 };
503
504 template <> struct MappingTraits<WasmYAML::Limits> {
505 static void mapping(IO &IO, WasmYAML::Limits &Limits);
506 };
507
508 template <> struct MappingTraits<WasmYAML::Function> {
509 static void mapping(IO &IO, WasmYAML::Function &Function);
510 };
511
512 template <> struct MappingTraits<WasmYAML::Relocation> {
513 static void mapping(IO &IO, WasmYAML::Relocation &Relocation);
514 };
515
516 template <> struct MappingTraits<WasmYAML::NameEntry> {
517 static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry);
518 };
519
520 template <> struct MappingTraits<WasmYAML::ProducerEntry> {
521 static void mapping(IO &IO, WasmYAML::ProducerEntry &ProducerEntry);
522 };
523
524 template <> struct ScalarEnumerationTraits<WasmYAML::FeaturePolicyPrefix> {
525 static void enumeration(IO &IO, WasmYAML::FeaturePolicyPrefix &Prefix);
526 };
527
528 template <> struct MappingTraits<WasmYAML::FeatureEntry> {
529 static void mapping(IO &IO, WasmYAML::FeatureEntry &FeatureEntry);
530 };
531
532 template <> struct MappingTraits<WasmYAML::SegmentInfo> {
533 static void mapping(IO &IO, WasmYAML::SegmentInfo &SegmentInfo);
534 };
535
536 template <> struct MappingTraits<WasmYAML::LocalDecl> {
537 static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl);
538 };
539
540 template <> struct MappingTraits<WasmYAML::InitExpr> {
541 static void mapping(IO &IO, WasmYAML::InitExpr &Expr);
542 };
543
544 template <> struct MappingTraits<WasmYAML::DataSegment> {
545 static void mapping(IO &IO, WasmYAML::DataSegment &Segment);
546 };
547
548 template <> struct MappingTraits<WasmYAML::ElemSegment> {
549 static void mapping(IO &IO, WasmYAML::ElemSegment &Segment);
550 };
551
552 template <> struct MappingTraits<WasmYAML::SymbolInfo> {
553 static void mapping(IO &IO, WasmYAML::SymbolInfo &Info);
554 };
555
556 template <> struct MappingTraits<WasmYAML::InitFunction> {
557 static void mapping(IO &IO, WasmYAML::InitFunction &Init);
558 };
559
560 template <> struct ScalarEnumerationTraits<WasmYAML::ComdatKind> {
561 static void enumeration(IO &IO, WasmYAML::ComdatKind &Kind);
562 };
563
564 template <> struct MappingTraits<WasmYAML::ComdatEntry> {
565 static void mapping(IO &IO, WasmYAML::ComdatEntry &ComdatEntry);
566 };
567
568 template <> struct MappingTraits<WasmYAML::Comdat> {
569 static void mapping(IO &IO, WasmYAML::Comdat &Comdat);
570 };
571
572 template <> struct ScalarEnumerationTraits<WasmYAML::ValueType> {
573 static void enumeration(IO &IO, WasmYAML::ValueType &Type);
574 };
575
576 template <> struct ScalarEnumerationTraits<WasmYAML::ExportKind> {
577 static void enumeration(IO &IO, WasmYAML::ExportKind &Kind);
578 };
579
580 template <> struct ScalarEnumerationTraits<WasmYAML::TableType> {
581 static void enumeration(IO &IO, WasmYAML::TableType &Type);
582 };
583
584 template <> struct ScalarEnumerationTraits<WasmYAML::Opcode> {
585 static void enumeration(IO &IO, WasmYAML::Opcode &Opcode);
586 };
587
588 template <> struct ScalarEnumerationTraits<WasmYAML::RelocType> {
589 static void enumeration(IO &IO, WasmYAML::RelocType &Kind);
590 };
591
592 template <> struct MappingTraits<WasmYAML::DylinkImportInfo> {
593 static void mapping(IO &IO, WasmYAML::DylinkImportInfo &Info);
594 };
595
596 template <> struct MappingTraits<WasmYAML::DylinkExportInfo> {
597 static void mapping(IO &IO, WasmYAML::DylinkExportInfo &Info);
598 };
599
600 } // end namespace yaml
601 } // end namespace llvm
602
603 #endif // LLVM_OBJECTYAML_WASMYAML_H
604