OSDN Git Service

Update README
[linuxjm/LDP_man-pages.git] / release / man7 / vdso.7
1 .\" Written by Mike Frysinger <vapier@gentoo.org>
2 .\"
3 .\" %%%LICENSE_START(PUBLIC_DOMAIN)
4 .\" This page is in the public domain.
5 .\" %%%LICENSE_END
6 .\"
7 .\" Useful background:
8 .\"   http://articles.manugarg.com/systemcallinlinux2_6.html
9 .\"   https://lwn.net/Articles/446528/
10 .\"   http://www.linuxjournal.com/content/creating-vdso-colonels-other-chicken
11 .\"   http://www.trilithium.com/johan/2005/08/linux-gate/
12 .\"
13 .\"*******************************************************************
14 .\"
15 .\" This file was generated with po4a. Translate the source file.
16 .\"
17 .\"*******************************************************************
18 .TH VDSO 7 2014\-08\-19 Linux "Linux Programmer's Manual"
19 .SH 名前
20 vDSO \- 仮想 ELF 動的共有オブジェクトの概要
21 .SH 書式
22 \fB#include <sys/auxv.h>\fP
23
24 \fBvoid *vdso = (uintptr_t) getauxval(AT_SYSINFO_EHDR);\fP
25 .SH 説明
26 "vDSO" (virtual dynamic shared object; 仮想動的共有オブジェクト) は、
27 カーネルが自動的にすべてのユーザー空間アプリケーションのアドレス空間にマッピングを行う小さな共有ライブラリである。 vDSO はほとんどの場合 C
28 ライブラリから呼び出されるため、 アプリケーションは通常これらの詳細を自分では気にする必要はない。 このように、 標準関数と C
29 ライブラリを使って通常の方法でコードを作成することで、 vDSO 経由で利用可能な機能が活用されることになる。
30
31 いったいなぜ vDSO は存在しているのか? カーネルが提供するシステムコールのいくつかは、
32 ユーザー空間のコードがこれらのシステムコールを頻繁に呼び出すことになり、 このような呼び出しが全体の性能を支配するようになる場合がある。 これは、
33 呼び出しの頻度と、 ユーザー空間から抜けてカーネルに入ることによるコンテキストスイッチのオーバーヘッドの両方に起因する。
34
35 この文書の残りの部分は、 一般の開発者向けというではなく、 好奇心がある人と C ライブラリの開発者向けの内容となっている。 もしあなたが C
36 ライブラリではなく自分のアプリケーションで vDSO を呼びだそうとしているのであれば、 ほとんどの場合間違ったことをしていることだろう。
37 .SS "Example background"
38 システムコールの呼び出しは遅くなる場合がある。 x86 32 ビットシステムでは、
39 システムコールを呼び出したいことをカーネルに教えるためにソフトウェア割り込み (\fIint $0x80\fP) を使うことができる。
40 しかしながら、この割り込みはコストがかかる処理である。 割り込みがあると、
41 カーネルとプロセッサーのマイクロコードの両方のすべての割り込み処理パスが実行される。 新しいプロセッサーには、
42 システムコール呼び出しを起動するための高速な (だが、後方互換性がある) 命令が用意されている。 C
43 ライブラリが実行時にこの機能が利用できるかを確認するのではなく、 C ライブラリは vDSO でカーネルが提供する関数を使うことができる。
44
45 用語が紛らわしい点には注意が必要である。 x86 システムでは、 システムコールを呼び出す推奨される方法を判定するのに使用される vDSO 関数は
46 "__kernel_vsyscall" という名前だが、 x86_64 では、 "vsyscall" という用語は、
47 カーネルに時刻はいつかや呼び出し元はどの CPU 上にいるかを問い合わせるための廃止予定の方法も参照している。
48
49 頻繁に使用されるシステムコールの一つが \fBgettimeofday\fP(2) である。 このシステムコールは、
50 ユーザー空間アプリケーションから直接呼び出されることも、 C ライブラリから間接的に呼び出されることもある。 タイムスタンプが必要な場面、
51 タイミングループを行う場面、 ポーリングを行う場面を考えてほしい。 これらはいずれも現在時刻が何かを直ちに知りたいのが普通である。
52 また、この情報は秘密ではなく、 (ルートでも非特権ユーザーでも) 任意の特権モードの多くのアプリケーションが同じ情報を取得できる。 したがって、
53 カーネルはこの質問に応えるのに必要な情報をプロセスがアクセスできるメモリー上に配置する。 これにより、 \fBgettimeofday\fP(2)
54 はシステムコールから通常の関数コールになり、 少ないメモリーアクセスになる。
55 .SS "vDSO を見つける"
56 vDSO のベースアドレスは、 (存在する場合には) カーネルから各プログラムに初期補助ベクトル (\fBgetauxval\fP(3) 参照) の
57 \fBAT_SYSINFO_EHDR\fP タグ経由で渡される。
58
59 vDSO がユーザーのメモリーマップの何か特定の場所にマッピングされると仮定してはならない。 通常新しいプロセスイメージが作成されるたびに
60 (\fBexecve\fP(2) 実行時点) 、 実行時にベースアドレスのランダム化が行われる。 これは "return\-to\-libc" 攻撃
61 を防ぐためにセキュリティ上の理由から行われる。
62
63 アーキテクチャーによっては \fBAT_SYSINFO\fP タグもある。 このタグは vsyscall エントリーポイントの場所を知るためだけのものであり、
64 しばしば省略されるか (利用できない場合は) 0 にセットされる。 このタグは最初の vDSO の実装で使用されていたものであり
65 (下記の「歴史」を参照)、 このタグを利用するのは避けるべきである。
66 .SS ファイルフォーマット
67 vDSO は完全な形式の ELF イメージなので、 vDSO に対してシンボルの検索を行うことができる。 このため、
68 新しいカーネルリリースで新しいシンボルを追加することができ、 C
69 ライブラリが別のバージョンのカーネル上で動作する際に実行時に利用可能な機能を検出することができる。 多くの場合、 C
70 ライブラリは最初の呼び出し時に検出を行い、 それ以降の呼び出しで利用できるようにその結果をキャッシュする。
71
72 すべてのシンボルは (GNU のバージョンフォーマットを使って) バージョンが付けられている。 これにより、
73 カーネルは後方互換性を持たせつつ関数のシグネチャーを更新することができる。 つまり、
74 関数が受け取る引き数や返り値が変更されることがあるということである。 したがって、 vDSO のシンボルを検索する際には、 自分が期待する ABI
75 に一致するバージョンをしなければならない。
76
77 通常は vDSO はすべてのシンボルに "__vdso_" か "__kernel_"
78 というプレフィックスを付けるという慣習に従った名前付けを行っており、 他の標準のシンボルから区別することができる。 例えば、
79 "gettimeofday" 関数は ""__vdso_gettimeofday" という名前になっている。
80
81 これらの関数を呼び出す場合は標準の C の呼び出しの慣習にしたがっておけばよい。 特殊なレジスターやスタックの動作に気を使う必要はない。
82 .SH 注意
83 .SS ソース
84 カーネルをコンパイルする際に、 vDSO コードはコンパイルされリンクが行われる。 通常はアーキテクチャー固有のディレクトリに vDSO
85 コードが生成される。
86
87     find arch/$ARCH/ \-name '*vdso*.so*' \-o \-name '*gate*.so*'
88
89 .SS "vDSO 名"
90 vDSO の名前はアーキテクチャーにより異なる。 この名前は glibc の \fBldd\fP(1) の出力などに現れる。
91 名前はコードで必要となることはなく、 名前をハードコードしないこと。
92 .if  t \{\
93 .ft CW
94 \}
95 .TS
96 l l.
97 ユーザー ABI        vDSO 名
98 _
99 aarch64 linux\-vdso.so.1
100 ia64    linux\-gate.so.1
101 ppc/32  linux\-vdso32.so.1
102 ppc/64  linux\-vdso64.so.1
103 s390    linux\-vdso32.so.1
104 s390x   linux\-vdso64.so.1
105 sh      linux\-gate.so.1
106 i386    linux\-gate.so.1
107 x86_64  linux\-vdso.so.1
108 x86/x32 linux\-vdso.so.1
109 .TE
110 .if  t \{\
111 .in
112 .ft P
113 \}
114 .SH アーキテクチャー固有の注意
115 以下のサブ章では vDSO のアーキテクチャー固有の注意について説明する。
116
117 使用される vDSO は、 カーネルの ABI ではなく、 ユーザー空間コードの ABI に基づくことに注意すること。 したがって、 例えば、 i386
118 32 ビットの ELF ライブラリ上で実行する場合、 i386 32 ビットカーネル上で実行されているか x86_64 64
119 ビットカーネル上で実行されているかに関わらず同じ vDSO が得られる。 したがって、 以下のどの節が関係するかを判断する際にはユーザー空間 ABI
120 の名前を使用する必要がある。
121 .SS "ARM 関数"
122 .\" See linux/arch/arm/kernel/entry-armv.S
123 .\" See linux/Documentation/arm/kernel_user_helpers.txt
124 The ARM port has a code page full of utility functions.  Since it's just a
125 raw page of code, there is no ELF information for doing symbol lookups or
126 versioning.  It does provide support for different versions though.
127
128 For information on this code page, it's best to refer to the kernel
129 documentation as it's extremely detailed and covers everything you need to
130 know: \fIDocumentation/arm/kernel_user_helpers.txt\fP.
131 .SS "aarch64 関数"
132 .\" See linux/arch/arm64/kernel/vdso/vdso.lds.S
133 以下のテーブルは vDSO で公開されるシンボルの一覧である。
134 .if  t \{\
135 .ft CW
136 \}
137 .TS
138 l l.
139 シンボル    バージョン
140 _
141 __kernel_rt_sigreturn   LINUX_2.6.39
142 __kernel_gettimeofday   LINUX_2.6.39
143 __kernel_clock_gettime  LINUX_2.6.39
144 __kernel_clock_getres   LINUX_2.6.39
145 .TE
146 .if  t \{\
147 .in
148 .ft P
149 \}
150 .SS "bfin (Blackfin) 関数"
151 .\" See linux/arch/blackfin/kernel/fixed_code.S
152 .\" See http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:fixed-code
153 As this CPU lacks a memory management unit (MMU), it doesn't set up a vDSO
154 in the normal sense.  Instead, it maps at boot time a few raw functions into
155 a fixed location in memory.  User\-space applications then call directly into
156 that region.  There is no provision for backward compatibility beyond
157 sniffing raw opcodes, but as this is an embedded CPU, it can get away with
158 things\(emsome of the object formats it runs aren't even ELF based (they're
159 bFLT/FLAT).
160
161 For information on this code page, it's best to refer to the public
162 documentation:
163 .br
164 http://docs.blackfin.uclinux.org/doku.php?id=linux\-kernel:fixed\-code
165 .SS "ia64 (Itanium) 関数"
166 .\" See linux/arch/ia64/kernel/gate.lds.S
167 .\" Also linux/arch/ia64/kernel/fsys.S and linux/Documentation/ia64/fsys.txt
168 以下のテーブルは vDSO で公開されるシンボルの一覧である。
169 .if  t \{\
170 .ft CW
171 \}
172 .TS
173 l l.
174 シンボル    バージョン
175 _
176 __kernel_sigtramp       LINUX_2.5
177 __kernel_syscall_via_break      LINUX_2.5
178 __kernel_syscall_via_epc        LINUX_2.5
179 .TE
180 .if  t \{\
181 .in
182 .ft P
183 \}
184
185 The Itanium port is somewhat tricky.  In addition to the vDSO above, it also
186 has "light\-weight system calls" (also known as "fast syscalls" or "fsys").
187 You can invoke these via the \fI__kernel_syscall_via_epc\fP vDSO helper.  The
188 system calls listed here have the same semantics as if you called them
189 directly via \fBsyscall\fP(2), so refer to the relevant documentation for
190 each.  The table below lists the functions available via this mechanism.
191 .if  t \{\
192 .ft CW
193 \}
194 .TS
195 l.
196 関数
197 _
198 clock_gettime
199 getcpu
200 getpid
201 getppid
202 gettimeofday
203 set_tid_address
204 .TE
205 .if  t \{\
206 .in
207 .ft P
208 \}
209 .SS "parisc (hppa) 関数"
210 .\" See linux/arch/parisc/kernel/syscall.S
211 .\" See linux/Documentation/parisc/registers
212 The parisc port has a code page full of utility functions called a gateway
213 page.  Rather than use the normal ELF auxiliary vector approach, it passes
214 the address of the page to the process via the SR2 register.  The
215 permissions on the page are such that merely executing those addresses
216 automatically executes with kernel privileges and not in user space.  This
217 is done to match the way HP\-UX works.
218
219 Since it's just a raw page of code, there is no ELF information for doing
220 symbol lookups or versioning.  Simply call into the appropriate offset via
221 the branch instruction, for example:
222
223     ble <offset>(%sr2, %r0)
224 .if  t \{\
225 .ft CW
226 \}
227 .TS
228 l l.
229 オフセット 関数
230 _
231 00b0    lws_entry
232 00e0    set_thread_pointer
233 0100    linux_gateway_entry (syscall)
234 0268    syscall_nosys
235 0274    tracesys
236 0324    tracesys_next
237 0368    tracesys_exit
238 03a0    tracesys_sigexit
239 03b8    lws_start
240 03dc    lws_exit_nosys
241 03e0    lws_exit
242 03e4    lws_compare_and_swap64
243 03e8    lws_compare_and_swap
244 0404    cas_wouldblock
245 0410    cas_action
246 .TE
247 .if  t \{\
248 .in
249 .ft P
250 \}
251 .SS "ppc/32 関数"
252 .\" See linux/arch/powerpc/kernel/vdso32/vdso32.lds.S
253 以下のテーブルは vDSO で公開されるシンボルの一覧である。 \fI*\fP のマークが付いた関数は、カーネルが PowerPC64 (64 ビット)
254 カーネルの場合にだけ利用可能である。
255 .if  t \{\
256 .ft CW
257 \}
258 .TS
259 l l.
260 シンボル    バージョン
261 _
262 __kernel_clock_getres   LINUX_2.6.15
263 __kernel_clock_gettime  LINUX_2.6.15
264 __kernel_datapage_offset        LINUX_2.6.15
265 __kernel_get_syscall_map        LINUX_2.6.15
266 __kernel_get_tbfreq     LINUX_2.6.15
267 __kernel_getcpu \fI*\fP LINUX_2.6.15
268 __kernel_gettimeofday   LINUX_2.6.15
269 __kernel_sigtramp_rt32  LINUX_2.6.15
270 __kernel_sigtramp32     LINUX_2.6.15
271 __kernel_sync_dicache   LINUX_2.6.15
272 __kernel_sync_dicache_p5        LINUX_2.6.15
273 .TE
274 .if  t \{\
275 .in
276 .ft P
277 \}
278 .SS "ppc/64 関数"
279 .\" See linux/arch/powerpc/kernel/vdso64/vdso64.lds.S
280 以下のテーブルは vDSO で公開されるシンボルの一覧である。
281 .if  t \{\
282 .ft CW
283 \}
284 .TS
285 l l.
286 シンボル    バージョン
287 _
288 __kernel_clock_getres   LINUX_2.6.15
289 __kernel_clock_gettime  LINUX_2.6.15
290 __kernel_datapage_offset        LINUX_2.6.15
291 __kernel_get_syscall_map        LINUX_2.6.15
292 __kernel_get_tbfreq     LINUX_2.6.15
293 __kernel_getcpu LINUX_2.6.15
294 __kernel_gettimeofday   LINUX_2.6.15
295 __kernel_sigtramp_rt64  LINUX_2.6.15
296 __kernel_sync_dicache   LINUX_2.6.15
297 __kernel_sync_dicache_p5        LINUX_2.6.15
298 .TE
299 .if  t \{\
300 .in
301 .ft P
302 \}
303 .SS "s390 関数"
304 .\" See linux/arch/s390/kernel/vdso32/vdso32.lds.S
305 以下のテーブルは vDSO で公開されるシンボルの一覧である。
306 .if  t \{\
307 .ft CW
308 \}
309 .TS
310 l l.
311 シンボル    バージョン
312 _
313 __kernel_clock_getres   LINUX_2.6.29
314 __kernel_clock_gettime  LINUX_2.6.29
315 __kernel_gettimeofday   LINUX_2.6.29
316 .TE
317 .if  t \{\
318 .in
319 .ft P
320 \}
321 .SS "s390x 関数"
322 .\" See linux/arch/s390/kernel/vdso64/vdso64.lds.S
323 以下のテーブルは vDSO で公開されるシンボルの一覧である。
324 .if  t \{\
325 .ft CW
326 \}
327 .TS
328 l l.
329 シンボル    バージョン
330 _
331 __kernel_clock_getres   LINUX_2.6.29
332 __kernel_clock_gettime  LINUX_2.6.29
333 __kernel_gettimeofday   LINUX_2.6.29
334 .TE
335 .if  t \{\
336 .in
337 .ft P
338 \}
339 .SS "sh (SuperH) 関数"
340 .\" See linux/arch/sh/kernel/vsyscall/vsyscall.lds.S
341 以下のテーブルは vDSO で公開されるシンボルの一覧である。
342 .if  t \{\
343 .ft CW
344 \}
345 .TS
346 l l.
347 シンボル    バージョン
348 _
349 __kernel_rt_sigreturn   LINUX_2.6
350 __kernel_sigreturn      LINUX_2.6
351 __kernel_vsyscall       LINUX_2.6
352 .TE
353 .if  t \{\
354 .in
355 .ft P
356 \}
357 .SS "i386 関数"
358 .\" See linux/arch/x86/vdso/vdso32/vdso32.lds.S
359 以下のテーブルは vDSO で公開されるシンボルの一覧である。
360 .if  t \{\
361 .ft CW
362 \}
363 .TS
364 l l.
365 シンボル    バージョン
366 _
367 __kernel_sigreturn      LINUX_2.5
368 __kernel_rt_sigreturn   LINUX_2.5
369 __kernel_vsyscall       LINUX_2.5
370 .\" Added in 7a59ed415f5b57469e22e41fc4188d5399e0b194 and updated
371 .\" in 37c975545ec63320789962bf307f000f08fabd48.
372 __vdso_clock_gettime    LINUX_2.6 (Linux 3.15 以降で公開)
373 __vdso_gettimeofday     LINUX_2.6 (Linux 3.15 以降で公開)
374 __vdso_time     LINUX_2.6 (Linux 3.15 以降で公開)
375 .TE
376 .if  t \{\
377 .in
378 .ft P
379 \}
380 .SS "x86_64 関数"
381 .\" See linux/arch/x86/vdso/vdso.lds.S
382 以下のテーブルは vDSO で公開されるシンボルの一覧である。 これらのシンボルはすべて "__vdso_" のプレフィックスなしでも利用できるが、
383 これらは無視し、 以下の名前だけを使うこと。
384 .if  t \{\
385 .ft CW
386 \}
387 .TS
388 l l.
389 シンボル    バージョン
390 _
391 __vdso_clock_gettime    LINUX_2.6
392 __vdso_getcpu   LINUX_2.6
393 __vdso_gettimeofday     LINUX_2.6
394 __vdso_time     LINUX_2.6
395 .TE
396 .if  t \{\
397 .in
398 .ft P
399 \}
400 .SS "x86/x32 関数"
401 .\" See linux/arch/x86/vdso/vdso32.lds.S
402 以下のテーブルは vDSO で公開されるシンボルの一覧である。
403 .if  t \{\
404 .ft CW
405 \}
406 .TS
407 l l.
408 シンボル    バージョン
409 _
410 __vdso_clock_gettime    LINUX_2.6
411 __vdso_getcpu   LINUX_2.6
412 __vdso_gettimeofday     LINUX_2.6
413 __vdso_time     LINUX_2.6
414 .TE
415 .if  t \{\
416 .in
417 .ft P
418 \}
419 .SS 歴史
420 vDSO は元々は一つの関数 vsyscall であった。 古いカーネルでは、 プロセスのメモリーマップに "vdso"
421 ではなくこの名前が見えるかもしれない。 時間が経つに連れて、 この仕組みはより多くの機能をユーザー空間に渡す有効な方法であると認識されるようになり、
422 現在の形の vDSO という形に見直しが行われた。
423 .SH 関連項目
424 \fBsyscalls\fP(2), \fBgetauxval\fP(3), \fBproc\fP(5)
425
426 Linux のソースコードツリーのドキュメント、例、ソースコード:
427 .in +4n
428 .nf
429
430 Documentation/ABI/stable/vdso
431 Documentation/ia64/fsys.txt
432 Documentation/vDSO/* (vDSO の使用例がある)
433
434 find arch/ \-iname '*vdso*' \-o \-iname '*gate*'
435 .fi
436 .in
437 .SH この文書について
438 この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 3.79 の一部
439 である。プロジェクトの説明とバグ報告に関する情報は
440 http://www.kernel.org/doc/man\-pages/ に書かれている。