blob: 80f1b4006205d056de2dc424f97f4aa5d6ad89aa [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- WasmYAML.h - Wasm YAMLIO implementation ------------------*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8///
9/// \file
Andrew Scullcdfcccc2018-10-05 20:58:37 +010010/// This file declares classes for handling the YAML representation
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010011/// 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)
Andrew Walbran3d2c1972020-04-07 12:24:26 +010041LLVM_YAML_STRONG_TYPEDEF(uint32_t, FeaturePolicyPrefix)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010042
43struct FileHeader {
44 yaml::Hex32 Version;
45};
46
47struct Limits {
48 LimitFlags Flags;
49 yaml::Hex32 Initial;
50 yaml::Hex32 Maximum;
51};
52
53struct Table {
54 TableType ElemType;
55 Limits TableLimits;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020056 uint32_t Index;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010057};
58
59struct Export {
60 StringRef Name;
61 ExportKind Kind;
62 uint32_t Index;
63};
64
65struct ElemSegment {
66 uint32_t TableIndex;
67 wasm::WasmInitExpr Offset;
68 std::vector<uint32_t> Functions;
69};
70
71struct Global {
72 uint32_t Index;
73 ValueType Type;
74 bool Mutable;
75 wasm::WasmInitExpr InitExpr;
76};
77
Andrew Walbran16937d02019-10-22 13:54:20 +010078struct Event {
79 uint32_t Index;
80 uint32_t Attribute;
81 uint32_t SigIndex;
82};
83
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010084struct Import {
85 StringRef Module;
86 StringRef Field;
87 ExportKind Kind;
88 union {
89 uint32_t SigIndex;
90 Global GlobalImport;
91 Table TableImport;
92 Limits Memory;
Andrew Walbran16937d02019-10-22 13:54:20 +010093 Event EventImport;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010094 };
95};
96
97struct LocalDecl {
98 ValueType Type;
99 uint32_t Count;
100};
101
102struct Function {
103 uint32_t Index;
104 std::vector<LocalDecl> Locals;
105 yaml::BinaryRef Body;
106};
107
108struct Relocation {
109 RelocType Type;
110 uint32_t Index;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200111 // TODO(wvo): this would strictly be better as Hex64, but that will change
112 // all existing obj2yaml output.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100113 yaml::Hex32 Offset;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200114 int64_t Addend;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100115};
116
117struct DataSegment {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100118 uint32_t SectionOffset;
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100119 uint32_t InitFlags;
120 uint32_t MemoryIndex;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100121 wasm::WasmInitExpr Offset;
122 yaml::BinaryRef Content;
123};
124
125struct NameEntry {
126 uint32_t Index;
127 StringRef Name;
128};
129
Andrew Walbran16937d02019-10-22 13:54:20 +0100130struct ProducerEntry {
131 std::string Name;
132 std::string Version;
133};
134
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100135struct FeatureEntry {
136 FeaturePolicyPrefix Prefix;
137 std::string Name;
138};
139
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100140struct SegmentInfo {
141 uint32_t Index;
142 StringRef Name;
143 uint32_t Alignment;
144 SegmentFlags Flags;
145};
146
147struct Signature {
148 uint32_t Index;
149 SignatureForm Form = wasm::WASM_TYPE_FUNC;
150 std::vector<ValueType> ParamTypes;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200151 std::vector<ValueType> ReturnTypes;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100152};
153
154struct SymbolInfo {
155 uint32_t Index;
156 StringRef Name;
157 SymbolKind Kind;
158 SymbolFlags Flags;
159 union {
160 uint32_t ElementIndex;
161 wasm::WasmDataReference DataRef;
162 };
163};
164
165struct InitFunction {
166 uint32_t Priority;
167 uint32_t Symbol;
168};
169
170struct ComdatEntry {
171 ComdatKind Kind;
172 uint32_t Index;
173};
174
175struct Comdat {
176 StringRef Name;
177 std::vector<ComdatEntry> Entries;
178};
179
180struct Section {
181 explicit Section(SectionType SecType) : Type(SecType) {}
182 virtual ~Section();
183
184 SectionType Type;
185 std::vector<Relocation> Relocations;
186};
187
188struct CustomSection : Section {
189 explicit CustomSection(StringRef Name)
190 : Section(wasm::WASM_SEC_CUSTOM), Name(Name) {}
191
192 static bool classof(const Section *S) {
193 return S->Type == wasm::WASM_SEC_CUSTOM;
194 }
195
196 StringRef Name;
197 yaml::BinaryRef Payload;
198};
199
Andrew Walbran16937d02019-10-22 13:54:20 +0100200struct DylinkSection : CustomSection {
201 DylinkSection() : CustomSection("dylink") {}
202
203 static bool classof(const Section *S) {
204 auto C = dyn_cast<CustomSection>(S);
205 return C && C->Name == "dylink";
206 }
207
208 uint32_t MemorySize;
209 uint32_t MemoryAlignment;
210 uint32_t TableSize;
211 uint32_t TableAlignment;
212 std::vector<StringRef> Needed;
213};
214
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100215struct NameSection : CustomSection {
216 NameSection() : CustomSection("name") {}
217
218 static bool classof(const Section *S) {
219 auto C = dyn_cast<CustomSection>(S);
220 return C && C->Name == "name";
221 }
222
223 std::vector<NameEntry> FunctionNames;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200224 std::vector<NameEntry> GlobalNames;
225 std::vector<NameEntry> DataSegmentNames;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100226};
227
228struct LinkingSection : CustomSection {
229 LinkingSection() : CustomSection("linking") {}
230
231 static bool classof(const Section *S) {
232 auto C = dyn_cast<CustomSection>(S);
233 return C && C->Name == "linking";
234 }
235
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100236 uint32_t Version;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100237 std::vector<SymbolInfo> SymbolTable;
238 std::vector<SegmentInfo> SegmentInfos;
239 std::vector<InitFunction> InitFunctions;
240 std::vector<Comdat> Comdats;
241};
242
Andrew Walbran16937d02019-10-22 13:54:20 +0100243struct ProducersSection : CustomSection {
244 ProducersSection() : CustomSection("producers") {}
245
246 static bool classof(const Section *S) {
247 auto C = dyn_cast<CustomSection>(S);
248 return C && C->Name == "producers";
249 }
250
251 std::vector<ProducerEntry> Languages;
252 std::vector<ProducerEntry> Tools;
253 std::vector<ProducerEntry> SDKs;
254};
255
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100256struct TargetFeaturesSection : CustomSection {
257 TargetFeaturesSection() : CustomSection("target_features") {}
258
259 static bool classof(const Section *S) {
260 auto C = dyn_cast<CustomSection>(S);
261 return C && C->Name == "target_features";
262 }
263
264 std::vector<FeatureEntry> Features;
265};
266
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100267struct TypeSection : Section {
268 TypeSection() : Section(wasm::WASM_SEC_TYPE) {}
269
270 static bool classof(const Section *S) {
271 return S->Type == wasm::WASM_SEC_TYPE;
272 }
273
274 std::vector<Signature> Signatures;
275};
276
277struct ImportSection : Section {
278 ImportSection() : Section(wasm::WASM_SEC_IMPORT) {}
279
280 static bool classof(const Section *S) {
281 return S->Type == wasm::WASM_SEC_IMPORT;
282 }
283
284 std::vector<Import> Imports;
285};
286
287struct FunctionSection : Section {
288 FunctionSection() : Section(wasm::WASM_SEC_FUNCTION) {}
289
290 static bool classof(const Section *S) {
291 return S->Type == wasm::WASM_SEC_FUNCTION;
292 }
293
294 std::vector<uint32_t> FunctionTypes;
295};
296
297struct TableSection : Section {
298 TableSection() : Section(wasm::WASM_SEC_TABLE) {}
299
300 static bool classof(const Section *S) {
301 return S->Type == wasm::WASM_SEC_TABLE;
302 }
303
304 std::vector<Table> Tables;
305};
306
307struct MemorySection : Section {
308 MemorySection() : Section(wasm::WASM_SEC_MEMORY) {}
309
310 static bool classof(const Section *S) {
311 return S->Type == wasm::WASM_SEC_MEMORY;
312 }
313
314 std::vector<Limits> Memories;
315};
316
Andrew Walbran16937d02019-10-22 13:54:20 +0100317struct EventSection : Section {
318 EventSection() : Section(wasm::WASM_SEC_EVENT) {}
319
320 static bool classof(const Section *S) {
321 return S->Type == wasm::WASM_SEC_EVENT;
322 }
323
324 std::vector<Event> Events;
325};
326
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200327struct GlobalSection : Section {
328 GlobalSection() : Section(wasm::WASM_SEC_GLOBAL) {}
329
330 static bool classof(const Section *S) {
331 return S->Type == wasm::WASM_SEC_GLOBAL;
332 }
333
334 std::vector<Global> Globals;
335};
336
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100337struct ExportSection : Section {
338 ExportSection() : Section(wasm::WASM_SEC_EXPORT) {}
339
340 static bool classof(const Section *S) {
341 return S->Type == wasm::WASM_SEC_EXPORT;
342 }
343
344 std::vector<Export> Exports;
345};
346
347struct StartSection : Section {
348 StartSection() : Section(wasm::WASM_SEC_START) {}
349
350 static bool classof(const Section *S) {
351 return S->Type == wasm::WASM_SEC_START;
352 }
353
354 uint32_t StartFunction;
355};
356
357struct ElemSection : Section {
358 ElemSection() : Section(wasm::WASM_SEC_ELEM) {}
359
360 static bool classof(const Section *S) {
361 return S->Type == wasm::WASM_SEC_ELEM;
362 }
363
364 std::vector<ElemSegment> Segments;
365};
366
367struct CodeSection : Section {
368 CodeSection() : Section(wasm::WASM_SEC_CODE) {}
369
370 static bool classof(const Section *S) {
371 return S->Type == wasm::WASM_SEC_CODE;
372 }
373
374 std::vector<Function> Functions;
375};
376
377struct DataSection : Section {
378 DataSection() : Section(wasm::WASM_SEC_DATA) {}
379
380 static bool classof(const Section *S) {
381 return S->Type == wasm::WASM_SEC_DATA;
382 }
383
384 std::vector<DataSegment> Segments;
385};
386
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100387struct DataCountSection : Section {
388 DataCountSection() : Section(wasm::WASM_SEC_DATACOUNT) {}
389
390 static bool classof(const Section *S) {
391 return S->Type == wasm::WASM_SEC_DATACOUNT;
392 }
393
394 uint32_t Count;
395};
396
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100397struct Object {
398 FileHeader Header;
399 std::vector<std::unique_ptr<Section>> Sections;
400};
401
402} // end namespace WasmYAML
403} // end namespace llvm
404
405LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::WasmYAML::Section>)
406LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature)
407LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ValueType)
408LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Table)
409LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Import)
410LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Export)
411LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ElemSegment)
412LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Limits)
413LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DataSegment)
414LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Global)
415LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function)
416LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl)
417LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
418LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
Andrew Walbran16937d02019-10-22 13:54:20 +0100419LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ProducerEntry)
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100420LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::FeatureEntry)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100421LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo)
422LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
423LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction)
424LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ComdatEntry)
425LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Comdat)
Andrew Walbran16937d02019-10-22 13:54:20 +0100426LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Event)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100427
428namespace llvm {
429namespace yaml {
430
431template <> struct MappingTraits<WasmYAML::FileHeader> {
432 static void mapping(IO &IO, WasmYAML::FileHeader &FileHdr);
433};
434
435template <> struct MappingTraits<std::unique_ptr<WasmYAML::Section>> {
436 static void mapping(IO &IO, std::unique_ptr<WasmYAML::Section> &Section);
437};
438
439template <> struct MappingTraits<WasmYAML::Object> {
440 static void mapping(IO &IO, WasmYAML::Object &Object);
441};
442
443template <> struct MappingTraits<WasmYAML::Import> {
444 static void mapping(IO &IO, WasmYAML::Import &Import);
445};
446
447template <> struct MappingTraits<WasmYAML::Export> {
448 static void mapping(IO &IO, WasmYAML::Export &Export);
449};
450
451template <> struct MappingTraits<WasmYAML::Global> {
452 static void mapping(IO &IO, WasmYAML::Global &Global);
453};
454
455template <> struct ScalarBitSetTraits<WasmYAML::LimitFlags> {
456 static void bitset(IO &IO, WasmYAML::LimitFlags &Value);
457};
458
459template <> struct ScalarBitSetTraits<WasmYAML::SymbolFlags> {
460 static void bitset(IO &IO, WasmYAML::SymbolFlags &Value);
461};
462
463template <> struct ScalarEnumerationTraits<WasmYAML::SymbolKind> {
464 static void enumeration(IO &IO, WasmYAML::SymbolKind &Kind);
465};
466
467template <> struct ScalarBitSetTraits<WasmYAML::SegmentFlags> {
468 static void bitset(IO &IO, WasmYAML::SegmentFlags &Value);
469};
470
471template <> struct ScalarEnumerationTraits<WasmYAML::SectionType> {
472 static void enumeration(IO &IO, WasmYAML::SectionType &Type);
473};
474
475template <> struct MappingTraits<WasmYAML::Signature> {
476 static void mapping(IO &IO, WasmYAML::Signature &Signature);
477};
478
479template <> struct MappingTraits<WasmYAML::Table> {
480 static void mapping(IO &IO, WasmYAML::Table &Table);
481};
482
483template <> struct MappingTraits<WasmYAML::Limits> {
484 static void mapping(IO &IO, WasmYAML::Limits &Limits);
485};
486
487template <> struct MappingTraits<WasmYAML::Function> {
488 static void mapping(IO &IO, WasmYAML::Function &Function);
489};
490
491template <> struct MappingTraits<WasmYAML::Relocation> {
492 static void mapping(IO &IO, WasmYAML::Relocation &Relocation);
493};
494
495template <> struct MappingTraits<WasmYAML::NameEntry> {
496 static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry);
497};
498
Andrew Walbran16937d02019-10-22 13:54:20 +0100499template <> struct MappingTraits<WasmYAML::ProducerEntry> {
500 static void mapping(IO &IO, WasmYAML::ProducerEntry &ProducerEntry);
501};
502
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100503template <> struct ScalarEnumerationTraits<WasmYAML::FeaturePolicyPrefix> {
504 static void enumeration(IO &IO, WasmYAML::FeaturePolicyPrefix &Prefix);
505};
506
507template <> struct MappingTraits<WasmYAML::FeatureEntry> {
508 static void mapping(IO &IO, WasmYAML::FeatureEntry &FeatureEntry);
509};
510
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100511template <> struct MappingTraits<WasmYAML::SegmentInfo> {
512 static void mapping(IO &IO, WasmYAML::SegmentInfo &SegmentInfo);
513};
514
515template <> struct MappingTraits<WasmYAML::LocalDecl> {
516 static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl);
517};
518
519template <> struct MappingTraits<wasm::WasmInitExpr> {
520 static void mapping(IO &IO, wasm::WasmInitExpr &Expr);
521};
522
523template <> struct MappingTraits<WasmYAML::DataSegment> {
524 static void mapping(IO &IO, WasmYAML::DataSegment &Segment);
525};
526
527template <> struct MappingTraits<WasmYAML::ElemSegment> {
528 static void mapping(IO &IO, WasmYAML::ElemSegment &Segment);
529};
530
531template <> struct MappingTraits<WasmYAML::SymbolInfo> {
532 static void mapping(IO &IO, WasmYAML::SymbolInfo &Info);
533};
534
535template <> struct MappingTraits<WasmYAML::InitFunction> {
536 static void mapping(IO &IO, WasmYAML::InitFunction &Init);
537};
538
539template <> struct ScalarEnumerationTraits<WasmYAML::ComdatKind> {
540 static void enumeration(IO &IO, WasmYAML::ComdatKind &Kind);
541};
542
543template <> struct MappingTraits<WasmYAML::ComdatEntry> {
544 static void mapping(IO &IO, WasmYAML::ComdatEntry &ComdatEntry);
545};
546
547template <> struct MappingTraits<WasmYAML::Comdat> {
548 static void mapping(IO &IO, WasmYAML::Comdat &Comdat);
549};
550
551template <> struct ScalarEnumerationTraits<WasmYAML::ValueType> {
552 static void enumeration(IO &IO, WasmYAML::ValueType &Type);
553};
554
555template <> struct ScalarEnumerationTraits<WasmYAML::ExportKind> {
556 static void enumeration(IO &IO, WasmYAML::ExportKind &Kind);
557};
558
559template <> struct ScalarEnumerationTraits<WasmYAML::TableType> {
560 static void enumeration(IO &IO, WasmYAML::TableType &Type);
561};
562
563template <> struct ScalarEnumerationTraits<WasmYAML::Opcode> {
564 static void enumeration(IO &IO, WasmYAML::Opcode &Opcode);
565};
566
567template <> struct ScalarEnumerationTraits<WasmYAML::RelocType> {
568 static void enumeration(IO &IO, WasmYAML::RelocType &Kind);
569};
570
Andrew Walbran16937d02019-10-22 13:54:20 +0100571template <> struct MappingTraits<WasmYAML::Event> {
572 static void mapping(IO &IO, WasmYAML::Event &Event);
573};
574
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100575} // end namespace yaml
576} // end namespace llvm
577
578#endif // LLVM_OBJECTYAML_WASMYAML_H