| 日本−日本語 |
|
|
|
![]() |
HP-UX リファレンス: セクション 5 : その他の機能 > ddld.so(5)HP-UX 11i Version 2: September 2004 |
|
名称dld.so ― ダイナミックローダー 説明/usr/lib/hpux64/dld.so 共有ライブラリは、64 ビット ダイナミックローダーです。 /usr/lib/hpux32/dld.so 共有ライブラリは、32 ビット ダイナミックローダーです。 共有ライブラリを使用するプログラムでは、 dld.so は起動時に自動的に実行されます。 /usr/ccs/lib/hpux64/crt0.o は、64 ビット 実行時起動ファイルです。 /usr/ccs/lib/hpux32/crt0.o は、32 ビット 実行時起動ファイルです。 /usr/lib/hpux32/uld.so 共有ライブラリと /usr/lib/hpux64/uld.so 共有ライブラリは、それぞれ 32 ビットと 64 ビットのマイクロローダーです。 共有ライブラリを使用するプログラムでは、マイクロローダーは exec(2) によって起動時に自動的に実行されます。 マイクロローダーの唯一の役割は、プログラムの実行のためにダイナミックローダー dld.so をメモリーにロードすることです。 マイクロローダー (uld.so) とダイナミックローダー (dld.so) は、それ自身が共有ライブラリですが、ユーザープログラムで使用するためのシンボルを定義しません。 共有ライブラリ共有ライブラリは、 ld の -b オプションで作成された実行可能ファイルです ld(1) を参照)。 これらのファイルには、位置独立コード (PIC) を含める必要があります。このコードは、プロセスのアドレス空間の任意の場所にマップすることが可能で、最小限の再配置で実行できます。 PIC は、 PC 相対アドレッシングモードとリンクテーブルを使用できます。HP コンパイラは、デフォルトで PIC を生成します。 不完全な実行可能ファイル1 つ以上の共有ライブラリにリンクしている実行可能プログラムを 不完全な実行可能ファイル と呼びます。 オブジェクトファイルやライブラリから実行可能 (a.out) ファイルを作成する際、リンカーは、テキスト (コード) やデータを共有ライブラリから出力ファイルにコピーしません。 その代わりに、ダイナミックローダーが実行時にライブラリをプロセスのアドレス空間にマップします。 リンカーは、すべてのプログラム参照を共有ライブラリルーチンにバインドし、データをリンクテーブルのエントリにバインドします。さらに、ライブラリがマップされた後にダイナミックローダーを使用してリンクテーブルのエントリを埋めます。 このリンクテーブルは、関数呼び出し用のジャンプテーブルとして動作します。 スレッドローカルストレージ静的と動的の 2 つのスレッドローカルストレージ モデルがサポートされています。静的/動的は、コンパイラオプション +tls=static/dynamic によって制御されます。 デフォルトは +tls=dynamic です。 動的モデルによって構築された共有ライブラリは、 dlopen(3C) API と shl_load(3X) API を使用してロードできます。静的モデルによって構築された共有ライブラリを dlopen(3C) API または shl_load(3X) API を使用してロードしようとすると、以下のエラーになります。 /usr/lib/hpux[32|64]/dld.so: Can't shl_load() a library containing ダイナミックローダーは、プログラムのスレッドローカルストレージのサイズを算出するほか、各共有ライブラリのスレッドローカルストレージのサイズも算出します。すべてのライブラリがロードされると、ダイナミックローダーは、システムライブラリ libc のイニシャライザを実行します。これにより、スレッドの初期化、初期スレッドの割り当て、およびスレッドポインタの設定が行われます。 ローディング不完全な実行可能ファイルには、リンク時に検出された共有ライブラリのパス名のリストが含まれます。ダイナミックローダーは、実行時に、プログラムとリンクしているすべての共有ライブラリをプロセスにアタッチします。 ダイナミックローダーは、リンク時に各ライブラリが検出されたディレクトリから各ライブラリをロードしようとします。動的パスリストを指定して、共有ライブラリの実行時検索パスを変更することができます (PA32 互換モードについては、 『「動的パスリスト」』 を参照してください)。 ライブラリのテキストセグメントは、そのセグメントを使用するすべてのプロセスで共有されています。 データセグメントと bss (初期化されていないデータ) セグメントは、ページごとにロードされます。 プロセスがデータページまたは bss ページに初めてアクセス (読み取りまたは書き込み) した時点で、そのページのコピーがそのプロセス用に作成されます。 動的パスリストデフォルトモードのライブラリについては、ダイナミックローダーは、動的パス検索を使用して、プログラムのライブラリリストに名前がある共有ライブラリか、 / 文字が含まれていないロード済み共有ライブラリを検出します。動的パス検索は、これらのライブラリや実行可能ファイルに対しては、デフォルトで有効になっています。 ld +noenvvar が指定された場合は、ダイナミックローダーは、動的パス環境変数を参照せずに依存共有ライブラリを検索します。これにより、動的パス検索は、 rpath (実行時パス、または ld +b コマンドで設定された埋め込みパス) の値と 64 ビットライブラリ用デフォルトディレクトリ /usr/lib/hpux64 または 32 ビットライブラリ用デフォルトディレクトリ /usr/lib/hpux32 に限定されます。 PA32 互換モードライブラリ (ld +compat で構築されたライブラリ、または ld +compat でリンクしたライブラリ) については、ダイナミックローダーは、これらのライブラリが -l または -l: でリンクしていて、なおかつ以下のいずれかが指定された場合にのみ、動的パス検索を実行します。
動的パスリストを指定する方法は複数あります。
パスリストとは、1 つまたは複数のパス名をコロン (:) で区切ったものです。動的パスリストは、 ld の -l または -l: オプションを使用して指定されたライブラリについてのみ動作します。 ただし、 chatr の -l オプションを使用してライブラリの絶対パス名を指定することによって、動的パスリストを有効にすることができます chatr(1) を参照)。 +s と +b の両方を使用した場合は、コマンドラインでの相対順序が、どのパスリストが互換モードで最初に検索されるかを示します。詳細は、 ld(1) の +help オプションまたは 『『HP-UX リンカー & ライブラリー ユーザーズガイド』』 を参照してください。 ダイナミックローダーは、どの動的パスリストを使用するかを決定する際に、以下の規則を使用します。
これらの規則は、依存共有ライブラリの検索では若干異なります。
バインディングさらに、ダイナミックローダーは、実行可能ファイルとライブラリの間のシンボル参照を解決します。 デフォルトでは、関数呼び出しは、リンクテーブルを介してトラップされ、最初の参照時にバインドされます。 データシンボルへの参照や、その他の絶対アドレス参照はトラップできません。 これらは、オブジェクトを参照する可能性のある関数呼び出しの最初の解決時にバインドされます。 ld の -B immediate オプションを使用すると、ローダーは、必要な参照をすべて起動時にバインドします。 これによってプログラムの起動時の負担は増えますが、その後のバインディング処理が不要になります。 したがって、リアルタイム応答性が向上するうえ、未解決の外部参照が原因で実行が中断するというリスクがなくなります。 fastbind ツールを使用して、共有ライブラリ (不完全な実行可能ファイル) を使用するプログラムの起動時間を短縮できます。 fastbind ツールは、シンボルのバインドに使用された共有ライブラリルーチンおよびデータに対する解析を実行し、その情報を実行可能ファイルに保存します。ダイナミックローダーは、この情報が使用可能であることを通知し、標準の検索メソッドの代わりにこの fastbind 情報を使用してシンボルをバインドします。詳細は、 fastbind(1) と、 ld(1) の +help オプション、または 『『HP-UX リンカー & ライブラリー ユーザーズガイド』』 を参照してください。 幅優先探索ダイナミックローダーは、デフォルトでは、シンボルのバインド時に幅優先探索を実行します。不完全な実行可能ファイルが +compat でリンクされている場合、または shl_load() が実行中の場合は、深さ優先探索が使用されます ( 『「深さ優先探索」』 を参照)。 幅優先探索では、ダイナミックローダーは、不完全な実行可能ファイルで始まり、その後にすべてのロード済み共有ライブラリが続くシンボルを、左から右の順序でシンボルが見つかるまで検索します。たとえば、不完全な実行可能ファイルの検索に続いて、そのライブラリ ロードリストにあるすべてのライブラリが検索されます。その後、ライブラリ ロードリストの 1 番目のライブラリの依存共有ライブラリが検索され、さらにリストの 2 番目、3 番目といった具合にライブラリの依存共有ライブラリが続けて検索されます。 バージョン管理共有ライブラリのコードは実行時に別の共有ライブラリファイルからマップされるため、共有ライブラリを修正すると、既存の実行可能ファイルの動作が変わってしまう場合があります。 場合によっては、プログラムが正常に動作しなくなる可能性があります。 ライブラリレベルのバージョン化ユーザーは、命名規則 libname.n を使用して、各自のライブラリのバージョンを管理できます。 n は、ライブラリの新しいリリースごとに増分される数字です。新しい命名スキームを使用する場合は、共有ライブラリの構築時に ld の +h internal_name オプションを使用して、共有ライブラリの内部名を指定する必要があります。この内部名は、その共有ライブラリとリンクする不完全な実行可能ファイルおよび共有ライブラリのそれぞれに記録されます。 ダイナミックローダーは、実行時に、不完全な実行可能ファイルまたは共有ライブラリに記録されたライブラリリストを参照します。 リスト内のライブラリのうち内部名になっていないものについては、ダイナミックローダーは、ロードするライブラリ (たとえば、 libname.0) の .0 バージョンを検索します。このバージョンが見つからなければ、ダイナミックローダーは、リストに記録されているライブラリ名を検索します。 明示的なローディングとバインディングすでに説明したように、ダイナミックローダーの機能はすべて自動的に実行されますが、 ld の適切なオプションを使用することで、多少の制御は可能です。 ダイナミックローダーには、プログラムからアクセスすることもできます。 shl_load(3X)、 dlclose(3C)、 dlerror(3C)、 dlget(3C)、 dlmodinfo(3C)、 dlopen(3C)、 および dlsym(3C) で説明されているルーチンで提供される移植可能なインタフェースを使用すると、プログラマは、実行時に共有ライブラリをプロセスに明示的にアタッチすること、共有ライブラリ内で定義されたシンボルのアドレスを計算すること、およびプロセスの完了時にライブラリを切り離すことが可能です。 グローバルシンボルテーブルグローバルシンボルテーブル機構は、パフォーマンス強化オプションとして設計されています。この機構を有効にすると、グローバルシンボルテーブルが作成されます。グローバルシンボルテーブルにより、シンボルの検索のためにすべてのロード済みライブラリをスキャンする必要がなくなり、シンボルの検索を高速化できます。これは特に、多数の共有ライブラリを使用するアプリケーションで効果的です。この機構は、デフォルトではオフになっています。 グローバルシンボルテーブルは、ハッシュテーブルを使用して実装されます。 グローバルシンボルテーブル機構の下では、暗黙的に、あるいは dlopen() または shl_load() を使用してライブラリがロードされるたびに、この機構によってライブラリのエクスポートがハッシュされ、ハッシュテーブルに配置されます。ライブラリがアンロードされると、ハッシュテーブル内の該当するライブラリのエクスポートが検索され、削除されます。 ハッシュテーブルには、 shl_definesym() で定義されたシンボルのエントリは含まれません。 したがって、ユーザー定義のシンボルは別途処理する必要があります。 この機能を有効にすると、 dld のメモリー使用量が増え、API コールの dlopen()、 dlclose()、 shl_load()、 および shl_unload() のパフォーマンスに影響します。 グローバルシンボルテーブルを使用すると、ダイナミックローダーは、シンボルを配置するために多数のハッシュ処理を実行しなければならない場合があります。このハッシュ関数の実行には非常に時間がかかることがあります (特にシンボル名が極端に長い場合 (C++ プログラム))。 dld を高速化するために、ハッシュ値をリンカーに計算させることができます。 +gst オプションの +gst、 +gstsize、 および +nodynhash を使用すると、グローバルシンボルテーブルのハッシュ機構の動作を制御できます。 これらのオプションについては、 ld(1) および chatr(1) コマンドを参照してください。 これらのオプションを使用すると、 サイズ を調整することにより、パフォーマンスとメモリー使用のバランスを取ることができます。パフォーマンスを最大化するには、連鎖の長さが均一になるようにテーブルサイズを調整します。 パフォーマンスを犠牲にしてメモリーの使用効率を最適化する場合は、空のエントリの数が最少になるようにテーブルのサイズを調整します。テーブルサイズには通常は素数を使用します。 ハッシュテーブルのパフォーマンスに関する統計情報を取得するには、環境変数 _HP_DLDOPTS に -symtab_stat オプションを含めます。 このオプションを使用すると、各ライブラリに関するメッセージに以下の情報が含められます。
PA32 互換モードでのダイナミックローダーの動作ダイナミックローダーは、PA32 の旧リリースとの互換性をサポートするために、いくつかの動作を維持しています。これらの動作は、 ld +compat コマンドと shl_load() ライブラリ管理ルーチンを使用して作成されたプログラムに適用されます。 動的パスリスト動的パスリストの指定には以下の 2 通りの方法があります。
パスリストとは、1 つまたは複数のパス名をコロン (:) で区切ったものです。動的パスリストは、 ld の -l または -l: オプションを使用して指定されたライブラリに対してのみ動作します。 ただし、 chatr の -l オプションを使用してライブラリの絶対パス名を指定することによって、動的パスリストを有効にすることができます chatr(1) を参照)。 +s と +b の両方を使用した場合は、コマンドラインでの相対順序が、どのパスリストが互換モードで最初に検索されるかを示します。詳細は、 ld(1) の +help オプションまたは 『『HP-UX リンカー & ライブラリー ユーザーズガイド』』 を参照してください。 深さ優先探索これは互換モードで使用される検索動作で、 shl_load() を実行している場合、または不完全な実行可能ファイルが +compat でリンクされていた場合に使用されます。 ダイナミックローダーは、不完全な実行可能ファイルを検索し、次にそのライブラリロードリストにある 1 番目のライブラリを検索します。 次にこのライブラリの 1 番目の依存ライブラリを検索し、さらにこの依存ライブラリの 1 番目の依存ライブラリといった具合に検索を続行します。そうして依存ライブラリをすべて検索し終わると、兄弟ライブラリとその依存ライブラリを検索します。 これは、最終的にプログラムのライブラリロードリストの 2 番目のライブラリが検索されるまで続きます。さらにその後、このライブラリの 1 番目の依存ライブラリといった具合に検索を続行します。 診断と警告互換モードですべてのメッセージを表示するには、環境変数 _HP_DLDOPTS に 1 つ以上のオプションを含めます。 以下のオプションがサポートされています。
LD_PRELOAD 環境変数注記: LD_PRELOAD 機能は、 passwd などの seteuid/setegid プログラムに対しては無効になっています。 詳細は、 ld(1) を参照してください。この機能は、完全バインド静的実行可能プログラムでは使用できません。 LD_PRELOAD 環境変数を使用すると、プログラムの起動時に追加の共有ライブラリをロードできます。 LD_PRELOAD は、ダイナミックローダーがインタプリト可能な共有ライブラリのリスト (コロン区切りまたはスペース区切り) を提供します。ダイナミックローダー dld.so は、プログラムが LD_PRELOAD 環境変数で指定された共有ライブラリと明示的にリンクされていたかのように、それらの共有ライブラリを、プログラムのどの依存ライブラリよりも先にロードします。 ダイナミックローダーは、 LD_PRELOAD 環境変数で指定されたライブラリが 1 つまたは複数検出されると、それらを起動時に暗黙的にロードします。ダイナミックローダーは、ライブラリが実行可能ファイルの構築時にリンク行の 1 番目のライブラリとして明示的にリンクされている場合と同様のロード順序およびシンボル解決順序を使用します。たとえば、実行可能ファイルが以下のリンク行で構成されているとします。 $ ld ... lib2.so lib3.so lib4.so LD_PRELOAD="/var/tmp/lib1.so" の場合、ダイナミックローダーは、 lib1.so が以下のリンク行の 1 番目のライブラリとして指定されていた場合と同様のロード順序およびシンボル解決順序を使用します。 $ ld ... /var/tmp/lib1.so lib2.so lib3.so lib4.so 通常のコマンドラインの使用法 (/usr/bin/sh を使用) では、 LD_PRELOAD は以下のように定義されます。 $ LD_PRELOAD=mysl.so application ダイナミックローダーは、アプリケーションの検索では $PATH に従いますが、 mysl.so の検索では SHLIB_PATH、 LD_LIBRARY_PATH、 または埋め込みパス (有効な場合) に従います。 注記: すべての実行可能ファイル (seteuid/setegid プログラムは除く) の実行時に LD_PRELOAD 環境変数がダイナミックローダーによってチェックされるため、 LD_PRELOAD をエクスポートする場合は、実行可能ファイルの実行後にこれを設定解除するか、実行可能ファイルを、前述のコマンドの形式か、あるいはスクリプトの形式で実行する必要があります。 LD_PRELOAD 環境変数を使用して TLS を含む静的スレッドローカル ストレージモデルで構築されている共有ライブラリをロードすると、ライブラリを動的にロードする際に起こる以下のエラーを回避できます。 /usr/lib/hpux[32|64]/dld.so: Can't shl_load() a library containing +tls=dynamic コンパイラオプションを使用してライブラリを再コンパイルすると、このエラーメッセージを回避できます。 PA32 互換モードプログラムでは、ロード順序およびシンボル解決順序が異なる場合があります。これは、ダイナミックローダーが、PA32 モードでは深さ優先探索を使用し、標準モードでは幅優先探索を使用するためです。詳細は、 ld(1) の +help オプションの 『「Symbol Searching and Dependent Libraries」』 または 『『HP-UX リンカー & ライブラリー ユーザーズガイド』』 を参照してください。 リンク行で +noenvvar を使用した場合も、ダイナミックローダーでは LD_PRELOAD 環境変数が使用されます。 その結果、 +compat でリンクされた場合でも、(setuid および setgid プログラムを除いて) LD_PRELOAD の設定は常に有効です。 注記: 共有ライブラリとアーカイブライブラリの両方を使用するアプリケーションで LD_PRELOAD を使用すると、コアダンプが発生する場合があります。特に、共有ライブラリとアプリケーションの両方が aC++ で構築されている場合や、これらが libc を使用している場合に生じます。 LD_PRELOAD 環境変数には複数のライブラリを指定できます。複数のライブラリは、 LD_LIBRARY_PATH の場合と同様に、スペースまたはコロンで区切ります (LD_PRELOAD ライブラリリストにマルチバイト文字は使用できません)。 LD_PRELOAD ライブラリは、絶対パスで指定することも相対パスで指定することもできます。また、 LD_PRELOAD ライブラリはライブラリ名のみで構成することも可能です。その場合、ダイナミックローダーは、環境変数 LD_LIBRARY_PATH または SHLIB_PATH にあるディレクトリパスリストか、埋め込みパスリスト (有効な場合) を使用してライブラリを検索します。 ダイナミックローダーは、 LD_PRELOAD で指定されたライブラリが検出されなかった場合も、エラーメッセージも警告メッセージも発行しません。 ただし、ダイナミックローダーが LD_PRELOAD ライブラリの依存ライブラリを検出できない場合は、 LD_PRELOAD ライブラリがリンク行で指定された場合と同じエラーメッセージが発行されます。 診断ダイナミックローダーが存在しない場合、または何らかの理由でプロセスからダイナミックローダーを実行できない場合は、エラーメッセージが標準エラーに出力され、ゼロ以外の終了コードでプロセスが終了します。 これらのエラーは、2 つの基本カテゴリに分類されます。1 つは、共有ライブラリをアタッチする際のエラー、もう 1 つは、シンボルをバインドする際のエラーです。 前者はプロセスの起動時にのみ発生するものですが、後者は、 ld で -B immediate オプションが 使用されていなければ、プロセス実行中のどの時点でも発生する可能性があります。 共有ライブラリをアタッチする際に発生し得るエラーとしては、「ライブラリが存在しない」、「ライブラリが実行可能でない」、「ライブラリが破損している」、「高ウォーターマークが低すぎる」、「ライブラリ用アドレス空間に十分な余裕がない」などがあります。 シンボルをバインドする際に発生し得るエラーとしては、「シンボルが見つからない (外部参照が未解決)」、「ライブラリが破損している」などがあります。 ダイナミックローダーの明示的ロード機能を使用する場合は、これらのタイプのエラーは致命的とは見なされません。 詳細は、 shl_load(3X)、 dlclose(3C)、 dlget(3C)、 dlgetname(3C)、 dlmodinfo(3C)、 dlopen(3C)、 および dlsym(3C) を参照してください。エラーメッセージを表示するには、 dlerror() ルーチンを使用します。このルーチンは、ダイナミックローダーによって記録された最後のエラーメッセージを出力します。 警告ダイナミックローダーの起動時の負荷は、遅延バインディングを使用した場合でもかなり大きく、起動時の負荷の影響を受けるプロセス (たとえば、単純な ``hello world'' プログラム) では、パフォーマンスが著しく低下する可能性があります。 さらに、たいていの位置独立コードは通常のコードより低速なため、共有ライブラリ内に PIC が存在すると、プログラムのパフォーマンスが低下する場合があります。 ただし、通常はこうした影響よりも、ディスクスペースの使用量が少ないことと、実行可能ファイルに必要なメモリーが少ないことの利点のほうが重要です。 ごく稀に、共有ライブラリを使用する場合とアーカイブライブラリを使用する場合とで、プログラムの動作が異なることがあります。 これは主に、コンパイラ、アセンブラ、またはリンカーの、マニュアルに明示されていない機能やサポートされていない機能を使用した場合に生じます。 詳細は、 ld(1) の +help オプションまたは 『『HP-UX リンカー & ライブラリー ユーザーズガイド』』 を参照してください。 ライブラリ開発者は、バージョン管理の全面的な責任を負うため、互換性のない変更がライブラリインタフェースに加えられないかどうかを徹底的に確認する必要があります。 さもないと、ライブラリの新しいバージョンによってプログラムの予期しない誤動作が発生する可能性があります。 ライブラリ開発者によってバージョン管理が正しく行われていなければ、アプリケーションユーザーにできることはほとんどありません。 通常、アプリケーション開発者は、新しいインタフェースを使用できるようにソースコードを修正し、再コンパイルし、新しいライブラリに対して再リンクすることによって問題を解決できます。 デフォルトでは、ダイナミックローダーではほとんどの警告がレポートされません。 エラーメッセージがすべて表示されるようにするには、環境変数 DLD_VERBOSE_ERR を真 (true) に設定します。 参照システムツール
その他
テキストとチュートリアル
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||