# # 64-bit system call numbers and entry vectors # # The format is: # <number> <abi> <name> <entry point> # # The __x64_sys_*() stubs are created on-the-fly for sys_*() system calls # # The abi is "common", "64" or "x32"for this file. # 0 common read __x64_sys_read 1 common write __x64_sys_write 2 common open __x64_sys_open ... 547 x32 pwritev2 __x32_compat_sys_pwritev64v2
(gdb) bt #0 __x64_sys_write (regs=0xffffc900001b7f58) at fs/read_write.c:620 #1 0xffffffff81002389 in do_syscall_64 (nr=<optimized out>, regs=0xffffc900001b7f58) at arch/x86/entry/common.c:290 #2 0xffffffff81c0007c in entry_SYSCALL_64 () at arch/x86/entry/entry_64.S:175
通过调用栈可以看到 是从 entry_SYSCALL_64 开始的,先这个函数的实现,这也是系统调用的入口了,看了这个函数的注释,写的很详细,这里说明了 rax system call number
/* * 64-bit SYSCALL instruction entry. Up to6 arguments in registers. *.... * * SYSCALL instructions can be found inlined in libc implementations as * well as some other programs and libraries. There are also a handful * of SYSCALL instructions in the vDSO used, for example, asa * clock_gettimeofday fallback. ..... * * Registers on entry: * rax systemcallnumber * rcx return address * r11 saved rflags (note: r11 is callee-clobbered register in C ABI) * rdi arg0 * rsi arg1 * rdx arg2 * r10 arg3 (needs tobe moved to rcx to conform to C ABI) * r8 arg4 * r9 arg5 * Only called from user space. */
ENTRY(entry_SYSCALL_64) UNWIND_HINT_EMPTY /* * Interrupts are off on entry. * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON, * it is too small to ever cause noticeable irq latency. */
swapgs ... TRACE_IRQS_OFF
/* IRQs are off. */ movq %rax, %rdi movq %rsp, %rsi call do_syscall_64 /* returns with IRQs disabled */
TRACE_IRQS_IRETQ /* we're about to change IF */ ...
从代码上看,中间有调用 do_syscall_64,继续看 do_syscall_64 如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
ENTRY(entry_SYSCALL_64) UNWIND_HINT_EMPTY /* * Interrupts are off on entry. * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON, * it is too small to ever cause noticeable irq latency. */
swapgs ... TRACE_IRQS_OFF
/* IRQs are off. */ movq %rax, %rdi movq %rsp, %rsi call do_syscall_64 /* returns with IRQs disabled */
TRACE_IRQS_IRETQ /* we're about to change IF */ ...
enter_from_user_mode(); local_irq_enable(); ti = current_thread_info(); if (READ_ONCE(ti->flags) & _TIF_WORK_SYSCALL_ENTRY) nr = syscall_trace_enter(regs);