vdso学习

1、只有一小部分系统调用是通过vdso方式实现的,主要涉及get型的系统调用。例如:gettimeofday()、getcpu()、clock_gettime()、time()等。类似gettimeofday之类的调用,如果每次都陷入内核去拿一个时间戳,会消耗比较多的上下文切换时间,因此,内核把时间戳放在一个公共的可以暴露给任何用户进程的地方,并将其映射进用户进程的地址空间。不过,一般来说,通过vdso方式获得的都是一些不太敏感的信息,此时可以不用考虑特权等级,直接在用户态来获取。同时,vdso功能需要libc支持。引用一段话来说明vdso的意义:

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.


2、可以使用这篇博客上介绍的方法将进程地址空间中vdso段的内容dump到文件,可以发现,不同体系结构实现的vdso系统调用不尽相同,下面是三个不同体系结构所实现的不同vdso调用。
x86:

$ objdump -T vdso.dd

vdso.dd: 文件格式 elf64-x86-64

DYNAMIC SYMBOL TABLE:
ffffffffff700600 w DF .text 0000000000000545 LINUX_2.6 clock_gettime
0000000000000000 g DO *ABS* 0000000000000000 LINUX_2.6 LINUX_2.6
ffffffffff700b50 g DF .text 00000000000002b4 LINUX_2.6 __vdso_gettimeofday
ffffffffff700e30 g DF .text 000000000000003d LINUX_2.6 __vdso_getcpu
ffffffffff700b50 w DF .text 00000000000002b4 LINUX_2.6 gettimeofday
ffffffffff700e10 w DF .text 0000000000000016 LINUX_2.6 time
ffffffffff700e30 w DF .text 000000000000003d LINUX_2.6 getcpu
ffffffffff700600 g DF .text 0000000000000545 LINUX_2.6 __vdso_clock_gettime
ffffffffff700e10 g DF .text 0000000000000016 LINUX_2.6 __vdso_time


mips:

$ objdump -T vdso.dd

vdso.dd: 文件格式 elf64-tradlittlemips

DYNAMIC SYMBOL TABLE:
00000000000001c8 l d .MIPS.abiflags 0000000000000000 .MIPS.abiflags
0000000000000000 g DO *ABS* 0000000000000000 LINUX_2.6 LINUX_2.6
0000000000000350 g DF .text 00000000000001ac LINUX_2.6 __vdso_gettimeofday
0000000000000500 g DF .text 00000000000003f8 LINUX_2.6 __vdso_clock_gettime

ARM:

$ objdump -T vdso.dd

vdso.dd: 文件格式 elf64-littleaarch64

DYNAMIC SYMBOL TABLE:
0000000000000000 g DO *ABS* 0000000000000000 LINUX_2.6.39 LINUX_2.6.39
0000000000000644 g DF .text 0000000000000050 LINUX_2.6.39 __kernel_clock_getres
0000000000000698 g DF .text 0000000000000008 LINUX_2.6.39 __kernel_rt_sigreturn
0000000000000310 g DF .text 00000000000000a4 LINUX_2.6.39 __kernel_gettimeofday
00000000000003b4 g DF .text 0000000000000290 LINUX_2.6.39 __kernel_clock_gettime

参考资料:
1 https://man7.org/linux/man-pages/man7/vdso.7.html
2 https://blog.csdn.net/dog250/article/details/108807183
 

猜你喜欢

转载自blog.csdn.net/choumin/article/details/111352585
今日推荐