You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1166 lines
39 KiB
1166 lines
39 KiB
#include "current_sandbox.h"
|
|
#include "map.h"
|
|
#include "sandbox_set_as_running_sys.h"
|
|
#include "sandbox_set_as_running_user.h"
|
|
#include "sledge_abi.h"
|
|
#include "wasm_memory.h"
|
|
#include "wasi.h"
|
|
#include "wasi_serdes.h"
|
|
|
|
EXPORT void
|
|
sledge_abi__wasm_trap_raise(enum sledge_abi__wasm_trap trapno)
|
|
{
|
|
return current_sandbox_trap(trapno);
|
|
}
|
|
|
|
/**
|
|
* @brief Get the memory ptr for runtime object
|
|
*
|
|
* @param offset base offset of pointer
|
|
* @param length length starting at base offset
|
|
* @return host address of offset into WebAssembly linear memory
|
|
*/
|
|
static inline char *
|
|
get_memory_ptr_for_runtime(uint32_t offset, uint32_t length)
|
|
{
|
|
assert((uint64_t)offset + length < sledge_abi__current_wasm_module_instance.abi.memory.size);
|
|
char *mem_as_chars = (char *)sledge_abi__current_wasm_module_instance.abi.memory.buffer;
|
|
char *address = &mem_as_chars[offset];
|
|
return address;
|
|
}
|
|
|
|
static inline void
|
|
check_bounds(uint32_t offset, uint32_t bounds_check)
|
|
{
|
|
// Due to how we setup memory for x86, the virtual memory mechanism will catch the error, if bounds <
|
|
// WASM_PAGE_SIZE
|
|
assert(bounds_check < WASM_PAGE_SIZE
|
|
|| (sledge_abi__current_wasm_module_instance.abi.memory.size > bounds_check
|
|
&& offset <= sledge_abi__current_wasm_module_instance.abi.memory.size - bounds_check));
|
|
}
|
|
|
|
// TODO: Don't need to pass the memory here
|
|
EXPORT int32_t
|
|
sledge_abi__wasm_memory_expand(struct sledge_abi__wasm_memory *wasm_memory, uint32_t page_count)
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
int32_t old_page_count = wasm_memory->size / WASM_PAGE_SIZE;
|
|
int rc = wasm_memory_expand((struct wasm_memory *)wasm_memory, page_count * WASM_PAGE_SIZE);
|
|
|
|
if (unlikely(rc == -1)) {
|
|
old_page_count = -1;
|
|
goto DONE;
|
|
}
|
|
|
|
/* We updated "forked state" in sledge_abi__current_wasm_module_instance.memory. We need to write this back to
|
|
* the original struct as well */
|
|
current_sandbox_memory_writeback();
|
|
|
|
#ifdef LOG_SANDBOX_MEMORY_PROFILE
|
|
// Cache the runtime of the first N page allocations
|
|
for (int i = 0; i < page_count; i++) {
|
|
if (likely(sandbox->timestamp_of.page_allocations_size < SANDBOX_PAGE_ALLOCATION_TIMESTAMP_COUNT)) {
|
|
sandbox->timestamp_of.page_allocations[sandbox->timestamp_of.page_allocations_size++] =
|
|
sandbox->duration_of_state.running
|
|
+ (uint32_t)(__getcycles() - sandbox->timestamp_of.last_state_change);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
DONE:
|
|
sandbox_return(sandbox);
|
|
|
|
return old_page_count;
|
|
}
|
|
|
|
// TODO: Don't need to pass the memory here
|
|
EXPORT void
|
|
sledge_abi__wasm_memory_initialize_region(struct sledge_abi__wasm_memory *wasm_memory, uint32_t offset,
|
|
uint32_t region_size, uint8_t region[])
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
assert(sandbox->state == SANDBOX_RUNNING_SYS);
|
|
wasm_memory_initialize_region((struct wasm_memory *)wasm_memory, offset, region_size, region);
|
|
}
|
|
|
|
EXPORT int32_t
|
|
sledge_abi__wasm_globals_get_i32(uint32_t idx)
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
int32_t result;
|
|
int rc = wasm_globals_get_i32(&sandbox->globals, idx, &result);
|
|
sandbox_return(sandbox);
|
|
|
|
if (rc == -1) sledge_abi__wasm_trap_raise(WASM_TRAP_INVALID_INDEX);
|
|
if (rc == -2) sledge_abi__wasm_trap_raise(WASM_TRAP_MISMATCHED_TYPE);
|
|
|
|
return result;
|
|
}
|
|
|
|
EXPORT int64_t
|
|
sledge_abi__wasm_globals_get_i64(uint32_t idx)
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
int64_t result;
|
|
int rc = wasm_globals_get_i64(&sandbox->globals, idx, &result);
|
|
sandbox_return(sandbox);
|
|
|
|
if (rc == -1) sledge_abi__wasm_trap_raise(WASM_TRAP_INVALID_INDEX);
|
|
if (rc == -2) sledge_abi__wasm_trap_raise(WASM_TRAP_MISMATCHED_TYPE);
|
|
|
|
return result;
|
|
}
|
|
|
|
EXPORT void
|
|
sledge_abi__wasm_globals_set_i32(uint32_t idx, int32_t value, bool is_mutable)
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
int32_t rc = wasm_globals_set_i32(&sandbox->globals, idx, value, true);
|
|
sandbox_return(sandbox);
|
|
|
|
if (rc == -1) sledge_abi__wasm_trap_raise(WASM_TRAP_INVALID_INDEX);
|
|
if (rc == -2) sledge_abi__wasm_trap_raise(WASM_TRAP_MISMATCHED_TYPE);
|
|
}
|
|
|
|
// 0 on success, -1 on out of bounds, -2 on mismatched type
|
|
EXPORT void
|
|
sledge_abi__wasm_globals_set_i64(uint32_t idx, int64_t value, bool is_mutable)
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
int32_t rc = wasm_globals_set_i64(&sandbox->globals, idx, value, true);
|
|
sandbox_return(sandbox);
|
|
|
|
if (rc == -1) sledge_abi__wasm_trap_raise(WASM_TRAP_INVALID_INDEX);
|
|
if (rc == -2) sledge_abi__wasm_trap_raise(WASM_TRAP_MISMATCHED_TYPE);
|
|
}
|
|
|
|
/**
|
|
* @brief Writes argument offsets and buffer into linear memory
|
|
*
|
|
* @param argv_retoffset
|
|
* @param argv_buf_retoffset
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_args_get(__wasi_size_t argv_retoffset, __wasi_size_t argv_buf_retoffset)
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
|
|
__wasi_size_t rc = 0;
|
|
const __wasi_size_t argc = sandbox->wasi_context->argc;
|
|
if (unlikely(argc == 0)) { goto done; }
|
|
|
|
__wasi_size_t *argv_retptr = (__wasi_size_t *)get_memory_ptr_for_runtime(argv_retoffset,
|
|
WASI_SERDES_SIZE_size_t * argc);
|
|
const __wasi_size_t argv_buf_size = sandbox->wasi_context->argv_buf_size;
|
|
char *argv_buf_retptr = get_memory_ptr_for_runtime(argv_buf_retoffset, argv_buf_size);
|
|
|
|
/* args_get backings return a vector of host pointers. We need a host buffer to store this
|
|
* temporarily before unswizzling and writing to linear memory */
|
|
char **argv_temp = calloc(argc, sizeof(char *));
|
|
if (unlikely(argv_temp == NULL)) { goto done; }
|
|
|
|
/* Writes argv_buf to linear memory and argv vector to our temporary buffer */
|
|
rc = wasi_snapshot_preview1_backing_args_get(sandbox->wasi_context, argv_temp, argv_buf_retptr);
|
|
|
|
|
|
if (unlikely(rc != __WASI_ERRNO_SUCCESS)) { goto done; }
|
|
|
|
/* Unswizzle argv */
|
|
for (int i = 0; i < argc; i++) {
|
|
argv_retptr[i] = argv_buf_retoffset + (uint32_t)(argv_temp[i] - argv_temp[0]);
|
|
}
|
|
|
|
done:
|
|
if (likely(argv_temp != NULL)) {
|
|
free(argv_temp);
|
|
argv_temp = NULL;
|
|
}
|
|
sandbox_return(sandbox);
|
|
|
|
return (uint32_t)rc;
|
|
}
|
|
|
|
/**
|
|
* @brief Used by a WASI module to determine the argument count and size of the requried
|
|
* argument buffer
|
|
*
|
|
* @param argc_retoffset linear memory offset where we should write argc
|
|
* @param argv_buf_len_retoffset linear memory offset where we should write the length of the args buffer
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_args_sizes_get(__wasi_size_t argc_retoffset, __wasi_size_t argv_buf_len_retoffset)
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
__wasi_size_t *argc_retptr = (__wasi_size_t *)get_memory_ptr_for_runtime(argc_retoffset,
|
|
WASI_SERDES_SIZE_size_t);
|
|
__wasi_size_t *argv_buf_len_retptr = (__wasi_size_t *)get_memory_ptr_for_runtime(argv_buf_len_retoffset,
|
|
WASI_SERDES_SIZE_size_t);
|
|
|
|
uint32_t rc = wasi_snapshot_preview1_backing_args_sizes_get(sandbox->wasi_context, argc_retptr,
|
|
argv_buf_len_retptr);
|
|
sandbox_return(sandbox);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* @brief Return the resolution of a clock
|
|
* Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks,
|
|
* return `errno::inval`.
|
|
*
|
|
* @param id The clock for which to return the resolution.
|
|
* @param resolution_retoffset - The resolution of the clock
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_clock_res_get(__wasi_clockid_t id, __wasi_size_t resolution_retoffset)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Return the time value of a clock
|
|
*
|
|
* @param clock_id The clock for which to return the time.
|
|
* @param precision The maximum lag (exclusive) that the returned time value may have, compared to its actual value.
|
|
* @param time_retoffset The time value of the clock.
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_clock_time_get(__wasi_clockid_t clock_id, __wasi_timestamp_t precision,
|
|
__wasi_size_t time_retoffset)
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
__wasi_timestamp_t *time_retptr = (__wasi_timestamp_t *)
|
|
get_memory_ptr_for_runtime(time_retoffset, WASI_SERDES_SIZE_timestamp_t);
|
|
|
|
uint32_t rc = wasi_snapshot_preview1_backing_clock_time_get(sandbox->wasi_context, clock_id, precision,
|
|
time_retptr);
|
|
sandbox_return(sandbox);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* Read environment variable data.
|
|
* The sizes of the buffers should match that returned by `environ_sizes_get`.
|
|
*
|
|
* @param environ_retoffset
|
|
* @param environ_buf_retoffset
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_environ_get(__wasi_size_t env_retoffset, __wasi_size_t env_buf_retoffset)
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
__wasi_errno_t rc = 0;
|
|
|
|
const __wasi_size_t envc = sandbox->wasi_context->envc;
|
|
if (envc == 0) { goto done; }
|
|
|
|
const __wasi_size_t env_buf_size = sandbox->wasi_context->env_buf_size;
|
|
assert(env_buf_size > envc);
|
|
|
|
/* wasi_snapshot_preview1_backing_environ_get returns a vector of host pointers. We write
|
|
* these results to environ_temp temporarily before converting to offsets and writing to
|
|
* linear memory. We could technically write this to linear memory and then do a "fix up,"
|
|
* but this would leak host information and constitue a security issue */
|
|
char **env_temp = calloc(envc, sizeof(char *));
|
|
if (unlikely(env_temp == NULL)) { goto done; }
|
|
|
|
__wasi_size_t *env_retptr = (__wasi_size_t *)get_memory_ptr_for_runtime(env_retoffset,
|
|
WASI_SERDES_SIZE_size_t * envc);
|
|
char *env_buf_retptr = get_memory_ptr_for_runtime(env_buf_retoffset, env_buf_size);
|
|
|
|
rc = wasi_snapshot_preview1_backing_environ_get(sandbox->wasi_context, env_temp, env_buf_retptr);
|
|
if (unlikely(rc != __WASI_ERRNO_SUCCESS)) { goto done; }
|
|
|
|
/* Unswizzle env and write to linear memory */
|
|
for (int i = 0; i < envc; i++) { env_retptr[i] = env_buf_retoffset + (uint32_t)(env_temp[i] - env_temp[0]); }
|
|
|
|
done:
|
|
if (likely(env_temp != NULL)) {
|
|
free(env_temp);
|
|
env_temp = NULL;
|
|
}
|
|
|
|
sandbox_return(sandbox);
|
|
return (uint32_t)rc;
|
|
}
|
|
|
|
/**
|
|
* Returns the number of environment variable arguments and the size of the environment variable data.
|
|
*
|
|
* @param envc_retoffset - the offset where the resulting number of environment variable arguments should be written
|
|
* @param env_buf_len_retoffset - the offset where the resulting size of the environment variable data should be
|
|
* written
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_environ_sizes_get(__wasi_size_t envc_retoffset, __wasi_size_t env_buf_len_retoffset)
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
__wasi_size_t *envc_retptr = (__wasi_size_t *)get_memory_ptr_for_runtime(envc_retoffset,
|
|
WASI_SERDES_SIZE_size_t);
|
|
__wasi_size_t *env_buf_len_retptr = (__wasi_size_t *)get_memory_ptr_for_runtime(env_buf_len_retoffset,
|
|
WASI_SERDES_SIZE_size_t);
|
|
|
|
uint32_t rc = wasi_snapshot_preview1_backing_environ_sizes_get(sandbox->wasi_context, envc_retptr,
|
|
env_buf_len_retptr);
|
|
|
|
sandbox_return(sandbox);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* Provide file advisory information on a file descriptor.
|
|
* Note: similar to `posix_fadvise` in POSIX
|
|
*
|
|
* @param fd
|
|
* @param file_offset The offset within the file to which the advisory applies.
|
|
* @param len The length of the region to which the advisory applies.
|
|
* @param advice
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_advise(__wasi_fd_t fd, __wasi_filesize_t file_offset, __wasi_filesize_t len,
|
|
uint32_t advice_extended)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Force the allocation of space in a file.
|
|
*
|
|
* @param fd
|
|
* @param offset The offset at which to start the allocation.
|
|
* @param len The length of the area that is allocated.
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_allocate(__wasi_fd_t fd, __wasi_filesize_t offset, __wasi_filesize_t len)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Close a file descriptor.
|
|
*
|
|
* @param fd
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_close(__wasi_fd_t fd)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Synchronize the data of a file to disk.
|
|
*
|
|
* @param fd
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_datasync(__wasi_fd_t fd)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the attributes of a file descriptor.
|
|
*
|
|
* @param fd
|
|
* @param fdstat_retoffset return param of resulting wasi_fdstat structure
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_fdstat_get(__wasi_fd_t fd, __wasi_size_t fdstat_retoffset)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Adjust the flags associated with a file descriptor
|
|
*
|
|
* @param fd
|
|
* @param fdflags_extended The desired values of the file descriptor flags, zero extended to 32-bits
|
|
* @return WASI_ESUCCESS, WASI_EACCES, WASI_EAGAIN, WASI_EBADF, WASI_EFAULT, WASI_EINVAL, WASI_ENOENT, or WASI_EPERM
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_fdstat_set_flags(__wasi_fd_t fd, uint32_t fdflags_extended)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Adjust the rights associated with a file descriptor.
|
|
* This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add
|
|
* rights
|
|
*
|
|
* @param fd
|
|
* @param fs_rights_base The desired rights of the file descriptor.
|
|
* @param fs_rights_inheriting
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_fdstat_set_rights(__wasi_fd_t fd, __wasi_rights_t fs_rights_base,
|
|
__wasi_rights_t fs_rights_inheriting)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Return the attributes of an open file.
|
|
*
|
|
* @param fd
|
|
* @param filestat_retoffset The buffer where we should store the file's attributes
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_filestat_get(__wasi_fd_t fd, __wasi_size_t filestat_retoffset)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Adjust the size of an open file, zeroing extra bytes on increase
|
|
*
|
|
* @param fd
|
|
* @param size The desired file size.
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_filestat_set_size(__wasi_fd_t fd, __wasi_filesize_t size)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Adjust the timestamps of an open file or directory
|
|
*
|
|
* @param fd
|
|
* @param atim The desired values of the data access timestamp.
|
|
* @param mtim The desired values of the data modification timestamp.
|
|
* @param fstflags A bitmask indicating which timestamps to adjust.
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_filestat_set_times(__wasi_fd_t fd, __wasi_timestamp_t atim,
|
|
__wasi_timestamp_t mtim, uint32_t fstflags_extended)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Read from a file descriptor without updating the descriptor's offset
|
|
*
|
|
* @param fd
|
|
* @param iovs_baseoffset List of scatter/gather vectors in which to store data.
|
|
* @param iovs_len The length of the iovs vector
|
|
* @param offset The offset within the file at which to read.
|
|
* @param nread_retoffset The number of bytes read.
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_pread(__wasi_fd_t fd, __wasi_size_t iovs_baseoffset, __wasi_size_t iovs_len,
|
|
__wasi_filesize_t offset, __wasi_size_t nread_retoffset)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Return a description of the given preopened file descriptor.
|
|
*
|
|
* @param fd
|
|
* @param prestat_retoffset The buffer where the description is stored.
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_prestat_get(__wasi_fd_t fd, __wasi_size_t prestat_retoffset)
|
|
{
|
|
/* This signals that there are no file descriptors */
|
|
return __WASI_ERRNO_BADF;
|
|
}
|
|
|
|
/**
|
|
* Return a description of the given preopened file descriptor.
|
|
*
|
|
* @param fd
|
|
* @param dirname_retoffset A buffer into which to write the preopened directory name.
|
|
* @param dirname_len The length of the buffer at path_retptr
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_prestat_dir_name(__wasi_fd_t fd, __wasi_size_t dirname_retoffset,
|
|
__wasi_size_t dirname_len)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Write to a file descriptor without updating the descriptor's offset
|
|
*
|
|
* @param fd
|
|
* @param iovs_baseoffset List of scatter/gather vectors from which to retrieve data.
|
|
* @param iovs_len The length of the array pointed to by `iovs`.
|
|
* @param offset The offset within the file at which to write.
|
|
* @param nwritten_retoffset The number of bytes written.
|
|
* @return status code
|
|
*
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_pwrite(__wasi_fd_t fd, __wasi_size_t iovs_baseoffset, __wasi_size_t iovs_len,
|
|
__wasi_filesize_t file_offset, __wasi_size_t nwritten_retoffset)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Read from a file descriptor
|
|
*
|
|
* @param fd
|
|
* @param iovs_baseptr
|
|
* @param iovs_len
|
|
* @param nread_retoffset The number of bytes read.
|
|
* @return WASI_ESUCCESS, WASI_EAGAIN, WASI_EWOULDBLOCK, WASI_EBADF, WASI_EFAULT, WASI_EINTR, WASI_EIO, WASI_EISDIR, or
|
|
* others
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_read(__wasi_fd_t fd, __wasi_size_t iovs_baseoffset, __wasi_size_t iovs_len,
|
|
__wasi_size_t nread_retoffset)
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
__wasi_errno_t rc = 0;
|
|
__wasi_size_t *nread_retptr = (__wasi_size_t *)get_memory_ptr_for_runtime(nread_retoffset,
|
|
WASI_SERDES_SIZE_size_t);
|
|
|
|
/* Swizzle iovs, writting to temp buffer */
|
|
check_bounds(iovs_baseoffset, WASI_SERDES_SIZE_iovec_t * iovs_len);
|
|
__wasi_iovec_t *iovs_baseptr = calloc(iovs_len, sizeof(__wasi_iovec_t));
|
|
if (unlikely(iovs_baseptr == NULL)) { goto done; }
|
|
rc = wasi_serdes_readv_iovec_t(sandbox->memory->abi.buffer, sandbox->memory->abi.size, iovs_baseoffset,
|
|
iovs_baseptr, iovs_len);
|
|
if (unlikely(rc != __WASI_ERRNO_SUCCESS)) { goto done; }
|
|
|
|
rc = wasi_snapshot_preview1_backing_fd_read(sandbox->wasi_context, fd, iovs_baseptr, iovs_len, nread_retptr);
|
|
|
|
done:
|
|
if (likely(iovs_baseptr != NULL)) {
|
|
free(iovs_baseptr);
|
|
iovs_baseptr = NULL;
|
|
}
|
|
|
|
sandbox_return(sandbox);
|
|
return (uint32_t)rc;
|
|
}
|
|
|
|
/**
|
|
* Atomically replace a file descriptor by renumbering another file descriptor.
|
|
* Due to the strong focus on thread safety, this environment does not provide
|
|
* a mechanism to duplicate or renumber a file descriptor to an arbitrary
|
|
* number, like `dup2()`. This would be prone to race conditions, as an actual
|
|
* file descriptor with the same number could be allocated by a different
|
|
* thread at the same time.
|
|
* This function provides a way to atomically renumber file descriptors, which
|
|
* would disappear if `dup2()` were to be removed entirely.
|
|
*
|
|
* @param fd
|
|
* @param to the file descriptor to overwrite
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_readdir(__wasi_fd_t fd, __wasi_size_t buf_baseoffset, __wasi_size_t buf_len,
|
|
__wasi_dircookie_t cookie, __wasi_size_t nread_retoffset)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Atomically replace a file descriptor by renumbering another file descriptor.
|
|
* Due to the strong focus on thread safety, this environment does not provide
|
|
* a mechanism to duplicate or renumber a file descriptor to an arbitrary
|
|
* number, like `dup2()`. This would be prone to race conditions, as an actual
|
|
* file descriptor with the same number could be allocated by a different
|
|
* thread at the same time.
|
|
* This function provides a way to atomically renumber file descriptors, which
|
|
* would disappear if `dup2()` were to be removed entirely.
|
|
*
|
|
* @param fd
|
|
* @param to the file descriptor to overwrite
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_renumber(__wasi_fd_t fd, __wasi_fd_t to)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Move the offset of a file descriptor
|
|
*
|
|
* @param fd
|
|
* @param file_offset The number of bytes to move.
|
|
* @param whence_extended The base from which the offset is relative.
|
|
* @param newoffset_retoffset The new offset of the file descriptor, relative to the start of the file.
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_seek(__wasi_fd_t fd, __wasi_filedelta_t file_offset, uint32_t whence_extended,
|
|
__wasi_size_t newoffset_retoffset)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Synchronize the data and metadata of a file to disk
|
|
*
|
|
* @param fd
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_sync(__wasi_fd_t fd)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
|
|
/**
|
|
* Return the current offset of a file descriptor
|
|
*
|
|
* @param fd
|
|
* @param fileoffset_retoffset The current offset of the file descriptor, relative to the start of the file.
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_tell(__wasi_fd_t fd, __wasi_size_t fileoffset_retoffset)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Write to a file descriptor
|
|
*
|
|
* @param fd
|
|
* @param iovs_baseoffset List of scatter/gather vectors from which to retrieve data.
|
|
* @param iovs_len The length of the array pointed to by `iovs`.
|
|
* @param nwritten_retoffset
|
|
* @return WASI_ESUCCESS, WASI_EAGAIN, WASI_EWOULDBLOCK, WASI_EBADF, WASI_EFAULT,
|
|
* WASI_EFBIG, WASI_EINTR, WASI_EIO, WASI_ENOSPC, WASI_EPERM, WASI_EPIPE, or others
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_fd_write(__wasi_fd_t fd, __wasi_size_t iovs_baseoffset, __wasi_size_t iovs_len,
|
|
__wasi_size_t nwritten_retoffset)
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
__wasi_errno_t rc = 0;
|
|
__wasi_size_t *nwritten_retptr = (__wasi_size_t *)get_memory_ptr_for_runtime(nwritten_retoffset,
|
|
WASI_SERDES_SIZE_size_t);
|
|
|
|
/* Swizzle iovs, writting to temporary buffer */
|
|
check_bounds(iovs_baseoffset, WASI_SERDES_SIZE_ciovec_t * iovs_len);
|
|
__wasi_ciovec_t *iovs_baseptr = calloc(iovs_len, sizeof(__wasi_ciovec_t));
|
|
if (unlikely(iovs_baseptr == NULL)) { goto done; }
|
|
rc = wasi_serdes_readv_ciovec_t(sandbox->memory->abi.buffer, sandbox->memory->abi.size, iovs_baseoffset,
|
|
iovs_baseptr, iovs_len);
|
|
if (unlikely(rc != __WASI_ERRNO_SUCCESS)) { goto done; }
|
|
|
|
rc = wasi_snapshot_preview1_backing_fd_write(sandbox->wasi_context, fd, iovs_baseptr, iovs_len,
|
|
nwritten_retptr);
|
|
|
|
done:
|
|
sandbox_return(sandbox);
|
|
if (likely(iovs_baseptr != NULL)) {
|
|
free(iovs_baseptr);
|
|
iovs_baseptr = NULL;
|
|
}
|
|
|
|
return (uint32_t)rc;
|
|
}
|
|
|
|
/**
|
|
* Create a directory
|
|
*
|
|
* @param fd
|
|
* @param path_baseoffset
|
|
* @param path_len
|
|
* @return WASI_ESUCCESS, WASI_EACCES, WASI_EBADF, WASI_EDQUOT, WASI_EEXIST,
|
|
* WASI_EFAULT, WASI_EINVAL, WASI_ELOOP, WASI_EMLINK, WASI_ENAMETOOLONG,
|
|
* WASI_ENOENT, WASI_ENOMEM, WASI_ENOSPC, WASI_ENOTDIR, WASI_EPERM, or WASI_EROFS
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_path_create_directory(__wasi_fd_t fd, __wasi_size_t path_baseoffset,
|
|
__wasi_size_t path_len)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Return the attributes of a file or directory
|
|
*
|
|
* @param fd
|
|
* @param flags Flags determining the method of how the path is resolved.
|
|
* @param path_baseoffset The path of the file or directory to inspect.
|
|
* @param filestat_retoffset The buffer where the file's attributes are stored.
|
|
* @return WASI_ESUCCESS, WASI_EACCES, WASI_EBAD, WASI_EFAUL, WASI_EINVAL, WASI_ELOOP,
|
|
* WASI_ENAMETOOLON, WASI_ENOENT, WASI_ENOENT, WASI_ENOMEM, WASI_ENOTDI, or WASI_EOVERFLOW
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_path_filestat_get(__wasi_fd_t fd, __wasi_lookupflags_t flags,
|
|
__wasi_size_t path_baseoffset, __wasi_size_t path_len,
|
|
__wasi_size_t filestat_retoffset)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Adjust the timestamps of a file or directory
|
|
*
|
|
* @param fd
|
|
* @param flags Flags determining the method of how the path is resolved.
|
|
* @param path_baseoffset The path of the file or directory to operate on.
|
|
* @param path_len
|
|
* @param atim The desired values of the data access timestamp.
|
|
* @param mtim The desired values of the data modification timestamp.
|
|
* @param fstflags_extended A bitmask indicating which timestamps to adjust.
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_path_filestat_set_times(__wasi_fd_t fd, __wasi_lookupflags_t flags,
|
|
__wasi_size_t path_baseoffset, __wasi_size_t path_len,
|
|
__wasi_timestamp_t atim, __wasi_timestamp_t mtim,
|
|
uint32_t fstflags_extended)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Create a hard link
|
|
*
|
|
* @param old_fd
|
|
* @param old_flags Flags determining the method of how the path is resolved.
|
|
* @param old_path_baseoffset The source path from which to link.
|
|
* @param old_path_len
|
|
* @param new_fd The working directory at which the resolution of the new path starts.
|
|
* @param new_path_baseoffset The destination path at which to create the hard link.
|
|
* @param new_path_len
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_path_link(__wasi_fd_t old_fd, __wasi_lookupflags_t old_flags,
|
|
__wasi_size_t old_path_baseoffset, __wasi_size_t old_path_len,
|
|
__wasi_fd_t new_fd, __wasi_size_t new_path_baseoffset,
|
|
__wasi_size_t new_path_len)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Open a file or directory
|
|
* The returned file descriptor is not guaranteed to be the lowest-numbered
|
|
* file descriptor not currently open; it is randomized to prevent
|
|
* applications from depending on making assumptions about indexes, since this
|
|
* is error-prone in multi-threaded contexts. The returned file descriptor is
|
|
* guaranteed to be less than 2**31.
|
|
*
|
|
* @param dirfd
|
|
* @param lookupflags
|
|
* @param path_baseoffset
|
|
* @param path_len
|
|
* @param oflags
|
|
* @param fs_rights_base
|
|
* @param fs_rights_inheriting
|
|
* @param fdflags
|
|
* @param fd_retoffset The file descriptor of the file that has been opened.
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_path_open(__wasi_fd_t dirfd, __wasi_lookupflags_t lookupflags,
|
|
__wasi_size_t path_baseoffset, __wasi_size_t path_len,
|
|
uint32_t oflags_extended, __wasi_rights_t fs_rights_base,
|
|
__wasi_rights_t fs_rights_inheriting, uint32_t fdflags_extended,
|
|
__wasi_size_t fd_retoffset)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Remove a directory
|
|
* Return `errno::notempty` if the directory is not empty.
|
|
*
|
|
* @param fd
|
|
* @param path_baseoffset The path to a directory to remove.
|
|
* @param path_len
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_path_readlink(__wasi_fd_t fd, __wasi_size_t path_baseoffset, __wasi_size_t path_len,
|
|
__wasi_size_t buf_baseretoffset, __wasi_size_t buf_len,
|
|
__wasi_size_t nread_retoffset)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Remove a directory
|
|
* Return `errno::notempty` if the directory is not empty.
|
|
*
|
|
* @param fd
|
|
* @param path_baseoffset The path to a directory to remove.
|
|
* @param path_len
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_path_remove_directory(__wasi_fd_t fd, __wasi_size_t path_baseoffset,
|
|
__wasi_size_t path_len)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Rename a file or directory
|
|
*
|
|
* @param fd
|
|
* @param old_path The source path of the file or directory to rename.
|
|
* @param new_fd The working directory at which the resolution of the new path starts.
|
|
* @param new_path The destination path to which to rename the file or directory.
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_path_rename(__wasi_fd_t fd, __wasi_size_t old_path_baseoffset,
|
|
__wasi_size_t old_path_len, __wasi_fd_t new_fd,
|
|
__wasi_size_t new_path_baseoffset, __wasi_size_t new_path_len)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Create a symbolic link
|
|
*
|
|
* @param old_path_baseoffset The contents of the symbolic link.
|
|
* @param old_path_len
|
|
* @param fd
|
|
* @param new_path_baseoffset The path where we want the symbolic link.
|
|
* @param new_path_len
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_path_symlink(__wasi_size_t old_path_baseoffset, __wasi_size_t old_path_len,
|
|
__wasi_fd_t fd, __wasi_size_t new_path_baseoffset,
|
|
__wasi_size_t new_path_len)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Unlink a file
|
|
* Return `errno::isdir` if the path refers to a directory.
|
|
*
|
|
* @param fd
|
|
* @param path_baseoffset
|
|
* @param path_len
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_path_unlink_file(__wasi_fd_t fd, __wasi_size_t path_baseoffset,
|
|
__wasi_size_t path_len)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Concurrently poll for the occurrence of a set of events.
|
|
*
|
|
* @param in The events to which to subscribe.
|
|
* @param out The events that have occurred.
|
|
* @param nsubscriptions Both the number of subscriptions and events.
|
|
* @param retptr The number of events stored.
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_poll_oneoff(__wasi_size_t in_baseoffset, __wasi_size_t out_baseoffset,
|
|
__wasi_size_t nsubscriptions, __wasi_size_t nevents_retoffset)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Terminate the process normally. An exit code of 0 indicates successful
|
|
* termination of the program. The meanings of other values is dependent on
|
|
* the environment.
|
|
*
|
|
* @param exitcode
|
|
*/
|
|
EXPORT void
|
|
sledge_abi__wasi_snapshot_preview1_proc_exit(__wasi_exitcode_t exitcode)
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
wasi_snapshot_preview1_backing_proc_exit(sandbox->wasi_context, exitcode);
|
|
}
|
|
|
|
/**
|
|
* Send a signal to the process of the calling thread.
|
|
*
|
|
* @param sig_extended The signal condition to trigger.
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_proc_raise(uint32_t sig_extended)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Write high-quality random data into a buffer.
|
|
* This function blocks when the implementation is unable to immediately
|
|
* provide sufficient high-quality random data.
|
|
* This function may execute slowly, so when large mounts of random data are
|
|
* required, it's advisable to use this function to seed a pseudo-random
|
|
* number generator, rather than to provide the random data directly.
|
|
*
|
|
* @param buf_baseretoffset The buffer to fill with random data.
|
|
* @param buf_len The length of the buffer
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_random_get(__wasi_size_t buf_baseretoffset, __wasi_size_t buf_len)
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
uint8_t *buf_baseretptr = (uint8_t *)get_memory_ptr_for_runtime(buf_baseretoffset, buf_len);
|
|
|
|
uint32_t rc = (uint32_t)wasi_snapshot_preview1_backing_random_get(sandbox->wasi_context, buf_baseretptr,
|
|
buf_len);
|
|
sandbox_return(sandbox);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* Temporarily yield execution of the calling thread similar to `sched_yield` in POSIX.
|
|
* This implementation ignores client calls and silently returns RC 0
|
|
*
|
|
* @return WASI_ESUCCESS
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_sched_yield(void)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Receive a message from a socket.
|
|
* Note: This WASI syscall is in flux pending a decision on whether WASI
|
|
* should only support fd_read and fd_write
|
|
* See: https://github.com/WebAssembly/WASI/issues/4
|
|
* Note: This is similar to `recv` in POSIX, though it also supports reading
|
|
* the data into multiple buffers in the manner of `readv`.
|
|
*
|
|
* @param fd
|
|
* @param ri_data_baseretoffset List of scatter/gather vectors to which to store data.
|
|
* @param ri_data_len The length of the array pointed to by `ri_data`.
|
|
* @param ri_flags Message flags.
|
|
* @param ri_data_nbytes_retoffset Number of bytes stored in ri_data flags.
|
|
* @param message_nbytes_retoffset Number of bytes stored in message flags.
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_sock_recv(__wasi_fd_t fd, __wasi_size_t ri_data_baseretoffset,
|
|
__wasi_size_t ri_data_len, uint32_t ri_flags_extended,
|
|
__wasi_size_t ri_data_nbytes_retoffset,
|
|
__wasi_size_t message_nbytes_retoffset)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Send a message on a socket.
|
|
* Note: This WASI syscall is in flux pending a decision on whether WASI
|
|
* should only support fd_read and fd_write
|
|
* See: https://github.com/WebAssembly/WASI/issues/4
|
|
* Note: This is similar to `send` in POSIX, though it also supports writing
|
|
* the data from multiple buffers in the manner of `writev`.
|
|
*
|
|
* @param fd
|
|
* @param si_data_baseoffset List of scatter/gather vectors to which to retrieve data
|
|
* @param si_data_len The length of the array pointed to by `si_data`.
|
|
* @param si_flags Message flags.
|
|
* @param nbytes_retoffset Number of bytes transmitted.
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_sock_send(__wasi_fd_t fd, __wasi_size_t si_data_baseoffset,
|
|
__wasi_size_t si_data_len, uint32_t si_flags_extended,
|
|
__wasi_size_t nbytes_retoffset)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* Shut down socket send and receive channels.
|
|
* Note: This WASI syscall is in flux pending a decision on whether WASI
|
|
* should only support fd_read and fd_write
|
|
* See: https://github.com/WebAssembly/WASI/issues/4
|
|
*
|
|
* @param fd
|
|
* @param how Which channels on the socket to shut down.
|
|
* @return status code
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__wasi_snapshot_preview1_sock_shutdown(__wasi_fd_t fd, uint32_t how)
|
|
{
|
|
return wasi_unsupported_syscall(__func__);
|
|
}
|
|
|
|
/**
|
|
* @param key
|
|
* @param key_len
|
|
* @returns value_len at key or 0 if key not present
|
|
*/
|
|
EXPORT uint32_t
|
|
sledge_abi__scratch_storage_get_size(uint32_t key_offset, uint32_t key_len)
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
|
|
uint8_t *key = (uint8_t *)get_memory_ptr_for_runtime(key_offset, key_len);
|
|
|
|
uint32_t value_len;
|
|
map_get(&sandbox->tenant->scratch_storage, key, key_len, &value_len);
|
|
|
|
sandbox_return(sandbox);
|
|
|
|
return value_len;
|
|
}
|
|
|
|
EXPORT int
|
|
sledge_abi__scratch_storage_get(uint32_t key_offset, uint32_t key_len, uint32_t buf_offset, uint32_t buf_len)
|
|
{
|
|
int rc = 0;
|
|
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
|
|
uint8_t *key = (uint8_t *)get_memory_ptr_for_runtime(key_offset, key_len);
|
|
uint8_t *buf = (uint8_t *)get_memory_ptr_for_runtime(buf_offset, buf_len);
|
|
|
|
uint32_t value_len;
|
|
uint8_t *value = map_get(&sandbox->tenant->scratch_storage, key, key_len, &value_len);
|
|
|
|
if (value == NULL) {
|
|
rc = 1;
|
|
goto DONE;
|
|
} else if (value_len > buf_len) {
|
|
rc = 2;
|
|
goto DONE;
|
|
} else {
|
|
memcpy(buf, value, value_len);
|
|
rc = 0;
|
|
}
|
|
|
|
DONE:
|
|
sandbox_return(sandbox);
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* @param key_offset
|
|
* @param key_len
|
|
* @param value_offset
|
|
* @param value_len
|
|
* @returns 0 on success, 1 if already present,
|
|
*/
|
|
EXPORT int
|
|
sledge_abi__scratch_storage_set(uint32_t key_offset, uint32_t key_len, uint32_t value_offset, uint32_t value_len)
|
|
{
|
|
int rc = 0;
|
|
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
|
|
uint8_t *key = (uint8_t *)get_memory_ptr_for_runtime(key_offset, key_len);
|
|
uint8_t *value = (uint8_t *)get_memory_ptr_for_runtime(value_offset, value_len);
|
|
|
|
bool did_set = map_set(&sandbox->tenant->scratch_storage, key, key_len, value, value_len);
|
|
|
|
DONE:
|
|
sandbox_return(sandbox);
|
|
return did_set ? 0 : 1;
|
|
}
|
|
|
|
/**
|
|
* @param key_offset
|
|
* @param key_len
|
|
* @returns 0 on success, 1 if not present
|
|
*/
|
|
EXPORT int
|
|
sledge_abi__scratch_storage_delete(uint32_t key_offset, uint32_t key_len)
|
|
{
|
|
int rc = 0;
|
|
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
|
|
uint8_t *key = (uint8_t *)get_memory_ptr_for_runtime(key_offset, key_len);
|
|
|
|
bool did_delete = map_delete(&sandbox->tenant->scratch_storage, key, key_len);
|
|
|
|
DONE:
|
|
sandbox_return(sandbox);
|
|
return did_delete ? 0 : 1;
|
|
}
|
|
|
|
/**
|
|
* @param key_offset
|
|
* @param key_len
|
|
* @param value_offset
|
|
* @param value_len
|
|
*/
|
|
EXPORT void
|
|
sledge_abi__scratch_storage_upsert(uint32_t key_offset, uint32_t key_len, uint32_t value_offset, uint32_t value_len)
|
|
{
|
|
struct sandbox *sandbox = current_sandbox_get();
|
|
|
|
sandbox_syscall(sandbox);
|
|
|
|
uint8_t *key = (uint8_t *)get_memory_ptr_for_runtime(key_offset, key_len);
|
|
uint8_t *value = (uint8_t *)get_memory_ptr_for_runtime(value_offset, value_len);
|
|
|
|
map_upsert(&sandbox->tenant->scratch_storage, key, key_len, value, value_len);
|
|
|
|
sandbox_return(sandbox);
|
|
}
|