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 std::optional<uint8_t> HeaderSecSizeEncodingLen; 193 }; 194 195 struct 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 207 struct DylinkImportInfo { 208 StringRef Module; 209 StringRef Field; 210 SymbolFlags Flags; 211 }; 212 213 struct DylinkExportInfo { 214 StringRef Name; 215 SymbolFlags Flags; 216 }; 217 218 struct DylinkSection : CustomSection { 219 DylinkSection() : CustomSection("dylink.0") {} 220 221 static bool classof(const Section *S) { 222 auto C = dyn_cast<CustomSection>(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 235 struct NameSection : CustomSection { 236 NameSection() : CustomSection("name") {} 237 238 static bool classof(const Section *S) { 239 auto C = dyn_cast<CustomSection>(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 248 struct LinkingSection : CustomSection { 249 LinkingSection() : CustomSection("linking") {} 250 251 static bool classof(const Section *S) { 252 auto C = dyn_cast<CustomSection>(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 263 struct ProducersSection : CustomSection { 264 ProducersSection() : CustomSection("producers") {} 265 266 static bool classof(const Section *S) { 267 auto C = dyn_cast<CustomSection>(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 276 struct TargetFeaturesSection : CustomSection { 277 TargetFeaturesSection() : CustomSection("target_features") {} 278 279 static bool classof(const Section *S) { 280 auto C = dyn_cast<CustomSection>(S); 281 return C && C->Name == "target_features"; 282 } 283 284 std::vector<FeatureEntry> Features; 285 }; 286 287 struct 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 297 struct 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 307 struct 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 317 struct 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 327 struct 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 337 struct 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 347 struct 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 357 struct 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 367 struct 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 377 struct 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 387 struct 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 397 struct 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 407 struct 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 417 struct Object { 418 FileHeader Header; 419 std::vector<std::unique_ptr<Section>> Sections; 420 }; 421 422 } // end namespace WasmYAML 423 } // end namespace llvm 424 425 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::WasmYAML::Section>) 426 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature) 427 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ValueType) 428 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Table) 429 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Import) 430 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Export) 431 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ElemSegment) 432 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Limits) 433 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DataSegment) 434 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Global) 435 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function) 436 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl) 437 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation) 438 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry) 439 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ProducerEntry) 440 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::FeatureEntry) 441 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo) 442 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo) 443 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction) 444 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ComdatEntry) 445 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Comdat) 446 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DylinkImportInfo) 447 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DylinkExportInfo) 448 449 namespace llvm { 450 namespace yaml { 451 452 template <> struct MappingTraits<WasmYAML::FileHeader> { 453 static void mapping(IO &IO, WasmYAML::FileHeader &FileHdr); 454 }; 455 456 template <> struct MappingTraits<std::unique_ptr<WasmYAML::Section>> { 457 static void mapping(IO &IO, std::unique_ptr<WasmYAML::Section> &Section); 458 }; 459 460 template <> struct MappingTraits<WasmYAML::Object> { 461 static void mapping(IO &IO, WasmYAML::Object &Object); 462 }; 463 464 template <> struct MappingTraits<WasmYAML::Import> { 465 static void mapping(IO &IO, WasmYAML::Import &Import); 466 }; 467 468 template <> struct MappingTraits<WasmYAML::Export> { 469 static void mapping(IO &IO, WasmYAML::Export &Export); 470 }; 471 472 template <> struct MappingTraits<WasmYAML::Global> { 473 static void mapping(IO &IO, WasmYAML::Global &Global); 474 }; 475 476 template <> struct ScalarBitSetTraits<WasmYAML::LimitFlags> { 477 static void bitset(IO &IO, WasmYAML::LimitFlags &Value); 478 }; 479 480 template <> struct ScalarBitSetTraits<WasmYAML::SymbolFlags> { 481 static void bitset(IO &IO, WasmYAML::SymbolFlags &Value); 482 }; 483 484 template <> struct ScalarEnumerationTraits<WasmYAML::SymbolKind> { 485 static void enumeration(IO &IO, WasmYAML::SymbolKind &Kind); 486 }; 487 488 template <> struct ScalarBitSetTraits<WasmYAML::SegmentFlags> { 489 static void bitset(IO &IO, WasmYAML::SegmentFlags &Value); 490 }; 491 492 template <> struct ScalarEnumerationTraits<WasmYAML::SectionType> { 493 static void enumeration(IO &IO, WasmYAML::SectionType &Type); 494 }; 495 496 template <> struct MappingTraits<WasmYAML::Signature> { 497 static void mapping(IO &IO, WasmYAML::Signature &Signature); 498 }; 499 500 template <> struct MappingTraits<WasmYAML::Table> { 501 static void mapping(IO &IO, WasmYAML::Table &Table); 502 }; 503 504 template <> struct MappingTraits<WasmYAML::Limits> { 505 static void mapping(IO &IO, WasmYAML::Limits &Limits); 506 }; 507 508 template <> struct MappingTraits<WasmYAML::Function> { 509 static void mapping(IO &IO, WasmYAML::Function &Function); 510 }; 511 512 template <> struct MappingTraits<WasmYAML::Relocation> { 513 static void mapping(IO &IO, WasmYAML::Relocation &Relocation); 514 }; 515 516 template <> struct MappingTraits<WasmYAML::NameEntry> { 517 static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry); 518 }; 519 520 template <> struct MappingTraits<WasmYAML::ProducerEntry> { 521 static void mapping(IO &IO, WasmYAML::ProducerEntry &ProducerEntry); 522 }; 523 524 template <> struct ScalarEnumerationTraits<WasmYAML::FeaturePolicyPrefix> { 525 static void enumeration(IO &IO, WasmYAML::FeaturePolicyPrefix &Prefix); 526 }; 527 528 template <> struct MappingTraits<WasmYAML::FeatureEntry> { 529 static void mapping(IO &IO, WasmYAML::FeatureEntry &FeatureEntry); 530 }; 531 532 template <> struct MappingTraits<WasmYAML::SegmentInfo> { 533 static void mapping(IO &IO, WasmYAML::SegmentInfo &SegmentInfo); 534 }; 535 536 template <> struct MappingTraits<WasmYAML::LocalDecl> { 537 static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl); 538 }; 539 540 template <> struct MappingTraits<WasmYAML::InitExpr> { 541 static void mapping(IO &IO, WasmYAML::InitExpr &Expr); 542 }; 543 544 template <> struct MappingTraits<WasmYAML::DataSegment> { 545 static void mapping(IO &IO, WasmYAML::DataSegment &Segment); 546 }; 547 548 template <> struct MappingTraits<WasmYAML::ElemSegment> { 549 static void mapping(IO &IO, WasmYAML::ElemSegment &Segment); 550 }; 551 552 template <> struct MappingTraits<WasmYAML::SymbolInfo> { 553 static void mapping(IO &IO, WasmYAML::SymbolInfo &Info); 554 }; 555 556 template <> struct MappingTraits<WasmYAML::InitFunction> { 557 static void mapping(IO &IO, WasmYAML::InitFunction &Init); 558 }; 559 560 template <> struct ScalarEnumerationTraits<WasmYAML::ComdatKind> { 561 static void enumeration(IO &IO, WasmYAML::ComdatKind &Kind); 562 }; 563 564 template <> struct MappingTraits<WasmYAML::ComdatEntry> { 565 static void mapping(IO &IO, WasmYAML::ComdatEntry &ComdatEntry); 566 }; 567 568 template <> struct MappingTraits<WasmYAML::Comdat> { 569 static void mapping(IO &IO, WasmYAML::Comdat &Comdat); 570 }; 571 572 template <> struct ScalarEnumerationTraits<WasmYAML::ValueType> { 573 static void enumeration(IO &IO, WasmYAML::ValueType &Type); 574 }; 575 576 template <> struct ScalarEnumerationTraits<WasmYAML::ExportKind> { 577 static void enumeration(IO &IO, WasmYAML::ExportKind &Kind); 578 }; 579 580 template <> struct ScalarEnumerationTraits<WasmYAML::TableType> { 581 static void enumeration(IO &IO, WasmYAML::TableType &Type); 582 }; 583 584 template <> struct ScalarEnumerationTraits<WasmYAML::Opcode> { 585 static void enumeration(IO &IO, WasmYAML::Opcode &Opcode); 586 }; 587 588 template <> struct ScalarEnumerationTraits<WasmYAML::RelocType> { 589 static void enumeration(IO &IO, WasmYAML::RelocType &Kind); 590 }; 591 592 template <> struct MappingTraits<WasmYAML::DylinkImportInfo> { 593 static void mapping(IO &IO, WasmYAML::DylinkImportInfo &Info); 594 }; 595 596 template <> 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