blob: 51f6ab2594b0cdd4183a2363f1fb6e3c454b64a4 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- Wasm.h - Wasm object file format -------------------------*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8//
9// This file defines manifest constants for the wasm object file format.
10// See: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_BINARYFORMAT_WASM_H
15#define LLVM_BINARYFORMAT_WASM_H
16
17#include "llvm/ADT/ArrayRef.h"
Andrew Scull0372a572018-11-16 15:47:06 +000018#include "llvm/ADT/SmallVector.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010019
20namespace llvm {
21namespace wasm {
22
23// Object file magic string.
24const char WasmMagic[] = {'\0', 'a', 's', 'm'};
25// Wasm binary format version
26const uint32_t WasmVersion = 0x1;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010027// Wasm linking metadata version
Andrew Walbran16937d02019-10-22 13:54:20 +010028const uint32_t WasmMetadataVersion = 0x2;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010029// Wasm uses a 64k page size
30const uint32_t WasmPageSize = 65536;
31
32struct WasmObjectHeader {
33 StringRef Magic;
34 uint32_t Version;
35};
36
Andrew Walbran16937d02019-10-22 13:54:20 +010037struct WasmDylinkInfo {
38 uint32_t MemorySize; // Memory size in bytes
39 uint32_t MemoryAlignment; // P2 alignment of memory
40 uint32_t TableSize; // Table size in elements
41 uint32_t TableAlignment; // P2 alignment of table
42 std::vector<StringRef> Needed; // Shared library depenedencies
43};
44
45struct WasmProducerInfo {
46 std::vector<std::pair<std::string, std::string>> Languages;
47 std::vector<std::pair<std::string, std::string>> Tools;
48 std::vector<std::pair<std::string, std::string>> SDKs;
49};
50
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010051struct WasmExport {
52 StringRef Name;
53 uint8_t Kind;
54 uint32_t Index;
55};
56
57struct WasmLimits {
58 uint8_t Flags;
59 uint32_t Initial;
60 uint32_t Maximum;
61};
62
63struct WasmTable {
64 uint8_t ElemType;
65 WasmLimits Limits;
66};
67
68struct WasmInitExpr {
69 uint8_t Opcode;
70 union {
71 int32_t Int32;
72 int64_t Int64;
73 int32_t Float32;
74 int64_t Float64;
75 uint32_t Global;
76 } Value;
77};
78
79struct WasmGlobalType {
80 uint8_t Type;
81 bool Mutable;
82};
83
84struct WasmGlobal {
85 uint32_t Index;
86 WasmGlobalType Type;
87 WasmInitExpr InitExpr;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010088 StringRef SymbolName; // from the "linking" section
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010089};
90
Andrew Walbran16937d02019-10-22 13:54:20 +010091struct WasmEventType {
92 // Kind of event. Currently only WASM_EVENT_ATTRIBUTE_EXCEPTION is possible.
93 uint32_t Attribute;
94 uint32_t SigIndex;
95};
96
97struct WasmEvent {
98 uint32_t Index;
99 WasmEventType Type;
100 StringRef SymbolName; // from the "linking" section
101};
102
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100103struct WasmImport {
104 StringRef Module;
105 StringRef Field;
106 uint8_t Kind;
107 union {
108 uint32_t SigIndex;
109 WasmGlobalType Global;
110 WasmTable Table;
111 WasmLimits Memory;
Andrew Walbran16937d02019-10-22 13:54:20 +0100112 WasmEventType Event;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100113 };
114};
115
116struct WasmLocalDecl {
117 uint8_t Type;
118 uint32_t Count;
119};
120
121struct WasmFunction {
122 uint32_t Index;
123 std::vector<WasmLocalDecl> Locals;
124 ArrayRef<uint8_t> Body;
125 uint32_t CodeSectionOffset;
126 uint32_t Size;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100127 uint32_t CodeOffset; // start of Locals and Body
128 StringRef SymbolName; // from the "linking" section
Andrew Scull0372a572018-11-16 15:47:06 +0000129 StringRef DebugName; // from the "name" section
130 uint32_t Comdat; // from the "comdat info" section
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100131};
132
133struct WasmDataSegment {
134 uint32_t MemoryIndex;
135 WasmInitExpr Offset;
136 ArrayRef<uint8_t> Content;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100137 StringRef Name; // from the "segment info" section
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100138 uint32_t Alignment;
139 uint32_t Flags;
140 uint32_t Comdat; // from the "comdat info" section
141};
142
143struct WasmElemSegment {
144 uint32_t TableIndex;
145 WasmInitExpr Offset;
146 std::vector<uint32_t> Functions;
147};
148
149// Represents the location of a Wasm data symbol within a WasmDataSegment, as
150// the index of the segment, and the offset and size within the segment.
151struct WasmDataReference {
152 uint32_t Segment;
153 uint32_t Offset;
154 uint32_t Size;
155};
156
157struct WasmRelocation {
158 uint8_t Type; // The type of the relocation.
159 uint32_t Index; // Index into either symbol or type index space.
160 uint64_t Offset; // Offset from the start of the section.
161 int64_t Addend; // A value to add to the symbol.
162};
163
164struct WasmInitFunc {
165 uint32_t Priority;
166 uint32_t Symbol;
167};
168
169struct WasmSymbolInfo {
170 StringRef Name;
171 uint8_t Kind;
172 uint32_t Flags;
Andrew Walbran16937d02019-10-22 13:54:20 +0100173 StringRef ImportModule; // For undefined symbols the module of the import
174 StringRef ImportName; // For undefined symbols the name of the import
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100175 union {
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100176 // For function or global symbols, the index in function or global index
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100177 // space.
178 uint32_t ElementIndex;
179 // For a data symbols, the address of the data relative to segment.
180 WasmDataReference DataRef;
181 };
182};
183
184struct WasmFunctionName {
185 uint32_t Index;
186 StringRef Name;
187};
188
189struct WasmLinkingData {
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100190 uint32_t Version;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100191 std::vector<WasmInitFunc> InitFunctions;
192 std::vector<StringRef> Comdats;
193 std::vector<WasmSymbolInfo> SymbolTable;
194};
195
196enum : unsigned {
Andrew Walbran16937d02019-10-22 13:54:20 +0100197 WASM_SEC_CUSTOM = 0, // Custom / User-defined section
198 WASM_SEC_TYPE = 1, // Function signature declarations
199 WASM_SEC_IMPORT = 2, // Import declarations
200 WASM_SEC_FUNCTION = 3, // Function declarations
201 WASM_SEC_TABLE = 4, // Indirect function table and other tables
202 WASM_SEC_MEMORY = 5, // Memory attributes
203 WASM_SEC_GLOBAL = 6, // Global declarations
204 WASM_SEC_EXPORT = 7, // Exports
205 WASM_SEC_START = 8, // Start function declaration
206 WASM_SEC_ELEM = 9, // Elements section
207 WASM_SEC_CODE = 10, // Function bodies (code)
208 WASM_SEC_DATA = 11, // Data segments
209 WASM_SEC_DATACOUNT = 12, // Data segment count
210 WASM_SEC_EVENT = 13 // Event declarations
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100211};
212
213// Type immediate encodings used in various contexts.
214enum : unsigned {
215 WASM_TYPE_I32 = 0x7F,
216 WASM_TYPE_I64 = 0x7E,
217 WASM_TYPE_F32 = 0x7D,
218 WASM_TYPE_F64 = 0x7C,
Andrew Scull0372a572018-11-16 15:47:06 +0000219 WASM_TYPE_V128 = 0x7B,
Andrew Walbran16937d02019-10-22 13:54:20 +0100220 WASM_TYPE_FUNCREF = 0x70,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100221 WASM_TYPE_EXCEPT_REF = 0x68,
222 WASM_TYPE_FUNC = 0x60,
223 WASM_TYPE_NORESULT = 0x40, // for blocks with no result values
224};
225
226// Kinds of externals (for imports and exports).
227enum : unsigned {
228 WASM_EXTERNAL_FUNCTION = 0x0,
229 WASM_EXTERNAL_TABLE = 0x1,
230 WASM_EXTERNAL_MEMORY = 0x2,
231 WASM_EXTERNAL_GLOBAL = 0x3,
Andrew Walbran16937d02019-10-22 13:54:20 +0100232 WASM_EXTERNAL_EVENT = 0x4,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100233};
234
235// Opcodes used in initializer expressions.
236enum : unsigned {
237 WASM_OPCODE_END = 0x0b,
Andrew Walbran16937d02019-10-22 13:54:20 +0100238 WASM_OPCODE_GLOBAL_GET = 0x23,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100239 WASM_OPCODE_I32_CONST = 0x41,
240 WASM_OPCODE_I64_CONST = 0x42,
241 WASM_OPCODE_F32_CONST = 0x43,
242 WASM_OPCODE_F64_CONST = 0x44,
243};
244
245enum : unsigned {
246 WASM_LIMITS_FLAG_HAS_MAX = 0x1,
Andrew Walbran16937d02019-10-22 13:54:20 +0100247 WASM_LIMITS_FLAG_IS_SHARED = 0x2,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100248};
249
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100250// Kind codes used in the custom "name" section
251enum : unsigned {
252 WASM_NAMES_FUNCTION = 0x1,
Andrew Scull0372a572018-11-16 15:47:06 +0000253 WASM_NAMES_LOCAL = 0x2,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100254};
255
256// Kind codes used in the custom "linking" section
257enum : unsigned {
Andrew Scull0372a572018-11-16 15:47:06 +0000258 WASM_SEGMENT_INFO = 0x5,
259 WASM_INIT_FUNCS = 0x6,
260 WASM_COMDAT_INFO = 0x7,
261 WASM_SYMBOL_TABLE = 0x8,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100262};
263
264// Kind codes used in the custom "linking" section in the WASM_COMDAT_INFO
265enum : unsigned {
Andrew Scull0372a572018-11-16 15:47:06 +0000266 WASM_COMDAT_DATA = 0x0,
267 WASM_COMDAT_FUNCTION = 0x1,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100268};
269
270// Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE
271enum WasmSymbolType : unsigned {
272 WASM_SYMBOL_TYPE_FUNCTION = 0x0,
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100273 WASM_SYMBOL_TYPE_DATA = 0x1,
274 WASM_SYMBOL_TYPE_GLOBAL = 0x2,
275 WASM_SYMBOL_TYPE_SECTION = 0x3,
Andrew Walbran16937d02019-10-22 13:54:20 +0100276 WASM_SYMBOL_TYPE_EVENT = 0x4,
277};
278
279// Kinds of event attributes.
280enum WasmEventAttribute : unsigned {
281 WASM_EVENT_ATTRIBUTE_EXCEPTION = 0x0,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100282};
283
Andrew Scull0372a572018-11-16 15:47:06 +0000284const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;
285const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0xc;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100286
Andrew Scull0372a572018-11-16 15:47:06 +0000287const unsigned WASM_SYMBOL_BINDING_GLOBAL = 0x0;
288const unsigned WASM_SYMBOL_BINDING_WEAK = 0x1;
289const unsigned WASM_SYMBOL_BINDING_LOCAL = 0x2;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100290const unsigned WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0;
Andrew Scull0372a572018-11-16 15:47:06 +0000291const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4;
292const unsigned WASM_SYMBOL_UNDEFINED = 0x10;
Andrew Walbran16937d02019-10-22 13:54:20 +0100293const unsigned WASM_SYMBOL_EXPORTED = 0x20;
294const unsigned WASM_SYMBOL_EXPLICIT_NAME = 0x40;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100295
296#define WASM_RELOC(name, value) name = value,
297
298enum : unsigned {
299#include "WasmRelocs.def"
300};
301
302#undef WASM_RELOC
303
Andrew Scull0372a572018-11-16 15:47:06 +0000304// Subset of types that a value can have
305enum class ValType {
306 I32 = WASM_TYPE_I32,
307 I64 = WASM_TYPE_I64,
308 F32 = WASM_TYPE_F32,
309 F64 = WASM_TYPE_F64,
310 V128 = WASM_TYPE_V128,
311 EXCEPT_REF = WASM_TYPE_EXCEPT_REF,
312};
313
314struct WasmSignature {
Andrew Walbran16937d02019-10-22 13:54:20 +0100315 SmallVector<ValType, 1> Returns;
316 SmallVector<ValType, 4> Params;
Andrew Scull0372a572018-11-16 15:47:06 +0000317 // Support empty and tombstone instances, needed by DenseMap.
318 enum { Plain, Empty, Tombstone } State = Plain;
319
Andrew Walbran16937d02019-10-22 13:54:20 +0100320 WasmSignature(SmallVector<ValType, 1> &&InReturns,
321 SmallVector<ValType, 4> &&InParams)
Andrew Scull0372a572018-11-16 15:47:06 +0000322 : Returns(InReturns), Params(InParams) {}
323 WasmSignature() = default;
324};
325
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100326// Useful comparison operators
327inline bool operator==(const WasmSignature &LHS, const WasmSignature &RHS) {
Andrew Scull0372a572018-11-16 15:47:06 +0000328 return LHS.State == RHS.State && LHS.Returns == RHS.Returns &&
329 LHS.Params == RHS.Params;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100330}
331
332inline bool operator!=(const WasmSignature &LHS, const WasmSignature &RHS) {
333 return !(LHS == RHS);
334}
335
336inline bool operator==(const WasmGlobalType &LHS, const WasmGlobalType &RHS) {
337 return LHS.Type == RHS.Type && LHS.Mutable == RHS.Mutable;
338}
339
340inline bool operator!=(const WasmGlobalType &LHS, const WasmGlobalType &RHS) {
341 return !(LHS == RHS);
342}
343
Andrew Walbran16937d02019-10-22 13:54:20 +0100344std::string toString(WasmSymbolType type);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100345std::string relocTypetoString(uint32_t type);
346
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100347} // end namespace wasm
348} // end namespace llvm
349
350#endif