xref: /freebsd/contrib/llvm-project/llvm/include/llvm/ObjectYAML/WasmYAML.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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   yaml::Hex32 PageSize;
52 };
53 
54 struct Table {
55   TableType ElemType;
56   Limits TableLimits;
57   uint32_t Index;
58 };
59 
60 struct Export {
61   StringRef Name;
62   ExportKind Kind;
63   uint32_t Index;
64 };
65 
66 struct InitExpr {
InitExprInitExpr67   InitExpr() {}
68   bool Extended;
69   union {
70     wasm::WasmInitExprMVP Inst;
71     yaml::BinaryRef Body;
72   };
73 };
74 
75 struct ElemSegment {
76   uint32_t Flags;
77   uint32_t TableNumber;
78   ValueType ElemKind;
79   InitExpr Offset;
80   std::vector<uint32_t> Functions;
81 };
82 
83 struct Global {
84   uint32_t Index;
85   ValueType Type;
86   bool Mutable;
87   InitExpr Init;
88 };
89 
90 struct Import {
ImportImport91   Import() {}
92   StringRef Module;
93   StringRef Field;
94   ExportKind Kind;
95   union {
96     uint32_t SigIndex;
97     Table TableImport;
98     Limits Memory;
99     uint32_t TagIndex;
100     Global GlobalImport;
101   };
102 };
103 
104 struct LocalDecl {
105   ValueType Type;
106   uint32_t Count;
107 };
108 
109 struct Function {
110   uint32_t Index;
111   std::vector<LocalDecl> Locals;
112   yaml::BinaryRef Body;
113 };
114 
115 struct Relocation {
116   RelocType Type;
117   uint32_t Index;
118   // TODO(wvo): this would strictly be better as Hex64, but that will change
119   // all existing obj2yaml output.
120   yaml::Hex32 Offset;
121   int64_t Addend;
122 };
123 
124 struct DataSegment {
125   uint32_t SectionOffset;
126   uint32_t InitFlags;
127   uint32_t MemoryIndex;
128   InitExpr Offset;
129   yaml::BinaryRef Content;
130 };
131 
132 struct NameEntry {
133   uint32_t Index;
134   StringRef Name;
135 };
136 
137 struct ProducerEntry {
138   std::string Name;
139   std::string Version;
140 };
141 
142 struct FeatureEntry {
143   FeaturePolicyPrefix Prefix;
144   std::string Name;
145 };
146 
147 struct SegmentInfo {
148   uint32_t Index;
149   StringRef Name;
150   uint32_t Alignment;
151   SegmentFlags Flags;
152 };
153 
154 struct Signature {
155   uint32_t Index;
156   SignatureForm Form = wasm::WASM_TYPE_FUNC;
157   std::vector<ValueType> ParamTypes;
158   std::vector<ValueType> ReturnTypes;
159 };
160 
161 struct SymbolInfo {
162   uint32_t Index;
163   StringRef Name;
164   SymbolKind Kind;
165   SymbolFlags Flags;
166   union {
167     uint32_t ElementIndex;
168     wasm::WasmDataReference DataRef;
169   };
170 };
171 
172 struct InitFunction {
173   uint32_t Priority;
174   uint32_t Symbol;
175 };
176 
177 struct ComdatEntry {
178   ComdatKind Kind;
179   uint32_t Index;
180 };
181 
182 struct Comdat {
183   StringRef Name;
184   std::vector<ComdatEntry> Entries;
185 };
186 
187 struct Section {
SectionSection188   explicit Section(SectionType SecType) : Type(SecType) {}
189   virtual ~Section();
190 
191   SectionType Type;
192   std::vector<Relocation> Relocations;
193   std::optional<uint8_t> HeaderSecSizeEncodingLen;
194 };
195 
196 struct CustomSection : Section {
CustomSectionCustomSection197   explicit CustomSection(StringRef Name)
198       : Section(wasm::WASM_SEC_CUSTOM), Name(Name) {}
199 
classofCustomSection200   static bool classof(const Section *S) {
201     return S->Type == wasm::WASM_SEC_CUSTOM;
202   }
203 
204   StringRef Name;
205   yaml::BinaryRef Payload;
206 };
207 
208 struct DylinkImportInfo {
209   StringRef Module;
210   StringRef Field;
211   SymbolFlags Flags;
212 };
213 
214 struct DylinkExportInfo {
215   StringRef Name;
216   SymbolFlags Flags;
217 };
218 
219 struct DylinkSection : CustomSection {
DylinkSectionDylinkSection220   DylinkSection() : CustomSection("dylink.0") {}
221 
classofDylinkSection222   static bool classof(const Section *S) {
223     auto C = dyn_cast<CustomSection>(S);
224     return C && C->Name == "dylink.0";
225   }
226 
227   uint32_t MemorySize;
228   uint32_t MemoryAlignment;
229   uint32_t TableSize;
230   uint32_t TableAlignment;
231   std::vector<StringRef> Needed;
232   std::vector<DylinkImportInfo> ImportInfo;
233   std::vector<DylinkExportInfo> ExportInfo;
234   std::vector<StringRef> RuntimePath;
235 };
236 
237 struct NameSection : CustomSection {
NameSectionNameSection238   NameSection() : CustomSection("name") {}
239 
classofNameSection240   static bool classof(const Section *S) {
241     auto C = dyn_cast<CustomSection>(S);
242     return C && C->Name == "name";
243   }
244 
245   std::vector<NameEntry> FunctionNames;
246   std::vector<NameEntry> GlobalNames;
247   std::vector<NameEntry> DataSegmentNames;
248 };
249 
250 struct LinkingSection : CustomSection {
LinkingSectionLinkingSection251   LinkingSection() : CustomSection("linking") {}
252 
classofLinkingSection253   static bool classof(const Section *S) {
254     auto C = dyn_cast<CustomSection>(S);
255     return C && C->Name == "linking";
256   }
257 
258   uint32_t Version;
259   std::vector<SymbolInfo> SymbolTable;
260   std::vector<SegmentInfo> SegmentInfos;
261   std::vector<InitFunction> InitFunctions;
262   std::vector<Comdat> Comdats;
263 };
264 
265 struct ProducersSection : CustomSection {
ProducersSectionProducersSection266   ProducersSection() : CustomSection("producers") {}
267 
classofProducersSection268   static bool classof(const Section *S) {
269     auto C = dyn_cast<CustomSection>(S);
270     return C && C->Name == "producers";
271   }
272 
273   std::vector<ProducerEntry> Languages;
274   std::vector<ProducerEntry> Tools;
275   std::vector<ProducerEntry> SDKs;
276 };
277 
278 struct TargetFeaturesSection : CustomSection {
TargetFeaturesSectionTargetFeaturesSection279   TargetFeaturesSection() : CustomSection("target_features") {}
280 
classofTargetFeaturesSection281   static bool classof(const Section *S) {
282     auto C = dyn_cast<CustomSection>(S);
283     return C && C->Name == "target_features";
284   }
285 
286   std::vector<FeatureEntry> Features;
287 };
288 
289 struct TypeSection : Section {
TypeSectionTypeSection290   TypeSection() : Section(wasm::WASM_SEC_TYPE) {}
291 
classofTypeSection292   static bool classof(const Section *S) {
293     return S->Type == wasm::WASM_SEC_TYPE;
294   }
295 
296   std::vector<Signature> Signatures;
297 };
298 
299 struct ImportSection : Section {
ImportSectionImportSection300   ImportSection() : Section(wasm::WASM_SEC_IMPORT) {}
301 
classofImportSection302   static bool classof(const Section *S) {
303     return S->Type == wasm::WASM_SEC_IMPORT;
304   }
305 
306   std::vector<Import> Imports;
307 };
308 
309 struct FunctionSection : Section {
FunctionSectionFunctionSection310   FunctionSection() : Section(wasm::WASM_SEC_FUNCTION) {}
311 
classofFunctionSection312   static bool classof(const Section *S) {
313     return S->Type == wasm::WASM_SEC_FUNCTION;
314   }
315 
316   std::vector<uint32_t> FunctionTypes;
317 };
318 
319 struct TableSection : Section {
TableSectionTableSection320   TableSection() : Section(wasm::WASM_SEC_TABLE) {}
321 
classofTableSection322   static bool classof(const Section *S) {
323     return S->Type == wasm::WASM_SEC_TABLE;
324   }
325 
326   std::vector<Table> Tables;
327 };
328 
329 struct MemorySection : Section {
MemorySectionMemorySection330   MemorySection() : Section(wasm::WASM_SEC_MEMORY) {}
331 
classofMemorySection332   static bool classof(const Section *S) {
333     return S->Type == wasm::WASM_SEC_MEMORY;
334   }
335 
336   std::vector<Limits> Memories;
337 };
338 
339 struct TagSection : Section {
TagSectionTagSection340   TagSection() : Section(wasm::WASM_SEC_TAG) {}
341 
classofTagSection342   static bool classof(const Section *S) {
343     return S->Type == wasm::WASM_SEC_TAG;
344   }
345 
346   std::vector<uint32_t> TagTypes;
347 };
348 
349 struct GlobalSection : Section {
GlobalSectionGlobalSection350   GlobalSection() : Section(wasm::WASM_SEC_GLOBAL) {}
351 
classofGlobalSection352   static bool classof(const Section *S) {
353     return S->Type == wasm::WASM_SEC_GLOBAL;
354   }
355 
356   std::vector<Global> Globals;
357 };
358 
359 struct ExportSection : Section {
ExportSectionExportSection360   ExportSection() : Section(wasm::WASM_SEC_EXPORT) {}
361 
classofExportSection362   static bool classof(const Section *S) {
363     return S->Type == wasm::WASM_SEC_EXPORT;
364   }
365 
366   std::vector<Export> Exports;
367 };
368 
369 struct StartSection : Section {
StartSectionStartSection370   StartSection() : Section(wasm::WASM_SEC_START) {}
371 
classofStartSection372   static bool classof(const Section *S) {
373     return S->Type == wasm::WASM_SEC_START;
374   }
375 
376   uint32_t StartFunction;
377 };
378 
379 struct ElemSection : Section {
ElemSectionElemSection380   ElemSection() : Section(wasm::WASM_SEC_ELEM) {}
381 
classofElemSection382   static bool classof(const Section *S) {
383     return S->Type == wasm::WASM_SEC_ELEM;
384   }
385 
386   std::vector<ElemSegment> Segments;
387 };
388 
389 struct CodeSection : Section {
CodeSectionCodeSection390   CodeSection() : Section(wasm::WASM_SEC_CODE) {}
391 
classofCodeSection392   static bool classof(const Section *S) {
393     return S->Type == wasm::WASM_SEC_CODE;
394   }
395 
396   std::vector<Function> Functions;
397 };
398 
399 struct DataSection : Section {
DataSectionDataSection400   DataSection() : Section(wasm::WASM_SEC_DATA) {}
401 
classofDataSection402   static bool classof(const Section *S) {
403     return S->Type == wasm::WASM_SEC_DATA;
404   }
405 
406   std::vector<DataSegment> Segments;
407 };
408 
409 struct DataCountSection : Section {
DataCountSectionDataCountSection410   DataCountSection() : Section(wasm::WASM_SEC_DATACOUNT) {}
411 
classofDataCountSection412   static bool classof(const Section *S) {
413     return S->Type == wasm::WASM_SEC_DATACOUNT;
414   }
415 
416   uint32_t Count;
417 };
418 
419 struct Object {
420   FileHeader Header;
421   std::vector<std::unique_ptr<Section>> Sections;
422 };
423 
424 } // end namespace WasmYAML
425 } // end namespace llvm
426 
427 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::WasmYAML::Section>)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature)428 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature)
429 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ValueType)
430 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Table)
431 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Import)
432 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Export)
433 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ElemSegment)
434 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Limits)
435 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DataSegment)
436 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Global)
437 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function)
438 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl)
439 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
440 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
441 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ProducerEntry)
442 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::FeatureEntry)
443 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo)
444 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
445 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction)
446 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ComdatEntry)
447 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Comdat)
448 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DylinkImportInfo)
449 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DylinkExportInfo)
450 
451 namespace llvm {
452 namespace yaml {
453 
454 template <> struct MappingTraits<WasmYAML::FileHeader> {
455   static void mapping(IO &IO, WasmYAML::FileHeader &FileHdr);
456 };
457 
458 template <> struct MappingTraits<std::unique_ptr<WasmYAML::Section>> {
459   static void mapping(IO &IO, std::unique_ptr<WasmYAML::Section> &Section);
460 };
461 
462 template <> struct MappingTraits<WasmYAML::Object> {
463   static void mapping(IO &IO, WasmYAML::Object &Object);
464 };
465 
466 template <> struct MappingTraits<WasmYAML::Import> {
467   static void mapping(IO &IO, WasmYAML::Import &Import);
468 };
469 
470 template <> struct MappingTraits<WasmYAML::Export> {
471   static void mapping(IO &IO, WasmYAML::Export &Export);
472 };
473 
474 template <> struct MappingTraits<WasmYAML::Global> {
475   static void mapping(IO &IO, WasmYAML::Global &Global);
476 };
477 
478 template <> struct ScalarBitSetTraits<WasmYAML::LimitFlags> {
479   static void bitset(IO &IO, WasmYAML::LimitFlags &Value);
480 };
481 
482 template <> struct ScalarBitSetTraits<WasmYAML::SymbolFlags> {
483   static void bitset(IO &IO, WasmYAML::SymbolFlags &Value);
484 };
485 
486 template <> struct ScalarEnumerationTraits<WasmYAML::SymbolKind> {
487   static void enumeration(IO &IO, WasmYAML::SymbolKind &Kind);
488 };
489 
490 template <> struct ScalarBitSetTraits<WasmYAML::SegmentFlags> {
491   static void bitset(IO &IO, WasmYAML::SegmentFlags &Value);
492 };
493 
494 template <> struct ScalarEnumerationTraits<WasmYAML::SectionType> {
495   static void enumeration(IO &IO, WasmYAML::SectionType &Type);
496 };
497 
498 template <> struct MappingTraits<WasmYAML::Signature> {
499   static void mapping(IO &IO, WasmYAML::Signature &Signature);
500 };
501 
502 template <> struct MappingTraits<WasmYAML::Table> {
503   static void mapping(IO &IO, WasmYAML::Table &Table);
504 };
505 
506 template <> struct MappingTraits<WasmYAML::Limits> {
507   static void mapping(IO &IO, WasmYAML::Limits &Limits);
508 };
509 
510 template <> struct MappingTraits<WasmYAML::Function> {
511   static void mapping(IO &IO, WasmYAML::Function &Function);
512 };
513 
514 template <> struct MappingTraits<WasmYAML::Relocation> {
515   static void mapping(IO &IO, WasmYAML::Relocation &Relocation);
516 };
517 
518 template <> struct MappingTraits<WasmYAML::NameEntry> {
519   static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry);
520 };
521 
522 template <> struct MappingTraits<WasmYAML::ProducerEntry> {
523   static void mapping(IO &IO, WasmYAML::ProducerEntry &ProducerEntry);
524 };
525 
526 template <> struct ScalarEnumerationTraits<WasmYAML::FeaturePolicyPrefix> {
527   static void enumeration(IO &IO, WasmYAML::FeaturePolicyPrefix &Prefix);
528 };
529 
530 template <> struct MappingTraits<WasmYAML::FeatureEntry> {
531   static void mapping(IO &IO, WasmYAML::FeatureEntry &FeatureEntry);
532 };
533 
534 template <> struct MappingTraits<WasmYAML::SegmentInfo> {
535   static void mapping(IO &IO, WasmYAML::SegmentInfo &SegmentInfo);
536 };
537 
538 template <> struct MappingTraits<WasmYAML::LocalDecl> {
539   static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl);
540 };
541 
542 template <> struct MappingTraits<WasmYAML::InitExpr> {
543   static void mapping(IO &IO, WasmYAML::InitExpr &Expr);
544 };
545 
546 template <> struct MappingTraits<WasmYAML::DataSegment> {
547   static void mapping(IO &IO, WasmYAML::DataSegment &Segment);
548 };
549 
550 template <> struct MappingTraits<WasmYAML::ElemSegment> {
551   static void mapping(IO &IO, WasmYAML::ElemSegment &Segment);
552 };
553 
554 template <> struct MappingTraits<WasmYAML::SymbolInfo> {
555   static void mapping(IO &IO, WasmYAML::SymbolInfo &Info);
556 };
557 
558 template <> struct MappingTraits<WasmYAML::InitFunction> {
559   static void mapping(IO &IO, WasmYAML::InitFunction &Init);
560 };
561 
562 template <> struct ScalarEnumerationTraits<WasmYAML::ComdatKind> {
563   static void enumeration(IO &IO, WasmYAML::ComdatKind &Kind);
564 };
565 
566 template <> struct MappingTraits<WasmYAML::ComdatEntry> {
567   static void mapping(IO &IO, WasmYAML::ComdatEntry &ComdatEntry);
568 };
569 
570 template <> struct MappingTraits<WasmYAML::Comdat> {
571   static void mapping(IO &IO, WasmYAML::Comdat &Comdat);
572 };
573 
574 template <> struct ScalarEnumerationTraits<WasmYAML::ValueType> {
575   static void enumeration(IO &IO, WasmYAML::ValueType &Type);
576 };
577 
578 template <> struct ScalarEnumerationTraits<WasmYAML::ExportKind> {
579   static void enumeration(IO &IO, WasmYAML::ExportKind &Kind);
580 };
581 
582 template <> struct ScalarEnumerationTraits<WasmYAML::TableType> {
583   static void enumeration(IO &IO, WasmYAML::TableType &Type);
584 };
585 
586 template <> struct ScalarEnumerationTraits<WasmYAML::Opcode> {
587   static void enumeration(IO &IO, WasmYAML::Opcode &Opcode);
588 };
589 
590 template <> struct ScalarEnumerationTraits<WasmYAML::RelocType> {
591   static void enumeration(IO &IO, WasmYAML::RelocType &Kind);
592 };
593 
594 template <> struct MappingTraits<WasmYAML::DylinkImportInfo> {
595   static void mapping(IO &IO, WasmYAML::DylinkImportInfo &Info);
596 };
597 
598 template <> struct MappingTraits<WasmYAML::DylinkExportInfo> {
599   static void mapping(IO &IO, WasmYAML::DylinkExportInfo &Info);
600 };
601 
602 } // end namespace yaml
603 } // end namespace llvm
604 
605 #endif // LLVM_OBJECTYAML_WASMYAML_H
606