リンカーとライブラリ

再配置処理

出力ファイルを作成すると、入力ファイルからのすべてのデータセクションは新しいイメージにコピーされます。入力ファイル内に指定された再配置は、出力イメージに適用されます。生成する必要がある追加の再配置情報も、新しいイメージに書き込まれます。

再配置処理には、通常、大きな問題はありませんが、特定のエラーメッセージを伴うエラー状態が発生することがあります。ここでは、2 つの状態について説明します。1 つは、位置に依存するコードによって発生するテキスト再配置です。この状態の詳細については、「位置独立のコード」を参照してください。もう 1 つは、ディスプレイスメント再配置に関連して発生します。ディスプレイスメント再配置については、次の項で詳しく説明します。

ディスプレイスメント再配置

データ項目 (コピー再配置で使用可能) にディスプレイスメント再配置が適用されていると、エラー状態が発生することがあります。コピー再配置の詳細については、「コピー再配置」を参照してください。

ディスプレイスメント再配置は、再配置されるオフセットと再配置ターゲットが両方とも同じ位置だけ離れているかぎり有効です。コピー再配置では、共有オブジェクト内の大域データ項目が実行可能ファイルの .bss にコピーされます。このコピーは、実行可能ファイルの参照専用テキストセグメントを保持します。コピーされるデータにディスプレイスメント再配置が適用されていたり、外部再配置がコピーされるデータへのディスプレイスメントであったりすると、ディスプレイスメント再配置は無効になります。

ディスプレイスメント再配置の問題を検知するために、次の 2 つの領域で検証が試みられます。

このような問題の診断を助けるため、リンカーは、動的オブジェクトに対してディスプレイスメント再配置が使用されていると、1 つまたは複数の動的 DT_FLAGS_1 フラグを立てます (表 7–34 を参照)。さらに、その可能性のある再配置をリンカーの -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

注 –

ldd(1)-d-r のいずれかのオプションを指定すると、ディスプレイスメント動的フラグによって同じような再配置警告が生成されます。


このようなエラー状態は、再配置するシンボル定義 (オフセット) と再配置のシンボルターゲットを両方ともローカルに置くことによって避けることができます。静的な定義を使用するか、リンカーの範囲指定を使用してください。「シンボル範囲の縮小」を参照してください。この種の再配置の問題は、機能インタフェースを使用して共有オブジェクト内のデータにアクセスすれば、回避することができます。