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