为什么除了eax还提供orig_eax? [英] Why is orig_eax provided in addition to eax?
问题描述
为什么orig_eax
成员包含在sys/user.h
的struct user_regs_struct
中?
Why is the orig_eax
member included in sys/user.h
's struct user_regs_struct
?
推荐答案
因为它在 struct pt_regs
中,也就是 .... http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/arch/x86/include/asm/user_32.h#L77
Because it was in struct pt_regs
, which is .... 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
中(与旧的调试器和 ptrace
rs)
So, a lot of user-space utilities expect an orig_eax
field here, so it is included in user_regs_struct
too (to be compatible with older debuggers and ptrace
rs)
下一个问题是为什么 orig_eax
成员包含在 struct pt_regs
中?".
Next question is "Why is the orig_eax
member included in struct pt_regs
?".
它是在 linux 0.95 http://lxr.linux.no/#linux-old+v0.95/include/sys/ptrace.h#L44.我建议这是在其他一些带有 pt_regs
结构的 unix 之后完成的.0.95 中的评论说
It was added in linux 0.95 http://lxr.linux.no/#linux-old+v0.95/include/sys/ptrace.h#L44.
I suggest this was done after some other unix with pt_regs
struct. Comment in 0.95 says
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
So, the place of orig_eax
is defined by syscall interface. Here it is 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 的返回值(同一个文件,下面有点):
Why do we need to save old eax
twice? Because eax
will be used for the return value of syscall (same file, a bit below):
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
.那么在 syscall 之前使用的原始 eax
将丢失.为了保存它,有一个 orig_eax
字段.
Ptrace needs to be able to read both all registers state before syscall and the return value of syscall; but the return value is written to %eax
. Then original eax
, used before syscall will be lost. To save it, there is a orig_eax
field.
更新:感谢 R.. 和伟大的 LXR,我在 linux 0.95 中对 orig_eax
进行了全面搜索.
UPDATE: Thanks to R.. and great LXR, I did a full search of orig_eax
in linux 0.95.
它不仅用于ptrace,还用于do_signal 重新启动系统调用时(如果有系统调用,以 ERESTARTSYS
结尾)
It is used not only in ptrace, but also in do_signal when restarting a syscall (if there is a syscall, ended with ERESTARTSYS
)
158 *(&eax) = orig_eax;
UPDATE2:Linus 说一些有趣的事情:
UPDATE2: Linus said something interesting about it:
将 ORIG_EAX 设置为不是的某个值很重要有效的系统调用号,以便系统调用重启逻辑(见信号处理代码)不会触发.
It's important that ORIG_EAX be set to some value that is not a valid system call number, so that the system call restart logic (see the signal handling code) doesn't trigger.
UPDATE3: ptrace
r app (debugger) 可以改变 orig_eax
来改变被调用的系统调用号:http://lkml.org/lkml/1999/10/30/82(在某些版本的内核中,是 EIO 在 ptrace 中更改 ORIG_EAX)
UPDATE3: ptrace
r app (debugger) can change orig_eax
to change system call number to be called: http://lkml.org/lkml/1999/10/30/82 (in some versions of kernel, is was EIO to change in ptrace an ORIG_EAX)
这篇关于为什么除了eax还提供orig_eax?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!