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