【发布时间】:2018-03-19 08:19:40
【问题描述】:
我正在研究linux中的系统调用处理过程。
我发现在用户进程运行syscall指令调用系统调用时调用了entry_SYSCALL_64函数。
这个函数保存中断帧。
但是,当它推送 ip 中断帧时,它读取的不是 rip 而是 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 */
....
我在重要的一行输入了这么多的“*”。
在评论中,它说它保存了ip寄存器并且这个偏移量是正确的ip偏移量。
但是,它读取的是 rcx....
有人知道为什么吗?
【问题讨论】:
标签: assembly linux-kernel operating-system system-calls cpu-registers