OSDN Git Service

Update README
[linuxjm/LDP_man-pages.git] / draft / man3 / dlopen.3
1 .\" Copyright 1995 Yggdrasil Computing, Incorporated.
2 .\" written by Adam J. Richter (adam@yggdrasil.com),
3 .\" with typesetting help from Daniel Quinlan (quinlan@yggdrasil.com).
4 .\" and Copyright 2003 Michael Kerrisk (mtk.manpages@gmail.com).
5 .\"
6 .\" %%%LICENSE_START(GPLv2+_DOC_FULL)
7 .\" This is free documentation; you can redistribute it and/or
8 .\" modify it under the terms of the GNU General Public License as
9 .\" published by the Free Software Foundation; either version 2 of
10 .\" the License, or (at your option) any later version.
11 .\"
12 .\" The GNU General Public License's references to "object code"
13 .\" and "executables" are to be interpreted as the output of any
14 .\" document formatting or typesetting system, including
15 .\" intermediate and printed output.
16 .\"
17 .\" This manual is distributed in the hope that it will be useful,
18 .\" but WITHOUT ANY WARRANTY; without even the implied warranty of
19 .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 .\" GNU General Public License for more details.
21 .\"
22 .\" You should have received a copy of the GNU General Public
23 .\" License along with this manual; if not, see
24 .\" <http://www.gnu.org/licenses/>.
25 .\" %%%LICENSE_END
26 .\"
27 .\" Modified by David A. Wheeler <dwheeler@dwheeler.com> 2000-11-28.
28 .\" Applied patch by Terran Melconian, aeb, 2001-12-14.
29 .\" Modified by Hacksaw <hacksaw@hacksaw.org> 2003-03-13.
30 .\" Modified by Matt Domsch, 2003-04-09: _init and _fini obsolete
31 .\" Modified by Michael Kerrisk <mtk.manpages@gmail.com> 2003-05-16.
32 .\" Modified by Walter Harms: dladdr, dlvsym
33 .\" Modified by Petr Baudis <pasky@suse.cz>, 2008-12-04: dladdr caveat
34 .\"
35 .\"*******************************************************************
36 .\"
37 .\" This file was generated with po4a. Translate the source file.
38 .\"
39 .\"*******************************************************************
40 .\"
41 .\" Japanese Version Copyright (c) 1998 NAKANO Takeo all rights reserved.
42 .\" Translated Sat May 23 1998 by NAKANO Takeo <nakano@apm.seikei.ac.jp>
43 .\" Updated & Modified 1999-09-14, NAKANO Takeo
44 .\" Modified 2000-03-19, HANATAKA Shinya <hanataka@abyss.rim.or.jp>
45 .\" Updated 2001-02-16, Kentaro Shirakata <argrath@ub32.org>
46 .\" Updated 2001-12-21, Kentaro Shirakata <argrath@ub32.org>
47 .\" Updated 2002-10-21, Kentaro Shirakata <argrath@ub32.org>
48 .\" Updated 2003-09-01, Kentaro Shirakata <argrath@ub32.org>
49 .\" Updated 2005-03-15, Akihiro MOTOKI <amotoki@dd.iij4u.or.jp>
50 .\" Updated 2006-01-20, Akihiro MOTOKI
51 .\" Updated 2009-03-02, Akihiro MOTOKI, LDP v3.19
52 .\"
53 .TH DLOPEN 3 2014\-10\-02 Linux "Linux Programmer's Manual"
54 .SH 名前
55 dlclose, dlerror, dlopen, dlsym \- 動的リンクを行うローダーへの プログラミングインターフェース
56 .SH 書式
57 \fB#include <dlfcn.h>\fP
58 .sp
59 \fBvoid *dlopen(const char *\fP\fIfilename\fP\fB, int \fP\fIflag\fP\fB);\fP
60 .sp
61 \fBchar *dlerror(void);\fP
62 .sp
63 \fBvoid *dlsym(void *\fP\fIhandle\fP\fB, const char *\fP\fIsymbol\fP\fB);\fP
64 .sp
65 \fBint dlclose(void *\fP\fIhandle\fP\fB);\fP
66 .sp
67 \fI\-ldl\fP でリンクする。
68 .SH 説明
69 \fBdlopen\fP(), \fBdlsym\fP(), \fBdlclose\fP(), \fBdlerror\fP()  の 4つの関数は、動的リンク (dynamic
70 linking) を行うローダーへの インターフェースを実装したものである。
71 .SS dlerror()
72 関数 \fBdlerror\fP()  は、前回 \fBdlerror\fP()  が呼び出された後に、 \fBdlopen\fP(), \fBdlsym\fP(),
73 \fBdlclose\fP()  のいずれかで最後に発生したエラーについての説明メッセージを返す。
74 初期化後または前回呼び出された後で、エラーが発生していなければ NULL を返す。
75 .SS dlopen()
76 関数 \fBdlopen\fP()  は、ヌル終端された文字列 \fIfilename\fP で指定されたファイル名の動的ライブラリ (dynamic
77 library) をロードし、 その動的ライブラリへの内部「ハンドル」を返す。 \fIfilename\fP が NULL
78 の場合、メインプログラムへのハンドルが返される。 \fIfilename\fP がスラッシュ ("/")
79 を含む場合、(相対か絶対かの)パス名として解釈される。 それ以外の場合、動的リンカーは以下の手順でライブラリを検索する (詳細は \fBld.so\fP(8)
80 を参照):
81 .IP o 4
82 (ELF のみ) 呼び出し元プログラムの実行ファイルに DT_RPATH タグが含まれており、 DT_RUNPATH
83 タグが含まれていない場合、DT_RPATH タグに書かれている ディレクトリリストを検索する。
84 .IP o
85 プログラムの開始時に環境変数 \fBLD_LIBRARY_PATH\fP にコロン区切りのディレクトリのリストが定義されていれば、
86 この環境変数に定義されたディレクトリが検索される (セキュリティ上の理由で、この変数は set\-UID や set\-GID された
87 プログラムの場合は無視される)。
88 .IP o
89 (ELF のみ) 呼び出し元プログラムの実行ファイルに DT_RUNPATH タグが含まれて
90 いる場合、そのタグに書かれているディレクトリリストを検索する。
91 .IP o
92 キャッシュファイル \fI/etc/ld.so.cache\fP の中に \fIfilename\fP のエントリーが入っているかをチェックする
93 (\fB/etc/ld.so.cache\fP は \fBldconfig\fP(8)  によって管理されている)。
94 .IP o
95 ディレクトリ \fI/lib\fP と \fI/usr/lib\fP をこの順番で検索する。
96 .PP
97 そのライブラリが他の共有ライブラリに依存している場合は、 依存しているライブラリも動的リンカーが同じ検索ルールに基づいて 自動的にロードする
98 (それらのライブラリにさらに依存関係がある場合などは この処理は再帰的に行われる)。
99 .PP
100 \fIflag\fP には以下の 2 つの値のいずれかを含めなければならない:
101 .TP 
102 \fBRTLD_LAZY\fP
103 lazy binding (手抜きなシンボルの結び付け) が行う。 シンボルの解決はそのシンボルを参照するコードが実行されるときにのみ
104 行われる。シンボルが一度も参照されなかった場合には、そのシンボルは 解決されないままとなる。 (lazy binding
105 は関数参照についてのみ実施される; 変数への参照は常に ライブラリがロードされた時点で直ちに解決される。)
106 .TP 
107 \fBRTLD_NOW\fP
108 この値が指定されるか、環境変数 \fBLD_BIND_NOW\fP に空でない文字列が設定された場合、 ライブラリ中の未定義のシンボルを全て解決してから
109 \fBdlopen\fP()  は復帰する。解決できなかったときにはエラーが返される。
110 .PP
111 以下の値のうち 0 個以上を論理和 (OR) の形で \fIflag\fP に追加することもできる:
112 .TP 
113 \fBRTLD_GLOBAL\fP
114 このライブラリで定義されているシンボルが、これより後でロードされる ライブラリのシンボル解決で利用できるようになる。
115 .TP 
116 \fBRTLD_LOCAL\fP
117 このフラグは \fBRTLD_GLOBAL\fP の反対の意味であり、どちらのフラグも指定されなかった場合は こちらがデフォルトとなる。
118 このライブラリで定義されているシンボルは、これより後でロードされる ライブラリでのシンボル参照で利用できない。
119 .TP 
120 \fBRTLD_NODELETE\fP (glibc 2.2 以降)
121 .\" (But it is present on Solaris.)
122 \fBdlclose\fP()  中にそのライブラリをアンロードしない。 そのため、同じライブラリをこれ以降に \fBdlopen\fP()
123 で再度ロードした場合に、ライブラリ内の静的変数は再初期化されない。 このフラグは POSIX.1\-2001 では規定されていない。
124 .TP 
125 \fBRTLD_NOLOAD\fP (glibc 2.2 以降)
126 .\" (But it is present on Solaris.)
127 .\"
128 そのライブラリをロードしない。 このフラグはそのライブラリがすでに組み込まれているかを検査するのに 利用できる (\fBdlopen\fP()
129 は、ライブラリが組み込まれていなければ NULL を返し、 すでに組み込まれていればそのライブラリのハンドルを返す)。
130 また、すでにロードされているライブラリのフラグを昇格させるのにも 利用できる。例えば、過去に \fBRTLD_LOCAL\fP でロードしたライブラリを
131 \fBRTLD_NOLOAD\ |\ RTLD_GLOBAL\fP で再オープンすることができる。 このフラグは POSIX.1\-2001
132 では規定されていない。
133 .TP 
134 \fBRTLD_DEEPBIND\fP (glibc 2.3.4 以降)
135 .\" Inimitably described by UD in
136 .\" http://sources.redhat.com/ml/libc-hacker/2004-09/msg00083.html.
137 このライブラリ内のシンボルの参照領域をグローバル領域よりも前に配置する。 つまり、内蔵型のライブラリでは、すでにロードされたライブラリに含まれる
138 同じ名前のグローバルなシンボルよりも自ライブラリ内のシンボルが優先して 使われる。 このフラグは POSIX.1\-2001 では規定されていない。
139 .PP
140 \fIfilename\fP が NULL である場合は、 返されるハンドルはメインプログラムのものになる。 このハンドルが \fBdlsym\fP()
141 に渡されると、シンボルの検索は、メインプログラム内、 プログラムの起動時にロードされる全ての共有ライブラリ、 \fBdlopen\fP()  によって
142 \fBRTLD_GLOBAL\fP フラグ付きでロードされた全ての共有ライブラリ、の順序で行われる。
143 .PP
144 オープンされたライブラリ中での外部参照は、 そのライブラリの依存リストにあるライブラリか、 \fBRTLD_GLOBAL\fP
145 フラグ付きで既にオープンされているライブラリを使って解決される。 実行ファイルが "\-rdynamic" フラグ ("\-\-export\-dynamic"
146 も同義)  付きでリンクされている場合は、実行ファイル中のグローバルシンボルも、 動的にロードされるライブラリ内の参照解決に用いられる。
147 .PP
148 同じライブラリが \fBdlopen\fP()  によって再度ロードされた場合には、同じライブラリハンドルが返される。 dl
149 ライブラリはライブラリハンドルのリンク数を管理している。 したがって動的ライブラリは \fBdlclose\fP()  が \fBdlopen\fP()
150 と同じ回数だけ呼び出されない限りアンロードされない。 \fB_init\fP()  ルーチンは一度だけ呼び出される (\fB_init\fP()
151 が存在する場合のみ)。 \fBRTLD_NOW\fP が指定されて \fBdlopen\fP()  が呼び出された場合、 \fBRTLD_LAZY\fP
152 で以前にロードされたライブラリのシンボル解決が実行されることがある。
153 .PP
154 \fBdlopen\fP()  は、何らかの理由で失敗すると NULL を返す。
155 .SS dlsym()
156 関数 \fBdlsym\fP()  は、 \fBdlopen\fP()  が返した動的ライブラリの「ハンドル」と、 NULL
157 終端されたシンボル名の文字列を引き数に取り、 そのシンボルがロードされたメモリーのアドレスを返す。
158 シンボルが、指定されたライブラリと、指定されたライブラリがロードされる際に \fBdlopen\fP()
159 が自動的にロードしてライブラリのいずれにも見つからない場合には、 \fBdlsym\fP()  は NULL を返す (\fBdlsym\fP()
160 による検索は、これらのライブラリの依存関係のツリーを先頭から 辿って行われる)。 実際にはシンボルの値自体が NULL になることもある (そのため、
161 \fBdlsym\fP()  の返り値が NULL であったとしても必ずしもエラーという訳ではない)。 エラーかどうかを確認する正しい方法は以下の通りである:
162 \fBdlerror\fP()  を呼び出して以前のエラー状態をクリアしてから、 \fBdlsym\fP()  を呼び出す。その後でもう一度
163 \fBdlerror\fP()  を呼び出して、 \fBdlerror\fP()  の返り値を変数に保存し、保存した値が NULL であるか判定する。
164 .PP
165 \fBRTLD_DEFAULT\fP と \fBRTLD_NEXT\fP という二つの特別な擬似ハンドルがある。 \fBRTLD_DEFAULT\fP
166 は、デフォルトのライブラリ検索順序にしたがって、 検索対象のシンボルが最初に現れるところを探す。 \fBRTLD_NEXT\fP
167 は、ライブラリ検索順序の中で現在のライブラリ以降で最初に 関数が現れるところを探す。この機能を使うことで、別の共有ライブラリの
168 関数へのラッパーを提供することができる。
169 .SS dlclose()
170 関数 \fBdlclose\fP()  は動的ライブラリのハンドル \fIhandle\fP の参照カウントを 1 減らす。参照カウントが 0
171 になり、ロードされている 他のライブラリからそのライブラリ内のシンボルが使われていなければ、 その動的ライブラリをアンロードする。
172 .LP
173 関数 \fBdlclose\fP()  は、成功した場合は 0 を返し、エラーの場合 0 以外を返す。
174 .SS "廃止されたシンボル _init() と _fini()"
175 リンカーは \fB_init\fP と \fB_fini\fP を特別なシンボルと解釈する。 ある動的ライブラリで \fB_init\fP()
176 という名前のルーチンがエクスポートされていれば、 そのコードは、ライブラリのロード後、かつ \fBdlopen\fP()  が復帰する前に実行される。
177 その動的ライブラリで \fB_fini\fP()  という名前のルーチンがエクスポートされていれば、
178 ライブラリがアンロードされる直前にそのルーチンが呼び出される。 システムの起動ファイルに対するリンクを避ける必要がある場合、 \fBgcc\fP(1)
179 のコマンドラインに \fI\-nostartfiles\fP オプションを指定すればよい。
180 .LP
181 .\" void _init(void) __attribute__((constructor));
182 .\" void _fini(void) __attribute__((destructor));
183 このルーチンや、gcc のオプション \fB\-nostartfiles\fP や \fB\-nostdlib\fP は使用しないことを推奨する。
184 これらを使うと、望ましくない動作をすることがある。 なぜなら、(特別な措置が行われない限り) これらの constructor/destructor
185 ルーチンは実行されないからである。
186 .LP
187 代わりに、ライブラリは \fB__attribute__((constructor))\fP や \fB__attribute__((destructor))\fP
188 の関数属性を使って必要なルーチンをエクスポートするのがよい。 これらについては gcc の info ページを参照のこと。 constructor
189 ルーチンは \fBdlopen\fP()  が復帰する前に実行され、 destructor ルーチンは \fBdlclose\fP()  が復帰する前に実行される。
190 .SS "GNU での拡張: dladdr() と dlvsym()"
191 glibc では POSIX には記載されていない関数が 2つ追加されている。 プロトタイプは以下の通りである。
192 .sp
193 .nf
194 \fB#define _GNU_SOURCE\fP         /* feature_test_macros(7) 参照 */
195 \fB#include <dlfcn.h>\fP
196 .sp
197 \fBint dladdr(void *\fP\fIaddr\fP\fB, Dl_info *\fP\fIinfo\fP\fB);\fP
198 .sp
199 \fBvoid *dlvsym(void *\fP\fIhandle\fP\fB, char *\fP\fIsymbol\fP\fB, char *\fP\fIversion\fP\fB);\fP
200 .fi
201 .PP
202 関数 \fBdladdr\fP()  は、関数のポインターを引き数にとり、関数の名前と関数が定義されている ファイルの解決を試みる。情報は
203 \fIDl_info\fP 構造体に格納される。
204 .sp
205 .in +4n
206 .nf
207 typedef struct {
208     const char *dli_fname;  /* Pathname of shared object that
209                                contains address */
210     void       *dli_fbase;  /* Address at which shared object
211                                is loaded */
212     const char *dli_sname;  /* Name of symbol whose definition
213                                overlaps \fIaddr\fP */
214     void       *dli_saddr;  /* Exact address of symbol named
215                                in \fIdli_sname\fP */
216 } Dl_info;
217 .fi
218 .in
219 .PP
220 \fIaddr\fP にマッチするシンボルが見つからなかった場合、 \fIdli_sname\fP と \fIdli_saddr\fP は NULL にセットされる。
221 .PP
222 \fBdladdr\fP()  は、エラー時には 0 を返し、成功した場合は 0 以外を返す。
223 .PP
224 関数 \fBdlvsym\fP()  は \fBdlsym\fP()  と同じ動作をするが、バージョンの文字列を渡す引き数が 追加されている点が異なる
225 (\fBdlvsym\fP()  はバージョン 2.1 以降の glibc で提供されている)。
226 .SH 準拠
227 POSIX.1\-2003 には \fBdlclose\fP(), \fBdlerror\fP(), \fBdlopen\fP(), \fBdlsym\fP().
228 の記載がある。
229 .SH 注意
230 .\" .LP
231 .\" The string returned by
232 .\" .BR dlerror ()
233 .\" should not be modified.
234 .\" Some systems give the prototype as
235 .\" .sp
236 .\" .in +5
237 .\" .B "const char *dlerror(void);"
238 .\" .in
239 シンボル \fBRTLD_DEFAULT\fP と \fBRTLD_NEXT\fP は \fI<dlfcn.h>\fP で定義されており、
240 \fI<dlfcn.h>\fP のインクルード前に \fB_GNU_SOURCE\fP が定義されている場合のみ有効となる。
241
242 glibc 2.2.3 以降では、 \fBatexit\fP(3)  を使って、ライブラリがアンロードされる際に自動的に呼び出される 終了ハンドラー
243 (exit handler) を登録することができる。
244 .SS 歴史
245 dlopen インターフェースの標準は SunOS をもとにしている。 SunOS には \fBdladdr\fP()  もあったが、 \fBdlvsym\fP()
246 はなかった。
247 .SH バグ
248 時として、 \fBdladdr\fP()  に渡した関数ポインターは驚くような値になることがある。 いくつかのアーキテクチャー (特に i386 と
249 x86_64) では、 引き数として使用した関数が動的リンクライブラリで定義されるもので あったとしても、 \fIdli_fname\fP と
250 \fIdli_fbase\fP が \fBdladdr\fP()  を呼び出したオブジェクトを参照した状態で終わっていることがある。
251 .PP
252 問題は、関数ポインターの解決は今なおコンパイル時に行われるが、 そのポインターは元のオブジェクトの \fIplt\fP (Procedure Linkage
253 Table) セクションを指しているだけだという点にある (オブジェクト自体は、ダイナミックリンカーによってシンボルの解決が行われた後に、
254 関数の呼び出しを行う)。 これに対処する方法としては、 コードを position\-independent でコンパイルするという方法がある。
255 そうすると、コンパイラはコンパイル時にポインターを用意することができず、 今日の \fBgcc\fP(1)  では、実行時に \fBdladdr\fP()
256 に関数ポインターを渡す前に、 \fIgot\fP (Global Offset Table) から最終的なシンボルのアドレスをロードするだけの
257 コードが生成される。
258 .SH 例
259 math ライブラリをロードし、2.0 の余弦を表示する
260 .nf
261
262 #include <stdio.h>
263 #include <stdlib.h>
264 #include <dlfcn.h>
265
266 int
267 main(int argc, char **argv)
268 {
269     void *handle;
270     double (*cosine)(double);
271     char *error;
272
273     handle = dlopen("libm.so", RTLD_LAZY);
274     if (!handle) {
275         fprintf(stderr, "%s\en", dlerror());
276         exit(EXIT_FAILURE);
277     }
278
279     dlerror();    /* Clear any existing error */
280
281     cosine = (double (*)(double)) dlsym(handle, "cos");
282
283     /* ISO の C 標準によれば、上のような、関数ポインターと 'void *' 間の
284        キャストを行った場合に得られる結果は不定である。
285        POSIX.1\-2003 と POSIX.1\-2008 では、この状況は認められており、
286        以下のようなワークアラウンドが提案されている。
287
288            *(void **) (&cosine) = dlsym(handle, "cos");
289
290        この (ぶかっこうな) キャストは ISO の C 標準に従っており、
291        コンパイラの警告を避けることができる。
292
293 .\" http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html#tag_03_112_08
294 .\" http://pubs.opengroup.org/onlinepubs/9699919799/functions/dlsym.html#tag_16_96_07
295 .\" http://austingroupbugs.net/view.php?id=74
296        POSIX.1\-2008 の 2013 Technical Corrigendum (別名 POSIX.1\-2013)
297        では、 POSIX に準拠する実装では 'void *' から関数ポインターへの
298        キャストをサポートすることが要求されるようになり、状況が改善
299        された。にもかかわらず、('\-pedantic' オプションを指定した gcc
300        などの) いくつかのコンパイラは、このプログラムで使用されている
301        キャストについて文句を言うのだ。
302
303     error = dlerror();
304     if (error != NULL) {
305         fprintf(stderr, "%s\en", error);
306         exit(EXIT_FAILURE);
307     }
308
309     printf("%f\en", (*cosine)(2.0));
310     dlclose(handle);
311     exit(EXIT_SUCCESS);
312 }
313 .fi
314 .PP
315 このプログラムを "foo.c" に書いたとすると、以下のコマンドでプログラムを ビルドできる。
316 .in +4n
317 .LP
318     gcc \-rdynamic \-o foo foo.c \-ldl
319 .in
320 .PP
321 \fB_init\fP()  と \fB_fini\fP()  をエクスポートするライブラリの場合は 以下のようにしてコンパイルする必要がある。 例として
322 \fIbar.c\fP をコンパイルする場合:
323 .in +4n
324 .LP
325     gcc \-shared \-nostartfiles \-o bar bar.c
326 .in
327 .SH 関連項目
328 \fBld\fP(1), \fBldd\fP(1), \fBpldd\fP(1), \fBdl_iterate_phdr\fP(3), \fBrtld\-audit\fP(7),
329 \fBld.so\fP(8), \fBldconfig\fP(8)
330
331 ld.so info pages, gcc info pages, ld info pages
332 .SH この文書について
333 この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 3.79 の一部
334 である。プロジェクトの説明とバグ報告に関する情報は
335 http://www.kernel.org/doc/man\-pages/ に書かれている。