2.6的内核的系统调用的入口在那里,内核里说是0x80,可实际的机器呢?

当你在一个比较新的linux系统下使用ldd命令时,你会经常看到一个比较奇怪的文件名,即linux-gate.so.1:

ldd /bin/sh
linux-gate.so.1 => (0xffffe000)
libdl.so.2 => /lib/libdl.so.2 (0xb7fb2000)
libc.so.6 => /lib/libc.so.6 (0xb7e7c000)
/lib/ld-linux.so.2 (0xb7fba000)

它到底是什么文件呢?仅仅是一个动态载入库(dynamically loaded library),对吗?

对于广义的动态载入库定义来说,有那么几分意思。输出缺少文件名暗示了ldd不能找到这个文件的位置。事实上,任何试图找到这个文件的做法——无论是手工查找还是利用自动载入和分析这种库文件的软件——都不会成功。

一些用户时常因为寻找并不存在的系统文件而晕头转向并屡屡受挫。对于这种根本就不会有结果的寻找,你可以很自信的告诉用户:linux-gate.so.1文件目前在文件系统中根本就不被支持;它只是一个虚拟的DSO(译者注virtual DSO:dynamically shared object),一个在每个进程的存储空间(process’ memory)指定的地址点被内核暴露出来的共享对象:

cat /proc/self/maps
08048000-0804c000 r-xp 00000000 08:03 7971106 /bin/cat
0804c000-0804d000 rwxp 00003000 08:03 7971106 /bin/cat
0804d000-0806e000 rwxp 0804d000 00:00 0 [heap]
b7e88000-b7e89000 rwxp b7e88000 00:00 0 
b7e89000-b7fb8000 r-xp 00000000 08:03 8856588 /lib/libc-2.3.5.so
b7fb8000-b7fb9000 r-xp 0012e000 08:03 8856588 /lib/libc-2.3.5.so
b7fb9000-b7fbc000 rwxp 0012f000 08:03 8856588 /lib/libc-2.3.5.so
b7fbc000-b7fbe000 rwxp b7fbc000 00:00 0 
b7fc2000-b7fd9000 r-xp 00000000 08:03 8856915 /lib/ld-2.3.5.so
b7fd9000-b7fdb000 rwxp 00016000 08:03 8856915 /lib/ld-2.3.5.so
bfac3000-bfad9000 rw-p bfac3000 00:00 0 [stack]
ffffe000-fffff000 ---p 00000000 00:00 0 [vdso]

这里,cat输出了它自己的内存映射。标记[vdso]的行是该进程的linux-gate.so.1对象,一个映射到地址为ffffe000的单独的内存页面。程序可以通过查询ELF辅助向量中的AT_SYSINFO入口点来获取内存中共享对象的位置。和程序参数(argv)和环境变量(envp)类似,辅助向量(auxv)是一个指向新进程的指针数组。

理论上进程之间的地址可能是不同的,但是,据我所知linux内核总是把它映射到一个固定的位置。上面例子的输出来自一个x86 box,那里进程存在于无格式老的32位地址空间,空间页面大小为4096字节,使得ffffe000为倒数第二个页面。真正的最后一个页面被保存用来捕捉通过无效指针访问,例如,对一个消耗掉的NULL指针或者从mmap返回的MAP_FAILED指针进行解除参照。

因为所有的进程在相同的位置共享相同的对象,所以如果我们想进一步查看,很容易的就可以摘录出它的一个副本。例如,我们可以简单的使用dd来从它自己的空间中得到这个页面(谨慎的选择一个与linux-gate.so.1不同的输出名以免创建已存在的文件):

dd if=/proc/self/mem of=linux-gate.dso bs=4096 skip=1048574 count=1
1+0 records in
1+0 records out

我们跳过1048574个页面是因为总共有220=1048576个页面,我们想要的是与最后一个页面相邻的那个页面。和其它的共享ELF对象文件类似,结果如下:

file -b linux-gate.dso
ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), stripped

objdump -T linux-gate.dso

linux-gate.dso: file format elf32-i386

DYNAMIC SYMBOL TABLE:
ffffe400 l d .text 00000000 
ffffe460 l d .eh_frame_hdr 00000000 
ffffe484 l d .eh_frame 00000000 
ffffe608 l d .useless 00000000 
ffffe400 g DF .text 00000014 LINUX_2.5 __kernel_vsyscall
00000000 g DO *ABS* 00000000 LINUX_2.5 LINUX_2.5
ffffe440 g DF .text 00000007 LINUX_2.5 __kernel_rt_sigreturn
ffffe420 g DF .text 00000008 LINUX_2.5 __kernel_sigreturn

