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 Initial;
50   yaml::Hex32 Maximum;
51 };
52 
53 struct Table {
54   TableType ElemType;
55   Limits TableLimits;
56 };
57 
58 struct Export {
59   StringRef Name;
60   ExportKind Kind;
61   uint32_t Index;
62 };
63 
64 struct ElemSegment {
65   uint32_t TableIndex;
66   wasm::WasmInitExpr Offset;
67   std::vector<uint32_t> Functions;
68 };
69 
70 struct Global {
71   uint32_t Index;
72   ValueType Type;
73   bool Mutable;
74   wasm::WasmInitExpr InitExpr;
75 };
76 
77 struct Event {
78   uint32_t Index;
79   uint32_t Attribute;
80   uint32_t SigIndex;
81 };
82 
83 struct 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 
96 struct LocalDecl {
97   ValueType Type;
98   uint32_t Count;
99 };
100 
101 struct Function {
102   uint32_t Index;
103   std::vector<LocalDecl> Locals;
104   yaml::BinaryRef Body;
105 };
106 
107 struct Relocation {
108   RelocType Type;
109   uint32_t Index;
110   yaml::Hex32 Offset;
111   int32_t Addend;
112 };
113 
114 struct DataSegment {
115   uint32_t SectionOffset;
116   uint32_t InitFlags;
117   uint32_t MemoryIndex;
118   wasm::WasmInitExpr Offset;
119   yaml::BinaryRef Content;
120 };
121 
122 struct NameEntry {
123   uint32_t Index;
124   StringRef Name;
125 };
126 
127 struct ProducerEntry {
128   std::string Name;
129   std::string Version;
130 };
131 
132 struct FeatureEntry {
133   FeaturePolicyPrefix Prefix;
134   std::string Name;
135 };
136 
137 struct SegmentInfo {
138   uint32_t Index;
139   StringRef Name;
140   uint32_t Alignment;
141   SegmentFlags Flags;
142 };
143 
144 struct Signature {
145   uint32_t Index;
146   SignatureForm Form = wasm::WASM_TYPE_FUNC;
147   std::vector<ValueType> ParamTypes;
148   std::vector<ValueType> ReturnTypes;
149 };
150 
151 struct 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 
162 struct InitFunction {
163   uint32_t Priority;
164   uint32_t Symbol;
165 };
166 
167 struct ComdatEntry {
168   ComdatKind Kind;
169   uint32_t Index;
170 };
171 
172 struct Comdat {
173   StringRef Name;
174   std::vector<ComdatEntry> Entries;
175 };
176 
177 struct Section {
178   explicit Section(SectionType SecType) : Type(SecType) {}
179   virtual ~Section();
180 
181   SectionType Type;
182   std::vector<Relocation> Relocations;
183 };
184 
185 struct 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 
197 struct 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 
212 struct 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 
223 struct 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 
238 struct 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 
251 struct 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 
262 struct 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 
272 struct 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 
282 struct 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 
292 struct 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 
302 struct 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 
312 struct 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 
322 struct 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 
332 struct 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 
342 struct 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 
352 struct 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 
362 struct 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 
372 struct 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 
382 struct 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 
392 struct Object {
393   FileHeader Header;
394   std::vector<std::unique_ptr<Section>> Sections;
395 };
396 
397 } // end namespace WasmYAML
398 } // end namespace llvm
399 
400 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::WasmYAML::Section>)
401 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature)
402 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ValueType)
403 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Table)
404 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Import)
405 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Export)
406 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ElemSegment)
407 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Limits)
408 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DataSegment)
409 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Global)
410 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function)
411 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl)
412 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
413 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
414 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ProducerEntry)
415 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::FeatureEntry)
416 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo)
417 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
418 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction)
419 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ComdatEntry)
420 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Comdat)
421 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Event)
422 
423 namespace llvm {
424 namespace yaml {
425 
426 template <> struct MappingTraits<WasmYAML::FileHeader> {
427   static void mapping(IO &IO, WasmYAML::FileHeader &FileHdr);
428 };
429 
430 template <> struct MappingTraits<std::unique_ptr<WasmYAML::Section>> {
431   static void mapping(IO &IO, std::unique_ptr<WasmYAML::Section> &Section);
432 };
433 
434 template <> struct MappingTraits<WasmYAML::Object> {
435   static void mapping(IO &IO, WasmYAML::Object &Object);
436 };
437 
438 template <> struct MappingTraits<WasmYAML::Import> {
439   static void mapping(IO &IO, WasmYAML::Import &Import);
440 };
441 
442 template <> struct MappingTraits<WasmYAML::Export> {
443   static void mapping(IO &IO, WasmYAML::Export &Export);
444 };
445 
446 template <> struct MappingTraits<WasmYAML::Global> {
447   static void mapping(IO &IO, WasmYAML::Global &Global);
448 };
449 
450 template <> struct ScalarBitSetTraits<WasmYAML::LimitFlags> {
451   static void bitset(IO &IO, WasmYAML::LimitFlags &Value);
452 };
453 
454 template <> struct ScalarBitSetTraits<WasmYAML::SymbolFlags> {
455   static void bitset(IO &IO, WasmYAML::SymbolFlags &Value);
456 };
457 
458 template <> struct ScalarEnumerationTraits<WasmYAML::SymbolKind> {
459   static void enumeration(IO &IO, WasmYAML::SymbolKind &Kind);
460 };
461 
462 template <> struct ScalarBitSetTraits<WasmYAML::SegmentFlags> {
463   static void bitset(IO &IO, WasmYAML::SegmentFlags &Value);
464 };
465 
466 template <> struct ScalarEnumerationTraits<WasmYAML::SectionType> {
467   static void enumeration(IO &IO, WasmYAML::SectionType &Type);
468 };
469 
470 template <> struct MappingTraits<WasmYAML::Signature> {
471   static void mapping(IO &IO, WasmYAML::Signature &Signature);
472 };
473 
474 template <> struct MappingTraits<WasmYAML::Table> {
475   static void mapping(IO &IO, WasmYAML::Table &Table);
476 };
477 
478 template <> struct MappingTraits<WasmYAML::Limits> {
479   static void mapping(IO &IO, WasmYAML::Limits &Limits);
480 };
481 
482 template <> struct MappingTraits<WasmYAML::Function> {
483   static void mapping(IO &IO, WasmYAML::Function &Function);
484 };
485 
486 template <> struct MappingTraits<WasmYAML::Relocation> {
487   static void mapping(IO &IO, WasmYAML::Relocation &Relocation);
488 };
489 
490 template <> struct MappingTraits<WasmYAML::NameEntry> {
491   static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry);
492 };
493 
494 template <> struct MappingTraits<WasmYAML::ProducerEntry> {
495   static void mapping(IO &IO, WasmYAML::ProducerEntry &ProducerEntry);
496 };
497 
498 template <> struct ScalarEnumerationTraits<WasmYAML::FeaturePolicyPrefix> {
499   static void enumeration(IO &IO, WasmYAML::FeaturePolicyPrefix &Prefix);
500 };
501 
502 template <> struct MappingTraits<WasmYAML::FeatureEntry> {
503   static void mapping(IO &IO, WasmYAML::FeatureEntry &FeatureEntry);
504 };
505 
506 template <> struct MappingTraits<WasmYAML::SegmentInfo> {
507   static void mapping(IO &IO, WasmYAML::SegmentInfo &SegmentInfo);
508 };
509 
510 template <> struct MappingTraits<WasmYAML::LocalDecl> {
511   static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl);
512 };
513 
514 template <> struct MappingTraits<wasm::WasmInitExpr> {
515   static void mapping(IO &IO, wasm::WasmInitExpr &Expr);
516 };
517 
518 template <> struct MappingTraits<WasmYAML::DataSegment> {
519   static void mapping(IO &IO, WasmYAML::DataSegment &Segment);
520 };
521 
522 template <> struct MappingTraits<WasmYAML::ElemSegment> {
523   static void mapping(IO &IO, WasmYAML::ElemSegment &Segment);
524 };
525 
526 template <> struct MappingTraits<WasmYAML::SymbolInfo> {
527   static void mapping(IO &IO, WasmYAML::SymbolInfo &Info);
528 };
529 
530 template <> struct MappingTraits<WasmYAML::InitFunction> {
531   static void mapping(IO &IO, WasmYAML::InitFunction &Init);
532 };
533 
534 template <> struct ScalarEnumerationTraits<WasmYAML::ComdatKind> {
535   static void enumeration(IO &IO, WasmYAML::ComdatKind &Kind);
536 };
537 
538 template <> struct MappingTraits<WasmYAML::ComdatEntry> {
539   static void mapping(IO &IO, WasmYAML::ComdatEntry &ComdatEntry);
540 };
541 
542 template <> struct MappingTraits<WasmYAML::Comdat> {
543   static void mapping(IO &IO, WasmYAML::Comdat &Comdat);
544 };
545 
546 template <> struct ScalarEnumerationTraits<WasmYAML::ValueType> {
547   static void enumeration(IO &IO, WasmYAML::ValueType &Type);
548 };
549 
550 template <> struct ScalarEnumerationTraits<WasmYAML::ExportKind> {
551   static void enumeration(IO &IO, WasmYAML::ExportKind &Kind);
552 };
553 
554 template <> struct ScalarEnumerationTraits<WasmYAML::TableType> {
555   static void enumeration(IO &IO, WasmYAML::TableType &Type);
556 };
557 
558 template <> struct ScalarEnumerationTraits<WasmYAML::Opcode> {
559   static void enumeration(IO &IO, WasmYAML::Opcode &Opcode);
560 };
561 
562 template <> struct ScalarEnumerationTraits<WasmYAML::RelocType> {
563   static void enumeration(IO &IO, WasmYAML::RelocType &Kind);
564 };
565 
566 template <> 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