vdso 官方文档翻译

官方文档
水平有限, 如果发现错误请指出, 我会尽快修改

NAME

vsdo - overview of the virtual ELF dynamic shared object

SYNOPSIS

void *vdso = (uintptr_t) getauxval(AT_SYSINFO_EHDR); //TODO

DESCRIPTION

"vDSO"(虚拟动态共享对象)是一个内核会自动映射到每个用户进程的地址空间的小型共享库. 用户的程序通常不需要关心vdso的内部细节, 因为这个库主要是提供给c语言库使用的. 你只需要使用c语言库提供的函数, 而c语言库会在某些必要的函数中使用到vdso提供的功能.

所以究竟为什么vdso会存在呢? 有些内核提供的系统调用会被用户非常频繁地调用, 以至于这些系统调用的性能会对程序的整体性能有决定性的影响. 因为频繁地系统调用同时也会导致用户空间和内核空间之间的频繁切换.

这个文档剩下的部分主要针对的是C语言库的开发者, 如果你试图在你自己的程序中使用vdso而不是使用c语言库那么你很有可能出错了.

Example background

进行系统调用可以很慢, 在x86架构的32位系统中, 你可以通过触发一个软中断(int 0x80)来告诉系统你要进行一个进行系统调用, 然而这个指令(int) 的代价非常大: 它需要经过一个完成的中断处理过程.(译注:原文为 it goes through the full interrupt-handling paths in the processor's microcode as well as in the kernel., 因为不清楚就不擅自翻译了)新的处理器提供了更快(同时也是向后兼容)的指令来进行系统调用. c语言库可以使用vdso中内核提供的函数, 而不是在运行时判断这项功能是否可以使用.

需要注意的是这儿有个属于可能会比较容易引起误会. 在x86系统中, vDSO中用来进行系统调用的函数被命名为__kernel_vsyscall, 但是在x86-64中, vsyscall还有这样的意思:一个过时的方法来询问内核当前的时间或者调用者所使用的cpu的信息.

一个常用的系统调用就是gettimeofday. 这个系统调用既会被用户直接调用, 也可能被c语言库调用. 比如polling, timing loops 或者timestamps , 这些情况下都需要通过频繁地调用gettimeofday来获知当前的时间. 而且时间这个信息不是需要保密的-任何运行在任何权限的程序(root 或者guest)都会得到相同的答案. 因此内核将获得答案(时间)所需要的信息放置在程序可以访问的到的内存空间中. 现在调用gettimeofday从需要进行系统调用变成了普通的函数调用和一些内存访问.

Finding the vDSO

内核通过ELF辅助向量(译注:关于什么是elf辅助向量可以参考这篇文章)中标签为AT_SYSINFO_EHDR的项来把vDSO的基地址传递给每个进程(参考 getauxval(3))

每个新创建的进程中vdso映射的地址是随机的, 这么做是出于安全性的考虑, 为了避免return2libc攻击

某些架构的elf辅助向量中还有一个标签为AT_SYSINFO的项. 这一项的作用就是用来确定vsyscall的入口地址而且经常被省略或者被置为0(意味着不可用). 从vdso的作用的角度看, 这个标签是倒退的表现.(参考下面的History部分) 所以应该避免使用它.

File format

既然vdso是一个完成的elf镜像, 所以你可以在其中查找符号(译注:原文为you can do symbol lookups on it). 这也意味着随着新的内核的发布, 新的符号也可以被添加进去, 同时也允许C语言库运行在不同版本的内核中时侦查可用的功能. 通常情况下c语言库会在第一次使用某个功能是进行查询并将结果缓存供之后调用使用.

所有的符号都有版本信息(译注:All symbols are also versioned (using the GNU version format))这样可以允许内核更新函数的签名而避免和之前的内核不兼容. 这意味着函数的参数和返回值都会被修改(译注:原文This means changing the arguments that the function accepts as well as the return value.不懂什么意思, 是update的过程中可以修改参数和返回值吗). 因此, 当你在vdso中查找某个符号的时候, 你必须把版本信息也带上.

通常情况下vsdo符合这样的命名规范: 每个符号都有__vdso_或者__kernel_前缀. 用以将这些符号和标准符号区分开来. for example: gettimeofday函数就被命名为__vdso_gettimeofday

调用vdso中的函数的过程就和调用c语言库调用中的函数是完全相同的, 你完全不需要考虑寄存器或者栈的行为.

NOTES

source

当你编译内核的时候, 它会自动编译并链接vdso的代码. 你会经常在architecture-specific目录中找到它
find arch/$ARCH/ -name '*vdso*.so*' -o -name '*gate*.so*'

vDSO names

vdso的命名在不同架构中可能不同. 我们通常可以通过类似glibc的ldd(1)的工具的输出来得到答案:

 $ ldd /bin/ls
         linux-vdso.so.1 (0x00007ffcc3563000)
         libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f87e5459000)
         libcap.so.2 => /lib64/libcap.so.2 (0x00007f87e5254000)
         libc.so.6 => /lib64/libc.so.6 (0x00007f87e4e92000)
         libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f87e4c22000)
         libdl.so.2 => /lib64/libdl.so.2 (0x00007f87e4a1e000)
         /lib64/ld-linux-x86-64.so.2 (0x00005574bf12e000)
         libattr.so.1 => /lib64/libattr.so.1 (0x00007f87e4817000)
         libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f87e45fa000)

