1 /* $NetBSD: irix_signal.c,v 1.52 2009/11/23 00:46:06 rmind Exp $ */
4 * Copyright (c) 1994, 2001-2002 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas and Emmanuel Dreyfus.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: irix_signal.c,v 1.52 2009/11/23 00:46:06 rmind Exp $");
35 #include <sys/types.h>
36 #include <sys/signal.h>
37 #include <sys/param.h>
38 #include <sys/kernel.h>
40 #include <sys/ptrace.h>
42 #include <sys/resourcevar.h>
43 #include <sys/systm.h>
44 #include <sys/vnode.h>
47 #include <machine/regnum.h>
48 #include <machine/trap.h>
50 #include <compat/common/compat_util.h>
52 #include <compat/svr4/svr4_types.h>
53 #include <compat/svr4/svr4_wait.h>
54 #include <compat/svr4/svr4_signal.h>
55 #include <compat/svr4/svr4_lwp.h>
56 #include <compat/svr4/svr4_ucontext.h>
57 #include <compat/svr4/svr4_syscallargs.h>
59 #include <compat/irix/irix_signal.h>
60 #include <compat/irix/irix_errno.h>
61 #include <compat/irix/irix_exec.h>
62 #include <compat/irix/irix_syscallargs.h>
64 extern const int native_to_svr4_signo
[];
65 extern const int svr4_to_native_signo
[];
67 static int irix_wait_siginfo(int, struct rusage
*, int,
68 struct irix_irix5_siginfo
*);
69 static void irix_signal_siginfo(struct irix_irix5_siginfo
*,
71 static void irix_set_ucontext(struct irix_ucontext
*, const sigset_t
*,
73 static void irix_set_sigcontext(struct irix_sigcontext
*, const sigset_t
*,
75 static void irix_get_ucontext(struct irix_ucontext
*, struct lwp
*);
76 static void irix_get_sigcontext(struct irix_sigcontext
*, struct lwp
*);
78 #define irix_sigmask(n) (1 << (((n) - 1) & 31))
79 #define irix_sigword(n) (((n) - 1) >> 5)
80 #define irix_sigemptyset(s) memset((s), 0, sizeof(*(s)))
81 #define irix_sigismember(s, n) ((s)->bits[irix_sigword(n)] & irix_sigmask(n))
82 #define irix_sigaddset(s, n) ((s)->bits[irix_sigword(n)] |= irix_sigmask(n))
85 * Build a struct siginfo wor waitsys/waitid
86 * This is ripped from svr4_setinfo. See irix_sys_waitsys...
89 irix_wait_siginfo(int pid
, struct rusage
*ru
, int st
, struct irix_irix5_siginfo
*s
)
91 struct irix_irix5_siginfo i
;
94 memset(&i
, 0, sizeof(i
));
96 i
.isi_signo
= SVR4_SIGCHLD
;
97 i
.isi_errno
= 0; /* XXX? */
101 i
.isi_stime
= ru
->ru_stime
.tv_sec
;
102 i
.isi_utime
= ru
->ru_utime
.tv_sec
;
106 i
.isi_status
= WEXITSTATUS(st
);
107 i
.isi_code
= SVR4_CLD_EXITED
;
108 } else if (WIFSTOPPED(st
)) {
110 if (sig
>= 0 && sig
< NSIG
)
111 i
.isi_status
= native_to_svr4_signo
[sig
];
113 if (i
.isi_status
== SVR4_SIGCONT
)
114 i
.isi_code
= SVR4_CLD_CONTINUED
;
116 i
.isi_code
= SVR4_CLD_STOPPED
;
119 if (sig
>= 0 && sig
< NSIG
)
120 i
.isi_status
= native_to_svr4_signo
[sig
];
123 i
.isi_code
= SVR4_CLD_DUMPED
;
125 i
.isi_code
= SVR4_CLD_KILLED
;
128 return copyout(&i
, s
, sizeof(i
));
132 * Build a struct siginfo for signal delivery
135 irix_signal_siginfo(struct irix_irix5_siginfo
*isi
, int sig
, u_long code
, void *addr
)
137 if (sig
< 0 || sig
>= SVR4_NSIG
) {
138 isi
->isi_errno
= IRIX_EINVAL
;
141 isi
->isi_signo
= native_to_svr4_signo
[sig
];
143 isi
->isi_addr
= (intptr_t)addr
;
151 isi
->isi_code
= IRIX_SEGV_MAPERR
;
152 isi
->isi_errno
= IRIX_EFAULT
;
155 isi
->isi_code
= IRIX_BUS_ADRERR
;
156 isi
->isi_errno
= IRIX_EACCES
;
159 isi
->isi_code
= IRIX_SEGV_MAPERR
;
160 isi
->isi_errno
= IRIX_ENOMEM
;
169 case T_BUS_ERR_IFETCH
:
170 case T_BUS_ERR_LD_ST
:
171 /* NetBSD issues a SIGSEGV here, IRIX rather uses SIGBUS */
172 isi
->isi_code
= IRIX_SEGV_MAPERR
;
173 isi
->isi_errno
= IRIX_EFAULT
;
177 isi
->isi_code
= IRIX_TRAP_BRKPT
;
182 /* NetBSD issues SIGSEGV here, IRIX rather uses SIGILL */
183 isi
->isi_code
= IRIX_SEGV_MAPERR
;
184 isi
->isi_errno
= IRIX_EFAULT
;
188 isi
->isi_errno
= IRIX_EOVERFLOW
;
190 isi
->isi_code
= IRIX_FPE_INTOVF
;
194 isi
->isi_code
= IRIX_FPE_FLTINV
;
205 printf("irix_signal_siginfo: sig %d code %ld\n", sig
, code
);
212 native_to_irix_sigset(const sigset_t
*bss
, irix_sigset_t
*sss
)
216 irix_sigemptyset(sss
);
217 for (i
= 1; i
< NSIG
; i
++) {
218 if (sigismember(bss
, i
)) {
219 newsig
= native_to_svr4_signo
[i
];
221 irix_sigaddset(sss
, newsig
);
227 irix_to_native_sigset(const irix_sigset_t
*sss
, sigset_t
*bss
)
232 for (i
= 1; i
< SVR4_NSIG
; i
++) {
233 if (irix_sigismember(sss
, i
)) {
234 newsig
= svr4_to_native_signo
[i
];
236 sigaddset(bss
, newsig
);
242 irix_sendsig(const ksiginfo_t
*ksi
, const sigset_t
*mask
)
244 struct lwp
*l
= curlwp
;
245 struct proc
*p
= l
->l_proc
;
247 struct frame
*f
= l
->l_md
.md_regs
;
250 sig_t catcher
= SIGACTION(p
, ksi
->ksi_signo
).sa_handler
;
251 struct irix_sigframe sf
;
254 printf("irix_sendsig()\n");
255 printf("catcher = %p, sig = %d, code = 0x%x\n",
256 (void *)catcher
, ksi
->ksi_signo
, ksi
->ksi_trap
);
257 printf("irix_sendsig(): starting [PC=0x%#"PRIxREGISTER
258 " SP=%#"PRIxREGISTER
" SR=0x%08lx]\n",
259 f
->f_regs
[_R_PC
], f
->f_regs
[_R_SP
], f
->f_regs
[_R_SR
]);
260 #endif /* DEBUG_IRIX */
263 * Do we need to jump onto the signal stack?
266 (l
->l_sigstk
.ss_flags
& (SS_DISABLE
| SS_ONSTACK
)) == 0
267 && (SIGACTION(p
, ksi
->ksi_signo
).sa_flags
& SA_ONSTACK
) != 0;
270 printf("irix_sendsig: using signal stack\n");
273 * Allocate space for the signal handler context.
276 sp
= (void *)((char *)l
->l_sigstk
.ss_sp
277 + l
->l_sigstk
.ss_size
);
279 /* cast for O64 case */
280 sp
= (void *)(intptr_t)f
->f_regs
[_R_SP
];
283 * Build the signal frame
285 memset(&sf
, 0, sizeof(sf
));
286 if (SIGACTION(p
, ksi
->ksi_signo
).sa_flags
& SA_SIGINFO
) {
287 irix_set_ucontext(&sf
.isf_ctx
.iss
.iuc
, mask
, ksi
->ksi_trap
, l
);
288 irix_signal_siginfo(&sf
.isf_ctx
.iss
.iis
, ksi
->ksi_signo
,
289 ksi
->ksi_trap
, (void *)f
->f_regs
[_R_BADVADDR
]);
291 irix_set_sigcontext(&sf
.isf_ctx
.isc
, mask
, ksi
->ksi_trap
, l
);
295 * Compute the new stack address after copying sigframe
297 sp
= (void *)((intptr_t)sp
- sizeof(sf
.isf_ctx
));
298 sp
= (void *)((intptr_t)sp
& ~0xfUL
); /* 16 bytes alignement */
301 * Install the sigframe onto the stack
303 sendsig_reset(l
, ksi
->ksi_signo
);
304 mutex_exit(p
->p_lock
);
305 error
= copyout(&sf
.isf_ctx
, sp
, sizeof(sf
.isf_ctx
));
306 mutex_enter(p
->p_lock
);
310 * Process has trashed its stack; give it an illegal
311 * instruction to halt it in its tracks.
314 printf("irix_sendsig: stack trashed\n");
315 #endif /* DEBUG_IRIX */
322 * Set up signal trampoline arguments.
324 f
->f_regs
[_R_A0
] = native_to_svr4_signo
[ksi
->ksi_signo
];/* signo */
325 f
->f_regs
[_R_A1
] = 0; /* NULL */
326 f
->f_regs
[_R_A2
] = (intptr_t)sp
; /* ucontext/sigcontext */
327 f
->f_regs
[_R_A3
] = (intptr_t)catcher
; /* signal handler address */
330 * When siginfo is selected, the higher bit of A0 is set
331 * This is how the signal trampoline is able to discover if A2
332 * points to a struct irix_sigcontext or struct irix_ucontext.
333 * Also, A1 points to struct siginfo instead of being NULL.
335 if (SIGACTION(p
, ksi
->ksi_signo
).sa_flags
& SA_SIGINFO
) {
336 f
->f_regs
[_R_A0
] |= 0x80000000;
337 f
->f_regs
[_R_A1
] = (intptr_t)sp
+
338 ((intptr_t)&sf
.isf_ctx
.iss
.iis
- (intptr_t)&sf
);
342 * Set up the new stack pointer
344 f
->f_regs
[_R_SP
] = (intptr_t)sp
;
346 printf("stack pointer at %p, A1 = %p\n", sp
, (void *)f
->f_regs
[_R_A1
]);
347 #endif /* DEBUG_IRIX */
350 * Set up the registers to jump to the signal trampoline
351 * on return to userland.
352 * see irix_sys_sigaction for details about how we get
353 * the signal trampoline address.
355 f
->f_regs
[_R_PC
] = (intptr_t)
356 (((struct irix_emuldata
*)(p
->p_emuldata
))->ied_sigtramp
[ksi
->ksi_signo
]);
359 * Remember that we're now on the signal stack.
362 l
->l_sigstk
.ss_flags
|= SS_ONSTACK
;
365 printf("returning from irix_sendsig()\n");
370 irix_set_sigcontext (struct irix_sigcontext
*scp
, const sigset_t
*mask
,
371 int code
, struct lwp
*l
)
377 KASSERT(mutex_owned(l
->l_proc
->p_lock
));
380 printf("irix_set_sigcontext()\n");
382 f
= (struct frame
*)l
->l_md
.md_regs
;
384 * Build stack frame for signal trampoline.
386 native_to_irix_sigset(mask
, &scp
->isc_sigset
);
387 for (i
= 1; i
< 32; i
++) { /* save gpr1 - gpr31 */
388 scp
->isc_regs
[i
] = f
->f_regs
[i
];
390 scp
->isc_regs
[0] = 0;
391 scp
->isc_fp_rounded_result
= 0;
392 scp
->isc_regmask
= -2;
393 scp
->isc_mdhi
= f
->f_regs
[_R_MULHI
];
394 scp
->isc_mdlo
= f
->f_regs
[_R_MULLO
];
395 scp
->isc_pc
= f
->f_regs
[_R_PC
];
396 scp
->isc_badvaddr
= f
->f_regs
[_R_BADVADDR
];
397 scp
->isc_cause
= f
->f_regs
[_R_CAUSE
];
400 * Save the floating-pointstate, if necessary, then copy it.
404 scp
->isc_ownedfp
= l
->l_md
.md_flags
& MDP_FPUSED
;
405 if (scp
->isc_ownedfp
) {
406 /* if FPU has current state, save it first */
409 memcpy(&scp
->isc_fpregs
, &pcb
->pcb_fpregs
,
410 sizeof(scp
->isc_fpregs
));
411 scp
->isc_fpc_csr
= pcb
->pcb_fpregs
.r_regs
[32];
414 memcpy(&scp
->isc_fpregs
, &pcb
->pcb_fpregs
, sizeof(scp
->isc_fpregs
));
420 (l
->l_sigstk
.ss_flags
& SS_ONSTACK
) ? IRIX_SS_ONSTACK
: 0;
426 irix_set_ucontext(struct irix_ucontext
*ucp
, const sigset_t
*mask
,
427 int code
, struct lwp
*l
)
432 KASSERT(mutex_owned(l
->l_proc
->p_lock
));
435 printf("irix_set_ucontext()\n");
438 f
= (struct frame
*)l
->l_md
.md_regs
;
440 * Save general purpose registers
442 native_to_irix_sigset(mask
, &ucp
->iuc_sigmask
);
443 memcpy(&ucp
->iuc_mcontext
.svr4___gregs
,
444 &f
->f_regs
, 32 * sizeof(mips_reg_t
));
445 /* Theses registers have different order on NetBSD and IRIX */
446 ucp
->iuc_mcontext
.svr4___gregs
[IRIX_CTX_MDLO
] = f
->f_regs
[_R_MULLO
];
447 ucp
->iuc_mcontext
.svr4___gregs
[IRIX_CTX_MDHI
] = f
->f_regs
[_R_MULHI
];
448 ucp
->iuc_mcontext
.svr4___gregs
[IRIX_CTX_EPC
] = f
->f_regs
[_R_PC
];
449 ucp
->iuc_mcontext
.svr4___gregs
[IRIX_CTX_CAUSE
] = f
->f_regs
[_R_CAUSE
];
452 * Save the floating-pointstate, if necessary, then copy it.
456 if (l
->l_md
.md_flags
& MDP_FPUSED
) {
457 /* if FPU has current state, save it first */
460 memcpy(&ucp
->iuc_mcontext
.svr4___fpregs
,
461 &pcb
->pcb_fpregs
, sizeof(ucp
->iuc_mcontext
.svr4___fpregs
));
462 ucp
->iuc_mcontext
.svr4___fpregs
.svr4___fp_csr
=
463 pcb
->pcb_fpregs
.r_regs
[32];
466 memcpy(&ucp
->iuc_mcontext
.svr4___fpregs
,
467 &pcb
->pcb_fpregs
, sizeof(ucp
->iuc_mcontext
.svr4___fpregs
));
472 ucp
->iuc_stack
.ss_sp
= l
->l_sigstk
.ss_sp
;
473 ucp
->iuc_stack
.ss_size
= l
->l_sigstk
.ss_size
;
475 if (l
->l_sigstk
.ss_flags
& SS_ONSTACK
)
476 ucp
->iuc_stack
.ss_flags
|= IRIX_SS_ONSTACK
;
478 ucp
->iuc_stack
.ss_flags
&= ~IRIX_SS_ONSTACK
;
480 if (l
->l_sigstk
.ss_flags
& SS_DISABLE
)
481 ucp
->iuc_stack
.ss_flags
|= IRIX_SS_DISABLE
;
483 ucp
->iuc_stack
.ss_flags
&= ~IRIX_SS_DISABLE
;
486 * Used fields in irix_ucontext: all
488 ucp
->iuc_flags
= IRIX_UC_ALL
;
494 irix_sys_sigreturn(struct lwp
*l
, const struct irix_sys_sigreturn_args
*uap
, register_t
*retval
)
497 syscallarg(struct irix_sigcontext *) scp;
498 syscallarg(struct irix_ucontext *) ucp;
499 syscallarg(int) signo;
502 struct irix_sigframe ksf
;
503 struct proc
*p
= l
->l_proc
;
507 printf("irix_sys_sigreturn()\n");
508 printf("scp = %p, ucp = %p, sig = %d\n",
509 (void *)SCARG(uap
, scp
), (void *)SCARG(uap
, ucp
),
511 #endif /* DEBUG_IRIX */
514 * The trampoline code hands us the context.
515 * It is unsafe to keep track of it ourselves, in the event that a
516 * program jumps out of a signal handler.
518 usf
= (void *)SCARG(uap
, scp
);
520 usf
= (void *)SCARG(uap
, ucp
);
522 if ((error
= copyin(usf
, &ksf
.isf_ctx
.iss
.iuc
,
523 sizeof(ksf
.isf_ctx
))) != 0)
526 mutex_enter(p
->p_lock
);
527 irix_get_ucontext(&ksf
.isf_ctx
.iss
.iuc
, l
);
528 mutex_exit(p
->p_lock
);
530 if ((error
= copyin(usf
, &ksf
.isf_ctx
.isc
,
531 sizeof(ksf
.isf_ctx
))) != 0)
534 mutex_enter(p
->p_lock
);
535 irix_get_sigcontext(&ksf
.isf_ctx
.isc
, l
);
536 mutex_exit(p
->p_lock
);
540 printf("irix_sys_sigreturn(): returning [PC=%p SP=%p SR=0x%08lx]\n",
541 (void *)((struct frame
*)(l
->l_md
.md_regs
))->f_regs
[_R_PC
],
542 (void *)((struct frame
*)(l
->l_md
.md_regs
))->f_regs
[_R_SP
],
543 ((struct frame
*)(l
->l_md
.md_regs
))->f_regs
[_R_SR
]);
550 irix_get_ucontext(struct irix_ucontext
*ucp
, struct lwp
*l
)
555 KASSERT(mutex_owned(l
->l_proc
->p_lock
));
557 /* Restore the register context. */
558 f
= (struct frame
*)l
->l_md
.md_regs
;
560 if (ucp
->iuc_flags
& IRIX_UC_CPU
) {
561 (void)memcpy(&f
->f_regs
, &ucp
->iuc_mcontext
.svr4___gregs
,
562 32 * sizeof(mips_reg_t
));
563 /* Theses registers have different order on NetBSD and IRIX */
564 f
->f_regs
[_R_MULLO
] =
565 ucp
->iuc_mcontext
.svr4___gregs
[IRIX_CTX_MDLO
];
566 f
->f_regs
[_R_MULHI
] =
567 ucp
->iuc_mcontext
.svr4___gregs
[IRIX_CTX_MDHI
];
569 ucp
->iuc_mcontext
.svr4___gregs
[IRIX_CTX_EPC
];
572 if (ucp
->iuc_flags
& IRIX_UC_MAU
) {
573 struct pcb
*pcb
= lwp_getpcb(l
);
575 /* Disable the FPU to fault in FP registers. */
576 f
->f_regs
[_R_SR
] &= ~MIPS_SR_COP_1_BIT
;
579 memcpy(&pcb
->pcb_fpregs
, &ucp
->iuc_mcontext
.svr4___fpregs
,
580 sizeof(pcb
->pcb_fpregs
));
581 pcb
->pcb_fpregs
.r_regs
[32] =
582 ucp
->iuc_mcontext
.svr4___fpregs
.svr4___fp_csr
;
584 memcpy(&pcb
->pcb_fpregs
, &ucp
->iuc_mcontext
.svr4___fpregs
,
585 sizeof(pcb
->pcb_fpregs
));
592 if (ucp
->iuc_flags
& IRIX_UC_STACK
) {
593 l
->l_sigstk
.ss_sp
= ucp
->iuc_stack
.ss_sp
;
594 l
->l_sigstk
.ss_size
= ucp
->iuc_stack
.ss_size
;
596 if (ucp
->iuc_stack
.ss_flags
& IRIX_SS_ONSTACK
)
597 l
->l_sigstk
.ss_flags
|= SS_ONSTACK
;
599 l
->l_sigstk
.ss_flags
&= ~SS_ONSTACK
;
601 if (ucp
->iuc_stack
.ss_flags
& IRIX_SS_DISABLE
)
602 l
->l_sigstk
.ss_flags
|= IRIX_SS_DISABLE
;
604 l
->l_sigstk
.ss_flags
&= ~IRIX_SS_DISABLE
;
608 * Restore signal mask
610 if (ucp
->iuc_flags
& IRIX_UC_SIGMASK
) {
611 /* Restore signal mask. */
612 irix_to_native_sigset(&ucp
->iuc_sigmask
, &mask
);
613 (void)sigprocmask1(l
, SIG_SETMASK
, &mask
, 0);
620 irix_get_sigcontext(struct irix_sigcontext
*scp
, struct lwp
*l
)
627 KASSERT(mutex_owned(l
->l_proc
->p_lock
));
629 /* Restore the register context. */
630 f
= (struct frame
*)l
->l_md
.md_regs
;
632 for (i
= 1; i
< 32; i
++) /* restore gpr1 to gpr31 */
633 f
->f_regs
[i
] = scp
->isc_regs
[i
];
634 f
->f_regs
[_R_MULLO
] = scp
->isc_mdlo
;
635 f
->f_regs
[_R_MULHI
] = scp
->isc_mdhi
;
636 f
->f_regs
[_R_PC
] = scp
->isc_pc
;
640 if (scp
->isc_ownedfp
) {
641 /* Disable the FPU to fault in FP registers. */
642 f
->f_regs
[_R_SR
] &= ~MIPS_SR_COP_1_BIT
;
645 memcpy(&pcb
->pcb_fpregs
, &scp
->isc_fpregs
,
646 sizeof(scp
->isc_fpregs
));
647 pcb
->pcb_fpregs
.r_regs
[32] = scp
->isc_fpc_csr
;
650 memcpy(&pcb
->pcb_fpregs
, &scp
->isc_fpregs
, sizeof(pcb
->pcb_fpregs
));
653 /* Restore signal stack. */
654 if (scp
->isc_ssflags
& IRIX_SS_ONSTACK
)
655 l
->l_sigstk
.ss_flags
|= SS_ONSTACK
;
657 l
->l_sigstk
.ss_flags
&= ~SS_ONSTACK
;
660 /* Restore signal mask. */
661 irix_to_native_sigset(&scp
->isc_sigset
, &mask
);
662 (void)sigprocmask1(l
, SIG_SETMASK
, &mask
, 0);
669 irix_sys_sginap(struct lwp
*l
, const struct irix_sys_sginap_args
*uap
, register_t
*retval
)
672 syscallarg(long) ticks;
674 int rticks
= SCARG(uap
, ticks
);
675 struct timeval tvb
, tve
, tvd
;
682 if ((tsleep(&dontcare
, PZERO
|PCATCH
, 0, rticks
) != 0) &&
685 timersub(&tve
, &tvb
, &tvd
);
686 delta
= ((tvd
.tv_sec
* 1000000) + tvd
.tv_usec
); /* XXX */
687 *retval
= (register_t
)(rticks
- (delta
/ tick
));
694 * XXX Untested. Expect bugs and security problems here
697 irix_sys_getcontext(struct lwp
*l
, const struct irix_sys_getcontext_args
*uap
, register_t
*retval
)
700 syscallarg(struct irix_ucontext *) ucp;
702 struct proc
*p
= l
->l_proc
;
704 struct irix_ucontext kucp
;
707 f
= (struct frame
*)l
->l_md
.md_regs
;
709 kucp
.iuc_flags
= IRIX_UC_ALL
;
710 kucp
.iuc_link
= NULL
; /* XXX */
712 mutex_enter(p
->p_lock
);
713 native_to_irix_sigset(&l
->l_sigmask
, &kucp
.iuc_sigmask
);
714 kucp
.iuc_stack
.ss_sp
= l
->l_sigstk
.ss_sp
;
715 kucp
.iuc_stack
.ss_size
= l
->l_sigstk
.ss_size
;
716 kucp
.iuc_stack
.ss_flags
= 0;
717 if (l
->l_sigstk
.ss_flags
& SS_ONSTACK
)
718 kucp
.iuc_stack
.ss_flags
&= IRIX_SS_ONSTACK
;
719 if (l
->l_sigstk
.ss_flags
& SS_DISABLE
)
720 kucp
.iuc_stack
.ss_flags
&= IRIX_SS_DISABLE
;
721 mutex_exit(p
->p_lock
);
723 for (i
= 0; i
< 36; i
++) /* Is order correct? */
724 kucp
.iuc_mcontext
.svr4___gregs
[i
] = f
->f_regs
[i
];
725 for (i
= 0; i
< 32; i
++)
726 kucp
.iuc_mcontext
.svr4___fpregs
.svr4___fp_r
.svr4___fp_regs
[i
]
727 = 0; /* XXX where are FP registers? */
728 for (i
= 0; i
< 47; i
++)
729 kucp
.iuc_filler
[i
] = 0; /* XXX */
730 kucp
.iuc_triggersave
= 0; /* XXX */
732 error
= copyout(&kucp
, SCARG(uap
, ucp
), sizeof(kucp
));
738 * XXX Untested. Expect bugs and security problems here
741 irix_sys_setcontext(struct lwp
*l
, const struct irix_sys_setcontext_args
*uap
, register_t
*retval
)
744 syscallarg(struct irix_ucontext *) ucp;
746 struct proc
*p
= l
->l_proc
;
748 struct irix_ucontext kucp
;
751 error
= copyin(SCARG(uap
, ucp
), &kucp
, sizeof(kucp
));
755 f
= (struct frame
*)l
->l_md
.md_regs
;
757 mutex_enter(p
->p_lock
);
759 if (kucp
.iuc_flags
& IRIX_UC_SIGMASK
)
760 irix_to_native_sigset(&kucp
.iuc_sigmask
,
763 if (kucp
.iuc_flags
& IRIX_UC_STACK
) {
764 l
->l_sigstk
.ss_sp
= kucp
.iuc_stack
.ss_sp
;
765 l
->l_sigstk
.ss_size
=
766 (unsigned long)kucp
.iuc_stack
.ss_sp
;
767 l
->l_sigstk
.ss_flags
= 0;
768 if (kucp
.iuc_stack
.ss_flags
& IRIX_SS_ONSTACK
)
769 l
->l_sigstk
.ss_flags
&= SS_ONSTACK
;
770 if (kucp
.iuc_stack
.ss_flags
& IRIX_SS_DISABLE
)
771 l
->l_sigstk
.ss_flags
&= SS_DISABLE
;
774 mutex_exit(p
->p_lock
);
776 if (kucp
.iuc_flags
& IRIX_UC_CPU
)
777 for (i
= 0; i
< 36; i
++) /* Is register order right? */
778 f
->f_regs
[i
] = kucp
.iuc_mcontext
.svr4___gregs
[i
];
780 if (kucp
.iuc_flags
& IRIX_UC_MAU
) { /* XXX */
782 printf("irix_sys_setcontext(): IRIX_UC_MAU requested\n");
792 * The following code is from svr4_sys_waitsys(), with a few lines added
793 * for supporting the rusage argument which is present in the IRIX version
794 * and not in the SVR4 version.
795 * Both version could be merged by creating a svr4_sys_waitsys1() with the
796 * rusage argument, and by calling it with NULL from svr4_sys_waitsys().
797 * irix_wait_siginfo is here because 1) svr4_setinfo is static and cannot be
798 * used here and 2) because struct irix_irix5_siginfo is quite different
799 * from svr4_siginfo. In order to merge, we need to include irix_signal.h
800 * from svr4_misc.c, or push the irix_irix5_siginfo into svr4_siginfo.h
803 irix_sys_waitsys(struct lwp
*l
, const struct irix_sys_waitsys_args
*uap
,
807 syscallarg(int) type;
809 syscallarg(struct irix_irix5_siginfo *) info;
810 syscallarg(int) options;
811 syscallarg(struct rusage *) ru;
813 struct proc
*parent
= l
->l_proc
;
814 int error
, status
, options
, pid
;
817 switch (SCARG(uap
, type
)) {
819 pid
= SCARG(uap
, pid
);
823 pid
= -parent
->p_pgid
;
835 printf("waitsys(%d, %d, %p, %x, %p)\n",
836 SCARG(uap
, type
), pid
,
837 SCARG(uap
, info
), SCARG(uap
, options
), SCARG(uap
, ru
));
840 /* Translate options */
841 options
= WOPTSCHECKED
;
842 if (SCARG(uap
, options
) & SVR4_WNOWAIT
)
844 if (SCARG(uap
, options
) & SVR4_WNOHANG
)
846 if ((SCARG(uap
, options
) & (SVR4_WEXITED
|SVR4_WTRAPPED
)) == 0)
847 options
|= WNOZOMBIE
;
848 if (SCARG(uap
, options
) & (SVR4_WSTOPPED
|SVR4_WCONTINUED
))
849 options
|= WUNTRACED
;
851 error
= do_sys_wait(&pid
, &status
, options
, &ru
);
855 if (SCARG(uap
, ru
)) {
856 error
= copyout(&ru
, SCARG(uap
, ru
), sizeof(ru
));
861 return irix_wait_siginfo(pid
, &ru
, status
, SCARG(uap
,info
));
865 irix_sys_sigprocmask(struct lwp
*l
, const struct irix_sys_sigprocmask_args
*uap
, register_t
*retval
)
869 syscallarg(const irix_sigset_t *) set;
870 syscallarg(irix_sigset_t *) oset;
872 struct proc
*p
= l
->l_proc
;
873 struct svr4_sys_sigprocmask_args cup
;
876 irix_sigset_t niss
, oiss
;
878 if (SCARG(uap
, how
) != IRIX_SIG_SETMASK32
) {
879 SCARG(&cup
, how
) = SCARG(uap
, how
);
880 SCARG(&cup
, set
) = (const svr4_sigset_t
*)SCARG(uap
, set
);
881 SCARG(&cup
, oset
) = (svr4_sigset_t
*)SCARG(uap
, oset
);
882 return svr4_sys_sigprocmask(l
, &cup
, retval
);
885 if ((error
= copyin(SCARG(uap
, set
), &niss
, sizeof(niss
))) != 0)
888 /* We must preserve the high bits of the irix sigmask, so mustget them */
889 native_to_irix_sigset(&l
->l_sigmask
, &oiss
);
890 /* The irix bitmask is 128 bits, I think we only have the bottom 32 */
891 niss
.bits
[1] = oiss
.bits
[1];
892 niss
.bits
[2] = oiss
.bits
[2];
893 niss
.bits
[3] = oiss
.bits
[3];
894 /* We now need the corresponding netbsd mask */
895 irix_to_native_sigset(&niss
, &nbss
);
897 mutex_enter(p
->p_lock
);
898 error
= sigprocmask1(l
, SIG_SETMASK
, &nbss
, &obss
);
899 mutex_exit(p
->p_lock
);
901 if (error
!= 0 || SCARG(&cup
, oset
) == NULL
)
904 native_to_irix_sigset(&obss
, &oiss
);
906 /* XXX: should this copyout only be 4 bytes ? */
907 return copyout(&oiss
, SCARG(&cup
, oset
), sizeof(oiss
));
911 irix_sys_sigaction(struct lwp
*l
, const struct irix_sys_sigaction_args
*uap
, register_t
*retval
)
914 syscallarg(int) signum;
915 syscallarg(const struct svr4_sigaction *) nsa;
916 syscallarg(struct svr4_sigaction *) osa;
917 syscallarg(void *) sigtramp;
919 struct proc
*p
= l
->l_proc
;
921 struct svr4_sys_sigaction_args cup
;
922 struct irix_emuldata
*ied
;
928 * On IRIX, the sigaction() system call has a fourth argument, which
929 * is a pointer to the signal trampoline code. The kernel does not
930 * seems to provide a signal trampoline, the user process has to
931 * embed it. Of course, the sigaction() stub in libc only has three
932 * argument. The fourth argument to the system call is filled by the
935 * The signal trampoline does the following job:
936 * - holds extra bytes on the stack (48 on IRIX 6, 24 on IRIX 5)
937 * for the signal frame. See struct irix_sigframe in irix_signal.h
938 * for the details of the signal frame fields for IRIX 6.
939 * - checks if the higher bit of a0 is set (the kernel sets this
940 * when SA_SIGINFO is set)
941 * - if so, stores in a2 sf.isf_ucp, and NULL in sf.isf_scp
942 * SA_SIGACTION is set, we are using a struct irix_ucontext in a2
943 * - if not, stores a2 in sf.isf_scp. Here SA_SIGACTION is clear
944 * and we are using a struct irix_sigcontext in a2.
945 * - finds the address of errno, and stores it in sf.isf_uep (IRIX 6
946 * only). This is done by looking up the Global Offset Table and
947 * assuming that the errnoaddr symbol is at a fixed offset from
948 * the signal trampoline.
949 * - invoke the signal handler
950 * - sets errno using sf.isf_uep and sf.isf_errno (IRIX 6 only)
951 * - calls sigreturn(sf.isf_scp, sf.isf_ucp, sf.isf_signo) on IRIX 6
952 * and sigreturn(sf.isf_scp, sf.isf_ucp) on IRIX 5. Note that if
953 * SA_SIGINFO was set, then the higher bit of sf.isf_signo is
956 * The signal trampoline is hence saved in the p_emuldata field
957 * of struct proc, in an array (one element for each signal)
959 signum
= SCARG(uap
, signum
);
960 if (signum
< 0 || signum
>= SVR4_NSIG
)
962 signum
= svr4_to_native_signo
[signum
];
963 ied
= (struct irix_emuldata
*)(p
->p_emuldata
);
966 sigtramp
= ied
->ied_sigtramp
[signum
];
968 if (sigtramp
!= NULL
&& sigtramp
!= SCARG(uap
, sigtramp
))
969 printf("Warning: sigtramp changed from %p to %p for sig. %d\n",
970 sigtramp
, SCARG(uap
, sigtramp
), signum
);
973 ied
->ied_sigtramp
[signum
] = SCARG(uap
, sigtramp
);
975 SCARG(&cup
, signum
) = signum
;
976 SCARG(&cup
, nsa
) = SCARG(uap
, nsa
);
977 SCARG(&cup
, osa
) = SCARG(uap
, osa
);
979 return svr4_sys_sigaction(l
, &cup
, retval
);