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