Annotation of sys/arch/hp300/hp300/hpux_machdep.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: hpux_machdep.c,v 1.20 2005/11/06 17:23:39 miod Exp $ */
2: /* $NetBSD: hpux_machdep.c,v 1.19 1998/02/16 20:58:30 thorpej Exp $ */
3:
4: /*
5: * Copyright (c) 1995, 1996, 1997 Jason R. Thorpe. All rights reserved.
6: * Copyright (c) 1988 University of Utah.
7: * Copyright (c) 1990, 1993
8: * The Regents of the University of California. All rights reserved.
9: *
10: * This code is derived from software contributed to Berkeley by
11: * the Systems Programming Group of the University of Utah Computer
12: * Science Department.
13: *
14: * Redistribution and use in source and binary forms, with or without
15: * modification, are permitted provided that the following conditions
16: * are met:
17: * 1. Redistributions of source code must retain the above copyright
18: * notice, this list of conditions and the following disclaimer.
19: * 2. Redistributions in binary form must reproduce the above copyright
20: * notice, this list of conditions and the following disclaimer in the
21: * documentation and/or other materials provided with the distribution.
22: * 3. The name of the author may not be used to endorse or promote products
23: * derived from this software without specific prior written permission.
24: *
25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35: * SUCH DAMAGE.
36: */
37:
38: /*
39: * Machine-dependent bits for HP-UX binary compatibility.
40: */
41:
42: #include <sys/param.h>
43: #include <sys/systm.h>
44: #include <sys/buf.h>
45: #include <sys/conf.h>
46: #include <sys/device.h>
47: #include <sys/exec.h>
48: #include <sys/file.h>
49: #include <sys/filedesc.h>
50: #include <sys/ioctl.h>
51: #include <sys/ipc.h>
52: #include <sys/kernel.h>
53: #include <sys/malloc.h>
54: #include <sys/mman.h>
55: #include <sys/mount.h>
56: #include <sys/namei.h>
57: #include <sys/poll.h>
58: #include <sys/proc.h>
59: #include <sys/ptrace.h>
60: #include <sys/signalvar.h>
61: #include <sys/stat.h>
62: #include <sys/syslog.h>
63: #include <sys/tty.h>
64: #include <sys/user.h>
65: #include <sys/vnode.h>
66: #include <sys/wait.h>
67:
68: #include <machine/cpu.h>
69: #include <machine/reg.h>
70: #include <machine/psl.h>
71: #include <machine/vmparam.h>
72:
73: #include <uvm/uvm_extern.h>
74:
75: #include <sys/syscallargs.h>
76:
77: #include <compat/hpux/hpux.h>
78: #include <compat/hpux/hpux_sig.h>
79: #include <compat/hpux/hpux_util.h>
80: #include <compat/hpux/hpux_syscall.h>
81: #include <compat/hpux/hpux_syscallargs.h>
82:
83: #include <machine/hpux_machdep.h>
84:
85: extern short exframesize[];
86:
87: struct valtostr {
88: int val;
89: const char *str;
90: };
91:
92: /*
93: * 6.0 and later context.
94: * XXX what are the HP-UX "localroot" semantics? Should we handle
95: * XXX diskless systems here?
96: */
97: static const char context_040[] =
98: "standalone HP-MC68040 HP-MC68881 HP-MC68020 HP-MC68010 localroot default";
99:
100: static const char context_fpu[] =
101: "standalone HP-MC68881 HP-MC68020 HP-MC68010 localroot default";
102:
103: static const char context_nofpu[] =
104: "standalone HP-MC68020 HP-MC68010 localroot default";
105:
106: static struct valtostr context_table[] = {
107: { FPU_68060, &context_040[0] },
108: { FPU_68040, &context_040[0] },
109: { FPU_68882, &context_fpu[0] },
110: { FPU_68881, &context_fpu[0] },
111: { 0, NULL },
112: };
113:
114: #define UOFF(f) ((int)&((struct user *)0)->f)
115: #define HPUOFF(f) ((int)&((struct hpux_user *)0)->f)
116:
117: /* simplified FP structure */
118: struct bsdfp {
119: int save[54];
120: int reg[24];
121: int ctrl[3];
122: };
123:
124: /*
125: * m68k-specific setup for HP-UX executables.
126: */
127: int
128: hpux_cpu_makecmds(p, epp)
129: struct proc *p;
130: struct exec_package *epp;
131: {
132: /* struct hpux_exec *hpux_ep = epp->ep_hdr; */
133:
134: /* set up command for exec header */
135: NEW_VMCMD(&epp->ep_vmcmds, hpux_cpu_vmcmd,
136: sizeof(struct hpux_exec), (long)epp->ep_hdr, NULLVP, 0, 0);
137: return (0);
138: }
139:
140: /*
141: * We need to stash the exec header in the pcb, so we define
142: * this vmcmd to do it for us, since vmcmds are executed once
143: * we're committed to the exec (i.e. the old program has been unmapped).
144: *
145: * The address of the header is in ev->ev_addr and the length is
146: * in ev->ev_len.
147: */
148: int
149: hpux_cpu_vmcmd(p, ev)
150: struct proc *p;
151: struct exec_vmcmd *ev;
152: {
153: struct hpux_exec *execp = (struct hpux_exec *)ev->ev_addr;
154:
155: /* Make sure we have room. */
156: if (ev->ev_len <= sizeof(p->p_addr->u_md.md_exec))
157: bcopy((caddr_t)ev->ev_addr, p->p_addr->u_md.md_exec,
158: ev->ev_len);
159:
160: /* Deal with misc. HP-UX process attributes. */
161: if (execp->ha_trsize & HPUXM_VALID) {
162: if (execp->ha_trsize & HPUXM_DATAWT)
163: p->p_md.md_flags &= ~MDP_CCBDATA;
164:
165: if (execp->ha_trsize & HPUXM_STKWT)
166: p->p_md.md_flags &= ~MDP_CCBSTACK;
167: }
168:
169: return (0);
170: }
171:
172: /*
173: * Return arch-type for hpux_sys_sysconf()
174: */
175: int
176: hpux_cpu_sysconf_arch()
177: {
178:
179: switch (cputype) {
180: case CPU_68020:
181: return (HPUX_SYSCONF_CPUM020);
182:
183: case CPU_68030:
184: return (HPUX_SYSCONF_CPUM030);
185:
186: default:
187: return (HPUX_SYSCONF_CPUM040);
188: }
189: /* NOTREACHED */
190: }
191:
192: /*
193: * HP-UX advise(2) system call.
194: */
195: int
196: hpux_sys_advise(p, v, retval)
197: struct proc *p;
198: void *v;
199: register_t *retval;
200: {
201: struct hpux_sys_advise_args *uap = v;
202: int error = 0;
203:
204: switch (SCARG(uap, arg)) {
205: case 0:
206: p->p_md.md_flags |= MDP_HPUXMMAP;
207: break;
208:
209: case 1:
210: ICIA();
211: break;
212:
213: case 2:
214: DCIA();
215: break;
216:
217: default:
218: error = EINVAL;
219: break;
220: }
221:
222: return (error);
223: }
224:
225: /*
226: * HP-UX getcontext(2) system call.
227: * Man page lies, behaviour here is based on observed behaviour.
228: */
229: int
230: hpux_sys_getcontext(p, v, retval)
231: struct proc *p;
232: void *v;
233: register_t *retval;
234: {
235: struct hpux_sys_getcontext_args *uap = v;
236: const char *str;
237: int l, i, error = 0;
238: int len;
239:
240: if (SCARG(uap, len) <= 0)
241: return (EINVAL);
242:
243: for (i = 0; context_table[i].str != NULL; i++)
244: if (context_table[i].val == fputype)
245: break;
246: if (context_table[i].str == NULL)
247: str = &context_nofpu[0];
248: else
249: str = context_table[i].str;
250:
251: /* + 1 ... count the terminating \0. */
252: l = strlen(str) + 1;
253: len = min(SCARG(uap, len), l);
254:
255: if (len)
256: error = copyout(str, SCARG(uap, buf), len);
257: if (error == 0)
258: *retval = l;
259: return (0);
260: }
261:
262: /*
263: * Brutal hack! Map HP-UX u-area offsets into BSD k-stack offsets.
264: * XXX This probably doesn't work anymore, BTW. --thorpej
265: */
266: int
267: hpux_to_bsd_uoff(off, isps, p)
268: int *off, *isps;
269: struct proc *p;
270: {
271: int *ar0 = p->p_md.md_regs;
272: struct hpux_fp *hp;
273: struct bsdfp *bp;
274: u_int raddr;
275:
276: *isps = 0;
277:
278: /* u_ar0 field; procxmt puts in U_ar0 */
279: if ((int)off == HPUOFF(hpuxu_ar0))
280: return(UOFF(U_ar0));
281:
282: if (fputype) {
283: /* FP registers from PCB */
284: hp = (struct hpux_fp *)HPUOFF(hpuxu_fp);
285: bp = (struct bsdfp *)UOFF(u_pcb.pcb_fpregs);
286:
287: if (off >= hp->hpfp_ctrl && off < &hp->hpfp_ctrl[3])
288: return((int)&bp->ctrl[off - hp->hpfp_ctrl]);
289:
290: if (off >= hp->hpfp_reg && off < &hp->hpfp_reg[24])
291: return((int)&bp->reg[off - hp->hpfp_reg]);
292: }
293:
294: /*
295: * Everything else we recognize comes from the kernel stack,
296: * so we convert off to an absolute address (if not already)
297: * for simplicity.
298: */
299: if (off < (int *)ctob(UPAGES))
300: off = (int *)((u_int)off + (u_int)p->p_addr); /* XXX */
301:
302: /*
303: * General registers.
304: * We know that the HP-UX registers are in the same order as ours.
305: * The only difference is that their PS is 2 bytes instead of a
306: * padded 4 like ours throwing the alignment off.
307: */
308: if (off >= ar0 && off < &ar0[18]) {
309: /*
310: * PS: return low word and high word of PC as HP-UX would
311: * (e.g. &u.u_ar0[16.5]).
312: *
313: * XXX we don't do this since HP-UX adb doesn't rely on
314: * it and passing such an offset to procxmt will cause
315: * it to fail anyway. Instead, we just set the offset
316: * to PS and let hpux_ptrace() shift up the value returned.
317: */
318: if (off == &ar0[PS]) {
319: #if 0
320: raddr = (u_int) &((short *)ar0)[PS*2+1];
321: #else
322: raddr = (u_int) &ar0[(int)(off - ar0)];
323: #endif
324: *isps = 1;
325: }
326: /*
327: * PC: off will be &u.u_ar0[16.5] since HP-UX saved PS
328: * is only 16 bits.
329: */
330: else if (off == (int *)&(((short *)ar0)[PS*2+1]))
331: raddr = (u_int) &ar0[PC];
332: /*
333: * D0-D7, A0-A7: easy
334: */
335: else
336: raddr = (u_int) &ar0[(int)(off - ar0)];
337: return((int)(raddr - (u_int)p->p_addr)); /* XXX */
338: }
339:
340: /* everything else */
341: return (-1);
342: }
343:
344: #define HSS_RTEFRAME 0x01
345: #define HSS_FPSTATE 0x02
346: #define HSS_USERREGS 0x04
347:
348: struct hpuxsigstate {
349: int hss_flags; /* which of the following are valid */
350: struct frame hss_frame; /* original exception frame */
351: struct fpframe hss_fpstate; /* 68881/68882 state info */
352: };
353:
354: /*
355: * WARNING: code in locore.s assumes the layout shown here for hsf_signum
356: * thru hsf_handler so... don't screw with them!
357: */
358: struct hpuxsigframe {
359: int hsf_signum; /* signo for handler */
360: int hsf_code; /* additional info for handler */
361: struct hpuxsigcontext *hsf_scp; /* context ptr for handler */
362: sig_t hsf_handler; /* handler addr for u_sigc */
363: struct hpuxsigstate hsf_sigstate; /* state of the hardware */
364: struct hpuxsigcontext hsf_sc; /* actual context */
365: };
366:
367: #ifdef DEBUG
368: int hpuxsigdebug = 0;
369: int hpuxsigpid = 0;
370: #define SDB_FOLLOW 0x01
371: #define SDB_KSTACK 0x02
372: #define SDB_FPSTATE 0x04
373: #endif
374:
375: /*
376: * Send an interrupt to process.
377: */
378: /* ARGSUSED */
379: void
380: hpux_sendsig(catcher, sig, mask, code, type, val)
381: sig_t catcher;
382: int sig, mask;
383: u_long code;
384: int type;
385: union sigval val;
386: {
387: struct proc *p = curproc;
388: struct hpuxsigframe *kfp, *fp;
389: struct frame *frame;
390: struct sigacts *psp = p->p_sigacts;
391: short ft;
392: int oonstack, fsize;
393:
394: frame = (struct frame *)p->p_md.md_regs;
395: ft = frame->f_format;
396: oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
397:
398: /*
399: * Allocate and validate space for the signal handler
400: * context. Note that if the stack is in P0 space, the
401: * call to grow() is a nop, and the useracc() check
402: * will fail if the process has not already allocated
403: * the space with a `brk'.
404: */
405: fsize = sizeof(struct hpuxsigframe);
406: if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
407: (psp->ps_sigonstack & sigmask(sig))) {
408: fp = (struct hpuxsigframe *)(psp->ps_sigstk.ss_sp +
409: psp->ps_sigstk.ss_size - fsize);
410: psp->ps_sigstk.ss_flags |= SS_ONSTACK;
411: } else
412: fp = (struct hpuxsigframe *)(frame->f_regs[SP] - fsize);
413: if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
414: (void)uvm_grow(p, (unsigned)fp);
415:
416: #ifdef DEBUG
417: if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)
418: printf("hpux_sendsig(%d): sig %d ssp %p usp %p scp %p ft %d\n",
419: p->p_pid, sig, &oonstack, fp, &fp->hsf_sc, ft);
420: #endif
421:
422: kfp = (struct hpuxsigframe *)malloc((u_long)fsize, M_TEMP, M_WAITOK);
423:
424: /*
425: * Build the argument list for the signal handler.
426: */
427: kfp->hsf_signum = bsdtohpuxsig(sig);
428: kfp->hsf_code = code;
429: kfp->hsf_scp = &fp->hsf_sc;
430: kfp->hsf_handler = catcher;
431:
432: /*
433: * Save necessary hardware state. Currently this includes:
434: * - general registers
435: * - original exception frame (if not a "normal" frame)
436: * - FP coprocessor state
437: */
438: kfp->hsf_sigstate.hss_flags = HSS_USERREGS;
439: bcopy((caddr_t)frame->f_regs,
440: (caddr_t)kfp->hsf_sigstate.hss_frame.f_regs, sizeof frame->f_regs);
441: if (ft >= FMT7) {
442: #ifdef DEBUG
443: if (ft > 15 || exframesize[ft] < 0)
444: panic("hpux_sendsig: bogus frame type");
445: #endif
446: kfp->hsf_sigstate.hss_flags |= HSS_RTEFRAME;
447: kfp->hsf_sigstate.hss_frame.f_format = frame->f_format;
448: kfp->hsf_sigstate.hss_frame.f_vector = frame->f_vector;
449: bcopy((caddr_t)&frame->F_u,
450: (caddr_t)&kfp->hsf_sigstate.hss_frame.F_u, exframesize[ft]);
451:
452: /*
453: * Leave an indicator that we need to clean up the kernel
454: * stack. We do this by setting the "pad word" above the
455: * hardware stack frame to the amount the stack must be
456: * adjusted by.
457: *
458: * N.B. we increment rather than just set f_stackadj in
459: * case we are called from syscall when processing a
460: * sigreturn. In that case, f_stackadj may be non-zero.
461: */
462: frame->f_stackadj += exframesize[ft];
463: frame->f_format = frame->f_vector = 0;
464: #ifdef DEBUG
465: if (hpuxsigdebug & SDB_FOLLOW)
466: printf("hpux_sendsig(%d): copy out %d of frame %d\n",
467: p->p_pid, exframesize[ft], ft);
468: #endif
469: }
470: if (fputype) {
471: kfp->hsf_sigstate.hss_flags |= HSS_FPSTATE;
472: m68881_save(&kfp->hsf_sigstate.hss_fpstate);
473: }
474:
475: #ifdef DEBUG
476: if ((hpuxsigdebug & SDB_FPSTATE) &&
477: *(char *)&kfp->hsf_sigstate.hss_fpstate)
478: printf("hpux_sendsig(%d): copy out FP state (%x) to %p\n",
479: p->p_pid, *(u_int *)&kfp->hsf_sigstate.hss_fpstate,
480: &kfp->hsf_sigstate.hss_fpstate);
481: #endif
482:
483: /*
484: * Build the signal context to be used by hpux_sigreturn.
485: */
486: kfp->hsf_sc.hsc_syscall = 0; /* XXX */
487: kfp->hsf_sc.hsc_action = 0; /* XXX */
488: kfp->hsf_sc.hsc_pad1 = kfp->hsf_sc.hsc_pad2 = 0;
489: kfp->hsf_sc.hsc_onstack = oonstack;
490: kfp->hsf_sc.hsc_mask = mask;
491: kfp->hsf_sc.hsc_sp = frame->f_regs[SP];
492: kfp->hsf_sc.hsc_ps = frame->f_sr;
493: kfp->hsf_sc.hsc_pc = frame->f_pc;
494:
495: /* How amazingly convenient! */
496: kfp->hsf_sc._hsc_pad = 0;
497: kfp->hsf_sc._hsc_ap = (int)&fp->hsf_sigstate;
498:
499: if (copyout((caddr_t)kfp, (caddr_t)fp, fsize) != 0) {
500: #ifdef DEBUG
501: if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)
502: printf("hpux_sendsig(%d): copyout failed on sig %d\n",
503: p->p_pid, sig);
504: #endif
505: /*
506: * Process has trashed its stack; give it an illegal
507: * instruction to halt it in its tracks.
508: */
509: free((caddr_t)kfp, M_TEMP);
510: sigexit(p, SIGILL);
511: /* NOTREACHED */
512: }
513: frame->f_regs[SP] = (int)fp;
514:
515: #ifdef DEBUG
516: if (hpuxsigdebug & SDB_FOLLOW) {
517: printf(
518: "hpux_sendsig(%d): sig %d scp %p fp %p sc_sp %x sc_ap %x\n",
519: p->p_pid, sig, kfp->hsf_scp, fp,
520: kfp->hsf_sc.hsc_sp, kfp->hsf_sc._hsc_ap);
521: }
522: #endif
523:
524: /*
525: * Signal trampoline code is at base of user stack.
526: */
527: frame->f_pc = p->p_sigcode;
528: #ifdef DEBUG
529: if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)
530: printf("hpux_sendsig(%d): sig %d returns\n",
531: p->p_pid, sig);
532: #endif
533: free((caddr_t)kfp, M_TEMP);
534: }
535:
536: /*
537: * System call to cleanup state after a signal
538: * has been taken. Reset signal mask and
539: * stack state from context left by sendsig (above).
540: * Return to previous pc and psl as specified by
541: * context left by sendsig. Check carefully to
542: * make sure that the user has not modified the
543: * psl to gain improper privileges or to cause
544: * a machine fault.
545: */
546: /* ARGSUSED */
547: int
548: hpux_sys_sigreturn(p, v, retval)
549: struct proc *p;
550: void *v;
551: register_t *retval;
552: {
553: struct hpux_sys_sigreturn_args /* {
554: syscallarg(struct hpuxsigcontext *) sigcntxp;
555: } */ *uap = v;
556: struct hpuxsigcontext *scp;
557: struct frame *frame;
558: int rf;
559: struct hpuxsigcontext tsigc;
560: struct hpuxsigstate tstate;
561: int flags;
562:
563: scp = SCARG(uap, sigcntxp);
564: #ifdef DEBUG
565: if (hpuxsigdebug & SDB_FOLLOW)
566: printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp);
567: #endif
568: if ((int)scp & 1)
569: return (EINVAL);
570:
571: /*
572: * Fetch and test the HP-UX context structure.
573: * We grab it all at once for speed.
574: */
575: if (copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc))
576: return (EINVAL);
577: scp = &tsigc;
578: if ((scp->hsc_ps & PSL_USERCLR) != 0 ||
579: (scp->hsc_ps & PSL_USERSET) != PSL_USERSET)
580: return (EINVAL);
581:
582: /*
583: * Restore the user supplied information
584: */
585: if (scp->hsc_onstack & 01)
586: p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
587: else
588: p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
589: p->p_sigmask = scp->hsc_mask &~ sigcantmask;
590: frame = (struct frame *) p->p_md.md_regs;
591: frame->f_regs[SP] = scp->hsc_sp;
592: frame->f_pc = scp->hsc_pc;
593: frame->f_sr = scp->hsc_ps;
594:
595: /*
596: * Grab a pointer to the hpuxsigstate.
597: * If zero, the user is probably doing a longjmp.
598: * (This will never happen, really, since HP-UX doesn't
599: * know/care about the state pointer.)
600: */
601: if ((rf = scp->_hsc_ap) == 0)
602: return (EJUSTRETURN);
603:
604: /*
605: * See if there is anything to do before we go to the
606: * expense of copying in close to 1/2K of data
607: */
608: if (copyin((caddr_t)rf, &flags, sizeof(int)) != 0)
609: return (EINVAL);
610: #ifdef DEBUG
611: if (hpuxsigdebug & SDB_FOLLOW)
612: printf("sigreturn(%d): sc_ap %x flags %x\n",
613: p->p_pid, rf, flags);
614: #endif
615: if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate))
616: return (EJUSTRETURN);
617: #ifdef DEBUG
618: if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)
619: printf("sigreturn(%d): ssp %p usp %x scp %p ft %d\n",
620: p->p_pid, &flags, scp->hsc_sp, SCARG(uap, sigcntxp),
621: (flags & HSS_RTEFRAME) ? tstate.hss_frame.f_format : -1);
622: #endif
623: /*
624: * Restore most of the users registers except for A6 and SP
625: * which were handled above.
626: */
627: if (flags & HSS_USERREGS)
628: bcopy((caddr_t)tstate.hss_frame.f_regs,
629: (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW);
630:
631: /*
632: * Restore long stack frames. Note that we do not copy
633: * back the saved SR or PC, they were picked up above from
634: * the sigcontext structure.
635: */
636: if (flags & HSS_RTEFRAME) {
637: int sz;
638:
639: /* grab frame type and validate */
640: sz = tstate.hss_frame.f_format;
641: if (sz > 15 || (sz = exframesize[sz]) < 0)
642: return (EINVAL);
643: frame->f_stackadj -= sz;
644: frame->f_format = tstate.hss_frame.f_format;
645: frame->f_vector = tstate.hss_frame.f_vector;
646: bcopy((caddr_t)&tstate.hss_frame.F_u,
647: (caddr_t)&frame->F_u, sz);
648: #ifdef DEBUG
649: if (hpuxsigdebug & SDB_FOLLOW)
650: printf("sigreturn(%d): copy in %d of frame type %d\n",
651: p->p_pid, sz, tstate.hss_frame.f_format);
652: #endif
653: }
654:
655: /*
656: * Finally we restore the original FP context
657: */
658: if (flags & HSS_FPSTATE)
659: m68881_restore(&tstate.hss_fpstate);
660:
661: #ifdef DEBUG
662: if ((hpuxsigdebug & SDB_FPSTATE) && *(char *)&tstate.hss_fpstate)
663: printf("sigreturn(%d): copied in FP state (%x) at %p\n",
664: p->p_pid, *(u_int *)&tstate.hss_fpstate,
665: &tstate.hss_fpstate);
666:
667: if ((hpuxsigdebug & SDB_FOLLOW) ||
668: ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid))
669: printf("sigreturn(%d): returns\n", p->p_pid);
670: #endif
671: return (EJUSTRETURN);
672: }
673:
674: /*
675: * Set registers on exec.
676: * XXX Should clear registers except sp, pc.
677: */
678: void
679: hpux_setregs(p, pack, stack, retval)
680: struct proc *p;
681: struct exec_package *pack;
682: u_long stack;
683: register_t *retval;
684: {
685: struct frame *frame = (struct frame *)p->p_md.md_regs;
686:
687: frame->f_pc = pack->ep_entry & ~1;
688: frame->f_regs[SP] = stack;
689: frame->f_regs[A2] = (int)PS_STRINGS;
690:
691: /* restore a null state frame */
692: p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0;
693: if (fputype)
694: m68881_restore(&p->p_addr->u_pcb.pcb_fpregs);
695:
696: p->p_md.md_flags &= ~MDP_HPUXMMAP;
697: frame->f_regs[A0] = 0; /* not 68010 (bit 31), no FPA (30) */
698: retval[0] = 0; /* no float card */
699: if (fputype)
700: retval[1] = 1; /* yes 68881 */
701: else
702: retval[1] = 0; /* no 68881 */
703: }
CVSweb