原因
スタックアライメントの矛盾がオブジェクト・コード内で検知される場合、このリンカエラーが発生します。
「ARMアーキテクチャー用のABI」は、コードがそのインターフェースで 8 バイトのスタックアライメントを維持することを要求します。これは、8 バイトアラインの "double" および "long long" データタイプにアクセスする LDRD および STRD 命令( ARM アーキテクチャー 5TE 以降のコアのみ)の効率的な使用を許可します。
'~PRES8'および'REQ8'というシンボルはオブジェクトのビルド属性を示します。
- 'PRES8'は、オブジェクトがスタックの8バイトアライメントを保持する(PREServes)ことを意味します。
- '~PRES8'は、オブジェクトがスタックの 8 バイトアライメントを保持しない(~はNotを示します)ことを意味します。
- 'REQ8'は、オブジェクトがスタックの 8 バイトアライメントを要求する(REQuires)ことを意味します。
このリンクエラーは一般的に以下の2つのケースで発生します。
- アセンブラコード( 8 バイトのスタックアライメントを保存しない)がコンパイルされた C/C++ コード ( 8 バイトのスタックアライメントを要求する)を呼び出した場合
- 古い SDT/ADS のオブジェクトを RVCT 2.x のオブジェクトとリンクすることを試みた場合、 これらの属性を持っていない古い SDT/ADS オブジェクトは、偶然に RVDS と ADS1.2. の 8 バイトアライメントを保持する場合でも、'~PRES8'として扱われます。
例:
Error: L6238E: foo.o(.text) contains invalid call from '~PRES8' function to 'REQ8' function foobar
これは、オブジェクト foo.o 内にある関数(.textセクション内)が 8 バイトのスタックアライメントを保存しないにも関わらず、 8 バイトのスタックアライメントを要求する関数 foobar を呼ぼうとしている事を意味します。
外部シンボルのアドレスが参照されている場合、発生する可能性がある同様の警告は以下の通りです:
Warning: L6306W: '~PRES8' section foo.o(.text) should not use the address of 'REQ8' function foobar
解決方法
この問題に対応するには 2 つの可能なアプローチがあります:
1.すべてのソースコードにアクセスし、リビルドすることが可能な場合
この場合、最新のコンパイレーションツールを使用して、オブジェクトおよびライブラリをすべてリビルドするべきです。もしアセンブラファイルも含まれる場合、以下の点にご注意ください:
- すべての命令が 8 バイトのスタックアライメントを保持することをチェックし、必要であれば修正を行います。
例)
STMFD sp!, {r0-r3, lr} ; 奇数個のレジスタをプッシュします
を、
STMFD sp!, {r0-r3, r12, lr} ; 偶数個のレジスタをプッシュします
の様に修正します。
- それぞれのアセンブラファイルの先頭に PRESERVE8 ディレクティブを追加します。
例)
AREA Init, CODE, READONLY
を、
PRESERVE8 AREA Init, CODE, READONLY
の様に修正します。( PRES8 属性はコードセクションだけでなく
全体のオブジェクトに適用されます)
2.ソースコードをリビルドできない場合
ソースコードがない、あるいは古いオブジェクトをリビルドしてはならない(例えば証明/認証上の理由で)といった原因で、 リビルドできない古いオブジェクトやライブラリがある場合、それらが 8 バイトのアライメントを保持するかどうかをチェックするため、 古いオブジェクトを調べなければなりません。
オブジェクトコードを逆アセンブルするために fromelf -c を使用してください。
ADS1.1 以降でコンパイルされた C/C++ コードは通常 8 バイトアライメントを保持しますが、アセンブラコードでは保持されません。
オブジェクトが確実に 8 バイトアライメントを保持する場合、
リンカエラー L6238E はリンカコマンドラインで "--diag_suppress 6238" を使用することによって抑制することができます。このオプションを使用することによって、"すべてのオブジェクトは PRES8 であることを保証する"という事が示されます。
リンカワーニング L6306W は"--diag_suppress 6306"により抑制することが可能です。