问题描述
我正在研究linux中的系统调用处理过程.
I'm studying system call handling process in linux.
我发现当用户进程运行syscall指令来调用系统调用时,会调用entry_SYSCALL_64函数.
I found that the entry_SYSCALL_64 function is called when the user process run syscall instruction to call system call.
此功能保存中断帧.
但是,当将ip推送到中断帧时,它读取的不是rip而是rcx.
However, when it push the ip to interrupt frame, it read not rip but rcx.
此代码很麻烦.
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
/*
* This path is only taken when PAGE_TABLE_ISOLATION is disabled so it
* is not required to switch CR3.
*/
movq %rsp, PER_CPU_VAR(rsp_scratch)
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
/* Construct struct pt_regs on stack */
pushq $__USER_DS /* pt_regs->ss */
pushq PER_CPU_VAR(rsp_scratch) /* pt_regs->sp */
pushq %r11 /* pt_regs->flags */
pushq $__USER_CS /* pt_regs->cs */
pushq %rcx /* pt_regs->ip ********************************** */
GLOBAL(entry_SYSCALL_64_after_hwframe)
pushq %rax /* pt_regs->orig_ax */
PUSH_AND_CLEAR_REGS rax=$-ENOSYS
TRACE_IRQS_OFF
/* IRQs are off. */
movq %rsp, %rdi
call do_syscall_64 /* returns with IRQs disabled */
....
我在重要的行中输入了很多'*'.
I entered the so many '*' in important line.
在评论中,它说它保存了ip寄存器,并且该偏移量正确地是ip的偏移量.
In the comment, it saying that it save ip register and this offset is offset of ip correctly.
但是,它显示为rcx....
However, it read rcx....
有人知道为什么吗?
推荐答案
因为 syscall
指令在进入内核之前,将syscall
之后的指令的地址存储到RCX中.
Because the syscall
instruction stores the address of the instruction following syscall
into RCX before entering the kernel.
这篇关于为什么Linux从entry_SYSCALL_64函数中的rcx寄存器读取ip寄存器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!