I wanted to check the code for performing system calls in glibc. I found something like this.
ENTRY (syscall) movq %rdi, %rax /* Syscall number -> rax. */ movq %rsi, %rdi /* shift arg1 - arg5. */ movq %rdx, %rsi movq %rcx, %rdx movq %r8, %r10 movq %r9, %r8 movq 8(%rsp),%r9 /* arg6 is on the stack. */ syscall /* Do the system call. */ cmpq $-4095, %rax /* Check %rax for error. */ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ L(pseudo_end): ret /* Return to caller. */
Now my question is if the syscall (before the cmpq
instruction) is an instruction? Secondly, if it is an instruction, what is the meaning of ENTRY (syscall)? The same name for an ENTRY (I don't know what an ENTRY is) and instruction? Secondly, what is L(pseudo_end)?
syscall
is an instruction in x86-64, and is used as part of the ABI for making system calls. (The 32-bit ABI uses int 80h
or sysenter
, and is also available in 64-bit mode, but using the 32-bit ABI from 64-bit code is a bad idea, especially for calls with pointer arguments.)
But there is also a C library function named syscall(2)
, a generic wrapper for the system-call ABI. Your code shows the dump of that function, including its decoding of the return value into errno
-setting. ENTRY(syscall)
just means that the function starts there.
L()
and ENTRY()
are CPP macros.
L(pseudo_end)
is just a Label that can be a jump target. Maybe the code at SYSCALL_ERROR_LABEL
jumps back to there, although it would be more efficient for that block of code to just ret
, so maybe it's a relic from a former version, or used for something else.
Yes, syscall
is an instruction on x86-64. There is a similar instruction sysenter
on i686.
ENTRY(syscall)
would be a macro. Probably expands to the symbol definition, you have to grep for that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With