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 /// \brief 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(int32_t, ValueType) 32 LLVM_YAML_STRONG_TYPEDEF(int32_t, TableType) 33 LLVM_YAML_STRONG_TYPEDEF(int32_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 38 struct FileHeader { 39 yaml::Hex32 Version; 40 }; 41 42 struct Limits { 43 yaml::Hex32 Flags; 44 yaml::Hex32 Initial; 45 yaml::Hex32 Maximum; 46 }; 47 48 struct Table { 49 TableType ElemType; 50 Limits TableLimits; 51 }; 52 53 struct Export { 54 StringRef Name; 55 ExportKind Kind; 56 uint32_t Index; 57 }; 58 59 struct ElemSegment { 60 uint32_t TableIndex; 61 wasm::WasmInitExpr Offset; 62 std::vector<uint32_t> Functions; 63 }; 64 65 struct Global { 66 ValueType Type; 67 bool Mutable; 68 wasm::WasmInitExpr InitExpr; 69 }; 70 71 struct Import { 72 StringRef Module; 73 StringRef Field; 74 ExportKind Kind; 75 union { 76 uint32_t SigIndex; 77 Global GlobalImport; 78 Table TableImport; 79 Limits Memory; 80 }; 81 }; 82 83 struct LocalDecl { 84 ValueType Type; 85 uint32_t Count; 86 }; 87 88 struct Function { 89 std::vector<LocalDecl> Locals; 90 yaml::BinaryRef Body; 91 }; 92 93 struct Relocation { 94 RelocType Type; 95 uint32_t Index; 96 yaml::Hex32 Offset; 97 int32_t Addend; 98 }; 99 100 struct DataSegment { 101 uint32_t MemoryIndex; 102 uint32_t SectionOffset; 103 wasm::WasmInitExpr Offset; 104 yaml::BinaryRef Content; 105 }; 106 107 struct NameEntry { 108 uint32_t Index; 109 StringRef Name; 110 }; 111 112 struct SegmentInfo { 113 uint32_t Index; 114 StringRef Name; 115 uint32_t Alignment; 116 uint32_t Flags; 117 }; 118 119 struct Signature { 120 uint32_t Index; 121 SignatureForm Form = wasm::WASM_TYPE_FUNC; 122 std::vector<ValueType> ParamTypes; 123 ValueType ReturnType; 124 }; 125 126 struct SymbolInfo { 127 StringRef Name; 128 uint32_t Flags; 129 }; 130 131 struct Section { 132 explicit Section(SectionType SecType) : Type(SecType) {} 133 virtual ~Section(); 134 135 SectionType Type; 136 std::vector<Relocation> Relocations; 137 }; 138 139 struct CustomSection : Section { 140 explicit CustomSection(StringRef Name) 141 : Section(wasm::WASM_SEC_CUSTOM), Name(Name) {} 142 143 static bool classof(const Section *S) { 144 return S->Type == wasm::WASM_SEC_CUSTOM; 145 } 146 147 StringRef Name; 148 yaml::BinaryRef Payload; 149 }; 150 151 struct NameSection : CustomSection { 152 NameSection() : CustomSection("name") {} 153 154 static bool classof(const Section *S) { 155 auto C = dyn_cast<CustomSection>(S); 156 return C && C->Name == "name"; 157 } 158 159 std::vector<NameEntry> FunctionNames; 160 }; 161 162 struct LinkingSection : CustomSection { 163 LinkingSection() : CustomSection("linking") {} 164 165 static bool classof(const Section *S) { 166 auto C = dyn_cast<CustomSection>(S); 167 return C && C->Name == "linking"; 168 } 169 170 uint32_t DataSize; 171 std::vector<SymbolInfo> SymbolInfos; 172 std::vector<SegmentInfo> SegmentInfos; 173 }; 174 175 struct TypeSection : Section { 176 TypeSection() : Section(wasm::WASM_SEC_TYPE) {} 177 178 static bool classof(const Section *S) { 179 return S->Type == wasm::WASM_SEC_TYPE; 180 } 181 182 std::vector<Signature> Signatures; 183 }; 184 185 struct ImportSection : Section { 186 ImportSection() : Section(wasm::WASM_SEC_IMPORT) {} 187 188 static bool classof(const Section *S) { 189 return S->Type == wasm::WASM_SEC_IMPORT; 190 } 191 192 std::vector<Import> Imports; 193 }; 194 195 struct FunctionSection : Section { 196 FunctionSection() : Section(wasm::WASM_SEC_FUNCTION) {} 197 198 static bool classof(const Section *S) { 199 return S->Type == wasm::WASM_SEC_FUNCTION; 200 } 201 202 std::vector<uint32_t> FunctionTypes; 203 }; 204 205 struct TableSection : Section { 206 TableSection() : Section(wasm::WASM_SEC_TABLE) {} 207 208 static bool classof(const Section *S) { 209 return S->Type == wasm::WASM_SEC_TABLE; 210 } 211 212 std::vector<Table> Tables; 213 }; 214 215 struct MemorySection : Section { 216 MemorySection() : Section(wasm::WASM_SEC_MEMORY) {} 217 218 static bool classof(const Section *S) { 219 return S->Type == wasm::WASM_SEC_MEMORY; 220 } 221 222 std::vector<Limits> Memories; 223 }; 224 225 struct GlobalSection : Section { 226 GlobalSection() : Section(wasm::WASM_SEC_GLOBAL) {} 227 228 static bool classof(const Section *S) { 229 return S->Type == wasm::WASM_SEC_GLOBAL; 230 } 231 232 std::vector<Global> Globals; 233 }; 234 235 struct ExportSection : Section { 236 ExportSection() : Section(wasm::WASM_SEC_EXPORT) {} 237 238 static bool classof(const Section *S) { 239 return S->Type == wasm::WASM_SEC_EXPORT; 240 } 241 242 std::vector<Export> Exports; 243 }; 244 245 struct StartSection : Section { 246 StartSection() : Section(wasm::WASM_SEC_START) {} 247 248 static bool classof(const Section *S) { 249 return S->Type == wasm::WASM_SEC_START; 250 } 251 252 uint32_t StartFunction; 253 }; 254 255 struct ElemSection : Section { 256 ElemSection() : Section(wasm::WASM_SEC_ELEM) {} 257 258 static bool classof(const Section *S) { 259 return S->Type == wasm::WASM_SEC_ELEM; 260 } 261 262 std::vector<ElemSegment> Segments; 263 }; 264 265 struct CodeSection : Section { 266 CodeSection() : Section(wasm::WASM_SEC_CODE) {} 267 268 static bool classof(const Section *S) { 269 return S->Type == wasm::WASM_SEC_CODE; 270 } 271 272 std::vector<Function> Functions; 273 }; 274 275 struct DataSection : Section { 276 DataSection() : Section(wasm::WASM_SEC_DATA) {} 277 278 static bool classof(const Section *S) { 279 return S->Type == wasm::WASM_SEC_DATA; 280 } 281 282 std::vector<DataSegment> Segments; 283 }; 284 285 struct Object { 286 FileHeader Header; 287 std::vector<std::unique_ptr<Section>> Sections; 288 }; 289 290 } // end namespace WasmYAML 291 } // end namespace llvm 292 293 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::WasmYAML::Section>) 294 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Signature) 295 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ValueType) 296 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Table) 297 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Import) 298 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Export) 299 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ElemSegment) 300 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Limits) 301 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::DataSegment) 302 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Global) 303 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function) 304 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl) 305 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation) 306 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry) 307 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo) 308 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo) 309 310 namespace llvm { 311 namespace yaml { 312 313 template <> struct MappingTraits<WasmYAML::FileHeader> { 314 static void mapping(IO &IO, WasmYAML::FileHeader &FileHdr); 315 }; 316 317 template <> struct MappingTraits<std::unique_ptr<WasmYAML::Section>> { 318 static void mapping(IO &IO, std::unique_ptr<WasmYAML::Section> &Section); 319 }; 320 321 template <> struct MappingTraits<WasmYAML::Object> { 322 static void mapping(IO &IO, WasmYAML::Object &Object); 323 }; 324 325 template <> struct MappingTraits<WasmYAML::Import> { 326 static void mapping(IO &IO, WasmYAML::Import &Import); 327 }; 328 329 template <> struct MappingTraits<WasmYAML::Export> { 330 static void mapping(IO &IO, WasmYAML::Export &Export); 331 }; 332 333 template <> struct MappingTraits<WasmYAML::Global> { 334 static void mapping(IO &IO, WasmYAML::Global &Global); 335 }; 336 337 template <> struct ScalarEnumerationTraits<WasmYAML::SectionType> { 338 static void enumeration(IO &IO, WasmYAML::SectionType &Type); 339 }; 340 341 template <> struct MappingTraits<WasmYAML::Signature> { 342 static void mapping(IO &IO, WasmYAML::Signature &Signature); 343 }; 344 345 template <> struct MappingTraits<WasmYAML::Table> { 346 static void mapping(IO &IO, WasmYAML::Table &Table); 347 }; 348 349 template <> struct MappingTraits<WasmYAML::Limits> { 350 static void mapping(IO &IO, WasmYAML::Limits &Limits); 351 }; 352 353 template <> struct MappingTraits<WasmYAML::Function> { 354 static void mapping(IO &IO, WasmYAML::Function &Function); 355 }; 356 357 template <> struct MappingTraits<WasmYAML::Relocation> { 358 static void mapping(IO &IO, WasmYAML::Relocation &Relocation); 359 }; 360 361 template <> struct MappingTraits<WasmYAML::NameEntry> { 362 static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry); 363 }; 364 365 template <> struct MappingTraits<WasmYAML::SegmentInfo> { 366 static void mapping(IO &IO, WasmYAML::SegmentInfo &SegmentInfo); 367 }; 368 369 template <> struct MappingTraits<WasmYAML::LocalDecl> { 370 static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl); 371 }; 372 373 template <> struct MappingTraits<wasm::WasmInitExpr> { 374 static void mapping(IO &IO, wasm::WasmInitExpr &Expr); 375 }; 376 377 template <> struct MappingTraits<WasmYAML::DataSegment> { 378 static void mapping(IO &IO, WasmYAML::DataSegment &Segment); 379 }; 380 381 template <> struct MappingTraits<WasmYAML::ElemSegment> { 382 static void mapping(IO &IO, WasmYAML::ElemSegment &Segment); 383 }; 384 385 template <> struct MappingTraits<WasmYAML::SymbolInfo> { 386 static void mapping(IO &IO, WasmYAML::SymbolInfo &Info); 387 }; 388 389 template <> struct ScalarEnumerationTraits<WasmYAML::ValueType> { 390 static void enumeration(IO &IO, WasmYAML::ValueType &Type); 391 }; 392 393 template <> struct ScalarEnumerationTraits<WasmYAML::ExportKind> { 394 static void enumeration(IO &IO, WasmYAML::ExportKind &Kind); 395 }; 396 397 template <> struct ScalarEnumerationTraits<WasmYAML::TableType> { 398 static void enumeration(IO &IO, WasmYAML::TableType &Type); 399 }; 400 401 template <> struct ScalarEnumerationTraits<WasmYAML::Opcode> { 402 static void enumeration(IO &IO, WasmYAML::Opcode &Opcode); 403 }; 404 405 template <> struct ScalarEnumerationTraits<WasmYAML::RelocType> { 406 static void enumeration(IO &IO, WasmYAML::RelocType &Kind); 407 }; 408 409 } // end namespace yaml 410 } // end namespace llvm 411 412 #endif // LLVM_OBJECTYAML_WASMYAML_H 413