void EMULNAME(syscall_intern)(struct proc *p) { if (trace_is_enabled(p)) p->p_md.md_syscall = EMULNAME(syscall_fancy); else p->p_md.md_syscall = EMULNAME(syscall_plain); }
void EMULNAME(syscall_intern)(struct proc *p) { #ifdef KTRACE if (p->p_traceflag & (KTRFAC_SYSCALL | KTRFAC_SYSRET)) p->p_md.md_syscall = EMULNAME(syscall_fancy); else #endif p->p_md.md_syscall = EMULNAME(syscall_plain); }
void EMULNAME(syscall_intern)(struct proc *p) { p->p_md.md_syscall = EMULNAME(syscall); }
void EMULNAME(syscall)(struct trapframe *tf) { struct lwp * const l = curlwp; struct proc * const p = l->l_proc; register_t *args = &tf->tf_a0; register_t retval[2]; const struct sysent *callp; int code, error; size_t i; #ifdef _LP64 const bool pk32_p = (p->p_flag & PK_32) != 0; register_t copyargs[EMULNAME(SYS_MAXSYSARGS)]; #endif LWP_CACHE_CREDS(l, p); curcpu()->ci_data.cpu_nsyscall++; tf->tf_pc += sizeof(uint32_t); callp = p->p_emul->e_sysent; code = tf->tf_t6 - SYSCALL_SHIFT; /* * Userland should have taken care of moving everything to their * usual place so these code's should never get to the kernel. */ if (code == SYS_syscall || code == SYS___syscall) { error = ENOSYS; goto bad; } if (code >= p->p_emul->e_nsysent) callp += p->p_emul->e_nosys; else callp += code; const size_t nargs = callp->sy_narg; #ifdef _LP64 /* * If there are no 64bit arguments, we still need "sanitize" the * 32-bit arguments in case they try to slip through a 64-bit pointer. * and all arguments were in * registers, just use the trapframe for the source of arguments */ if (pk32_p) { size_t narg64 = SYCALL_NARGS64(callp); unsigned int arg64mask = SYCALL_ARG_64_MASK(callp); bool doing_arg64 = false; register_t *args32 = args; /* * All arguments are 32bits wide and if we have 64bit arguments * then use two 32bit registers to construct a 64bit argument. * We remarshall them into 64bit slots but we don't want to * disturb the original arguments in case we get restarted. */ if (SYCALL_NARGS64(callp) > 0) { args = copyargs; } /* * Copy all the arguments to copyargs, starting with the ones * in registers. Using the hints in the 64bit argmask, * we marshall the passed 32bit values into 64bit slots. If we * encounter a 64 bit argument, we grab two adjacent 32bit * values and synthesize the 64bit argument. */ for (i = 0; i < nargs + narg64; ) { register_t arg = *args32++; if (__predict_true((arg64mask & 1) == 0)) { /* * Just copy it with sign extension on */ args[i++] = (int32_t) arg; arg64mask >>= 1; continue; } /* * 64bit arg. grab the low 32 bits, discard the high. */ arg = (uint32_t)arg; if (!doing_arg64) { /* * Pick up the 1st word of a 64bit arg. * If lowword == 1 then highword == 0, * so this is the highword and thus * shifted left by 32, otherwise * lowword == 0 and highword == 1 so * it isn't shifted at all. Remember * we still need another word. */ doing_arg64 = true; args[i] = arg << (_QUAD_LOWWORD*32); narg64--; /* one less 64bit arg */ } else { /* * Pick up the 2nd word of a 64bit arg. * if highword == 1, it's shifted left * by 32, otherwise lowword == 1 and * highword == 0 so it isn't shifted at * all. And now head to the next argument. */ doing_arg64 = false; args[i++] |= arg << (_QUAD_HIGHWORD*32); arg64mask >>= 1; } } }
#include <riscv/locore.h> #ifndef EMULNAME #define EMULNAME(x) (x) #include <sys/syscall.h> #include <sys/syscallvar.h> #endif #ifndef SYSCALL_SHIFT #define SYSCALL_SHIFT 0 #endif void EMULNAME(syscall_intern)(struct proc *); static void EMULNAME(syscall)(struct trapframe *); __CTASSERT(EMULNAME(SYS_MAXSYSARGS) <= 8); void EMULNAME(syscall_intern)(struct proc *p) { p->p_md.md_syscall = EMULNAME(syscall); } /* * Process a system call. * * System calls are strange beasts. They are passed the syscall number * in t6, and the arguments in the registers (as normal). * The return value (if any) in a0 and possibly a1. The instruction * directly after the syscall is excepted to contain a jump instruction * for an error handler. If the syscall completes with no error, the PC