1 //===- Wasm.h - Wasm object file format -------------------------*- 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 // This file defines manifest constants for the wasm object file format. 11 // See: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_BINARYFORMAT_WASM_H 16 #define LLVM_BINARYFORMAT_WASM_H 17 18 #include "llvm/ADT/ArrayRef.h" 19 20 namespace llvm { 21 namespace wasm { 22 23 // Object file magic string. 24 const char WasmMagic[] = {'\0', 'a', 's', 'm'}; 25 // Wasm binary format version 26 const uint32_t WasmVersion = 0x1; 27 // Wasm linking metadata version 28 const uint32_t WasmMetadataVersion = 0x1; 29 // Wasm uses a 64k page size 30 const uint32_t WasmPageSize = 65536; 31 32 struct WasmObjectHeader { 33 StringRef Magic; 34 uint32_t Version; 35 }; 36 37 struct WasmSignature { 38 std::vector<uint8_t> ParamTypes; 39 uint8_t ReturnType; 40 }; 41 42 struct WasmExport { 43 StringRef Name; 44 uint8_t Kind; 45 uint32_t Index; 46 }; 47 48 struct WasmLimits { 49 uint8_t Flags; 50 uint32_t Initial; 51 uint32_t Maximum; 52 }; 53 54 struct WasmTable { 55 uint8_t ElemType; 56 WasmLimits Limits; 57 }; 58 59 struct WasmInitExpr { 60 uint8_t Opcode; 61 union { 62 int32_t Int32; 63 int64_t Int64; 64 int32_t Float32; 65 int64_t Float64; 66 uint32_t Global; 67 } Value; 68 }; 69 70 struct WasmGlobalType { 71 uint8_t Type; 72 bool Mutable; 73 }; 74 75 struct WasmGlobal { 76 uint32_t Index; 77 WasmGlobalType Type; 78 WasmInitExpr InitExpr; 79 StringRef SymbolName; // from the "linking" section 80 }; 81 82 struct WasmImport { 83 StringRef Module; 84 StringRef Field; 85 uint8_t Kind; 86 union { 87 uint32_t SigIndex; 88 WasmGlobalType Global; 89 WasmTable Table; 90 WasmLimits Memory; 91 }; 92 }; 93 94 struct WasmLocalDecl { 95 uint8_t Type; 96 uint32_t Count; 97 }; 98 99 struct WasmFunction { 100 uint32_t Index; 101 std::vector<WasmLocalDecl> Locals; 102 ArrayRef<uint8_t> Body; 103 uint32_t CodeSectionOffset; 104 uint32_t Size; 105 uint32_t CodeOffset; // start of Locals and Body 106 StringRef SymbolName; // from the "linking" section 107 StringRef DebugName; // from the "name" section 108 uint32_t Comdat; // from the "comdat info" section 109 }; 110 111 struct WasmDataSegment { 112 uint32_t MemoryIndex; 113 WasmInitExpr Offset; 114 ArrayRef<uint8_t> Content; 115 StringRef Name; // from the "segment info" section 116 uint32_t Alignment; 117 uint32_t Flags; 118 uint32_t Comdat; // from the "comdat info" section 119 }; 120 121 struct WasmElemSegment { 122 uint32_t TableIndex; 123 WasmInitExpr Offset; 124 std::vector<uint32_t> Functions; 125 }; 126 127 // Represents the location of a Wasm data symbol within a WasmDataSegment, as 128 // the index of the segment, and the offset and size within the segment. 129 struct WasmDataReference { 130 uint32_t Segment; 131 uint32_t Offset; 132 uint32_t Size; 133 }; 134 135 struct WasmRelocation { 136 uint8_t Type; // The type of the relocation. 137 uint32_t Index; // Index into either symbol or type index space. 138 uint64_t Offset; // Offset from the start of the section. 139 int64_t Addend; // A value to add to the symbol. 140 }; 141 142 struct WasmInitFunc { 143 uint32_t Priority; 144 uint32_t Symbol; 145 }; 146 147 struct WasmSymbolInfo { 148 StringRef Name; 149 uint8_t Kind; 150 uint32_t Flags; 151 StringRef Module; // For undefined symbols the module name of the import 152 union { 153 // For function or global symbols, the index in function or global index 154 // space. 155 uint32_t ElementIndex; 156 // For a data symbols, the address of the data relative to segment. 157 WasmDataReference DataRef; 158 }; 159 }; 160 161 struct WasmFunctionName { 162 uint32_t Index; 163 StringRef Name; 164 }; 165 166 struct WasmLinkingData { 167 uint32_t Version; 168 std::vector<WasmInitFunc> InitFunctions; 169 std::vector<StringRef> Comdats; 170 std::vector<WasmSymbolInfo> SymbolTable; 171 }; 172 173 enum : unsigned { 174 WASM_SEC_CUSTOM = 0, // Custom / User-defined section 175 WASM_SEC_TYPE = 1, // Function signature declarations 176 WASM_SEC_IMPORT = 2, // Import declarations 177 WASM_SEC_FUNCTION = 3, // Function declarations 178 WASM_SEC_TABLE = 4, // Indirect function table and other tables 179 WASM_SEC_MEMORY = 5, // Memory attributes 180 WASM_SEC_GLOBAL = 6, // Global declarations 181 WASM_SEC_EXPORT = 7, // Exports 182 WASM_SEC_START = 8, // Start function declaration 183 WASM_SEC_ELEM = 9, // Elements section 184 WASM_SEC_CODE = 10, // Function bodies (code) 185 WASM_SEC_DATA = 11 // Data segments 186 }; 187 188 // Type immediate encodings used in various contexts. 189 enum : unsigned { 190 WASM_TYPE_I32 = 0x7F, 191 WASM_TYPE_I64 = 0x7E, 192 WASM_TYPE_F32 = 0x7D, 193 WASM_TYPE_F64 = 0x7C, 194 WASM_TYPE_ANYFUNC = 0x70, 195 WASM_TYPE_EXCEPT_REF = 0x68, 196 WASM_TYPE_FUNC = 0x60, 197 WASM_TYPE_NORESULT = 0x40, // for blocks with no result values 198 }; 199 200 // Kinds of externals (for imports and exports). 201 enum : unsigned { 202 WASM_EXTERNAL_FUNCTION = 0x0, 203 WASM_EXTERNAL_TABLE = 0x1, 204 WASM_EXTERNAL_MEMORY = 0x2, 205 WASM_EXTERNAL_GLOBAL = 0x3, 206 }; 207 208 // Opcodes used in initializer expressions. 209 enum : unsigned { 210 WASM_OPCODE_END = 0x0b, 211 WASM_OPCODE_GET_GLOBAL = 0x23, 212 WASM_OPCODE_I32_CONST = 0x41, 213 WASM_OPCODE_I64_CONST = 0x42, 214 WASM_OPCODE_F32_CONST = 0x43, 215 WASM_OPCODE_F64_CONST = 0x44, 216 }; 217 218 enum : unsigned { 219 WASM_LIMITS_FLAG_HAS_MAX = 0x1, 220 }; 221 222 // Subset of types that a value can have 223 enum class ValType { 224 I32 = WASM_TYPE_I32, 225 I64 = WASM_TYPE_I64, 226 F32 = WASM_TYPE_F32, 227 F64 = WASM_TYPE_F64, 228 EXCEPT_REF = WASM_TYPE_EXCEPT_REF, 229 }; 230 231 // Kind codes used in the custom "name" section 232 enum : unsigned { 233 WASM_NAMES_FUNCTION = 0x1, 234 WASM_NAMES_LOCAL = 0x2, 235 }; 236 237 // Kind codes used in the custom "linking" section 238 enum : unsigned { 239 WASM_SEGMENT_INFO = 0x5, 240 WASM_INIT_FUNCS = 0x6, 241 WASM_COMDAT_INFO = 0x7, 242 WASM_SYMBOL_TABLE = 0x8, 243 }; 244 245 // Kind codes used in the custom "linking" section in the WASM_COMDAT_INFO 246 enum : unsigned { 247 WASM_COMDAT_DATA = 0x0, 248 WASM_COMDAT_FUNCTION = 0x1, 249 }; 250 251 // Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE 252 enum WasmSymbolType : unsigned { 253 WASM_SYMBOL_TYPE_FUNCTION = 0x0, 254 WASM_SYMBOL_TYPE_DATA = 0x1, 255 WASM_SYMBOL_TYPE_GLOBAL = 0x2, 256 WASM_SYMBOL_TYPE_SECTION = 0x3, 257 }; 258 259 const unsigned WASM_SYMBOL_BINDING_MASK = 0x3; 260 const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0xc; 261 262 const unsigned WASM_SYMBOL_BINDING_GLOBAL = 0x0; 263 const unsigned WASM_SYMBOL_BINDING_WEAK = 0x1; 264 const unsigned WASM_SYMBOL_BINDING_LOCAL = 0x2; 265 const unsigned WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0; 266 const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4; 267 const unsigned WASM_SYMBOL_UNDEFINED = 0x10; 268 269 #define WASM_RELOC(name, value) name = value, 270 271 enum : unsigned { 272 #include "WasmRelocs.def" 273 }; 274 275 #undef WASM_RELOC 276 277 // Useful comparison operators 278 inline bool operator==(const WasmSignature &LHS, const WasmSignature &RHS) { 279 return LHS.ReturnType == RHS.ReturnType && LHS.ParamTypes == RHS.ParamTypes; 280 } 281 282 inline bool operator!=(const WasmSignature &LHS, const WasmSignature &RHS) { 283 return !(LHS == RHS); 284 } 285 286 inline bool operator==(const WasmGlobalType &LHS, const WasmGlobalType &RHS) { 287 return LHS.Type == RHS.Type && LHS.Mutable == RHS.Mutable; 288 } 289 290 inline bool operator!=(const WasmGlobalType &LHS, const WasmGlobalType &RHS) { 291 return !(LHS == RHS); 292 } 293 294 std::string toString(wasm::WasmSymbolType type); 295 std::string relocTypetoString(uint32_t type); 296 297 } // end namespace wasm 298 } // end namespace llvm 299 300 #endif 301