├── BasicCABI.md
├── BasicModuleABI.md
├── BuildId.md
├── CodeMetadata.md
├── Coredump.md
├── Debugging.md
├── DynamicLinking.md
├── EHScheme.md
├── ItaniumLikeC++ABI.md
├── LICENSE
├── Lime.md
├── Linking.md
├── ProducersSection.md
├── README.md
├── SetjmpLongjmp.md
├── Signatures.md
└── SwiftABI.md
/BasicCABI.md:
--------------------------------------------------------------------------------
1 | This document describes the "Basic" C ABI for WebAssembly. As mentioned in
2 | [README](README.md), it's not the only possible C ABI. It is the ABI that the
3 | clang/LLVM WebAssembly backend is currently using, and any other C or C++
4 | compiler wishing to be ABI-compatible with it.
5 |
6 | # Versioning and Machine interface
7 |
8 | The current version of this ABI is *1*.
9 |
10 | This ABI is designed to work with Release 1.0 of the WebAssembly [Specification](https://webassembly.github.io/spec/core/index.html). It does not require any
11 | [features](https://github.com/WebAssembly/proposals)
12 | that have not yet been implemented and standardized. Future versions will depend on
13 | features such as threads and/or multi-value.
14 |
15 | ## Data Representation
16 |
17 | **Scalar Types**
18 |
19 | The ABI for the currently-specifed version of WebAssembly (also known as "wasm32") uses an "ILP32" data model,
20 | where `int`, `long`, and pointer types are 32 bits. It is expected that the proposed extension to allow memories
21 | larger than 4GB ("wasm64") will use an "LP64" data model, where `int` is 32 bits while `pointer` and `long` are
22 | 64 bits.
23 |
24 | The following table shows the memory sizes and alignments of C and C++ scalar types, and their
25 | correspondence to types used in the WebAssembly specification:
26 |
27 |
28 | General type | C Type | `sizeof` | Alignment (bytes) | Wasm Value Type
29 | -|-|-|-|-
30 | Integer | `_Bool`/`bool` | 1 | 1 | i32
31 | Integer | `char`, `signed char` | 1 | 1 | i32
32 | Integer | `unsigned char` | 1 | 1 | i32
33 | Integer | `short` / `signed short` | 2 | 2 | i32
34 | Integer | `unsigned short` | 2 | 2 | i32
35 | Integer | `int` / `signed int` / `enum` | 4 | 4 | i32
36 | Integer | `unsigned int` | 4 | 4 | i32
37 | Integer | `long` / `signed long` | 4 | 4 | i32
38 | Integer | `unsigned long` | 4 | 4 | i32
39 | Integer | `long long` / `signed long long` | 8 | 8 | i64
40 | Integer | `unsigned long long` | 8 | 8 | i64
41 | Integer | `__int128_t` | 16 | 16 | (none)
42 | Integer | `__uint128_t` | 16 | 16 | (none)
43 | Pointer | *`any-type *`* / *`any-type (*)()`* | 4 | 4 | i32
44 | Floating point | `float` | 4 | 4 | f32
45 | Floating point | `double` | 8 | 8 | f64
46 | Floating point | `long double` | 16 | 16 | (none)
47 | Floating point | `long double` (Emscripten) | 16 | 8 | (none)
48 |
49 | * `long double` values correspond to 128-bit IEEE-754 quad-precision binary128 values.
50 | Operations on these values are currently implemented as calls to
51 | compiler-rt library functions.
52 | * A null pointer (for all types) has the value zero
53 | * The `size_t` type is defined as `unsigned long`.
54 | * An `enum` is `i32` if all the members of the `enum` can be represented
55 | by an `int`.
56 | An `enum` is `i32` if all the members of the `enum` can be represented
57 | by an `unsigned int`.
58 | Otherwise, if a compiler supports such an `enum`, it would use `i64`
59 | for the `enum`.
60 | * Emscripten uses 8 byte alignment for `long double`.
61 | * `__int128_t` and `__uint128_t` are passed as two `i64`s in little-endian
62 | order, and are otherwise represented in the ABI as a struct containing two
63 | `i64` fields, in little-endian order.
64 | * `_Complex` types are represented in the ABI as a struct containing two
65 | corresponding floating-point fields, real and imaginary.
66 | * `_BitInt(N)` types are supported up to width 128 and are represented as the
67 | smallest same-signedness Integer type with at least as many bits.
68 |
69 | **Aggregates and Unions**
70 |
71 | Structures and unions assume the alignment of their most strictly aligned component.
72 | Each member is assigned to the lowest available offset with the appropriate
73 | alignment. The size of any object is always a multiple of the object‘s alignment.
74 | An array uses the same alignment as its elements, except that a local or global
75 | array variable of length at least 16 bytes or a C99 variable-length array variable
76 | always has alignment of at least 16 bytes.
77 | Structure and union objects can require padding to meet size and alignment
78 | constraints. The contents of any padding is undefined.
79 |
80 | **Bit-fields**
81 |
82 | C struct and union definitions may include bit-fields that define integral values of
83 | a specified size.
84 | The ABI does not permit bit-fields having the type __m64, __m128 or __m256.
85 | (Programs using bit-fields of these types are not portable.)
86 | Bit-fields that are neither signed nor unsigned always have non-negative values.
87 | Although they may have type char, short, int, or long (which can have negative values),
88 | these bit-fields have the same range as a bit-field of the same size
89 | with the corresponding unsigned type. Bit-fields obey the same size and alignment
90 | rules as other structure and union members.
91 | Also:
92 |
93 | * bit-fields are allocated from right to left
94 | * bit-fields must be contained in a storage unit appropriate for its declared
95 | type
96 | * bit-fields may share a storage unit with other struct / union members
97 | * Unnamed bit-fields’ types do not affect the alignment of a structure or union.
98 |
99 | Bitfield type | Witdh *w* | Range
100 | -|-|-
101 | `signed char` | 1 to 8 | -2(w-1) to 2(w-1)-1
102 | `char`, `unsigned char` | 1 to 8 | 0 to 2w-1
103 | `signed short` | 1 to 16 | -2(w-1) to 2(w-1)-1
104 | `short`, `unsigned short` | 1 to 16 | 0 to 2w-1
105 | `signed int` | 1 to 32 | -2(w-1) to 2(w-1)-1
106 | `int`, `unsigned int` | 1 to 32 | 0 to 2w-1
107 | `signed long long` | 1 to 64 | -2(w-1) to 2(w-1)-1
108 | `long long`, `unsigned long long` | 1 to 64 | 0 to 2w-1
109 |
110 | **SIMD Vector types**
111 |
112 | The ABI for vector types is not stable and may change as new optimization opportunities are
113 | found.
114 |
115 | # Function Calling Sequence
116 | This section describes the standard function calling sequence, including stack frame
117 | layout, Wasm argument and local value usage, and so on. These requirements apply
118 | only to global functions (those reachable from other compilation units) . Local functions
119 | may use different conventions; however this may reduce the ability of external tools
120 | to understand them.
121 |
122 |
123 | ## Locals and the stack frame
124 | WebAssembly does not have registers in the style of hardware architectures. Instead it has an
125 | unlimited number of function arguments and local variables, which have wasm value types. These
126 | local values are generally used as registers would be in a traditional architecture, but there
127 | are some important differences. Because arguments are modeled explicitly and locals are local
128 | to a function, there is no need for a concept of callee- or caller-saved locals.
129 |
130 |
131 | ### The linear stack
132 | WebAssembly is a [Harvard](https://en.wikipedia.org/wiki/Harvard_architecture) architecture;
133 | this means that code and data are not in the same memory space. No code or code addresses are
134 | visible in the wasm linear memory space, the only "address" that a function has is its index
135 | in the wasm function index space. Additionally the wasm implementation's runtime call stack
136 | (including the return address and function arguments) is not visible in the linear memory either.
137 | This means that address-taken local C variables need to be on a separate stack in the linear memory
138 | (herafter called the "linear stack"). It also means that some functions may not need a frame in the
139 | linear stack at all.
140 |
141 | Instead of registers visible to all functions, WebAssembly has a table of global variables. One of these
142 | acts as the stack pointer [TODO: describe how stack pointer is designated here, or in object file section]
143 | [TODO: discuss mutable global requirement].
144 |
145 | Each function may have a frame on the linear stack. This stack grows downward
146 | [TODO: describe how start position is determined].
147 | The stack pointer global (`SP`) points to the bottom of the stack frame and always has 16-byte alignment.
148 | If there are dynamically-sized objects on the stack, a frame pointer (a local variable, `FP`) is used,
149 | and it points to the bottom of the static-size objects (those whose sizes are known at compile time).
150 | If objects in the current frame require alignment greater than 16, then a base pointer (another local, `BP`)
151 | is used, which points to the bottom of the previous frame.
152 | The stack also has a "red zone" which extends 128 bytes below the stack pointer. If a function
153 | does not need a frame or base pointer, it may write data into the red zone which is not needed
154 | across function calls. So a leaf function which needs less than 128 bytes of stack space
155 | need not update the stack pointer in its prolog or epilog at all.
156 |
157 | The frame organization is illustrated as follows (with higher memory addresses at the top):
158 |
159 | Position | Contents | Frame
160 | ---------------------------- | -------------------------------| -----------
161 | `BP` | unspecified | Previous
162 | ... | unspecified (aligment padding) | Current
163 | `FP` + *s*
...
`FP` | static-size objects | Current
164 | `SP` + *d*
...
`SP` | dynamic-size objects | Current
165 | ...
`SP`-128 | small static-size objects | Current (red zone)
166 |
167 | Note: in other ABIs the frame pointer typically points to a saved frame pointer (and return address)
168 | at the top of the current frame. In this ABI the frame pointer points to the bottom of the current frame instead.
169 | This is because the constant offset
170 | field of Wasm load and store instructions are unsigned; addresses of the form `FP` + *n* can be folded
171 | into a single insruction, e.g. `i32.load offset=n`. This is also why the stack grows downward (so `SP` + *n*
172 | can also be folded). One consequence of of the lack of return addresses and frame pointer chains is that there
173 | is no way to traverse the linear stack. There is also no currently-specified way to determine which wasm local
174 | is used as the frame pointer or base pointer. This functionality is not needed for backtracing or unwinding (since the
175 | wasm VM must do this in any case); however it may still be desirable to allow this functionality for debugging
176 | or in-field crash reporting. Future ABIs may designate a convention for determining frame size and local usage.
177 |
178 | ### Function arguments and return values
179 |
180 | Types can be passed directly via WebAssembly function parameters or indirectly
181 | via a pointer parameter that points to the value in memory. The callee is
182 | allowed to modify the contents of that memory, so the caller is responsible for
183 | making a copy of any indirectly passed data that the callee should not modify.
184 | Similarly, types can either be returned directly from WebAssembly functions or
185 | returned indirectly via a pointer parameter prepended to the parameter list.
186 |
187 | Type | Parameter | Result |
188 | -----------------------------|---------------|----------|
189 | scalar[1] | direct | direct |
190 | empty struct or union | ignored | ignored |
191 | singleton struct or union[2] | direct | direct |
192 | other struct or union[3] | indirect | indirect |
193 | array | indirect | N/A |
194 |
195 | [1] `long long double` and `__int128` are passed directly as two `i64` values.
196 | Signed 8 and 16-bit scalars are sign-extended, and unsigned 8 and 16-bit
197 | scalars are zero-extended before passing or returning.
198 |
199 | [2] Any struct or union that recursively (including through nested structs,
200 | unions, and arrays) contains just a single scalar value and is not specified to
201 | have greater than natural alignment.
202 |
203 | [3] This calling convention was defined before
204 | [multivalue](https://github.com/WebAssembly/multi-value) was standardized. A new
205 | default calling convention that changes this behavior and takes advantage of
206 | multivalue may be introduced in the future.
207 |
208 | Varargs are placed in a buffer by the caller and the last parameter to the
209 | function is a pointer to that buffer. The callee is allowed to modify the
210 | contents of the buffer, so the caller is responsible for making a copy of any
211 | varargs data that the callee should not modify. Arguments are arranged in order
212 | in the buffer, with each argument placed at the lowest appropriately aligned
213 | address after the previous argument.
214 |
215 | ## Program startup
216 |
217 | ### User entrypoint
218 |
219 | The *user entrypoint* is the function which runs the bulk of the program.
220 | It is called `main` in C, C++, and other languages. Note that this may
221 | not be the first function in the program to be called, as programs may
222 | also have global constructors which run before it.
223 |
224 | At the wasm C ABI level, the following symbol names are used:
225 |
226 | C ABI Symbol name | C and C++ signature |
227 | ---------------------------- | -----------------------------------|
228 | `main` | `int main(void)` or `int main()` |
229 | `__main_argc_argv` | `int main(int argc, char *argv[])` |
230 |
231 | These symbol names only apply at the ABI level; C and C++ source should
232 | continue to use the standard `main` name, and compilers will handle the
233 | details of conforming to the ABI.
234 |
235 | Also note that C symbol names are distinct from WebAssembly export
236 | names, which are outside the scope of the C ABI. Toolchains which export
237 | the user entrypoint may chose to export it as the name `main`, even when
238 | the C ABI symbol name is `__main_argc_argv`.
239 |
240 | A symbol name other than `main` is needed because the usual trick of
241 | having implementations pass arguments to `main` even when they aren't
242 | needed doesn't work in wasm, which requires caller and callee signatures
243 | to exactly match.
244 |
245 | For the same reason, the wasm C ABI doesn't support an `envp` parameter.
246 | Fortunately, `envp` is not required by C, POSIX, or any other relevant
247 | standards, and is generally considered obsolete in favor of `getenv`.
248 |
249 | ### Program entrypoint
250 |
251 | The *program entrypoint* is the first function in the program to be called.
252 | It is commonly called `_start` on other platforms, though this is a
253 | low-level detail that most code doesn't interact with.
254 |
255 | The program entrypoint is out of scope for the wasm C ABI. It may depend
256 | on what environment the program will be run in.
257 |
--------------------------------------------------------------------------------
/BasicModuleABI.md:
--------------------------------------------------------------------------------
1 | Basic Module ABI
2 | ================
3 |
4 | There are many different ways to use Wasm modules, and many different
5 | conventions, language-specific ABIs, and toolchain-specific ABIs. This
6 | document describes ABI features intended to be common across all ABIs.
7 |
8 | ## The `_initialize` function
9 |
10 | If a module exports a function named `_initialize` with no arguments and no
11 | return values, and does not export a function named `_start`, the toolchain
12 | that produced my assume that on any instance of the module, this `_initialize`
13 | function is called before any other exports are accessed.
14 |
15 | This is intended to support language features such as C++ static constructors,
16 | as well as "top-level scripts" in many scripting languages, which can't use
17 | the [wasm start function] because they may call imports that need to access
18 | the module's exports. In use cases that don't need this, the wasm start
19 | function should be used.
20 |
21 | [wasm start section]: https://webassembly.github.io/spec/core/syntax/modules.html#syntax-start
22 |
--------------------------------------------------------------------------------
/BuildId.md:
--------------------------------------------------------------------------------
1 | # Build ID
2 |
3 | A Build ID (or debug info ID) is a value that uniquely identifies a build. It
4 | is intended to capture the "meaning" or inputs of the build, and is usually
5 | associated with debug info. So for example, programs compiled from different
6 | sources would have different build IDs, even if their generated code happened to
7 | be the same. A common use case is when a build is created with debug info, and
8 | then the debug info is stripped before distribution and archived by the
9 | developer. If both the distributed and archived version retain the build ID,
10 | then they can be matched, and the distributed version can be debugged or
11 | symbolized.
12 |
13 | Because the build ID is usually intended to identify debug info, tools that
14 | transform Wasm binaries will need to decide whether they will preserve, drop, or
15 | recompute the build ID. Generally speaking, if a transformation would invalidate
16 | debug info (for example, by rewriting the code section and changing the code
17 | offsets), then the tool should drop or recompute the build ID. If a tool updates
18 | or regenerates debug info along with its transformation, it should also
19 | generally update the build ID, since the debug info no longer
20 | matches. Conversely, adding custom sections to a binary would generally not
21 | require updating the build ID.
22 |
23 | ## Build ID Section
24 | The Build ID section is a [custom section](https://webassembly.github.io/spec/core/binary/modules.html#custom-section)
25 | and thus has no semantic effects and can be stripped at any time. It is named
26 | `build_id` and has no restriction on where in the binary it can appear. It
27 | consists of only 2 fields:
28 |
29 | | Field | Type | Description |
30 | | ----------- | ----------- | ----------- |
31 | | length | `varuint32` | number of bytes that follow |
32 | | id | `bytes` | sequence of bytes |
33 |
34 | Unlike most "string" fields in wasm binaries, the `id` field is arbitrary binary
35 | data and is not required to be valid UTF-8.
36 |
37 | ## Implementation Notes
38 | The exact size and method of generating the build ID is unspecified, other than
39 | that it should be unique. LLVM lld supports several different methods, including
40 | a hash (which includes at least all the code, data, and debug info sections of
41 | the output), a random (v4) UUID, and user-specified values. The default is to
42 | hash the output and create from it a name-based (v5) UUID, which is
43 | deterministic for a given set of inputs.
44 |
--------------------------------------------------------------------------------
/CodeMetadata.md:
--------------------------------------------------------------------------------
1 | # Code Metadata Framework
2 |
3 | This document describe a convention for encoding a number of WebAssembly features (here generically called "code metadata") that don't affect the module semantics.
4 | The goal of this convention is to make it easier for tools that work on WebAssembly modules to handle and preserve such metadata.
5 |
6 | Note: This is a work in progress
7 |
8 | ## Code Metadata
9 |
10 | Each type of Code Metadata is identified by a name: `metadata.code.`.
11 |
12 | An instance of Code Metadata is defined by its type, a position in the code section,
13 | and a payload.
14 |
15 | The payload is a byte string, whose meaning depends on the type.
16 |
17 | Removing Code Metadata from a module does not change its semantics.
18 |
19 | A tool that transforms the module must drop any Code Metadata that it does not know, or knows it can’t preserve.
20 |
21 | ## Binary Representation
22 |
23 | Each type of Code Metadata is encoded in a custom section named `metadata.code.`.
24 |
25 | Such sections have the following binary format:
26 |
27 | ```
28 | codemetadatasec(A) ::= section_0(codemetadatacontent(A))
29 |
30 | codemetadatacontent(A) ::= n:name (if n = 'metadata.code.A')
31 | vec(codemetadatafunc(A))
32 |
33 | codemetadatafunc(A) ::= idx: funcidx
34 | vec(codemetadatainstance(A))
35 |
36 | codemetadatainstance(A) ::= funcpos: u32
37 | size: u32 (if size = ||A||)
38 | data: A
39 | ```
40 |
41 | Where `funcpos` is the byte offset of the annotation starting from the beginning of the function body, and `data` is a further payload, whose content depends on the section type `A`.
42 |
43 | `codemetadatafunc` entries must appear in order of increasing `idx`, and duplicate `idx` values are not allowed.
44 | `codemetadatainstance` entries must appear in order of increasing `funcpos`, and duplicate `funcpos` values are not allowed.
45 |
46 | ## Text Representation
47 |
48 | Code Metadata are represented in the .wat format using [custom annotations](https://github.com/WebAssembly/annotations), as follows:
49 |
50 | ```
51 | (@metadata.code. data:str)
52 | ```
53 | The `data` fields correspond to the field with the same name in the binary representation.
54 | The code position is implicit and it is derived by the position of the annotation:
55 |
56 | Custom annotations can appear anywhere , but **Code Metadata annotations** are allowed only in function definitions (in which case the code position is the offset of the start of the function body in the code section), or before an instruction (in which case the code position is the byte offset of the instruction relative to the beginning of the function body).
57 |
58 | Example:
59 |
60 | ```
61 | (module
62 | (type (;0;) (func (param i32 result i32)))
63 | (func (@metadata.code.hotness "\01") $test (type 0)
64 | (@metadata.code.branch_hint "\00") if
65 | i32.const 0
66 | local.set 0
67 | end
68 | local.get 1
69 | (@metadata.code.custom "aaa\13bb") return
70 | )
71 | )
72 | ```
73 |
74 | ## Code Metadata well-known types
75 |
76 | Currently the following type of Code Metadata are defined:
77 |
78 | ### Branch Hints
79 |
80 | - section name: `metadata.code.branch_hint`
81 | - binary format:
82 |
83 | ```
84 | codemetadatainstance(branch_hint) ::= funcpos: u32
85 | size: 0x01
86 | data: branchhint
87 | branch_hint ::= unlikely | likely
88 | unlikely ::= 0x00
89 | likely ::= 0x01
90 | ```
91 |
92 | Branch hints can appear only before a `if` or `br_if` instruction, and are considered attached to it.
93 | Code transformations that remove the instruction should remove the associated instance, and transformations that flip the direction of the branch should preserve the hint but flip the hint.
94 |
95 | ## Trace Instruction
96 |
97 | - section name: metadata.code.trace_inst
98 | - binary format:
99 |
100 | ```
101 | codemetadatainstance(trace_inst) ::= funcpos: u32
102 | size: u32v
103 | data: mark_id
104 | mark_id ::= u32
105 | ```
106 |
107 | Trace marks can appear on any instruction and are considered attached to the instruction. If a code transformation reorders the instruction, the trace mark should move with it. If a code transformation removes the instruction, the trace mark should be removed.
108 |
--------------------------------------------------------------------------------
/Coredump.md:
--------------------------------------------------------------------------------
1 | This document describes the usage of coredump for post-mortem debugging with
2 | WebAssembly.
3 |
4 | # Idea
5 |
6 | When WebAssembly enters a trap, it starts unwinding and collects debugging
7 | information. For each stack frame, collect the values in locals (includes
8 | function parameters) and on the stack. Along with binary offsets to resolve to
9 | source file locations. Finally, make a snapshot of the linear memory (or
10 | multiple linear memories when the [multi-memory] feature is used), tables and
11 | globals.
12 |
13 | All this information is saved to the file, called the coredump file.
14 |
15 | The post mortem analysis is done using the coredump and [DWARF] information.
16 | Similar to the debugging flow with [gdb].
17 |
18 | # Implementation status
19 |
20 | Stability of this specification is **experimental**.
21 |
22 | Tools that support the generation of Wasm coredumps:
23 | - [wasm-edit]
24 | - [Wasmtime]
25 |
26 | Debugger that supports post-mortem debugging with Wasm coredumps:
27 | - [wasmgdb]
28 |
29 | ## Runtime support
30 |
31 | Most of the WebAssembly runtimes are already able to present a useful stacktrace
32 | on crash to the user. When they are configured to emit a coredump, they collect
33 | the debugging information and write a coredump file.
34 |
35 | An example output:
36 |
37 | ```
38 | $ my-wasm-runtime module.wasm
39 |
40 | Exit 1: Uncaught RuntimeError: memory access out of bounds (core dumped).
41 | ```
42 |
43 | A coredump file has been generated.
44 |
45 | For experimenting, runtime support is not strictly necessary. A tool can
46 | transform the Wasm binary to inject code that will manually unwind the stack and
47 | collect debugging information, for instance [wasm-edit coredump]. Such a
48 | transformation has important limitations; a trap caused by an invalid memory
49 | operation or exception in a host function might not be caught.
50 |
51 | ## Security and privacy considerations
52 |
53 | Using the WebAssembly linear memory for debugging exposes the risk of seeing,
54 | manipulating and/or collecting sensitive informations.
55 |
56 | For the user of Wasm coredumps, there's no particular security or privacy
57 | considerations.
58 |
59 | ## Debugger support
60 |
61 | [gdb] doesn't support Wasm coredump and it's unclear if it can. Wasm coredump
62 | differ from ELF coredump in a few significant ways:
63 | - Wasm semantics; usage of locals, globals and the stack.
64 | - The process image is only the Wasm linear memory.
65 | - etc.
66 |
67 | For experimenting, a custom tool has been built and mimics [gdb]: [wasmgdb].
68 |
69 | It seems possible for Chrome's Wasm debugger extension to support Wasm
70 | coredumps. Challenges for coredumps in the web context would be to collect the
71 | instance's state as tools like emscripten (and of course most of a larger web
72 | app's state) are in JS rather than Wasm.
73 |
74 | # Coredump file format
75 |
76 | The coredump file is encoded using the [Wasm binary format], containing:
77 | - general information about the process.
78 | - the threads and stack frames.
79 | - a snapshot of the WebAssembly linear memory or relevant regions.
80 |
81 | The order in which they appear in the file is not important.
82 |
83 | As opposed to regular Wasm files, Wasm Coredumps are not [instantiated].
84 |
85 | `u32` are encoded using [Wasm u32].
86 |
87 | ## Process information
88 |
89 | General information about the process is stored in a [Custom section], called
90 | `core`.
91 |
92 | This custom section must only appear once in the coredump file.
93 |
94 | ```
95 | core ::= customsec(process-info)
96 | process-info ::= 0x0 executable-name:name
97 | ```
98 |
99 | ## Module information
100 |
101 | Information about the modules present in the coredump are stored in a [Custom
102 | section] called `coremodules`.
103 |
104 | This custom section must only appear once in the coredump file.
105 |
106 | This custom section establishes an index space of modules that can be referenced
107 | in the `coreinstances` custom section (see below).
108 |
109 | ```
110 | coremodules ::= customsec(vec(coremodule))
111 | coremodule ::= 0x0 module-name:name
112 | ```
113 |
114 | The `module-name` may be a URL, file path, or other identifier for the module.
115 |
116 | ## Instance information
117 |
118 | Information about the instances present in the coredump are stored in a [Custom
119 | section] called `coreinstances`.
120 |
121 | This custom section must only appear once in the coredump file.
122 |
123 | This custom section establishes an index space of instances that can be
124 | referenced in `frame` productions within the `corestack` custom section (see
125 | below).
126 |
127 | ```
128 | coreinstances ::= customsec(vec(coreinstance))
129 | coreinstance ::= 0x0 moduleidx:u32 memories:vec(u32) globals:vec(u32)
130 | ```
131 |
132 | Each `coreinstance` specifies:
133 |
134 | * Which module this is an instance of, via indexing into the `coremodules` index
135 | space.
136 |
137 | * Which of the coredump's memories are this instance's memories, via indexing
138 | into the memory index space. Memories are listed in instance order: the `i`th
139 | entry in `coreinstance::memories` is the coredump memory index of this
140 | instance's `i`th memory.
141 |
142 | * Which of the coredump's globals are this instance's globals, via indexing into
143 | the global index space. Globals are listed in instance order: the `i`th entry
144 | in `coreinstance::globals` is the coredump global index of this instance's
145 | `i`th global.
146 |
147 | ## Thread(s) and stack frames
148 |
149 | For each thread a [Custom section], called `corestack`, is used to store the
150 | debugging information.
151 |
152 | ```
153 | corestack ::= customsec(thread-info vec(frame))
154 | thread-info ::= 0x0 thread-name:name
155 | frame ::= 0x0 instanceidx:u32 funcidx:u32 codeoffset:u32 locals:vec(value)
156 | stack:vec(value)
157 | ```
158 |
159 | The frames in a `corestack` production are listed from youngest to oldest.
160 |
161 | > Example: If `f` calls `g` calls `h`, and `h` traps and the runtime creates a
162 | > coredump, then the coredump's `corestack` will list the frames in this order:
163 | > `h`, `g`, `f`.
164 |
165 | The `instanceidx` is an index into the `coreinstances` index space, describing
166 | which instance is associated with this stack frame.
167 |
168 | `funcidx` is the WebAssembly function index in the instance's module and
169 | `codeoffset` is the instruction's offset relative to the function's start.
170 |
171 | > Note: implementations may leave `codeoffset` offset empty if unknown. Setting
172 | > 0 will point to the function's start.
173 |
174 | Local and stack values are encoded using one byte for the type (similar to
175 | Wasm's [Number Types]) followed by bytes representing the actual value:
176 | ```
177 | value ::= 0x01 => ∅
178 | | 0x7F n:i32 => n
179 | | 0x7E n:i64 => n
180 | | 0x7D n:f32 => n
181 | | 0x7C n:f64 => n
182 | ```
183 |
184 | The special byte `0x01` is used to represent a missing value, usually because it
185 | was optimized out by the WebAssembly engine.
186 |
187 | ## Memory
188 |
189 | Each instance's memory is captured in the [Memory Section] and [Data Section].
190 |
191 | To determine which memory is associated with which instance(s), you can use the
192 | mapping defined in `coreinstances`.
193 |
194 | > Note: A single memory may be associated with multiple instances if it is, for
195 | > example, defined and exported by one instance and imported by another.
196 |
197 | > Note: A memory's data may be captured either entirely as one active data
198 | > segment, or as multiple data segments. The latter can be used as a space
199 | > saving mechanism to avoid long runs of zeroes or it can be used to represent
200 | > partial coredumps.
201 |
202 | ## Globals
203 |
204 | Globals are captured in the [Global Section] as constant, non-mutable globals.
205 |
206 | To determine which global is associated with which instance(s), you can use the
207 | mapping defined in `coreinstances`.
208 |
209 | > Note: A single global may be associated with multiple instances if it is, for
210 | > example, defined and exported by one instance and imported by another.
211 |
212 | # Demo
213 |
214 | Please have a look at the demonstration using the experimental support and
215 | tooling: [demo].
216 |
217 | # Useful links
218 |
219 | - [ELF coredump]
220 | - [Wasmer FrameInfo]
221 |
222 | [Wasm Vectors]: https://webassembly.github.io/spec/core/binary/conventions.html#binary-vec
223 | [ELF coredump]: https://www.gabriel.urdhr.fr/2015/05/29/core-file/
224 | [Core dump on Wikipedia]: https://en.wikipedia.org/wiki/Core_dump
225 | [gdb]: https://linux.die.net/man/1/gdb
226 | [wasm-edit coredump]: https://github.com/xtuc/wasm-coredump/blob/main/bin/rewriter/src/rewriter.rs
227 | [wasm-edit]: https://github.com/xtuc/wasm-coredump/tree/main/bin/rewriter
228 | [wasmgdb]: https://github.com/xtuc/wasm-coredump/tree/main/bin/wasmgdb
229 | [DWARF]: https://yurydelendik.github.io/webassembly-dwarf
230 | [Wasmer FrameInfo]: https://docs.rs/wasmer/latest/wasmer/struct.FrameInfo.html
231 | [Wasm u32]: https://webassembly.github.io/spec/core/binary/values.html#binary-int
232 | [demo]: https://github.com/xtuc/wasm-coredump/blob/main/bin/wasmgdb/demo.md
233 | [multi-memory]: https://github.com/WebAssembly/multi-memory
234 | [Wasm binary format]: https://webassembly.github.io/spec/core/binary/index.html
235 | [Data Section]: https://webassembly.github.io/spec/core/binary/modules.html#data-section
236 | [Custom section]: https://webassembly.github.io/spec/core/binary/modules.html#binary-customsec
237 | [Memory Section]: https://webassembly.github.io/spec/core/binary/modules.html#binary-memsec
238 | [instantiated]: https://webassembly.github.io/spec/core/exec/modules.html#instantiation
239 | [Global Section]: https://webassembly.github.io/spec/core/binary/modules.html#binary-globalsec
240 | [Number Types]: https://webassembly.github.io/spec/core/binary/types.html#binary-numtype
241 | [Wasmtime]: https://wasmtime.dev
242 |
--------------------------------------------------------------------------------
/Debugging.md:
--------------------------------------------------------------------------------
1 | This document describes conventions regarding debugging.
2 |
3 | # DWARF
4 |
5 | It is a goal to support DWARF in WebAssembly, see
6 | [the proposed additions to DWARF](https://yurydelendik.github.io/webassembly-dwarf/)
7 | for how that is planned to work.
8 |
9 | ## Embedded DWARF
10 |
11 | The proposal allows [embedding the DWARF sections](https://yurydelendik.github.io/webassembly-dwarf/#embedding-DWARF)
12 | as WebAssembly custom sections with the same name (`.debug_*`) and raw data as in the DWARF spec.
13 |
14 | ## External DWARF
15 |
16 | The proposal also allows keeping the DWARF information
17 | [external to the Wasm](https://yurydelendik.github.io/webassembly-dwarf/#external-DWARF).
18 | When doing so, the main Wasm file does not need to contain any debug info, and
19 | instead has a custom section with the name `external_debug_info`. That section
20 | contains:
21 |
22 | | Field | Type | Description |
23 | | ------------ | ----------- | --------------------------------- |
24 | | url_name_len | `varuint32` | Length of `url_name_str` in bytes |
25 | | url_name_str | `bytes` | URL to debug info file |
26 |
27 | `url_name` is the location of a file containing DWARF debug info. That file is
28 | a Wasm container, which includes DWARF in Wasm custom sections, in the same
29 | format as they would appear normally in a Wasm file. Note that the container may
30 | also contain other sections, such as the code and data sections in the original
31 | Wasm file.
32 |
33 | # Source maps
34 |
35 | Adoption of DWARF is a fairly recent addition to WebAssembly, and many toolchains still
36 | support [Source Map](https://sourcemaps.info/spec.html) based debugging as well (or instead).
37 |
38 | Source map is an external JSON file that specifies how to map a (zero-based) line and column
39 | position in generated code to a file, line, and column location in the source. For
40 | WebAssembly binary locations, the line number is always 1, and the column number
41 | is interpreted as a byte offset into the WebAssembly binary content.
42 | Source locations are interpreted as in the source map spec.
43 |
44 | On the WebAssembly side, the URL of such Source Map file is stored in a custom section with the name
45 | `sourceMappingURL`. That section contains:
46 |
47 | | Field | Type | Description |
48 | | ------------ | ----------- | --------------------------------- |
49 | | url_name_len | `varuint32` | Length of `url_name_str` in bytes |
50 | | url_name_str | `bytes` | URL to the Source Map file |
51 |
--------------------------------------------------------------------------------
/DynamicLinking.md:
--------------------------------------------------------------------------------
1 | WebAssembly Dynamic Linking
2 | ===========================
3 |
4 | This document describes the current WebAssembly dynamic linking ABI used by
5 | emscripten and by the llvm backend when targeting emscripten.
6 |
7 | Note: This ABI is still a work in progress. There is no stable ABI yet.
8 |
9 | # Dynamic Libraries
10 |
11 | A WebAssembly dynamic library is a WebAssembly binary with a special custom
12 | section that indicates this is a dynamic library and contains additional
13 | information needed by the loader.
14 |
15 | ## The "dylink.0" Section
16 |
17 | The "dylink.0" is a custom section, the existence of which signals that the
18 | module conforms the dynaminc linking ABI described in this document. This
19 | section is expected to be the very first section in the module.
20 |
21 | A "dylink.0" consists of a series of sub-sections using the same format as found
22 | in the ["names"][names_sec] section:
23 |
24 | | Field | Type | Description |
25 | | ----------- | ------------- | ------------------------------------ |
26 | | subsections | `subsection*` | sequence of `subsection` |
27 |
28 | Each `subsection` is encoded as:
29 |
30 | | Field | Type | Description |
31 | | ------------ | ----------- | ------------------------------------ |
32 | | type | `uint8` | code identifying type of subsection |
33 | | payload_len | `varuint32` | size of this subsection in bytes |
34 | | payload_data | `bytes` | content of this subsection, of length `payload_len` |
35 |
36 | The current list of valid `type` codes are:
37 |
38 | - `1 / WASM_DYLINK_MEM_INFO` - Specifies the memory and table space requirements of the module
39 |
40 | - `2 / WASM_DYLINK_NEEDED` - Specifies external modules that this one depends on.
41 |
42 | - `3 / WASM_DYLINK_EXPORT_INFO` - Specify additional metadata about exports.
43 |
44 | - `4 / WASM_DYLINK_IMPORT_INFO` - Specify additional metadata about imports.
45 |
46 | - `5 / WASM_DYLINK_RUNTIME_PATH` - Specify the runtime path, corresponding to `DT_RUNPATH` in an ELF `.dynamic` section.
47 |
48 | For `WASM_DYLINK_MEM_INFO` the following fields are present in the
49 | subsection:
50 |
51 | | Field | Type | Description |
52 | | ---------------------- | --------------- | ------------------------------ |
53 | | memorysize | `varuint32` | Size of the memory area the loader should reserve for the module, which will begin at `env.__memory_base` |
54 | | memoryalignment | `varuint32` | The required alignment of the memory area, in bytes, encoded as a power of 2. |
55 | | tablesize | `varuint32` | Size of the table area the loader should reserve for the module, which will begin at `env.__table_base` |
56 | | tablealignment | `varuint32` | The required alignment of the table area, in elements, encoded as a power of 2. |
57 |
58 | For `WASM_DYLINK_NEEDED` the following fields are present in the
59 | subsection:
60 |
61 | | Field | Type | Description |
62 | | ---------------------- | --------------- | ------------------------------ |
63 | | needed_dynlibs_count | `varuint32` | Number of needed shared libraries |
64 | | needed_dynlibs_entries | `string*` | Repeated string names of dynamic libraries |
65 |
66 | The "string" type is defined as:
67 |
68 | | Field | Type | Description |
69 | | -------------- | ----------- | ----------------------------------- |
70 | | string_len | `varuint32` | Length of `string_payload` in bytes |
71 | | string_payload | `bytes` | valid UTF-8 byte sequence |
72 |
73 | `env.__memory_base` and `env.__table_base` are `i32` imports that contain
74 | offsets into the linked memory and table, respectively. If the dynamic library
75 | has `memorysize > 0` then the loader will reserve room in memory of that size
76 | and initialize it to zero (note: can be larger than the memory segments in the
77 | module, if the dynamic library wants additional space) at offset
78 | `env.__memory_base`, and similarly for the table (where initialization is to
79 | `null`, i.e., a trap will occur if it is called). The allocated regions of the
80 | table and memory are guaranteed to be at least as aligned as the library
81 | requests in the `memoryalignment` and `tablealignment` properties. The library
82 | can then place memory and table segments at the proper locations using those
83 | imports.
84 |
85 | If `needed_dynlibs_count > 0` then the loader, before loading the library, will
86 | first load needed libraries specified by `needed_dynlibs_entries`.
87 |
88 | For `WASM_DYLINK_EXPORT_INFO` the following fields are present in the
89 | subsection:
90 |
91 | | Field | Type | Description |
92 | | ------------------- | --------------- | --------------------- |
93 | | export_info_count | `varuint32` | Number of export info |
94 | | export_info_entries | `export_info*` | Repeated export info |
95 |
96 | The "export_info" type is defined as:
97 |
98 | | Field | Type | Description |
99 | | ----- | ----------- | ---------------------------------------- |
100 | | name | `string` | The name of the export |
101 | | flags | `varuint32` | Symbol flags for the export |
102 |
103 | For `WASM_DYLINK_IMPORT_INFO` the following fields are present in the
104 | subsection:
105 |
106 | | Field | Type | Description |
107 | | ------------------- | --------------- | --------------------- |
108 | | import_info_count | `varuint32` | Number of import info |
109 | | import_info_entries | `import_info*` | Repeated import info |
110 |
111 | The "import_info" type is defined as:
112 |
113 | | Field | Type | Description |
114 | | -------| ----------- | ---------------------------------------- |
115 | | module | `string` | The module name of the import |
116 | | field | `string` | The field name of the import |
117 | | flags | `varuint32` | Symbol flags for the export |
118 |
119 | The set of possible symbol flags are the same as those specified in
120 | [Linking](Linking.md).
121 |
122 | For `WASM_DYLINK_RUNTIME_PATH` the following fields are present in the
123 | subsection:
124 |
125 | | Field | Type | Description |
126 | | ---------------------- | --------------- | ------------------------------------- |
127 | | runtime_path_count | `varuint32` | Number of runtime_path entries |
128 | | runtime_path_entries | `string*` | string values of runtime_path entries |
129 |
130 | The "dylink" section should be the very first section in the module; this allows
131 | detection of whether a binary is a dynamic library without having to scan the
132 | entire contents.
133 |
134 | [names_sec]: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#name-section
135 |
136 | ## Interface and usage
137 |
138 | A WebAssembly dynamic library must obey certain conventions. In addition to
139 | the `dylink` section described above a module may import the following globals
140 | that will be provided by the dynamic loader:
141 |
142 | * `env.memory` - A wasm memory that is shared between all wasm modules that
143 | make up the program.
144 | * `env.__indirect_function_table` - A wasm table that is shared between all
145 | wasm modules that make up the program.
146 | * `env.__stack_pointer` - A mutable `i32` global representing the explicit
147 | stack pointer as an offset into the above memory.
148 | * `env.__memory_base` - An immutable `i32` global representing the offset in
149 | the above memory which has been reserved and zero-initialized for this
150 | module, as described earlier. The module can use this global in the
151 | initializer of its data segments so that they loaded at the correct address.
152 | * `env.__table_base` - An immutable `i32` global representing the offset in the
153 | above table which has been reserved for this module, as described earlier.
154 | The module can use this global in the intializer of its table element
155 | segments so that they loaded at the correct offset.
156 |
157 | ### Relocations
158 |
159 | WebAssembly dynamic libraries do not require relocations in the code section.
160 | This allows for streaming compilation and better code sharing, and reduces the
161 | complexity of the dynamic linker. For external symbols this is achieved by
162 | referencing WebAssembly imports. For internal symbols we introduce two new
163 | relocation types for accessing data and functions address relative to
164 | `__memory_base` and `__table_base` global:
165 |
166 | - `11 / R_WASM_MEMORY_ADDR_REL_SLEB,` - a memory address relative to the
167 | `__memory_base` wasm global. Used in position independent code (`-fPIC`)
168 | where absolute memory addresses are not known at link time.
169 | - `12 / R_WASM_TABLE_INDEX_REL_SLEB` - a function address (table index)
170 | relative to the `__table_base` wasm global. Used in position indepenent code
171 | (`-fPIC`) where absolute function addresses are not known at link time.
172 | - `17 / R_WASM_MEMORY_ADDR_REL_SLEB64` - the 64-bit counterpart of
173 | `R_WASM_MEMORY_ADDR_REL_SLEB`.
174 | - `21 / R_WASM_MEMORY_ADDR_TLS_SLEB` (in LLVM 12.0) - an offset from the
175 | `__tls_base` symbol encoded as a 5-byte [varint32]. Used for PIC case to avoid
176 | absolute relocation.
177 | - `25 / R_WASM_MEMORY_ADDR_TLS_SLEB64` (in LLVM 13.0) - the 64-bit counterpart
178 | of `R_WASM_MEMORY_ADDR_TLS_SLEB`.
179 |
180 | All code that gets linked into a WebAssembly dynamic library must be compiled
181 | as position independent. The corresponding absolute relocation types
182 | (R_WASM_MEMORY_ADDR_SLEB and R_WASM_TABLE_INDEX_SLEB) are not permitted in
183 | position independent code and will be rejected at link time.
184 |
185 | For relocation within the data segments a runtime fixup may be required. For
186 | example, if the address of an external symbol is stored in global data. In this
187 | case the dynamic library must generate code to apply these relocations at
188 | startup. The module can export a function called `__wasm_apply_data_relocs`.
189 | If it is so exported, the loader will call it after the module is instantiated,
190 | and before any other function, including `__wasm_call_ctors`, is called.
191 |
192 | ### Imports
193 |
194 | Functions are directly imported from the `env` module (e.g.
195 | `env.enternal_func`). Data addresses and function addresses are imported as
196 | WebAssembly globals that store the memory offset or table offset of the symbol.
197 | Such address are imported from `GOT.mem` and `GOT.func` respectively. The `GOT`
198 | prefix is borrowed from the ELF linking world and stands for "Global Offset
199 | Table". In WebAssembly the GOT is modeled as a set of imported wasm globals.
200 |
201 | For example, a dynamic library might import and use an external data symbol as
202 | follows:
203 |
204 | ```wasm
205 | (import "GOT.mem" "foo" (global $foo_addr (mut i32))
206 | ...
207 | ...
208 | get_global $foo_addr
209 | i32.load
210 | ```
211 |
212 | And an external function symbol as follows:
213 |
214 | ```wasm
215 | (import "GOT.func" "bar" (global $bar_addr (mut i32)))
216 | ...
217 | ...
218 | get_global $bar_addr
219 | call_indirect
220 | ```
221 |
222 | Note: This has no effect on exports, or the import of functions for direct call.
223 |
224 | The imported global must be mutable as the dynamic linker might need to
225 | modify the value after instantiation.
226 |
227 | ### Text format of `dylink.0`
228 |
229 | The text format for the `dylink.0` custom section uses [annotations proposal]
230 | extension to the WebAssembly text format. The text format looks like:
231 |
232 | [annotations proposal]: https://github.com/WebAssembly/annotations
233 |
234 | ```wasm
235 | (module $libc.so
236 | (@dylink.0
237 | (mem-info (memory 208392 4) (table 31 0))
238 | (import-info "env" "__main_argc_argv" binding-weak undefined)
239 | )
240 | )
241 | ```
242 |
243 | or
244 |
245 | ```
246 | (module $libbar.so
247 | (@dylink.0
248 | (needed "libfoo.so" "libc.so")
249 | (export-info "my_tls_variable_1" tls)
250 | (export-info "my_tls_variable_2" tls)
251 | )
252 | )
253 | ```
254 |
255 | The `(@dylink.0 ...)` structure must be placed directly within a `(module
256 | ...)` declaration and must be placed at the beginning of the module. Within
257 | `@dylink.0` there is a list of four possible parenthesis-delimited fields that
258 | correspond to the subsections within `dylink.0`:
259 |
260 | * `(mem-info ...)`
261 | * `(needed ...)`
262 | * `(export-info ...)`
263 | * `(import-info ...)`
264 |
265 | The `dylink.0` subsections are emitted in the same order they're listed within
266 | the `@dylink.0` annotation. The `export-info` and `import-info` subsections
267 | concatenate adjacent entries into one subsection.
268 |
269 | ```wasm
270 | (module
271 | (@dylink.0
272 | ;; these two symbols are concatenated into one subsection
273 | (export-info "a" tls)
274 | (export-info "b" tls)
275 |
276 | ;; this generates a second subsection
277 | (import-info "env" "c" binding-weak undefined)
278 | )
279 | )
280 | ```
281 |
282 | would produce two subsections where the first one has type
283 | `WASM_DYLINK_EXPORT_INFO` with two symbols.
284 |
285 | **`mem-info`**
286 |
287 | The `mem-info` section optionally contains `(memory ..)` and `(table ..)`
288 | entries. These correspond to the memory size/alignment and table size/alignment.
289 | If not specified the defaults are 0.
290 |
291 | For example:
292 |
293 | ```wasm
294 | (module
295 | (@dylink.0
296 | (mem-info (memory 100 1)) ;; 100-byte memory with 1-byte alignment
297 | ;; 0-entry table with 0 alignment
298 |
299 | (mem-info (table 10 2)) ;; 0-byte memory with 0-byte alignment
300 | ;; 10-entry table with 2 alignment
301 |
302 | (mem-info
303 | (memory 100 1)
304 | (table 10 2))
305 | )
306 | )
307 | ```
308 |
309 | **`needed`**
310 |
311 | The `needed` section contains a list of strings which are the needed modules
312 | present in `WASM_DYLINK_NEEDED`:
313 |
314 | ```wasm
315 | (module
316 | (@dylink.0
317 | (needed "libfoo.so" "libbar.so")
318 | )
319 | )
320 | ```
321 |
322 | ** `runtime-path` **
323 |
324 | The `runtime-path` contains a list of paths. The loader should look in these
325 | directories to locate `needed` dependencies that do not contain a slash in their
326 | name.
327 |
328 | Dynamic string tokens: The loader should expand certain string tokens appearing
329 | in the `runtime-path`. The tokens are as follows:
330 |
331 | * `$ORIGIN` and `${ORIGIN}` -- these expand to the directory containing the
332 | shared object.
333 |
334 | **`export-info` / `import-info`**
335 |
336 | The `export-info` and `import-info` constructs correspond to
337 | `WASM_DYLINK_EXPORT_INFO` and `WASM_DYLINK_IMPORT_INFO`. Each structure
338 | specifies information on a single symbol. After the symbol is a list of flags or
339 | integer values for flags. For example:
340 |
341 | ```wasm
342 | (module
343 | (@dylink.0
344 | (import-info "env" "__main_argc_argv" binding-weak undefined)
345 | (export-info "my_tls_variable_1" tls)
346 | )
347 | )
348 | ```
349 |
350 | Supported flags are:
351 |
352 | * `binding-weak` - `WASM_SYM_BINDING_WEAK`
353 | * `binding-local` - `WASM_SYM_BINDING_LOCAL`
354 | * `visibility-hidden` - `WASM_SYM_VISIBILITY_HIDDEN`
355 | * `undefined` - `WASM_SYM_UNDEFINED`
356 | * `exported` - `WASM_SYM_EXPORTED`
357 | * `explicit-name` - `WASM_SYM_EXPLICIT_NAME`
358 | * `no-strip` - `WASM_SYM_NO_STRIP`
359 | * `tls` - `WASM_SYM_TLS`
360 | * `absolute` - `WASM_SYM_ABSOLUTE`
361 |
362 | Flags can also be specified with an integer literal and the integer literal may
363 | have more than one bit set as well. Note that many of these flags aren't used in
364 | `dylink.0` but instead are used as part of the `linking` section, the current
365 | implementation in `wasm-ld` of emitting `dylink.0` only uses `import-info` for
366 | `binding-weak` symbols and `export-info` for `tls` symbols.
367 |
368 | ### Exports
369 |
370 | Functions are directly exported as WebAssembly function exports. Exported
371 | addresses (i.e., exported memory locations or exported table locations) are
372 | exported as i32 WebAssembly globals. However since exports are static, modules
373 | connect export the final relocated addresses (i.e. they cannot add
374 | `__memory_base` before exporting). Thus, the exported address is before
375 | relocation; the loader, which knows `__memory_base`, can then calculate the
376 | final relocated address.
377 |
378 | ### Note for memory/table exports
379 |
380 | The commonly used C conventions including WASIp1 require modules to
381 | export the `memory` memory and the `__indirect_function_table` table.
382 |
383 | However, because PIE executables with this dynamic-linking convention
384 | are already importing these instance resources, it's redundant to
385 | export them as well. For that reason, for PIE executables, we don't
386 | require these resources exported.
387 |
388 | Shared libraries don't need to export these resources either.
389 | Instead, they should import these resources, since they share the memory
390 | and function table with the main module. (The runtime linkers
391 | can validate if it's actually the case and reject loading modules
392 | otherwise.)
393 |
394 | On the other hand, non-PIE executables need to export these instance
395 | resources as usual.
396 |
397 | ## Implementation Status
398 |
399 | ### LLVM Implementation
400 |
401 | When llvm is run with `--relocation-model=pic` (a.k.a `-fPIC`) it will generate
402 | code that accesses non-DSO-local addresses via the `GOT.mem` and `GOT.func`
403 | entries. Such code must then be linked with either `-shared` to produce a
404 | shared library or `-pie` to produced a dynamically linked executable.
405 |
406 | ### WASI-SDK
407 |
408 | [WASI-SDK] 21.0 and later ships shared builds of its libraries including libc.
409 |
410 | Note: You might need
411 | `-Xlinker --export-if-defined=__main_argc_argv` to workaround
412 | a [wasi-libc bug].
413 |
414 | [WASI-SDK]: https://github.com/WebAssembly/wasi-sdk
415 |
416 | [wasi-libc bug]: https://github.com/WebAssembly/wasi-libc/issues/485
417 |
418 | Note: WASI-SDK 25.0 ships an LLVM version with
419 | [an issue for non-PIE executable].
420 |
421 | [an issue for non-PIE executable]: https://github.com/llvm/llvm-project/issues/107387
422 |
423 | ### Emscripten
424 |
425 | Emscripten can load WebAssembly dynamic libraries either at startup (using
426 | `RUNTIME_LINKED_LIBS`) or dynamically (using `dlopen`/`dlsym`/etc).
427 | See `test_dylink_*` and `test_dlfcn_*` in the test suite for examples.
428 |
429 | Emscripten can create WebAssembly dynamic libraries with its `SIDE_MODULE`
430 | option, see [the wiki](https://github.com/kripken/emscripten/wiki/WebAssembly-Standalone).
431 |
432 | ### toywasm
433 |
434 | Toywasm's [libdyld] library implements dynamic linking.
435 | It supports both of PIE and non-PIE executables.
436 | It also provides dlopen-like host functions.
437 |
438 | [libdyld]: https://github.com/yamt/toywasm/tree/master/libdyld
439 |
--------------------------------------------------------------------------------
/EHScheme.md:
--------------------------------------------------------------------------------
1 | # WebAssembly Exception Handling Scheme
2 |
3 | This document describes the plans for a new exception handling scheme for
4 | WebAssembly, regarding what each tool components does and how they interact with
5 | each other to implement the scheme.
6 |
7 | Here we describe a new exception handling scheme for WebAssembly for the
8 | toolchain side to generate compatible wasm binary files to support the
9 | aforementioned [WebAssembly exception handling proposal][eh_proposal].
10 |
11 | We use [the exception IR designed for Windows EH][llvm_win_eh] for the Wasm IR
12 | because of its well-defined EH pad scopes and hierarchies between them, we
13 | use [the Itanium EH ABI][itanium_abi] for the communication between user code
14 | and libraries.
15 |
16 | ---
17 |
18 | ## Background
19 |
20 | ### WebAssembly try-catch Blocks
21 |
22 | WebAssembly's `try` and `catch` instructions are structured as follows:
23 | ```
24 | try
25 | instruction*
26 | catch (C++ tag)
27 | instruction*
28 | catch (Another language's tag)
29 | instruction*
30 | ...
31 | catch_all
32 | instruction*
33 | try_end
34 | ```
35 | A `catch` instruction in WebAssembly does not correspond to a C++ `catch`
36 | clause. **In WebAssembly, there is a single `catch` instruction for all C++
37 | exceptions.** `catch` instruction with tags for other languages and `catch_all`
38 | instructions are not generated for the current version of implementation. **All
39 | catch clauses for various C++ types go into this big `catch (C++ tag)` block.**
40 | Each language will have a tag number assigned to it, so you can think the C++
41 | tag as a fixed integer here. So the structure for the prototype will look like
42 | ```
43 | try
44 | instruction*
45 | catch (C++ tag)
46 | instruction*
47 | try_end
48 | ```
49 |
50 | So for example, if we have this C++ code:
51 | ```cpp
52 | try {
53 | foo(); // may throw
54 | } catch (int n) {
55 | printf("int caught");
56 | } catch (float f) {
57 | printf("float caught");
58 | }
59 | ```
60 |
61 | The resulting grouping of WebAssembly instructions will be, in pseudocode, like
62 | this:
63 | ```
64 | try
65 | foo();
66 | catch (C++ tag)
67 | if thrown exception is int
68 | printf("int caught");
69 | else if thrown exception is float
70 | printf("float caught");
71 | else
72 | throw exception to the caller
73 | try_end
74 | ```
75 |
76 | When a
77 | [`throw`][eh_proposal#throwing-an-exception]
78 | instruction throws an exception within a `try` block or functions called from
79 | it, the control flow is transferred to `catch (C++ tag)` instruction, after
80 | which the thrown exception object is placed on top of WebAssembly value stack.
81 | This means, from user code's point of view, `catch` instruction returns the
82 | thrown exception object. For more information, refer to [Try-catch
83 | blocks][eh_proposal_try_catch_blocks] section in the exception proposal.
84 |
85 |
86 | ### C++ Libraries
87 |
88 | Here we only discuss C++ libraries because currenly we only support C++
89 | exceptions, but every language that supports exceptions should have some kind of
90 | libraries that play similar roles, which we can extend to support WebAssembly
91 | exceptions once we add support for that language.
92 |
93 | Two C++ runtime libraries participate in exception handling: [C++ ABI
94 | library](https://clang.llvm.org/docs/Toolchain.html#c-abi-library) and [Unwind
95 | library](https://clang.llvm.org/docs/Toolchain.html#unwind-library).
96 |
97 | The C++ ABI library provides an implementation of the library portion of the
98 | Itanium C++ ABI, covering both the [support functionality in the main Itanium
99 | C++ ABI document][itanium_abi] and [Level II of the exception handling
100 | support][itanium_abi_cxx_abi]. References to the functions and objects in this
101 | library are implicitly generated by Clang when compiling C++ code. Broadly used
102 | implementations of this spec include LLVM's [libc++abi][llvm_libcxxabi] and GNU
103 | GCC's
104 | [libsupc++](https://github.com/gcc-mirror/gcc/tree/master/libstdc%2B%2B-v3/libsupc%2B%2B).
105 |
106 | The unwind library provides a family of `_Unwind_*` functions implementing the
107 | language-neutral stack unwinding portion of the Itanium C++ ABI ([Level
108 | I][itanium_abi_base_abi]). It is a dependency of the C++ ABI library, and
109 | sometimes is a dependency of other runtimes. GNU GCC's
110 | [libgcc_s](https://github.com/gcc-mirror/gcc/tree/master/libgcc) has an
111 | integrated unwinder. libunwind has a separate library for the unwinder and there
112 | are several implementations including [LLVM's libunwind][llvm_libunwind].
113 |
114 | Our implementation is based on LLVM's libc++abi and libunwind.
115 | Our ports of the libraries, which contain Wasm EH specific changes, are in
116 | https://github.com/emscripten-core/emscripten/tree/main/system/lib/libcxxabi and
117 | https://github.com/emscripten-core/emscripten/tree/main/system/lib/libunwind.
118 |
119 |
120 | ## Why New Exception Handing Scheme?
121 |
122 | Currently there are several exception handling schemes supported by major
123 | compilers such as GCC or LLVM. LLVM supports four kinds of exception handling
124 | schemes: Dwarf CFI, SjLj (setjmp/longjmp), ARM (EABI), and WinEH. Then why do we
125 | need the support for a new exception handling scheme in a compiler as well as
126 | libraries supporting C++ ABI?
127 |
128 | The most distinguished aspect about WebAssembly EH that necessiates a new
129 | exception handling scheme is WebAssembly code is not allowed to inspect or
130 | modify the call stack, and cannot jump indirectly. As a result, when an
131 | exception is thrown, the stack is unwound by not the unwind library but the VM.
132 | This affects various components of WebAssembly EH that will be discussed in
133 | detail in this document.
134 |
135 | The definition of an exception handling scheme can be different when defined
136 | from a compiler's point of view and when from libraries. LLVM currently supports
137 | four exception handling schemes: Dwarf CFI, SjLj, ARMEH, and WinEH, where all of
138 | them use Itanium C++ ABI with an exception of WinEH. ARMEH resembles Dwarf CFI
139 | in many ways other than a few architectural differences. Unwind libraries
140 | implement different unwinding mechanism for many architectures, each of which
141 | can be considered as a separate scheme. We will refer to the WebAssembly
142 | exception handling scheme as WebAssembly EH in short in this document.
143 |
144 | In this document we mostly describe WebAssembly EH using comparisons with with
145 | two Itanium-based schemes: Dwarf CFI and SjLj. Even though the unwinding process
146 | itself is very different, code transformation required by compiler and the way
147 | C++ ABI library and unwind library communicate partly resemble that of SjLj
148 | exception handling scheme.
149 |
150 | ---
151 |
152 | ## Direct Personality Function Call
153 |
154 | ### Stack Unwinding and Personality Function
155 |
156 | For other schemes, stack unwinding is performed by the unwind library: for
157 | example, DWARF CFI scheme uses call frame information stored in DWARF format to
158 | access callers' frames, whereas SjLj scheme traverses in-memory chain of
159 | structures recorded for every try clause to find a matching catch site. And at
160 | every call frame with try-catch clauses, these exception handling schemes call
161 | the _personality function_ in the C++ ABI library to check if we need to stop at
162 | the call frame, in which case there is a matching catch site or cleanup actions
163 | to perform.
164 |
165 | **Unlike this process, WebAssembly unwinding process is performed by a VM, and
166 | it stops at every call frame that has `catch (C++ tag)` instruction.** From
167 | WebAssembly code's point of view, after a
168 | [`throw`][eh_proposal_throwing_an_exception] instruction within a try block
169 | throws, the control flow is magically transferred to a corresponding `catch (C++
170 | tag)` instruction, which returns an exception object. So the unwinding process
171 | is completely hidden from WebAssembly code, which means the personality function
172 | cannot be called before control returns to the compiler-generated user code.
173 |
174 | For example, in Dwarf CFI scheme, after the personality function figures out
175 | which frame to stop, the function does three things (in SjLj scheme the
176 | personality function doesn't do the landing pad setting because it uses
177 | `longjmp`):
178 | * Sets IP to the start of a matching landing pad block (so that the unwinder
179 | will jump to this block after the personality routine returns).
180 | * Gives the address of the thrown exception object.
181 | * Gives the _selector value_ corresponding to the type of exception thrown.
182 |
183 | Can WebAssembly EH get all this information without calling a personality
184 | function? Program control flow is transferred to `catch (C++ tag)` instruction
185 | by the unwinder in a VM; WebAssembly code cannot access or modify IP.
186 | WebAssembly `catch` instruction's result is the address of a thrown object.
187 | **But we cannot get a selector without calling a personality function.** In
188 | WebAssembly EH, the personality function is _directly_ called from the
189 | compiler-generated user code rather than from the unwind library. To do that,
190 | WebAssembly compiler inserts a call to the personality function at the start of
191 | each landing pad.
192 |
193 |
194 | ### Landing Pad Code
195 |
196 | In exception handling schemes based on Itanium C++ ABI, C++ `throw` keyword is
197 | compiled into a call to [`__cxa_throw`][__cxa_throw] function, which
198 | [calls](https://github.com/emscripten-core/emscripten/blob/19607820c447a13fd8d0b7680c56148427d6e1b8/system/lib/libcxxabi/src/cxa_exception.cpp#L288-L292)
199 | `_Unwind_RaiseException` (in Dwarf CFI scheme) or `_Unwind_SjLj_RaiseException`
200 | (in SjLj scheme) to start an unwinding process. These `_Unwind_RaiseException`/
201 | `_Unwind_SjLj_RaiseException` functions performs the actual stack unwinding
202 | process and calls the personality function for each eligible call frame. You can
203 | see libcxxabi's personality function implementation
204 | [here][__gxx_personality_wasm0].
205 |
206 | As discussed above, in WebAssembly EH stack unwinding is not done by the unwind
207 | library, the compiler inserts a call to a personality function, more precisely,
208 | a _wrapper_ to the personality function after WebAssembly `catch` instruction,
209 | passing the thrown exception object returned from the `catch` instruction. The
210 | wrapper function lives in the unwind library, and its signature will be
211 | ```cpp
212 | _Unwind_Reason_Code _Unwind_CallPersonality(void *exception_ptr);
213 | ```
214 |
215 | Even though the wrapper signature looks simple, we use an auxiliary data
216 | structure to pass more information from the compiler-generated user code to the
217 | personality function and retrieve a selector computed after the function
218 | returns. The structure is used as a communication channel: we set input
219 | parameters within the structure before calling the wrapper function, and reads
220 | output parameters after the function returns. This structure lives in the unwind
221 | library and this is how it looks like:
222 | ```cpp
223 | struct _Unwind_LandingPadContext {
224 | // Input information to personality function
225 | uintptr_t lpad_index; // landing pad index
226 | __personality_routine personality; // personality function
227 | uintptr_t lsda; // LSDA address
228 |
229 | // Output information computed by personality function
230 | uintptr_t selector; // selector value, used to select a C++ catch clause
231 | };
232 |
233 | // Communication channel between WebAssembly code and personality function
234 | struct _Unwind_LandingPadContext __wasm_lpad_context = ...;
235 |
236 | // Personality function wrapper
237 | _Unwind_Reason_Code _Unwind_CallPersonality(void *exception_ptr) {
238 | struct _Unwind_Exception *exception_obj =
239 | (struct _Unwind_Exception *)exception_ptr;
240 |
241 | // Call personality function
242 | _Unwind_Reason_Code ret = (*__wasm_lpad_context->personality)(
243 | 1, _UA_CLEANUP_PHASE, exception_obj->exception_class, exception_obj,
244 | (struct _Unwind_Context *)__wasm_lpad_context);
245 | return ret;
246 | }
247 | ```
248 |
249 | As you can see in the code above, here's the list of input and output parameters
250 | communicated throw `__wasm_lpad_context`:
251 | * Input parameters
252 | * Landing pad index
253 | * Personality function address
254 | * LSDA information (exception handling table) address
255 | * Output parameters
256 | * Selector value
257 |
258 | These three input parameters are not directly passed to the personality function
259 | as arguments, but are read from it using various `_Unwind_Get*` functions in
260 | unwind library API. The output parameter, a selector value is also not directly
261 | returned by the personality function but will be set by the personality function
262 | using `_Unwind_SetGR`. (`SetGR` here means setting a general register, and it
263 | does set a physical register in Dwarf CFI. But for SjLj and WebAssembly schemes
264 | it sets some field in a data structure instead.)
265 |
266 | When looking for a matching catch site in each call frame, what the personality
267 | function does is querying the call site table within the current function's LSDA
268 | (Language Specipic Data Area), also known as exception handling table or
269 | `gcc_except_table`, with a call site information. For example, the table answers
270 | queries such as "If an exception is thrown at this call site, which action table
271 | entry should I check?" In Dwarf CFI scheme, the offset of actual callsite
272 | address relative to function start address is used as callsite information. In
273 | SjLj scheme, each callsite that can throw has an index starting from 0, and the
274 | indices serve as callsite information to query the action table. In WebAssembly
275 | EH, because a call to the personality function wrapper is inserted at the start
276 | of each landing pad, we give each landing pad an index starting from 0 and use
277 | this as callsite information. We also need to pass the address of the
278 | personality function so that the wrapper can call it. The address of LSDA for
279 | the current function is also required because the personality function examines
280 | the tables there to look for a matching catch site.
281 |
282 | Putting it all together, below is an example of code snippet the compiler
283 | inserts at the beginning of each landing pad. (This is C-style pseudocode; the
284 | real code inserted will be in IR or assembly level.)
285 | ```cpp
286 | // Gets a thrown exception object
287 | void *exn = catch(0); // WebAssembly catch instruction
288 |
289 | // Set input parameters
290 | __wasm_lpad_context.lpad_index = index;
291 | __wasm_lpad_context.personality = __gxx_personality_v0;
292 | __wasm_lpad_context.lsda = &GCC_except_table0; // LSDA symbol of this function
293 |
294 | // Call personality wrapper function
295 | _Unwind_CallPersonality(exn);
296 |
297 | // Retrieve output parameter
298 | int selector = __wasm_lpad_context.selector;
299 |
300 | // use exn and selector hereafter
301 | ```
302 |
303 | ---
304 |
305 | ## No Two-Phase Unwinding
306 |
307 | Itanium-style two-phase unwinding typically consists of two phases: search and
308 | cleanup. In the search phase, call frames are searched to find a matching catch
309 | site that can catch the type of exception thrown or one that needs some cleanup
310 | action as the stack is unwound. If one is found, it enters the cleanup phase in
311 | which the unwinder stops at the stack frame with the matching catch site found
312 | and starts to run the code there. (The whole search in the second phase is
313 | usually avoided by reusing cached information from the first search phase.) If
314 | no matching clause is found in the first phase, the program aborts.
315 |
316 | **WebAssembly unwinder does not perform two-phase unwinding.** Therefore,
317 | effectively, it only runs the second, cleanup phase. As discussed, because the
318 | unwinding is done by a VM, the unwind library and the C++ ABI library cannot
319 | drive its two-phase unwinding. Because we do not have any cached information
320 | from the first search stage, we do full searches as in the first search stage of
321 | two-phase unwinding.
322 |
323 | ---
324 |
325 | ## LSDA Information
326 |
327 | LSDA (Language Specific Data Area) contains various tables used by the
328 | personality function to check if there is any matching catch sites or cleanup
329 | code to run. Every function that has landing pads has its own LSDA information
330 | area. Usually symbols with prefix `GCC_except_table` or `gcc_except_table` are
331 | used to denote the start of a LSDA information. For some exception handling
332 | schemes LSDA information is stored in its own section, but WebAssembly uses the
333 | data section.
334 |
335 | There are three tables in WebAssembly LSDA information:
336 | * Call site table
337 | * Maps call sites (landing pad indices) to action table entries.
338 | * Action table
339 | * Each entry contains the current action (type information and whether to
340 | catch it or filter it) and the next action entry to proceed. Refers to type
341 | information table on which type to catch or filter.
342 | * Type information table
343 | * List of type information
344 |
345 | In WebAssembly EH, the formats of the action table and the type information
346 | table are the same with that of Dwarf CFI and SjLj scheme. The primary
347 | difference of our scheme is we use landing pad indices as call sites.
348 |
349 | ```text
350 | Exception Handling Table Layout:
351 |
352 | +-----------------+--------+----------------------+
353 | | lpStartEncoding | (char) | always DW_EH_PE_omit |
354 | +---------+-------+--------+---------------+----------+
355 | | lpStart | (encoded with lpStartEncoding) | Not used |
356 | +---------+-----+--------+-----------------+---------------+
357 | | ttypeEncoding | (char) | Encoding of the type_info table |
358 | +---------------+-+------+----+----------------------------+----------------+
359 | | classInfoOffset | (ULEB128) | Offset to type_info table, defaults to null |
360 | +-----------------++--------+-+----------------------------+----------------+
361 | | callSiteEncoding | (char) | Encoding for Call Site Table |
362 | +------------------+--+-----+-----+------------------------+--------------------------+
363 | | callSiteTableLength | (ULEB128) | Call Site Table length, used to find Action table |
364 | +---------------------+-----------+---------------------------------------------------+
365 | +---------------------+-----------+------------------------------------------------+
366 | | Beginning of Call Site Table landing pad index is a index into this |
367 | | table. |
368 | | +-------------+---------------------------------+------------------------------+ |
369 | | | landingPad | (ULEB128) | landingpad index | |
370 | | | actionEntry | (ULEB128) | Action Table Index 1-based | |
371 | | | | | actionEntry == 0 -> cleanup | |
372 | | +-------------+---------------------------------+------------------------------+ |
373 | | ... |
374 | +----------------------------------------------------------------------------------+
375 | +---------------------------------------------------------------------+
376 | | Beginning of Action Table ttypeIndex == 0 : cleanup |
377 | | ... ttypeIndex > 0 : catch |
378 | | ttypeIndex < 0 : exception spec |
379 | | +--------------+-----------+--------------------------------------+ |
380 | | | ttypeIndex | (SLEB128) | Index into type_info Table (1-based) | |
381 | | | actionOffset | (SLEB128) | Offset into next Action Table entry | |
382 | | +--------------+-----------+--------------------------------------+ |
383 | | ... |
384 | +---------------------------------------------------------------------+-----------------+
385 | | type_info Table, but classInfoOffset does *not* point here! |
386 | | +----------------+------------------------------------------------+-----------------+ |
387 | | | Nth type_info* | Encoded with ttypeEncoding, 0 means catch(...) | ttypeIndex == N | |
388 | | +----------------+------------------------------------------------+-----------------+ |
389 | | ... |
390 | | +----------------+------------------------------------------------+-----------------+ |
391 | | | 1st type_info* | Encoded with ttypeEncoding, 0 means catch(...) | ttypeIndex == 1 | |
392 | | +----------------+------------------------------------------------+-----------------+ |
393 | | +---------------------------------------+-----------+------------------------------+ |
394 | | | 1st ttypeIndex for 1st exception spec | (ULEB128) | classInfoOffset points here! | |
395 | | | ... | (ULEB128) | | |
396 | | | Mth ttypeIndex for 1st exception spec | (ULEB128) | | |
397 | | | 0 | (ULEB128) | | |
398 | | +---------------------------------------+------------------------------------------+ |
399 | | ... |
400 | | +---------------------------------------+------------------------------------------+ |
401 | | | 0 | (ULEB128) | throw() | |
402 | | +---------------------------------------+------------------------------------------+ |
403 | | ... |
404 | | +---------------------------------------+------------------------------------------+ |
405 | | | 1st ttypeIndex for Nth exception spec | (ULEB128) | | |
406 | | | ... | (ULEB128) | | |
407 | | | Mth ttypeIndex for Nth exception spec | (ULEB128) | | |
408 | | | 0 | (ULEB128) | | |
409 | | +---------------------------------------+------------------------------------------+ |
410 | +---------------------------------------------------------------------------------------+
411 | ```
412 |
413 | You can see the exception table structure for DwarfCFI and SjLj scheme
414 | [here](https://github.com/emscripten-core/emscripten/blob/19607820c447a13fd8d0b7680c56148427d6e1b8/system/lib/libcxxabi/src/cxa_personality.cpp#L60-L155).
415 | Other than call site table, the structure for WebAssembly EH is mostly the same.
416 |
417 | ---
418 |
419 | ## WebAssembly C++ Exception Handling ABI
420 |
421 | We discussed in a [prior section](#landing-pad-code) about some additions
422 | required to the C++ ABI library and the unwind library to implement WebAssembly
423 | EH. Here we list up required additional data structure/functions and
424 | WebAssembly's implementation of required APIs.
425 |
426 | ### Compiler Builtins
427 |
428 | This section describes compiler builtins that require support from compiler
429 | implementations.
430 |
431 | ##### __builtin_wasm_throw
432 | ```
433 | void __builtin_wasm_throw(unsigned int, void *);
434 | ```
435 | A call to this builtin function is converted to a WebAssembly
436 | [`throw`][eh_proposal_throwing_an_exception] instruction in the instruction
437 | selection stage in the backend. This builtin function is used to implement
438 | exception-throwing functions in the base ABI.
439 |
440 | ##### __builtin_wasm_rethrow
441 | ```
442 | void __builtin_wasm_rethrow();
443 | ```
444 | A call to this builtin function is converted to a WebAssembly
445 | [`rethrow`][eh_proposal_rethrowing_an_exception] instruction in the instruction
446 | selection stage in the backend. This builtin function is used to implement
447 | rethrowing exceptions in the base API.
448 |
449 |
450 | ### Base ABI
451 |
452 | This section defines the unwind library interface, expected to be provided by
453 | any Itanium ABI-compliant system. This is the interface on which the C++ ABI
454 | exception-handling facilities are built. This section describes what WebAssembly
455 | version of the ABI functions do and additional data structures or functions we
456 | need to add. For the complete Itanium C++ base ABI, refer to the spec
457 | [here][itanium_abi_base_abi].
458 |
459 |
460 | #### Data Structures
461 |
462 | ##### Landing Pad Context
463 | This serves as a communication channel between WebAssembly code and the
464 | personality function. A global variable `__wasm_lpad_context` is an instance of
465 | this data structure.
466 |
467 | ```cpp
468 | struct _Unwind_LandingPadContext {
469 | // Input information to personality function
470 | uintptr_t lpad_index; // landing pad index
471 | __personality_routine personality; // personality function
472 | uintptr_t lsda; // LSDA address
473 |
474 | // Output information computed by personality function
475 | uintptr_t selector; // selector value
476 | };
477 |
478 | // Communication channel between WebAssembly code and personality function
479 | struct _Unwind_LandingPadContext __wasm_lpad_context = ...;
480 | ```
481 |
482 |
483 | #### Throwing an Exception
484 |
485 | ##### _Unwind_RaiseException
486 | ```cpp
487 | _Unwind_Reason_Code
488 | _Unwind_RaiseException(struct _Unwind_Exception *exception_object);
489 | ```
490 | Raise an exception using the [`__builtin_wasm_throw`
491 | builtin](#__builtin_wasm_throw), which will be converted to WebAssembly
492 | [`throw`][eh_proposal_throwing_an_exception] instruction. The arguments to the
493 | builtin are the tag number for C++ and a pointer to an exception object.
494 |
495 | ##### _Unwind_ForcedUnwind
496 | Not used.
497 |
498 | ##### _Unwind_Resume
499 | ```cpp
500 | void _Unwind_Resume(struct _Unwind_Exception *exception_object);
501 | ```
502 | Resume propagation of an existing exception. Unlike other `_Unwind_*` functions
503 | that are called from the C++ ABI library, this is called from compiler-generated
504 | user code. In other exception handling schemes, this function is mostly used
505 | when a call frame does not have a matching catch site but has cleanup code to
506 | run so that the unwinder stops there only to run the cleanup and resume the
507 | exception's propagation. But in WebAssembly EH, because the unwinder stops at
508 | every call frame with landing pads, this runs on every call frame with landing
509 | pads that does not have a matching catch site. This function also makes use of
510 | [`__builtin_wasm_throw` builtin](#__builtin_wasm_throw) to resume the
511 | propagation of an exception.
512 |
513 |
514 | #### Context Management
515 |
516 | ##### _Unwind_GetGR / _Unwind_SetGR
517 | ```cpp
518 | uint64 _Unwind_GetGR(struct _Unwind_Context *context, int index);
519 | void
520 | _Unwind_SetGR(struct _Unwind_Context *context, int index, uint64 new_value);
521 | ```
522 | The meaning of the original API name is it gets/sets the value of the given
523 | general register. But in WebAssembly EH, `_Unwind_SetGR` is only used to [set a
524 | selector
525 | value](https://github.com/emscripten-core/emscripten/blob/19607820c447a13fd8d0b7680c56148427d6e1b8/system/lib/libunwind/src/Unwind-wasm.c#L77)
526 | to a data structure used as a communication channel
527 | (`__wasm_lpad_context.selector`).
528 |
529 | In WebAssembly EH, `_Unwind_SetGR` expects the first argument to be a pointer to
530 | `struct _Unwind_LandingPadContext` instance, and only 1 is accepted as the
531 | second argument, in which case it sets the first argument's `selector` field.
532 | `_Unwind_GetGR` is not used.
533 |
534 | ##### _Unwind_GetIP / _Unwind_SetIP
535 | ```cpp
536 | uint64 _Unwind_GetIP(struct _Unwind_Context *context);
537 | void _Unwind_SetIP(struct _Unwind_Context *context, uint64 new_value);
538 | ```
539 | This sets/gets a real IP address in Dwarf CFI, but in our scheme `_Unwind_GetIP`
540 | returns the value of (landing pad index + 1). The landing pad index is set by
541 | compiler-generated user code to `__wasm_lpad_context.lpad_index` as discussed in
542 | [Landing Pad Code](#landing-pad-code). This information is used in the
543 | personality function to query the call site table. `_Unwind_SetIP` is not used.
544 |
545 | ##### _Unwind_GetLanguageSpecificData
546 | ```cpp
547 | uint64 _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context);
548 | ```
549 | Returns the address of the current function's LSDA information
550 | (`__wasm_lpad_context.lsda`), set by compiler-generated user code as discussed
551 | in [Landing Pad Code](#landing-pad-code).
552 |
553 | ##### _Unwind_GetRegionStart
554 | Not used.
555 |
556 |
557 | #### Personality Routine
558 |
559 | ##### Personality Function Wrapper
560 | A wrapper function used to call the actual personality function. This is
561 | supposed to be called from compiler-generated user code. Refer to [Landing Pad
562 | Code](#landing-pad-code) for details.
563 |
564 | ```cpp
565 | _Unwind_Reason_Code _Unwind_CallPersonality(void *exception_ptr) {
566 | struct _Unwind_Exception *exception_obj =
567 | (struct _Unwind_Exception *)exception_ptr;
568 |
569 | // Call personality function
570 | _Unwind_Reason_Code ret = (*__wasm_lpad_context->personality)(
571 | 1, _UA_CLEANUP_PHASE, exception_obj->exception_class, exception_obj,
572 | (struct _Unwind_Context *)__wasm_lpad_context);
573 | return ret;
574 | }
575 | ```
576 |
577 | ##### Transferring Control to a Landing Pad
578 | Transferring program control to a landing pad is done by not the unwind library
579 | but the VM. Refer to [Stack Unwinding and Personality
580 | Function](#stack-unwinding-and-personality-function) section for details.
581 |
582 |
583 | ### C++ ABI
584 |
585 | The second level of specification is the minimum required to allow
586 | interoperability of C++ implementations. This part contains the definition of an
587 | exception object, and various high-level APIs including functions required to
588 | allocate / throw / catch / rethrow an exception object. Functions in this
589 | section rely on the [base API][itanium_abi_base_abi] to do low-level
590 | architecture-dependent tasks. WebAssembly EH does not have a lot of things to
591 | add on this level because architecture-dependent components are usually taken
592 | care of in the base API level. But we still need some modifications on the
593 | personality function and functions called from it to handle some subtle
594 | differences between WebAssembly EH and other schemes, such as Dwarf CFI or SjLj.
595 | For the complete Itanium C++ ABI, refer to the spec [here][itanium_abi_cxx_abi].
596 |
597 | ---
598 |
599 | ## References
600 |
601 | * [Exception Handling using the Windows Runtime](https://llvm.org/docs/ExceptionHandling.html#exception-handling-using-the-windows-runtime)
602 | * [Itanium C++ ABI: Exception Handling](https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html)
603 |
604 | * Github repos
605 | * [llvm](https://github.com/llvm/llvm-project)
606 | * [libcxxabi](https://github.com/emscripten-core/emscripten/tree/main/system/lib/libcxxabi)
607 | * [libunwind](https://github.com/emscripten-core/emscripten/tree/main/system/lib/libunwind)
608 |
609 |
610 | [llvm_wasm_backend]: https://github.com/llvm/llvm-project/tree/main/llvm/lib/Target/WebAssembly
611 | [llvm_libcxxabi]: https://github.com/llvm/llvm-project/tree/main/libcxxabi
612 | [llvm_libunwind]: https://github.com/llvm/llvm-project/tree/main/libunwind
613 | [llvm_win_eh]: https://llvm.org/docs/ExceptionHandling.html#exception-handling-using-the-windows-runtime
614 |
615 | [binaryen]: https://github.com/WebAssembly/binaryen
616 | [emscripten]: https://github.com/emscripten-core/emscripten
617 | [emscripten_libcxxabi]: https://github.com/emscripten-core/emscripten/tree/main/system/lib/libcxxabi
618 | [emscripten_libunwind]: https://github.com/emscripten-core/emscripten/tree/main/system/lib/libunwind
619 |
620 | [eh_proposal]: https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md
621 | [eh_proposal_try_catch_blocks]: https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md#try-catch-blocks
622 | [eh_proposal_throwing_an_exception]: https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md#throwing-an-exception
623 | [eh_proposal_rethrowing_an_exception]: https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md#rethrowing-an-exception
624 |
625 | [itanium_abi]: https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html
626 | [itanium_abi_cxx_abi]: https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#cxx-abi
627 | [itanium_abi_base_abi]: https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#base_abi
628 |
629 | [__cxa_throw]: https://github.com/emscripten-core/emscripten/blob/19607820c447a13fd8d0b7680c56148427d6e1b8/system/lib/libcxxabi/src/cxa_exception.cpp#L263-L304
630 | [__gxx_personality_wasm0]: https://github.com/emscripten-core/emscripten/blob/19607820c447a13fd8d0b7680c56148427d6e1b8/system/lib/libcxxabi/src/cxa_personality.cpp#L910-L1003
631 |
--------------------------------------------------------------------------------
/ItaniumLikeC++ABI.md:
--------------------------------------------------------------------------------
1 | This document describes the "Itanium-like" C++ ABI for WebAssembly. As mentioned
2 | in [README](README.md), it's not the only possible C++ ABI or even the only
3 | possible Itanium-derived C++ ABI for WebAssembly. It is the ABI that the
4 | clang/LLVM WebAssembly backend is currently using, and any other C++ compiler
5 | wishing to be ABI-compatible with it.
6 |
7 | Most details follow
8 | [the base Itanium C++ ABI](https://itanium-cxx-abi.github.io/cxx-abi/abi.html).
9 |
10 | The following is a brief summary of deviations from this base:
11 |
12 | - The least-significant bit of the `adj` field of a member-function pointer is
13 | used to indicate whether the indicated function is virtual.
14 | - Member functions are not specially aligned.
15 | - Constructors and destructors return `this`.
16 | - Guard variables are 32-bit on wasm32.
17 | - Unused bits of guard variables are reserved.
18 | - Inline functions are never key functions.
19 | - C++11 POD rules are used to determine tail padding.
20 |
21 | The following are ideas for additional deviations that are being considered:
22 |
23 | - The Itanium C++ name mangling rules have special-case abbreviations for
24 | std::string, std::allocator, and a few others, however libc++ doesn’t get to
25 | take advantage of them because it uses a versioned namespace. It may be
26 | useful to add new special-cases to cover libc++’s mangled names for
27 | std::string et al.
28 | - There’s an interesting idea for a vtable optimization described
29 | [here](https://llvm.org/bugs/show_bug.cgi?id=26723) that’s worth thinking
30 | about.
31 | - Alternatively, the design of vtables may radically change to take better
32 | advantage of WebAssembly’s function table mechanisms.
33 | - Trivially copyable classes may be passed by value rather than by pointer.
34 | This would cover a lot of common C++ classes such as std::pair.
35 |
36 | This is just an initial sketch of the kind of content we plan to have here.
37 | Obviously it would be desirable to go into a lot more detail.
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The Artistic License 2.0
2 |
3 | Copyright (c) 2000-2006, The Perl Foundation.
4 |
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | This license establishes the terms under which a given free software
11 | Package may be copied, modified, distributed, and/or redistributed.
12 | The intent is that the Copyright Holder maintains some artistic
13 | control over the development of that Package while still keeping the
14 | Package available as open source and free software.
15 |
16 | You are always permitted to make arrangements wholly outside of this
17 | license directly with the Copyright Holder of a given Package. If the
18 | terms of this license do not permit the full use that you propose to
19 | make of the Package, you should contact the Copyright Holder and seek
20 | a different licensing arrangement.
21 |
22 | Definitions
23 |
24 | "Copyright Holder" means the individual(s) or organization(s)
25 | named in the copyright notice for the entire Package.
26 |
27 | "Contributor" means any party that has contributed code or other
28 | material to the Package, in accordance with the Copyright Holder's
29 | procedures.
30 |
31 | "You" and "your" means any person who would like to copy,
32 | distribute, or modify the Package.
33 |
34 | "Package" means the collection of files distributed by the
35 | Copyright Holder, and derivatives of that collection and/or of
36 | those files. A given Package may consist of either the Standard
37 | Version, or a Modified Version.
38 |
39 | "Distribute" means providing a copy of the Package or making it
40 | accessible to anyone else, or in the case of a company or
41 | organization, to others outside of your company or organization.
42 |
43 | "Distributor Fee" means any fee that you charge for Distributing
44 | this Package or providing support for this Package to another
45 | party. It does not mean licensing fees.
46 |
47 | "Standard Version" refers to the Package if it has not been
48 | modified, or has been modified only in ways explicitly requested
49 | by the Copyright Holder.
50 |
51 | "Modified Version" means the Package, if it has been changed, and
52 | such changes were not explicitly requested by the Copyright
53 | Holder.
54 |
55 | "Original License" means this Artistic License as Distributed with
56 | the Standard Version of the Package, in its current version or as
57 | it may be modified by The Perl Foundation in the future.
58 |
59 | "Source" form means the source code, documentation source, and
60 | configuration files for the Package.
61 |
62 | "Compiled" form means the compiled bytecode, object code, binary,
63 | or any other form resulting from mechanical transformation or
64 | translation of the Source form.
65 |
66 |
67 | Permission for Use and Modification Without Distribution
68 |
69 | (1) You are permitted to use the Standard Version and create and use
70 | Modified Versions for any purpose without restriction, provided that
71 | you do not Distribute the Modified Version.
72 |
73 |
74 | Permissions for Redistribution of the Standard Version
75 |
76 | (2) You may Distribute verbatim copies of the Source form of the
77 | Standard Version of this Package in any medium without restriction,
78 | either gratis or for a Distributor Fee, provided that you duplicate
79 | all of the original copyright notices and associated disclaimers. At
80 | your discretion, such verbatim copies may or may not include a
81 | Compiled form of the Package.
82 |
83 | (3) You may apply any bug fixes, portability changes, and other
84 | modifications made available from the Copyright Holder. The resulting
85 | Package will still be considered the Standard Version, and as such
86 | will be subject to the Original License.
87 |
88 |
89 | Distribution of Modified Versions of the Package as Source
90 |
91 | (4) You may Distribute your Modified Version as Source (either gratis
92 | or for a Distributor Fee, and with or without a Compiled form of the
93 | Modified Version) provided that you clearly document how it differs
94 | from the Standard Version, including, but not limited to, documenting
95 | any non-standard features, executables, or modules, and provided that
96 | you do at least ONE of the following:
97 |
98 | (a) make the Modified Version available to the Copyright Holder
99 | of the Standard Version, under the Original License, so that the
100 | Copyright Holder may include your modifications in the Standard
101 | Version.
102 |
103 | (b) ensure that installation of your Modified Version does not
104 | prevent the user installing or running the Standard Version. In
105 | addition, the Modified Version must bear a name that is different
106 | from the name of the Standard Version.
107 |
108 | (c) allow anyone who receives a copy of the Modified Version to
109 | make the Source form of the Modified Version available to others
110 | under
111 |
112 | (i) the Original License or
113 |
114 | (ii) a license that permits the licensee to freely copy,
115 | modify and redistribute the Modified Version using the same
116 | licensing terms that apply to the copy that the licensee
117 | received, and requires that the Source form of the Modified
118 | Version, and of any works derived from it, be made freely
119 | available in that license fees are prohibited but Distributor
120 | Fees are allowed.
121 |
122 |
123 | Distribution of Compiled Forms of the Standard Version
124 | or Modified Versions without the Source
125 |
126 | (5) You may Distribute Compiled forms of the Standard Version without
127 | the Source, provided that you include complete instructions on how to
128 | get the Source of the Standard Version. Such instructions must be
129 | valid at the time of your distribution. If these instructions, at any
130 | time while you are carrying out such distribution, become invalid, you
131 | must provide new instructions on demand or cease further distribution.
132 | If you provide valid instructions or cease distribution within thirty
133 | days after you become aware that the instructions are invalid, then
134 | you do not forfeit any of your rights under this license.
135 |
136 | (6) You may Distribute a Modified Version in Compiled form without
137 | the Source, provided that you comply with Section 4 with respect to
138 | the Source of the Modified Version.
139 |
140 |
141 | Aggregating or Linking the Package
142 |
143 | (7) You may aggregate the Package (either the Standard Version or
144 | Modified Version) with other packages and Distribute the resulting
145 | aggregation provided that you do not charge a licensing fee for the
146 | Package. Distributor Fees are permitted, and licensing fees for other
147 | components in the aggregation are permitted. The terms of this license
148 | apply to the use and Distribution of the Standard or Modified Versions
149 | as included in the aggregation.
150 |
151 | (8) You are permitted to link Modified and Standard Versions with
152 | other works, to embed the Package in a larger work of your own, or to
153 | build stand-alone binary or bytecode versions of applications that
154 | include the Package, and Distribute the result without restriction,
155 | provided the result does not expose a direct interface to the Package.
156 |
157 |
158 | Items That are Not Considered Part of a Modified Version
159 |
160 | (9) Works (including, but not limited to, modules and scripts) that
161 | merely extend or make use of the Package, do not, by themselves, cause
162 | the Package to be a Modified Version. In addition, such works are not
163 | considered parts of the Package itself, and are not subject to the
164 | terms of this license.
165 |
166 |
167 | General Provisions
168 |
169 | (10) Any use, modification, and distribution of the Standard or
170 | Modified Versions is governed by this Artistic License. By using,
171 | modifying or distributing the Package, you accept this license. Do not
172 | use, modify, or distribute the Package, if you do not accept this
173 | license.
174 |
175 | (11) If your Modified Version has been derived from a Modified
176 | Version made by someone other than you, you are nevertheless required
177 | to ensure that your Modified Version complies with the requirements of
178 | this license.
179 |
180 | (12) This license does not grant you the right to use any trademark,
181 | service mark, tradename, or logo of the Copyright Holder.
182 |
183 | (13) This license includes the non-exclusive, worldwide,
184 | free-of-charge patent license to make, have made, use, offer to sell,
185 | sell, import and otherwise transfer the Package with respect to any
186 | patent claims licensable by the Copyright Holder that are necessarily
187 | infringed by the Package. If you institute patent litigation
188 | (including a cross-claim or counterclaim) against any party alleging
189 | that the Package constitutes direct or contributory patent
190 | infringement, then this Artistic License to you shall terminate on the
191 | date that such litigation is filed.
192 |
193 | (14) Disclaimer of Warranty:
194 | THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
195 | IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
196 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
197 | NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
198 | LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
199 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
200 | DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
201 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
202 |
--------------------------------------------------------------------------------
/Lime.md:
--------------------------------------------------------------------------------
1 | # The Lime Series
2 |
3 | Lime is a series of defined and stable subsets of [WebAssembly features] that producers
4 | and consumers can both use to promote interoperability. It is intended to be implemented
5 | by producers such as LLVM, using features such as LLVM's concept of target CPUs. Once a
6 | Lime configuration is defined, it will be stable and not add or remove any features.
7 |
8 | Lime configuration names include a version number, such as "Lime1". When there is a
9 | need to add or remove features, a new Lime configuration with a new version number will
10 | be defined, such as "Lime2".
11 |
12 | Lime aims for features which do not involve significant new runtime cost or complexity,
13 | and can be implemented in mobile devices and other highly constrained environments.
14 |
15 | The name "Lime" was inspired by abbreviating *Li*near *Me*mory, as this series currently
16 | lacks wasm-gc and is therefore focused on linear-memory languages or language implementations.
17 |
18 | ## The configurations
19 |
20 | The following Lime configurations have been defined:
21 | - [Lime1](#lime1)
22 |
23 | ### Lime1
24 |
25 | The Lime1 target consists of [WebAssembly 1.0] plus the following standardized
26 | ([phase-5]) features:
27 |
28 | - [mutable-globals]
29 | - [multivalue]
30 | - [sign-ext]
31 | - [nontrapping-fptoint]
32 | - [bulk-memory-opt]
33 | - [extended-const]
34 | - [call-indirect-overlong]
35 |
36 | [WebAssembly features]: https://webassembly.org/features/
37 | [WebAssembly 1.0]: https://www.w3.org/TR/wasm-core-1/
38 | [phase-5]: https://github.com/WebAssembly/meetings/blob/main/process/phases.md#5-the-feature-is-standardized-working-group
39 | [mutable-globals]: https://github.com/WebAssembly/mutable-global/blob/master/proposals/mutable-global/Overview.md
40 | [multivalue]: https://github.com/WebAssembly/spec/blob/master/proposals/multi-value/Overview.md
41 | [sign-ext]: https://github.com/WebAssembly/spec/blob/master/proposals/sign-extension-ops/Overview.md
42 | [nontrapping-fptoint]: https://github.com/WebAssembly/spec/blob/master/proposals/nontrapping-float-to-int-conversion/Overview.md
43 | [bulk-memory-opt]: #bulk-memory-opt
44 | [extended-const]: https://github.com/WebAssembly/extended-const/blob/main/proposals/extended-const/Overview.md
45 | [call-indirect-overlong]: #call-indirect-overlong
46 |
47 | ## Feature subsets
48 |
49 | [WebAssembly features] sometimes contain several features combined into a
50 | single proposal to simplify the standardization process, but can have very
51 | different implementation considerations. This section defines subsets of
52 | standardized features for use in Lime configurations.
53 |
54 | ### bulk-memory-opt
55 |
56 | bulk-memory-opt is a subset of the [bulk-memory] feature that contains just the
57 | `memory.copy` and `memory.fill` instructions.
58 |
59 | It does not include the table instructions, `memory.init`, or `data.drop`.
60 |
61 | ### call-indirect-overlong
62 |
63 | call-indirect-overlong is a subset of the [reference-types] feature that contains
64 | just the change to the `call_indirect` instruction encoding to change the zero
65 | byte to an LEB encoding which may have an overlong encoding.
66 |
67 | It does not include the actual reference types.
68 |
69 | [bulk-memory]: https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md
70 | [reference-types]: https://github.com/WebAssembly/reference-types/blob/master/proposals/reference-types/Overview.md
71 |
--------------------------------------------------------------------------------
/Linking.md:
--------------------------------------------------------------------------------
1 | # WebAssembly Object File Linking
2 |
3 | This document describes the WebAssembly object file format and the ABI used for
4 | statically linking them to produce an executable WebAssembly module. This is
5 | currently implemented in the clang/LLVM WebAssembly
6 | backend and other tools such as binaryen and wabt. As mentioned in
7 | [README](README.md), this is not part of the official WebAssembly specification
8 | and other runtimes may choose to follow a different set of linking conventions.
9 |
10 | ## Overview
11 |
12 | Each translation unit is compiled into a WebAssembly object file. These files
13 | are themselves valid WebAssembly module binaries but are not expected to be
14 | directly executable and have certain additional constraints. In order to
15 | distinguish object files from executable WebAssembly modules the linker can
16 | check for the presence of the ["linking"](#linking-metadata-section) custom
17 | section which must exist in all object files.
18 |
19 | The goal of the linker is to take one or more WebAssembly object files and merge
20 | them into a single executable module. In order to achieve this the following
21 | tasks need to be performed:
22 |
23 | - Merging of function sections (re-numbering functions)
24 | - Merging of globals sections (re-numbering globals)
25 | - Merging of event sections (re-numbering events)
26 | - Merging of table sections (re-numbering tables)
27 | - Merging of data segments (re-positioning data with [limitations](#limitations))
28 | - Resolving undefined external references
29 | - Synthesizing functions to call constructors and perform other initialization
30 |
31 | The linking technique described here is designed to be fast, and avoids having
32 | to disassemble the code section. The extra metadata required by the linker
33 | is stored in a custom ["linking"](#linking-metadata-section) section and zero or
34 | more relocation sections whose names begin with "reloc.". For each section that
35 | requires relocation a "reloc" section will be present in the wasm file. By
36 | convention the reloc section names end with the name of the section that they
37 | refer to: e.g. "reloc.CODE" for code section relocations. However, everything
38 | after the period is ignored and the specific target section is encoded in the
39 | reloc section itself.
40 |
41 | The linker additionally checks that linked object files were built targeting
42 | compatible feature sets. Unlike native targets, WebAssembly has no runtime
43 | feature detection, and the presence of unsupported features causes a binary to
44 | fail to validate. It is therefore important for the user to have explicit
45 | control over the features used in the output binary and for the linker to
46 | provide helpful errors when instructed to link incompatible or disallowed
47 | features. This feature information is stored in a custom ["target feature
48 | section"](#target-features-section).
49 |
50 | ## Relocation Sections
51 |
52 | A relocation section is a user-defined section with a name starting with
53 | "reloc." Relocation sections start with an identifier specifying which
54 | section they apply to, and must be sequenced in the module after that
55 | section.
56 |
57 | Relocation sections can only target code, data and custom sections. All other
58 | sections are synthetic sections: that is, rather than being `memcpy`'d into
59 | place as the code and data sections are, they are created from scratch by the
60 | linker.
61 |
62 | The "reloc." custom sections must come after the
63 | ["linking"](#linking-metadata-section) custom section in order to validate
64 | relocation indices.
65 |
66 | Any LEB128-encoded values should be maximally padded so that they can be
67 | rewritten without affecting the position of any other bytes. For instance, the
68 | function index 3 should be encoded as `0x83 0x80 0x80 0x80 0x00`.
69 |
70 | Relocations contain the following fields:
71 |
72 | | Field | Type | Description |
73 | | ----------| ------------------- | ------------------------------- |
74 | | section | `varuint32` | the index of the target section |
75 | | count | `varuint32` | count of entries to follow |
76 | | entries | `relocation_entry*` | sequence of relocation entries |
77 |
78 | A `relocation_entry` begins with:
79 |
80 | | Field | Type | Description |
81 | | -------- | ------------------- | ------------------------------ |
82 | | type | `uint8` | the relocation type |
83 | | offset | `varuint32` | offset of the value to rewrite (relative to the relevant section's contents: offset zero is immediately after the id and size of the section) |
84 | | index | `varuint32` | the index of the symbol used (or, for `R_WASM_TYPE_INDEX_LEB` relocations, the index of the type) |
85 |
86 | A relocation type can be one of the following:
87 |
88 | - `0 / R_WASM_FUNCTION_INDEX_LEB` (since LLVM 10.0) - a function index encoded
89 | as a 5-byte [varuint32]. Used for the immediate argument of a `call`
90 | instruction.
91 | - `1 / R_WASM_TABLE_INDEX_SLEB` (since LLVM 10.0) - a function table index
92 | encoded as a 5-byte [varint32]. Used to refer to the immediate argument of a
93 | `i32.const` instruction, e.g. taking the address of a function.
94 | - `2 / R_WASM_TABLE_INDEX_I32` (since LLVM 10.0) - a function table index
95 | encoded as a [uint32], e.g. taking the address of a function in a static data
96 | initializer.
97 | - `3 / R_WASM_MEMORY_ADDR_LEB` (since LLVM 10.0) - a linear memory index
98 | encoded as a 5-byte [varuint32]. Used for the immediate argument of a `load` or
99 | `store` instruction, e.g. directly loading from or storing to a C++ global.
100 | - `4 / R_WASM_MEMORY_ADDR_SLEB` (since LLVM 10.0) - a linear memory index
101 | encoded as a 5-byte [varint32]. Used for the immediate argument of a `i32.const`
102 | instruction, e.g. taking the address of a C++ global.
103 | - `5 / R_WASM_MEMORY_ADDR_I32` (since LLVM 10.0) - a linear memory index
104 | encoded as a [uint32], e.g. taking the address of a C++ global in a static data
105 | initializer.
106 | - `6 / R_WASM_TYPE_INDEX_LEB` (since LLVM 10.0) - a type index encoded as
107 | a 5-byte [varuint32], e.g. the type immediate in a `call_indirect`.
108 | - `7 / R_WASM_GLOBAL_INDEX_LEB` (since LLVM 10.0) - a global index encoded as a
109 | 5-byte [varuint32], e.g. the index immediate in a `get_global`.
110 | - `8 / R_WASM_FUNCTION_OFFSET_I32` (since LLVM 10.0) - a byte offset within
111 | code section for the specific function encoded as a [uint32]. The offsets start
112 | at the actual function code excluding its size field.
113 | - `9 / R_WASM_SECTION_OFFSET_I32` (since LLVM 10.0) - a byte offset from start
114 | of the specified section encoded as a [uint32].
115 | - `10 / R_WASM_EVENT_INDEX_LEB` (since LLVM 10.0) - an event index encoded as a
116 | 5-byte [varuint32]. Used for the immediate argument of a `throw` and `if_except`
117 | instruction.
118 | - `13 / R_WASM_GLOBAL_INDEX_I32` (since LLVM 11.0) - a global index encoded as
119 | [uint32].
120 | - `14 / R_WASM_MEMORY_ADDR_LEB64` (since LLVM 11.0) - the 64-bit counterpart of
121 | `R_WASM_MEMORY_ADDR_LEB`. A 64-bit linear memory index encoded as a 10-byte
122 | [varuint64], Used for the immediate argument of a `load` or `store` instruction
123 | on a 64-bit linear memory array.
124 | - `15 / R_WASM_MEMORY_ADDR_SLEB64` (since LLVM 11.0) - the 64-bit counterpart
125 | of `R_WASM_MEMORY_ADDR_SLEB`. A 64-bit linear memory index encoded as a 10-byte
126 | [varint64]. Used for the immediate argument of a `i64.const` instruction.
127 | - `16 / R_WASM_MEMORY_ADDR_I64` (since LLVM 11.0) - the 64-bit counterpart of
128 | `R_WASM_MEMORY_ADDR`. A 64-bit linear memory index encoded as a [uint64], e.g.
129 | taking the 64-bit address of a C++ global in a static data initializer.
130 | - `18 / R_WASM_TABLE_INDEX_SLEB64` (in LLVM 12.0) - the 64-bit counterpart
131 | of `R_WASM_TABLE_INDEX_SLEB`. A function table index encoded as a 10-byte
132 | [varint64]. Used to refer to the immediate argument of a `i64.const`
133 | instruction, e.g. taking the address of a function in Wasm64.
134 | - `19 / R_WASM_TABLE_INDEX_I64` (in LLVM 12.0) - the 64-bit counterpart of
135 | `R_WASM_TABLE_INDEX_I32`. A function table index encoded as a [uint64], e.g.
136 | taking the address of a function in a static data initializer.
137 | - `20 / R_WASM_TABLE_NUMBER_LEB` (in LLVM 12.0) - a table number encoded as
138 | a 5-byte [varuint32]. Used for the table immediate argument in the table.*
139 | instructions.
140 | - `22 / R_WASM_FUNCTION_OFFSET_I64` (in LLVM 12.0) - the 64-bit counterpart
141 | of `R_WASM_FUNCTION_OFFSET_I32`. A byte offset within code section for the
142 | specific function encoded as a [uint64].
143 | - `23 / R_WASM_MEMORY_ADDR_LOCREL_I32` (in LLVM 13.0) - a byte offset between
144 | the relocating address and a linear memory index encoded as a [uint32]. Used
145 | for pointer-relative addressing.
146 | - `24 / R_WASM_TABLE_INDEX_REL_SLEB64` (in LLVM 13.0) - the 64-bit counterpart
147 | of `R_WASM_TABLE_INDEX_REL_SLEB`. A function table index encoded as a 10-byte
148 | [varint64].
149 | - `26 / R_WASM_FUNCTION_INDEX_I32` (in LLVM 17.0) - a function index encoded as
150 | a [uint32]. Used in custom sections for function annotations (`__attribute__((annotate()))`).
151 |
152 | **Note**: Please note that the 64bit relocations are not yet stable and
153 | therefore, subject to change.
154 |
155 | [varuint32]: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#varuintn
156 | [varuint64]: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#varuintn
157 | [varint32]: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#varintn
158 | [varint64]: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#varintn
159 | [uint32]: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#uintn
160 | [uint64]: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#uintn
161 |
162 | For `R_WASM_MEMORY_ADDR_*`, `R_WASM_FUNCTION_OFFSET_I32`, and
163 | `R_WASM_SECTION_OFFSET_I32` relocations (and their 64-bit counterparts) the
164 | following field is additionally present:
165 |
166 | | Field | Type | Description |
167 | | ------ | ---------------- | ----------------------------------- |
168 | | addend | `varint32` | addend to add to the address |
169 |
170 | Note that for all relocation types, the bytes being relocated:
171 | * from `offset` to `offset + 5` for LEB/SLEB relocations;
172 | * from `offset` to `offset + 10` for LEB64/SLEB64 relocations;
173 | * from `offset` to `offset + 4` for I32 relocations;
174 | * or from `offset` to `offset + 8` for I64;
175 |
176 | must lie within the section to which the relocation applies (as offsets are relative
177 | to the section's contents, this means that they cannot be too large). In addition,
178 | the bytes being relocated may not overlap the boundary between the section's chunks,
179 | where such a distinction exists (it may not for custom sections). For example, for
180 | relocations applied to the CODE section, a relocation cannot straddle two
181 | functions, and for the DATA section relocations must lie within a data element's
182 | body.
183 |
184 | ## Linking Metadata Section
185 |
186 | A linking metadata section is a user-defined section with the name
187 | "linking".
188 |
189 | The "linking" custom section must be after the [data
190 | section](https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#data-section)
191 | in order to validate data symbols.
192 |
193 | A linking metadata section begins with a version number which is then followed
194 | by a series of sub-sections laid out in the same way as the ["names"][names_sec]
195 | section:
196 |
197 | | Field | Type | Description |
198 | | ----------- | ------------- | ------------------------------------ |
199 | | version | `varuint32` | the version of linking metadata contained in this section. Currently: 2 |
200 | | subsections | `subsection*` | sequence of `subsection` |
201 |
202 | This `version` allows for breaking changes to be made to the format described
203 | here. Tools can then choose to reject inputs containing unexpected versions.
204 |
205 | Each `subsection` is encoded as:
206 |
207 | | Field | Type | Description |
208 | | ------------ | ----------- | ------------------------------------ |
209 | | type | `uint8` | code identifying type of subsection |
210 | | payload_len | `varuint32` | size of this subsection in bytes |
211 | | payload_data | `bytes` | content of this subsection, of length `payload_len` |
212 |
213 | The current list of valid `type` codes are:
214 |
215 | - `5 / WASM_SEGMENT_INFO` - Extra metadata about the data segments.
216 |
217 | - `6 / WASM_INIT_FUNCS` - Specifies a list of constructor functions to be called
218 | at startup. These constructors will be called in priority order after memory
219 | has been initialized.
220 |
221 | - `7 / WASM_COMDAT_INFO` - Specifies the COMDAT groups of associated linking
222 | objects, which are linked only once and all together.
223 |
224 | - `8 / WASM_SYMBOL_TABLE` - Specifies extra information about the symbols present
225 | in the module.
226 |
227 | ### Segment Info Subsection
228 |
229 | For `WASM_SEGMENT_INFO` the following fields are present in the
230 | subsection:
231 |
232 | | Field | Type | Description |
233 | | ----------- | ------------ | -------------------------------- |
234 | | count | `varuint32` | number of `segment` in segments |
235 | | segments | `segment*` | sequence of `segment` |
236 |
237 | where a `segment` is encoded as:
238 |
239 | | Field | Type | Description |
240 | | ------------ | ------------ | --------------------------------------------- |
241 | | name_len | `varuint32` | length of `name_data` in bytes |
242 | | name_data | `bytes` | UTF-8 encoding of the segment's name |
243 | | alignment | `varuint32` | The required alignment of the segment, encoded as a power of 2 |
244 | | flags | `varuint32` | a bitfield containing flags for this segment |
245 |
246 | The current set of valid flag for segments are:
247 | - `1 / WASM_SEGMENT_FLAG_STRINGS` - Signals that the segment contains only null terminated strings allowing the linker to perform merging.
248 | - `2 / WASM_SEGMENT_FLAG_TLS` - The segment contains thread-local data. This means that a unique copy of this segment will be created for each thread.
249 | - `4 / WASM_SEG_FLAG_RETAIN` - If the object file is included in the final link, the segment should be retained in the final output regardless of whether it is used by the program.
250 |
251 | ### Init Functions Subsection
252 |
253 | For `WASM_INIT_FUNCS` the following fields are present in the
254 | subsection:
255 |
256 | | Field | Type | Description |
257 | | ----------- | ------------ | ------------------------------------- |
258 | | count | `varuint32` | number of init functions that follow |
259 | | functions | `init_func*` | sequence of `init_func` |
260 |
261 | where an `init_func` is encoded as:
262 |
263 | | Field | Type | Description |
264 | | ------------ | ----------- | ------------------------------------------------------------ |
265 | | priority | `varuint32` | priority of the init function |
266 | | symbol_index | `varuint32` | the symbol index of init function (*not* the function index) |
267 |
268 | The `WASM_INIT_FUNC` subsection must come after the `WASM_SYMBOL_TABLE` subsection.
269 |
270 | ### Symbol Table Subsection
271 |
272 | For `WASM_SYMBOL_TABLE` the following fields are present in the
273 | subsection:
274 |
275 | | Field | Type | Description |
276 | | ------ | --------------- | ---------------------------- |
277 | | count | `varuint32` | number of `syminfo` in infos |
278 | | infos | `syminfo*` | sequence of `syminfo` |
279 |
280 | where a `syminfo` is encoded as:
281 |
282 | | Field | Type | Description |
283 | | ------------ | -------------- | ------------------------------------------- |
284 | | kind | `uint8` | The symbol type. One of: |
285 | | | | `0 / SYMTAB_FUNCTION` |
286 | | | | `1 / SYMTAB_DATA` |
287 | | | | `2 / SYMTAB_GLOBAL` |
288 | | | | `3 / SYMTAB_SECTION` |
289 | | | | `4 / SYMTAB_EVENT` |
290 | | | | `5 / SYMTAB_TABLE` |
291 | | flags | `varuint32` | a bitfield containing flags for this symbol |
292 |
293 | For functions, globals, events and tables, we reference an existing Wasm object, which
294 | is either an import or a defined function/global/event/table (recall that the operand of a
295 | Wasm `call` instruction uses an index space consisting of the function imports
296 | followed by the defined functions, and similarly `get_global` for global imports
297 | and definitions and `throw` for event imports and definitions).
298 |
299 | If a symbols refers to an import, and the
300 | `WASM_SYM_EXPLICIT_NAME` flag is not set, then the name is taken from the
301 | import; otherwise the `syminfo` specifies the symbol's name.
302 |
303 | | Field | Type | Description |
304 | | ------------ | -------------- | ------------------------------------------- |
305 | | index | `varuint32` | the index of the Wasm object corresponding to the symbol, which references an import if and only if the `WASM_SYM_UNDEFINED` flag is set |
306 | | name_len | `varuint32` ? | the optional length of `name_data` in bytes, omitted if `index` references an import |
307 | | name_data | `bytes` ? | UTF-8 encoding of the symbol name, omitted if `index` references an import |
308 |
309 | For data symbols:
310 |
311 | | Field | Type | Description |
312 | | ------------ | -------------- | ------------------------------------------- |
313 | | name_len | `varuint32` | the length of `name_data` in bytes |
314 | | name_data | `bytes` | UTF-8 encoding of the symbol name |
315 | | index | `varuint32` ? | the index of the data segment; provided if the symbol is defined |
316 | | offset | `varuint32` ? | the offset within the segment; provided if the symbol is defined; must be <= the segment's size |
317 | | size | `varuint32` ? | the size (which can be zero); provided if the symbol is defined; `offset + size` must be <= the segment's size |
318 |
319 | For section symbols:
320 |
321 | | Field | Type | Description |
322 | | ------------ | -------------- | ------------------------------------------- |
323 | | section | `varuint32` | the index of the target section |
324 |
325 | The current set of valid flags for symbols are:
326 |
327 | - `1 / WASM_SYM_BINDING_WEAK` - Indicating that this is a weak symbol. When
328 | linking multiple modules defining the same symbol, all weak definitions are
329 | discarded if any strong definitions exist; then if multiple weak definitions
330 | exist all but one (unspecified) are discarded; and finally it is an error if
331 | more than one definition remains.
332 | - `2 / WASM_SYM_BINDING_LOCAL` - Indicating that this is a local symbol (this
333 | is exclusive with `WASM_SYM_BINDING_WEAK`). Local symbols are not to be
334 | exported, or linked to other modules/sections. The names of all non-local
335 | symbols must be unique, but the names of local symbols are not considered for
336 | uniqueness. A local function or global symbol cannot reference an import.
337 | - `4 / WASM_SYM_VISIBILITY_HIDDEN` - Indicating that this is a hidden symbol.
338 | Hidden symbols are not to be exported when performing the final link, but
339 | may be linked to other modules.
340 | - `0x10 / WASM_SYM_UNDEFINED` - Indicating that this symbol is not defined.
341 | For non-data symbols, this must match whether the symbol is an import
342 | or is defined; for data symbols, determines whether a segment is specified.
343 | - `0x20 / WASM_SYM_EXPORTED` - The symbol is intended to be exported from the
344 | wasm module to the host environment. This differs from the visibility flags
345 | in that it effects the static linker.
346 | - `0x40 / WASM_SYM_EXPLICIT_NAME` - The symbol uses an explicit symbol name,
347 | rather than reusing the name from a wasm import. This allows it to remap
348 | imports from foreign WebAssembly modules into local symbols with different
349 | names.
350 | - `0x80 / WASM_SYM_NO_STRIP` - The symbol is intended to be included in the
351 | linker output, regardless of whether it is used by the program.
352 | - `0x100 / WASM_SYM_TLS` - The symbol resides in thread local storage.
353 | - `0x200 / WASM_SYM_ABSOLUTE` - The symbol represents an absolute address. This
354 | means it's offset is relative to the start of the wasm memory as opposed to
355 | being relative to a data segment.
356 |
357 | ### COMDAT Info Subsection
358 |
359 | For `WASM_COMDAT_INFO` the following fields are present in the
360 | subsection:
361 |
362 | | Field | Type | Description |
363 | | ------- | ----------- | ---------------------------------------------- |
364 | | count | `varuint32` | Number of `Comdat` in `comdats` |
365 | | comdats | `comdat*` | Sequence of `Comdat`
366 |
367 | where a `comdat` is encoded as:
368 |
369 | | Field | Type | Description |
370 | | ----------- | ------------- | ----------------------------------------- |
371 | | name_len | `varuint32` | length of `name_str` in bytes |
372 | | name_str | `bytes` | UTF-8 encoding of the name |
373 | | flags | `varuint32` | Must be zero, no flags currently defined |
374 | | count | `varuint32` | Number of `comdat_sym` in `comdat_syms` |
375 | | comdat_syms | `comdat_sym*` | Sequence of `comdat_sym` |
376 |
377 | and where a `comdat_sym` is encoded as:
378 |
379 | | Field | Type | Description |
380 | | -------- | -------------- | ------------------------------------------- |
381 | | kind | `uint8` | Type of symbol, one of: |
382 | | | | * `0 / WASM_COMDAT_DATA`, a data segment |
383 | | | | * `1 / WASM_COMDAT_FUNCTION` |
384 | | | | * `2 / WASM_COMDAT_GLOBAL` |
385 | | | | * `3 / WASM_COMDAT_EVENT` |
386 | | | | * `4 / WASM_COMDAT_TABLE` |
387 | | | | * `5 / WASM_COMDAT_SECTION` |
388 | | index | `varuint32` | Index of the data segment/function/global/event/table in the Wasm module (depending on kind). The function/global/event/table must not be an import. |
389 |
390 | ## Target Features Section
391 |
392 | The target features section is an optional custom section with the name
393 | "target_features". The target features section must come after the
394 | ["producers"](./ProducersSection.md) section.
395 |
396 | The contents of the target features section is a vector of entries:
397 |
398 | | Field | Type | Description |
399 | | ------- | ------- | ---------------------------------------- |
400 | | prefix | `byte` | See below. |
401 | | feature | `bytes` | The name of the feature. Must be unique. |
402 |
403 | The recognized prefix bytes and their meanings are below. When the user does not
404 | supply a set of allowed features explicitly, the set of allowed features is
405 | taken to be the set of used features. Any feature not mentioned in an object's
406 | target features section is not used by that object, but is not necessarily
407 | prohibited in the final binary.
408 |
409 | | Prefix | Meaning |
410 | | ---------- | ------- |
411 | | 0x2b (`+`) | This object uses this feature, and the link fails if this feature is not in the allowed set. |
412 | | 0x2d (`-`) | This object does not use this feature, and the link fails if this feature is in the allowed set. |
413 |
414 | The generally accepted features are:
415 |
416 | 1. `atomics`
417 | 1. `bulk-memory`
418 | 1. `bulk-memory-opt`
419 | 1. `call-indirect-overlong`
420 | 1. `exception-handling`
421 | 1. `extended-const`
422 | 1. `memory64`
423 | 1. `multimemory`
424 | 1. `multivalue`
425 | 1. `mutable-globals`
426 | 1. `nontrapping-fptoint`
427 | 1. `reference-types`
428 | 1. `relaxed-simd`
429 | 1. `sign-ext`
430 | 1. `simd128`
431 | 1. `tail-call`
432 |
433 | These features generally correspond to feature proposals as standardized in the CG with two exceptions:
434 | `bulk-memory-opt` refers to the `memory.copy` and `memory.fill` operations (a subset of `bulk-memory`).
435 | `call-indirect-overlong` allows the table field of the `call_indirect` instruction to be encoded
436 | as an LEB (which allows multibyte "overlong" encodings of small integers); this is a subset of the
437 | `reference-types` proposal.
438 |
439 | ## Merging Global Sections
440 |
441 | Merging of the global sections requires the re-numbering of globals. This
442 | follows the normal rules for defining symbols: if two object files provide the
443 | same global symbol strongly, there is a link error; if two object files provide
444 | the symbol weakly, one is chosen.
445 |
446 | When creating non-relocatable output, the Wasm output shall have an import for
447 | each undefined strong symbol, and an export for each defined symbol with
448 | non-local linkage and non-hidden visibility.
449 |
450 | The linker may provide certain symbols itself, even if not defined by any
451 | object file. For example, the `__stack_pointer` symbol may be provided at
452 | link-time.
453 |
454 | ## Merging Event Sections
455 |
456 | Events are meant to represent various control-flow changing constructs of wasm.
457 | Currently, we have a
458 | [proposal](https://github.com/WebAssembly/exception-handling/blob/master/proposals/exception-handling/Exceptions.md)
459 | for one kind of events: exceptions, but the event section can be used to support
460 | other kinds of events in future as well. The event section is a list of declared
461 | events associated with the module.
462 |
463 | Merging of the event sections requires the re-numbering of events. This follows
464 | the normal rules for defining symbols: if two object files provide the same
465 | event symbol strongly, there is a link error; if two object files provide the
466 | symbol weakly, one is chosen.
467 |
468 | When creating non-relocatable output, the Wasm output shall have an import for
469 | each undefined strong symbol, and an export for each defined symbol with
470 | non-local linkage and non-hidden visibility.
471 |
472 | ## Merging Function Sections
473 |
474 | Merging of the function sections requires the re-numbering of functions. This
475 | requires modification to code sections at each location where a function
476 | index is embedded. There are currently two ways in which function indices are
477 | stored in the code section:
478 |
479 | 1. Immediate argument of the `call` instruction (calling a function)
480 | 2. Immediate argument of the `i32.const` instruction (taking the address of a
481 | function).
482 |
483 | The immediate argument of all such instructions are stored as padded LEB128 such
484 | that they can be rewritten without altering the size of the code section. For
485 | each such instruction a `R_WASM_FUNCTION_INDEX_LEB` or `R_WASM_TABLE_INDEX_SLEB`
486 | `reloc` entry is generated pointing to the offset of the immediate within the
487 | code section.
488 |
489 | The same technique applies for all function calls whether the function is
490 | imported or defined locally.
491 |
492 | When creating non-relocatable output, the Wasm output shall have an import for
493 | each undefined strong symbol, and an export for each defined symbol with
494 | non-local linkage and non-hidden visibility.
495 |
496 | ## Merging Data Sections
497 |
498 | Merging of data sections is performed by creating a new data section from the
499 | data segments in the object files. Data symbols (e.g. C/C+ globals) are
500 | represented in the object file as Wasm data segments with an associated data
501 | symbol, so each linked data symbol pulls its associated data segment into the
502 | linked output.
503 |
504 | Segments are merged according their type: segments with a common prefix such as
505 | `.data` or `.rodata` are merged into a single segment in the output data
506 | section. It is an error if this behavior would merge shared and unshared
507 | segments.
508 |
509 | The output data section is formed, essentially, by concatenating the data
510 | sections of the input files. Since the final location in linear memory of any
511 | given symbol is not known until link time, all references to data addresses with
512 | the code and data sections generate `R_WASM_MEMORY_ADDR_*` relocation entries,
513 | which reference a data symbol.
514 |
515 | Segments are linked as a whole, and a segment is either entirely included or
516 | excluded from the link.
517 |
518 | ## Merging Custom Sections
519 |
520 | Merging of custom sections is performed by concatenating all payloads for the
521 | customs sections with the same name. The section symbol will refer the resulting
522 | section, this means that the relocation entries addend that refer
523 | the referred custom section fields shall be adjusted to take new offset
524 | into account.
525 |
526 | ## COMDATs
527 |
528 | A COMDAT group may contain one or more functions, data segments, and/or custom sections.
529 | The linker will include all of these elements with a given group name from one object file,
530 | and will exclude any element with this group name from all other object files.
531 |
532 | ## Processing Relocations
533 |
534 | The final code and data sections are written out with relocations applied.
535 |
536 | `R_WASM_TYPE_INDEX_LEB` relocations cannot fail. The output Wasm file
537 | shall contain a newly-synthesised type section which contains entries for all
538 | functions and type relocations in the output.
539 | `R_WASM_TABLE_INDEX_*` relocations cannot fail. The output Wasm file shall
540 | contain a newly-synthesised table, which contains an entry for all defined or
541 | imported symbols referenced by table relocations. The output table elements
542 | shall begin at a non-zero offset within the table, so that a `call_indirect 0`
543 | instruction is guaranteed to fail. Finally, when processing table relocations
544 | for symbols which have neither an import nor a definition (namely,
545 | weakly-undefined function symbols), the value `0` is written out as the value
546 | of the relocation.
547 |
548 | `R_WASM_FUNCTION_INDEX_LEB` relocations may fail to be processed, in
549 | which case linking fails. This occurs if there is a weakly-undefined function
550 | symbol, in which case there is no legal value that can be written as the target
551 | of any `call` instruction. The frontend must generate calls to undefined weak
552 | symbols via a `call_indirect` instruction.
553 |
554 | `R_WASM_GLOBAL_INDEX_LEB` relocations may fail to be processed, in which
555 | case linking fails. This occurs if there is a weakly-undefined global symbol,
556 | in which case there is no legal value that can be written as the target of any
557 | `get_global` or `set_global` instruction. (This means the frontend must not
558 | generate weak globals which may not be defined; a definition or import must
559 | exist for all global symbols in the linked output.)
560 |
561 | `R_WASM_MEMORY_*` relocations cannot fail. The relocation's value is the offset
562 | within the linear memory of the symbol within the output segment, plus the
563 | symbol's addend. If the symbol is undefined (whether weak or strong), the value
564 | of the relocation shall be `0`.
565 |
566 | `R_WASM_FUNCTION_OFFSET_I32` relocations cannot fail. The values shall be
567 | adjusted to reflect new offsets in the code section.
568 |
569 | `R_WASM_SECTION_OFFSET_I32` relocation cannot fail. The values shall be
570 | adjusted to reflect new offsets in the combined sections.
571 |
572 | `R_WASM_EVENT_INDEX_LEB` relocations may fail to be processed, in which
573 | case linking fails. This occurs if there is a weakly-undefined event symbol, in
574 | which case there is no legal value that can be written as the target of any
575 | `throw` and `if_except` instruction. (This means the frontend must not generate
576 | weak events which may not be defined; a definition or import must exist for all
577 | event symbols in the linked output.)
578 |
579 | [names_sec]: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#name-section
580 |
581 | ## Start Section
582 |
583 | By default the static linker should not output a WebAssembly start
584 | section. Constructors are instead called from a synthetic function
585 | `__wasm_call_ctors` that the runtime and embedder should arrange to have called
586 | after instantiation. `__wasm_call_ctors` is not exported by default because it
587 | may be called by some other startup function defined by the runtime. For the
588 | embedder to call it directly it should be exported like any other function.
589 |
590 | Rationale: Use of the WebAssembly start function was considered for running
591 | static constructors and/or the main entry point to the program. However,
592 | running arbitrary code in the start section is currently problematic due to the
593 | fact the module exports not available to the embedder at the time when the start
594 | function runs. A common example is the module memory itself. If the code in
595 | the start function wants to transfer any data to the embedder (e.g. `printf`)
596 | this will not work as the embedded cannot yet access the modules memory. This
597 | extends to all embedder functions that might want to call back into the module.
598 |
599 | If some future version of the WebAssembly spec allows for module exports to be
600 | available during execution of the start function it will make sense to
601 | reconsider this.
602 |
603 | When shared memory is requested, a start function will be emitted to initialize
604 | memory as described below.
605 |
606 | ## Experimental Threading Support
607 |
608 | By default all atomics and TLS are currently lowered to WebAssembly MVP and
609 | threads are not supported. However, when enabled, llvm does support an
610 | exprimental multithreading ABI based on the WebAssembly threads proposal. These
611 | features are used to support threading in Emscripten.
612 |
613 | The next section describes compatibility between threading features and MVP, and
614 | the following sections describe shared memory and TLS implementation based on
615 | bulk memory and experimental threading support.
616 |
617 | ### Lowering Atomics and TLS to MVP
618 |
619 | MVP WebAssembly does not include support for atomic operations or the bulk
620 | memory operations necessary to implement thread-local storage. As a result, any
621 | atomics or TLS present at the source level must be lowered to non-atomic
622 | operations and normal storage when targeting MVP WebAssembly. This is safe as
623 | long as the resulting MVP object files are not used in a multi-threaded context.
624 |
625 | To enforce this safety guarantee, the linker will error out if a shared memory
626 | is requested but the `atomics` target feature is disallowed in the target
627 | features section of any input objects. The compiler is responsible for marking
628 | `atomics` disallowed and thereby preventing thread-unsafe linking if either
629 | atomic operations or TLS are stripped during compilation. If the compiler
630 | removes either one of atomic operations or TLS, the resulting object may only be
631 | used with a single thread with an unshared memory, so the other one should be
632 | removed as well.
633 |
634 | If `atomics` or `bulk-memory` is not available during compilation but the source
635 | does not contain atomic operations or TLS, then the result is a
636 | "thread-agnostic" object that neither uses nor disallows the `atomics` feature.
637 | Thread-agnostic objects can be safely linked with objects that do or do not use
638 | `atomics`, although not both at the same time.
639 |
640 | ### Shared Memory and Passive Segments
641 |
642 | When shared memory is enabled, all data segments will be emitted as [passive
643 | segments][passive_segments] to prevent each thread from reinitializing
644 | memory. In a web context, using active segments would cause memory to be
645 | reinitialized every time the module is instantiated on a new WebWorker as part
646 | of spawning a new thread. The `memory.init` instructions that initialize these
647 | passive segments and the `data.drop` instructions that mark them collectible
648 | will be emitted into a synthetic function `__wasm_init_memory` that is made the
649 | WebAssembly start function and called automatically on instantiation but is not
650 | exported. `__wasm_init_memory` shall perform any synchronization necessary to
651 | ensure that no thread returns from instantiation until memory has been fully
652 | initialized, even if a module is instantiated on multiple threads
653 | simultaneously. This synchronization may involve waiting, but waiting is
654 | disallowed in some Web contexts such as on the main thread or in Audio worklets.
655 | For instantiation to succeed on all threads, the embedder must guarantee for
656 | each thread in a context that disallows waiting that the thread either wins the
657 | race and becomes responsible for initializing memory or that it is initialized
658 | after memory has already been initialized[1]. To make the `memory.init` and
659 | `data.drop` instructions valid, a [DataCount section][datacount_section] will
660 | also be emitted.
661 |
662 | Note that `memory.init` and the DataCount section are features of the
663 | bulk-memory proposal, not the atomics proposal, so any engine that supports
664 | threads needs to support both of these proposals.
665 |
666 | [1] In LLVM 13 and earlier, embedders had to guarantee that threads on contexts
667 | that disallow waiting had to win the race to initialize memory. That meant that
668 | there could only be one such thread in the system.
669 |
670 | [passive_segments]: https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md#design
671 | [datacount_section]: https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md#datacount-section
672 |
673 | ### Thread Local Storage
674 |
675 | Currently, thread-local storage is only supported in the main WASM module
676 | and cannot be accessed outside of it. This corresponds to the ELF local
677 | exec TLS model.
678 |
679 | Additionally, thread local storage depends on bulk memory instructions, and
680 | therefore support depends on the bulk memory proposal.
681 |
682 | All thread local variables will be merged into one passive segment called
683 | `.tdata`. This section contains the starting values for all TLS variables.
684 | The thread local block of every thread will be initialized with this segment.
685 |
686 | In a threaded build, the linker will create:
687 |
688 | * an immutable global variable of type `i32` called `__tls_size`.
689 | Its value is the total size of the thread local block for the module,
690 | i.e. the sum of the sizes of all thread local variables plus padding.
691 | This value will be `0` if there are no thread-local variables.
692 | * an immutable global variable of type `i32` called `__tls_align`.
693 | Its value is the alignment requirement of the thread local block, in bytes,
694 | and will be a power of 2. The value will be `1` if there are no thread-local
695 | variables.
696 | * a mutable global `i32` called `__tls_base`, with a `i32.const 0` initializer.
697 | * a global function called `__wasm_init_tls` with signature `(i32) -> ()`.
698 |
699 | To initialize thread-local storage, a thread should do the equivalent of the
700 | following pseudo-code upon startup:
701 |
702 | (if (global.get __tls_size) (then
703 | (call __wasm_init_tls
704 | (call aligned_alloc
705 | (global.get __tls_align)
706 | (call roundUpToMultipleOf
707 | (global.get __tls_align)
708 | (global.get __tls_size))))))
709 |
710 | `__wasm_init_tls` takes a pointer argument containing the memory block to use
711 | as the thread local storage block of the current thread. It should do nothing if
712 | there are no thread-local variables. Otherwise, the memory block will be
713 | initialized with the passive segment `.tdata` via the `memory.init` instruction.
714 | It will then set `__tls_base` to the address of the memory block passed to
715 | `__wasm_init_tls`.
716 |
717 | Note that `__tls_size` is not necessarily a multiple of `__tls_align`. In order to
718 | use `aligned_alloc`, we must round the size up to be a multiple of `__tls_align`.
719 |
720 | The relocations for thread local variables shall resolve into offsets relative to
721 | the start of the TLS block. As such, adding the value of `__tls_base` yields the
722 | actual address of the variable. For example, a variable called `tls_var` would
723 | have its address computed as follows:
724 |
725 | (i32.add (global.get __tls_base) (i32.const tls_var))
726 |
727 | The variable can then be used as normal. Upon thread exit, the runtime should free
728 | the memory allocated for the TLS block.
729 |
730 | ### Limitations
731 |
732 | - There is currently no support for passive data segments. The relocation types
733 | necessary for referencing such segments (e.g. in `data.drop` or `memory.init`
734 | instruction) do not yet exist.
735 | - There is currently no support for table element segments, either active or
736 | passive.
737 |
--------------------------------------------------------------------------------
/ProducersSection.md:
--------------------------------------------------------------------------------
1 | # Producers Section
2 |
3 | The purpose of the producers section is to provide an optional,
4 | highly-structured record of all the distinct tools that were used to produce
5 | a given WebAssembly module. A primary purpose of this record is to allow
6 | broad analysis of toolchain usage in the wild, which can help inform both wasm
7 | producers and consumers.
8 |
9 | The producers section is a
10 | [custom section](https://webassembly.github.io/spec/core/binary/modules.html#custom-section)
11 | and thus has no semantic effects and can be stripped at any time.
12 | Since the producers section is relatively small, tools are encouraged to emit
13 | the section or include themselves in an existing section by default, keeping
14 | the producers section even in release builds.
15 |
16 | WebAssembly consumers should avoid using the producers section to derive
17 | optimization hints. To ensure portable performance, hints should be
18 | standardized in a separate custom section, probably in the core spec's
19 | [Custom Sections appendix](https://webassembly.github.io/spec/core/appendix/custom.html).
20 |
21 | An additional goal of the producers section is to provide a discrete, but
22 | easily-growable [list of known tools/languages](#known-list) for each
23 | record field. This avoids the skew that otherwise happens with unstructured
24 | strings. Unknown names do not invalidate an otherwise-valid producers section.
25 | However, wasm consumers may provide less accurate telemetry results for unknown
26 | names or even emit diagnostics encouraging the name to be put on the known list.
27 |
28 | Since version information is useful, but highly-variable, each field value
29 | is accompanied with a version string so that the name can remain stable
30 | over time without requiring frequent updates to the known list.
31 |
32 | ## Custom Section
33 |
34 | Custom section `name` field: `producers`
35 |
36 | The producers section may appear only once, and only after the
37 | [Name section](https://webassembly.github.io/spec/core/appendix/custom.html#name-section).
38 |
39 | The producers section contains a sequence of fields with unique names, where the
40 | end of the last field must coincide with the last byte of the producers section:
41 |
42 | | Field | Type | Description |
43 | | ----------- | ----------- | ----------- |
44 | | field_count | `varuint32` | number of fields that follow |
45 | | fields | `field*` | sequence of field_count `field` records |
46 |
47 | where a `field` is encoded as:
48 |
49 | | Field | Type | Description |
50 | | ----------------- | ---- | ----------- |
51 | | field_name | [name][name-ref] | name of this field |
52 | | field_value_count | `varuint32` | number of value strings that follow |
53 | | field_values | `versioned-name*` | sequence of field_value_count name-value pairs |
54 |
55 | where a `versioned-name` is encoded as:
56 |
57 | | Field | Type | Description |
58 | | ------- | ---- | ----------- |
59 | | name | [name][name-ref] | name of the language/tool |
60 | | version | [name][name-ref] | version of the language/tool |
61 |
62 | with the additional constraint that each field_name in the list must be unique
63 | and found in the first column of the following table, and each of a given field_name's
64 | field_values's name strings must be unique and found in the second column of
65 | the field_name's row.
66 |
67 | | field_name | field_value name strings |
68 | | -------------- | -------------------- |
69 | | `language` | [source language list](#source-languages) |
70 | | `processed-by` | [individual tool list](#individual-tools) |
71 | | `sdk` | [SDK list](#sdks) |
72 |
73 | [name-ref]: https://webassembly.github.io/spec/core/binary/values.html#names
74 |
75 | ## Known list
76 |
77 | The following lists contain all the known names for the fields listed above.
78 | **If your tool is not on this list and you'd like it to be, please submit a PR.**
79 |
80 | ### Source Languages
81 |
82 | It is possible for multiple source languages to be present in a single module
83 | when the output of multiple compiled languages are statically linked together.
84 |
85 | * `wat`
86 | * `C`
87 | * `C++`
88 | * `Rust`
89 | * `JavaScript`
90 |
91 | ### Individual Tools
92 |
93 | It is possible (and common) for multiple tools to be used in the overall
94 | pipeline that produces and optimizes a given wasm module.
95 |
96 | * `wabt`
97 | * `LLVM`
98 | * `clang`
99 | * `lld`
100 | * `Binaryen`
101 | * `rustc`
102 | * `wasm-bindgen`
103 | * `wasm-pack`
104 | * `webassemblyjs`
105 | * `wasm-snip`
106 | * `Javy`
107 |
108 | ### SDKs
109 |
110 | While an SDK is technically just another tool, the `sdk` field designates the
111 | top-level "thing" that the developer installs and interacts with directly to
112 | produce the wasm module.
113 |
114 | * `Emscripten`
115 | * `Webpack`
116 |
117 | ## Text format
118 |
119 | The text format for the `producers` custom section uses [annotations proposal]
120 | extension to the WebAssembly text format. The text format looks like:
121 |
122 | [annotations proposal]: https://github.com/WebAssembly/annotations
123 |
124 | ```wasm
125 | (module
126 | (@producers
127 | (processed-by "rustc" "1.78.0 (9b00956e5 2024-04-29)")
128 | (language "Rust" "1.78.0")
129 | )
130 | )
131 | ```
132 |
133 | The `(@producers ...)` structure must be placed directly within a `(module
134 | ...)` declaration. Within `@producers` there is a list of parenthesis-delimited
135 | fields. The three accepted fields correspond to the three possible `field_name`s
136 | above:
137 |
138 | * `(language ...)`
139 | * `(processed-by ...)`
140 | * `(sdk ...)`
141 |
142 | Each field takes two strings corresponding to the `name` and `version` fields of
143 | the `versioned-name` construction in the custom section. For example:
144 |
145 | ```wasm
146 | (module
147 | (@producers
148 | (language "C" "18.1.2")
149 | (processed-by "LLVM" "18.1.2")
150 | (sdk "Emscripten" "3.1.60")
151 | )
152 | )
153 | ```
154 |
155 | The three fields can be specified in any order and any number of times.
156 |
157 | ```wasm
158 | (module
159 | (@producers
160 | (sdk "Emscripten" "3.1.60")
161 | (processed-by "LLVM" "18.1.2")
162 | (language "C" "18.1.2")
163 | (processed-by "LLVM" "17.1.0")
164 | (language "Rust" "1.78.0")
165 | (processed-by "clang" "18.1.2")
166 | )
167 | )
168 | ```
169 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | WebAssembly Tool Conventions
2 | ============================
3 |
4 | This repository holds documents describing *conventions* useful for coordinating
5 | interoperability between wasm-related tools. This includes descriptions of
6 | intermediate file formats, conventions for mapping high-level language types,
7 | names, and abstraction features to WebAssembly types, identifiers, and
8 | implementations, and schemes for supporting debuggers or other tools.
9 |
10 | These conventions are not part of the WebAssembly standard, and are not required
11 | of WebAssembly-consuming implementations to execute WebAssembly code. Tools
12 | producing and working with WebAssembly in other ways also need not follow any of
13 | these conventions. They exist only to support tools that wish to interoperate
14 | with other tools at a higher abstraction level than just WebAssembly itself.
15 |
16 | These conventions are also not exclusive. There could be multiple conventions
17 | for a given language for a given purpose. There are natural benefits to
18 | interoperability, but there are many reasons where having more than one way to
19 | do things can also make sense in many circumstances.
20 |
--------------------------------------------------------------------------------
/SetjmpLongjmp.md:
--------------------------------------------------------------------------------
1 | # C setjmp/longjmp in WebAssembly
2 |
3 | ## Overview
4 |
5 | This document describes a convention to implement C setjmp/longjmp via
6 | [WebAssembly exception-handling proposal].
7 |
8 | This document also briefly mentions another convention based on JavaScript
9 | exceptions.
10 |
11 | [WebAssembly exception-handling proposal]: https://github.com/WebAssembly/exception-handling
12 |
13 | ## Runtime ABI
14 |
15 | ### Linear memory structures
16 |
17 | This convention uses a few structures on the WebAssembly linear memory.
18 |
19 | #### Reserved area in jmp_buf
20 |
21 | The first 6 words of C jmp_buf is reserved for the use by the runtime.
22 | ("words" here are C pointer types specified in the [C ABI].)
23 | It should have large enough alignment to store C pointers.
24 | The actual contents of this area are private to the runtime implementation.
25 |
26 | [C ABI]: BasicCABI.md
27 |
28 | ##### Notes about the size of reserved area in jmp_buf
29 |
30 | Emscripten has been using 6 `unsigned long`s. (`unsigned long [6]`)
31 |
32 | GCC and Clang uses `intptr_t [5]` for their [setjmp/longjmp builtins].
33 | It isn't relevant right now though, because LLVM's WebAssembly target
34 | doesn't provide these builtins.
35 |
36 | [setjmp/longjmp builtins]: https://gcc.gnu.org/onlinedocs/gcc/Nonlocal-Gotos.html
37 |
38 | #### __WasmLongjmpArgs
39 |
40 | An equivalent of the following structure is used to associate necessary
41 | data to the WebAssembly exception.
42 |
43 | ```c
44 | struct __WasmLongjmpArgs {
45 | void *env; // a pointer to jmp_buf
46 | int val;
47 | };
48 | ```
49 |
50 | The lifetime of this structure is rather short. It lives only during a
51 | single longjmp execution.
52 | A runtime can use a part of `jmp_buf` for this structure. It's also ok to use
53 | a separate thread-local storage to place this structure. A runtime without
54 | multi-threading support can simply place this structure in a global variable.
55 |
56 | ### Exception tag
57 |
58 | This convention uses a WebAssembly exception to perform a non-local jump
59 | for C `longjmp`.
60 |
61 | The exception is created with an exception tag named `__c_longjmp`.
62 | The name is used for both of [static linking](Linking.md) and
63 | [dynamic linking](DynamicLinking.md).
64 | The type of exception tag is `(param i32)`. (Or, `(param i64)` for [memory64])
65 | The parameter is the address of the `__WasmLongjmpArgs` structure on the
66 | linear memory.
67 |
68 | [memory64]: https://github.com/WebAssembly/memory64
69 |
70 | ### Functions
71 |
72 | ```c
73 | void __wasm_setjmp(jmp_buf env, uint32_t label, void *func_invocation_id);
74 | uint32_t __wasm_setjmp_test(jmp_buf env, void *func_invocation_id);
75 | void __wasm_longjmp(jmp_buf env, int val);
76 | ```
77 |
78 | `__wasm_setjmp` records the necessary data in the `env` so that it can be
79 | used by `__wasm_longjmp` later.
80 | `label` is a non-zero identifier to distinguish setjmp call-sites within
81 | the function. Note that a C function can contain multiple setjmp() calls.
82 | `func_invocation_id` is the identifier to distinguish invocations of this
83 | C function. Note that, when a C function which calls setjmp() is invoked
84 | recursively, setjmp/longjmp needs to distinguish them.
85 |
86 | `__wasm_setjmp_test` tests if the longjmp target belongs to the current
87 | function invocation. if it does, this function returns the `label` value
88 | saved by `__wasm_setjmp`. Otherwise, it returns 0.
89 |
90 | `__wasm_longjmp` is similar to C `longjmp`.
91 | If `val` is 0, it's `__wasm_longjmp`'s responsibility to convert it to 1.
92 | It performs a long jump by filling a `__WasmLongjmpArgs` structure and
93 | throwing an exception with its address. The exception is created with
94 | the `__c_longjmp` exception tag.
95 |
96 | ## Code conversion
97 |
98 | The C compiler detects `setjmp` and `longjmp` calls in a program and
99 | converts them into the corresponding WebAssembly exception-handling
100 | instructions and calls to the above mentioned runtime ABI.
101 |
102 | ### Functions calling setjmp()
103 |
104 | On the function entry, the compiler would generate the logic to create
105 | the identifier of this function invocation, typically by performing an
106 | equivalent of `alloca(1)`. Note that the alloca size is not important
107 | because the pointer is merely used as an identifier and never be dereferenced.
108 |
109 | Also, the compiler converts C `setjmp` calls to `__wasm_setjmp` calls.
110 |
111 | For each setjmp callsite, the compiler allocates non-zero identifier called
112 | "label". The label value passed to `__wasm_setjmp` is recorded by the
113 | runtime and returned by later `__wasm_setjmp_test` when processing a longjmp
114 | to the corresponding jmp_buf.
115 |
116 | Also, for code blocks which possibly call `longjmp` directly or indirectly,
117 | the compiler generates instructions to catch and process exceptions with
118 | the `__c_longjmp` exception tag accordingly.
119 |
120 | When catching the exception, the compiler-generated logic calls
121 | `__wasm_setjmp_test` to see if the exception is for this invocation
122 | of this function.
123 | If it is, `__wasm_setjmp_test` returns the non-zero label value recorded by
124 | the last `__wasm_setjmp` call for the jmp_buf. The compiler-generated logic
125 | can use the label value to pretend a return from the corresponding setjmp.
126 | Otherwise, `__wasm_setjmp_test` returns 0. In that case, the
127 | compiler-generated logic should rethrow the exception by calling
128 | `__wasm_longjmp` so that it can be eventually caught by the right function.
129 |
130 | For an example, a C function like this would be converted like
131 | the following pseudo code.
132 | ```c
133 | void f(void) {
134 | jmp_buf env;
135 | if (!setjmp(env)) {
136 | might_call_longjmp(env);
137 | }
138 | }
139 | ```
140 |
141 | ```wat
142 | $func_invocation_id = alloca(1)
143 |
144 | ;; 100 is a label generated by the compiler
145 | call $__wasm_setjmp($env, 100, $func_invocation_id)
146 |
147 | block
148 | block (result i32)
149 | try_table (catch $__c_longjmp 0)
150 | call $might_call_longjmp
151 | end
152 | ;; might_call_longjmp didn't call longjmp
153 | br 1
154 | end
155 | ;; might_call_longjmp called longjmp
156 | pop __WasmLongjmpArgs pointer from the operand stack
157 | $env = __WasmLongjmpArgs.env
158 | $val = __WasmLongjmpArgs.val
159 | $label = $__wasm_setjmp_test($env, $func_invocation_id)
160 | if ($label == 0) {
161 | ;; not for us. rethrow.
162 | call $__wasm_longjmp($env, $val)
163 | }
164 | ;; ours.
165 | ;; somehow jump to the block corresponding to the $label
166 | ...
167 | ...
168 | end
169 | ```
170 |
171 | ### Longjmp calls
172 |
173 | The compiler converts C `longjmp` calls to `__wasm_longjmp` calls.
174 |
175 | ## Dynamic-linking consideration
176 |
177 | In case of [dynamic-linking], it's the dynamic linker's responsibility
178 | to provide the exception tag for this convention with the name
179 | "env.__c_longjmp". Modules should import the tag so that cross-module
180 | longjmp works.
181 |
182 | [dynamic-linking]: DynamicLinking.md
183 |
184 | ## Emscripten JavaScript-based exceptions
185 |
186 | Emscripten has a mode to use JavaScript-based exceptions instead of
187 | WebAssembly exceptions. In that mode, `emscripten_longjmp` function,
188 | which throws a JavaScript exception, is used instead of `__wasm_longjmp`.
189 |
190 | ```c
191 | void emscripten_longjmp(uintptr_t env, int val);
192 | ```
193 |
194 | The compiler translates C function calls which possibly ends up with
195 | calling `longjmp` to indirect calls via a JavaScript wrapper which
196 | catches the JavaScript exception.
197 |
198 | ## Implementations
199 |
200 | * LLVM (19 and later) has a pass ([WebAssemblyLowerEmscriptenEHSjLj.cpp])
201 | to perform the convertion mentioned above. It can be enabled with the
202 | `-mllvm -wasm-enable-sjlj` option.
203 |
204 | Note: as of writing this, LLVM produces a bit older version of
205 | exception-handling instructions. (`try`, `delegate`, etc)
206 | binaryen has a conversion from the old instructions to the latest
207 | instructions. (`try_table` etc.)
208 |
209 | * Emscripten (3.1.57 or later) has the runtime support ([emscripten_setjmp.c])
210 | for the convention documented above.
211 |
212 | * wasi-libc has the runtime support ([wasi-libc rt.c]) for the convention
213 | documented above.
214 |
215 | [WebAssemblyLowerEmscriptenEHSjLj.cpp]: https://github.com/llvm/llvm-project/blob/70deb7bfe90af91c68454b70683fbe98feaea87d/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
216 |
217 | [emscripten_setjmp.c]: https://github.com/emscripten-core/emscripten/blob/7d66497d96cdcffa394ad67d87f7118137edf9ab/system/lib/compiler-rt/emscripten_setjmp.c
218 |
219 | [wasi-libc rt.c]: https://github.com/WebAssembly/wasi-libc/blob/d03829489904d38c624f6de9983190f1e5e7c9c5/libc-top-half/musl/src/setjmp/wasm32/rt.c
220 |
221 | ## Future directions
222 |
223 | * `__WasmLongjmpArgs` can be replaced with WebAssembly multivalue.
224 |
225 | * Or, alternatively, we can make `__wasm_setjmp_test` take the
226 | `__WasmLongjmpArgs` pointer so that we can drop the `__WasmLongjmpArgs`
227 | structure layout from the ABI.
228 |
229 | * It might be simpler for the complier-generated catching logic to rethrow
230 | the exception with the `rethrow`/`throw_ref` instruction instead of
231 | calling `__wasm_longjmp`. Or, it might be simpler to make
232 | `__wasm_setjmp_test` rethow the exception internally.
233 |
234 | * If/When WebAssembly exception gets more ubiquitous, we might want to move
235 | the runtime to compiler-rt.
236 |
--------------------------------------------------------------------------------
/Signatures.md:
--------------------------------------------------------------------------------
1 | # WebAssembly module signatures
2 |
3 | This document describes a digital signature format specifically designed for WebAssembly modules.
4 |
5 | It satisfies the following requirements:
6 |
7 | - Is is possible to verify a module before execution.
8 | - It is possible to add signed custom sections to an already signed module.
9 | - It is possible to verify a subset of the module sections, at predefined boundaries.
10 | - The entire module doesn't have to fit in memory in order for a signature to be verified.
11 | - Signatures can be embedded in a custom section, or provided separately ("detached signatures").
12 | - Multiple signatures and algorithms can be used to sign a single module.
13 | - Signing an entire module doesn't require the module to be modified.
14 |
15 | Signatures have no semantic effects. A runtime that doesn't support signatures can ignore them.
16 |
17 | Note: this is still a work in progress.
18 |
19 | ## Discussion venues
20 |
21 | The [WebAssembly Modules Signatures](https://github.com/wasm-signatures/design) repository is the main discussion venue for this project.
22 |
23 | We also hold bimonthly open meetings. See the above repository for details.
24 |
25 | ## Custom sections
26 |
27 | Two custom section types are required for this signature format:
28 |
29 | - Custom sections named `signature`, storing signature data, when this information is embedded in the module.
30 | - Custom sections named `signature_delimiter`, separating consecutive sections that can be signed and verified independently.
31 |
32 | Example structure of a module with an embedded signature and delimiters:
33 |
34 | | sections |
35 | | ----------------------------------------- |
36 | | signature |
37 | | part _(one or more consecutive sections)_ |
38 | | delimiter |
39 | | part _(one or more consecutive sections)_ |
40 | | delimiter |
41 | | ... |
42 | | part _(one or more consecutive sections)_ |
43 | | delimiter |
44 |
45 | ## Parts and delimiters
46 |
47 | A module can be split into one or more parts (one or more consecutive sections).
48 | Each part is followd by a delimiter. A delimiter is a custom section named `signature_delimiter`, containing a 16 byte random string.
49 |
50 | | sections |
51 | | ---------------------------------------------- |
52 | | `p1` = input part 1 _(one or more sections)_ |
53 | | `d1` = delimiter 1 |
54 | | `p2` = input part 2 _(one or more sections)_ |
55 | | `d2` = delimiter 2 |
56 | | ... |
57 | | `pn` = input part `n` _(one or more sections)_ |
58 | | `dn` = delimiter `n` |
59 |
60 | If a signature covers the entire module (i.e. there is only one part), the delimiter is optional.
61 |
62 | However, its absence prevents additional sections to be added and signed later.
63 |
64 | ## Signature data
65 |
66 | The signature data is a concatenation of the following:
67 |
68 | - An identifier representing the version of the specification the module was signed with.
69 | - An identifier representing the hash function whose output will be signed.
70 | - A sequence of hashes and their signatures.
71 |
72 | A hash is computed for all the parts to be signed:
73 |
74 | `hn = H(pn‖dn)`
75 |
76 | A signature is computed on the concatenation of these hashes:
77 |
78 | `hashes = h1 ‖ h2 ‖ … ‖ hn`
79 |
80 | `s = Sign(k, "wasmsig" ‖ spec_version ‖ hash_id ‖ hashes)`
81 |
82 | One or more signatures can be associated with `hashes`, allowing multiple parties to sign the same data.
83 |
84 | The signature data can either be stored in the payload of a custom section named `signature`, or provided separately.
85 |
86 | If embedded in a module, the section must be the first section of the module.
87 |
88 | The signature data contains a sequence of signatures, where the end of the last signature must coincide with the last byte of the data.
89 |
90 | | Field | Type | Description |
91 | | ------------------- | ----------- | --------------------------------------------- |
92 | | spec_version | `byte` | Specification version (`0x01`) |
93 | | hash_fn | `byte` | Hash function identifier (`0x01` for SHA-256) |
94 | | signed_hashes_count | `varuint32` | Number of signed hashes |
95 | | signed_hashes* | `byte` | Sequence of hashes and their signatures |
96 |
97 | where `signed_hashes` is encoded as:
98 |
99 | | Field | Type | Description |
100 | | --------------- | ------------ | ------------------------------------------------- |
101 | | hashes_count | `varuint32` | Number of the concatenated hashes in bytes |
102 | | hashes | `bytes` | Concatenated hashes of the signed sections |
103 | | signature_count | `varuint32` | Number of signatures |
104 | | signatures | `signature*` | Sequence of `signature_count` `signature` records |
105 |
106 | where a `signature` is encoded as:
107 |
108 | | Field | Type | Description |
109 | | ------------- | ----------- | ---------------------------------------------------------- |
110 | | key_id_len | `varuint32` | Public key identifier length in bytes (can be `0`) |
111 | | key_id | `bytes` | Public key identifier |
112 | | signature_id | `byte` | Signature algorithm identifier |
113 | | signature_len | `varuint32` | Signature length in bytes |
114 | | signature | `bytes` | Signature for `hashes` that can be verified using `key_id` |
115 |
116 | ## Signature verification algorithm for an entire module
117 |
118 | 1. Verify the presence of the signature section, extract the specification version, the hash function to use and the signatures.
119 | 2. Check that at least one of the signatures is valid for `hashes`. If not, return an error and stop.
120 | 3. Split `hashes` (included in the signature) into `h1 … hn`
121 | 4. Read the module, computing the hash of every `(pi, di)` tuple with `i ∈ {1 … n}`, immediately returning an error if the output doesn't match `hi`
122 | 5. Return an error if the number of the number of hashes doesn't match the number of parts.
123 |
124 | ## Partial signatures
125 |
126 | The above format is compatible with partial signatures, i.e. signatures ignoring one or more parts.
127 |
128 | In order to do so, a signer only includes hashes of relevant parts.
129 |
130 | ## Partial verification
131 |
132 | The format is compatible with partial verification, i.e. verification of an arbitrary subset of a module:
133 |
134 | 1. Verify the presence of the header, extract the specification version, the hash function to use and the signatures.
135 | 2. Check that at least one of the signatures is valid for `hashes`. If not, return an error and stop.
136 | 3. Split `hashes` (included in the signature) into `h1 … hm` with `m` being the last section to verify.
137 | 4. Read the module, computing the hash of the `(pi, di)` tuples to verify, immediately returning an error if the output doesn't match `hi`.
138 | 5. Return an error if the number of the number of hashes doesn't match the number of parts to verify.
139 |
140 | Notes:
141 |
142 | - Subset verification doesn't require additional signatures, as verification is always made using the full set `hashes`.
143 | - Verifiers don't learn any information about removed sections due to delimiters containing random bits.
144 |
145 | By default, partial signatures must be ignored by WebAssembly runtimes. An explicit configuration is required to accept a partially signed module.
146 |
147 | ## Equivalence between embedded and detached signatures
148 |
149 | Signatures can be embedded in a module, or detached, i.e. not stored in the module itself but provided separately.
150 |
151 | A detached signature is equivalent to the payload of a `signature` custom section.
152 |
153 | Given an existing signed module with an embedded signature, the signature can be detached by:
154 |
155 | - Copying the payload of the `signature` custom section
156 | - Removing the `signature` custom section.
157 |
158 | Reciprocally, a detached signature can be embedded by adding a `signature` custom section, whose payload is a copy of the detached signature.
159 |
160 | Implementations should accept signatures as an optional parameter. If this parameter is not defined, the signature is assumed to be embedded, but the verification function remains the same.
161 |
162 | ## Algorithms and identifiers
163 |
164 | Identifier for the current version of the specification: `0x01`
165 |
166 | A conformant implementation must include support for the following hash functions:
167 |
168 | | Function | Identifier |
169 | | -------- | ---------- |
170 | | SHA-256 | `0x01` |
171 |
172 | ## Signature algorithms and key serialization
173 |
174 | For interoperability purposes, a conformant implementation must include support for the following signature systems:
175 |
176 | - Ed25519 (RFC8032)
177 |
178 | Public and private keys must include the algorithm and parameters they were created for.
179 |
180 | | Key type | Serialized key size | Identifier |
181 | | ------------------ | ------------------- | ---------- |
182 | | Ed25519 public key | 1 + 32 bytes | `0x01` |
183 | | Ed25519 key pair | 1 + 64 bytes | `0x81` |
184 |
185 | Ed25519 algorithm identifier: `0x01`.
186 |
187 | Representation of Ed25519 keys:
188 |
189 | - Ed25519 public key:
190 |
191 | `0x01 ‖ public key (32 bytes)`
192 |
193 | - Ed25519 key pair:
194 |
195 | `0x81 ‖ secret key (32 bytes) ‖ public key (32 bytes)`
196 |
197 | Implementations may support additional signatures schemes and key encoding formats.
198 |
199 | ## Appendix A. Examples
200 |
201 | The following examples assume the following unsigned module structure as a common starting point:
202 |
203 | ```text
204 | 0: type section
205 | 1: import section
206 | 2: function section
207 | 3: table section
208 | 4: memory section
209 | 5: global section
210 | 6: export section
211 | 7: element section
212 | 8: code section
213 | 9: data section
214 | 10: custom section: [.debug_info]
215 | 11: custom section: [.debug_macinfo]
216 | 12: custom section: [.debug_loc]
217 | 13: custom section: [.debug_ranges]
218 | 14: custom section: [.debug_abbrev]
219 | 15: custom section: [.debug_line]
220 | 16: custom section: [.debug_str]
221 | 17: custom section: [name]
222 | 18: custom section: [producers]
223 | ```
224 |
225 | ### Signatures for the entire module.
226 |
227 | Signed module structure:
228 |
229 | ```text
230 | 0: custom section: [signature]
231 | 1: type section
232 | 2: import section
233 | 3: function section
234 | 4: table section
235 | 5: memory section
236 | 6: global section
237 | 7: export section
238 | 8: element section
239 | 9: code section
240 | 10: data section
241 | 11: custom section: [.debug_info]
242 | 12: custom section: [.debug_macinfo]
243 | 13: custom section: [.debug_loc]
244 | 14: custom section: [.debug_ranges]
245 | 15: custom section: [.debug_abbrev]
246 | 16: custom section: [.debug_line]
247 | 17: custom section: [.debug_str]
248 | 18: custom section: [name]
249 | 19: custom section: [producers]
250 | 20: custom section: [signature_delimiter]
251 | ```
252 |
253 | Content of the signature section, for a single signature:
254 |
255 | - `0x01` (spec_version)
256 | - `0x01` (hash_fn)
257 | - `1` (signed_hashes_count)
258 | - signed_hashes:
259 | - `1` (hashes_count)
260 | - `<32 bytes>` (hashes=SHA-256(sections 1..end))
261 | - `1` (`signatures_count`)
262 | - signature:
263 | - `0` (`key_id_len` - no key ID)
264 | - `0x01` (Ed25519 algorithm identifier)
265 | - `64` (`signature_len`)
266 | - `<64 bytes>` (Ed22519(k, hashes))
267 |
268 | ### Signatures allowing partial verification.
269 |
270 | In this example, a signature can be verified for any of the following ranges of sections:
271 |
272 | - 1..10 (until the custom sections)
273 | - 1..17 (code, data and debugging information)
274 | - 1..end (entire module)
275 |
276 | ```text
277 | 0: custom section: [signature]
278 | 1: type section
279 | 2: import section
280 | 3: function section
281 | 4: table section
282 | 5: memory section
283 | 6: global section
284 | 7: export section
285 | 8: element section
286 | 9: code section
287 | 10: data section
288 | 11: custom section: [signature_delimiter]
289 | 12: custom section: [.debug_info]
290 | 13: custom section: [.debug_macinfo]
291 | 14: custom section: [.debug_loc]
292 | 15: custom section: [.debug_ranges]
293 | 16: custom section: [.debug_abbrev]
294 | 17: custom section: [.debug_line]
295 | 18: custom section: [.debug_str]
296 | 19: custom section: [signature_delimiter]
297 | 20: custom section: [name]
298 | 21: custom section: [producers]
299 | 22: custom section: [signature_delimiter]
300 | ```
301 |
302 | Content of the signature section, for a single signature:
303 |
304 | - `0x01` (spec_version)
305 | - `0x01` (hash_fn)
306 | - `1` (signed_hashes_count)
307 | - signed_hashes:
308 | - `3` (hashes_count)
309 | - `<96 bytes>` (hashes=SHA-256(sections 1..12) ‖ SHA-256(sections 1..20) ‖ SHA-256(sections 1..end))
310 | - `1` (signatures_count)
311 | - signature:
312 | - `0` (key_id_len - no key ID)
313 | - `0x01` (Ed25519 algorithm identifier)
314 | - `64` (signature_len)
315 | - `<64 bytes>` (Ed22519(k, hashes))
316 |
317 | Variant with two signatures for the same content and key identifiers:
318 |
319 | - `0x01` (spec_version)
320 | - `0x01` (hash_fn)
321 | - `1` (signed_hashes_count)
322 | - signed_hashes:
323 | - `3` (hashes_count)
324 | - `<96 bytes>` (hashes=SHA-256(sections 1..12) ‖ SHA-256(sections 1..20) ‖ SHA-256(sections 1..end))
325 | - `2` (signatures_count)
326 | - signature_1:
327 | - `5` (key_id_len)
328 | - `"first"` (key_id)
329 | - `0x01` (Ed25519 algorithm identifier)
330 | - `64` (`signature_len`)
331 | - `<64 bytes>` (Ed22519(k_first, hashes))
332 | - signature_2:
333 | - `6` (key_id_len)
334 | - `"second"` (key_id)
335 | - `0x01` (Ed25519 identifier)
336 | - `64` (`signature_len`)
337 | - `<64 bytes>` (Ed22519(k_second, hashes))
338 |
--------------------------------------------------------------------------------
/SwiftABI.md:
--------------------------------------------------------------------------------
1 | This document describes the Swift ABI for WebAssembly. As mentioned in README, it's not the only possible Swift ABI. It is the ABI that the clang/LLVM WebAssembly backend is currently using, and any other Swift compiler wishing to be ABI-compatible with it.
2 |
3 | Most parts of the ABI follow [the Swift ABI document in the official compiler repository](https://github.com/apple/swift/tree/master/docs/ABI)
4 |
5 | This document only describes what is necessary to be treated specially on WebAssembly.
6 |
7 | ## Swift Calling Convention
8 |
9 | Swift calling convention (`swiftcc` attribute in LLVM) is based on C calling convention as described [here](https://github.com/apple/swift/blob/master/docs/ABI/CallingConvention.rst)
10 |
11 | Swiftcc on WebAssembly is a little different from swiftcc on other architectures.
12 |
13 | On non-WebAssembly architectures, swiftcc accepts extra tail parameters that are attributed with swifterror or swiftself by a caller at the LLVM IR level and swifterror is always placed after swiftself. Even if the callee doesn't have these parameters at the LLVM IR level, the invocation succeeds by ignoring extra parameters.
14 |
15 | But WebAssembly strictly checks that [callee and caller signatures are the same](https://github.com/WebAssembly/design/blob/master/Semantics.md#calls).
16 | So at WebAssembly level, all swiftcc functions end up with extra arguments and all function definitions and invocations explicitly have additional tail parameters to fill swifterror and swiftself.
17 |
18 | For example, Swift global function `func foo(_ value: Int)` is lowered as `func (param i32 i32 i32)` at WebAssembly level.
19 |
20 | If you export swiftcc function and call it, you need the tail parameters. If the function did not have swiftself or swifterror at the IR level (and placeholders were added during lowering), then a placeholder may be passed any pointer size value. But if the embedding environment is JS, then missing params will be added as JS undefined and coerced to i32 as 0, so you don't need to fill them. This JS convention rule is documented at https://webassembly.github.io/spec/js-api/index.html
21 |
--------------------------------------------------------------------------------