| 日本−日本語 |
|
|
|
![]() |
HP-UX リファレンス: セクション 5 : その他の機能 > ddld.sl(5)HP-UX 11i Version 2: September 2004 |
|
名称dld.sl ― ダイナミックローダ 説明/usr/lib/pa20_64/dld.sl プログラムは、PA64 のダイナミックローダです。 /usr/lib/dld.sl プログラムは、PA32 のダイナミックローダです。 共有ライブラリを使用するプログラムでは、PA64 では exec が、また PA32 では起動ファイル crt0.o が自動的に dld.sl を呼び出します。 crt0.o と同じコピーが、 /opt/langtools/lib および /usr/ccs/lib ディレクトリの両方に保存されています。 ダイナミックローダは ユーザープログラムが使うシンボルを定義していませんが、 それ自身が共有ライブラリです。 共有ライブラリ共有ライブラリは -b オプションを ld ld(1) を参照) に付けることで生成される実行可能ファイルです。 その内部には、 プロセスのアドレス空間のどこにでもマップでき、 最小の再配置で実行できる 位置独立コード (PIC) が含まれていなければなりません。 PIC は PC 相対アドレッシングモードとリンケージテーブル を使います。 この共有ライブラリは、PA64 ではコンパイラにより、PA32 では +z/+Z オプションを指定することによって、デフォルトで生成されます。 PIC をアセンブリ言語で記述するための詳細は、 ld(1) の +help オプションと 『HP-UX リンカー & ライブラリー ユーザーズガイド』マニュアルを参照してください。 不完全実行可能ファイル1 つ以上の共有ライブラリとリンクされた実行可能プログラムを 不完全実行可能ファイル と呼びます。 オブジェクトファイルとライブラリから 実行可能ファイル (a.out) を生成するとき、リンカは共有ライブラリから出力ファイル へはテキスト (コード) またはデータをコピーしません。 その代わりに、ダイナミックローダは 実行時にライブラリをプロセスのアドレス空間 にマップします。リンカは、共有ライブラリルーチンおよびデータへのプログラムの 参照をリンケージテーブルのエントリーにバインドし、ライブラリがマップさ れたときにリンケージテーブルのエントリーを埋めるのをダイナミックローダ に任せます。 このリンケージテーブルは関数呼び出しのジャンプテーブルとして働きます。 スレッドのローカル記憶領域がサポートされるようになりました。 ダイナミックローダは、各共有ライブラリのスレッドローカル記憶領域サイズと、プログラムのスレッドローカル記憶領域サイズを数え上げます。 PA32 では、ライブラリをすべてロードし終わると、ダイナミックローダは、スレッドポインタ設定と領域の割り当てを行うスレッド初期化ルーチンを呼び出します。あるいは、直接 mmap() と lwp_setprivate() を呼び出して領域を割り当て、スレッドポインタを設定することもあります。 PA64 では、ダイナミックローダは、システムライブラリ libc 内にあるイニシャライザを呼び出し、スレッドの初期化、最初のスレッドの割り当て、スレッドポインタの設定を行います。 以前の PA32 では、プログラムが参照する共有ライブラリのデータアイテムは データの参照が静的に解決されるように実行可能ファイル の中にコピーされました。シリーズ 700/800 ワークステーションで 稼動する 10.0 以降の HP-UX から、a.out からの共有ライブラリのデータへの参照はリンクテーブルに含まれており、実行時に解決されます。 ロード不完全な実行可能ファイルには、リンク時に検索された共有ライブラリのパス名リストがあります。 実行時に、ダイナミックローダは プロセスをプログラムにリンクされたすべての共有ライブラリ とつなげます。 ダイナミックローダは、リンク時に検出したライブラリのあるディレクトリから、 各ライブラリをロードしようとします。 動的パスリストを指定して共有ライブラリ実行時検索パスを変更することが可能です。 『PA32』 の動的パスリスト および 『PA64』 の動的パスリスト を参照してください。 ライブラリのテキストセグメントは、そのライブラリを使用するすべてのプロセス間で共有されます。データセグメントおよび bss セグメントは、ページ単位で共有されます。プログラムが最初にデータまたは bss ページをアクセス (読み込みまたは書き込み) した時点で、そのページのコピーがそのプロセスのために作成されます。 PA32 の動的パスリスト動的パスを検索するには、2 通りの方法があります。
パスリストは、1 つのパス名またはコロン (:) で区切られた複数のパス名のリストです。 動的パスリストは、 ld に対してオプション -l を使用して指定したライブラリのみに動作します。 しかし、 chatr のオプション -l を使用した絶対パス名で指定することで、ライブラリを使用可能にすることができます chatr(1) を参照)。 +s と +b の両方を使用した場合は、コマンド行での相対順序が互換モードで最初に検索されるパスリストを示します。 詳細は、 ld(1) の +help オプションと 『HP-UX リンカー & ライブラリー ユーザーズガイド』を参照してください。 PA64 の動的パスリスト標準モードのライブラリ (ld +std で作成またはリンクされたライブラリ) の場合、ダイナミックローダは、動的パス検索を使用して、プログラムのライブラリリスト内に名前のある共有ライブラリ、または、 / 文字を含んでいないロード済みの共有ライブラリを探します。これらの標準モードのライブラリまたは実行可能ファイルに対して、動的パス検索がデフォルトで使用できます。 ld +noenvvar が指定されている場合には、ダイナミックローダは、従属する共有ライブラリを探すために動的パス環境変数を調べません。このため動的パス検索は rpath という値およびデフォルトディレクトリ /usr/lib/pa20_64 および /usr/ccs/lib/pa20_64 に限定されます。 互換モードのライブラリ (ld +compat で作成またはリンクされるライブラリ) では、ライブラリが -l または -l: でリンクされ、また次のいずれかが指定されている場合、ダイナミックローダは動的パス検索だけを行います。
動的パスリストを指定するには、次のように複数の方法があります。
パスリストは、コロン (:) で区切られた 1 つまたは複数のパス名のリストです。 動的パスリストは、 ld に対してオプション -l または -l: を指定したライブラリにのみ動作します。 しかし、 chatr に -l オプションを使用し、絶対パス名を指定したライブラリに使用することも可能です (chatr(1) を参照)。 +s と +b の両方を使用した場合は、コマンド行での相対順序によって、互換モードでどのパスリストが最初に検索されるかを示します。 詳細は、 ld(1) の +help オプションと 『HP-UX リンカー & ライブラリー ユーザーズガイド』を参照してください。 ダイナミックローダは、使用する動的パスリストを決定する際に、次の規則に従います。
従属共有ライブラリを探す際には、規則はわずかに変わります。
バインドダイナミックローダは実行可能ファイルとライブラリ との間のシンボル参照も解決します。デフォルトでは、 関数コールはリンケージテーブルを通してトラップされ、 最初の参照にバインドされています。データシンボルや絶対アドレスへの参照はトラップされません。 それらは、 オブジェクトを参照している可能性のある最初の関数コールの解決先のバインド されています。 -B immediate オプションを ld に付けると、ローダは必要な参照をすべて起動時にバインド します。これはプログラムのスタート時のコストを増大させますが、 その後はこれ以上バインド操作が必要とされないことを保証します。 つまり、実行時の応答が向上し、解決されない外部参照のために 後から実行を放棄する危険を取り除きます。 fastbind ツールを使用して、共有ライブラリを使用するプログラム (不完全な実行可能ファイル) の起動時間を改善することができます。 fastbind ツールは、シンボルをバインドするのに使用するライブラリのルーチンとデータを解析し、 この情報を実行可能ファイルに格納します。 ダイナミックローダはこの情報を使用できることを通知し、 この fastbind 情報を標準の検索方法の代わりに使用してシンボルをバインドします。 詳細は、 fastbind(1) と、 ld(1) に対する +help オプション、または 『HP-UX リンカー & ライブラリー ユーザーズガイド』マニュアルを参照してください。 同レベルの従属ライブラリの検索これは、PA64 でのみ使用可能です。デフォルトでは、ダイナミックローダは、シンボルをバインドする際に、同レベルの従属ライブラリの順に検索を実行します。不完全実行可能ファイルを +compat でリンクした場合、または shl_load() を実行している場合は、従属順に検索されます。 同レベルの従属ライブラリの検索は、ダイナミックローダがシンボルの検索を不完全実行可能ファイルから始めて、そのシンボルが見つかるまで、すべてのロード済みの共有ライブラリを右から左への順で検索していくことを指定します。 例えば、不完全実行可能ファイルが検索され、次に、そのライブラリ のロードリスト内のすべてのライブラリが検索されます。その後、ライブラリのロードリスト内の最初のライブラリの従属共有ライブラリが検索され、さらに、リストの 2 番目のライブラリの従属共有ライブラリという順で検索が続きます。 従属順の検索PA32 では唯一の検索方法ですが、PA64 では、 shl_load() を実行している場合、または、不完全実行可能ファイルを +compat でリンクした場合に使用されます。 ダイナミックローダは、不完全実行可能ファイルを検索し、次に、そのライブラリのロードリスト内の最初のライブラリを検索します。 この後、このライブラリの最初の従属ライブラリが検索され、さらに、この従属ライブラリの最初の従属ライブラリという順で検索が続きます。 従属ライブラリがそれ以上なくなると、兄弟ライブラリおよびその従属ライブラリが検索されます。結果的に、そのプログラムのライブラリのロードリスト内の 2 番目のライブラリが検索され、次に、このライブラリの最初の従属ライブラリという順で検索が続きます。 バージョン管理共有ライブラリからのコードが実行時に独立した共有ライブラリファイルからマップされるので、共有ライブラリ の変更はすでに存在する実行可能ファイル の動作を変えてしまうことがあります。 場合によってはプログラムが正しく動かなくなることもあります。 2 つのバージョン管理の手段はこの問題を解決するために用意されています。 1. 内部バージョン管理これは、PA32 のみで有効です。 ライブラリインタフェースに互換性のない変更が加えられたときは常に、 影響を受けた 1 つまたは複数のモジュールの両方のバージョンが ライブラリに含まれます。 変更が行なわれた日 (月/年) を示すマークが新しいモジュールに C のプラグマ HP_SHLIB_VERSION または FORTRAN および Pascal のコンパイラディレクティブ SHLIB_VERSION を通して記録されます。 この日付はモジュールの中で定義されたすべてのシンボルに適用されます。 互換性のない変更の最後の日付を与える高水標 が共有ライブラリに記録され、プログラムにリンクされた各ライブラリ の高水標が不完全実行可能ファイルに記録されます。 実行時に、ダイナミックローダは 各ライブラリの高水標を調べ、リンク時に記録された 高水標と同じ新しさであればライブラリをロードします。 シンボル参照をバインドするとき、ローダはリンク時に記録された 高水標よりは後でないうちで最も後のバージョンのシンボ ルを選択します。 この 2 つのチェックは実行時に使われる各ライブラリインタフェースのバージョン がリンク時に期待されたものと同じであることを保証します。 内部バージョン管理は、将来削除される可能性があります。 2. ライブラリレベルのバージョン管理ユーザーがライブラリのバージョン管理行うための 2 つ目の方法では、新しい命名規則 libname.n を使います。この場合、n は、新しくライブラリが提供されるたびに増加していきます。新しい命名規則を使うときには、ユーザーは、共有ライブラリの作成時に ld の +h internal_name オプションを使って、共有ライブラリの内部名称を 指定しなければなりません。 この内部名称は、共有ライブラリとリンクする、不完全な実行可能ファイルや 別の共有ライブラリにそれぞれ記録されます。 実行時に、ローダは不完全な実行可能ファイルや共有ライブラリに記録されたライブラリリストを参照します。リスト内の、内部名称が指定されていない各ライブラリに対しては、ダイナミックローダは、拡張子 .0 が付いたライブラリを探してロードします (例えば、libname.0)。 この拡張子が付いたライブラリが見つからない場合、ダーナミックローダはリスト内に記録されたライブラリ名を探します。 PA32 の明示的なロードとバインド上記のようなダイナミックローダの仕事は、 ld に適切なオプションを付けることで何らかの制御はできますが、 すべては自動的に実行されます。 ダイナミックローダはプログラムによってアクセスすることもできます。 crt0.o に定義された予約シンボル __dld_loc, はダイナミックローダの中のジャンプテーブルを指しています。 shl_load(3X) に記述されたルーチンは、 プログラマが明示的に共有ライブラリを実行時に プロセスにつなげ、共有ライブラリの中で定義されたシンボルの アドレスを計算し、実行が終ったらライブラリを切り離すための 移植可能なインタフェースを提供します。 PA64 の明示的なロードとバインド上記のようなダイナミックローダの仕事は、 ld に適切なオプションを付けることで何らかの制御はできますが、 すべては自動的に実行されます。 ダイナミックローダはプログラムによってアクセスすることもできます。 shl_load(3X)、 dlclose(3C)、 dlerror(3C)、 dlget(3C)、 dlmodinfo(3C)、 dlopen(3C)、 および dlsym(3C) に記述されたルーチンは、 プログラマが明示的に共有ライブラリを実行時に プロセスにつなげ、共有ライブラリの中で定義されたシンボルの アドレスを計算し、実行が終ったらライブラリを切り離すための 移植可能なインタフェースを提供します。 グローバルシンボルテーブルグローバルシンボルテーブル機構は、性能向上オプションとして設計されています。この機構を使用可能にすると、グローバルシンボルテーブルを作成することができます。グローバルシンボルテーブルを使用すると、ロードされたライブラリをすべて走査しなくてもシンボルを検索できるため、シンボルのルックアップを高速に処理することができます。これは、多数の共有ライブラリをもつアプリケーションにはとくに有効です。デフォルトでは、この機構はオフに設定されています。 グローバルシンボルテーブルは、ハッシュテーブルを使って実現されています。この機構により、(暗黙のうちに、あるいは、 dlopen() または shl_load() を使用して) ライブラリがロードされる時にはいつでも、ライブラリのエクスポートがハッシングされ、その後でこのテーブルに保存されます。ライブラリがアンロードされる場合は、テーブル内のライブラリのエクスポートが検索されて、削除されます。 ハッシュテーブルには、 shl_definesym() によって定義されたシンボルのエントリーは含まれません。したがって、ユーザー定義のシンボルは別に処理する必要があります。 この機能を使用可能にすると、 dld のメモリ使用量が増え、 dlopen()、 dlclose()、 shl_load()、 および shl_unload() の各 API コールの性能に影響を与えます。 グローバルシンボルテーブルを使用する場合、ダイナミックローダはシンボルを探すために大量のハッシング操作を実行しなければならないことがあります。このようにハッシュ機能を使用すると、とくにシンボル名が非常に長い場合に (C++ プログラム) 相当の時間がかかります。 dld の処理を速めるために、ハッシュ値の計算をリンカーに任せることができます。 +gst オプション、 +gst、 +gstbuckets (32 ビットのみ)、 +gstsize、 +nodynhash (64 ビットのみ)、 および +plabel_cache (32 ビットのみ) を使用して、 グローバルシンボルテーブルのハッシュ機構の動作を制御します。これらのオプションの詳細については、 ld(1) および chatr(1) の各コマンドを参照してください。 これらのオプションを指定すると、ハッシュテーブルのサイズ とエントリーごとのバケット数 を調整して、性能とメモリ使用量のバランスを取ることができます。性能を最大化するには、テーブルサイズを平均チェーン長 1 に調整します。 性能を犠牲にしてメモリ使用量を最大化するには、空エントリー数が最小になるようにテーブルサイズを調整します。 通常は、テーブルサイズに素数を使用します。デフォルト値は、テーブルサイズが 1103、バケット数が 3 です。 ハッシュテーブルの性能に関する統計情報を取得するには、環境変数 _HP_DLDOPTS に -symtab_stat オプションを指定します。 このオプションは、ライブラリごとに以下の情報を含むメッセージを提供します。
診断ダイナミックローダが存在しないか、何らかの理由でプロセス から実行できない場合は、エラーメッセージ が標準エラーに出力され、プロセスは 0 でない 終了コードで終了します。 エラーには基本的に 2 つの種類に分類されます。 それは、共有ライブラリに接続するときのエラーと シンボルをバインドするときのエラーです。 前者はプロセスが起動される時点でのみ起こり得ますが、後者は、 ld に -B immediate オプションを付けなければ、プロセスの実行時にいつでも 起こり得ます。 共有ライブラリの接続時に起こる可能性のあるエラー には、ライブラリが存在しない、ライブラリが実行可能ファイル でない、ライブラリが破壊されている、高水標 が低すぎる、アドレス空間にライブラリの入る空きがない、 というものがあります。 シンボルのバインド時に起こる可能性のあるエラー には、シンボルが見つからない (解決できない外部参照)、ライブラリ が破壊されている、というものがあります。 ダイナミックローダの明示的ロード機能を使うときには、 これらのエラーは致命的なものとはみなされません。 エラー処理についての詳細は、 shl_load(3X)、 dlclose(3C)、 dlget(3C)、 dlgetname(3C)、 dlmodinfo(3C)、 dlopen(3C)、 および dlsym(3C) を参照してください。 PA64 では、エラーメッセージを表示するために、 dlerror() ルーチンを使用します。このルーチンは、ダイナミックローダによって最後に記録されたエラーメッセージを出力します。 警告ダイナミックローダの起動時のコストは、遅延バインド を使ってもなお重大であり、起動時のコストが主になっているような (簡単な ``hello world''プログラムのような) プロセスにおいては 重大な性能低下になります。 さらに、位置独立コードは大抵通常のコード よりも遅いので、 共有ライブラリの中に PIC があることが性能に不利に働くことが考えられます。 しかし、実行可能ファイルに必要な ディスクスペース使用量とメモリの節約の利点は多くの場合 それらのことより重要です。 アーカイブライブラリの代わりに共有ライブラリ を使ったときにプログラムの動作が変わることが稀にあります。 これは主にコンパイラ、アセンブラ、リンカの ドキュメントにないサポートされていない機能を使っている 場合に起きます。 詳細は、 ld(1) に対する +help オプションと 『HP-UX リンカー & ライブラリー ユーザーズガイド』マニュアルを参照してください。 ライブラリの開発者はバージョン管理に関してすべて責任を持ち ライブラリインタフェースの互換性のない変更を常に認識していなければなりま せん。そうでなければ、プログラムが後のバージョンのライブラリ で予期せぬ誤動作を起こす可能性があります。 バージョン管理がライブラリ開発者によって適切に行われていなけれ ば、ユーザーが使えるアプリケーションは少ないでしょう。 アプリケーション作成者は通常 新しいインタフェースを使うためにソースコード を変更し、新しいライブラリを使って再コンパイル 、再リンクすることで問題を解決できます。 デフォルトでは、ダイラミックローダはほとんどの警告を報告しません。 PA32 では、すべてのメッセージを参照するには環境変数 _HP_DLDOPTS に 1 つ以上のオプションを設定する必要があります。 次のようなオプションをサポートしています。
PA64 では、すべてのメッセージを参照するには環境変数 DLD_VERBOSE_ERR を true に設定する必要があります。 参照システムツール
その他
テキストおよび指導書
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||