Why is the orig_eax
member included in sys/user.h
's struct user_regs_struct
?

- 224,562
- 31
- 268
- 324

- 112,946
- 110
- 377
- 526
1 Answers
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)
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)
Next question is "Why is the orig_eax
member included in struct pt_regs
?".
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.
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
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 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.
UPDATE: Thanks to R.. and great LXR, I did a full search of orig_eax
in linux 0.95.
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 said something interesting about it:
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) 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)
-
4cracking answer to a (seemingly) flimsy question! – sehe Jun 24 '11 at 14:50
-
2I figured it was related to syscalls (and possibly syscall restarting). +1 for tracking down the details! – R.. GitHub STOP HELPING ICE Jun 24 '11 at 16:18
-
note, that recent kernels renamed field to orig_ax - if you want to do a LXR search, do both orig_eax and orig_ax. – osgx Jun 24 '11 at 16:38
-
Why would it need orig_eax anyway? Why would it matter what system call it is after the appropriate one was invoked? As I understand, the return value of system call is written to the stack, where late we pop it and save it in eax. And orig_eax is there just to make sure we do not loose the sys call invoked. My other question, why is the return value written on stack and not immediately to eax? – Tony Tannous Apr 14 '18 at 22:05