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