Home > OS >  When does Linux x86-64 syscall clobber `%r8`, `%r9` and `%r10`?
When does Linux x86-64 syscall clobber `%r8`, `%r9` and `%r10`?

Time:10-11

I have just browsed the Linux kernel source tree, read the file tools/include/nolibc/nolibc.h [1].

I saw the syscall in this file uses %r8, %r9 and %r10 in the clobber list. Also there is a comment that says:

"rcx and r8..r11 may be clobbered, others are preserved."

As far as I know, syscall only clobbers %rax, %rcx and %r11 (and "memory").

Is there a real example of syscall that clobbers %r8, %r9 and %r10?

Link: [1] https://github.com/torvalds/linux/blob/7fd2bf83d59a2d32e0d596c5d3e623b9a0e7e2d5/tools/include/nolibc/nolibc.h#L268

CodePudding user response:

Only 32-bit system calls (e.g. via int 0x80) in 64-bit mode step on those registers, along with R11. (What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?).

syscall properly saves/restores R8, R9, and R10, so user-space using it can assume they keep their values.

(Those, with R11, are the non-legacy registers that are call-clobbered in the function-calling convention, so compiler-generated code for C functions inside the kernel naturally preserves R12-R15, even if an asm entry point didn't save them. Currently the 64-bit int 0x80 entry point just pushes 0 for the call-clobbered R8-R11 registers in the process-state struct that it will restore from before returning to user space, instead of the original register values. Perhaps earlier there were info leaks where it left them untouched after kernel code returned?)

  • Related