为什么在eax之外还提供orig_eax?

为什么orig_eax列入成员sys/user.hstruct user_regs_struct

回答:

因为它在中struct pt_regs,所以…。http :

//tomoyo.sourceforge.jp/cgi-

bin/lxr/source/arch/x86/include/asm/user_32.h#L77

 73  * is still the layout used by user mode (the new

74 * pt_regs doesn't have all registers as the kernel

75 * doesn't use the extra segment registers)

因此,许多用户空间实用程序都希望在orig_eax此处输入一个字段,因此也包含在其中user_regs_struct(以与较早的调试器和ptracers

兼容)

下一个问题是“为什么将orig_eax成员包括在其中struct pt_regs?”。

它是在Linux 0.95 http://lxr.linux.no/#linux-

old+v0.95/include/sys/ptrace.h#L44中添加的。我建议这是在其他一些带有pt_regsstruct的Unix之后完成的。0.95中的评论说

  29 * this struct defines the way the registers are stored on the 

30 * stack during a system call.

因此,的位置orig_eax由syscall接口定义。这是http://lxr.linux.no/#linux-

old+v0.95/kernel/sys_call.s

  17 * Stack layout in 'ret_from_system_call':

18 * ptrace needs to have all regs on the stack.

19 * if the order here is changed, it needs to be

20 * updated in fork.c:copy_process, signal.c:do_signal,

21 * ptrace.c ptrace.h

22 *

23 * 0(%esp) - %ebx

...

29 * 18(%esp) - %eax

...

34 * 2C(%esp) - orig_eax

为什么我们需要保存eax两次旧的?因为eax将用于syscall的返回值(相同的文件,下面一点):

  96_system_call:

97 cld

98 pushl %eax # save orig_eax

99 push %gs

...

102 push %ds

103 pushl %eax # save eax. The return value will be put here.

104 pushl %ebp

...

117 call _sys_call_table(,%eax,4)

Ptrace必须能够读取syscall之前的所有寄存器状态以及syscall的返回值。但返回值被写入%eax。然后eaxsyscall之前使用的original

将会丢失。要保存它,有一个orig_eax字段。

更新:感谢R ..和出色的LXR,我orig_eax在linux 0.95中进行了全面搜索。

它不仅在ptrace中使用,而且在重新启动syscall时也用在do_signal中(如果有syscall,以结束ERESTARTSYS

 158                        *(&eax) = orig_eax;

UPDATE2:Linus 说了一些有趣的事情:

重要的是将ORIG_EAX设置为某个值,该值 不是 有效的系统调用号,以免触发系统调用重新启动逻辑(请参见信号处理代码)。

UPDATE3:ptracer应用程序(调试器)可以更改orig_eax以更改要调用的系统调用号码:http

:

//lkml.org/lkml/1999/10/30/82(在某些版本的内核中,是EIO在ptrace中更改了ORIG_EAX)

以上是 为什么在eax之外还提供orig_eax? 的全部内容, 来源链接: utcz.com/qa/425911.html

回到顶部