OSDN Git Service

(split) LDP: draft snapshot generated from latest pthread/ja.po files.
[linuxjm/LDP_man-pages.git] / release / man3 / dlopen.3
1 .\" -*- nroff -*-
2 .\" Copyright 1995 Yggdrasil Computing, Incorporated.
3 .\" written by Adam J. Richter (adam@yggdrasil.com),
4 .\" with typesetting help from Daniel Quinlan (quinlan@yggdrasil.com).
5 .\" and Copyright 2003 Michael Kerrisk (mtk.manpages@gmail.com).
6 .\"
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, write to the Free
24 .\" Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
25 .\" USA.
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 .\" Japanese Version Copyright (c) 1998 NAKANO Takeo all rights reserved.
36 .\" Translated Sat May 23 1998 by NAKANO Takeo <nakano@apm.seikei.ac.jp>
37 .\" Updated & Modified 1999-09-14, NAKANO Takeo
38 .\" Modified 2000-03-19, HANATAKA Shinya <hanataka@abyss.rim.or.jp>
39 .\" Updated 2001-02-16, Kentaro Shirakata <argrath@ub32.org>
40 .\" Updated 2001-12-21, Kentaro Shirakata <argrath@ub32.org>
41 .\" Updated 2002-10-21, Kentaro Shirakata <argrath@ub32.org>
42 .\" Updated 2003-09-01, Kentaro Shirakata <argrath@ub32.org>
43 .\" Updated 2005-03-15, Akihiro MOTOKI <amotoki@dd.iij4u.or.jp>
44 .\" Updated 2006-01-20, Akihiro MOTOKI
45 .\" Updated 2009-03-02, Akihiro MOTOKI, LDP v3.19
46 .\"
47 .\"WORD:        linker                  リンカ
48 .\"WORD:        dynamic linking         動的リンク
49 .\"WORD:        dynamic library         動的ライブラリ
50 .\"
51 .TH DLOPEN 3 2008-12-06 "Linux" "Linux Programmer's Manual"
52 .SH 名前
53 dlclose, dlerror, dlopen, dlsym \- 動的リンクを行うローダへの
54 プログラミングインターフェース
55 .SH 書式
56 .B #include <dlfcn.h>
57 .sp
58 .BI "void *dlopen(const char *" filename ", int " flag );
59 .sp
60 .B "char *dlerror(void);"
61 .sp
62 .BI "void *dlsym(void *" handle ", const char *" symbol );
63 .sp
64 .BI "int dlclose(void *" handle );
65 .sp
66 \fI\-ldl\fP でリンクする。
67 .SH 説明
68 .BR dlopen (),
69 .BR dlsym (),
70 .BR dlclose (),
71 .BR dlerror ()
72 の 4つの関数は、動的リンク (dynamic linking) を行うローダへの
73 インタフェースを実装したものである。
74 .SS "dlerror()"
75 関数
76 .BR dlerror ()
77 は、前回
78 .BR dlerror ()
79 が呼び出された後に、
80 .BR dlopen (),
81 .BR dlsym (),
82 .BR dlclose ()
83 のいずれかで最後に発生したエラーについての説明メッセージを返す。
84 初期化後または前回呼び出された後で、エラーが発生していなければ NULL を返す。
85 .SS "dlopen()"
86 関数
87 .BR dlopen ()
88 は、NULL 終端された文字列
89 .I filename
90 で指定されたファイル名の動的ライブラリ (dynamic library) をロードし、
91 その動的ライブラリへの内部「ハンドル」を返す。
92 .I filename
93 が NULL の場合、メイン・プログラムへのハンドルが返される。
94 .I filename
95 がスラッシュ ("/") を含む場合、(相対か絶対かの)パス名として解釈される。
96 それ以外の場合、動的リンカは以下の手順でライブラリを検索する
97 (詳細は
98 .BR ld.so (8)
99 を参照):
100 .IP o 4
101 (ELF のみ) 呼び出し元プログラムの実行ファイルに DT_RPATH タグが含まれており、
102 DT_RUNPATH タグが含まれていない場合、DT_RPATH タグに書かれている
103 ディレクトリ・リストを検索する。
104 .IP o
105 プログラムの開始時に環境変数
106 .B LD_LIBRARY_PATH
107 にコロン区切りのディレクトリのリストが定義されていれば、
108 この環境変数に定義されたディレクトリが検索される
109 (セキュリティ上の理由で、この変数は set-UID や set-GID された
110 プログラムの場合は無視される)。
111 .IP o
112 (ELF のみ) 呼び出し元プログラムの実行ファイルに DT_RUNPATH タグが含まれて
113 いる場合、そのタグに書かれているディレクトリ・リストを検索する。
114 .IP o
115 キャッシュファイル
116 .I /etc/ld.so.cache
117 の中に
118 .I filename
119 のエントリが入っているかをチェックする
120 .RB ( /etc/ld.so.cache
121
122 .BR ldconfig (8)
123 によって管理されている)。
124 .IP o
125 ディレクトリ
126 .I /lib
127
128 .I /usr/lib
129 をこの順番で検索する。
130 .PP
131 そのライブラリが他の共有ライブラリに依存している場合は、
132 依存しているライブラリも動的リンカが同じ検索ルールに基づいて
133 自動的にロードする (それらのライブラリにさらに依存関係がある場合などは
134 この処理は再帰的に行われる)。
135 .PP
136 .I flag
137 には以下の 2 つの値のいずれかを含めなければならない:
138 .TP
139 .B RTLD_LAZY
140 lazy binding (手抜きなシンボルの結び付け) が行う。
141 シンボルの解決はそのシンボルを参照するコードが実行されるときにのみ
142 行われる。シンボルが一度も参照されなかった場合には、そのシンボルは
143 解決されないままとなる。
144 (lazy binding は関数参照についてのみ実施される; 変数への参照は常に
145 ライブラリがロードされた時点で直ちに解決される。)
146 .TP
147 .B RTLD_NOW
148 この値が指定されるか、環境変数
149 .B LD_BIND_NOW
150 に空でない文字列が設定された場合、
151 ライブラリ中の未定義のシンボルを全て解決してから
152 .BR dlopen ()
153 は復帰する。解決できなかったときにはエラーが返される。
154 .PP
155 以下の値のうち 0 個以上を論理和 (OR) の形で
156 .I flag
157 に追加することもできる:
158 .TP
159 .B RTLD_GLOBAL
160 このライブラリで定義されているシンボルが、これより後でロードされる
161 ライブラリのシンボル解決で利用できるようになる。
162 .TP
163 .B RTLD_LOCAL
164 このフラグは
165 .B RTLD_GLOBAL
166 の反対の意味であり、どちらのフラグも指定されなかった場合は
167 こちらがデフォルトとなる。
168 このライブラリで定義されているシンボルは、これより後でロードされる
169 ライブラリでのシンボル参照で利用できない。
170 .TP
171 .BR RTLD_NODELETE " (glibc 2.2 以降)"
172 .BR dlclose ()
173 中にそのライブラリをアンロードしない。
174 そのため、同じライブラリをこれ以降に
175 .BR dlopen ()
176 で再度ロードした場合に、ライブラリ内の静的変数は再初期化されない。
177 このフラグは POSIX.1-2001 では規定されていない。
178 .\" (しかし Solaris に存在する)
179 .TP
180 .BR RTLD_NOLOAD " (glibc 2.2 以降)"
181 そのライブラリをロードしない。
182 このフラグはそのライブラリがすでに組み込まれているかを検査するのに
183 利用できる
184 .RB ( dlopen ()
185 は、ライブラリが組み込まれていなければ NULL を返し、
186 すでに組み込まれていればそのライブラリのハンドルを返す)。
187 また、すでにロードされているライブラリのフラグを昇格させるのにも
188 利用できる。例えば、過去に
189 .B RTLD_LOCAL
190 でロードしたライブラリを
191 .BR RTLD_NOLOAD\ |\ RTLD_GLOBAL
192 で再オープンすることができる。
193 このフラグは POSIX.1-2001 では規定されていない。
194 .\" (しかし Solaris に存在する)
195 .TP
196 .BR RTLD_DEEPBIND " (glibc 2.3.4 以降)"
197 .\" Inimitably described by UD in
198 .\" http://sources.redhat.com/ml/libc-hacker/2004-09/msg00083.html.
199 このライブラリ内のシンボルの参照領域をグローバル領域よりも前に配置する。
200 つまり、内蔵型のライブラリでは、すでにロードされたライブラリに含まれる
201 同じ名前のグローバルなシンボルよりも自ライブラリ内のシンボルが優先して
202 使われる。
203 このフラグは POSIX.1-2001 では規定されていない。
204 .PP
205 .I filename
206 が NULL ポインタである場合は、
207 返されるハンドルはメイン・プログラムのものになる。
208 このハンドルが
209 .BR dlsym ()
210 に渡されると、シンボルの検索は、メイン・プログラム内、
211 プログラムの起動時にロードされる全ての共有ライブラリ、
212 .BR dlopen ()
213 によって
214 .B RTLD_GLOBAL
215 フラグ付きでロードされた全ての共有ライブラリ、の順序で行われる。
216 .PP
217 オープンされたライブラリ中での外部参照は、
218 そのライブラリの依存リストにあるライブラリか、
219 .B RTLD_GLOBAL
220 フラグ付きで既にオープンされているライブラリを使って解決される。
221 実行ファイルが "\-rdynamic" フラグ ("\-\-export\-dynamic" も同義)
222 付きでリンクされている場合は、実行ファイル中のグローバルシンボルも、
223 動的にロードされるライブラリ内の参照解決に用いられる。
224 .PP
225 同じライブラリが
226 .BR dlopen ()
227 によって再度ロードされた場合には、同じファイルハンドルが返される。
228 dl ライブラリはライブラリハンドルのリンク数を管理している。
229 したがって動的ライブラリは
230 .BR dlclose ()
231
232 .BR dlopen ()
233 と同じ回数だけ呼び出されない限りアンロードされない。
234 .BR _init ()
235 ルーチンは一度だけ呼び出される
236 .RB ( _init ()
237 が存在する場合のみ)。
238 .B RTLD_NOW
239 が指定されて
240 .BR dlopen ()
241 が呼び出された場合、
242 .B RTLD_LAZY
243 で以前にロードされたライブラリのシンボル解決が実行されることがある。
244 .PP
245 .BR dlopen ()
246 は、何らかの理由で失敗すると NULL を返す。
247
248 .SS "dlsym()"
249 関数
250 .BR dlsym ()
251 は、
252 .BR dlopen ()
253 が返した動的ライブラリの「ハンドル」と、
254 NULL 終端されたシンボル名の文字列を引き数に取り、
255 そのシンボルがロードされたメモリのアドレスを返す。
256 シンボルが、指定されたライブラリと、指定されたライブラリがロードされる際に
257 .BR dlopen ()
258 が自動的にロードしてライブラリのいずれにも見つからない場合には、
259 .BR dlsym ()
260 は NULL を返す
261 .RB ( dlsym ()
262 による検索は、これらのライブラリの依存関係のツリーを先頭から
263 辿って行われる)。
264 実際にはシンボルの値自体が NULL になることもある (そのため、
265 .BR dlsym ()
266 の返り値が NULL であったとしても必ずしもエラーという訳ではない)。
267 エラーかどうかを確認する正しい方法は以下の通りである:
268 .BR dlerror ()
269 を呼び出して以前のエラー状態をクリアしてから、
270 .BR dlsym ()
271 を呼び出す。その後でもう一度
272 .BR dlerror ()
273 を呼び出して、
274 .BR dlerror ()
275 の返り値を変数に保存し、保存した値が NULL であるか判定する。
276 .PP
277 .B RTLD_DEFAULT
278
279 .B RTLD_NEXT
280 という二つの特別な擬似ハンドルがある。
281 .B RTLD_DEFAULT
282 は、デフォルトのライブラリ検索順序にしたがって、
283 検索対象のシンボルが最初に現れるところを探す。
284 .B RTLD_NEXT
285 は、ライブラリ検索順序の中で現在のライブラリ以降で最初に
286 関数が現れるところを探す。この機能を使うことで、別の共有ライブラリの
287 関数へのラッパーを提供することができる。
288 .SS "dlclose()"
289 関数
290 .BR dlclose ()
291 は動的ライブラリのハンドル
292 .I handle
293 の参照カウントを 1 減らす。参照カウントが 0 になり、ロードされている
294 他のライブラリからそのライブラリ内のシンボルが使われていなければ、
295 その動的ライブラリをアンロードする。
296 .LP
297 関数
298 .BR dlclose ()
299 は、成功した場合は 0 を返し、エラーの場合 0 以外を返す。
300 .SS "廃止されたシンボル _init() と _fini()"
301 リンカは
302 .B _init
303
304 .B _fini
305 を特別なシンボルと解釈する。
306 ある動的ライブラリで
307 .BR _init ()
308 という名前のルーチンがエクスポートされていれば、
309 そのコードは、ライブラリのロード後、かつ
310 .BR dlopen ()
311 が復帰する前に実行される。
312 その動的ライブラリで
313 .BR _fini ()
314 という名前のルーチンがエクスポートされていれば、
315 ライブラリがアンロードされる直前にそのルーチンが呼び出される。
316 システムの起動ファイルに対するリンクを避ける必要がある場合、
317 .BR gcc (1)
318 のコマンドラインに
319 .I \-nostartfiles
320 オプションを指定すればよい。
321 .LP
322 このルーチンや、gcc のオプション
323 .B \-nostartfiles
324
325 .B \-nostdlib
326 は使用しないことを推奨する。
327 これらを使うと、望ましくない動作をすることがある。
328 なぜなら、(特別な措置が行われない限り) これらの constructor/destructor
329 ルーチンは実行されないからである。
330 .\" void _init(void) __attribute__((constructor));
331 .\" void _fini(void) __attribute__((destructor));
332 .LP
333 代わりに、ライブラリは
334 .B __attribute__((constructor))
335
336 .B __attribute__((destructor))
337 の関数属性を使って必要なルーチンをエクスポートするのがよい。
338 これらについては gcc の info ページを参照のこと。
339 constructor ルーチンは
340 .BR dlopen ()
341 が復帰する前に実行され、
342 destructor ルーチンは
343 .BR dlclose ()
344 が復帰する前に実行される。
345 .SS GNU での拡張: dladdr() と dlvsym()
346 glibc では POSIX には記載されていない関数が 2つ追加されている。
347 プロトタイプは以下の通りである。
348 .sp
349 .nf
350 .BR "#define _GNU_SOURCE" "         /* feature_test_macros(7) 参照 */"
351 .B #include <dlfcn.h>
352 .sp
353 .BI "int dladdr(void *" addr ", Dl_info *" info );
354 .sp
355 .BI "void *dlvsym(void *" handle ", char *" symbol ", char *" version );
356 .fi
357 .PP
358 関数
359 .BR dladdr ()
360 は、関数のポインタを引き数にとり、関数の名前と関数が定義されている
361 ファイルの解決を試みる。情報は
362 .I Dl_info
363 構造体に格納される。
364 .sp
365 .in +4n
366 .nf
367 typedef struct {
368     const char *dli_fname;  /* Pathname of shared object that
369                                contains address */
370     void       *dli_fbase;  /* Address at which shared object
371                                is loaded */
372     const char *dli_sname;  /* Name of nearest symbol with address
373                                lower than \fIaddr\fP */
374     void       *dli_saddr;  /* Exact address of symbol named
375                                in \fIdli_sname\fP */
376 } Dl_info;
377 .fi
378 .in
379 .PP
380 .I addr
381 にマッチするシンボルが見つからなかった場合、
382 .I dli_sname
383
384 .I dli_saddr
385 は NULL にセットされる。
386 .PP
387 .BR dladdr ()
388 は、エラー時には 0 を返し、成功した場合は 0 以外を返す。
389 .PP
390 関数
391 .BR dlvsym ()
392
393 .BR dlsym ()
394 と同じ動作をするが、バージョンの文字列を渡す引き数が
395 追加されている点が異なる
396 .RB ( dlvsym ()
397 はバージョン 2.1 以降の glibc で提供されている)。
398 .SH 準拠
399 POSIX.1-2003 には
400 .BR dlclose (),
401 .BR dlerror (),
402 .BR dlopen (),
403 .BR dlsym ().
404 の記載がある。
405 .SH 注意
406 シンボル
407 .B RTLD_DEFAULT
408
409 .B RTLD_NEXT
410
411 .I <dlfcn.h>
412 で定義されており、
413 .I <dlfcn.h>
414 のインクルード前に
415 .B _GNU_SOURCE
416 が定義されている場合のみ有効となる。
417 .\" .LP
418 .\" .BR dlerror ()
419 .\" が返す文字列は変更すべきではない。システムによっては、
420 .\" 以下のようなプロトタイプになっている。
421 .\" .sp
422 .\" .in +5
423 .\" .B "const char *dlerror(void);"
424 .\" .in
425
426 glibc 2.2.3 以降では、
427 .BR atexit (3)
428 を使って、ライブラリがアンロードされる際に自動的に呼び出される
429 終了ハンドラ (exit handler) を登録することができる。
430 .SS 歴史
431 dlopen インターフェースの標準は SunOS をもとにしている。
432 SunOS には
433 .BR dladdr ()
434 もあったが、
435 .BR dlvsym ()
436 はなかった。
437 .SH バグ
438 時として、
439 .BR dladdr ()
440 に渡した関数ポインタは驚くような値になることがある。
441 いくつかのアーキテクチャ (特に i386 と x86_64) では、
442 引き数として使用した関数が動的リンクライブラリで定義されるもので
443 あったとしても、
444 .I dli_fname
445
446 .I dli_fbase
447
448 .BR dladdr ()
449 を呼び出したオブジェクトを参照した状態で終わっていることがある。
450 .PP
451 問題は、関数ポインタの解決は今なおコンパイル時に行われるが、
452 そのポインタは元のオブジェクトの
453 .I plt
454 (Procedure Linkage Table) セクションを指しているだけだという点にある
455 (オブジェクト自体は、ダイナミックリンカによってシンボルの解決が行われた後に、
456 関数の呼び出しを行う)。
457 これに対処する方法としては、
458 コードを position-independent でコンパイルするという方法がある。
459 そうすると、コンパイラはコンパイル時にポインタを用意することができず、
460 今日の
461 .BR gcc (1)
462 では、実行時に
463 .BR dladdr ()
464 に関数ポインタを渡す前に、
465 .I got
466 (Global Offset Table) から最終的なシンボルのアドレスをロードするだけの
467 コードが生成される。
468 .SH 例
469 math ライブラリをロードし、2.0 の余弦を表示する
470 .nf
471
472 #include <stdio.h>
473 #include <stdlib.h>
474 #include <dlfcn.h>
475
476 int
477 main(int argc, char **argv)
478 {
479     void *handle;
480     double (*cosine)(double);
481     char *error;
482
483     handle = dlopen("libm.so", RTLD_LAZY);
484     if (!handle) {
485         fprintf(stderr, "%s\en", dlerror());
486         exit(EXIT_FAILURE);
487     }
488
489     dlerror();    /* Clear any existing error */
490
491     /* Writing: cosine = (double (*)(double)) dlsym(handle, "cos");
492        would seem more natural, but the C99 standard leaves
493        casting from "void *" to a function pointer undefined.
494        The assignment used below is the POSIX.1\-2003 (Technical
495        Corrigendum 1) workaround; see the Rationale for the
496        POSIX specification of dlsym(). */
497
498     *(void **) (&cosine) = dlsym(handle, "cos");
499 .\" But in fact "gcc -O2 -Wall" will complain about the preceding cast.
500
501     if ((error = dlerror()) != NULL)  {
502         fprintf(stderr, "%s\en", error);
503         exit(EXIT_FAILURE);
504     }
505
506     printf("%f\en", (*cosine)(2.0));
507     dlclose(handle);
508     exit(EXIT_SUCCESS);
509 }
510 .fi
511 .PP
512 このプログラムを "foo.c" に書いたとすると、以下のコマンドでプログラムを
513 ビルドできる。
514 .in +4n
515 .LP
516     gcc \-rdynamic \-o foo foo.c \-ldl
517 .in
518 .PP
519 .BR _init ()
520
521 .BR _fini ()
522 をエクスポートするライブラリの場合は
523 以下のようにしてコンパイルする必要がある。
524 例として \fIbar.c\fP をコンパイルする場合:
525 .in +4n
526 .LP
527     gcc \-shared \-nostartfiles \-o bar bar.c
528 .in
529 .SH 関連項目
530 .BR ld (1),
531 .BR ldd (1),
532 .BR dl_iterate_phdr (3),
533 .BR rtld-audit (7),
534 .BR ld.so (8),
535 .BR ldconfig (8),
536 ld.so info pages, gcc info pages, ld info pages