|
| 1 | +#include <wasi/version.h> |
| 2 | + |
| 3 | +#ifdef __wasm_libcall_thread_context__ |
| 4 | +// The size, in bytes, of the stack statically allocated for `cabi_realloc`. |
| 5 | +// This doesn't need to be too big as it's just running `cabi_realloc` as defined |
| 6 | +// in wasi-libc. The current number is determined by: |
| 7 | +// |
| 8 | +// * Start with 16 bytes. |
| 9 | +// * Double until tests don't crash in a debug build. |
| 10 | +// * Double again. |
| 11 | +// |
| 12 | +// The goal is to be pretty modest since this is part of every module. |
| 13 | +#define REALLOC_STACK_SIZE 512 |
| 14 | + |
| 15 | +// Declare the `__wasm_{g,s}et_stack_pointer` functions. |
| 16 | +.functype __wasm_set_stack_pointer (i32) -> () |
| 17 | +.functype __wasm_get_stack_pointer () -> (i32) |
| 18 | +.type __wasm_set_stack_pointer,@function |
| 19 | +.type __wasm_get_stack_pointer,@function |
| 20 | +.functype __cabi_realloc_impl (i32, i32, i32, i32) -> (i32) |
| 21 | +.type __cabi_realloc_impl,@function |
| 22 | + |
| 23 | +// Go ahead and generate an `-fPIC`-compatible addressing mode for |
| 24 | +// `cabi_realloc_stack` so this is compatible with both PIC and not builds. |
| 25 | +.type __memory_base,@global |
| 26 | +.globaltype __memory_base, i32, immutable |
| 27 | + |
| 28 | +// For coop-threads builds we need to configure TLS to the initial TLS |
| 29 | +// value for all tasks/etc, so import those symbols here. |
| 30 | +#ifdef __wasi_cooperative_threads__ |
| 31 | +.functype __wasm_set_tls_base (i32) -> () |
| 32 | +.functype __wasm_get_tls_base () -> (i32) |
| 33 | +.type __wasm_set_tls_base,@function |
| 34 | +.type __wasm_get_tls_base,@function |
| 35 | +.type __init_tls_base,@global |
| 36 | +#ifdef __PIC__ |
| 37 | +.globaltype __init_tls_base, i32 |
| 38 | +#else |
| 39 | +.globaltype __init_tls_base, i32, immutable |
| 40 | +#endif |
| 41 | +#endif |
| 42 | + |
| 43 | +// This wrapper takes over the `cabi_realloc` symbol itself and the |
| 44 | +// `cabi_realloc` core module export. The C implementation it forwards to is |
| 45 | +// renamed to `__cabi_realloc_impl` by `cabi_realloc_augment.h`. |
| 46 | +// |
| 47 | +// Note that it's important that the symbol name matches the export name here. |
| 48 | +// In a `BUILD_SHARED=ON` build `libc.so` is dynamically linked against by other |
| 49 | +// shared libraries and by `crt1-{command,reactor}.o`, and the name a symbol is |
| 50 | +// resolved by in that context is its wasm export name. If `.export_name` were |
| 51 | +// used to rename the export then this function would be unresolvable by name |
| 52 | +// from anything linking against `libc.so`. |
| 53 | +.globl cabi_realloc |
| 54 | +.export_name cabi_realloc, "cabi_realloc" |
| 55 | +.type cabi_realloc,@function |
| 56 | +cabi_realloc: |
| 57 | + .functype cabi_realloc (i32, i32, i32, i32) -> (i32) |
| 58 | + |
| 59 | + // Prior to bytecodealliance/wasmtime#13949 wasmtime's handling of |
| 60 | + // `cabi_realloc` and context slots was a bit buggy. That means that prior |
| 61 | + // to that PR the slots aren't guaranteed to be 0 and the value present will |
| 62 | + // be used by some future task. This export is going to clobber these |
| 63 | + // slots, so while that Wasmtime change is percolating this preserves the |
| 64 | + // slots around the invocation of `cabi_realloc`. Once #13949 percolates and |
| 65 | + // ships then this workaround code, and the restore down below, can be |
| 66 | + // deleted. |
| 67 | + .local i32, i32 |
| 68 | + call __wasm_get_stack_pointer |
| 69 | + local.set 4 |
| 70 | +#ifdef __wasi_cooperative_threads__ |
| 71 | + call __wasm_get_tls_base |
| 72 | + local.set 5 |
| 73 | +#endif |
| 74 | + |
| 75 | + // First up, configure the stack pointer. Get the base of the stack from the |
| 76 | + // data symbol defined below, add the stack size, and that's what we're |
| 77 | + // starting with. |
| 78 | + i32.const cabi_realloc_stack@MBREL |
| 79 | + global.get __memory_base |
| 80 | + i32.add |
| 81 | + i32.const REALLOC_STACK_SIZE |
| 82 | + i32.add |
| 83 | + call __wasm_set_stack_pointer |
| 84 | + |
| 85 | + // Next up configure TLS. This is only required in coop-threads builds. |
| 86 | +#ifdef __wasi_cooperative_threads__ |
| 87 | + global.get __init_tls_base |
| 88 | + call __wasm_set_tls_base |
| 89 | +#endif |
| 90 | + |
| 91 | + // And finally forward to the actual implementation of `cabi_realloc` |
| 92 | + // defined in `wasip3.c` |
| 93 | + local.get 0 |
| 94 | + local.get 1 |
| 95 | + local.get 2 |
| 96 | + local.get 3 |
| 97 | + call __cabi_realloc_impl |
| 98 | + |
| 99 | + local.get 4 |
| 100 | + call __wasm_set_stack_pointer |
| 101 | +#ifdef __wasi_cooperative_threads__ |
| 102 | + local.get 5 |
| 103 | + call __wasm_set_tls_base |
| 104 | +#endif |
| 105 | + |
| 106 | + end_function |
| 107 | + |
| 108 | +// Define a data symbol which is the stack that `cabi_realloc` runs on. |
| 109 | +// Note that this is aligned to 16-bytes, the expected stack alignment. |
| 110 | +.type cabi_realloc_stack,@object |
| 111 | +.section .bss.cabi_realloc_stack,"",@ |
| 112 | +.p2align 4, 0x0 |
| 113 | +cabi_realloc_stack: |
| 114 | + .skip REALLOC_STACK_SIZE |
| 115 | + .size cabi_realloc_stack, REALLOC_STACK_SIZE |
| 116 | + |
| 117 | +#endif // __wasm_libcall_thread_context__ |
0 commit comments