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