1 // Platform support for Wasmtime's `no_std` build. 2 // 3 // This header file is what Wasmtime will rely on when it does not otherwise 4 // have support for the native platform. This can happen with `no_std` binaries 5 // for example where the traditional Unix-or-Windows implementation is not 6 // suitable. 7 // 8 // Embedders are expected to implement the symbols defined in this header file. 9 // These symbols can be defined either in C/C++ or in Rust (using 10 // `#[unsafe(no_mangle)]`). 11 // 12 // Note that there are some `#define`s here which can be added before this 13 // header file is included to indicate how Wasmtime was built. This corresponds 14 // to the `wasmtime` crate's Cargo features where if the feature is disabled 15 // then the symbols will not be required. 16 // 17 // * `WASMTIME_SIGNALS_BASED_TRAPS` - corresponds to `signals-based-traps` 18 // * `WASMTIME_CUSTOM_SYNC` - corresponds to `custom-sync-primitives` 19 // 20 // Some more information about this header can additionally be found at 21 // <https://docs.wasmtime.dev/stability-platform-support.html>. 22 23 24 #ifndef _WASMTIME_PLATFORM_H 25 #define _WASMTIME_PLATFORM_H 26 27 /* Generated with cbindgen:0.29.0 */ 28 29 #include <stdarg.h> 30 #include <stdbool.h> 31 #include <stdint.h> 32 #include <stdlib.h> 33 34 #if defined(WASMTIME_VIRTUAL_MEMORY) 35 /** 36 * Indicates that the memory region should be readable. 37 */ 38 #define WASMTIME_PROT_READ (1 << 0) 39 #endif 40 41 #if defined(WASMTIME_VIRTUAL_MEMORY) 42 /** 43 * Indicates that the memory region should be writable. 44 */ 45 #define WASMTIME_PROT_WRITE (1 << 1) 46 #endif 47 48 #if defined(WASMTIME_VIRTUAL_MEMORY) 49 /** 50 * Indicates that the memory region should be executable. 51 */ 52 #define WASMTIME_PROT_EXEC (1 << 2) 53 #endif 54 55 #if defined(WASMTIME_VIRTUAL_MEMORY) 56 /** 57 * Abstract pointer type used in the `wasmtime_memory_image_*` APIs which 58 * is defined by the embedder. 59 */ 60 typedef struct wasmtime_memory_image wasmtime_memory_image; 61 #endif 62 63 #if defined(WASMTIME_NATIVE_SIGNALS) 64 /** 65 * Handler function for traps in Wasmtime passed to `wasmtime_init_traps`. 66 * 67 * This function is invoked whenever a trap is caught by the system. For 68 * example this would be invoked during a signal handler on Linux. This 69 * function is passed a number of parameters indicating information about the 70 * trap: 71 * 72 * * `ip` - the instruction pointer at the time of the trap. 73 * * `fp` - the frame pointer register's value at the time of the trap. 74 * * `has_faulting_addr` - whether this trap is associated with an access 75 * violation (e.g. a segfault) meaning memory was accessed when it shouldn't 76 * be. If this is `true` then the next parameter is filled in. 77 * * `faulting_addr` - if `has_faulting_addr` is true then this is the address 78 * that was attempted to be accessed. Otherwise this value is not used. 79 * 80 * If this function returns then the trap was not handled by Wasmtime. This 81 * means that it's left up to the embedder how to deal with the trap/signal 82 * depending on its default behavior. This could mean forwarding to a 83 * non-Wasmtime handler, aborting the process, logging then crashing, etc. The 84 * meaning of a trap that's not handled by Wasmtime depends on the context in 85 * which the trap was generated. 86 * 87 * When this function does not return it's because a native exception handler 88 * was resumed to. 89 */ 90 typedef void (*wasmtime_trap_handler_t)(uintptr_t ip, 91 uintptr_t fp, 92 bool has_faulting_addr, 93 uintptr_t faulting_addr); 94 #endif 95 96 #ifdef __cplusplus 97 extern "C" { 98 #endif // __cplusplus 99 100 #if defined(WASMTIME_VIRTUAL_MEMORY) 101 /** 102 * Creates a new virtual memory mapping of the `size` specified with 103 * protection bits specified in `prot_flags`. 104 * 105 * Memory can be lazily committed. 106 * 107 * Stores the base pointer of the new mapping in `ret` on success. 108 * 109 * Returns 0 on success and an error code on failure. 110 * 111 * Similar to `mmap(0, size, prot_flags, MAP_PRIVATE, 0, -1)` on Linux. 112 */ 113 extern int32_t wasmtime_mmap_new(uintptr_t size, uint32_t prot_flags, uint8_t **ret); 114 #endif 115 116 #if defined(WASMTIME_VIRTUAL_MEMORY) 117 /** 118 * Remaps the virtual memory starting at `addr` going for `size` bytes to 119 * the protections specified with a new blank mapping. 120 * 121 * This will unmap any prior mappings and decommit them. New mappings for 122 * anonymous memory are used to replace these mappings and the new area 123 * should have the protection specified by `prot_flags`. 124 * 125 * Returns 0 on success and an error code on failure. 126 * 127 * Similar to `mmap(addr, size, prot_flags, MAP_PRIVATE | MAP_FIXED, 0, -1)` on Linux. 128 */ 129 extern int32_t wasmtime_mmap_remap(uint8_t *addr, uintptr_t size, uint32_t prot_flags); 130 #endif 131 132 #if defined(WASMTIME_VIRTUAL_MEMORY) 133 /** 134 * Unmaps memory at the specified `ptr` for `size` bytes. 135 * 136 * The memory should be discarded and decommitted and should generate a 137 * segfault if accessed after this function call. 138 * 139 * Returns 0 on success and an error code on failure. 140 * 141 * Similar to `munmap` on Linux. 142 */ 143 extern int32_t wasmtime_munmap(uint8_t *ptr, uintptr_t size); 144 #endif 145 146 #if defined(WASMTIME_VIRTUAL_MEMORY) 147 /** 148 * Configures the protections associated with a region of virtual memory 149 * starting at `ptr` and going to `size`. 150 * 151 * Returns 0 on success and an error code on failure. 152 * 153 * Similar to `mprotect` on Linux. 154 */ 155 extern int32_t wasmtime_mprotect(uint8_t *ptr, uintptr_t size, uint32_t prot_flags); 156 #endif 157 158 #if defined(WASMTIME_VIRTUAL_MEMORY) 159 /** 160 * Returns the page size, in bytes, of the current system. 161 */ 162 extern uintptr_t wasmtime_page_size(void); 163 #endif 164 165 #if defined(WASMTIME_NATIVE_SIGNALS) 166 /** 167 * Initializes trap-handling logic for this platform. 168 * 169 * Wasmtime's implementation of WebAssembly relies on the ability to catch 170 * signals/traps/etc. For example divide-by-zero may raise a machine 171 * exception. Out-of-bounds memory accesses may also raise a machine 172 * exception. This function is used to initialize trap handling. 173 * 174 * The `handler` provided is a function pointer to invoke whenever a trap 175 * is encountered. The `handler` is invoked whenever a trap is caught by 176 * the system. 177 * 178 * Returns 0 on success and an error code on failure. 179 */ 180 extern int32_t wasmtime_init_traps(wasmtime_trap_handler_t handler); 181 #endif 182 183 #if defined(WASMTIME_VIRTUAL_MEMORY) 184 /** 185 * Attempts to create a new in-memory image of the `ptr`/`len` combo which 186 * can be mapped to virtual addresses in the future. 187 * 188 * On success the returned `wasmtime_memory_image` pointer is stored into `ret`. 189 * This value stored can be `NULL` to indicate that an image cannot be 190 * created but no failure occurred. The structure otherwise will later be 191 * deallocated with `wasmtime_memory_image_free` and 192 * `wasmtime_memory_image_map_at` will be used to map the image into new 193 * regions of the address space. 194 * 195 * The `ptr` and `len` arguments are only valid for this function call, if 196 * the image needs to refer to them in the future then it must make a copy. 197 * 198 * Both `ptr` and `len` are guaranteed to be page-aligned. 199 * 200 * Returns 0 on success and an error code on failure. Note that storing 201 * `NULL` into `ret` is not considered a failure, and failure is used to 202 * indicate that something fatal has happened and Wasmtime will propagate 203 * the error upwards. 204 */ 205 extern int32_t wasmtime_memory_image_new(const uint8_t *ptr, 206 uintptr_t len, 207 struct wasmtime_memory_image **ret); 208 #endif 209 210 #if defined(WASMTIME_VIRTUAL_MEMORY) 211 /** 212 * Maps the `image` provided to the virtual address at `addr` and `len`. 213 * 214 * This semantically should make it such that `addr` and `len` looks the 215 * same as the contents of what the memory image was first created with. 216 * The mappings of `addr` should be private and changes do not reflect back 217 * to `wasmtime_memory_image`. 218 * 219 * In effect this is to create a copy-on-write mapping at `addr`/`len` 220 * pointing back to the memory used by the image originally. 221 * 222 * Note that the memory region will be unmapped with `wasmtime_munmap` in 223 * the future. 224 * 225 * Aborts the process on failure. 226 */ 227 extern int32_t wasmtime_memory_image_map_at(struct wasmtime_memory_image *image, 228 uint8_t *addr, 229 uintptr_t len); 230 #endif 231 232 #if defined(WASMTIME_VIRTUAL_MEMORY) 233 /** 234 * Deallocates the provided `wasmtime_memory_image`. 235 * 236 * Note that mappings created from this image are not guaranteed to be 237 * deallocated and/or unmapped before this is called. 238 */ 239 extern void wasmtime_memory_image_free(struct wasmtime_memory_image *image); 240 #endif 241 242 /** 243 * Wasmtime requires a single pointer's space of TLS to be used at runtime, 244 * and this function returns the current value of the TLS variable. 245 * 246 * This value should default to `NULL`. 247 */ 248 extern uint8_t *wasmtime_tls_get(void); 249 250 /** 251 * Sets the current TLS value for Wasmtime to the provided value. 252 * 253 * This value should be returned when later calling `wasmtime_tls_get`. 254 */ 255 extern void wasmtime_tls_set(uint8_t *ptr); 256 257 #if defined(WASMTIME_CUSTOM_SYNC) 258 /** 259 * Frees a synchronization lock. 260 * 261 * May be called on a lock that was never used (still has a zero pattern). 262 * The implementor must handle this case gracefully. 263 */ 264 extern void wasmtime_sync_lock_free(uintptr_t *lock); 265 #endif 266 267 #if defined(WASMTIME_CUSTOM_SYNC) 268 /** 269 * Acquires an exclusive lock. 270 * 271 * If the lock is uninitialized (zero pattern), it will be initialized lazily. 272 * This function blocks until the lock is acquired. 273 * Must be paired with [`wasmtime_sync_lock_release`]. 274 */ 275 extern void wasmtime_sync_lock_acquire(uintptr_t *lock); 276 #endif 277 278 #if defined(WASMTIME_CUSTOM_SYNC) 279 /** 280 * Releases an exclusive lock previously acquired with [`wasmtime_sync_lock_acquire`]. 281 */ 282 extern void wasmtime_sync_lock_release(uintptr_t *lock); 283 #endif 284 285 #if defined(WASMTIME_CUSTOM_SYNC) 286 /** 287 * Acquires a read lock on an RwLock. 288 * 289 * If the lock is uninitialized (zero pattern), it will be initialized lazily. 290 * Multiple readers can hold the lock simultaneously. 291 * Must be paired with [`wasmtime_sync_rwlock_read_release`]. 292 */ 293 extern void wasmtime_sync_rwlock_read(uintptr_t *lock); 294 #endif 295 296 #if defined(WASMTIME_CUSTOM_SYNC) 297 /** 298 * Releases a read lock previously acquired with [`wasmtime_sync_rwlock_read`]. 299 */ 300 extern void wasmtime_sync_rwlock_read_release(uintptr_t *lock); 301 #endif 302 303 #if defined(WASMTIME_CUSTOM_SYNC) 304 /** 305 * Acquires a write lock on an RwLock. 306 * 307 * If the lock is uninitialized (zero pattern), it will be initialized lazily. 308 * Only one writer can hold the lock, and no readers can be present. 309 * Must be paired with [`wasmtime_sync_rwlock_write_release`]. 310 */ 311 extern void wasmtime_sync_rwlock_write(uintptr_t *lock); 312 #endif 313 314 #if defined(WASMTIME_CUSTOM_SYNC) 315 /** 316 * Releases a write lock previously acquired with [`wasmtime_sync_rwlock_write`]. 317 */ 318 extern void wasmtime_sync_rwlock_write_release(uintptr_t *lock); 319 #endif 320 321 #if defined(WASMTIME_CUSTOM_SYNC) 322 /** 323 * Frees an RwLock. 324 * 325 * May be called on a lock that was never used (still has a zero pattern). 326 * The implementor must handle this case gracefully. 327 */ 328 extern void wasmtime_sync_rwlock_free(uintptr_t *lock); 329 #endif 330 331 #ifdef __cplusplus 332 } // extern "C" 333 #endif // __cplusplus 334 335 #endif /* _WASMTIME_PLATFORM_H */ 336