]>
Commit | Line | Data |
---|---|---|
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 | .TH VDSO 7 2019-08-02 "Linux" "Linux Programmer's Manual" | |
14 | .SH NAME | |
15 | vdso \- overview of the virtual ELF dynamic shared object | |
16 | .SH SYNOPSIS | |
17 | .B #include <sys/auxv.h> | |
18 | .PP | |
19 | .B void *vdso = (uintptr_t) getauxval(AT_SYSINFO_EHDR); | |
20 | .SH DESCRIPTION | |
21 | The "vDSO" (virtual dynamic shared object) is a small shared library that | |
22 | the kernel automatically maps into the | |
23 | address space of all user-space applications. | |
24 | Applications usually do not need to concern themselves with these details | |
25 | as the vDSO is most commonly called by the C library. | |
26 | This way you can code in the normal way using standard functions | |
27 | and the C library will take care | |
28 | of using any functionality that is available via the vDSO. | |
29 | .PP | |
30 | Why does the vDSO exist at all? | |
31 | There are some system calls the kernel provides that | |
32 | user-space code ends up using frequently, | |
33 | to the point that such calls can dominate overall performance. | |
34 | This is due both to the frequency of the call as well as the | |
35 | context-switch overhead that results | |
36 | from exiting user space and entering the kernel. | |
37 | .PP | |
38 | The rest of this documentation is geared toward the curious and/or | |
39 | C library writers rather than general developers. | |
40 | If you're trying to call the vDSO in your own application rather than using | |
41 | the C library, you're most likely doing it wrong. | |
42 | .SS Example background | |
43 | Making system calls can be slow. | |
44 | In x86 32-bit systems, you can trigger a software interrupt | |
45 | .RI ( "int $0x80" ) | |
46 | to tell the kernel you wish to make a system call. | |
47 | However, this instruction is expensive: it goes through | |
48 | the full interrupt-handling paths | |
49 | in the processor's microcode as well as in the kernel. | |
50 | Newer processors have faster (but backward incompatible) instructions to | |
51 | initiate system calls. | |
52 | Rather than require the C library to figure out if this functionality is | |
53 | available at run time, | |
54 | the C library can use functions provided by the kernel in | |
55 | the vDSO. | |
56 | .PP | |
57 | Note that the terminology can be confusing. | |
58 | On x86 systems, the vDSO function | |
59 | used to determine the preferred method of making a system call is | |
60 | named "__kernel_vsyscall", but on x86-64, | |
61 | the term "vsyscall" also refers to an obsolete way to ask the kernel | |
62 | what time it is or what CPU the caller is on. | |
63 | .PP | |
64 | One frequently used system call is | |
65 | .BR gettimeofday (2). | |
66 | This system call is called both directly by user-space applications | |
67 | as well as indirectly by | |
68 | the C library. | |
69 | Think timestamps or timing loops or polling\(emall of these | |
70 | frequently need to know what time it is right now. | |
71 | This information is also not secret\(emany application in any | |
72 | privilege mode (root or any unprivileged user) will get the same answer. | |
73 | Thus the kernel arranges for the information required to answer | |
74 | this question to be placed in memory the process can access. | |
75 | Now a call to | |
76 | .BR gettimeofday (2) | |
77 | changes from a system call to a normal function | |
78 | call and a few memory accesses. | |
79 | .SS Finding the vDSO | |
80 | The base address of the vDSO (if one exists) is passed by the kernel to | |
81 | each program in the initial auxiliary vector (see | |
82 | .BR getauxval (3)), | |
83 | via the | |
84 | .B AT_SYSINFO_EHDR | |
85 | tag. | |
86 | .PP | |
87 | You must not assume the vDSO is mapped at any particular location in the | |
88 | user's memory map. | |
89 | The base address will usually be randomized at run time every time a new | |
90 | process image is created (at | |
91 | .BR execve (2) | |
92 | time). | |
93 | This is done for security reasons, | |
94 | to prevent "return-to-libc" attacks. | |
95 | .PP | |
96 | For some architectures, there is also an | |
97 | .B AT_SYSINFO | |
98 | tag. | |
99 | This is used only for locating the vsyscall entry point and is frequently | |
100 | omitted or set to 0 (meaning it's not available). | |
101 | This tag is a throwback to the initial vDSO work (see | |
102 | .IR History | |
103 | below) and its use should be avoided. | |
104 | .SS File format | |
105 | Since the vDSO is a fully formed ELF image, you can do symbol lookups on it. | |
106 | This allows new symbols to be added with newer kernel releases, | |
107 | and allows the C library to detect available functionality at | |
108 | run time when running under different kernel versions. | |
109 | Oftentimes the C library will do detection with the first call and then | |
110 | cache the result for subsequent calls. | |
111 | .PP | |
112 | All symbols are also versioned (using the GNU version format). | |
113 | This allows the kernel to update the function signature without breaking | |
114 | backward compatibility. | |
115 | This means changing the arguments that the function accepts as well as the | |
116 | return value. | |
117 | Thus, when looking up a symbol in the vDSO, | |
118 | you must always include the version | |
119 | to match the ABI you expect. | |
120 | .PP | |
121 | Typically the vDSO follows the naming convention of prefixing | |
122 | all symbols with "__vdso_" or "__kernel_" | |
123 | so as to distinguish them from other standard symbols. | |
124 | For example, the "gettimeofday" function is named "__vdso_gettimeofday". | |
125 | .PP | |
126 | You use the standard C calling conventions when calling | |
127 | any of these functions. | |
128 | No need to worry about weird register or stack behavior. | |
129 | .SH NOTES | |
130 | .SS Source | |
131 | When you compile the kernel, | |
132 | it will automatically compile and link the vDSO code for you. | |
133 | You will frequently find it under the architecture-specific directory: | |
134 | .PP | |
135 | find arch/$ARCH/ \-name \(aq*vdso*.so*\(aq \-o \-name \(aq*gate*.so*\(aq | |
136 | .\" | |
137 | .SS vDSO names | |
138 | The name of the vDSO varies across architectures. | |
139 | It will often show up in things like glibc's | |
140 | .BR ldd (1) | |
141 | output. | |
142 | The exact name should not matter to any code, so do not hardcode it. | |
143 | .if t \{\ | |
144 | .ft CW | |
145 | \} | |
146 | .TS | |
147 | l l. | |
148 | user ABI vDSO name | |
149 | _ | |
150 | aarch64 linux\-vdso.so.1 | |
151 | arm linux\-vdso.so.1 | |
152 | ia64 linux\-gate.so.1 | |
153 | mips linux\-vdso.so.1 | |
154 | ppc/32 linux\-vdso32.so.1 | |
155 | ppc/64 linux\-vdso64.so.1 | |
156 | riscv linux\-vdso.so.1 | |
157 | s390 linux\-vdso32.so.1 | |
158 | s390x linux\-vdso64.so.1 | |
159 | sh linux\-gate.so.1 | |
160 | i386 linux\-gate.so.1 | |
161 | x86-64 linux\-vdso.so.1 | |
162 | x86/x32 linux\-vdso.so.1 | |
163 | .TE | |
164 | .if t \{\ | |
165 | .in | |
166 | .ft P | |
167 | \} | |
168 | .SS strace(1), seccomp(2), and the vDSO | |
169 | When tracing systems calls with | |
170 | .BR strace (1), | |
171 | symbols (system calls) that are exported by the vDSO will | |
172 | .I not | |
173 | appear in the trace output. | |
174 | Those system calls will likewise not be visible to | |
175 | .BR seccomp (2) | |
176 | filters. | |
177 | .SH ARCHITECTURE-SPECIFIC NOTES | |
178 | The subsections below provide architecture-specific notes | |
179 | on the vDSO. | |
180 | .PP | |
181 | Note that the vDSO that is used is based on the ABI of your user-space code | |
182 | and not the ABI of the kernel. | |
183 | Thus, for example, | |
184 | when you run an i386 32-bit ELF binary, | |
185 | you'll get the same vDSO regardless of whether you run it under | |
186 | an i386 32-bit kernel or under an x86-64 64-bit kernel. | |
187 | Therefore, the name of the user-space ABI should be used to determine | |
188 | which of the sections below is relevant. | |
189 | .SS ARM functions | |
190 | .\" See linux/arch/arm/vdso/vdso.lds.S | |
191 | .\" Commit: 8512287a8165592466cb9cb347ba94892e9c56a5 | |
192 | The table below lists the symbols exported by the vDSO. | |
193 | .if t \{\ | |
194 | .ft CW | |
195 | \} | |
196 | .TS | |
197 | l l. | |
198 | symbol version | |
199 | _ | |
200 | __vdso_gettimeofday LINUX_2.6 (exported since Linux 4.1) | |
201 | __vdso_clock_gettime LINUX_2.6 (exported since Linux 4.1) | |
202 | .TE | |
203 | .if t \{\ | |
204 | .in | |
205 | .ft P | |
206 | \} | |
207 | .PP | |
208 | .\" See linux/arch/arm/kernel/entry-armv.S | |
209 | .\" See linux/Documentation/arm/kernel_user_helpers.txt | |
210 | Additionally, the ARM port has a code page full of utility functions. | |
211 | Since it's just a raw page of code, there is no ELF information for doing | |
212 | symbol lookups or versioning. | |
213 | It does provide support for different versions though. | |
214 | .PP | |
215 | For information on this code page, | |
216 | it's best to refer to the kernel documentation | |
217 | as it's extremely detailed and covers everything you need to know: | |
218 | .IR Documentation/arm/kernel_user_helpers.txt . | |
219 | .SS aarch64 functions | |
220 | .\" See linux/arch/arm64/kernel/vdso/vdso.lds.S | |
221 | The table below lists the symbols exported by the vDSO. | |
222 | .if t \{\ | |
223 | .ft CW | |
224 | \} | |
225 | .TS | |
226 | l l. | |
227 | symbol version | |
228 | _ | |
229 | __kernel_rt_sigreturn LINUX_2.6.39 | |
230 | __kernel_gettimeofday LINUX_2.6.39 | |
231 | __kernel_clock_gettime LINUX_2.6.39 | |
232 | __kernel_clock_getres LINUX_2.6.39 | |
233 | .TE | |
234 | .if t \{\ | |
235 | .in | |
236 | .ft P | |
237 | \} | |
238 | .SS bfin (Blackfin) functions (port removed in Linux 4.17) | |
239 | .\" See linux/arch/blackfin/kernel/fixed_code.S | |
240 | .\" See http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:fixed-code | |
241 | As this CPU lacks a memory management unit (MMU), | |
242 | it doesn't set up a vDSO in the normal sense. | |
243 | Instead, it maps at boot time a few raw functions into | |
244 | a fixed location in memory. | |
245 | User-space applications then call directly into that region. | |
246 | There is no provision for backward compatibility | |
247 | beyond sniffing raw opcodes, | |
248 | but as this is an embedded CPU, it can get away with things\(emsome of the | |
249 | object formats it runs aren't even ELF based (they're bFLT/FLAT). | |
250 | .PP | |
251 | For information on this code page, | |
252 | it's best to refer to the public documentation: | |
253 | .br | |
254 | http://docs.blackfin.uclinux.org/doku.php?id=linux\-kernel:fixed\-code | |
255 | .SS mips functions | |
256 | .\" See linux/arch/mips/vdso/vdso.ld.S | |
257 | .PP | |
258 | The table below lists the symbols exported by the vDSO. | |
259 | .if t \{\ | |
260 | .ft CW | |
261 | \} | |
262 | .TS | |
263 | l l. | |
264 | symbol version | |
265 | _ | |
266 | __kernel_gettimeofday LINUX_2.6 (exported since Linux 4.4) | |
267 | __kernel_clock_gettime LINUX_2.6 (exported since Linux 4.4) | |
268 | .TE | |
269 | .if t \{\ | |
270 | .in | |
271 | .ft P | |
272 | \} | |
273 | .SS ia64 (Itanium) functions | |
274 | .\" See linux/arch/ia64/kernel/gate.lds.S | |
275 | .\" Also linux/arch/ia64/kernel/fsys.S and linux/Documentation/ia64/fsys.txt | |
276 | The table below lists the symbols exported by the vDSO. | |
277 | .if t \{\ | |
278 | .ft CW | |
279 | \} | |
280 | .TS | |
281 | l l. | |
282 | symbol version | |
283 | _ | |
284 | __kernel_sigtramp LINUX_2.5 | |
285 | __kernel_syscall_via_break LINUX_2.5 | |
286 | __kernel_syscall_via_epc LINUX_2.5 | |
287 | .TE | |
288 | .if t \{\ | |
289 | .in | |
290 | .ft P | |
291 | \} | |
292 | .PP | |
293 | The Itanium port is somewhat tricky. | |
294 | In addition to the vDSO above, it also has "light-weight system calls" | |
295 | (also known as "fast syscalls" or "fsys"). | |
296 | You can invoke these via the | |
297 | .I __kernel_syscall_via_epc | |
298 | vDSO helper. | |
299 | The system calls listed here have the same semantics as if you called them | |
300 | directly via | |
301 | .BR syscall (2), | |
302 | so refer to the relevant | |
303 | documentation for each. | |
304 | The table below lists the functions available via this mechanism. | |
305 | .if t \{\ | |
306 | .ft CW | |
307 | \} | |
308 | .TS | |
309 | l. | |
310 | function | |
311 | _ | |
312 | clock_gettime | |
313 | getcpu | |
314 | getpid | |
315 | getppid | |
316 | gettimeofday | |
317 | set_tid_address | |
318 | .TE | |
319 | .if t \{\ | |
320 | .in | |
321 | .ft P | |
322 | \} | |
323 | .SS parisc (hppa) functions | |
324 | .\" See linux/arch/parisc/kernel/syscall.S | |
325 | .\" See linux/Documentation/parisc/registers | |
326 | The parisc port has a code page with utility functions | |
327 | called a gateway page. | |
328 | Rather than use the normal ELF auxiliary vector approach, | |
329 | it passes the address of | |
330 | the page to the process via the SR2 register. | |
331 | The permissions on the page are such that merely executing those addresses | |
332 | automatically executes with kernel privileges and not in user space. | |
333 | This is done to match the way HP-UX works. | |
334 | .PP | |
335 | Since it's just a raw page of code, there is no ELF information for doing | |
336 | symbol lookups or versioning. | |
337 | Simply call into the appropriate offset via the branch instruction, | |
338 | for example: | |
339 | .PP | |
340 | ble <offset>(%sr2, %r0) | |
341 | .if t \{\ | |
342 | .ft CW | |
343 | \} | |
344 | .TS | |
345 | l l. | |
346 | offset function | |
347 | _ | |
348 | 00b0 lws_entry (CAS operations) | |
349 | 00e0 set_thread_pointer (used by glibc) | |
350 | 0100 linux_gateway_entry (syscall) | |
351 | .TE | |
352 | .if t \{\ | |
353 | .in | |
354 | .ft P | |
355 | \} | |
356 | .SS ppc/32 functions | |
357 | .\" See linux/arch/powerpc/kernel/vdso32/vdso32.lds.S | |
358 | The table below lists the symbols exported by the vDSO. | |
359 | The functions marked with a | |
360 | .I * | |
361 | are available only when the kernel is | |
362 | a PowerPC64 (64-bit) kernel. | |
363 | .if t \{\ | |
364 | .ft CW | |
365 | \} | |
366 | .TS | |
367 | l l. | |
368 | symbol version | |
369 | _ | |
370 | __kernel_clock_getres LINUX_2.6.15 | |
371 | __kernel_clock_gettime LINUX_2.6.15 | |
372 | __kernel_datapage_offset LINUX_2.6.15 | |
373 | __kernel_get_syscall_map LINUX_2.6.15 | |
374 | __kernel_get_tbfreq LINUX_2.6.15 | |
375 | __kernel_getcpu \fI*\fR LINUX_2.6.15 | |
376 | __kernel_gettimeofday LINUX_2.6.15 | |
377 | __kernel_sigtramp_rt32 LINUX_2.6.15 | |
378 | __kernel_sigtramp32 LINUX_2.6.15 | |
379 | __kernel_sync_dicache LINUX_2.6.15 | |
380 | __kernel_sync_dicache_p5 LINUX_2.6.15 | |
381 | .TE | |
382 | .if t \{\ | |
383 | .in | |
384 | .ft P | |
385 | \} | |
386 | .PP | |
387 | The | |
388 | .B CLOCK_REALTIME_COARSE | |
389 | and | |
390 | .B CLOCK_MONOTONIC_COARSE | |
391 | clocks are | |
392 | .I not | |
393 | supported by the | |
394 | .I __kernel_clock_getres | |
395 | and | |
396 | .I __kernel_clock_gettime | |
397 | interfaces; | |
398 | the kernel falls back to the real system call. | |
399 | .SS ppc/64 functions | |
400 | .\" See linux/arch/powerpc/kernel/vdso64/vdso64.lds.S | |
401 | The table below lists the symbols exported by the vDSO. | |
402 | .if t \{\ | |
403 | .ft CW | |
404 | \} | |
405 | .TS | |
406 | l l. | |
407 | symbol version | |
408 | _ | |
409 | __kernel_clock_getres LINUX_2.6.15 | |
410 | __kernel_clock_gettime LINUX_2.6.15 | |
411 | __kernel_datapage_offset LINUX_2.6.15 | |
412 | __kernel_get_syscall_map LINUX_2.6.15 | |
413 | __kernel_get_tbfreq LINUX_2.6.15 | |
414 | __kernel_getcpu LINUX_2.6.15 | |
415 | __kernel_gettimeofday LINUX_2.6.15 | |
416 | __kernel_sigtramp_rt64 LINUX_2.6.15 | |
417 | __kernel_sync_dicache LINUX_2.6.15 | |
418 | __kernel_sync_dicache_p5 LINUX_2.6.15 | |
419 | .TE | |
420 | .if t \{\ | |
421 | .in | |
422 | .ft P | |
423 | \} | |
424 | .PP | |
425 | The | |
426 | .B CLOCK_REALTIME_COARSE | |
427 | and | |
428 | .B CLOCK_MONOTONIC_COARSE | |
429 | clocks are | |
430 | .I not | |
431 | supported by the | |
432 | .I __kernel_clock_getres | |
433 | and | |
434 | .I __kernel_clock_gettime | |
435 | interfaces; | |
436 | the kernel falls back to the real system call. | |
437 | .SS riscv functions | |
438 | .\" See linux/arch/riscv/kernel/vdso/vdso.lds.S | |
439 | The table below lists the symbols exported by the vDSO. | |
440 | .if t \{\ | |
441 | .ft CW | |
442 | \} | |
443 | .TS | |
444 | l l. | |
445 | symbol version | |
446 | _ | |
447 | __kernel_rt_sigreturn LINUX_4.15 | |
448 | __kernel_gettimeofday LINUX_4.15 | |
449 | __kernel_clock_gettime LINUX_4.15 | |
450 | __kernel_clock_getres LINUX_4.15 | |
451 | __kernel_getcpu LINUX_4.15 | |
452 | __kernel_flush_icache LINUX_4.15 | |
453 | .TE | |
454 | .if t \{\ | |
455 | .in | |
456 | .ft P | |
457 | \} | |
458 | .SS s390 functions | |
459 | .\" See linux/arch/s390/kernel/vdso32/vdso32.lds.S | |
460 | The table below lists the symbols exported by the vDSO. | |
461 | .if t \{\ | |
462 | .ft CW | |
463 | \} | |
464 | .TS | |
465 | l l. | |
466 | symbol version | |
467 | _ | |
468 | __kernel_clock_getres LINUX_2.6.29 | |
469 | __kernel_clock_gettime LINUX_2.6.29 | |
470 | __kernel_gettimeofday LINUX_2.6.29 | |
471 | .TE | |
472 | .if t \{\ | |
473 | .in | |
474 | .ft P | |
475 | \} | |
476 | .SS s390x functions | |
477 | .\" See linux/arch/s390/kernel/vdso64/vdso64.lds.S | |
478 | The table below lists the symbols exported by the vDSO. | |
479 | .if t \{\ | |
480 | .ft CW | |
481 | \} | |
482 | .TS | |
483 | l l. | |
484 | symbol version | |
485 | _ | |
486 | __kernel_clock_getres LINUX_2.6.29 | |
487 | __kernel_clock_gettime LINUX_2.6.29 | |
488 | __kernel_gettimeofday LINUX_2.6.29 | |
489 | .TE | |
490 | .if t \{\ | |
491 | .in | |
492 | .ft P | |
493 | \} | |
494 | .SS sh (SuperH) functions | |
495 | .\" See linux/arch/sh/kernel/vsyscall/vsyscall.lds.S | |
496 | The table below lists the symbols exported by the vDSO. | |
497 | .if t \{\ | |
498 | .ft CW | |
499 | \} | |
500 | .TS | |
501 | l l. | |
502 | symbol version | |
503 | _ | |
504 | __kernel_rt_sigreturn LINUX_2.6 | |
505 | __kernel_sigreturn LINUX_2.6 | |
506 | __kernel_vsyscall LINUX_2.6 | |
507 | .TE | |
508 | .if t \{\ | |
509 | .in | |
510 | .ft P | |
511 | \} | |
512 | .SS i386 functions | |
513 | .\" See linux/arch/x86/vdso/vdso32/vdso32.lds.S | |
514 | The table below lists the symbols exported by the vDSO. | |
515 | .if t \{\ | |
516 | .ft CW | |
517 | \} | |
518 | .TS | |
519 | l l. | |
520 | symbol version | |
521 | _ | |
522 | __kernel_sigreturn LINUX_2.5 | |
523 | __kernel_rt_sigreturn LINUX_2.5 | |
524 | __kernel_vsyscall LINUX_2.5 | |
525 | .\" Added in 7a59ed415f5b57469e22e41fc4188d5399e0b194 and updated | |
526 | .\" in 37c975545ec63320789962bf307f000f08fabd48. | |
527 | __vdso_clock_gettime LINUX_2.6 (exported since Linux 3.15) | |
528 | __vdso_gettimeofday LINUX_2.6 (exported since Linux 3.15) | |
529 | __vdso_time LINUX_2.6 (exported since Linux 3.15) | |
530 | .TE | |
531 | .if t \{\ | |
532 | .in | |
533 | .ft P | |
534 | \} | |
535 | .SS x86-64 functions | |
536 | .\" See linux/arch/x86/vdso/vdso.lds.S | |
537 | The table below lists the symbols exported by the vDSO. | |
538 | All of these symbols are also available without the "__vdso_" prefix, but | |
539 | you should ignore those and stick to the names below. | |
540 | .if t \{\ | |
541 | .ft CW | |
542 | \} | |
543 | .TS | |
544 | l l. | |
545 | symbol version | |
546 | _ | |
547 | __vdso_clock_gettime LINUX_2.6 | |
548 | __vdso_getcpu LINUX_2.6 | |
549 | __vdso_gettimeofday LINUX_2.6 | |
550 | __vdso_time LINUX_2.6 | |
551 | .TE | |
552 | .if t \{\ | |
553 | .in | |
554 | .ft P | |
555 | \} | |
556 | .SS x86/x32 functions | |
557 | .\" See linux/arch/x86/vdso/vdso32.lds.S | |
558 | The table below lists the symbols exported by the vDSO. | |
559 | .if t \{\ | |
560 | .ft CW | |
561 | \} | |
562 | .TS | |
563 | l l. | |
564 | symbol version | |
565 | _ | |
566 | __vdso_clock_gettime LINUX_2.6 | |
567 | __vdso_getcpu LINUX_2.6 | |
568 | __vdso_gettimeofday LINUX_2.6 | |
569 | __vdso_time LINUX_2.6 | |
570 | .TE | |
571 | .if t \{\ | |
572 | .in | |
573 | .ft P | |
574 | \} | |
575 | .SS History | |
576 | The vDSO was originally just a single function\(emthe vsyscall. | |
577 | In older kernels, you might see that name | |
578 | in a process's memory map rather than "vdso". | |
579 | Over time, people realized that this mechanism | |
580 | was a great way to pass more functionality | |
581 | to user space, so it was reconceived as a vDSO in the current format. | |
582 | .SH SEE ALSO | |
583 | .BR syscalls (2), | |
584 | .BR getauxval (3), | |
585 | .BR proc (5) | |
586 | .PP | |
587 | The documents, examples, and source code in the Linux source code tree: | |
588 | .PP | |
589 | .in +4n | |
590 | .EX | |
591 | Documentation/ABI/stable/vdso | |
592 | Documentation/ia64/fsys.txt | |
593 | Documentation/vDSO/* (includes examples of using the vDSO) | |
594 | ||
595 | find arch/ \-iname \(aq*vdso*\(aq \-o \-iname \(aq*gate*\(aq | |
596 | .EE | |
597 | .in |