Skip to content

Commit

Permalink
Use the correct memory for host func
Browse files Browse the repository at this point in the history
Instead of assuming memory index 0,
look up an export with the name "memory".
  • Loading branch information
yamt committed Aug 10, 2024
1 parent 5217493 commit f8186be
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 40 deletions.
30 changes: 30 additions & 0 deletions lib/cconv.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* a part of core wasm.
*/

#include "cconv.h"
#include "exec.h"
#include "instance.h"
#include "module.h"
Expand All @@ -11,6 +12,18 @@
static const struct name name_func_table =
NAME_FROM_CSTR_LITERAL("__indirect_function_table");

/*
* the export name "memory" is defined by wasi.
* https://github.com/WebAssembly/WASI/blob/main/legacy/README.md
* it's widely used for non-wasi interfaces as well.
*
* Note: some runtimes, including old versions of toywasm, assume
* the memidx 0 even for wasi. it would end up with some
* incompatibilities with multi-memory proposal.
*/
static const struct name name_default_memory =
NAME_FROM_CSTR_LITERAL("memory");

/*
* dereference a C function pointer.
* that is, get the func inst pointed by the pointer.
Expand Down Expand Up @@ -48,3 +61,20 @@ cconv_deref_func_ptr(struct exec_context *ctx, const struct instance *inst,
*fip = func;
return 0;
}

int
cconv_default_memory(struct exec_context *ctx, uint32_t *memidxp)
{
const struct module *m = ctx->instance->module;
int ret;
/*
* XXX searching exports on each call can be too slow.
*/
ret = module_find_export(m, &name_default_memory, EXTERNTYPE_MEMORY,
memidxp);
if (ret != 0) {
return trap_with_id(ctx, TRAP_DEFAULT_MEMORY_NOT_FOUND,
"default memory not found");
}
return 0;
}
2 changes: 2 additions & 0 deletions lib/cconv.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ int cconv_deref_func_ptr(struct exec_context *ctx, const struct instance *inst,
uint32_t wasmfuncptr, const struct functype *ft,
const struct funcinst **fip);

int cconv_default_memory(struct exec_context *ctx, uint32_t *memidxp);

__END_EXTERN_C
2 changes: 1 addition & 1 deletion lib/exec_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ enum trapid {
TRAP_UNCAUGHT_EXCEPTION,
TRAP_THROW_REF_NULL,
TRAP_UNRESOLVED_IMPORTED_FUNC,
TRAP_INVALID_MEMORY,
TRAP_DEFAULT_MEMORY_NOT_FOUND,
};

