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