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