命名并不会对其中的代码产生影响. 所以不要对其进行硬编码(译注: The exact name should not matter to any code, so do not hardcode it.)

user 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
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

(译注: 1. 我经过查询并未获知i386和x86的区别, 参考SO, 2. 关于x32可以参考这篇回答, 3. user ABI可能值得是用户空间的ABI, 而不是内核空间的ABI, 可以参考下面ARCHITECTURE-SPECIFIC NOTES的开头部分内容)

strace(1), seccomp(2), and the vDSO

当使用strace(1)追踪系统调用的时候, vdso 导出(export)的系统调用的符号不会再trace的输出中显示. 那些系统调用可能会对seccomp(2)过滤器不可见.

ARCHITECTURE-SPECIFIC NOTES

注意具体使用哪种vdso取决于用户空间的ABI, 而不是内核空间的ABI. 因此, for example, 当你运行一个i386 32位 elf 2进制文件, 不管你是在i386 32位内核空间还是x64 64位内核空间, 都会得到相同的vsdo, 因此需要根据用户空间的ABI来决定参考下面的哪个section(译注: 我这儿就贴一些我觉得常用的架构了)

ARM functions

下面的表列出了vdso导出的符号

symbol                 version
────────────────────────────────────────────────────────────
__vdso_gettimeofday    LINUX_2.6 (exported since Linux 4.1)
__vdso_clock_gettime   LINUX_2.6 (exported since Linux 4.1)

i386 functions

下面的表列出了vdso导出的符号

symbol                  version
──────────────────────────────────────────────────────────────
__kernel_sigreturn      LINUX_2.5
__kernel_rt_sigreturn   LINUX_2.5
__kernel_vsyscall       LINUX_2.5
__vdso_clock_gettime    LINUX_2.6 (exported since Linux 3.15)
__vdso_gettimeofday     LINUX_2.6 (exported since Linux 3.15)
__vdso_time             LINUX_2.6 (exported since Linux 3.15)

x86-64 functions

下面的表列出了vdso导出的符号, 所有这些符号去掉__vdso_前缀也都是可以找到的.

symbol                 version
─────────────────────────────────
__vdso_clock_gettime   LINUX_2.6
__vdso_getcpu          LINUX_2.6
__vdso_gettimeofday    LINUX_2.6
__vdso_time            LINUX_2.6

x86/x32 functions

下面的表列出了vdso导出的符号

symbol                 version
─────────────────────────────────
__vdso_clock_gettime   LINUX_2.6
__vdso_getcpu          LINUX_2.6
__vdso_gettimeofday    LINUX_2.6
__vdso_time            LINUX_2.6

History

vdso最初只包含一个函数:vsyscall, 在老版本的内核中, 你可能会在进程的memory map中看到vsyscall而不是vdso. 经过一段时间之后, 意识到可以使用这种机制给用户空间提供更多的功能, 所以它在新的版本中被重新构思(reconceive)为vdso

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,423评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,339评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,241评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,503评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,824评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,262评论 1 207
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,615评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,337评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,989评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,300评论 2 240
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,829评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,193评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,753评论 3 230
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,970评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,708评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,295评论 2 267
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,207评论 2 258

推荐阅读更多精彩内容