Open4
WasmLinux: "普通の" Hello, Worldに対応する
いやまぁ "普通" って何だよってのは有るけど。。
cc hello.c
のようにしてビルドした普通のHello, worldが実行できる状況を目指す。つってもコンパイラドライバの対応は前回 https://zenn.dev/okuoku/scraps/0212b8e32270ff で終えているので、後はmain問題をどうにかすれば良い。
main 問題
実はWasmには普通のmain関数が存在しない。WASI含め環境変数が無かったりとか諸々の違いがあるため、
int main(int argc, char** argv);
とか、
int main(int argc, char** argv, char** envp);
といったシグネチャを持つmain関数の存在が想定されていない。素直に考えると、そもそもmain関数のどちらのシグネチャで呼び出しているのか厳密に判定できないとC言語的に未定義挙動になってしまう。
現状の挙動を確認
現状の挙動は、
- 3引数の
mainを定義 →main関数ができる - 2引数の
mainを定義 →__main_argc_argv関数ができる
... いやコレどうすれば良いんだ。。?
Clangは(libc側の)main 関数ポインタを __original_main へのポインタに変換している。この __original_main を誰がどこで実装すべきなのかという問題がある。
とりあえず、
- Muslからは直接
mainを参照しないように変更する (wasmlinux_mainをCRTとして用意しておく) -
wasm-ldでweakシンボルが使えるなら
__main_argc_argv→mainのwrapperを別途用意する
という感じで行こう。まぁweakシンボルはLinuxでも使ってるので大丈夫なんではないか説。
main トランポリンの実装
とりあえず、MuslのCRT1に手を入れてトランポリンすることにした。つまり、真の main (3引数) が存在する場合は無視されるように、 weak 宣言で3引数の main を宣言しておき、そちらには __main_argc_argv が呼ばれるように仕向けておく。