データ項目 (それ自体はコピー再配置で使用可能) にディスプレイスメント再配置が適用されていると、エラー状態が発生することがあります。コピー再配置の詳細については、コピー再配置を参照してください。
ディスプレイスメント再配置は、再配置されるオフセットと再配置される先のターゲットが両方とも同じ位置だけ離れている限り有効です。コピー再配置とは、共有オブジェクト内の大域データ項目を実行可能プログラムの .bss にコピーし、実行可能プログラムの読み取り専用テキストセグメントを同じ状態に保つことをいいます。コピーされるデータにディスプレイスメント再配置が適用されていたり、外部再配置がコピーされるデータへのディスプレイスメントであったりすると、ディスプレイスメント再配置は無効になります。
コピー再配置可能なデータ項目がディスプレイスメント再配置を伴うと問題が発生する可能性がある場合は、共有オブジェクトを生成するときにそれらに対しフラグを立てる。リンカーが共有オブジェクトを構築する際には、共有オブジェクトに対しどのような参照がされるかは不明である。したがって、フラグが立てられたデータ項目は、エラーを引き起こす可能性がある。
コピー再配置のデータがディスプレイスメント再配置を伴う場合は、実行可能プログラムを生成するときにコピー再配置の作成に対しフラグを立てる。
しかし、リンク編集で共有オブジェクトを作成するときに、共有オブジェクトに適用されたディスプレイスメント再配置が完了することがある。 したがって、この共有オブジェクトを参照するアプリケーションのリンク編集時には、コピー再配置データで有効になっているディスプレイスメントは不明となる。
このような問題の診断を助けるため、リンカーは、動的オブジェクトに対してディスプレイスメント再配置が使用されていると、1 つまたは複数の動的 DT_FLAGS_1 フラグを立てます (表 7–44 を参照)。さらに、その可能性のある再配置をリンカーの -z verbose オプションを使って表示することもできます。
たとえば、大域データ項目 bar[]を持つ共有オブジェクトを作成し、このデータ項目にディスプレイスメント再配置が適用されているとします。この項目は、動的実行可能ファイルから参照されると、コピー再配置される可能性があります。リンカーは、この状態に対し次の警告を出します。
$ cc -G -o libfoo.so.1 -z verbose -K pic foo.o ld: warning: relocation warning: R_SPARC_DISP32: file foo.o: symbol foo: \ displacement relocation to be applied to the symbol bar: at 0x194: \ displacement relocation will be visible in output image |
次にデータ項目 bar[] を参照するアプリケーションを作成すると、コピー再配置が行われ、ディスプレイスメント再配置が無効にされる可能性があります。リンカーはこの状況を明示的に検出できるため、z verbose オプションが使用されていなくても、次のエラーメッセージを生成します。
$ cc -o prog prog.o -L. -lfoo ld: warning: relocation error: R_SPARC_DISP32: file foo.so: symbol foo: \ displacement relocation applied to the symbol bar at: 0x194: \ the symbol bar is a copy relocated symbol |
リンカーの -d または -r オプションとともに ldd(1) を使用すると、ディスプレイスメント動的フラグによって同じような再配置警告が生成されます。
このようなエラー状態は、再配置するシンボル定義 (オフセット) と再配置のシンボルターゲットを両方ともローカルに置くことによって避けることができます。静的な定義を使用するか、リンカーの範囲指定を使用してください。シンボル範囲の縮小を参照してください。このような再配置の問題は、機能インタフェースを使用して共有オブジェクト内のデータにアクセスすれば、回避することができます。