リンカーとライブラリ

ウィークシンボル

生成中の出力ファイルタイプがどのようなタイプであっても、リンク編集中に結合されないウィークシンボル参照により、重大なエラー状態が発生します。

静的実行可能プログラムを生成中の場合は、シンボルは絶対シンボルに変換され、ゼロの値が割り当てられます。

動的実行可能ファイルまたは共有オブジェクトの作成中の場合は、シンボルは定義されていないウィーク参照として残され、値には 0 が割り当てられます。プロセスの実行中に、実行時リンカーがこのシンボルを検索します。一致が検出されない場合、実行時リンカーは重大な実行時再配置エラーを生成する代わりに、その参照をゼロのアドレスに結合します。

従来は、これらの定義されていないウィーク参照シンボルは、機能の存在をテストするためのメカニズムとして使用されていました。たとえば、次の C コードフラグは、共有オブジェクト libfoo.so.1 内で次のように使用されていました。


#pragma weak    foo

extern  void    foo(char *);

void bar(char * path)
{
        void (* fptr)(char *);

        if ((fptr = foo) != 0)
                (* fptr)(path);
}

アプリケーションが参照 libfoo.so.1 で構築されると、シンボル foo の定義が検出されたかどうかに関係なく、リンク編集は、正常に完了します。アプリケーションの実行中に、機能アドレスがゼロ以外をテストすると、その機能が呼び出されます。ただし、シンボル定義が検出されない場合には、機能アドレスはゼロをテストするため、その機能は呼び出されません。

コンパイルシステムは、定義されないセマンティクスを保持しながら、このアドレスの比較テクニックを参照します。その結果、テストステートメントは最適化処理によって削除されます。さらに、実行時シンボルの結合メカニズムでは、このテクニックの使用にこれ以外の制限も加え、これにより、すべての動的オブジェクトが整合性のあるモデルを使用できる状態ではなくなります。


注 –

未定義のウィーク参照をこのように使用することは避けてください。RTLD_DEFAULT フラグを指定した dlsym(3DL) を使用してシンボルの存在テストを行うことをお勧めします。 機能のテストを参照してください。