BitVisorはClangでビルドできるか. その1
BitVisor Advent Calendar 2020 13日目の記事です。 BitVisor Advent Calendar 2020 - Qiita
今回は、タイトルの通りclangでbitvisorをビルドできるか試した話です。
scan-buildとかできたら楽しそうですよね。
現状、ビルドできてませんが、途中経過を。
準備
- コンパイラの指定
bitvisorのコンパイラの指定は、Makefile.common
にあるようで、現状はこんな感じ。
$ head Makefile.common # -*- makefile-gmake -*- # commands AR = ar CC = cc RM = rm -f OBJCOPY = objcopy SED = sed SIZE = size STRIP = strip
このCC = エラーcc
を CC = clang
に変更してみる.
ビルド
これでとりあえずビルドを開始してみる.
- invlpga
$ make .... In file included from core/svm_main.c:30: core/asm.h:768:16: error: too few operanエラーds for instruction asm volatile ("invlpga" : : "a" (addr), "c" (asid)); ^ <inline asm>:1:2: note: instantiated into assembly here invlpga ^ 1 error generated. make[2]: *** [Makefile.build:145: core/svm_main.o] Error 1 make[1]: *** [Makefile.build:136: core/output.o_p] Error 2 make: *** [Makefile:43: build-all] Error 2
invlpg
は、指定したページのTLB をflushする命令らしいが、invlpga
はASIDを指定してそれに属指定しているTLBエントリだけflushできるらしい。
しかし、後者の命令はAMD64にしかないらしく、それにまつわるエラーだと思われる。(too few operands for instruction
なので違う?)
問題になるかもしれないが、とりあえずコメントアウトしてビルドしてみる.
- -Wa,--divide
次に直面した問題は、ビルド時のオプションの差によるエラー
CC core/arith.o clang-11: error: unsupported argument '--divide' to option 'Wa,' make[2]: *** [Makefile.build:152: core/arith.o] Error 1 make[1]: *** [Makefile.build:136: core/output.o_p] Error 2
-Wa
なのでアセンブラに渡す引数ということで、manを見る
$ man as ... --divide On SVR4-derived platforms, the character / is treated as a comment character, which means that it cannot be used in expressions. The --divide option turns / into a normal character. This does not disable / at the beginning of a line starting a comment, or affect using # for starting a comment. ...
コメントにまつわるオプションとのことで、だめならビルドエラーが出るだろうということで、とりあえず無効にしてみる.
定義は、Makefile.build
にあり、ただ消すだけ.
$ cat Makefile.build ... ASFLAGS = -m$(bits-$(CONFIG_64)) -g -Wa,-I,$(DIR) -Wa,--divide ...
- vmload, vmrun, vmsave
さらに作業をするめると、AMD-Vな命令の箇所でエラーが発生する.
CC core/asm.o core/asm.s:212:1: error: too few operands for instruction vmload ^ core/asm.s:213:1: error: too few operands for instruction vmrun ^ core/asm.s:214:1: error: too few operands for instruction vmsave ^
Intel環境で動かすことをとりあえず目標にしているので、コメントアウトする.
- current
次に当たる問題は、inline assemblyにまつわる話。
LD bitvisor.elf動かしていきたい /usr/bin/ld: output.o: in function `acpi_smi_hook': /aaa/bitvisor/core/acpi.c:686: undefined reference to `%gs:gs_current' /usr/bin/ld: /aaa/bitvisor/core/acpi.c:690: undefined reference to `%gs:gs_current' /usr/bin/ld: output.o: in function `acpi_iohook': /aaa/bitvisor/core/acpi.c:700: undefined reference to `%gs:gs_current'
エラーの原因はcore/current.h
$ cat core/current.h ... extern struct vcpu *current asm ("%gs:gs_current"); ...
どうも調べるに、clangでsegment registerにアクセスするのはちょっと特殊な方法を使わないと行けない模様.
Clang Language Extensions — Clang 12 documentation
> Annotating a pointer with address space #256 causes it to be code generated relative to the X86 GS segment register, > address space #257 causes it to be relative to the X86 FS segment, and address space #258 causes it to be relati動かしていきたいve to the X86 SS segment. > Note that this is a very very low-level feature that should only be used if you know what you’re doing (for example in an OS kernel).
__attribute__((address_space(256)))
のように、書いてこの256
がx86のGS segment registerを指し示すらしい。
これを用いて書き換える必要がありそうだが、まだうまく行っていない。現状はここまで。
とりあえず、手元とちょっとググる感じで頑張ってみたが、参考にすべきはclangで既にビルドされているシステムソフトウェアで、
例としては、FreeBSD 10以降や LLVMLinux(ClangBuiltLinux)だと思われるのでそこらへんのコードから何やっているのかも調べて動かしていきたい.