1 /*	$NetBSD: svr4_machdep.c,v 1.55 2011/03/04 22:25:29 joerg Exp $	 */
2 
3 /*-
4  * Copyright (c) 1994 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Christos Zoulas.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
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.
18  *
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.
30  */
31 
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: svr4_machdep.c,v 1.55 2011/03/04 22:25:29 joerg Exp $");
34 
35 #ifdef _KERNEL_OPT
36 #include "opt_ddb.h"
37 #endif
38 
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/namei.h>
42 #include <sys/proc.h>
43 #include <sys/exec.h>
44 #include <sys/filedesc.h>
45 #include <sys/ioctl.h>
46 #include <sys/kernel.h>
47 #include <sys/signal.h>
48 #include <sys/signalvar.h>
49 #include <sys/malloc.h>
50 #include <sys/mount.h>
51 #include <sys/syscallargs.h>
52 #include <sys/exec_elf.h>
53 #include <sys/types.h>
54 
55 #include <compat/svr4/svr4_types.h>
56 #include <compat/svr4/svr4_lwp.h>
57 #include <compat/svr4/svr4_ucontext.h>
58 #include <compat/svr4/svr4_syscallargs.h>
59 #include <compat/svr4/svr4_util.h>
60 #include <compat/svr4/svr4_exec.h>
61 
62 #include <machine/cpu.h>
63 #include <machine/psl.h>
64 #include <machine/reg.h>
65 #include <machine/frame.h>
66 #include <machine/trap.h>
67 #include <machine/vmparam.h>
68 #include <machine/svr4_machdep.h>
69 
70 static void svr4_getsiginfo(union svr4_siginfo *, int, u_long, void *);
71 
72 void
svr4_setregs(struct lwp * l,struct exec_package * epp,vaddr_t stack)73 svr4_setregs(struct lwp *l, struct exec_package *epp, vaddr_t stack)
74 {
75 	register struct trapframe64 *tf = l->l_md.md_tf;
76 
77 	setregs(l, epp, stack);
78 
79 	/* This should be the exit function, not p->p_psstrp. */
80 	tf->tf_global[1] = (vaddr_t)0;
81 }
82 
83 #ifdef DEBUG
84 #include <sparc64/sparc64/sigdebug.h>
85 #endif
86 
87 #ifdef DEBUG_SVR4
88 static void svr4_printmcontext(const char *, struct svr4_mcontext *);
89 
90 static void
svr4_printmcontext(const char * fun,struct svr4_mcontext * mc)91 svr4_printmcontext(const char *fun, struct svr4_mcontext *mc)
92 {
93 	svr4_greg_t *r = mc->greg;
94 
95 	printf("%s at %p\n", fun, mc);
96 
97 	printf("Regs: ");
98 #ifdef __arch64__
99 	printf("CCR = 0x%lx ", r[SVR4_SPARC_CCR]);
100 #else
101 	printf("PSR = 0x%lx ", r[SVR4_SPARC_PSR]);
102 #endif
103 	printf("PC = 0x%lx ",  r[SVR4_SPARC_PC]);
104 	printf("nPC = 0x%lx ", r[SVR4_SPARC_nPC]);
105 	printf("Y = 0x%lx ",   r[SVR4_SPARC_Y]);
106 	printf("G1 = 0x%lx ",  r[SVR4_SPARC_G1]);
107 	printf("G2 = 0x%lx ",  r[SVR4_SPARC_G2]);
108 	printf("G3 = 0x%lx ",  r[SVR4_SPARC_G3]);
109 	printf("G4 = 0x%lx ",  r[SVR4_SPARC_G4]);
110 	printf("G5 = 0x%lx ",  r[SVR4_SPARC_G5]);
111 	printf("G6 = 0x%lx ",  r[SVR4_SPARC_G6]);
112 	printf("G7 = 0x%lx ",  r[SVR4_SPARC_G7]);
113 	printf("O0 = 0x%lx ",  r[SVR4_SPARC_O0]);
114 	printf("O1 = 0x%lx ",  r[SVR4_SPARC_O1]);
115 	printf("O2 = 0x%lx ",  r[SVR4_SPARC_O2]);
116 	printf("O3 = 0x%lx ",  r[SVR4_SPARC_O3]);
117 	printf("O4 = 0x%lx ",  r[SVR4_SPARC_O4]);
118 	printf("O5 = 0x%lx ",  r[SVR4_SPARC_O5]);
119 	printf("O6 = 0x%lx ",  r[SVR4_SPARC_O6]);
120 	printf("O7 = 0x%lx ",  r[SVR4_SPARC_O7]);
121 #ifdef __arch64__
122 	printf("ASI = 0x%lx ",  r[SVR4_SPARC_ASI]);
123 	printf("FPRS = 0x%lx ",  r[SVR4_SPARC_FPRS]);
124 #endif
125 	printf("\n");
126 }
127 #endif
128 
129 void *
svr4_getmcontext(struct lwp * l,struct svr4_mcontext * mc,u_long * flags)130 svr4_getmcontext(struct lwp *l, struct svr4_mcontext *mc, u_long *flags)
131 {
132 	struct trapframe64 *tf = (struct trapframe64 *)l->l_md.md_tf;
133 	svr4_greg_t *r = mc->greg;
134 #ifdef FPU_CONTEXT
135 	svr4_fregset_t *f = &mc->freg;
136 	struct fpstate *fps = l->l_md.md_fpstate;
137 #endif
138 
139 	write_user_windows();
140 	if (rwindow_save(l)) {
141 #ifdef DEBUG
142 		printf("svr4_getcontext: rwindow_save(%p) failed, sending SIGILL\n", l->l_proc);
143 #ifdef DDB
144 		Debugger();
145 #endif
146 #endif
147 		mutex_enter(l->l_proc->p_lock);
148 		sigexit(l, SIGILL);
149 	}
150 
151 	/*
152 	 * Get the general purpose registers
153 	 */
154 #ifdef __arch64__
155 	r[SVR4_SPARC_CCR] = (tf->tf_tstate & TSTATE_CCR) >> TSTATE_CCR_SHIFT;
156 #else
157 	r[SVR4_SPARC_PSR] = TSTATECCR_TO_PSR(tf->tf_tstate);
158 #endif
159 	r[SVR4_SPARC_PC] = tf->tf_pc;
160 	r[SVR4_SPARC_nPC] = tf->tf_npc;
161 	r[SVR4_SPARC_Y] = tf->tf_y;
162 	r[SVR4_SPARC_G1] = tf->tf_global[1];
163 	r[SVR4_SPARC_G2] = tf->tf_global[2];
164 	r[SVR4_SPARC_G3] = tf->tf_global[3];
165 	r[SVR4_SPARC_G4] = tf->tf_global[4];
166 	r[SVR4_SPARC_G5] = tf->tf_global[5];
167 	r[SVR4_SPARC_G6] = tf->tf_global[6];
168 	r[SVR4_SPARC_G7] = tf->tf_global[7];
169 	r[SVR4_SPARC_O0] = tf->tf_out[0];
170 	r[SVR4_SPARC_O1] = tf->tf_out[1];
171 	r[SVR4_SPARC_O2] = tf->tf_out[2];
172 	r[SVR4_SPARC_O3] = tf->tf_out[3];
173 	r[SVR4_SPARC_O4] = tf->tf_out[4];
174 	r[SVR4_SPARC_O5] = tf->tf_out[5];
175 	r[SVR4_SPARC_O6] = tf->tf_out[6];
176 	r[SVR4_SPARC_O7] = tf->tf_out[7];
177 #ifdef __arch64__
178 	r[SVR4_SPARC_ASI] = (tf->tf_tstate & TSTATE_ASI) >> TSTATE_ASI_SHIFT;
179 #endif
180 
181 	*flags |= SVR4_UC_CPU;
182 
183 #ifdef FPU_CONTEXT
184 	/*
185 	 * Get the floating point registers
186 	 */
187 	memcpy(f->fpu_regs, fps->fs_regs, sizeof(f->fpu_regs));
188 	f->fp_nqsize = sizeof(struct fp_qentry);
189 	f->fp_nqel = fps->fs_qsize;
190 	f->fp_fsr = fps->fs_fsr;
191 	if (f->fp_q != NULL) {
192 		size_t sz = f->fp_nqel * f->fp_nqsize;
193 		if (sz > sizeof(fps->fs_queue)) {
194 #ifdef DIAGNOSTIC
195 			printf("getcontext: fp_queue too large\n");
196 #endif
197 			return;
198 		}
199 		if (copyout(fps->fs_queue, f->fp_q, sz) != 0) {
200 #ifdef DIAGNOSTIC
201 			printf("getcontext: copy of fp_queue failed %d\n",
202 			    error);
203 #endif
204 			return;
205 		}
206 	}
207 	f->fp_busy = 0;	/* XXX: How do we determine that? */
208 	*flags |= SVR4_UC_FPU;
209 #endif
210 
211 
212 #ifdef DEBUG_SVR4
213 	svr4_printmcontext("getmcontext", mc);
214 #endif
215 	return (void *)(u_long)tf->tf_out[6];
216 }
217 
218 
219 /*
220  * Set to mcontext specified.
221  * Return to previous pc and psl as specified by
222  * context left by sendsig. Check carefully to
223  * make sure that the user has not modified the
224  * psl to gain improper privileges or to cause
225  * a machine fault.
226  * This is almost like sigreturn() and it shows.
227  */
228 int
svr4_setmcontext(struct lwp * l,struct svr4_mcontext * mc,u_long flags)229 svr4_setmcontext(struct lwp *l, struct svr4_mcontext *mc, u_long flags)
230 {
231 	register struct trapframe64 *tf;
232 	svr4_greg_t *r = mc->greg;
233 #ifdef FPU_CONTEXT
234 	svr4_fregset_t *f = &mc->freg;
235 	struct fpstate64 *fps = l->l_md.md_fpstate;
236 #endif
237 
238 #ifdef DEBUG_SVR4
239 	svr4_printmcontext("setmcontext", uc);
240 #endif
241 
242 	write_user_windows();
243 	if (rwindow_save(l)) {
244 #ifdef DEBUG
245 		printf("svr4_setcontext: rwindow_save(%p) failed, sending SIGILL\n", l->l_proc);
246 #ifdef DDB
247 		Debugger();
248 #endif
249 #endif
250 		mutex_enter(l->l_proc->p_lock);
251 		sigexit(l, SIGILL);
252 	}
253 
254 #ifdef DEBUG
255 	if (sigdebug & SDB_FOLLOW)
256 		printf("svr4_setmcontext: %s[%d], svr4_mcontext %p\n",
257 		    l->l_proc->p_comm, l->l_proc->p_pid, mc);
258 #endif
259 
260 	if (flags & SVR4_UC_CPU) {
261 		/* Restore register context. */
262 		tf = (struct trapframe64 *)l->l_md.md_tf;
263 
264 		/*
265 		 * Only the icc bits in the psr are used, so it need not be
266 		 * verified.  pc and npc must be multiples of 4.  This is all
267 		 * that is required; if it holds, just do it.
268 		 */
269 		if (((r[SVR4_SPARC_PC] | r[SVR4_SPARC_nPC]) & 3) != 0) {
270 			printf("pc or npc are not multiples of 4!\n");
271 			return EINVAL;
272 		}
273 
274 #ifdef __arch64__
275 		/* take only tstate ASI and CCR fields */
276 		tf->tf_tstate = (tf->tf_tstate & ~(TSTATE_CCR | TSTATE_ASI)) |
277 		    ((r[SVR4_SPARC_CCR] << TSTATE_CCR_SHIFT) & TSTATE_CCR) |
278 		    ((r[SVR4_SPARC_ASI] << TSTATE_ASI_SHIFT) & TSTATE_ASI);
279 #else
280 		/* take only tstate CCR field */
281 		tf->tf_tstate = (tf->tf_tstate & ~TSTATE_CCR) |
282 		    PSRCC_TO_TSTATE(r[SVR4_SPARC_PSR]);
283 #endif
284 		tf->tf_pc = r[SVR4_SPARC_PC];
285 		tf->tf_npc = r[SVR4_SPARC_nPC];
286 		tf->tf_y = r[SVR4_SPARC_Y];
287 
288 		/* Restore everything */
289 		tf->tf_global[1] = r[SVR4_SPARC_G1];
290 		tf->tf_global[2] = r[SVR4_SPARC_G2];
291 		tf->tf_global[3] = r[SVR4_SPARC_G3];
292 		tf->tf_global[4] = r[SVR4_SPARC_G4];
293 		tf->tf_global[5] = r[SVR4_SPARC_G5];
294 		tf->tf_global[6] = r[SVR4_SPARC_G6];
295 		tf->tf_global[7] = r[SVR4_SPARC_G7];
296 
297 		tf->tf_out[0] = r[SVR4_SPARC_O0];
298 		tf->tf_out[1] = r[SVR4_SPARC_O1];
299 		tf->tf_out[2] = r[SVR4_SPARC_O2];
300 		tf->tf_out[3] = r[SVR4_SPARC_O3];
301 		tf->tf_out[4] = r[SVR4_SPARC_O4];
302 		tf->tf_out[5] = r[SVR4_SPARC_O5];
303 		tf->tf_out[6] = r[SVR4_SPARC_O6];
304 		tf->tf_out[7] = r[SVR4_SPARC_O7];
305 
306 		/* SVR4_SPARC_ASI restored above */
307 	}
308 
309 
310 #ifdef FPU_CONTEXT
311 	if (flags & SVR4_UC_FPU) {
312 		/*
313 		 * Set the floating point registers
314 		 */
315 		int error;
316 		size_t sz = f->fp_nqel * f->fp_nqsize;
317 		if (sz > sizeof(fps->fs_queue)) {
318 #ifdef DIAGNOSTIC
319 			printf("setmcontext: fp_queue too large\n");
320 #endif
321 			return EINVAL;
322 		}
323 		/* Note: only copy as much FP registers as in the mcontext. */
324 		memcpy(fps->fs_regs, f->fpu_regs, sizeof(f->fpu_regs));
325 		fps->fs_qsize = f->fp_nqel;
326 		fps->fs_fsr = f->fp_fsr;
327 		if (f->fp_q != NULL) {
328 			if ((error = copyin(f->fp_q, fps->fs_queue,
329 					    f->fp_nqel * f->fp_nqsize)) != 0) {
330 #ifdef DIAGNOSTIC
331 				printf("setmcontext: fp_queue copy failed\n");
332 #endif
333 				return error;
334 			}
335 		}
336 	}
337 #endif
338 
339 	return 0;
340 }
341 
342 /*
343  * map the trap code into the svr4 siginfo as best we can
344  */
345 static void
svr4_getsiginfo(union svr4_siginfo * si,int sig,u_long code,void * addr)346 svr4_getsiginfo(union svr4_siginfo *si, int sig, u_long code, void *addr)
347 {
348 	si->si_signo = native_to_svr4_signo[sig];
349 	si->si_errno = 0;
350 	si->si_addr  = addr;
351 	/*
352 	 * we can do this direct map as they are the same as all sparc
353 	 * architectures.
354 	 */
355 	si->si_trap = code;
356 	switch (code) {
357 	case T_POR:
358 	case T_WDR:
359 	case T_XIR:
360 	case T_SIR:
361 	case T_RED_EXCEPTION:
362 		si->si_code = 0;
363 		break;
364 
365 	case T_TEXTFAULT:
366 		si->si_code = SVR4_BUS_ADRALN;
367 		break;
368 
369 	case T_ILLINST:
370 		si->si_code = SVR4_ILL_ILLOPC;
371 		break;
372 
373 	case T_PRIVINST:
374 		si->si_code = SVR4_ILL_PRVOPC;
375 		break;
376 
377 	case T_FPDISABLED:
378 		si->si_code = SVR4_FPE_FLTINV;
379 		break;
380 
381 	case T_ALIGN:
382 		si->si_code = SVR4_BUS_ADRALN;
383 		break;
384 
385 	case T_FP_IEEE_754:
386 	case T_FP_OTHER:
387 		si->si_code = SVR4_FPE_FLTINV;
388 		break;
389 
390 	case T_DATAFAULT:
391 		si->si_code = SVR4_BUS_ADRALN;
392 		break;
393 
394 	case T_TAGOF:
395 		si->si_code = SVR4_EMT_TAGOVF;
396 		break;
397 
398 	case T_IDIV0:
399 		si->si_code = SVR4_FPE_INTDIV;
400 		break;
401 
402 	case T_INTOF:
403 		si->si_code = SVR4_FPE_INTOVF;
404 		break;
405 
406 	case T_BREAKPOINT:
407 		si->si_code = SVR4_TRAP_BRKPT;
408 		break;
409 
410 	/*
411 	 * XXX - hardware traps with unknown code
412 	 */
413 	case T_L1INT:
414 	case T_L2INT:
415 	case T_L3INT:
416 	case T_L4INT:
417 	case T_L5INT:
418 	case T_L6INT:
419 	case T_L7INT:
420 	case T_L8INT:
421 	case T_L9INT:
422 	case T_L10INT:
423 	case T_L11INT:
424 	case T_L12INT:
425 	case T_L13INT:
426 	case T_L14INT:
427 	case T_L15INT:
428 		si->si_code = 0;
429 		break;
430 
431 	/*
432 	 * XXX - software traps with unknown code
433 	 */
434 	case T_SUN_SYSCALL:
435 	case T_FLUSHWIN:
436 	case T_CLEANWIN:
437 	case T_RANGECHECK:
438 	case T_FIXALIGN:
439 	case T_SVR4_SYSCALL:
440 	case T_BSD_SYSCALL:
441 	case T_KGDB_EXEC:
442 		si->si_code = 0;
443 		break;
444 
445 	default:
446 		si->si_code = 0;
447 #ifdef notyet
448 		/*
449 		 * XXX: in trap.c, code gets passed the address
450 		 * of the fault! not the trap code on SEGV!
451 		 */
452 #ifdef DIAGNOSTIC
453 		printf("sig %d code %ld\n", sig, code);
454 		panic("svr4_getsiginfo");
455 #endif
456 #endif
457 		break;
458 	}
459 }
460 
461 /*
462  * Send an interrupt to process.
463  *
464  * Stack is set up to allow sigcode stored
465  * in u. to call routine. After the handler is
466  * done svr4 will call setcontext for us
467  * with the user context we just set up, and we
468  * will return to the user pc, psl.
469  */
470 #ifdef __arch64__
471 #define STACK_OFFSET	BIAS
472 #define CPOUTREG(l,v)	copyout(&(v), (l), sizeof(v))
473 #undef CCFSZ
474 #define CCFSZ	CC64FSZ
475 #define rwindow	rwindow64
476 #else
477 #define STACK_OFFSET	0
478 #define CPOUTREG(l,v)	copyout(&(v), (l), sizeof(v))
479 #define rwindow	rwindow32
480 #endif
481 
482 void
svr4_sendsig(const ksiginfo_t * ksi,const sigset_t * mask)483 svr4_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
484 {
485 	int sig = ksi->ksi_signo;
486 	register struct lwp *l = curlwp;
487 	struct proc *p = l->l_proc;
488 	register struct trapframe64 *tf;
489 	struct svr4_sigframe *fp, frame;
490 	int onstack, error;
491 	vaddr_t oldsp, newsp, addr;
492 	sig_t catcher = SIGACTION(p, sig).sa_handler;
493 
494 	tf = (struct trapframe64 *)l->l_md.md_tf;
495 	oldsp = tf->tf_out[6] + STACK_OFFSET;
496 
497 	/* Do we need to jump onto the signal stack? */
498 	onstack =
499 	    (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
500 	    (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
501 
502 	/*
503 	 * Allocate space for the signal handler context.
504 	 */
505 	if (onstack)
506 		fp = (struct svr4_sigframe *)((char *)l->l_sigstk.ss_sp +
507 						l->l_sigstk.ss_size);
508 	else
509 		fp = (struct svr4_sigframe *)oldsp;
510 	fp = (struct svr4_sigframe *) ((long) (fp - 1) & ~0x0f);
511 
512 #ifdef DEBUG
513 	sigpid = p->p_pid;
514 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) {
515 		printf("svr4_sendsig: %s[%d] sig %d newusp %p scp %p oldsp %p\n",
516 		    p->p_comm, p->p_pid, sig, fp, &fp->sf_uc, (void *)(u_long)oldsp);
517 #ifdef DDB
518 		if (sigdebug & SDB_DDB) Debugger();
519 #endif
520 	}
521 #endif
522 	/*
523 	 * Build the argument list for the signal handler.
524 	 */
525 	svr4_getsiginfo(&frame.sf_si, sig, ksi->ksi_trap,
526 	    (void *)(u_long)tf->tf_pc);
527 
528 	/* Build stack frame for signal trampoline. */
529 	frame.sf_signum = frame.sf_si.si_signo;
530 	frame.sf_sip = &fp->sf_si;
531 	frame.sf_ucp = &fp->sf_uc;
532 	frame.sf_handler = catcher;
533 
534 	DPRINTF(("svr4_sendsig signum=%d si = %p uc = %p handler = %p\n",
535 	         frame.sf_signum, frame.sf_sip,
536 		 frame.sf_ucp, frame.sf_handler));
537 	/*
538 	 * Modify the signal context to be used by sigreturn.
539 	 */
540 	sendsig_reset(l, sig);
541 	mutex_exit(p->p_lock);
542 	svr4_getcontext(l, &frame.sf_uc);
543 	frame.sf_uc.uc_mcontext.greg[SVR4_SPARC_SP] = (long)tf->tf_out[6];
544 
545 	newsp = (u_long)fp - sizeof(struct rwindow);
546 	write_user_windows();
547 
548 #ifdef DEBUG
549 	if ((sigdebug & SDB_KSTACK))
550 	    printf("svr4_sendsig: saving sf to %p, setting stack pointer %p to %p\n",
551 		   fp, &(((struct rwindow *)newsp)->rw_in[6]), (void *)(u_long)oldsp);
552 #endif
553 	error = (rwindow_save(l) || copyout(&frame, fp, sizeof(frame)) != 0 ||
554 	    CPOUTREG(&((struct rwindow *)newsp)->rw_in[6], oldsp));
555 	mutex_enter(p->p_lock);
556 
557 	if (error) {
558 		/*
559 		 * Process has trashed its stack; give it an illegal
560 		 * instruction to halt it in its tracks.
561 		 */
562 #ifdef DEBUG
563 		mutex_exit(p->p_lock);
564 		if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
565 			printf("svr4_sendsig: window save or copyout error\n");
566 		printf("svr4_sendsig: stack was trashed trying to send sig %d, sending SIGILL\n", sig);
567 #ifdef DDB
568 		Debugger();
569 #endif
570 		mutex_enter(p->p_lock);
571 #endif
572 		sigexit(l, SIGILL);
573 		/* NOTREACHED */
574 	}
575 
576 #ifdef DEBUG
577 	if (sigdebug & SDB_FOLLOW) {
578 		printf("svr4_sendsig: %s[%d] sig %d scp %p\n",
579 		       p->p_comm, p->p_pid, sig, &fp->sf_uc);
580 	}
581 #endif
582 	/*
583 	 * Build context to run handler in.
584 	 */
585 	addr = (vaddr_t)p->p_sigctx.ps_sigcode;
586 	tf->tf_pc = addr;
587 	tf->tf_npc = addr + 4;
588 	tf->tf_global[1] = (vaddr_t)catcher;
589 	tf->tf_out[6] = newsp;
590 
591 	/* Remember that we're now on the signal stack. */
592 	if (onstack)
593 		l->l_sigstk.ss_flags |= SS_ONSTACK;
594 #ifdef DEBUG
595 	if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) {
596 		mutex_exit(p->p_lock);
597 		printf("svr4_sendsig: about to return to catcher %p thru %p\n",
598 		       catcher, (void *)(u_long)addr);
599 #ifdef DDB
600 		if (sigdebug & SDB_DDB) Debugger();
601 #endif
602 		mutex_enter(p->p_lock);
603 	}
604 #endif
605 }
606 
607 
608 #define	ADVANCE (n = tf->tf_npc, tf->tf_pc = n, tf->tf_npc = n + 4)
609 int
svr4_trap(int type,struct lwp * l)610 svr4_trap(int type, struct lwp *l)
611 {
612 	struct proc *p = l->l_proc;
613 	int n;
614 	struct trapframe64 *tf = l->l_md.md_tf;
615 	struct timespec ts;
616 	struct timeval tv;
617 	struct timeval rtime, stime;
618 	uint64_t tm;
619 
620 	if (p->p_emul != &emul_svr4)
621 		return 0;
622 
623 	switch (type) {
624 	case T_SVR4_GETCC:
625 		uprintf("T_SVR4_GETCC\n");
626 		break;
627 
628 	case T_SVR4_SETCC:
629 		uprintf("T_SVR4_SETCC\n");
630 		break;
631 
632 	case T_SVR4_GETPSR:
633 		tf->tf_out[0] = TSTATECCR_TO_PSR(tf->tf_tstate);
634 		break;
635 
636 	case T_SVR4_SETPSR:
637 		uprintf("T_SVR4_SETPSR\n");
638 		break;
639 
640 	case T_SVR4_GETHRTIME:
641 		/*
642 		 * This is like gethrtime(3), returning the time expressed
643 		 * in nanoseconds since an arbitrary time in the past and
644 		 * guaranteed to be monotonically increasing, which we
645 		 * obtain from nanouptime()
646 		 */
647 		nanouptime(&ts);
648 
649 		tm = ts.tv_nsec;
650 		tm += ts.tv_sec * (uint64_t)1000000000u;
651 		tf->tf_out[0] = (tm >> 32) & 0x00000000ffffffffUL;
652 		tf->tf_out[1] = tm & 0x00000000ffffffffUL;
653 		break;
654 
655 	case T_SVR4_GETHRVTIME:
656 		/*
657 		 * This is like gethrvtime(3). returning the LWP's (now:
658 		 * proc's) virtual time expressed in nanoseconds. It is
659 		 * supposedly guaranteed to be monotonically increasing, but
660 		 * for now using the process's real time augmented with its
661 		 * current runtime is the best we can do.
662 		 */
663 		microtime(&tv);
664 		bintime2timeval(&l->l_rtime, &rtime);
665 		bintime2timeval(&l->l_stime, &stime);
666 
667 		tm = (rtime.tv_sec + tv.tv_sec - stime.tv_sec) * 1000000ull;
668 		tm += rtime.tv_usec + tv.tv_usec;
669 		tm -= stime.tv_usec;
670 		tm *= 1000u;
671 		tf->tf_out[0] = (tm >> 32) & 0x00000000ffffffffUL;
672 		tf->tf_out[1] = tm & 0x00000000ffffffffUL;
673 		break;
674 
675 	case T_SVR4_GETHRESTIME:
676 		/* I assume this is like gettimeofday(3) */
677 		nanotime(&ts);
678 		tf->tf_out[0] = ts.tv_sec;
679 		tf->tf_out[1] = ts.tv_nsec;
680 		break;
681 
682 	default:
683 		return 0;
684 	}
685 
686 	ADVANCE;
687 	return 1;
688 }
689 
690 /*
691  */
692 int
svr4_sys_sysarch(struct lwp * l,const struct svr4_sys_sysarch_args * uap,register_t * retval)693 svr4_sys_sysarch(struct lwp *l, const struct svr4_sys_sysarch_args *uap, register_t *retval)
694 {
695 
696 	switch (SCARG(uap, op)) {
697 	default:
698 		printf("(sparc64) svr4_sysarch(%d)\n", SCARG(uap, op));
699 		return EINVAL;
700 	}
701 }
702 
703 void
svr4_md_init(void)704 svr4_md_init(void)
705 {
706 
707 }
708 
709 void
svr4_md_fini(void)710 svr4_md_fini(void)
711 {
712 
713 }
714