WasmYAML.h revision 360784
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
26namespace llvm {
27namespace WasmYAML {
28
29LLVM_YAML_STRONG_TYPEDEF(uint32_t, SectionType)
30LLVM_YAML_STRONG_TYPEDEF(uint32_t, ValueType)
31LLVM_YAML_STRONG_TYPEDEF(uint32_t, TableType)
32LLVM_YAML_STRONG_TYPEDEF(uint32_t, SignatureForm)
33LLVM_YAML_STRONG_TYPEDEF(uint32_t, ExportKind)
34LLVM_YAML_STRONG_TYPEDEF(uint32_t, Opcode)
35LLVM_YAML_STRONG_TYPEDEF(uint32_t, RelocType)
36LLVM_YAML_STRONG_TYPEDEF(uint32_t, SymbolFlags)
37LLVM_YAML_STRONG_TYPEDEF(uint32_t, SymbolKind)
38LLVM_YAML_STRONG_TYPEDEF(uint32_t, SegmentFlags)
39LLVM_YAML_STRONG_TYPEDEF(uint32_t, LimitFlags)
40LLVM_YAML_STRONG_TYPEDEF(uint32_t, ComdatKind)
41LLVM_YAML_STRONG_TYPEDEF(uint32_t, FeaturePolicyPrefix)
42
43struct FileHeader {
44  yaml::Hex32 Version;
45};
46
47struct Limits {
48  LimitFlags Flags;
49  yaml::Hex32 Initial;
50  yaml::Hex32 Maximum;
51};
52
53struct Table {
54  TableType ElemType;
55  Limits TableLimits;
56};
57
58struct Export {
59  StringRef Name;
60  ExportKind Kind;
61  uint32_t Index;
62};
63
64struct ElemSegment {
65  uint32_t TableIndex;
66  wasm::WasmInitExpr Offset;
67  std::vector<uint32_t> Functions;
68};
69
70struct Global {
71  uint32_t Index;
72  ValueType Type;
73  bool Mutable;
74  wasm::WasmInitExpr InitExpr;
75};
76
77struct Event {
78  uint32_t Index;
79  uint32_t Attribute;
80  uint32_t SigIndex;
81};
82
83struct Import {
84  StringRef Module;
85  StringRef Field;
86  ExportKind Kind;
87  union {
88    uint32_t SigIndex;
89    Global GlobalImport;
90    Table TableImport;
91    Limits Memory;
92    Event EventImport;
93  };
94};
95
96struct LocalDecl {
97  ValueType Type;
98  uint32_t Count;
99};
100
101struct Function {
102  uint32_t Index;
103  std::vector<LocalDecl> Locals;
104  yaml::BinaryRef Body;
105};
106
107struct Relocation {
108  RelocType Type;
109  uint32_t Index;
110  yaml::Hex32 Offset;
111  int32_t Addend;
112};
113
114struct DataSegment {
115  uint32_t SectionOffset;
116  uint32_t InitFlags;
117  uint32_t MemoryIndex;
118  wasm::WasmInitExpr Offset;
119  yaml::BinaryRef Content;
120};
121
122struct NameEntry {
123  uint32_t Index;
124  StringRef Name;
125};
126
127struct ProducerEntry {
128  std::string Name;
129  std::string Version;
130};
131
132struct FeatureEntry {
133  FeaturePolicyPrefix Prefix;
134  std::string Name;
135};
136
137struct SegmentInfo {
138  uint32_t Index;
139  StringRef Name;
140  uint32_t Alignment;
141  SegmentFlags Flags;
142};
143
144struct Signature {
145  uint32_t Index;
146  SignatureForm Form = wasm::WASM_TYPE_FUNC;
147  std::vector<ValueType> ParamTypes;
148  std::vector<ValueType> ReturnTypes;
149};
150
151struct SymbolInfo {
152  uint32_t Index;
153  StringRef Name;
154  SymbolKind Kind;
155  SymbolFlags Flags;
156  union {
157    uint32_t ElementIndex;
158    wasm::WasmDataReference DataRef;
159  };
160};
161
162struct InitFunction {
163  uint32_t Priority;
164  uint32_t Symbol;
165};
166
167struct ComdatEntry {
168  ComdatKind Kind;
169  uint32_t Index;
170};
171
172struct Comdat {
173  StringRef Name;
174  std::vector<ComdatEntry> Entries;
175};
176
177struct Section {
178  explicit Section(SectionType SecType) : Type(SecType) {}
179  virtual ~Section();
180
181  SectionType Type;
182  std::vector<Relocation> Relocations;
183};
184
185struct CustomSection : Section {
186  explicit CustomSection(StringRef Name)
187      : Section(wasm::WASM_SEC_CUSTOM), Name(Name) {}
188
189  static bool classof(const Section *S) {
190    return S->Type == wasm::WASM_SEC_CUSTOM;
191  }
192
193  StringRef Name;
194  yaml::BinaryRef Payload;
195};
196
197struct DylinkSection : CustomSection {
198  DylinkSection() : CustomSection("dylink") {}
199
200  static bool classof(const Section *S) {
201    auto C = dyn_cast<CustomSection>(S);
202    return C && C->Name == "dylink";
203  }
204
205  uint32_t MemorySize;
206  uint32_t MemoryAlignment;
207  uint32_t TableSize;
208  uint32_t TableAlignment;
209  std::vector<StringRef> Needed;
210};
211
212struct NameSection : CustomSection {
213  NameSection() : CustomSection("name") {}
214
215  static bool classof(const Section *S) {
216    auto C = dyn_cast<CustomSection>(S);
217    return C && C->Name == "name";
218  }
219
220  std::vector<NameEntry> FunctionNames;
221};
222
223struct LinkingSection : CustomSection {
224  LinkingSection() : CustomSection("linking") {}
225
226  static bool classof(const Section *S) {
227    auto C = dyn_cast<CustomSection>(S);
228    return C && C->Name == "linking";
229  }
230
231  uint32_t Version;
232  std::vector<SymbolInfo> SymbolTable;
233  std::vector<SegmentInfo> SegmentInfos;
234  std::vector<InitFunction> InitFunctions;
235  std::vector<Comdat> Comdats;
236};
237
238struct ProducersSection : CustomSection {
239  ProducersSection() : CustomSection("producers") {}
240
241  static bool classof(const Section *S) {
242    auto C = dyn_cast<CustomSection>(S);
243    return C && C->Name == "producers";
244  }
245
246  std::vector<ProducerEntry> Languages;
247  std::vector<ProducerEntry> Tools;
248  std::vector<ProducerEntry> SDKs;
249};
250
251struct TargetFeaturesSection : CustomSection {
252  TargetFeaturesSection() : CustomSection("target_features") {}
253
254  static bool classof(const Section *S) {
255    auto C = dyn_cast<CustomSection>(S);
256    return C && C->Name == "target_features";
257  }
258
259  std::vector<FeatureEntry> Features;
260};
261
262struct TypeSection : Section {
263  TypeSection() : Section(wasm::WASM_SEC_TYPE) {}
264
265  static bool classof(const Section *S) {
266    return S->Type == wasm::WASM_SEC_TYPE;
267  }
268
269  std::vector<Signature> Signatures;
270};
271
272struct ImportSection : Section {
273  ImportSection() : Section(wasm::WASM_SEC_IMPORT) {}
274
275  static bool classof(const Section *S) {
276    return S->Type == wasm::WASM_SEC_IMPORT;
277  }
278
279  std::vector<Import> Imports;
280};
281
282struct FunctionSection : Section {
283  FunctionSection() : Section(wasm::WASM_SEC_FUNCTION) {}
284
285  static bool classof(const Section *S) {
286    return S->Type == wasm::WASM_SEC_FUNCTION;
287  }
288
289  std::vector<uint32_t> FunctionTypes;
290};
291
292struct TableSection : Section {
293  TableSection() : Section(wasm::WASM_SEC_TABLE) {}
294
295  static bool classof(const Section *S) {
296    return S->Type == wasm::WASM_SEC_TABLE;
297  }
298
299  std::vector<Table> Tables;
300};
301
302struct MemorySection : Section {
303  MemorySection() : Section(wasm::WASM_SEC_MEMORY) {}
304
305  static bool classof(const Section *S) {
306    return S->Type == wasm::WASM_SEC_MEMORY;
307  }
308
309  std::vector<Limits> Memories;
310};
311
312struct GlobalSection : Section {
313  GlobalSection() : Section(wasm::WASM_SEC_GLOBAL) {}
314
315  static bool classof(const Section *S) {
316    return S->Type == wasm::WASM_SEC_GLOBAL;
317  }
318
319  std::vector<Global> Globals;
320};
321
322struct EventSection : Section {
323  EventSection() : Section(wasm::WASM_SEC_EVENT) {}
324
325  static bool classof(const Section *S) {
326    return S->Type == wasm::WASM_SEC_EVENT;
327  }
328
329  std::vector<Event> Events;
330};
331
332struct ExportSection : Section {
333  ExportSection() : Section(wasm::WASM_SEC_EXPORT) {}
334
335  static bool classof(const Section *S) {
336    return S->Type == wasm::WASM_SEC_EXPORT;
337  }
338
339  std::vector<Export> Exports;
340};
341
342struct StartSection : Section {
343  StartSection() : Section(wasm::WASM_SEC_START) {}
344
345  static bool classof(const Section *S) {
346    return S->Type == wasm::WASM_SEC_START;
347  }
348
349  uint32_t StartFunction;
350};
351
352struct ElemSection : Section {
353  ElemSection() : Section(wasm::WASM_SEC_ELEM) {}
354
355  static bool classof(const Section *S) {
356    return S->Type == wasm::WASM_SEC_ELEM;
357  }
358
359  std::vector<ElemSegment> Segments;
360};
361
362struct CodeSection : Section {
363  CodeSection() : Section(wasm::WASM_SEC_CODE) {}
364
365  static bool classof(const Section *S) {
366    return S->Type == wasm::WASM_SEC_CODE;
367  }
368
369  std::vector<Function> Functions;
370};
371
372struct DataSection : Section {
373  DataSection() : Section(wasm::WASM_SEC_DATA) {}
374
375  static bool classof(const Section *S) {
376    return S->Type == wasm::WASM_SEC_DATA;
377  }
378
379  std::vector<DataSegment> Segments;
380};
381
382struct DataCountSection : Section {
383  DataCountSection() : Section(wasm::WASM_SEC_DATACOUNT) {}
384
385  static bool classof(const Section *S) {
386    return S->Type == wasm::WASM_SEC_DATACOUNT;
387  }
388
389  uint32_t Count;
390};
391
392struct Object {
393  FileHeader Header;
394  std::vector<std::unique_ptr<Section>> Sections;
395};
396
397} // end namespace WasmYAML
398} // end namespace llvm
399
400LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::WasmYAML::Section>)
401LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature)
402LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ValueType)
403LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Table)
404LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Import)
405LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Export)
406LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ElemSegment)
407LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Limits)
408LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DataSegment)
409LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Global)
410LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function)
411LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl)
412LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
413LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
414LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ProducerEntry)
415LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::FeatureEntry)
416LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo)
417LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
418LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction)
419LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ComdatEntry)
420LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Comdat)
421LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Event)
422
423namespace llvm {
424namespace yaml {
425
426template <> struct MappingTraits<WasmYAML::FileHeader> {
427  static void mapping(IO &IO, WasmYAML::FileHeader &FileHdr);
428};
429
430template <> struct MappingTraits<std::unique_ptr<WasmYAML::Section>> {
431  static void mapping(IO &IO, std::unique_ptr<WasmYAML::Section> &Section);
432};
433
434template <> struct MappingTraits<WasmYAML::Object> {
435  static void mapping(IO &IO, WasmYAML::Object &Object);
436};
437
438template <> struct MappingTraits<WasmYAML::Import> {
439  static void mapping(IO &IO, WasmYAML::Import &Import);
440};
441
442template <> struct MappingTraits<WasmYAML::Export> {
443  static void mapping(IO &IO, WasmYAML::Export &Export);
444};
445
446template <> struct MappingTraits<WasmYAML::Global> {
447  static void mapping(IO &IO, WasmYAML::Global &Global);
448};
449
450template <> struct ScalarBitSetTraits<WasmYAML::LimitFlags> {
451  static void bitset(IO &IO, WasmYAML::LimitFlags &Value);
452};
453
454template <> struct ScalarBitSetTraits<WasmYAML::SymbolFlags> {
455  static void bitset(IO &IO, WasmYAML::SymbolFlags &Value);
456};
457
458template <> struct ScalarEnumerationTraits<WasmYAML::SymbolKind> {
459  static void enumeration(IO &IO, WasmYAML::SymbolKind &Kind);
460};
461
462template <> struct ScalarBitSetTraits<WasmYAML::SegmentFlags> {
463  static void bitset(IO &IO, WasmYAML::SegmentFlags &Value);
464};
465
466template <> struct ScalarEnumerationTraits<WasmYAML::SectionType> {
467  static void enumeration(IO &IO, WasmYAML::SectionType &Type);
468};
469
470template <> struct MappingTraits<WasmYAML::Signature> {
471  static void mapping(IO &IO, WasmYAML::Signature &Signature);
472};
473
474template <> struct MappingTraits<WasmYAML::Table> {
475  static void mapping(IO &IO, WasmYAML::Table &Table);
476};
477
478template <> struct MappingTraits<WasmYAML::Limits> {
479  static void mapping(IO &IO, WasmYAML::Limits &Limits);
480};
481
482template <> struct MappingTraits<WasmYAML::Function> {
483  static void mapping(IO &IO, WasmYAML::Function &Function);
484};
485
486template <> struct MappingTraits<WasmYAML::Relocation> {
487  static void mapping(IO &IO, WasmYAML::Relocation &Relocation);
488};
489
490template <> struct MappingTraits<WasmYAML::NameEntry> {
491  static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry);
492};
493
494template <> struct MappingTraits<WasmYAML::ProducerEntry> {
495  static void mapping(IO &IO, WasmYAML::ProducerEntry &ProducerEntry);
496};
497
498template <> struct ScalarEnumerationTraits<WasmYAML::FeaturePolicyPrefix> {
499  static void enumeration(IO &IO, WasmYAML::FeaturePolicyPrefix &Prefix);
500};
501
502template <> struct MappingTraits<WasmYAML::FeatureEntry> {
503  static void mapping(IO &IO, WasmYAML::FeatureEntry &FeatureEntry);
504};
505
506template <> struct MappingTraits<WasmYAML::SegmentInfo> {
507  static void mapping(IO &IO, WasmYAML::SegmentInfo &SegmentInfo);
508};
509
510template <> struct MappingTraits<WasmYAML::LocalDecl> {
511  static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl);
512};
513
514template <> struct MappingTraits<wasm::WasmInitExpr> {
515  static void mapping(IO &IO, wasm::WasmInitExpr &Expr);
516};
517
518template <> struct MappingTraits<WasmYAML::DataSegment> {
519  static void mapping(IO &IO, WasmYAML::DataSegment &Segment);
520};
521
522template <> struct MappingTraits<WasmYAML::ElemSegment> {
523  static void mapping(IO &IO, WasmYAML::ElemSegment &Segment);
524};
525
526template <> struct MappingTraits<WasmYAML::SymbolInfo> {
527  static void mapping(IO &IO, WasmYAML::SymbolInfo &Info);
528};
529
530template <> struct MappingTraits<WasmYAML::InitFunction> {
531  static void mapping(IO &IO, WasmYAML::InitFunction &Init);
532};
533
534template <> struct ScalarEnumerationTraits<WasmYAML::ComdatKind> {
535  static void enumeration(IO &IO, WasmYAML::ComdatKind &Kind);
536};
537
538template <> struct MappingTraits<WasmYAML::ComdatEntry> {
539  static void mapping(IO &IO, WasmYAML::ComdatEntry &ComdatEntry);
540};
541
542template <> struct MappingTraits<WasmYAML::Comdat> {
543  static void mapping(IO &IO, WasmYAML::Comdat &Comdat);
544};
545
546template <> struct ScalarEnumerationTraits<WasmYAML::ValueType> {
547  static void enumeration(IO &IO, WasmYAML::ValueType &Type);
548};
549
550template <> struct ScalarEnumerationTraits<WasmYAML::ExportKind> {
551  static void enumeration(IO &IO, WasmYAML::ExportKind &Kind);
552};
553
554template <> struct ScalarEnumerationTraits<WasmYAML::TableType> {
555  static void enumeration(IO &IO, WasmYAML::TableType &Type);
556};
557
558template <> struct ScalarEnumerationTraits<WasmYAML::Opcode> {
559  static void enumeration(IO &IO, WasmYAML::Opcode &Opcode);
560};
561
562template <> struct ScalarEnumerationTraits<WasmYAML::RelocType> {
563  static void enumeration(IO &IO, WasmYAML::RelocType &Kind);
564};
565
566template <> struct MappingTraits<WasmYAML::Event> {
567  static void mapping(IO &IO, WasmYAML::Event &Event);
568};
569
570} // end namespace yaml
571} // end namespace llvm
572
573#endif // LLVM_OBJECTYAML_WASMYAML_H
574