Is syscall an instruction on x86_64?

pythonic picture pythonic · May 14, 2012 · Viewed 18.1k times · Source

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)?

Answer

flolo picture flolo · May 14, 2012

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.