Registers stored on the stack in system_call

When the system_call function is called, it must check some arguments and call the function specified in the system call table according to the argument passed to eax. This is the part that preserves the registers:

system_call:
pushl %eax
SAVE_ALL
movl $0xffffe000, %ebx /* or 0xfffff000 for 4-KB stacks */
andl %esp, %ebx

      

Why does he save eax twice? (in the pushl command% eax and in the SAVE_ALL macro, which also saves eax).

+3


source to share


1 answer


In a standard C call on x86-32, it is used %eax

to return a value from a function. Linux system calls also return a return value to user space in %eax

. How is this done on x86-32?

The syscall entry point arch/x86/entry/entry_32.S

calls the syscall handler function and then overwrites the stored value %eax

(stored in SAVE_ALL

) on the stack with its return value. Later, returning back to user space, the stored values โ€‹โ€‹of all registers are popped off the stack into registers. Since the value %eax

stored SAVE_ALL

was overwritten with the required return value, when the user code resumes execution, naturally it finds the return value of syscall in %eax

.



But there are times when the kernel needs to find the original stored value %eax

. Even if the value saved in SAVE_ALL

has already been overwritten, it can still look at the value saved first pushl %eax

. In the kernel code, this value is called orig_eax

. (Grep is the kernel source, and you'll find it in several places.)

Take a look at the macro RESTORE_REGS

in arch/x86/entry/entry_32.S

and you will see that it takes a parameter pop

that is used to set up the stack after it has popped all the stored register values โ€‹โ€‹back into registers. You will RESTORE_REGS 4

only find in the place where syscall goes back to user space. This is "4" to get rid of the value pushl %eax

you asked for, also known as orig_eax

!

+1


source







All Articles