这些符号是rt_sigreturn/sigreturn函数的入口点,也是为了虚拟系统调用(virtual system call)用而设置。在x86平台上,linux-gate.so.1一开始的名字是linux-vsyscall.so.1,但是在开发过程中,为了使用一个通俗的名字而被修改了,从而精确的反映了在跨平台下的目的:在用户和内核空间之间起到网关(gateway)的作用。并不是所有的系统都需要虚拟系统调用,但是对x86它们一定同等重要,从而来保证这个精细的机制。

传统中,x86系统调用通过中断来实现。你可能还记得在不方便的老的MS-DOS时代,请求操作系统函数的方式是通过中断33(21h)。Windows系统调用隐藏在用户模式API层,但在一些地方它们同样深入到了int ox2e。在linux和其它的*nix内核中类似的实现使用int 0x80。

然而,在很多x86处理器家族中的新成员中,通过使用中断来调用系统调用的效率被证明是“相当”(^_^)低的。一个0x80系统调用单从命令来说,在2GHz Pentium上要比在一个850MHz Pentium Ⅲ上慢很多很多。因为这个原因而产生的在执行上的影响是明显的,至少对于执行大量系统调用的应用程序是这样的。

Intel在早期就注意到了这个问题,并且引进了一个更有效的以sysenter和sysexit的形式的系统调用接口。快速系统调用特色最初在Pentium Pro处理器中出现,但是由于硬件上的bug,它实际上被早期的大部分CPU所抛弃(broken)。这就是你可能看到PentiumⅡ甚至Pentium Ⅲ引入了sysenter的声明的原因了。

硬件的问题也可以帮助解释为什么在操作系统开始支持快速系统调用之前经历了很长时间。如果我们忽略早期的实验性质的片段(patches),Linux对sysenter的支持出现在2002年12月,那时内核2.5正在开发中。距离sysenter的提出已经有10年了!Micorsoft在Windows XP中才刚刚使用sysenter。

如果你的Linux机器在系统调用上使用了sysenter指令,你可以通过反汇编__kernel_vsyscall找到:

objdump -d --start-address=0xffffe400 --stop-address=0xffffe414 linux-gate.dso

linux-gate.dso: file format elf32-i386

Disassembly of section .text:

ffffe400 <__kernel_vsyscall>:
ffffe400: 51 push %ecx
ffffe401: 52 push %edx
ffffe402: 55 push %ebp
ffffe403: 89 e5 mov %esp,%ebp
ffffe405: 0f 34 sysenter 
ffffe407: 90 nop 
ffffe408: 90 nop 
ffffe409: 90 nop 
ffffe40a: 90 nop 
ffffe40b: 90 nop 
ffffe40c: 90 nop 
ffffe40d: 90 nop 
ffffe40e: eb f3 jmp ffffe403 <__kernel_vsyscall+0x3>
ffffe410: 5d pop %ebp
ffffe411: 5a pop %edx
ffffe412: 59 pop %ecx
ffffe413: c3 ret

系统调用的首选调用策略在启动时由内核确定,很明显这个box使用了sysenter。在老式机器上你可能会看到int 0x80被使用。如果你正努力地想搞清楚这个跳转(jump)的含义(象我第一次看到它一样),你可能会兴趣很浓的去学习以至于认为其原因是:Linus Torvalds is a disgusting pig and proud of it.(使用六个参数来处理重起系统调用是一个小窍门)。

转载于:https://www.cnblogs.com/moonflow/archive/2012/04/21/2461678.html

