.align 5
NESTED(handle_sys64, PT_SIZE, sp)
dsubu t0, v0, __NR_64_Linux # check syscall number 检查是否为有效系统调用号
sltiu t0, t0, __NR_64_Linux_syscalls + 1
beqz t0, illegal_syscall
dsll t0, v0, 3 # offset into table
ld t2, (sys_call_table - (__NR_64_Linux * 8))(t0)
# syscall routine 通过偏移计算出系统调用入口在sys_call_table的位置
sd a3, PT_R26(sp) # save a3 for syscall restarting 寄存器压栈
li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_KERNEL_TRACE
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? 检查是否打开了系统调用跟踪
and t0, t1, t0
bnez t0, syscall_trace_entry
jalr t2 # Do The Real Thing (TM) 系统调用入口函数
li t0, -EMAXERRNO - 1 # error?
sltu t0, t0, v0
sd t0, PT_R7(sp) # set error flag 系统调用返回值检查
beqz t0, 1f
dnegu v0 # error
sd v0, PT_R0(sp) # set flag for syscall
# restarting
1: sd v0, PT_R2(sp) # result
n64_syscall_exit:
local_irq_disable # make sure need_resched and
# signals dont change between
# sampling and return
LONG_L a2, TI_FLAGS($28) # current->work
li t0, _TIF_ALLWORK_MASK
and t0, a2, t0
bnez t0, n64_syscall_exit_work
j restore_partial
n64_syscall_exit_work:
j syscall_exit_work_partial
/* ------------------------------------------------------------------------ */
syscall_trace_entry:
SAVE_STATIC #寄存器16-30入栈
move s0, t2
move a0, sp #第一个参数是当前栈指针
li a1, 0 #第二个参数是0
jal do_syscall_trace
move t0, s0 #回到
RESTORE_STATIC #恢复寄存器16-30
ld a0, PT_R4(sp) # Restore argument registers
ld a1, PT_R5(sp)
ld a2, PT_R6(sp)
ld a3, PT_R7(sp)
ld a4, PT_R8(sp)
ld a5, PT_R9(sp)
jalr t0
li t0, -EMAXERRNO - 1 # error?
sltu t0, t0, v0
sd t0, PT_R7(sp) # set error flag
beqz t0, 1f
dnegu v0 # error
sd v0, PT_R0(sp) # set flag for syscall restarting
1: sd v0, PT_R2(sp) # result
j syscall_exit
illegal_syscall:
/* This also isn't a 64-bit syscall, throw an error. */
li v0, ENOSYS # error
sd v0, PT_R2(sp)
li t0, 1 # set error flag
sd t0, PT_R7(sp)
j n64_syscall_exit
END(handle_sys64)