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

source code of llvm/include/llvm/ObjectYAML/WasmYAML.h