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