VDSO与vsyscall

概述

vsyscall和vDSO是用于加速某些系统调用的两种机制。

 

传统的int 0x80有点慢, Intel和AMD分别实现了sysenter/sysexit和syscall/ sysret, 即所谓的快速系统调用指令, 使用它们更快, 但是也带来了兼容性的问题. 于是Linux实现了vsyscall, 程序统一调用vsyscall, 具体的选择由内核来决定. 而vsyscall的实现就在VDSO中。

 

【vsyscall】

用来执行特定的系统调用,减少系统调用的开销。某些系统调用并不会向内核提交参数,而仅仅只是从内核里请求读取某个数据,例如gettimeofday(),内核在处理这部分系统调用时可以把系统当前时间写在一个固定的位置(由内核在每个时间中断里去完成这个更新动作),mmap映射到用户空间。这样会更快速,避免了传统系统调用模式INT 0x80/SYSCALL造成的内核空间和用户空间的上下文切换。

 

【vsyscall的局限】

分配的内存较小;

只允许4个系统调用;

Vsyscall页面在每个进程中是静态分配了相同的地址;

 

【vDSO】

提供和vsyscall相同的功能,同时解决了其局限。

vDSO是动态分配的,地址是随机的;

可以提供超过4个系统调用;

vDSO是glibc库提供的功能;

X64

测试环境Ubuntu 16.04

2.1 查看vsyscall/VDSO内存映射

millionsky@ubuntu-16:~/tmp/VDSO$ cat /proc/`pgrep cat | head -1`/maps | egrep 'vdso|vsyscall'

7ffdb57da000-7ffdb57dc000 r-xp 00000000 00:00 0                          [vdso]

ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

2.2 导出VDSO/vsyscall

2.2.1 Gdb导出vdso/vsyscall

millionsky@ubuntu-16:~/tmp/VDSO$ gdb -q /bin/ls

Reading symbols from /bin/ls...(no debugging symbols found)...done.

(gdb) tb __open

Function "__open" not defined.

Make breakpoint pending on future shared library load? (y or [n]) y

Temporary breakpoint 1 (__open) pending.

(gdb) r

Starting program: /bin/ls

 

Temporary breakpoint 1, open64 () at ../sysdeps/unix/syscall-template.S:84

84      ../sysdeps/unix/syscall-template.S: 没有那个文件或目录.

(gdb) info program

        Using the running image of child process 12012.

Program stopped at 0x7ffff7df2320.

It stopped at a breakpoint that has since been deleted.

Type "info stack" or "info registers" for more information.

(gdb) shell cat /proc/12012/maps | grep vdso

7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0                          [vdso]

(gdb) dump memory /tmp/linux-vdso.so.1 0x7ffff7ffa000 0x7ffff7ffc000

(gdb) q

 

同样的方法可以导出vsyscall

2.2.2 python导出vdso

#!/usr/bin/env python
from ctypes import *

for ln in open( '/proc/self/maps'):
if "[vdso]" in ln:
start, end = [ int(x, 16) for x in ln.split()[ 0].split( '-')]
CDLL( "libc.so.6").write( 1, c_void_p(start), end-start)
break

这里是Python调用的C库函数

2.2.3 C导出vdso

/* extract_vdso.c */
#include <stdio.h>
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值