0

I'm trying to call a WASI function (fd_write) directly in a C program using wasi-sdk. This is the the library (lib.c):

#include <stdint.h>

struct Ciovec
{
    uint8_t *buf;
    uint32_t buf_len;
};

uint16_t fd_write(uint32_t fd, struct Ciovec *iovs_ptr, uint32_t iovs_len, uint32_t *nwritten);

static char *str = "just testing\n";

void c_main()
{
    struct Ciovec vec = { .buf = (uint8_t*)str, .buf_len = 13 };
    uint32_t nwritten = 0;
    fd_write(1, &vec, 1, &nwritten);
}

Now if I build this to a statically-linkable library using wasi-sdk

~/wasi-sdk-11.0/bin/clang --sysroot ~/wasi-sdk-11.0/share/wasi-sysroot/ lib.c -c -o lib.o -fpic

I get this wat: (wasm2wat --enable-all output)

(module
  (type (;0;) (func))
  (type (;1;) (func (param i32 i32 i32 i32) (result i32)))
  (import "env" "__linear_memory" (memory (;0;) 1))
  (import "env" "__indirect_function_table" (table (;0;) 0 funcref))
  (import "env" "__stack_pointer" (global (;0;) (mut i32)))
  (import "env" "fd_write" (func (;0;) (type 1)))
  ...)

Now this import line for fd_write is not correct. As far as I understand WASI functions need to be imported from wasi_snapshot_preview1 or wasi_unstable (I don't have a source for the first one, I just saw it in an open-source code, for the second see the example here, but I'm not sure how to do then in C. Any ideas?

2 Answers 2

2

So I made this to work:

#include <stdint.h>
#include <stdio.h>

extern uint16_t my_func()
__attribute__((
    __import_module__("my_module"),
    __import_name__("my_func"),
));

int main(){
    my_func();
    return 0;
}

Compile with -Wl,--allow-undefined

Generates

(module
  (type (;0;) (func (param i32 i32 i32) (result i32)))
  (type (;1;) (func (param i32 i64 i32) (result i64)))
  (type (;2;) (func (param i32 i32) (result i32)))
  (type (;3;) (func (result i32)))
  (type (;4;) (func (param i32)))
  (type (;5;) (func (param i32) (result i32)))
  (type (;6;) (func (param i32 i32 i32 i32) (result i32)))
  (type (;7;) (func (param i32 i64 i32 i32) (result i32)))
  (type (;8;) (func))
  (import "wasi_unstable" "fd_prestat_get" (func $__wasi_fd_prestat_get (type 2)))
  (import "wasi_unstable" "fd_prestat_dir_name" (func $__wasi_fd_prestat_dir_name (type 0)))
  (import "my_module" "my_func" (func $my_func__ (type 3)))
  (import "wasi_unstable" "proc_exit" (func $__wasi_proc_exit (type 4)))
  (import "wasi_unstable" "fd_fdstat_get" (func $__wasi_fd_fdstat_get (type 2)))
  (import "wasi_unstable" "fd_close" (func $__wasi_fd_close (type 5)))
  (import "wasi_unstable" "fd_write" (func $__wasi_fd_write (type 6)))
  (import "wasi_unstable" "fd_seek" (func $__wasi_fd_seek (type 7)))
  (func $__wasm_call_ctors (type 8))
  (func $undefined:__wasilibc_populate_environ (type 3) (result i32)
Sign up to request clarification or add additional context in comments.

Comments

0

Found the answer in wasi-libc source code:

uint16_t fd_write(uint32_t fd, struct Ciovec *iovs_ptr, uint32_t iovs_len, uint32_t *nwritten)
    __attribute__((
                __import_module__("wasi_snapshot_preview1"),
                __import_name__("fd_write"),
                ));

Generated Wasm:

  (import "wasi_snapshot_preview1" "fd_write" (func $fd_write (type 1)))

This still doesn't work though, I get undefined symbol: fd_write errors, but at least I know how to specify the import path now.

1 Comment

Have you progressed since ? I'm trying to do the same thing but with a custom function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.