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