ここでいう ABI (Application Binary Interface) とは,C コンパイラにおいて
現在,ARM Linux 上で使われている ABI には以下の2つの種類があります.
従来から ARM gcc で使用されている ABI.
gcc でのコンパイルオプションは -mabi=apcs-gnu
です.
ARM holdings が定義
http://www.arm.com/products/DevTools/ABI.htmlした ABI です. gcc 4.1 以降で使用可能で,コンパイルオプションは
-mabi=aapcs-linux
です.
これらの ABI の違いは,Linux カーネルの設定ファイル(linux-2.6.x/arch/arm/Kconfig)によると
Since there are major incompatibilities between the legacy ABI and EABI, especially with regard to structure member alignment, this option also changes the kernel syscall calling convention to disambiguate both ABIs and allow for backward compatibility support (selected with CONFIG_OABI_COMPAT).ということだそうです. 構造体のアラインメントに違いがあるようです.
以下のプログラムで違いを見てみます.
/* abitest.c */ #include <stdio.h> struct foo { char a; }; main ( void ) { printf ( "sizeof(struct foo) = %d\n", sizeof(struct foo)); }
lagacy ABI のほうは
$ gcc -mabi=apcs-gnu abitest.c
$ ./a.out
sizeof(struct foo) = 4
$
ARM EABI のほうは
$ gcc -mabi=aapcs-linux abitest.c
$ ./a.out
sizeof(struct foo) = 1
$
という結果が得られます. 構造体のアラインメントの違いが見られますね.
手元にあるプログラムが ARM EABI か legacy ABI か見分けるには readelf
を使います.
$ gcc -mabi=aapcs-linux -c abitest.c # ARM EABI でコンパイル
$ readelf -h abitest.o
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
...
(略)
...
Flags: 0x4000000, Version4 EABI
...
(略)
...
$ gcc -mabi=apcs-gnu abitest.c # legacy ABI でコンパイル
$ readelf -h abitest.o
ELF Header:
Magic: 7f 45 4c 46 01 01 01 61 00 00 00 00 00 00 00 00
...
(略)
...
Flags: 0x400, GNU EABI, VFP
...
(略)
...
(注)この節は後から追加しており,前の readelf と出力フォーマットが違ってます.
つまり,Flags: の項が
Debian では lenny(執筆時点での test 版)で EABI 化されたユーザランドが用意されました. アーキテクチャ名は
legacy ABI のユーザランド
ARM EABI のユーザランド
「システム内部で ABI を統一せよ」
これが鉄則です.
もちろん,ABI を統一しておかなくてはいけません. ライブラリ関数が仮定している構造体のデータ構造と呼出元が仮定している 構造体のデータ構造が食い違っていては,マトモに動作することは期待できません.
これらも ABI を統一しておく必要かあります. これも同様の理由です.
最近の Linux カーネルでは CONFIG_AEABI と CONFIG_OABI_COMPAT オプションを有効にすると
ただし,legacy ABI プログラムからのシステムコールは引数を EABI のデータ構造に変換するため,多少のオーバヘッドが生じることになります. また,以前のバージョンではこの変換に不具合があったらしく,apache などのプログラムが動作しないこともありました. というわけで,カーネルを自分でコンパイルできる場合はカーネルの ABI をユーザランド側に合わせてしまえば良いわけで,わざわざ使う機能ではないと思います.