Open4

WasmLinux: "普通の" Hello, Worldに対応する

okuokuokuoku

いやまぁ "普通" って何だよってのは有るけど。。

cc hello.c

のようにしてビルドした普通のHello, worldが実行できる状況を目指す。つってもコンパイラドライバの対応は前回 https://zenn.dev/okuoku/scraps/0212b8e32270ff で終えているので、後はmain問題をどうにかすれば良い。

okuokuokuoku

main 問題

実はWasmには普通のmain関数が存在しない。WASI含め環境変数が無かったりとか諸々の違いがあるため、

int main(int argc, char** argv);

とか、

int main(int argc, char** argv, char** envp);

といったシグネチャを持つmain関数の存在が想定されていない。素直に考えると、そもそもmain関数のどちらのシグネチャで呼び出しているのか厳密に判定できないとC言語的に未定義挙動になってしまう。

okuokuokuoku

現状の挙動を確認

現状の挙動は、

  • 3引数の main を定義 → main 関数ができる
  • 2引数の main を定義 → __main_argc_argv 関数ができる

https://github.com/llvm/llvm-project/blob/0fc69b1402d75704744c73e15d278dcc8f437f0e/clang/lib/AST/Mangle.cpp#L181-L184

... いやコレどうすれば良いんだ。。?

Clangは(libc側の)main 関数ポインタを __original_main へのポインタに変換している。この __original_main を誰がどこで実装すべきなのかという問題がある。

https://github.com/llvm/llvm-project/blob/0fc69b1402d75704744c73e15d278dcc8f437f0e/llvm/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp#L282-L300

とりあえず、

  1. Muslからは直接 main を参照しないように変更する (wasmlinux_main をCRTとして用意しておく)
  2. wasm-ldでweakシンボルが使えるなら __main_argc_argvmain のwrapperを別途用意する

という感じで行こう。まぁweakシンボルはLinuxでも使ってるので大丈夫なんではないか説。