SPARC バイナリでは、-K pic オプションと -K PIC オプションの動作がわずかに違っており、大域オフセットテーブルエントリの参照方法が異なります。「大域オフセットテーブル (プロセッサ固有)」を参照してください。
大域オフセットテーブルはポインタの配列で、エントリのサイズは、32 ビット (4 バイト) および 64 ビット (8 バイト) に固定です。-K pic を使用してエントリを参照するコードは、次のようになります。
ld [%l7 + j], %o0 ! load &j into %o0 |
%l7 には、参照元オブジェクトのシンボル _GLOBAL_OFFSET_TABLE_ であらかじめ計算された値が代入されます。
このコード例は 13 ビットの置換定数を大域オフセットテーブルエントリに使用するので、32 ビットオブジェクトの場合は 2048 個の一意のエントリが取得され、64 ビットオブジェクトの場合は 1024 個の一意のエントリが取得されます。返されるエントリ数より多くのエントリを要求するオブジェクトの場合、リンカーは致命的なエラーを生成します。
$ cc -Kpic -G -o lobfoo.so.1 a.o b.o ... z.o ld: fatal: too many symbols require `small' PIC references: have 2050, maximum 2048 -- recompile some modules -K PIC. |
このエラー状態を解決するには、入力再配置可能オブジェクトの一部またはすべてをコンパイルするときに、-K PIC オプションを指定します。 このオプションには、32 ビットの定数を大域オフセットテーブルエントリに使用します。
sethi %hi(j), %g1 or %g1, %lo(j), %g1 ! get 32-bit constant GOT offset ld [%l7 + j], %o0 ! load &j into %o0 |
elfdump(1) を -G オプションと共に使用すれば、オブジェクトの大域オフセットテーブルの要件を調べることができます。リンカーのデバッグトークン -D got,detail を使用すれば、リンク編集中のこれらのエントリの処理を確認することもできます。
頻繁にアクセスするデータ項目に対しては、-K pic を使用する方法が有利です。どちらの方法でもエントリを参照することはできます。しかし、再配置可能オブジェクトをどちらの方法でコンパイルしたらいいのか決めるのには時間がかかる上、性能はわずかしか改善されません。すべての再配置型オブジェクトを -K PIC オプションを指定して再コンパイルする方が一般には簡単です。