/系统调用中的 ptregs table
/ptregs in syscall table
为什么系统调用table中的某些系统调用有/ptregs
?
来自 arch/x86/entry/syscalls/syscall_64.tbl 的示例:
54 64 setsockopt sys_setsockopt
55 64 getsockopt sys_getsockopt
56 common clone sys_clone/ptregs
57 common fork sys_fork/ptregs
58 common vfork sys_vfork/ptregs
59 64 execve sys_execve/ptregs
60 common exit sys_exit
61 common wait4 sys_wait4
这些是特殊的系统调用,需要在堆栈上布置完整的寄存器转储(作为 struct pt_regs
)。这只适用于 64 位 x86 架构,因为它有更多的寄存器(与 32 位相比)。
系统调用处理程序 (arch/x86/entry/entry_64.S:entry_SYSCALL_64) 在系统调用入口时将大部分寄存器保存在堆栈中。这样做部分是为了支持 ptrace(),部分是为了将参数传递给用 C 编写的实际系统调用处理程序(这就是为什么他们有 asmlinkage
规范,它使函数从堆栈中获取参数)。系统调用最多有 6 个参数(rdi、rsi、rdx、r10、r8、r9),一些寄存器用于 SYSCALL 簿记(rax、rcx、r11)。您不需要保存 rbp、rbx、r12、r13、r14、r15(因为它们是被调用者保存的),因此出于性能原因它们不会在入口时保存。系统调用处理完成后,寄存器会在返回用户空间之前从此备份中恢复。
但是,有些系统调用(如execve()、fork()、sigreturn()等)需要在栈上有all寄存器(包括rbp、rbx , r12–r15), 在 struct pt_regs
。这是因为这些系统调用会导致用户空间从不同的地方重新开始执行,所以它们需要保存准确的寄存器值。它们在 syscall_64.tbl 中用 /ptregs
标记,以便发生以下魔术。
通常系统调用处理程序 table (sys_call_table
) 包含指向 C 函数的指针。但是对于那些特殊的系统调用,处理程序是 small assembly thunks,它首先保存额外的寄存器,然后跳转到 C 代码(这就是慢路径所做的)。 table 中的 /ptregs
后缀指示脚本将这些存根而不是 C 函数插入处理程序 table.
为什么系统调用table中的某些系统调用有/ptregs
?
来自 arch/x86/entry/syscalls/syscall_64.tbl 的示例:
54 64 setsockopt sys_setsockopt
55 64 getsockopt sys_getsockopt
56 common clone sys_clone/ptregs
57 common fork sys_fork/ptregs
58 common vfork sys_vfork/ptregs
59 64 execve sys_execve/ptregs
60 common exit sys_exit
61 common wait4 sys_wait4
这些是特殊的系统调用,需要在堆栈上布置完整的寄存器转储(作为 struct pt_regs
)。这只适用于 64 位 x86 架构,因为它有更多的寄存器(与 32 位相比)。
系统调用处理程序 (arch/x86/entry/entry_64.S:entry_SYSCALL_64) 在系统调用入口时将大部分寄存器保存在堆栈中。这样做部分是为了支持 ptrace(),部分是为了将参数传递给用 C 编写的实际系统调用处理程序(这就是为什么他们有 asmlinkage
规范,它使函数从堆栈中获取参数)。系统调用最多有 6 个参数(rdi、rsi、rdx、r10、r8、r9),一些寄存器用于 SYSCALL 簿记(rax、rcx、r11)。您不需要保存 rbp、rbx、r12、r13、r14、r15(因为它们是被调用者保存的),因此出于性能原因它们不会在入口时保存。系统调用处理完成后,寄存器会在返回用户空间之前从此备份中恢复。
但是,有些系统调用(如execve()、fork()、sigreturn()等)需要在栈上有all寄存器(包括rbp、rbx , r12–r15), 在 struct pt_regs
。这是因为这些系统调用会导致用户空间从不同的地方重新开始执行,所以它们需要保存准确的寄存器值。它们在 syscall_64.tbl 中用 /ptregs
标记,以便发生以下魔术。
通常系统调用处理程序 table (sys_call_table
) 包含指向 C 函数的指针。但是对于那些特殊的系统调用,处理程序是 small assembly thunks,它首先保存额外的寄存器,然后跳转到 C 代码(这就是慢路径所做的)。 table 中的 /ptregs
后缀指示脚本将这些存根而不是 C 函数插入处理程序 table.