.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)