How can I invoke `exec` to chainload one WASM program from another?

91 Views Asked by At

How can I invoke exec in WASM? When I try the example below, it gives error 45 (Operation not supported). Is there some flag to enable exec? Is callee.wasm not the right file to exec?

Terminal:

> emcc callee.c -o callee.wasm
> emcc caller.c --embed-file callee.wasm -o index.html
> # will be used through index.html, but node is faster for development
> # note: MEMFS working directory is "/" and "/callee.wasm" exists
> # https://emscripten.org/docs/api_reference/Filesystem-API.html
> node index.js
Caller
Caller: 45

caller.c

#include <errno.h>
#include <stdio.h>
#include <unistd.h>

int main() {
  printf("Caller\n");

  char *args[] = {"./callee.wasm", NULL};
  execvp(args[0], args);

  printf("Caller: %d\n", errno);
}

callee.c

#include <stdio.h>

int main() {
  printf("Success!\n");
}

It should be made clear that this is simplified version, so do not suggest putting printf("Success!\n"); in caller.c and avoiding exec entirely.

1

There are 1 best solutions below

0
On BEST ANSWER

It seems you can’t, short of reimplementing exec yourself.

Point of order first: errno 45 is not EOPNOTSUPP under Emscripten as the question would suggest; it is, in fact, ENOEXEC (see arch/emscripten/bits/errno.h and wasi/api.h). errno numbers are generally not consistent between platforms, and there is no reason why errno numbers in a BSD libc would agree with Emscripten libc.

And the Emscripten libc hardcodes execve to always fail with ENOEXEC, and the entire exec* family of libc calls ultimately ends up there, including execvp. The symbol is declared as weak, however, so you can in principle replace the default implementation with your own. How you are going to accomplish that, I leave up to you.