vDSO(7) Miscellaneous Information Manual vDSO(7) vdso - ELF #include void *vdso = (uintptr_t) getauxval(AT_SYSINFO_EHDR); <> (virtual dynamic shared object, ) -- , . , , vDSO, , C. , C vDSO. , vDSO? , , . - , , . / C, . vDSO C, , , . . 32- x86 (int $0x80), . , : , . ( ) . , C , C , vDSO. , . x86 vDSO, , <<__kernel_vsyscall>>, x86-64 <> . One frequently used system call is gettimeofday(2). This system call is called both directly by user-space applications as well as indirectly by the C library. Think timestamps or timing loops or polling--all of these frequently need to know what time it is right now. This information is also not secret--any application in any privilege mode (root or any unprivileged user) will get the same answer. Thus the kernel arranges for the information required to answer this question to be placed in memory the process can access. Now a call to gettimeofday(2) changes from a system call to a normal function call and a few memory accesses. vDSO vDSO ( ) ( getauxval(3)) AT_SYSINFO_EHDR. , vDSO - . , ( execve(2)). << libc>>. AT_SYSINFO. vsyscall 0 ( ). -- vDSO ( ) . vDSO -- ELF, . C . , C . ( GNU). . . , vDSO, ABI. , vDSO , <<__vdso_>> <<__kernel_>>, . , <> <<__vdso_gettimeofday>>. . . vDSO . , : find arch/$ARCH/ -name '*vdso*.so*' -o -name '*gate*.so*' vDSO vDSO . , ldd(1) glibc. , . ABI vDSO name ------------------------------------------------------------- aarch64 linux-vdso.so.1 arm linux-vdso.so.1 ia64 linux-gate.so.1 mips linux-vdso.so.1 ppc/32 linux-vdso32.so.1 ppc/64 linux-vdso64.so.1 riscv linux-vdso.so.1 s390 linux-vdso32.so.1 s390x linux-vdso64.so.1 sh linux-gate.so.1 i386 linux-gate.so.1 x86-64 linux-vdso.so.1 x86/x32 linux-vdso.so.1 strace(1), seccomp(2) vDSO strace(1), ( ), vDSO, . seccomp(2). vDSO . , vDSO ABI , ABI . , 32- ELF i386, vDSO , 32- i386 64- x86-64. , ABI . ARM , vDSO. version ------------------------------------------------------------------------------------------------------------------ __vdso_gettimeofday LINUX_2.6 ( Linux 4.1) __vdso_clock_gettime LINUX_2.6 ( Linux 4.1) , ARM . , ELF . . For information on this code page, it's best to refer to the kernel documentation as it's extremely detailed and covers everything you need to know: Documentation/arm/kernel_user_helpers.rst. aarch64 , vDSO. version -------------------------------------- __kernel_rt_sigreturn LINUX_2.6.39 __kernel_gettimeofday LINUX_2.6.39 __kernel_clock_gettime LINUX_2.6.39 __kernel_clock_getres LINUX_2.6.39 bfin (Blackfin) ( Linux 4.17) As this CPU lacks a memory management unit (MMU), it doesn't set up a vDSO in the normal sense. Instead, it maps at boot time a few raw functions into a fixed location in memory. User-space applications then call directly into that region. There is no provision for backward compatibility beyond sniffing raw opcodes, but as this is an embedded CPU, it can get away with things--some of the object formats it runs aren't even ELF based (they're bFLT/FLAT). : http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:fixed-code mips , vDSO. version -------------------------------------------------------------------------------------------------------------------- __kernel_gettimeofday LINUX_2.6 ( Linux 4.4) __kernel_clock_gettime LINUX_2.6 ( Linux 4.4) ia64 (Itanium) , vDSO. version --------------------------------------- __kernel_sigtramp LINUX_2.5 __kernel_syscall_via_break LINUX_2.5 __kernel_syscall_via_epc LINUX_2.5 Itanium, , . vDSO, , << >> ( << syscall>> <>). vDSO __kernel_syscall_via_epc. , syscall(2), . , . ---------------------- clock_gettime getcpu getpid getppid gettimeofday set_tid_address parisc (hppa) parisc , (gateway) . , ELF, SR2. , . HP-UX. , ELF . , : ble <>(%sr2, %r0) offset ----------------------------------------------------------------------------- 00b0 lws_entry ( CAS) 00e0 set_thread_pointer ( glibc) 0100 linux_gateway_entry (syscall) ppc/32 , vDSO. , *, PowerPC64 (64-). version ---------------------------------------- __kernel_clock_getres LINUX_2.6.15 __kernel_clock_gettime LINUX_2.6.15 __kernel_clock_gettime64 LINUX_5.11 __kernel_datapage_offset LINUX_2.6.15 __kernel_get_syscall_map LINUX_2.6.15 __kernel_get_tbfreq LINUX_2.6.15 __kernel_getcpu * LINUX_2.6.15 __kernel_gettimeofday LINUX_2.6.15 __kernel_sigtramp_rt32 LINUX_2.6.15 __kernel_sigtramp32 LINUX_2.6.15 __kernel_sync_dicache LINUX_2.6.15 __kernel_sync_dicache_p5 LINUX_2.6.15 Before Linux 5.6, the CLOCK_REALTIME_COARSE and CLOCK_MONOTONIC_COARSE clocks are not supported by the __kernel_clock_getres and __kernel_clock_gettime interfaces; the kernel falls back to the real system call. ppc/64 , vDSO. version ---------------------------------------- __kernel_clock_getres LINUX_2.6.15 __kernel_clock_gettime LINUX_2.6.15 __kernel_datapage_offset LINUX_2.6.15 __kernel_get_syscall_map LINUX_2.6.15 __kernel_get_tbfreq LINUX_2.6.15 __kernel_getcpu LINUX_2.6.15 __kernel_gettimeofday LINUX_2.6.15 __kernel_sigtramp_rt64 LINUX_2.6.15 __kernel_sync_dicache LINUX_2.6.15 __kernel_sync_dicache_p5 LINUX_2.6.15 Before Linux 4.16, the CLOCK_REALTIME_COARSE and CLOCK_MONOTONIC_COARSE clocks are not supported by the __kernel_clock_getres and __kernel_clock_gettime interfaces; the kernel falls back to the real system call. riscv , vDSO. version ---------------------------------- __vdso_rt_sigreturn LINUX_4.15 __vdso_gettimeofday LINUX_4.15 __vdso_clock_gettime LINUX_4.15 __vdso_clock_getres LINUX_4.15 __vdso_getcpu LINUX_4.15 __vdso_flush_icache LINUX_4.15 s390 , vDSO. version -------------------------------------- __kernel_clock_getres LINUX_2.6.29 __kernel_clock_gettime LINUX_2.6.29 __kernel_gettimeofday LINUX_2.6.29 s390x , vDSO. version -------------------------------------- __kernel_clock_getres LINUX_2.6.29 __kernel_clock_gettime LINUX_2.6.29 __kernel_gettimeofday LINUX_2.6.29 sh (SuperH) , vDSO. version ---------------------------------- __kernel_rt_sigreturn LINUX_2.6 __kernel_sigreturn LINUX_2.6 __kernel_vsyscall LINUX_2.6 i386 , vDSO. version -------------------------------------------------------------------------------------------------------------------- __kernel_sigreturn LINUX_2.5 __kernel_rt_sigreturn LINUX_2.5 __kernel_vsyscall LINUX_2.5 __vdso_clock_gettime LINUX_2.6 ( Linux 3.15) __vdso_gettimeofday LINUX_2.6 ( Linux 3.15) __vdso_time LINUX_2.6 ( Linux 3.15) x86-64 , vDSO. <<__vdso_>>, , , . version --------------------------------- __vdso_clock_gettime LINUX_2.6 __vdso_getcpu LINUX_2.6 __vdso_gettimeofday LINUX_2.6 __vdso_time LINUX_2.6 x86/x32 , vDSO. version --------------------------------- __vdso_clock_gettime LINUX_2.6 __vdso_getcpu LINUX_2.6 __vdso_gettimeofday LINUX_2.6 __vdso_time LINUX_2.6 The vDSO was originally just a single function--the vsyscall. In older kernels, you might see that name in a process's memory map rather than "vdso". Over time, people realized that this mechanism was a great way to pass more functionality to user space, so it was reconceived as a vDSO in the current format. . syscalls(2), getauxval(3), proc(5) , Linux: Documentation/ABI/stable/vdso Documentation/ia64/fsys.rst Documentation/vDSO/* (includes examples of using the vDSO) find arch/ -iname '*vdso*' -o -iname '*gate*' Azamat Hackimov , Dmitriy Ovchinnikov , Dmitry Bolkhovskikh , Katrin Kutepova , Yuri Kozlov ; GNU 3 , . . , , . Linux man-pages 6.06 31 2023 . vDSO(7)