Linux-gate.so.1的含义[ZZ]相关推荐

  1. Linux特殊符号使用及含义

    linux特殊符号使用及含义 #: #!/bin/bash 常出现在命令之前,或者命令之后,后面是注释文字,不会被执行 #当输入的命令不想被执行时输入(#)就行了 #This line is comm ...

  2. Linux Ubuntu终端“@”前后的含义及修改(修改用户名及主机名)【试用办法,部分不可行】

    Linux & Ubuntu终端"@"前后的含义及修改(修改用户名及主机名)[试用办法,部分不可行] "@" 前为用户名(当前用户),修改方法: htt ...

  3. Linux的三种权限含义,Linux chmod命令及权限含义

    对于一条权限赋值命令:sudo chmod  -R 764 ×××:我们必须了解其含义: (1)各字段含义:sudo chmod  -R(更改文件夹及其子文件夹) 7(所有者权限)6(组用户权限)4( ...

  4. linux su 的含义,linux su命令的真正含义,linuxsu命令

    linux su命令的真正含义,linuxsu命令 linux中,我以root登录,和以其他用户登录然后使用su命令切换至root用户,有什么不一样,如果一样的话,我执行su命令之后,其他的用户还在不 ...

  5. 07-15 shell命令 man ps linux各个文件夹的含义

    man [name] 获取联机帮助 NAME:命令(函数)的名称 SYNOPSIS:命令的语法格式 DESCRIPTION:命令的一般描述及用途 OPTIONS:描述命令所有的参数或选项 SEE AL ...

  6. Linux Linux中“”, “.“和”..“的含义

    Linux中"/", "./"和"-/"的含义 Linux 中的文件(夹)是以树形结构表示的. / 表示根目录 ./ 表示当前目录 ../ ...

  7. 【博客529】linux cpu的 “steal time“含义

    linux cpu的 "steal time"含义 Steal Time Steal time is the percentage of time a virtual CPU wa ...

  8. linux程序返回码的含义

    [原文链接]linux程序返回码的含义 文章目录 一.错误码 0-10 的含义 二.错误码 11-20 的含义 三.错误码 21-30 的含义 四.错误码 31-40 的含义 五.错误码 41-50 ...

  9. Linux下chmod命令的含义

    关于linux下chmod命令的含义 在Linux文件系统中,文件基本上被分为三个属性:可读( r ).可写( w ).可执行( x ). 使用ls -l命令可以查看每个文件的权限,如果我们需要修改某 ...

  10. linux权限0777代表的含义

    linux权限0777代表的含义 0777前面的0是代表suid和guid的 suid意味着如果某个用户对属于自己的shell脚本设置了这种权限,那么其他用户在执行这一脚本时也会具有其属主的相应权限. ...

最新文章

  1. Spring Security——获取当前已登录用户UserDetails对象
  2. 操作系统【连续式分配方式、隐式链接、显示链接、索引方式、混合索引、位示图、成组链接】
  3. Java生成pgp密钥对_在Javascript中生成PGP密钥对,并使用加密的PGP私钥对文本进行签名...
  4. 程序员的吸星大法-IDA反汇编工具初探
  5. Bigraph Extension
  6. GIT提交记录和Revert commit过程分析
  7. 由PPPOE看Linux网络协议栈的实现
  8. 基于jQuery的uploadify(flash上传文件)控件v1.6.2 bug修正
  9. vs 生成get set_使用EasyCode+Lombok快速生成增删查改的代码
  10. python读取txt文件数据并存到list中
  11. 使用百度地图时,经纬度坐标正确,但位置只显示北京
  12. matlab求n阶行列式,发福利了,线性代数n阶行列式计算器!(需要的拿走吧)
  13. 如何扩展以太坊:分片原理解释
  14. 什么是大数据?大数据的特点?
  15. 鸿蒙思维闪卡训练,提高孩子智力,父母不妨使用思维导图来提升孩子记忆力和创造力...
  16. 一、区块链项目的基础架构
  17. 文件下载(解决中文文件名下载乱码问题)(二)
  18. outlook电子邮件解析_放大Outlook 2007中的电子邮件
  19. 一键通(手机实现对讲机功能)
  20. Linux常用命令——uname命令

热门文章

  1. 移动全平台性能测试工具PerfDog--安装及运行
  2. h5滚动时侧滑出现_H5触摸事件中如何判断用户滑动方向
  3. npm install react-native-video --save
  4. php加mysql分页_php mysql 分页函数
  5. python变量类型之间转换_Python变量赋值类型转换
  6. Visual Studio找不到iOS模拟器
  7. ios开发中计算代码运算时间_iOS日历、日期、时间的计算
  8. codebilcks怎么新建c++文件_电脑开机后桌面空白一个图标都没有,怎么回事?
  9. iphone圆点怎么弄出来_新款iPhone放出终极大招,果粉:就没高级点的嘛
  10. vivoNEX3s版本服务器无响应,vivo NEX 3S为什么突然无人问津,这几点原因道出真相...