本文に進む 日本−日本語
日本HPホーム 製品とサービス お客様サポート/ ダウンロード ソリューション ご購入の方法
≫ お問い合わせ
詳細検索オプション
日本HPホーム
HP-UX リファレンス: セクション 5 : その他の機能 > d

dld.sl(5)

HP-UX 11i Version 2: September 2004
≫ 

テクニカル ドキュメント

PDF版
フィードバック
ここから本文が始まります

 ≫ 目次

 ≫ 索引

名称

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 通りの方法があります。

  • ld に対して +b の path_list オプションを使用し、実行可能ファイルにディレクトリのパスリストを格納する方法

  • 実行時に環境変数 SHLIB_PATH を定義して実行可能ファイルでパスリストを使用できるようし、 ld のオプション +s を使用して実行可能ファイルをリンクする方法

パスリストは、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: でリンクされ、また次のいずれかが指定されている場合、ダイナミックローダは動的パス検索だけを行います。

  • ld +s

  • ld +b

  • chatr +s enable

動的パスリストを指定するには、次のように複数の方法があります。

  • ld に対してオプション +b path_list を使用して、実行可能ファイル内にディレクトリパスリストを保存する方法

  • ld +b指定せず に、リンカーが rpath 値に ld -L path_list、次に環境変数 LPATH の値、その後デフォルトディレクトリ /usr/lib/pa20_64 および /usr/ccs/lib/pa20_64 を連結して設定する方法。 これは、標準モードの共有ライブラリに対してだけ有効です。

  • LD_LIBRARY_PATH および SHLIB_PATH の両方またはどちらかの環境変数にディレクトリの path_list を保存する方法。互換モードの共有ライブラリおよび実行可能ファイルの場合、ディレクトリの path_list は SHLIB_PATH 環境変数内に入れなければなりません。

パスリストは、コロン (:) で区切られた 1 つまたは複数のパス名のリストです。 動的パスリストは、 ld に対してオプション -l または -l: を指定したライブラリにのみ動作します。 しかし、 chatr-l オプションを使用し、絶対パス名を指定したライブラリに使用することも可能です (chatr(1) を参照)。 +s+b の両方を使用した場合は、コマンド行での相対順序によって、互換モードでどのパスリストが最初に検索されるかを示します。 詳細は、 ld(1)+help オプションと 『HP-UX リンカー & ライブラリー ユーザーズガイド』を参照してください。

ダイナミックローダは、使用する動的パスリストを決定する際に、次の規則に従います。

  • ld +noenvvar が指定され、 ld +bld +compat指定されていない 場合、実行できる動的パス検索は、 rpath 、次に、デフォルトディレクトリ /usr/lib/pa20_64 および /usr/ccs/lib/pa20_64 内での path_list を検索します。

  • ld +compat が指定されていて、 ld +bld +s指定されていない 場合、共有ライブラリは、動的パス検索の対象にはなりません。

  • ld +compat および ld +b オプションが指定されていない 場合、 LD_LIBRARY_PATH 環境変数内の path_list、次に SHLIB_PATH 環境変数内の path_list、 rpath 内の path_list、その後、デフォルトディレクトリ /usr/lib/pa20_64 および /usr/ccs/lib/pa20_64 という順で検索されます。

  • ld +compatld +b、 および ld +s が指定されている場合、ダイナミックローダは、 ld +bld +s の相対順序に従って、 rpath 内の path_list、 SHLIB_PATH 、ライブラリリスト内のライブラリを検索します。 ld +b が最初に指定されている場合は、 rpath 内の path_list を最初に使用します。

従属共有ライブラリを探す際には、規則はわずかに変わります。

  • 標準モードのライブラリの場合、 LD_LIBRARY_PATH 環境変数内の path_list が最初に検索され、次に SHLIB_PATH 環境変数内の path_list、親の共有ライブラリの rpath 内の値、その後、デフォルトディレクトリ /usr/lib/pa20_64 および /usr/ccs/lib/pa20_ の順に検索されます。 親の共有ライブラリの祖先が rpath 内の path_list を含む可能性がありますが、 これは、この親の従属共有ライブラリの検索の際には無視され、親の rpath だけが使用されます。

  • 互換モードのライブラリの場合、 rpath を親の共有ライブラリから子の従属共有ライブラリへ、さらにその子の従属共有ライブラリへと引き渡すことができることを除けば、検索は親の共有ライブラリの場合の検索と同じです。

バインド

ダイナミックローダは実行可能ファイルとライブラリ との間のシンボル参照も解決します。デフォルトでは、 関数コールはリンケージテーブルを通してトラップされ、 最初の参照にバインドされています。データシンボルや絶対アドレスへの参照はトラップされません。 それらは、 オブジェクトを参照している可能性のある最初の関数コールの解決先のバインド されています。

-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 つ以上のオプションを設定する必要があります。 次のようなオプションをサポートしています。

-warnings 

追加のダイラミックローダの警告メッセージを表示します。 これには次のようなものがあります。

  • 同じ名前のシンボルだが、例えば CODE や DATA などの異なる型のものについて。 この警告についての詳細は、 ld(1) の「 警告 」の項を参照してください。

  • shl_load(3X) に記述された特定のフラグやルーチンを使用する場合

-fbverbose 

fastbind(1) を参照

-nofastbind 

fastbind(1) を参照

PA64 では、すべてのメッセージを参照するには環境変数 DLD_VERBOSE_ERR を true に設定する必要があります。

著者

/usr/lib/dld.sl および /usr/lib/pa20_64/dld.sl 共有ライブラリは HP で開発されました。

参照

システムツール

aCC(1) 

HP-UX aC++ コンパイラの呼び出し

as(1) 

アセンブリコードからマシンコードへの変換

CC(1) 

HP-UX C++ コンパイラの実行

cc(1) 

HP-UX C コンパイラの実行

chatr(1) 

プログラムの内部属性の変更

f77(1) 

HP-UX FORTRAN コンパイラの実行

f90(1) 

HP-UX Fortran 90 コンパイラの呼び出し

fastbind(1) 

fastbind ツールの実行

ld(1) 

リンクエディタの実行

pc(1) 

HP-UX Pascal コンパイラの実行

その他

a.out(4) 

アセンブラ, コンパイラ, およびリンカの出力

dlclose(3C) 

dlopen() によって以前にロードした共有ライブラリのアンロード

dlerror(3C) 

dld によって最後に記録されたエラーメッセージの出力

dlget(3C) 

ロードされているモジュールに関する情報を戻す

dlgetname(3C) 

ロードモジュールを含む記憶装置の名前を戻す

dlmodinfo(3C) 

ロードモジュールに関する情報を戻す

dlopen(3C) 

共有ライブラリのロード

dlsym(3C) 

共有ライブラリ内のシンボルのアドレスの取得

shl_load(3X) 

共有ライブラリのロード/アンロード

テキストおよび指導書

『HP-UX リンカー & ライブラリー オンライン ユーザーズガイド』
  

ld(1) に対する +help オプションを参照)

『HP-UX リンカー & ライブラリー ユーザーズガイド』
  

印刷用画面へ
プライバシー 本サイト利用時の合意事項
© 1983-2004 Hewlett-Packard Development Company, L.P.