Linux系统调用,libc,VDSO和实现解析
我在最后一个libc中剖析了syscall调用:
我在sysdeps / unix / sysv / linux / i386 / sysdep.h中有这个代码:
如果我理解这段代码,那么LOADREGS _ ## nr(args)宏会将参数加载到寄存器ebx,ecx,edx,esi,edx和ebp中. sysdeps / UNIX / SYSV / LINUX / I386 / sysdep.h中
在ebx,edx和ebp寄存器中加载参数的代码在哪里?这是上面的代码吗?我不明白实施.
这段代码是什么:
它加载ebx寄存器中的第一个参数? 然后“call * %% gs:%P2”跳转到VDSO代码?这段代码对应“call * gs:0x10”? 那么,这个写系统调用的下图,它很好吗?:
我不懂VDSO实用程序! vdso选择syscall方法(sysenter或int 0x80). 提前谢谢你的帮助.抱歉,我的英语非常糟糕. 最佳答案 对于退出系统调用的例子,glibc的系统调用中涉及的宏将扩展为类似下面的内容.
LOADREGS_1(args)将扩展为LOADREGS_0(),它将扩展为空 – LOADREGS _ *(…)只需要在提供更多参数时调整寄存器. ASMARGS_1(args)将扩展为ASMARGS_0(),“b”((unsigned int)(arg1)),它将扩展为“b”((unsigned int)(arg1). x86上__NR_exit为1. 因此,代码将扩展为:
ASMARGS_ *实际上并不执行代码本身 – 它们是gcc的指令,以确保某些值(例如(unsigned int)(arg1))在某些寄存器中(例如b,aka ebx).因此,asm volatile的参数组合(当然,这不是一个函数,只是一个gcc内置函数)只是简单地指定gcc应该如何为系统调用做准备以及在系统调用完成后它应该如何继续. 现在,生成的程序集将如下所示:
%gs是一个引用线程本地存储的段寄存器 – 具体来说,glibc引用一个指向VDSO的保存值,当它首次解析说明VDSO所在位置的ELF头时,它存储在那里. 一旦代码进入VDSO,我们就不确切知道发生了什么 – 它取决于内核版本 – 但我们知道它使用最有效的可用机制来运行系统调用,例如sysenter指令或int 0x80指令. 所以,是的,你的图表是准确的:
这是一个更简单的代码调用VDSO,特别是对于单参数系统调用,来自我维护的名为libsyscall的库:
这只是将参数从堆栈移到寄存器中,通过从内存加载的指针调用VDSO,将其他寄存器恢复到先前的状态,并返回系统调用的结果. (编辑:鲜蔬坊站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- linux – su和sudo在shell脚本中
- linux – rsync到NAS每次都会复制一切
- linux – Ubuntu / Mint上的PhpStorm更新
- linux – 在json中使Apache2服务目录索引
- linux – 意外地以root身份运行“chown www-data:www-data
- c – 来自Windows的交叉编译GNU ARM(BeagleBoneBlack). * .
- linux – 如何执行cron作业故障转移?
- linux – 在Spark sbin /文件夹中的stop-all.sh没有停止所有
- linux – 从“ps”获取完整的结果
- linux – 两个目录的不同文件