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