Stream: general

Topic: Passing a pointer to a struct into a function call


view this post on Zulip Kaitlyn Kenwell (Apr 23 2020 at 15:47):

I'm playing around with the Rust wasmtime API, and I'm trying to pass a pointer to a struct defined in a crate that both the runtime crate and the compiled wasm depend on when I compile the wasm crate to wasm32-wasi, the pointer becomes a u32 parameter, but I'm not sure what to do in the caller to pass a pointer that can be used properly. I tried copying the struct value into the exported memory and passing the address to that, but that still resulted in an out of bounds trap being thrown.

view this post on Zulip Yury Delendik (Apr 23 2020 at 16:05):

Copying the struct into exported memory is right move, did compiled wasm allocated memory for this structure or you just selected the offset randomly?

view this post on Zulip Kaitlyn Kenwell (Apr 23 2020 at 16:38):

I just started at 0, the crate that I'm trying to run
is very minimal. Here's the code https://hasteb.in/jufodijo.swift

view this post on Zulip Yury Delendik (Apr 23 2020 at 16:56):

@Kaitlyn Kenwell 0 is not right. Ask wasm to allocate memory for you, e.g. Vec::with_capacity + mem::forget perhaps

view this post on Zulip Kaitlyn Kenwell (Apr 23 2020 at 18:20):

I don't understand how that ties in to sending a struct from the host into the wasm application

view this post on Zulip Yury Delendik (Apr 23 2020 at 18:23):

Based on your example your structure contains other pointers: the s

view this post on Zulip Yury Delendik (Apr 23 2020 at 18:26):

@Kaitlyn Kenwell Do you set 5 i32's in the wasm exported memory for the CommonStruct? Which values are these initialized to?

view this post on Zulip Yury Delendik (Apr 23 2020 at 18:29):

if buffer of the String points to some weird location, you might be getting out of bounds.

view this post on Zulip Kaitlyn Kenwell (Apr 23 2020 at 18:30):

https://hasteb.in/inarumol.js here's what I have in the host, ignore the &str parameter, I cut that out to make sure that extra pointers weren't a factor

view this post on Zulip Yury Delendik (Apr 23 2020 at 18:33):

I think main issue here is that you are mixing wasm pointer and native pointer, e.g. let ptr = &buf[0] as *const _ as i32;

view this post on Zulip Yury Delendik (Apr 23 2020 at 18:34):

it shall be let ptr = 0; -- you cannot cast 64 bit pointer to i32, it needs to be offset in wasm memory (from host point of view)

view this post on Zulip Kaitlyn Kenwell (Apr 23 2020 at 18:34):

ok

view this post on Zulip Yury Delendik (Apr 23 2020 at 18:35):

also std::ptr::copy definitely wrong, since it copied all pointers as is (not i32 offsets as mentioned above)

view this post on Zulip Pat Hickey (Apr 23 2020 at 18:38):

for what its worth: this sort of translation between guest memory and host is complicated and easy to get wrong in ways that may cause security problems (e.g. letting the guest modify a host pointer). the crates/wiggle crate is designed for automatically generating host interfaces from .witx descriptions. it is currently used in crates/wasi-common.

view this post on Zulip Pat Hickey (Apr 23 2020 at 18:39):

we're also using it over in lucet. unfortunately i'm not the authority on how to integrate it with wasmtime, but hopefully you can follow how its use in wasi-common works?

view this post on Zulip Till Schneidereit (Apr 23 2020 at 18:56):

For more info on how to use these, @Radu M recently wrote a blog post describing how to add syscalls using wasi-common: https://radu-matei.com/blog/adding-wasi-syscall/

In this article, we explore how to add a new system call to WASI, the WebAssembly System Interface, and implement it in Wasmtime

view this post on Zulip Pat Hickey (Apr 23 2020 at 18:57):

oh wow, i was not aware of that!

view this post on Zulip Pat Hickey (Apr 23 2020 at 19:00):

great blog post @Radu M

view this post on Zulip Johnnie Birch (Apr 23 2020 at 22:30):

(deleted)

view this post on Zulip Kaitlyn Kenwell (Apr 25 2020 at 03:31):

Sort of related to this, I've decided to just try passing data with marshalling and to use a proc macro to make it easier to use on the plugin end. in general, how can a host know where is a safe region in the memory to copy to? I didn't run into any problems with a fairly simple program with just copying into an early index in the memory, but when I printed it out I did see more stuff near the bottom. Not sure how I can be sure if I won't ruin anything accidentally by just choosing some arbitrary location near the start to inject values

view this post on Zulip Chris Fallin (Apr 25 2020 at 03:45):

@Kaitlyn Kenwell the general principle is that the wasm program itself owns and manages its memory -- e.g., the copy of the standard library that you link with inside the wasm environment will be keeping its own malloc data structures. So the best way to allow for a caller to pass data in would be to invoke an entry point first to ask for a block of memory, then fill that memory with your data, then invoke the main function call. E.g., export both a alloc_buffer(len: usize) -> *mut u8 function along with your test_fun(...)

view this post on Zulip Chris Fallin (Apr 25 2020 at 03:47):

In Rust, you can alloc a Vec and then forget it, as Yury hints at above, or for a struct, you can use Box::into_raw

view this post on Zulip bjorn3 (Apr 25 2020 at 08:01):

There is Vec::into_raw_parts, which returns a ptr, len and capacity.


Last updated: Dec 23 2024 at 12:05 UTC