blob: 44dd92ea90103422bdd812e2eae28bd804844046 [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"
Andrew Scull0372a572018-11-16 15:47:06 +000019#include "llvm/ADT/SmallVector.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010020
21namespace llvm {
22namespace wasm {
23
24// Object file magic string.
25const char WasmMagic[] = {'\0', 'a', 's', 'm'};
26// Wasm binary format version
27const uint32_t WasmVersion = 0x1;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010028// Wasm linking metadata version
29const uint32_t WasmMetadataVersion = 0x1;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010030// Wasm uses a 64k page size
31const uint32_t WasmPageSize = 65536;
32
33struct WasmObjectHeader {
34 StringRef Magic;
35 uint32_t Version;
36};
37
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010038struct WasmExport {
39 StringRef Name;
40 uint8_t Kind;
41 uint32_t Index;
42};
43
44struct WasmLimits {
45 uint8_t Flags;
46 uint32_t Initial;
47 uint32_t Maximum;
48};
49
50struct WasmTable {
51 uint8_t ElemType;
52 WasmLimits Limits;
53};
54
55struct WasmInitExpr {
56 uint8_t Opcode;
57 union {
58 int32_t Int32;
59 int64_t Int64;
60 int32_t Float32;
61 int64_t Float64;
62 uint32_t Global;
63 } Value;
64};
65
66struct WasmGlobalType {
67 uint8_t Type;
68 bool Mutable;
69};
70
71struct WasmGlobal {
72 uint32_t Index;
73 WasmGlobalType Type;
74 WasmInitExpr InitExpr;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010075 StringRef SymbolName; // from the "linking" section
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010076};
77
78struct WasmImport {
79 StringRef Module;
80 StringRef Field;
81 uint8_t Kind;
82 union {
83 uint32_t SigIndex;
84 WasmGlobalType Global;
85 WasmTable Table;
86 WasmLimits Memory;
87 };
88};
89
90struct WasmLocalDecl {
91 uint8_t Type;
92 uint32_t Count;
93};
94
95struct WasmFunction {
96 uint32_t Index;
97 std::vector<WasmLocalDecl> Locals;
98 ArrayRef<uint8_t> Body;
99 uint32_t CodeSectionOffset;
100 uint32_t Size;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100101 uint32_t CodeOffset; // start of Locals and Body
102 StringRef SymbolName; // from the "linking" section
Andrew Scull0372a572018-11-16 15:47:06 +0000103 StringRef DebugName; // from the "name" section
104 uint32_t Comdat; // from the "comdat info" section
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100105};
106
107struct WasmDataSegment {
108 uint32_t MemoryIndex;
109 WasmInitExpr Offset;
110 ArrayRef<uint8_t> Content;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100111 StringRef Name; // from the "segment info" section
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100112 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;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100147 StringRef Module; // For undefined symbols the module name of the import
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100148 union {
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100149 // For function or global symbols, the index in function or global index
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100150 // space.
151 uint32_t ElementIndex;
152 // For a data symbols, the address of the data relative to segment.
153 WasmDataReference DataRef;
154 };
155};
156
157struct WasmFunctionName {
158 uint32_t Index;
159 StringRef Name;
160};
161
162struct WasmLinkingData {
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100163 uint32_t Version;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100164 std::vector<WasmInitFunc> InitFunctions;
165 std::vector<StringRef> Comdats;
166 std::vector<WasmSymbolInfo> SymbolTable;
167};
168
169enum : unsigned {
170 WASM_SEC_CUSTOM = 0, // Custom / User-defined section
171 WASM_SEC_TYPE = 1, // Function signature declarations
172 WASM_SEC_IMPORT = 2, // Import declarations
173 WASM_SEC_FUNCTION = 3, // Function declarations
174 WASM_SEC_TABLE = 4, // Indirect function table and other tables
175 WASM_SEC_MEMORY = 5, // Memory attributes
176 WASM_SEC_GLOBAL = 6, // Global declarations
177 WASM_SEC_EXPORT = 7, // Exports
178 WASM_SEC_START = 8, // Start function declaration
179 WASM_SEC_ELEM = 9, // Elements section
180 WASM_SEC_CODE = 10, // Function bodies (code)
181 WASM_SEC_DATA = 11 // Data segments
182};
183
184// Type immediate encodings used in various contexts.
185enum : unsigned {
186 WASM_TYPE_I32 = 0x7F,
187 WASM_TYPE_I64 = 0x7E,
188 WASM_TYPE_F32 = 0x7D,
189 WASM_TYPE_F64 = 0x7C,
Andrew Scull0372a572018-11-16 15:47:06 +0000190 WASM_TYPE_V128 = 0x7B,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100191 WASM_TYPE_ANYFUNC = 0x70,
192 WASM_TYPE_EXCEPT_REF = 0x68,
193 WASM_TYPE_FUNC = 0x60,
194 WASM_TYPE_NORESULT = 0x40, // for blocks with no result values
195};
196
197// Kinds of externals (for imports and exports).
198enum : unsigned {
199 WASM_EXTERNAL_FUNCTION = 0x0,
200 WASM_EXTERNAL_TABLE = 0x1,
201 WASM_EXTERNAL_MEMORY = 0x2,
202 WASM_EXTERNAL_GLOBAL = 0x3,
203};
204
205// Opcodes used in initializer expressions.
206enum : unsigned {
207 WASM_OPCODE_END = 0x0b,
208 WASM_OPCODE_GET_GLOBAL = 0x23,
209 WASM_OPCODE_I32_CONST = 0x41,
210 WASM_OPCODE_I64_CONST = 0x42,
211 WASM_OPCODE_F32_CONST = 0x43,
212 WASM_OPCODE_F64_CONST = 0x44,
213};
214
215enum : unsigned {
216 WASM_LIMITS_FLAG_HAS_MAX = 0x1,
217};
218
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100219// Kind codes used in the custom "name" section
220enum : unsigned {
221 WASM_NAMES_FUNCTION = 0x1,
Andrew Scull0372a572018-11-16 15:47:06 +0000222 WASM_NAMES_LOCAL = 0x2,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100223};
224
225// Kind codes used in the custom "linking" section
226enum : unsigned {
Andrew Scull0372a572018-11-16 15:47:06 +0000227 WASM_SEGMENT_INFO = 0x5,
228 WASM_INIT_FUNCS = 0x6,
229 WASM_COMDAT_INFO = 0x7,
230 WASM_SYMBOL_TABLE = 0x8,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100231};
232
233// Kind codes used in the custom "linking" section in the WASM_COMDAT_INFO
234enum : unsigned {
Andrew Scull0372a572018-11-16 15:47:06 +0000235 WASM_COMDAT_DATA = 0x0,
236 WASM_COMDAT_FUNCTION = 0x1,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100237};
238
239// Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE
240enum WasmSymbolType : unsigned {
241 WASM_SYMBOL_TYPE_FUNCTION = 0x0,
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100242 WASM_SYMBOL_TYPE_DATA = 0x1,
243 WASM_SYMBOL_TYPE_GLOBAL = 0x2,
244 WASM_SYMBOL_TYPE_SECTION = 0x3,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100245};
246
Andrew Scull0372a572018-11-16 15:47:06 +0000247const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;
248const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0xc;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100249
Andrew Scull0372a572018-11-16 15:47:06 +0000250const unsigned WASM_SYMBOL_BINDING_GLOBAL = 0x0;
251const unsigned WASM_SYMBOL_BINDING_WEAK = 0x1;
252const unsigned WASM_SYMBOL_BINDING_LOCAL = 0x2;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100253const unsigned WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0;
Andrew Scull0372a572018-11-16 15:47:06 +0000254const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4;
255const unsigned WASM_SYMBOL_UNDEFINED = 0x10;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100256
257#define WASM_RELOC(name, value) name = value,
258
259enum : unsigned {
260#include "WasmRelocs.def"
261};
262
263#undef WASM_RELOC
264
Andrew Scull0372a572018-11-16 15:47:06 +0000265// Subset of types that a value can have
266enum class ValType {
267 I32 = WASM_TYPE_I32,
268 I64 = WASM_TYPE_I64,
269 F32 = WASM_TYPE_F32,
270 F64 = WASM_TYPE_F64,
271 V128 = WASM_TYPE_V128,
272 EXCEPT_REF = WASM_TYPE_EXCEPT_REF,
273};
274
275struct WasmSignature {
276 SmallVector<wasm::ValType, 1> Returns;
277 SmallVector<wasm::ValType, 4> Params;
278 // Support empty and tombstone instances, needed by DenseMap.
279 enum { Plain, Empty, Tombstone } State = Plain;
280
281 WasmSignature(SmallVector<wasm::ValType, 1> &&InReturns,
282 SmallVector<wasm::ValType, 4> &&InParams)
283 : Returns(InReturns), Params(InParams) {}
284 WasmSignature() = default;
285};
286
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100287// Useful comparison operators
288inline bool operator==(const WasmSignature &LHS, const WasmSignature &RHS) {
Andrew Scull0372a572018-11-16 15:47:06 +0000289 return LHS.State == RHS.State && LHS.Returns == RHS.Returns &&
290 LHS.Params == RHS.Params;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100291}
292
293inline bool operator!=(const WasmSignature &LHS, const WasmSignature &RHS) {
294 return !(LHS == RHS);
295}
296
297inline bool operator==(const WasmGlobalType &LHS, const WasmGlobalType &RHS) {
298 return LHS.Type == RHS.Type && LHS.Mutable == RHS.Mutable;
299}
300
301inline bool operator!=(const WasmGlobalType &LHS, const WasmGlobalType &RHS) {
302 return !(LHS == RHS);
303}
304
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100305std::string toString(wasm::WasmSymbolType type);
306std::string relocTypetoString(uint32_t type);
307
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100308} // end namespace wasm
309} // end namespace llvm
310
311#endif