enum exec_event {
Expand Down
43 changes: 21 additions & 22 deletions lib/host_instance.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <stdlib.h>
#include <string.h>

#include "cconv.h"
#include "exec.h"
#include "host_instance.h"
#include "instance.h"
Expand Down Expand Up @@ -159,13 +160,18 @@ int
host_func_copyin(struct exec_context *ctx, void *hostaddr, uint32_t wasmaddr,
size_t len, size_t align)
{
uint32_t memidx;
void *p;
int ret;
ret = cconv_default_memory(ctx, &memidx);
if (ret != 0) {
return ret;
}
ret = host_func_check_align(ctx, wasmaddr, align);
if (ret != 0) {
return ret;
}
ret = memory_getptr(ctx, 0, wasmaddr, 0, len, &p);
ret = memory_getptr(ctx, memidx, wasmaddr, 0, len, &p);
if (ret != 0) {
return ret;
}
Expand All @@ -177,50 +183,43 @@ int
host_func_copyout(struct exec_context *ctx, const void *hostaddr,
uint32_t wasmaddr, size_t len, size_t align)
{
uint32_t memidx;
void *p;
int ret;
ret = cconv_default_memory(ctx, &memidx);
if (ret != 0) {
return ret;
}
ret = host_func_check_align(ctx, wasmaddr, align);
if (ret != 0) {
return ret;
}
ret = memory_getptr(ctx, 0, wasmaddr, 0, len, &p);
ret = memory_getptr(ctx, memidx, wasmaddr, 0, len, &p);
if (ret != 0) {
return ret;
}
memcpy(p, hostaddr, len);
return 0;
}

static int
check_memidx(struct exec_context *ctx, uint32_t memidx)
{
const struct module *m = ctx->instance->module;
if (memidx < m->nmems + m->nimportedmems) {
return 0;
}
return trap_with_id(
ctx, TRAP_INVALID_MEMORY,
"access to invalid memidx %" PRIx32 " in a host call", memidx);
}

int
host_func_memory_getptr(struct exec_context *ctx, uint32_t memidx,
uint32_t ptr, uint32_t offset, uint32_t size,
void **pp)
host_func_getptr(struct exec_context *ctx, uint32_t ptr, uint32_t offset,
uint32_t size, void **pp)
{
int ret = check_memidx(ctx, memidx);
uint32_t memidx;
int ret = cconv_default_memory(ctx, &memidx);
if (ret != 0) {
return ret;
}
return memory_getptr(ctx, memidx, ptr, offset, size, pp);
}

int
host_func_memory_getptr2(struct exec_context *ctx, uint32_t memidx,
uint32_t ptr, uint32_t offset, uint32_t size,
void **pp, bool *movedp)
host_func_getptr2(struct exec_context *ctx, uint32_t ptr, uint32_t offset,
uint32_t size, void **pp, bool *movedp)
{
int ret = check_memidx(ctx, memidx);
uint32_t memidx;
int ret = cconv_default_memory(ctx, &memidx);
if (ret != 0) {
return ret;
}
Expand Down
10 changes: 4 additions & 6 deletions lib/host_instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,10 @@ int host_func_copyout(struct exec_context *ctx, const void *hostaddr,
uint32_t wasmaddr, size_t len, size_t align);
int host_func_copyin(struct exec_context *ctx, void *hostaddr,
uint32_t wasmaddr, size_t len, size_t align);
int host_func_memory_getptr(struct exec_context *ctx, uint32_t memidx,
uint32_t ptr, uint32_t offset, uint32_t size,
void **pp);
int host_func_memory_getptr2(struct exec_context *ctx, uint32_t memidx,
uint32_t ptr, uint32_t offset, uint32_t size,
void **pp, bool *movedp);
int host_func_getptr(struct exec_context *ctx, uint32_t ptr, uint32_t offset,
uint32_t size, void **pp);
int host_func_getptr2(struct exec_context *ctx, uint32_t ptr, uint32_t offset,
uint32_t size, void **pp, bool *movedp);
int host_func_trap(struct exec_context *ctx, const char *fmt, ...)
__attribute__((__format__(__printf__, 2, 3)));
struct restart_info;
Expand Down
4 changes: 2 additions & 2 deletions libdyld/dyld_dlfcn.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ dyld_dlfcn_load_object(struct exec_context *ctx, struct host_instance *hi,
}

void *vp;
ret = host_func_memory_getptr(ctx, 0, namep, 0, namelen, &vp);
ret = host_func_getptr(ctx, namep, 0, namelen, &vp);
if (ret != 0) {
user_ret = 1;
goto fail;
Expand Down Expand Up @@ -169,7 +169,7 @@ dyld_dlfcn_resolve_symbol(struct exec_context *ctx, struct host_instance *hi,
const struct dyld_dynamic_object *dobj = &VEC_ELEM(d->dynobjs, idx);

void *vp;
ret = host_func_memory_getptr(ctx, 0, namep, 0, namelen, &vp);
ret = host_func_getptr(ctx, namep, 0, namelen, &vp);
if (ret != 0) {
user_ret = 1;
goto fail;
Expand Down
2 changes: 1 addition & 1 deletion libwasi/wasi_abi_path.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ wasi_path_readlink(struct exec_context *ctx, struct host_instance *hi,
* https://github.com/bytecodealliance/wasmtime/commit/24b607cf751930c51f2b6449cdfbf2e81dce1c31
*/
void *p;
host_ret = host_func_memory_getptr(ctx, 0, buf, 0, buflen, &p);
host_ret = host_func_getptr(ctx, buf, 0, buflen, &p);
if (host_ret != 0) {
goto fail;
}
Expand Down
6 changes: 3 additions & 3 deletions libwasi/wasi_abi_poll.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <stdlib.h>
#include <string.h>

#include "cconv.h"
#include "endian.h"
#include "exec_context.h"
#include "restart.h"
Expand Down Expand Up @@ -51,7 +52,7 @@ wasi_poll_oneoff(struct exec_context *ctx, struct host_instance *hi,
if (host_ret != 0) {
goto fail;
}
host_ret = host_func_memory_getptr(ctx, 0, in, 0, insize, &p);
host_ret = host_func_getptr(ctx, in, 0, insize, &p);
if (host_ret != 0) {
goto fail;
}
Expand All @@ -62,8 +63,7 @@ wasi_poll_oneoff(struct exec_context *ctx, struct host_instance *hi,
if (host_ret != 0) {
goto fail;
}
host_ret =
host_func_memory_getptr2(ctx, 0, out, 0, outsize, &p, &moved);
host_ret = host_func_getptr2(ctx, out, 0, outsize, &p, &moved);
if (host_ret != 0) {
goto fail;
}
Expand Down
2 changes: 1 addition & 1 deletion libwasi/wasi_abi_random.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ wasi_random_get(struct exec_context *ctx, struct host_instance *hi,
uint32_t buflen = HOST_FUNC_PARAM(ft, params, 1, i32);
int ret = 0;
void *p;
int host_ret = host_func_memory_getptr(ctx, 0, buf, 0, buflen, &p);
int host_ret = host_func_getptr(ctx, buf, 0, buflen, &p);
if (host_ret != 0) {
goto fail;
}
Expand Down
8 changes: 4 additions & 4 deletions libwasi/wasi_subr.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ wasi_copyin_iovec(struct exec_context *ctx, uint32_t iov_uaddr,
if (host_ret != 0) {
goto fail;
}
host_ret = host_func_memory_getptr(
ctx, 0, iov_uaddr, 0, iov_count * sizeof(struct wasi_iov), &p);
host_ret = host_func_getptr(ctx, iov_uaddr, 0,
iov_count * sizeof(struct wasi_iov), &p);
if (host_ret != 0) {
goto fail;
}
Expand All @@ -93,8 +93,8 @@ wasi_copyin_iovec(struct exec_context *ctx, uint32_t iov_uaddr,
uint32_t iov_len = le32_decode(&iov_in_module[i].iov_len);
xlog_trace("iov [%" PRIu32 "] base %" PRIx32 " len %" PRIu32,
i, iov_base, iov_len);
host_ret = host_func_memory_getptr2(ctx, 0, iov_base, 0,
iov_len, &p, &moved);
host_ret = host_func_getptr2(ctx, iov_base, 0, iov_len, &p,
&moved);
if (host_ret != 0) {
goto fail;
}
Expand Down

0 comments on commit f8186be

Please sign in to comment.