blob: fa5448dacec4e6895bc41f4eb7e085cce4c85083 [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;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010027// Wasm linking metadata version
28const uint32_t WasmMetadataVersion = 0x1;
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
37struct WasmSignature {
38 std::vector<uint8_t> ParamTypes;
39 uint8_t ReturnType;
40};
41
42struct WasmExport {
43 StringRef Name;
44 uint8_t Kind;
45 uint32_t Index;
46};
47
48struct WasmLimits {
49 uint8_t Flags;
50 uint32_t Initial;
51 uint32_t Maximum;
52};
53
54struct WasmTable {
55 uint8_t ElemType;
56 WasmLimits Limits;
57};
58
59struct 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
70struct WasmGlobalType {
71 uint8_t Type;
72 bool Mutable;
73};
74
75struct WasmGlobal {
76 uint32_t Index;
77 WasmGlobalType Type;
78 WasmInitExpr InitExpr;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010079 StringRef SymbolName; // from the "linking" section
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010080};
81
82struct 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
94struct WasmLocalDecl {
95 uint8_t Type;
96 uint32_t Count;
97};
98
99struct WasmFunction {
100 uint32_t Index;
101 std::vector<WasmLocalDecl> Locals;
102 ArrayRef<uint8_t> Body;
103 uint32_t CodeSectionOffset;
104 uint32_t Size;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100105 uint32_t CodeOffset; // start of Locals and Body
106 StringRef SymbolName; // from the "linking" section
107 StringRef DebugName; // from the "name" section
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100108 uint32_t Comdat; // from the "comdat info" section
109};
110
111struct WasmDataSegment {
112 uint32_t MemoryIndex;
113 WasmInitExpr Offset;
114 ArrayRef<uint8_t> Content;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100115 StringRef Name; // from the "segment info" section
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100116 uint32_t Alignment;
117 uint32_t Flags;
118 uint32_t Comdat; // from the "comdat info" section
119};
120
121struct 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.
129struct WasmDataReference {
130 uint32_t Segment;
131 uint32_t Offset;
132 uint32_t Size;
133};
134
135struct 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
142struct WasmInitFunc {
143 uint32_t Priority;
144 uint32_t Symbol;
145};
146
147struct WasmSymbolInfo {
148 StringRef Name;
149 uint8_t Kind;
150 uint32_t Flags;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100151 StringRef Module; // For undefined symbols the module name of the import
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100152 union {
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100153 // For function or global symbols, the index in function or global index
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100154 // space.
155 uint32_t ElementIndex;
156 // For a data symbols, the address of the data relative to segment.
157 WasmDataReference DataRef;
158 };
159};
160
161struct WasmFunctionName {
162 uint32_t Index;
163 StringRef Name;
164};
165
166struct WasmLinkingData {
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100167 uint32_t Version;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100168 std::vector<WasmInitFunc> InitFunctions;
169 std::vector<StringRef> Comdats;
170 std::vector<WasmSymbolInfo> SymbolTable;
171};
172
173enum : 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.
189enum : 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).
201enum : 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.
209enum : 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
218enum : unsigned {
219 WASM_LIMITS_FLAG_HAS_MAX = 0x1,
220};
221
222// Subset of types that a value can have
223enum 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
232enum : unsigned {
233 WASM_NAMES_FUNCTION = 0x1,
234 WASM_NAMES_LOCAL = 0x2,
235};
236
237// Kind codes used in the custom "linking" section
238enum : 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
246enum : 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
252enum WasmSymbolType : unsigned {
253 WASM_SYMBOL_TYPE_FUNCTION = 0x0,
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100254 WASM_SYMBOL_TYPE_DATA = 0x1,
255 WASM_SYMBOL_TYPE_GLOBAL = 0x2,
256 WASM_SYMBOL_TYPE_SECTION = 0x3,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100257};
258
259const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;
260const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0xc;
261
262const unsigned WASM_SYMBOL_BINDING_GLOBAL = 0x0;
263const unsigned WASM_SYMBOL_BINDING_WEAK = 0x1;
264const unsigned WASM_SYMBOL_BINDING_LOCAL = 0x2;
265const unsigned WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0;
266const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4;
267const unsigned WASM_SYMBOL_UNDEFINED = 0x10;
268
269#define WASM_RELOC(name, value) name = value,
270
271enum : unsigned {
272#include "WasmRelocs.def"
273};
274
275#undef WASM_RELOC
276
277// Useful comparison operators
278inline bool operator==(const WasmSignature &LHS, const WasmSignature &RHS) {
279 return LHS.ReturnType == RHS.ReturnType && LHS.ParamTypes == RHS.ParamTypes;
280}
281
282inline bool operator!=(const WasmSignature &LHS, const WasmSignature &RHS) {
283 return !(LHS == RHS);
284}
285
286inline bool operator==(const WasmGlobalType &LHS, const WasmGlobalType &RHS) {
287 return LHS.Type == RHS.Type && LHS.Mutable == RHS.Mutable;
288}
289
290inline bool operator!=(const WasmGlobalType &LHS, const WasmGlobalType &RHS) {
291 return !(LHS == RHS);
292}
293
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100294std::string toString(wasm::WasmSymbolType type);
295std::string relocTypetoString(uint32_t type);
296
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100297} // end namespace wasm
298} // end namespace llvm
299
300#endif