カーネルやVMMを実装するときは標準ライブラリを使用せずにコンパイルを行う。32ビットカーネルやVMMを実装中に、long longなどの変数の除算やかけ算を行うとコンパイルが通らない。それはlong longなどの64ビット変数の乗算や除算などの命令を実行しているからである。32ビットカーネルでは64ビットレジスタの除算や演算が存在しないので、ライブラリが64ビット変数の演算のエミュレーションを行っている。

エミュレーションを行っているライブラリはlibgcc.aであり、プログラムにこのライブラリをリンクすればこの問題を解決できる。

例えば、32ビットカーネルで以下のようなコードの場合

/* test.c */
int main(void)
{
	long long x = 100;
	long long y = 10;
	long long z = x / y;

	while (1);

	return 0;
}

うまくいかない場合

$ gcc -nostdinc -e main test.c
/tmp/cc6vAL0z.o: In function `main':
div.c:(.text+0x49): undefined reference to `__divdi3'
collect2: ld はステータス 1 で終了しました

うまくいく場合

libgcc.aは使用しているgccディレクトリを合わせる必要がある。

$ gcc -nostdlib -e main test.c -L/usr/lib/gcc/i486-linux-gnu/4.1.2/ -lgcc
$ ./a.out

エミュレーションのコード

gcc4.2で、libgcc.Sは以下のディレクトリにある。

$ cd gcc4.2
$ less ./gcc/config/libgcc2.c