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 -K pic -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 + %g1], %o0 ! load &j into %o0
elfdump(1) を -G オプションとともに使用すれば、オブジェクトの大域オフセットテーブルの要件を調べることができます。リンカーのデバッグトークン -D got,detail を使用すれば、リンク編集中のこれらのエントリの処理を確認することもできます。
頻繁にアクセスするデータ項目に対しては、-K pic を使用する方法が有利です。どちらの方法でもエントリを参照することはできます。しかし、再配置可能オブジェクトをどちらの方法でコンパイルしたらいいのか決めるのには時間がかかる上、性能はわずかしか改善されません。すべての再配置型オブジェクトを -K PIC オプションを指定して再コンパイルする方が一般には簡単です。