Go to main content
Oracle® Solaris 11.3 リンカーとライブラリガイド

印刷ビューの終了

更新: 2015 年 10 月
 
 

使用されない対象物の削除

入力再配置可能オブジェクトファイルから関数およびデータを取り込んでも、構築されているオブジェクトで使用されない場合は無駄になります。この使用されない対象物によってオブジェクトが必要以上に肥大し、実行時にそのオブジェクトを使用するときのオーバーヘッドが増加します。

使用されない共有オブジェクト依存関係への参照も無駄です。特に遅延読み込みがない場合は、これらの参照によって実行時にこれらの共有オブジェクトの不必要な読み込みと処理が生じます。

未使用のセクション、未使用の再配置可能オブジェクトファイル、および未使用の共有オブジェクト依存関係は、リンク編集時にリンカーの –D unused デバッグオプションを使用して診断できます。

未使用のファイルと依存関係は、–z guidance オプションを使用したときにも診断されます。

未使用のセクション、未使用のファイル、および未使用の依存関係は、リンク編集から削除すべきです。この削除によって、リンク編集のコストが減少し、構築中のオブジェクトを実行時に使用するコストも減少します。ただし、これらの項目の削除に問題がある場合は、–z discard-unused オプションを使用すると、未使用の対象物を構築中のオブジェクトから破棄できます。

未使用セクションの削除

入力再配置可能オブジェクトファイルに含まれる ELF セクションは、3 つの条件が真である場合に未使用と判定されます。

  • そのセクションは、大域シンボルを提供しません。

  • そのセクションは、割り当て可能なセグメントで使用されます。

  • そのセクションは、リンク編集で使用される (任意のオブジェクトに含まれる) ほかの使用済みセクションによって参照されません。

未使用セクションをリンク編集から破棄するには、–z discard-unused=sections オプションを使用します。

動的オブジェクトの外部インタフェースを定義することにより、未使用セクションを診断して破棄するリンカーの機能を向上させることができます。Chapter 10, インタフェースおよびバージョン管理を参照してください。インタフェースを定義すると、インタフェースの一部として定義されていない大域シンボルが局所に限定されます。ほかのオブジェクトから参照されない限定されたシンボルは、破棄の対象として明確に識別されます。

関数やデータ変数が独自のセクションに割り当てられている場合、リンカーはこれらの項目を個別に破棄できます。このセクション改良は、–xF コンパイラオプションを使用して実現できます。

未使用ファイルの削除

入力再配置可能オブジェクトファイルは、再配置可能オブジェクトによって提供されるすべての割り当て可能セクションが未使用である場合に、未使用と判定されます。

未使用ファイルは、–z guidance オプションで診断され、–z discard-unused=files オプションを使用してリンク編集から破棄できます。

–z discard-unused オプションは、–z guidance の処理を補完するために、未使用セクションと未使用ファイルを独立して制御します。–z guidance では、未使用と判定されるファイルが識別されます。未使用ファイルは、多くの場合、リンク編集から簡単に削除できます。しかし、未使用と判定されるセクションは –z guidance の処理では識別されません。未使用セクションは、削除するためにより多くの調査と作業が必要であり、ユーザーが制御できないコンパイラ動作の結果として生じる可能性があります。

–z guidance オプションとともに –z discard-unused=sections オプションを使用すると、未使用セクションは自動的に削除されますが、未使用ファイルはリンク編集から削除する対象として識別されます。

未使用の依存関係の削除

明示的な共有オブジェクト依存関係は、コマンド行でパス名または (より一般的には) –l オプションを使用して定義されます。明示的な依存関係には、コンパイラドライバ (–lc など) によって提供された可能性があるものも含まれます。

暗黙の依存関係は、明示的な依存関係の依存関係です。暗黙の依存関係は、すべてのシンボル解決の封じ込めを完成させるため、リンク編集の一部として処理できます。このシンボルの封じ込めにより、構築中のオブジェクトが自己完結型であり、未参照のシンボルが残っていないことが保証されます。

すべての動的オブジェクトは、必要な依存関係を定義すべきです。この要件は、動的実行可能ファイルを構築するときはデフォルトで適用されますが、共有オブジェクトを構築するときには適用されません。共有オブジェクトを構築するときにこの要件を適用するには、–z defs オプションを使用します。

どの動的オブジェクトでも、必要としない依存関係を定義することは避けてください。実行時にこのような未使用の依存関係をロードすることは不要であり無駄です。

明示的な依存関係は、2 つの条件が真である場合に未使用と判定されます。

  • その依存関係によって提供される大域シンボルが、構築中のオブジェクトから参照されていません。

  • その依存関係は、暗黙の依存関係の要件を補いません。

未使用の依存関係は、–z guidance オプションを使用して診断します。これらの依存関係はリンク編集から削除してください。ただし、これらの項目の削除に問題がある場合は、–z discard-unused=dependencies オプションを使用すると、未使用の依存関係を構築中のオブジェクトから破棄できます。

残念ながら、必要とする一部の依存関係を定義していない共有オブジェクトが存在しています。これらの場合、開発者はしばしば、元の依存関係を正確に再構築するのではなく、失われた依存関係を実行可能ファイルや構築しているほかの共有オブジェクトに追加します。このような依存関係は、補完依存関係と呼ばれます。

たとえば、共有オブジェクト bar.so からシンボル bar() を参照する共有オブジェクト foo.so を考えてみます。ただし、foo.so には bar.so への依存関係が示されていません。foo.so を調べた結果、シンボル bar() が見つからないので必要な依存関係が欠如しているとわかります。

% ldd -r foo.so
     libc.so.1 =>     /lib/libc.so.1
     symbol not found: bar           (foo.so)

ここで、共有オブジェクト foo.so からシンボル foo() を参照する実行可能ファイルを作成する必要のあるアプリケーション開発者を考えてみます。foo.so への必要な依存関係を指定しますが、実行可能ファイルのリンク編集は失敗します。

% cc -Bdirect -o main main.c -L. -lfoo
Undefined                       first referenced
  symbol                             in file
  bar                                 ./libfoo.so
ld: fatal: symbol referencing errors

開発者は、bar.so への補完依存関係を追加して、この状況を強制的に修正します。

% cc -Bdirect -o main main.c -L. -lfoo -lbar

この修正によって、実行時に必要なすべて依存関係をロードするアプリケーションが作成され、問題は解決したように見えます。ただし、この結果は盤石ではありません。将来、bar.so からのシンボルを必要としない foo.so が配信されれば、このアプリケーションは理由もなく bar.so をロードすることになります。より適切な解決方法は、失われた依存関係 bar.so を追加して foo.so を修正するというものです。

補完依存関係の出現はガイダンスを通じて診断されます。

% cc -Bdirect -zguidance -o main main.c -L. -lfoo -lbar
ld: guidance: removal of compensating dependency recommended: libbar.so

補完依存関係はガイダンスを通じて診断されますが、–z discard-unused=dependencies から削除されません。依存関係は作成されているオブジェクトに関して使用されない場合もありますが、リンク編集のほかのコンポーネントで使用されます。この依存関係を削除すると、実行時に実行できないオブジェクトが作成されることになります。

補完依存関係は、計画的に –z defs オプションを使用してすべての動的オブジェクトを構築することで不要になります。

–z ignore および –z record オプションは、–z discard-unused=dependencies オプションと組み合わせて使用できる定位置オプションです。これらの定位置オプションは、対象となるオブジェクトを選択して、破棄機能をオンまたはオフにします。