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 ElemSegment {
66 uint32_t Flags;
67 uint32_t TableNumber;
68 ValueType ElemKind;
69 wasm::WasmInitExpr Offset;
70 std::vector<uint32_t> Functions;
71 };
72
73 struct Global {
74 uint32_t Index;
75 ValueType Type;
76 bool Mutable;
77 wasm::WasmInitExpr InitExpr;
78 };
79
80 struct Import {
81 StringRef Module;
82 StringRef Field;
83 ExportKind Kind;
84 union {
85 uint32_t SigIndex;
86 Global GlobalImport;
87 Table TableImport;
88 Limits Memory;
89 uint32_t TagIndex;
90 };
91 };
92
93 struct LocalDecl {
94 ValueType Type;
95 uint32_t Count;
96 };
97
98 struct Function {
99 uint32_t Index;
100 std::vector<LocalDecl> Locals;
101 yaml::BinaryRef Body;
102 };
103
104 struct Relocation {
105 RelocType Type;
106 uint32_t Index;
107 // TODO(wvo): this would strictly be better as Hex64, but that will change
108 // all existing obj2yaml output.
109 yaml::Hex32 Offset;
110 int64_t Addend;
111 };
112
113 struct DataSegment {
114 uint32_t SectionOffset;
115 uint32_t InitFlags;
116 uint32_t MemoryIndex;
117 wasm::WasmInitExpr Offset;
118 yaml::BinaryRef Content;
119 };
120
121 struct NameEntry {
122 uint32_t Index;
123 StringRef Name;
124 };
125
126 struct ProducerEntry {
127 std::string Name;
128 std::string Version;
129 };
130
131 struct FeatureEntry {
132 FeaturePolicyPrefix Prefix;
133 std::string Name;
134 };
135
136 struct SegmentInfo {
137 uint32_t Index;
138 StringRef Name;
139 uint32_t Alignment;
140 SegmentFlags Flags;
141 };
142
143 struct Signature {
144 uint32_t Index;
145 SignatureForm Form = wasm::WASM_TYPE_FUNC;
146 std::vector<ValueType> ParamTypes;
147 std::vector<ValueType> ReturnTypes;
148 };
149
150 struct SymbolInfo {
151 uint32_t Index;
152 StringRef Name;
153 SymbolKind Kind;
154 SymbolFlags Flags;
155 union {
156 uint32_t ElementIndex;
157 wasm::WasmDataReference DataRef;
158 };
159 };
160
161 struct InitFunction {
162 uint32_t Priority;
163 uint32_t Symbol;
164 };
165
166 struct ComdatEntry {
167 ComdatKind Kind;
168 uint32_t Index;
169 };
170
171 struct Comdat {
172 StringRef Name;
173 std::vector<ComdatEntry> Entries;
174 };
175
176 struct Section {
SectionSection177 explicit Section(SectionType SecType) : Type(SecType) {}
178 virtual ~Section();
179
180 SectionType Type;
181 std::vector<Relocation> Relocations;
182 };
183
184 struct CustomSection : Section {
CustomSectionCustomSection185 explicit CustomSection(StringRef Name)
186 : Section(wasm::WASM_SEC_CUSTOM), Name(Name) {}
187
classofCustomSection188 static bool classof(const Section *S) {
189 return S->Type == wasm::WASM_SEC_CUSTOM;
190 }
191
192 StringRef Name;
193 yaml::BinaryRef Payload;
194 };
195
196 struct DylinkExport {
197 StringRef Name;
198 SymbolFlags Flags;
199 };
200
201 struct DylinkSection : CustomSection {
DylinkSectionDylinkSection202 DylinkSection() : CustomSection("dylink.0") {}
203
classofDylinkSection204 static bool classof(const Section *S) {
205 auto C = dyn_cast<CustomSection>(S);
206 return C && C->Name == "dylink.0";
207 }
208
209 uint32_t MemorySize;
210 uint32_t MemoryAlignment;
211 uint32_t TableSize;
212 uint32_t TableAlignment;
213 std::vector<StringRef> Needed;
214 std::vector<DylinkExport> ExportInfo;
215 };
216
217 struct NameSection : CustomSection {
NameSectionNameSection218 NameSection() : CustomSection("name") {}
219
classofNameSection220 static bool classof(const Section *S) {
221 auto C = dyn_cast<CustomSection>(S);
222 return C && C->Name == "name";
223 }
224
225 std::vector<NameEntry> FunctionNames;
226 std::vector<NameEntry> GlobalNames;
227 std::vector<NameEntry> DataSegmentNames;
228 };
229
230 struct LinkingSection : CustomSection {
LinkingSectionLinkingSection231 LinkingSection() : CustomSection("linking") {}
232
classofLinkingSection233 static bool classof(const Section *S) {
234 auto C = dyn_cast<CustomSection>(S);
235 return C && C->Name == "linking";
236 }
237
238 uint32_t Version;
239 std::vector<SymbolInfo> SymbolTable;
240 std::vector<SegmentInfo> SegmentInfos;
241 std::vector<InitFunction> InitFunctions;
242 std::vector<Comdat> Comdats;
243 };
244
245 struct ProducersSection : CustomSection {
ProducersSectionProducersSection246 ProducersSection() : CustomSection("producers") {}
247
classofProducersSection248 static bool classof(const Section *S) {
249 auto C = dyn_cast<CustomSection>(S);
250 return C && C->Name == "producers";
251 }
252
253 std::vector<ProducerEntry> Languages;
254 std::vector<ProducerEntry> Tools;
255 std::vector<ProducerEntry> SDKs;
256 };
257
258 struct TargetFeaturesSection : CustomSection {
TargetFeaturesSectionTargetFeaturesSection259 TargetFeaturesSection() : CustomSection("target_features") {}
260
classofTargetFeaturesSection261 static bool classof(const Section *S) {
262 auto C = dyn_cast<CustomSection>(S);
263 return C && C->Name == "target_features";
264 }
265
266 std::vector<FeatureEntry> Features;
267 };
268
269 struct TypeSection : Section {
TypeSectionTypeSection270 TypeSection() : Section(wasm::WASM_SEC_TYPE) {}
271
classofTypeSection272 static bool classof(const Section *S) {
273 return S->Type == wasm::WASM_SEC_TYPE;
274 }
275
276 std::vector<Signature> Signatures;
277 };
278
279 struct ImportSection : Section {
ImportSectionImportSection280 ImportSection() : Section(wasm::WASM_SEC_IMPORT) {}
281
classofImportSection282 static bool classof(const Section *S) {
283 return S->Type == wasm::WASM_SEC_IMPORT;
284 }
285
286 std::vector<Import> Imports;
287 };
288
289 struct FunctionSection : Section {
FunctionSectionFunctionSection290 FunctionSection() : Section(wasm::WASM_SEC_FUNCTION) {}
291
classofFunctionSection292 static bool classof(const Section *S) {
293 return S->Type == wasm::WASM_SEC_FUNCTION;
294 }
295
296 std::vector<uint32_t> FunctionTypes;
297 };
298
299 struct TableSection : Section {
TableSectionTableSection300 TableSection() : Section(wasm::WASM_SEC_TABLE) {}
301
classofTableSection302 static bool classof(const Section *S) {
303 return S->Type == wasm::WASM_SEC_TABLE;
304 }
305
306 std::vector<Table> Tables;
307 };
308
309 struct MemorySection : Section {
MemorySectionMemorySection310 MemorySection() : Section(wasm::WASM_SEC_MEMORY) {}
311
classofMemorySection312 static bool classof(const Section *S) {
313 return S->Type == wasm::WASM_SEC_MEMORY;
314 }
315
316 std::vector<Limits> Memories;
317 };
318
319 struct TagSection : Section {
TagSectionTagSection320 TagSection() : Section(wasm::WASM_SEC_TAG) {}
321
classofTagSection322 static bool classof(const Section *S) {
323 return S->Type == wasm::WASM_SEC_TAG;
324 }
325
326 std::vector<uint32_t> TagTypes;
327 };
328
329 struct GlobalSection : Section {
GlobalSectionGlobalSection330 GlobalSection() : Section(wasm::WASM_SEC_GLOBAL) {}
331
classofGlobalSection332 static bool classof(const Section *S) {
333 return S->Type == wasm::WASM_SEC_GLOBAL;
334 }
335
336 std::vector<Global> Globals;
337 };
338
339 struct ExportSection : Section {
ExportSectionExportSection340 ExportSection() : Section(wasm::WASM_SEC_EXPORT) {}
341
classofExportSection342 static bool classof(const Section *S) {
343 return S->Type == wasm::WASM_SEC_EXPORT;
344 }
345
346 std::vector<Export> Exports;
347 };
348
349 struct StartSection : Section {
StartSectionStartSection350 StartSection() : Section(wasm::WASM_SEC_START) {}
351
classofStartSection352 static bool classof(const Section *S) {
353 return S->Type == wasm::WASM_SEC_START;
354 }
355
356 uint32_t StartFunction;
357 };
358
359 struct ElemSection : Section {
ElemSectionElemSection360 ElemSection() : Section(wasm::WASM_SEC_ELEM) {}
361
classofElemSection362 static bool classof(const Section *S) {
363 return S->Type == wasm::WASM_SEC_ELEM;
364 }
365
366 std::vector<ElemSegment> Segments;
367 };
368
369 struct CodeSection : Section {
CodeSectionCodeSection370 CodeSection() : Section(wasm::WASM_SEC_CODE) {}
371
classofCodeSection372 static bool classof(const Section *S) {
373 return S->Type == wasm::WASM_SEC_CODE;
374 }
375
376 std::vector<Function> Functions;
377 };
378
379 struct DataSection : Section {
DataSectionDataSection380 DataSection() : Section(wasm::WASM_SEC_DATA) {}
381
classofDataSection382 static bool classof(const Section *S) {
383 return S->Type == wasm::WASM_SEC_DATA;
384 }
385
386 std::vector<DataSegment> Segments;
387 };
388
389 struct DataCountSection : Section {
DataCountSectionDataCountSection390 DataCountSection() : Section(wasm::WASM_SEC_DATACOUNT) {}
391
classofDataCountSection392 static bool classof(const Section *S) {
393 return S->Type == wasm::WASM_SEC_DATACOUNT;
394 }
395
396 uint32_t Count;
397 };
398
399 struct Object {
400 FileHeader Header;
401 std::vector<std::unique_ptr<Section>> Sections;
402 };
403
404 } // end namespace WasmYAML
405 } // end namespace llvm
406
407 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::WasmYAML::Section>)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature)408 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature)
409 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ValueType)
410 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Table)
411 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Import)
412 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Export)
413 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ElemSegment)
414 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Limits)
415 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DataSegment)
416 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Global)
417 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function)
418 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl)
419 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
420 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
421 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ProducerEntry)
422 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::FeatureEntry)
423 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo)
424 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
425 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction)
426 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ComdatEntry)
427 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Comdat)
428 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DylinkExport)
429
430 namespace llvm {
431 namespace yaml {
432
433 template <> struct MappingTraits<WasmYAML::FileHeader> {
434 static void mapping(IO &IO, WasmYAML::FileHeader &FileHdr);
435 };
436
437 template <> struct MappingTraits<std::unique_ptr<WasmYAML::Section>> {
438 static void mapping(IO &IO, std::unique_ptr<WasmYAML::Section> &Section);
439 };
440
441 template <> struct MappingTraits<WasmYAML::Object> {
442 static void mapping(IO &IO, WasmYAML::Object &Object);
443 };
444
445 template <> struct MappingTraits<WasmYAML::Import> {
446 static void mapping(IO &IO, WasmYAML::Import &Import);
447 };
448
449 template <> struct MappingTraits<WasmYAML::Export> {
450 static void mapping(IO &IO, WasmYAML::Export &Export);
451 };
452
453 template <> struct MappingTraits<WasmYAML::Global> {
454 static void mapping(IO &IO, WasmYAML::Global &Global);
455 };
456
457 template <> struct ScalarBitSetTraits<WasmYAML::LimitFlags> {
458 static void bitset(IO &IO, WasmYAML::LimitFlags &Value);
459 };
460
461 template <> struct ScalarBitSetTraits<WasmYAML::SymbolFlags> {
462 static void bitset(IO &IO, WasmYAML::SymbolFlags &Value);
463 };
464
465 template <> struct ScalarEnumerationTraits<WasmYAML::SymbolKind> {
466 static void enumeration(IO &IO, WasmYAML::SymbolKind &Kind);
467 };
468
469 template <> struct ScalarBitSetTraits<WasmYAML::SegmentFlags> {
470 static void bitset(IO &IO, WasmYAML::SegmentFlags &Value);
471 };
472
473 template <> struct ScalarEnumerationTraits<WasmYAML::SectionType> {
474 static void enumeration(IO &IO, WasmYAML::SectionType &Type);
475 };
476
477 template <> struct MappingTraits<WasmYAML::Signature> {
478 static void mapping(IO &IO, WasmYAML::Signature &Signature);
479 };
480
481 template <> struct MappingTraits<WasmYAML::Table> {
482 static void mapping(IO &IO, WasmYAML::Table &Table);
483 };
484
485 template <> struct MappingTraits<WasmYAML::Limits> {
486 static void mapping(IO &IO, WasmYAML::Limits &Limits);
487 };
488
489 template <> struct MappingTraits<WasmYAML::Function> {
490 static void mapping(IO &IO, WasmYAML::Function &Function);
491 };
492
493 template <> struct MappingTraits<WasmYAML::Relocation> {
494 static void mapping(IO &IO, WasmYAML::Relocation &Relocation);
495 };
496
497 template <> struct MappingTraits<WasmYAML::NameEntry> {
498 static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry);
499 };
500
501 template <> struct MappingTraits<WasmYAML::ProducerEntry> {
502 static void mapping(IO &IO, WasmYAML::ProducerEntry &ProducerEntry);
503 };
504
505 template <> struct ScalarEnumerationTraits<WasmYAML::FeaturePolicyPrefix> {
506 static void enumeration(IO &IO, WasmYAML::FeaturePolicyPrefix &Prefix);
507 };
508
509 template <> struct MappingTraits<WasmYAML::FeatureEntry> {
510 static void mapping(IO &IO, WasmYAML::FeatureEntry &FeatureEntry);
511 };
512
513 template <> struct MappingTraits<WasmYAML::SegmentInfo> {
514 static void mapping(IO &IO, WasmYAML::SegmentInfo &SegmentInfo);
515 };
516
517 template <> struct MappingTraits<WasmYAML::LocalDecl> {
518 static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl);
519 };
520
521 template <> struct MappingTraits<wasm::WasmInitExpr> {
522 static void mapping(IO &IO, wasm::WasmInitExpr &Expr);
523 };
524
525 template <> struct MappingTraits<WasmYAML::DataSegment> {
526 static void mapping(IO &IO, WasmYAML::DataSegment &Segment);
527 };
528
529 template <> struct MappingTraits<WasmYAML::ElemSegment> {
530 static void mapping(IO &IO, WasmYAML::ElemSegment &Segment);
531 };
532
533 template <> struct MappingTraits<WasmYAML::SymbolInfo> {
534 static void mapping(IO &IO, WasmYAML::SymbolInfo &Info);
535 };
536
537 template <> struct MappingTraits<WasmYAML::InitFunction> {
538 static void mapping(IO &IO, WasmYAML::InitFunction &Init);
539 };
540
541 template <> struct ScalarEnumerationTraits<WasmYAML::ComdatKind> {
542 static void enumeration(IO &IO, WasmYAML::ComdatKind &Kind);
543 };
544
545 template <> struct MappingTraits<WasmYAML::ComdatEntry> {
546 static void mapping(IO &IO, WasmYAML::ComdatEntry &ComdatEntry);
547 };
548
549 template <> struct MappingTraits<WasmYAML::Comdat> {
550 static void mapping(IO &IO, WasmYAML::Comdat &Comdat);
551 };
552
553 template <> struct ScalarEnumerationTraits<WasmYAML::ValueType> {
554 static void enumeration(IO &IO, WasmYAML::ValueType &Type);
555 };
556
557 template <> struct ScalarEnumerationTraits<WasmYAML::ExportKind> {
558 static void enumeration(IO &IO, WasmYAML::ExportKind &Kind);
559 };
560
561 template <> struct ScalarEnumerationTraits<WasmYAML::TableType> {
562 static void enumeration(IO &IO, WasmYAML::TableType &Type);
563 };
564
565 template <> struct ScalarEnumerationTraits<WasmYAML::Opcode> {
566 static void enumeration(IO &IO, WasmYAML::Opcode &Opcode);
567 };
568
569 template <> struct ScalarEnumerationTraits<WasmYAML::RelocType> {
570 static void enumeration(IO &IO, WasmYAML::RelocType &Kind);
571 };
572
573 template <> struct MappingTraits<WasmYAML::DylinkExport> {
574 static void mapping(IO &IO, WasmYAML::DylinkExport &Export);
575 };
576
577 } // end namespace yaml
578 } // end namespace llvm
579
580 #endif // LLVM_OBJECTYAML_WASMYAML_H
581