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 Tag { 81 uint32_t Index; 82 uint32_t Attribute; 83 uint32_t SigIndex; 84 }; 85 86 struct 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 Tag TagImport; 96 }; 97 }; 98 99 struct LocalDecl { 100 ValueType Type; 101 uint32_t Count; 102 }; 103 104 struct Function { 105 uint32_t Index; 106 std::vector<LocalDecl> Locals; 107 yaml::BinaryRef Body; 108 }; 109 110 struct 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 119 struct DataSegment { 120 uint32_t SectionOffset; 121 uint32_t InitFlags; 122 uint32_t MemoryIndex; 123 wasm::WasmInitExpr Offset; 124 yaml::BinaryRef Content; 125 }; 126 127 struct NameEntry { 128 uint32_t Index; 129 StringRef Name; 130 }; 131 132 struct ProducerEntry { 133 std::string Name; 134 std::string Version; 135 }; 136 137 struct FeatureEntry { 138 FeaturePolicyPrefix Prefix; 139 std::string Name; 140 }; 141 142 struct SegmentInfo { 143 uint32_t Index; 144 StringRef Name; 145 uint32_t Alignment; 146 SegmentFlags Flags; 147 }; 148 149 struct Signature { 150 uint32_t Index; 151 SignatureForm Form = wasm::WASM_TYPE_FUNC; 152 std::vector<ValueType> ParamTypes; 153 std::vector<ValueType> ReturnTypes; 154 }; 155 156 struct 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 167 struct InitFunction { 168 uint32_t Priority; 169 uint32_t Symbol; 170 }; 171 172 struct ComdatEntry { 173 ComdatKind Kind; 174 uint32_t Index; 175 }; 176 177 struct Comdat { 178 StringRef Name; 179 std::vector<ComdatEntry> Entries; 180 }; 181 182 struct Section { 183 explicit Section(SectionType SecType) : Type(SecType) {} 184 virtual ~Section(); 185 186 SectionType Type; 187 std::vector<Relocation> Relocations; 188 }; 189 190 struct 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 202 struct 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 217 struct 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 230 struct 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 245 struct 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 258 struct 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 269 struct 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 279 struct 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 289 struct 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 299 struct 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 309 struct 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 319 struct TagSection : Section { 320 TagSection() : Section(wasm::WASM_SEC_TAG) {} 321 322 static bool classof(const Section *S) { 323 return S->Type == wasm::WASM_SEC_TAG; 324 } 325 326 std::vector<Tag> Tags; 327 }; 328 329 struct 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 339 struct 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 349 struct 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 359 struct 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 369 struct 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 379 struct 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 389 struct 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 399 struct Object { 400 FileHeader Header; 401 std::vector<std::unique_ptr<Section>> Sections; 402 }; 403 404 } // end namespace WasmYAML 405 } // end namespace llvm 406 407 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::WasmYAML::Section>) 408 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature) 409 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ValueType) 410 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Table) 411 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Import) 412 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Export) 413 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ElemSegment) 414 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Limits) 415 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DataSegment) 416 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Global) 417 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function) 418 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl) 419 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation) 420 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry) 421 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ProducerEntry) 422 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::FeatureEntry) 423 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo) 424 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo) 425 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction) 426 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ComdatEntry) 427 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Comdat) 428 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Tag) 429 430 namespace llvm { 431 namespace yaml { 432 433 template <> struct MappingTraits<WasmYAML::FileHeader> { 434 static void mapping(IO &IO, WasmYAML::FileHeader &FileHdr); 435 }; 436 437 template <> struct MappingTraits<std::unique_ptr<WasmYAML::Section>> { 438 static void mapping(IO &IO, std::unique_ptr<WasmYAML::Section> &Section); 439 }; 440 441 template <> struct MappingTraits<WasmYAML::Object> { 442 static void mapping(IO &IO, WasmYAML::Object &Object); 443 }; 444 445 template <> struct MappingTraits<WasmYAML::Import> { 446 static void mapping(IO &IO, WasmYAML::Import &Import); 447 }; 448 449 template <> struct MappingTraits<WasmYAML::Export> { 450 static void mapping(IO &IO, WasmYAML::Export &Export); 451 }; 452 453 template <> struct MappingTraits<WasmYAML::Global> { 454 static void mapping(IO &IO, WasmYAML::Global &Global); 455 }; 456 457 template <> struct ScalarBitSetTraits<WasmYAML::LimitFlags> { 458 static void bitset(IO &IO, WasmYAML::LimitFlags &Value); 459 }; 460 461 template <> struct ScalarBitSetTraits<WasmYAML::SymbolFlags> { 462 static void bitset(IO &IO, WasmYAML::SymbolFlags &Value); 463 }; 464 465 template <> struct ScalarEnumerationTraits<WasmYAML::SymbolKind> { 466 static void enumeration(IO &IO, WasmYAML::SymbolKind &Kind); 467 }; 468 469 template <> struct ScalarBitSetTraits<WasmYAML::SegmentFlags> { 470 static void bitset(IO &IO, WasmYAML::SegmentFlags &Value); 471 }; 472 473 template <> struct ScalarEnumerationTraits<WasmYAML::SectionType> { 474 static void enumeration(IO &IO, WasmYAML::SectionType &Type); 475 }; 476 477 template <> struct MappingTraits<WasmYAML::Signature> { 478 static void mapping(IO &IO, WasmYAML::Signature &Signature); 479 }; 480 481 template <> struct MappingTraits<WasmYAML::Table> { 482 static void mapping(IO &IO, WasmYAML::Table &Table); 483 }; 484 485 template <> struct MappingTraits<WasmYAML::Limits> { 486 static void mapping(IO &IO, WasmYAML::Limits &Limits); 487 }; 488 489 template <> struct MappingTraits<WasmYAML::Function> { 490 static void mapping(IO &IO, WasmYAML::Function &Function); 491 }; 492 493 template <> struct MappingTraits<WasmYAML::Relocation> { 494 static void mapping(IO &IO, WasmYAML::Relocation &Relocation); 495 }; 496 497 template <> struct MappingTraits<WasmYAML::NameEntry> { 498 static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry); 499 }; 500 501 template <> struct MappingTraits<WasmYAML::ProducerEntry> { 502 static void mapping(IO &IO, WasmYAML::ProducerEntry &ProducerEntry); 503 }; 504 505 template <> struct ScalarEnumerationTraits<WasmYAML::FeaturePolicyPrefix> { 506 static void enumeration(IO &IO, WasmYAML::FeaturePolicyPrefix &Prefix); 507 }; 508 509 template <> struct MappingTraits<WasmYAML::FeatureEntry> { 510 static void mapping(IO &IO, WasmYAML::FeatureEntry &FeatureEntry); 511 }; 512 513 template <> struct MappingTraits<WasmYAML::SegmentInfo> { 514 static void mapping(IO &IO, WasmYAML::SegmentInfo &SegmentInfo); 515 }; 516 517 template <> struct MappingTraits<WasmYAML::LocalDecl> { 518 static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl); 519 }; 520 521 template <> struct MappingTraits<wasm::WasmInitExpr> { 522 static void mapping(IO &IO, wasm::WasmInitExpr &Expr); 523 }; 524 525 template <> struct MappingTraits<WasmYAML::DataSegment> { 526 static void mapping(IO &IO, WasmYAML::DataSegment &Segment); 527 }; 528 529 template <> struct MappingTraits<WasmYAML::ElemSegment> { 530 static void mapping(IO &IO, WasmYAML::ElemSegment &Segment); 531 }; 532 533 template <> struct MappingTraits<WasmYAML::SymbolInfo> { 534 static void mapping(IO &IO, WasmYAML::SymbolInfo &Info); 535 }; 536 537 template <> struct MappingTraits<WasmYAML::InitFunction> { 538 static void mapping(IO &IO, WasmYAML::InitFunction &Init); 539 }; 540 541 template <> struct ScalarEnumerationTraits<WasmYAML::ComdatKind> { 542 static void enumeration(IO &IO, WasmYAML::ComdatKind &Kind); 543 }; 544 545 template <> struct MappingTraits<WasmYAML::ComdatEntry> { 546 static void mapping(IO &IO, WasmYAML::ComdatEntry &ComdatEntry); 547 }; 548 549 template <> struct MappingTraits<WasmYAML::Comdat> { 550 static void mapping(IO &IO, WasmYAML::Comdat &Comdat); 551 }; 552 553 template <> struct ScalarEnumerationTraits<WasmYAML::ValueType> { 554 static void enumeration(IO &IO, WasmYAML::ValueType &Type); 555 }; 556 557 template <> struct ScalarEnumerationTraits<WasmYAML::ExportKind> { 558 static void enumeration(IO &IO, WasmYAML::ExportKind &Kind); 559 }; 560 561 template <> struct ScalarEnumerationTraits<WasmYAML::TableType> { 562 static void enumeration(IO &IO, WasmYAML::TableType &Type); 563 }; 564 565 template <> struct ScalarEnumerationTraits<WasmYAML::Opcode> { 566 static void enumeration(IO &IO, WasmYAML::Opcode &Opcode); 567 }; 568 569 template <> struct ScalarEnumerationTraits<WasmYAML::RelocType> { 570 static void enumeration(IO &IO, WasmYAML::RelocType &Kind); 571 }; 572 573 template <> struct MappingTraits<WasmYAML::Tag> { 574 static void mapping(IO &IO, WasmYAML::Tag &Tag); 575 }; 576 577 } // end namespace yaml 578 } // end namespace llvm 579 580 #endif // LLVM_OBJECTYAML_WASMYAML_H 581