1 //===- WasmYAML.h - Wasm YAMLIO implementation ------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// This file declares classes for handling the YAML representation 12 /// of wasm binaries. 13 /// 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_OBJECTYAML_WASMYAML_H 17 #define LLVM_OBJECTYAML_WASMYAML_H 18 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/BinaryFormat/Wasm.h" 21 #include "llvm/ObjectYAML/YAML.h" 22 #include "llvm/Support/Casting.h" 23 #include <cstdint> 24 #include <memory> 25 #include <vector> 26 27 namespace llvm { 28 namespace WasmYAML { 29 30 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SectionType) 31 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ValueType) 32 LLVM_YAML_STRONG_TYPEDEF(uint32_t, TableType) 33 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SignatureForm) 34 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ExportKind) 35 LLVM_YAML_STRONG_TYPEDEF(uint32_t, Opcode) 36 LLVM_YAML_STRONG_TYPEDEF(uint32_t, RelocType) 37 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SymbolFlags) 38 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SymbolKind) 39 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SegmentFlags) 40 LLVM_YAML_STRONG_TYPEDEF(uint32_t, LimitFlags) 41 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ComdatKind) 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 Import { 78 StringRef Module; 79 StringRef Field; 80 ExportKind Kind; 81 union { 82 uint32_t SigIndex; 83 Global GlobalImport; 84 Table TableImport; 85 Limits Memory; 86 }; 87 }; 88 89 struct LocalDecl { 90 ValueType Type; 91 uint32_t Count; 92 }; 93 94 struct Function { 95 uint32_t Index; 96 std::vector<LocalDecl> Locals; 97 yaml::BinaryRef Body; 98 }; 99 100 struct Relocation { 101 RelocType Type; 102 uint32_t Index; 103 yaml::Hex32 Offset; 104 int32_t Addend; 105 }; 106 107 struct DataSegment { 108 uint32_t MemoryIndex; 109 uint32_t SectionOffset; 110 wasm::WasmInitExpr Offset; 111 yaml::BinaryRef Content; 112 }; 113 114 struct NameEntry { 115 uint32_t Index; 116 StringRef Name; 117 }; 118 119 struct SegmentInfo { 120 uint32_t Index; 121 StringRef Name; 122 uint32_t Alignment; 123 SegmentFlags Flags; 124 }; 125 126 struct Signature { 127 uint32_t Index; 128 SignatureForm Form = wasm::WASM_TYPE_FUNC; 129 std::vector<ValueType> ParamTypes; 130 ValueType ReturnType; 131 }; 132 133 struct SymbolInfo { 134 uint32_t Index; 135 StringRef Name; 136 SymbolKind Kind; 137 SymbolFlags Flags; 138 union { 139 uint32_t ElementIndex; 140 wasm::WasmDataReference DataRef; 141 }; 142 }; 143 144 struct InitFunction { 145 uint32_t Priority; 146 uint32_t Symbol; 147 }; 148 149 struct ComdatEntry { 150 ComdatKind Kind; 151 uint32_t Index; 152 }; 153 154 struct Comdat { 155 StringRef Name; 156 std::vector<ComdatEntry> Entries; 157 }; 158 159 struct Section { 160 explicit Section(SectionType SecType) : Type(SecType) {} 161 virtual ~Section(); 162 163 SectionType Type; 164 std::vector<Relocation> Relocations; 165 }; 166 167 struct CustomSection : Section { 168 explicit CustomSection(StringRef Name) 169 : Section(wasm::WASM_SEC_CUSTOM), Name(Name) {} 170 171 static bool classof(const Section *S) { 172 return S->Type == wasm::WASM_SEC_CUSTOM; 173 } 174 175 StringRef Name; 176 yaml::BinaryRef Payload; 177 }; 178 179 struct NameSection : CustomSection { 180 NameSection() : CustomSection("name") {} 181 182 static bool classof(const Section *S) { 183 auto C = dyn_cast<CustomSection>(S); 184 return C && C->Name == "name"; 185 } 186 187 std::vector<NameEntry> FunctionNames; 188 }; 189 190 struct LinkingSection : CustomSection { 191 LinkingSection() : CustomSection("linking") {} 192 193 static bool classof(const Section *S) { 194 auto C = dyn_cast<CustomSection>(S); 195 return C && C->Name == "linking"; 196 } 197 198 uint32_t Version; 199 std::vector<SymbolInfo> SymbolTable; 200 std::vector<SegmentInfo> SegmentInfos; 201 std::vector<InitFunction> InitFunctions; 202 std::vector<Comdat> Comdats; 203 }; 204 205 struct TypeSection : Section { 206 TypeSection() : Section(wasm::WASM_SEC_TYPE) {} 207 208 static bool classof(const Section *S) { 209 return S->Type == wasm::WASM_SEC_TYPE; 210 } 211 212 std::vector<Signature> Signatures; 213 }; 214 215 struct ImportSection : Section { 216 ImportSection() : Section(wasm::WASM_SEC_IMPORT) {} 217 218 static bool classof(const Section *S) { 219 return S->Type == wasm::WASM_SEC_IMPORT; 220 } 221 222 std::vector<Import> Imports; 223 }; 224 225 struct FunctionSection : Section { 226 FunctionSection() : Section(wasm::WASM_SEC_FUNCTION) {} 227 228 static bool classof(const Section *S) { 229 return S->Type == wasm::WASM_SEC_FUNCTION; 230 } 231 232 std::vector<uint32_t> FunctionTypes; 233 }; 234 235 struct TableSection : Section { 236 TableSection() : Section(wasm::WASM_SEC_TABLE) {} 237 238 static bool classof(const Section *S) { 239 return S->Type == wasm::WASM_SEC_TABLE; 240 } 241 242 std::vector<Table> Tables; 243 }; 244 245 struct MemorySection : Section { 246 MemorySection() : Section(wasm::WASM_SEC_MEMORY) {} 247 248 static bool classof(const Section *S) { 249 return S->Type == wasm::WASM_SEC_MEMORY; 250 } 251 252 std::vector<Limits> Memories; 253 }; 254 255 struct GlobalSection : Section { 256 GlobalSection() : Section(wasm::WASM_SEC_GLOBAL) {} 257 258 static bool classof(const Section *S) { 259 return S->Type == wasm::WASM_SEC_GLOBAL; 260 } 261 262 std::vector<Global> Globals; 263 }; 264 265 struct ExportSection : Section { 266 ExportSection() : Section(wasm::WASM_SEC_EXPORT) {} 267 268 static bool classof(const Section *S) { 269 return S->Type == wasm::WASM_SEC_EXPORT; 270 } 271 272 std::vector<Export> Exports; 273 }; 274 275 struct StartSection : Section { 276 StartSection() : Section(wasm::WASM_SEC_START) {} 277 278 static bool classof(const Section *S) { 279 return S->Type == wasm::WASM_SEC_START; 280 } 281 282 uint32_t StartFunction; 283 }; 284 285 struct ElemSection : Section { 286 ElemSection() : Section(wasm::WASM_SEC_ELEM) {} 287 288 static bool classof(const Section *S) { 289 return S->Type == wasm::WASM_SEC_ELEM; 290 } 291 292 std::vector<ElemSegment> Segments; 293 }; 294 295 struct CodeSection : Section { 296 CodeSection() : Section(wasm::WASM_SEC_CODE) {} 297 298 static bool classof(const Section *S) { 299 return S->Type == wasm::WASM_SEC_CODE; 300 } 301 302 std::vector<Function> Functions; 303 }; 304 305 struct DataSection : Section { 306 DataSection() : Section(wasm::WASM_SEC_DATA) {} 307 308 static bool classof(const Section *S) { 309 return S->Type == wasm::WASM_SEC_DATA; 310 } 311 312 std::vector<DataSegment> Segments; 313 }; 314 315 struct Object { 316 FileHeader Header; 317 std::vector<std::unique_ptr<Section>> Sections; 318 }; 319 320 } // end namespace WasmYAML 321 } // end namespace llvm 322 323 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::WasmYAML::Section>) 324 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature) 325 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ValueType) 326 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Table) 327 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Import) 328 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Export) 329 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ElemSegment) 330 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Limits) 331 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DataSegment) 332 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Global) 333 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function) 334 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl) 335 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation) 336 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry) 337 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo) 338 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo) 339 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction) 340 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ComdatEntry) 341 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Comdat) 342 343 namespace llvm { 344 namespace yaml { 345 346 template <> struct MappingTraits<WasmYAML::FileHeader> { 347 static void mapping(IO &IO, WasmYAML::FileHeader &FileHdr); 348 }; 349 350 template <> struct MappingTraits<std::unique_ptr<WasmYAML::Section>> { 351 static void mapping(IO &IO, std::unique_ptr<WasmYAML::Section> &Section); 352 }; 353 354 template <> struct MappingTraits<WasmYAML::Object> { 355 static void mapping(IO &IO, WasmYAML::Object &Object); 356 }; 357 358 template <> struct MappingTraits<WasmYAML::Import> { 359 static void mapping(IO &IO, WasmYAML::Import &Import); 360 }; 361 362 template <> struct MappingTraits<WasmYAML::Export> { 363 static void mapping(IO &IO, WasmYAML::Export &Export); 364 }; 365 366 template <> struct MappingTraits<WasmYAML::Global> { 367 static void mapping(IO &IO, WasmYAML::Global &Global); 368 }; 369 370 template <> struct ScalarBitSetTraits<WasmYAML::LimitFlags> { 371 static void bitset(IO &IO, WasmYAML::LimitFlags &Value); 372 }; 373 374 template <> struct ScalarBitSetTraits<WasmYAML::SymbolFlags> { 375 static void bitset(IO &IO, WasmYAML::SymbolFlags &Value); 376 }; 377 378 template <> struct ScalarEnumerationTraits<WasmYAML::SymbolKind> { 379 static void enumeration(IO &IO, WasmYAML::SymbolKind &Kind); 380 }; 381 382 template <> struct ScalarBitSetTraits<WasmYAML::SegmentFlags> { 383 static void bitset(IO &IO, WasmYAML::SegmentFlags &Value); 384 }; 385 386 template <> struct ScalarEnumerationTraits<WasmYAML::SectionType> { 387 static void enumeration(IO &IO, WasmYAML::SectionType &Type); 388 }; 389 390 template <> struct MappingTraits<WasmYAML::Signature> { 391 static void mapping(IO &IO, WasmYAML::Signature &Signature); 392 }; 393 394 template <> struct MappingTraits<WasmYAML::Table> { 395 static void mapping(IO &IO, WasmYAML::Table &Table); 396 }; 397 398 template <> struct MappingTraits<WasmYAML::Limits> { 399 static void mapping(IO &IO, WasmYAML::Limits &Limits); 400 }; 401 402 template <> struct MappingTraits<WasmYAML::Function> { 403 static void mapping(IO &IO, WasmYAML::Function &Function); 404 }; 405 406 template <> struct MappingTraits<WasmYAML::Relocation> { 407 static void mapping(IO &IO, WasmYAML::Relocation &Relocation); 408 }; 409 410 template <> struct MappingTraits<WasmYAML::NameEntry> { 411 static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry); 412 }; 413 414 template <> struct MappingTraits<WasmYAML::SegmentInfo> { 415 static void mapping(IO &IO, WasmYAML::SegmentInfo &SegmentInfo); 416 }; 417 418 template <> struct MappingTraits<WasmYAML::LocalDecl> { 419 static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl); 420 }; 421 422 template <> struct MappingTraits<wasm::WasmInitExpr> { 423 static void mapping(IO &IO, wasm::WasmInitExpr &Expr); 424 }; 425 426 template <> struct MappingTraits<WasmYAML::DataSegment> { 427 static void mapping(IO &IO, WasmYAML::DataSegment &Segment); 428 }; 429 430 template <> struct MappingTraits<WasmYAML::ElemSegment> { 431 static void mapping(IO &IO, WasmYAML::ElemSegment &Segment); 432 }; 433 434 template <> struct MappingTraits<WasmYAML::SymbolInfo> { 435 static void mapping(IO &IO, WasmYAML::SymbolInfo &Info); 436 }; 437 438 template <> struct MappingTraits<WasmYAML::InitFunction> { 439 static void mapping(IO &IO, WasmYAML::InitFunction &Init); 440 }; 441 442 template <> struct ScalarEnumerationTraits<WasmYAML::ComdatKind> { 443 static void enumeration(IO &IO, WasmYAML::ComdatKind &Kind); 444 }; 445 446 template <> struct MappingTraits<WasmYAML::ComdatEntry> { 447 static void mapping(IO &IO, WasmYAML::ComdatEntry &ComdatEntry); 448 }; 449 450 template <> struct MappingTraits<WasmYAML::Comdat> { 451 static void mapping(IO &IO, WasmYAML::Comdat &Comdat); 452 }; 453 454 template <> struct ScalarEnumerationTraits<WasmYAML::ValueType> { 455 static void enumeration(IO &IO, WasmYAML::ValueType &Type); 456 }; 457 458 template <> struct ScalarEnumerationTraits<WasmYAML::ExportKind> { 459 static void enumeration(IO &IO, WasmYAML::ExportKind &Kind); 460 }; 461 462 template <> struct ScalarEnumerationTraits<WasmYAML::TableType> { 463 static void enumeration(IO &IO, WasmYAML::TableType &Type); 464 }; 465 466 template <> struct ScalarEnumerationTraits<WasmYAML::Opcode> { 467 static void enumeration(IO &IO, WasmYAML::Opcode &Opcode); 468 }; 469 470 template <> struct ScalarEnumerationTraits<WasmYAML::RelocType> { 471 static void enumeration(IO &IO, WasmYAML::RelocType &Kind); 472 }; 473 474 } // end namespace yaml 475 } // end namespace llvm 476 477 #endif // LLVM_OBJECTYAML_WASMYAML_H 478