Fix some types:
* code, args, and rval should use register_t. * argsize should be a size_t. Remove old notimp() kluge; replaced by a better mechanism. Add some of the SunOS compat hooks.
This commit is contained in:
parent
e363664703
commit
e518635e13
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: trap.c,v 1.28 1995/02/08 14:53:33 mycroft Exp $ */
|
/* $NetBSD: trap.c,v 1.29 1995/03/08 06:39:06 mycroft Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1988 University of Utah.
|
* Copyright (c) 1988 University of Utah.
|
||||||
@ -885,25 +885,22 @@ dumpwb(num, s, a, d)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Proces a system call.
|
* Process a system call.
|
||||||
*/
|
*/
|
||||||
syscall(code, frame)
|
syscall(code, frame)
|
||||||
u_int code;
|
register_t code;
|
||||||
struct frame frame;
|
struct frame frame;
|
||||||
{
|
{
|
||||||
register caddr_t params;
|
register caddr_t params;
|
||||||
register struct sysent *callp;
|
register struct sysent *callp;
|
||||||
register struct proc *p;
|
register struct proc *p;
|
||||||
int error, opc, numsys;
|
int error, opc, nsys;
|
||||||
u_int argsize;
|
size_t argsize;
|
||||||
struct args {
|
register_t args[8], rval[2];
|
||||||
int i[8];
|
|
||||||
} args;
|
|
||||||
int rval[2];
|
|
||||||
u_quad_t sticks;
|
u_quad_t sticks;
|
||||||
#ifdef COMPAT_HPUX
|
#ifdef COMPAT_HPUX
|
||||||
extern struct sysent hpux_sysent[];
|
extern struct sysent hpux_sysent[];
|
||||||
extern int hpux_nsysent, notimp();
|
extern int hpux_nsysent;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cnt.v_syscall++;
|
cnt.v_syscall++;
|
||||||
@ -913,15 +910,55 @@ syscall(code, frame)
|
|||||||
sticks = p->p_sticks;
|
sticks = p->p_sticks;
|
||||||
p->p_md.md_regs = frame.f_regs;
|
p->p_md.md_regs = frame.f_regs;
|
||||||
opc = frame.f_pc;
|
opc = frame.f_pc;
|
||||||
#ifdef COMPAT_HPUX
|
|
||||||
if (p->p_emul == EMUL_HPUX)
|
|
||||||
callp = hpux_sysent, numsys = hpux_nsysent;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
callp = sysent, numsys = nsysent;
|
|
||||||
params = (caddr_t)frame.f_regs[SP] + sizeof(int);
|
|
||||||
switch (code) {
|
|
||||||
|
|
||||||
|
switch (p->p_emul) {
|
||||||
|
case EMUL_NETBSD:
|
||||||
|
nsys = nsysent;
|
||||||
|
callp = sysent;
|
||||||
|
break;
|
||||||
|
#ifdef COMPAT_SUNOS
|
||||||
|
case EMUL_SUNOS:
|
||||||
|
nsys = nsunos_sysent;
|
||||||
|
callp = sunos_sysent;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SunOS passes the syscall-number on the stack, whereas
|
||||||
|
* BSD passes it in D0. So, we have to get the real "code"
|
||||||
|
* from the stack, and clean up the stack, as SunOS glue
|
||||||
|
* code assumes the kernel pops the syscall argument the
|
||||||
|
* glue pushed on the stack. Sigh...
|
||||||
|
*/
|
||||||
|
code = fuword((caddr_t)frame.f_regs[SP]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX
|
||||||
|
* Don't do this for sunos_sigreturn, as there's no stored pc
|
||||||
|
* on the stack to skip, the argument follows the syscall
|
||||||
|
* number without a gap.
|
||||||
|
*/
|
||||||
|
if (code != SUNOS_SYS_sigreturn) {
|
||||||
|
frame.f_regs[SP] += sizeof (int);
|
||||||
|
/*
|
||||||
|
* remember that we adjusted the SP,
|
||||||
|
* might have to undo this if the system call
|
||||||
|
* returns ERESTART.
|
||||||
|
*/
|
||||||
|
p->p_md.md_flags |= MDP_STACKADJ;
|
||||||
|
} else
|
||||||
|
p->p_md.md_flags &= ~MDP_STACKADJ;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef COMPAT_HPUX
|
||||||
|
case EMUL_HPUX:
|
||||||
|
nsys = hpux_nsysent;
|
||||||
|
callp = hpux_sysent;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
params = (caddr_t)frame.f_regs[SP] + sizeof(int);
|
||||||
|
|
||||||
|
switch (code) {
|
||||||
case SYS_syscall:
|
case SYS_syscall:
|
||||||
/*
|
/*
|
||||||
* Code is first argument, followed by actual args.
|
* Code is first argument, followed by actual args.
|
||||||
@ -934,54 +971,43 @@ syscall(code, frame)
|
|||||||
* trap. Cannot allow it here so make sure we fail.
|
* trap. Cannot allow it here so make sure we fail.
|
||||||
*/
|
*/
|
||||||
if (code == SYS_sigreturn)
|
if (code == SYS_sigreturn)
|
||||||
code = numsys;
|
code = nsys;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SYS___syscall:
|
case SYS___syscall:
|
||||||
/*
|
/*
|
||||||
* Like syscall, but code is a quad, so as to maintain
|
* Like syscall, but code is a quad, so as to maintain
|
||||||
* quad alignment for the rest of the arguments.
|
* quad alignment for the rest of the arguments.
|
||||||
*/
|
*/
|
||||||
#ifdef COMPAT_HPUX
|
if (callp != sysent)
|
||||||
if (p->p_emul == EMUL_HPUX)
|
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
code = fuword(params + _QUAD_LOWWORD * sizeof(int));
|
code = fuword(params + _QUAD_LOWWORD * sizeof(int));
|
||||||
params += sizeof(quad_t);
|
params += sizeof(quad_t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* nothing to do by default */
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (code < numsys)
|
if (code < 0 || code >= nsys)
|
||||||
callp += code;
|
callp = &callp[0]; /* illegal */
|
||||||
else
|
else
|
||||||
callp += SYS_syscall; /* => nosys */
|
callp = &callp[code];
|
||||||
argsize = callp->sy_argsize;
|
argsize = callp->sy_argsize;
|
||||||
if (argsize && (error = copyin(params, (caddr_t)&args, argsize))) {
|
if (argsize)
|
||||||
#ifdef KTRACE
|
error = copyin(params, (caddr_t)args, argsize);
|
||||||
if (KTRPOINT(p, KTR_SYSCALL))
|
else
|
||||||
ktrsyscall(p->p_tracep, code, callp->sy_narg, argsize,
|
error = 0;
|
||||||
args.i);
|
#ifdef SYSCALL_DEBUG
|
||||||
|
scdebug_call(p, code, args);
|
||||||
#endif
|
#endif
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
#ifdef KTRACE
|
#ifdef KTRACE
|
||||||
if (KTRPOINT(p, KTR_SYSCALL))
|
if (KTRPOINT(p, KTR_SYSCALL))
|
||||||
ktrsyscall(p->p_tracep, code, callp->sy_narg, argsize, args.i);
|
ktrsyscall(p->p_tracep, code, callp->sy_narg, argsize, args);
|
||||||
#endif
|
#endif
|
||||||
|
if (error)
|
||||||
|
goto bad;
|
||||||
rval[0] = 0;
|
rval[0] = 0;
|
||||||
rval[1] = frame.f_regs[D1];
|
rval[1] = frame.f_regs[D1];
|
||||||
#ifdef COMPAT_HPUX
|
error = (*callp->sy_call)(p, args, rval);
|
||||||
/* debug kludge */
|
|
||||||
if (callp->sy_call == notimp)
|
|
||||||
error = notimp(p, args.i, rval, code, callp->sy_narg, argsize);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
error = (*callp->sy_call)(p, &args, rval);
|
|
||||||
switch (error) {
|
switch (error) {
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
/*
|
/*
|
||||||
* Reinitialize proc pointer `p' as it may be different
|
* Reinitialize proc pointer `p' as it may be different
|
||||||
@ -990,19 +1016,18 @@ syscall(code, frame)
|
|||||||
p = curproc;
|
p = curproc;
|
||||||
frame.f_regs[D0] = rval[0];
|
frame.f_regs[D0] = rval[0];
|
||||||
frame.f_regs[D1] = rval[1];
|
frame.f_regs[D1] = rval[1];
|
||||||
frame.f_sr &= ~PSL_C;
|
frame.f_sr &= ~PSL_C; /* carry bit */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ERESTART:
|
case ERESTART:
|
||||||
/*
|
/*
|
||||||
* Reconstruct pc, assuming trap #0 is 2 bytes.
|
* We always enter through a `trap' instruction, which is 2
|
||||||
|
* bytes, so adjust the pc by that amount.
|
||||||
*/
|
*/
|
||||||
frame.f_pc = opc - 2;
|
frame.f_pc = opc - 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EJUSTRETURN:
|
case EJUSTRETURN:
|
||||||
break; /* nothing to do */
|
/* nothing to do */
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
bad:
|
bad:
|
||||||
#ifdef COMPAT_HPUX
|
#ifdef COMPAT_HPUX
|
||||||
@ -1010,10 +1035,18 @@ syscall(code, frame)
|
|||||||
error = bsdtohpuxerrno(error);
|
error = bsdtohpuxerrno(error);
|
||||||
#endif
|
#endif
|
||||||
frame.f_regs[D0] = error;
|
frame.f_regs[D0] = error;
|
||||||
frame.f_sr |= PSL_C;
|
frame.f_sr |= PSL_C; /* carry bit */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SYSCALL_DEBUG
|
||||||
|
scdebug_ret(p, code, error, rval[0]);
|
||||||
|
#endif
|
||||||
|
#ifdef COMPAT_SUNOS
|
||||||
|
/* need new p-value for this */
|
||||||
|
if (error == ERESTART && (p->p_md.md_flags & MDP_STACKADJ))
|
||||||
|
frame.f_regs[SP] -= sizeof (int);
|
||||||
|
#endif
|
||||||
userret(p, &frame, sticks, (u_int)0, 0);
|
userret(p, &frame, sticks, (u_int)0, 0);
|
||||||
#ifdef KTRACE
|
#ifdef KTRACE
|
||||||
if (KTRPOINT(p, KTR_SYSRET))
|
if (KTRPOINT(p, KTR_SYSRET))
|
||||||
|
Loading…
Reference in New Issue
Block a user