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
が呼ばれるように仕向けておく。