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