void machdep_syscall( struct i386_saved_state *regs) { int trapno, nargs; machdep_call_t *entry; thread_t thread; struct proc *p; struct proc *current_proc(); trapno = regs->eax; if (trapno < 0 || trapno >= machdep_call_count) { regs->eax = (unsigned int)kern_invalid(); thread_exception_return(); /* NOTREACHED */ } entry = &machdep_call_table[trapno]; nargs = entry->nargs; if (nargs > 0) { int args[nargs]; if (copyin((char *) regs->uesp + sizeof (int), (char *) args, nargs * sizeof (int))) { regs->eax = KERN_INVALID_ADDRESS; thread_exception_return(); /* NOTREACHED */ } switch (nargs) { case 1: regs->eax = (*entry->routine)(args[0]); break; case 2: regs->eax = (*entry->routine)(args[0],args[1]); break; case 3: regs->eax = (*entry->routine)(args[0],args[1],args[2]); break; case 4: regs->eax = (*entry->routine)(args[0],args[1],args[2],args[3]); break; default: panic("machdep_syscall(): too many args"); } } else regs->eax = (*entry->routine)(); if (current_thread()->funnel_lock) (void) thread_funnel_set(current_thread()->funnel_lock, FALSE); thread_exception_return(); /* NOTREACHED */ }
void machdep_syscall64(x86_saved_state_t *state) { int trapno; const machdep_call_t *entry; x86_saved_state64_t *regs; assert(is_saved_state64(state)); regs = saved_state64(state); trapno = (int)(regs->rax & SYSCALL_NUMBER_MASK); DEBUG_KPRINT_SYSCALL_MDEP( "machdep_syscall64: trapno=%d\n", trapno); if (trapno < 0 || trapno >= machdep_call_count) { regs->rax = (unsigned int)kern_invalid(NULL); thread_exception_return(); /* NOTREACHED */ } entry = &machdep_call_table64[trapno]; switch (entry->nargs) { case 0: regs->rax = (*entry->routine.args_0)(); break; case 1: regs->rax = (*entry->routine.args64_1)(regs->rdi); break; case 2: regs->rax = (*entry->routine.args64_2)(regs->rdi, regs->rsi); break; default: panic("machdep_syscall64: too many args"); } DEBUG_KPRINT_SYSCALL_MDEP("machdep_syscall: retval=%llu\n", regs->rax); throttle_lowpri_io(1); thread_exception_return(); /* NOTREACHED */ }
void machdep_syscall(x86_saved_state_t *state) { int args[machdep_call_count]; int trapno; int nargs; const machdep_call_t *entry; x86_saved_state32_t *regs; assert(is_saved_state32(state)); regs = saved_state32(state); trapno = regs->eax; #if DEBUG_TRACE kprintf("machdep_syscall(0x%08x) code=%d\n", regs, trapno); #endif DEBUG_KPRINT_SYSCALL_MDEP( "machdep_syscall: trapno=%d\n", trapno); if (trapno < 0 || trapno >= machdep_call_count) { regs->eax = (unsigned int)kern_invalid(NULL); thread_exception_return(); /* NOTREACHED */ } entry = &machdep_call_table[trapno]; nargs = entry->nargs; if (nargs != 0) { if (copyin((user_addr_t) regs->uesp + sizeof (int), (char *) args, (nargs * sizeof (int)))) { regs->eax = KERN_INVALID_ADDRESS; thread_exception_return(); /* NOTREACHED */ } } switch (nargs) { case 0: regs->eax = (*entry->routine.args_0)(); break; case 1: regs->eax = (*entry->routine.args_1)(args[0]); break; case 2: regs->eax = (*entry->routine.args_2)(args[0],args[1]); break; case 3: if (!entry->bsd_style) regs->eax = (*entry->routine.args_3)(args[0],args[1],args[2]); else { int error; uint32_t rval; error = (*entry->routine.args_bsd_3)(&rval, args[0], args[1], args[2]); if (error) { regs->eax = error; regs->efl |= EFL_CF; /* carry bit */ } else { regs->eax = rval; regs->efl &= ~EFL_CF; } } break; case 4: regs->eax = (*entry->routine.args_4)(args[0], args[1], args[2], args[3]); break; default: panic("machdep_syscall: too many args"); } DEBUG_KPRINT_SYSCALL_MDEP("machdep_syscall: retval=%u\n", regs->eax); throttle_lowpri_io(1); thread_exception_return(); /* NOTREACHED */ }