1139790Simp/*- 243412Snewton * Copyright (c) 1998 Mark Newton 343412Snewton * Copyright (c) 1994 Christos Zoulas 443412Snewton * All rights reserved. 543412Snewton * 643412Snewton * Redistribution and use in source and binary forms, with or without 743412Snewton * modification, are permitted provided that the following conditions 843412Snewton * are met: 943412Snewton * 1. Redistributions of source code must retain the above copyright 1043412Snewton * notice, this list of conditions and the following disclaimer. 1143412Snewton * 2. Redistributions in binary form must reproduce the above copyright 1243412Snewton * notice, this list of conditions and the following disclaimer in the 1343412Snewton * documentation and/or other materials provided with the distribution. 1443412Snewton * 3. The name of the author may not be used to endorse or promote products 1543412Snewton * derived from this software without specific prior written permission 1643412Snewton * 1743412Snewton * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1843412Snewton * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1943412Snewton * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2043412Snewton * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2143412Snewton * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2243412Snewton * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2343412Snewton * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2443412Snewton * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2543412Snewton * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2643412Snewton * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2743412Snewton */ 2843412Snewton 29116145Sobrien#include <sys/cdefs.h> 30116145Sobrien__FBSDID("$FreeBSD$"); 31116145Sobrien 3243412Snewton#include <sys/types.h> 3343412Snewton#include <sys/param.h> 3443412Snewton#include <sys/systm.h> 3543412Snewton#include <sys/exec.h> 3676166Smarkm#include <sys/filedesc.h> 3743412Snewton#include <sys/lock.h> 3876166Smarkm#include <sys/mutex.h> 3976166Smarkm#include <sys/proc.h> 4043412Snewton#include <sys/signal.h> 4143412Snewton#include <sys/signalvar.h> 4243412Snewton 4343412Snewton#include <machine/cpu.h> 4443412Snewton#include <machine/cpufunc.h> 4543412Snewton#include <machine/psl.h> 4643412Snewton#include <machine/reg.h> 4743412Snewton#include <machine/specialreg.h> 4843412Snewton#include <machine/sysarch.h> 4943412Snewton#include <machine/vm86.h> 5043412Snewton#include <machine/vmparam.h> 5143412Snewton 5276166Smarkm#include <vm/vm.h> 5376166Smarkm#include <vm/pmap.h> 5476166Smarkm 5565302Sobrien#include <compat/svr4/svr4.h> 5665302Sobrien#include <compat/svr4/svr4_types.h> 5765302Sobrien#include <compat/svr4/svr4_signal.h> 5843412Snewton#include <i386/svr4/svr4_machdep.h> 5965302Sobrien#include <compat/svr4/svr4_ucontext.h> 6065302Sobrien#include <compat/svr4/svr4_proto.h> 6165302Sobrien#include <compat/svr4/svr4_util.h> 6243412Snewton 6343412Snewton#undef sigcode 6443412Snewton#undef szsigcode 6543412Snewton 6643412Snewtonextern int svr4_szsigcode; 6743412Snewtonextern char svr4_sigcode[]; 6843412Snewton 6992765Salfredstatic void svr4_getsiginfo(union svr4_siginfo *, int, u_long, caddr_t); 7043412Snewton 7143412Snewton#if !defined(__NetBSD__) 7243412Snewton /* taken from /sys/arch/i386/include/psl.h on NetBSD-1.3 */ 7343412Snewton# define PSL_MBZ 0xffc08028 7443412Snewton# define PSL_USERSTATIC (PSL_USER | PSL_MBZ | PSL_IOPL | PSL_NT | PSL_VM | PSL_VIF | PSL_VIP) 7543412Snewton# define USERMODE(c, f) (ISPL(c) == SEL_UPL) 7643412Snewton#endif 7743412Snewton 7843412Snewton#if defined(__NetBSD__) 7943412Snewtonvoid 8083366Sjuliansvr4_setregs(td, epp, stack) 8183366Sjulian struct thread *td; 8243412Snewton struct exec_package *epp; 8343412Snewton u_long stack; 8443412Snewton{ 8583366Sjulian register struct pcb *pcb = td->td_pcb; 8643412Snewton 8743412Snewton pcb->pcb_savefpu.sv_env.en_cw = __SVR4_NPXCW__; 8883366Sjulian setregs(td, epp, stack, 0UL); 8943412Snewton} 9043412Snewton#endif /* __NetBSD__ */ 9143412Snewton 9243412Snewtonvoid 9383366Sjuliansvr4_getcontext(td, uc, mask, oonstack) 9483366Sjulian struct thread *td; 9543412Snewton struct svr4_ucontext *uc; 9651793Smarcel sigset_t *mask; 9751793Smarcel int oonstack; 9843412Snewton{ 9983366Sjulian struct proc *p = td->td_proc; 10083366Sjulian struct trapframe *tf = td->td_frame; 10143412Snewton svr4_greg_t *r = uc->uc_mcontext.greg; 10243412Snewton struct svr4_sigaltstack *s = &uc->uc_stack; 10356044Snewton#if defined(DONE_MORE_SIGALTSTACK_WORK) 10471495Sjhb struct sigacts *psp; 10571495Sjhb struct sigaltstack *sf; 10649270Snewton#endif 10743412Snewton 10883641Sjhb PROC_LOCK(p); 10971495Sjhb#if defined(DONE_MORE_SIGALTSTACK_WORK) 11071495Sjhb psp = p->p_sigacts; 11171495Sjhb sf = &p->p_sigstk; 11271495Sjhb#endif 11371495Sjhb 11443412Snewton memset(uc, 0, sizeof(struct svr4_ucontext)); 11543412Snewton 11644270Snewton uc->uc_link = p->p_emuldata; 11743412Snewton /* 11843412Snewton * Set the general purpose registers 11943412Snewton */ 12047694Snewton#ifdef VM86 12143412Snewton if (tf->tf_eflags & PSL_VM) { 12243412Snewton r[SVR4_X86_GS] = tf->tf_vm86_gs; 12343412Snewton r[SVR4_X86_FS] = tf->tf_vm86_fs; 12443412Snewton r[SVR4_X86_ES] = tf->tf_vm86_es; 12543412Snewton r[SVR4_X86_DS] = tf->tf_vm86_ds; 12683366Sjulian r[SVR4_X86_EFL] = get_vflags(td); 12743412Snewton } else 12847694Snewton#endif 12943412Snewton { 13046129Sluoqi#if defined(__NetBSD__) 13143412Snewton __asm("movl %%gs,%w0" : "=r" (r[SVR4_X86_GS])); 13243412Snewton __asm("movl %%fs,%w0" : "=r" (r[SVR4_X86_FS])); 13346129Sluoqi#else 13446129Sluoqi r[SVR4_X86_GS] = rgs(); 13546129Sluoqi r[SVR4_X86_FS] = tf->tf_fs; 13646129Sluoqi#endif 13743412Snewton r[SVR4_X86_ES] = tf->tf_es; 13843412Snewton r[SVR4_X86_DS] = tf->tf_ds; 13943412Snewton r[SVR4_X86_EFL] = tf->tf_eflags; 14043412Snewton } 14143412Snewton r[SVR4_X86_EDI] = tf->tf_edi; 14243412Snewton r[SVR4_X86_ESI] = tf->tf_esi; 14343412Snewton r[SVR4_X86_EBP] = tf->tf_ebp; 14443412Snewton r[SVR4_X86_ESP] = tf->tf_esp; 14543412Snewton r[SVR4_X86_EBX] = tf->tf_ebx; 14643412Snewton r[SVR4_X86_EDX] = tf->tf_edx; 14743412Snewton r[SVR4_X86_ECX] = tf->tf_ecx; 14843412Snewton r[SVR4_X86_EAX] = tf->tf_eax; 14944270Snewton r[SVR4_X86_TRAPNO] = tf->tf_trapno; 15044270Snewton r[SVR4_X86_ERR] = tf->tf_err; 15143412Snewton r[SVR4_X86_EIP] = tf->tf_eip; 15243412Snewton r[SVR4_X86_CS] = tf->tf_cs; 15343412Snewton r[SVR4_X86_UESP] = 0; 15443412Snewton r[SVR4_X86_SS] = tf->tf_ss; 15543412Snewton 15643412Snewton /* 15743412Snewton * Set the signal stack 15843412Snewton */ 15956044Snewton#if defined(DONE_MORE_SIGALTSTACK_WORK) 16043412Snewton bsd_to_svr4_sigaltstack(sf, s); 16144270Snewton#else 162298433Spfg s->ss_sp = (void *)rounddown2((u_long)tf->tf_esp, 16384); 16344270Snewton s->ss_size = 16384; 16444270Snewton s->ss_flags = 0; 16544270Snewton#endif 16683641Sjhb PROC_UNLOCK(p); 16743412Snewton 16843412Snewton /* 16943412Snewton * Set the signal mask 17043412Snewton */ 17151793Smarcel bsd_to_svr4_sigset(mask, &uc->uc_sigmask); 17243412Snewton 17343412Snewton /* 17443412Snewton * Set the flags 17543412Snewton */ 17656044Snewton uc->uc_flags = SVR4_UC_SIGMASK|SVR4_UC_CPU|SVR4_UC_STACK; 17743412Snewton} 17843412Snewton 17943412Snewton 18043412Snewton/* 18156044Snewton * Set to ucontext specified. Reset signal mask and 18243412Snewton * stack state from context. 18343412Snewton * Return to previous pc and psl as specified by 18443412Snewton * context left by sendsig. Check carefully to 18543412Snewton * make sure that the user has not modified the 18643412Snewton * psl to gain improper privileges or to cause 18743412Snewton * a machine fault. 18843412Snewton */ 18943412Snewtonint 19083366Sjuliansvr4_setcontext(td, uc) 19183366Sjulian struct thread *td; 19243412Snewton struct svr4_ucontext *uc; 19343412Snewton{ 19456044Snewton#if defined(DONE_MORE_SIGALTSTACK_WORK) 19571495Sjhb struct sigacts *psp; 19656044Snewton#endif 19783366Sjulian struct proc *p = td->td_proc; 19843412Snewton register struct trapframe *tf; 19943412Snewton svr4_greg_t *r = uc->uc_mcontext.greg; 20043412Snewton struct svr4_sigaltstack *s = &uc->uc_stack; 20171495Sjhb struct sigaltstack *sf; 20251793Smarcel sigset_t mask; 20343412Snewton 20483641Sjhb PROC_LOCK(p); 20571495Sjhb#if defined(DONE_MORE_SIGALTSTACK_WORK) 20683641Sjhb psp = p->p_sigacts; 20771495Sjhb#endif 208124141Sobrien sf = &td->td_sigstk; 20971495Sjhb 21043412Snewton /* 21143412Snewton * XXX: 21243412Snewton * Should we check the value of flags to determine what to restore? 21343412Snewton * What to do with uc_link? 21443412Snewton * What to do with floating point stuff? 21543412Snewton * Should we bother with the rest of the registers that we 21643412Snewton * set to 0 right now? 21743412Snewton */ 21843412Snewton 219113623Sjhb if ((uc->uc_flags & SVR4_UC_CPU) == 0) { 220113623Sjhb PROC_UNLOCK(p); 22144270Snewton return 0; 222113623Sjhb } 22344270Snewton 22456044Snewton DPRINTF(("svr4_setcontext(%d)\n", p->p_pid)); 22556044Snewton 22683366Sjulian tf = td->td_frame; 22743412Snewton 22843412Snewton /* 22943412Snewton * Restore register context. 23043412Snewton */ 23147694Snewton#ifdef VM86 23256044Snewton#warning "VM86 doesn't work yet, please don't try to use it." 23343412Snewton if (r[SVR4_X86_EFL] & PSL_VM) { 23443412Snewton tf->tf_vm86_gs = r[SVR4_X86_GS]; 23543412Snewton tf->tf_vm86_fs = r[SVR4_X86_FS]; 23643412Snewton tf->tf_vm86_es = r[SVR4_X86_ES]; 23743412Snewton tf->tf_vm86_ds = r[SVR4_X86_DS]; 23883366Sjulian set_vflags(td, r[SVR4_X86_EFL]); 23943412Snewton } else 24047694Snewton#endif 24143412Snewton { 24243412Snewton /* 24343412Snewton * Check for security violations. If we're returning to 24443412Snewton * protected mode, the CPU will validate the segment registers 24543412Snewton * automatically and generate a trap on violations. We handle 24643412Snewton * the trap, rather than doing all of the checking here. 24743412Snewton */ 24843412Snewton if (((r[SVR4_X86_EFL] ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 || 249113623Sjhb !USERMODE(r[SVR4_X86_CS], r[SVR4_X86_EFL])) { 250113623Sjhb PROC_UNLOCK(p); 25143412Snewton return (EINVAL); 252113623Sjhb } 25343412Snewton 25446129Sluoqi#if defined(__NetBSD__) 25543412Snewton /* %fs and %gs were restored by the trampoline. */ 25646129Sluoqi#else 25746129Sluoqi /* %gs was restored by the trampoline. */ 25846129Sluoqi tf->tf_fs = r[SVR4_X86_FS]; 25946129Sluoqi#endif 26043412Snewton tf->tf_es = r[SVR4_X86_ES]; 26143412Snewton tf->tf_ds = r[SVR4_X86_DS]; 26243412Snewton tf->tf_eflags = r[SVR4_X86_EFL]; 26343412Snewton } 26443412Snewton tf->tf_edi = r[SVR4_X86_EDI]; 26543412Snewton tf->tf_esi = r[SVR4_X86_ESI]; 26643412Snewton tf->tf_ebp = r[SVR4_X86_EBP]; 26743412Snewton tf->tf_ebx = r[SVR4_X86_EBX]; 26843412Snewton tf->tf_edx = r[SVR4_X86_EDX]; 26943412Snewton tf->tf_ecx = r[SVR4_X86_ECX]; 27043412Snewton tf->tf_eax = r[SVR4_X86_EAX]; 27144270Snewton tf->tf_trapno = r[SVR4_X86_TRAPNO]; 27244270Snewton tf->tf_err = r[SVR4_X86_ERR]; 27343412Snewton tf->tf_eip = r[SVR4_X86_EIP]; 27443412Snewton tf->tf_cs = r[SVR4_X86_CS]; 27543412Snewton tf->tf_ss = r[SVR4_X86_SS]; 27643412Snewton tf->tf_esp = r[SVR4_X86_ESP]; 27743412Snewton 27844270Snewton p->p_emuldata = uc->uc_link; 27943412Snewton /* 28043412Snewton * restore signal stack 28143412Snewton */ 28244270Snewton if (uc->uc_flags & SVR4_UC_STACK) { 28344270Snewton svr4_to_bsd_sigaltstack(s, sf); 28444270Snewton } 28543412Snewton 28643412Snewton /* 28743412Snewton * restore signal mask 28843412Snewton */ 28944270Snewton if (uc->uc_flags & SVR4_UC_SIGMASK) { 29056044Snewton#if defined(DEBUG_SVR4) 29156044Snewton { 29256044Snewton int i; 29356044Snewton for (i = 0; i < 4; i++) 29456044Snewton DPRINTF(("\tuc_sigmask[%d] = %lx\n", i, 29556044Snewton uc->uc_sigmask.bits[i])); 29656044Snewton } 29756044Snewton#endif 29844270Snewton svr4_to_bsd_sigset(&uc->uc_sigmask, &mask); 29952140Sluoqi SIG_CANTMASK(mask); 300112888Sjeff td->td_sigmask = mask; 301112888Sjeff signotify(td); 30244270Snewton } 30383641Sjhb PROC_UNLOCK(p); 30443412Snewton 30543412Snewton return 0; /*EJUSTRETURN;*/ 30643412Snewton} 30743412Snewton 30843412Snewton 30943412Snewtonstatic void 31043412Snewtonsvr4_getsiginfo(si, sig, code, addr) 31143412Snewton union svr4_siginfo *si; 31243412Snewton int sig; 31343412Snewton u_long code; 31443412Snewton caddr_t addr; 31543412Snewton{ 316151467Srwatson si->svr4_si_signo = bsd_to_svr4_sig[sig]; 317151467Srwatson si->svr4_si_errno = 0; 318151467Srwatson si->svr4_si_addr = addr; 31943412Snewton 32043412Snewton switch (code) { 32143412Snewton case T_PRIVINFLT: 322151467Srwatson si->svr4_si_code = SVR4_ILL_PRVOPC; 323151467Srwatson si->svr4_si_trap = SVR4_T_PRIVINFLT; 32443412Snewton break; 32543412Snewton 32643412Snewton case T_BPTFLT: 327151467Srwatson si->svr4_si_code = SVR4_TRAP_BRKPT; 328151467Srwatson si->svr4_si_trap = SVR4_T_BPTFLT; 32943412Snewton break; 33043412Snewton 33143412Snewton case T_ARITHTRAP: 332151467Srwatson si->svr4_si_code = SVR4_FPE_INTOVF; 333151467Srwatson si->svr4_si_trap = SVR4_T_DIVIDE; 33443412Snewton break; 33543412Snewton 33643412Snewton case T_PROTFLT: 337151467Srwatson si->svr4_si_code = SVR4_SEGV_ACCERR; 338151467Srwatson si->svr4_si_trap = SVR4_T_PROTFLT; 33943412Snewton break; 34043412Snewton 34143412Snewton case T_TRCTRAP: 342151467Srwatson si->svr4_si_code = SVR4_TRAP_TRACE; 343151467Srwatson si->svr4_si_trap = SVR4_T_TRCTRAP; 34443412Snewton break; 34543412Snewton 34643412Snewton case T_PAGEFLT: 347151467Srwatson si->svr4_si_code = SVR4_SEGV_ACCERR; 348151467Srwatson si->svr4_si_trap = SVR4_T_PAGEFLT; 34943412Snewton break; 35043412Snewton 35143412Snewton case T_ALIGNFLT: 352151467Srwatson si->svr4_si_code = SVR4_BUS_ADRALN; 353151467Srwatson si->svr4_si_trap = SVR4_T_ALIGNFLT; 35443412Snewton break; 35543412Snewton 35643412Snewton case T_DIVIDE: 357151467Srwatson si->svr4_si_code = SVR4_FPE_FLTDIV; 358151467Srwatson si->svr4_si_trap = SVR4_T_DIVIDE; 35943412Snewton break; 36043412Snewton 36143412Snewton case T_OFLOW: 362151467Srwatson si->svr4_si_code = SVR4_FPE_FLTOVF; 363151467Srwatson si->svr4_si_trap = SVR4_T_DIVIDE; 36443412Snewton break; 36543412Snewton 36643412Snewton case T_BOUND: 367151467Srwatson si->svr4_si_code = SVR4_FPE_FLTSUB; 368151467Srwatson si->svr4_si_trap = SVR4_T_BOUND; 36943412Snewton break; 37043412Snewton 37143412Snewton case T_DNA: 372151467Srwatson si->svr4_si_code = SVR4_FPE_FLTINV; 373151467Srwatson si->svr4_si_trap = SVR4_T_DNA; 37443412Snewton break; 37543412Snewton 37643412Snewton case T_FPOPFLT: 377151467Srwatson si->svr4_si_code = SVR4_FPE_FLTINV; 378151467Srwatson si->svr4_si_trap = SVR4_T_FPOPFLT; 37943412Snewton break; 38043412Snewton 38143412Snewton case T_SEGNPFLT: 382151467Srwatson si->svr4_si_code = SVR4_SEGV_MAPERR; 383151467Srwatson si->svr4_si_trap = SVR4_T_SEGNPFLT; 38443412Snewton break; 38543412Snewton 38643412Snewton case T_STKFLT: 387151467Srwatson si->svr4_si_code = SVR4_ILL_BADSTK; 388151467Srwatson si->svr4_si_trap = SVR4_T_STKFLT; 38943412Snewton break; 39043412Snewton 39143412Snewton default: 392151467Srwatson si->svr4_si_code = 0; 393151467Srwatson si->svr4_si_trap = 0; 39456044Snewton#if defined(DEBUG_SVR4) 39543412Snewton printf("sig %d code %ld\n", sig, code); 39656044Snewton/* panic("svr4_getsiginfo");*/ 39743412Snewton#endif 39843412Snewton break; 39943412Snewton } 40043412Snewton} 40143412Snewton 40243412Snewton 40343412Snewton/* 40443412Snewton * Send an interrupt to process. 40543412Snewton * 40643412Snewton * Stack is set up to allow sigcode stored 40743412Snewton * in u. to call routine. After the handler is 40843412Snewton * done svr4 will call setcontext for us 40943412Snewton * with the user context we just set up, and we 41043412Snewton * will return to the user pc, psl. 41143412Snewton */ 41243412Snewtonvoid 413151316Sdavidxusvr4_sendsig(catcher, ksi, mask) 41443412Snewton sig_t catcher; 415151366Sdavidxu ksiginfo_t *ksi; 41651793Smarcel sigset_t *mask; 41743412Snewton{ 41883366Sjulian register struct thread *td = curthread; 41983366Sjulian struct proc *p = td->td_proc; 42043412Snewton register struct trapframe *tf; 42143412Snewton struct svr4_sigframe *fp, frame; 42271495Sjhb struct sigacts *psp; 42343412Snewton int oonstack; 424151316Sdavidxu int sig; 425151316Sdavidxu int code; 42643412Snewton 427151467Srwatson PROC_LOCK_ASSERT(p, MA_OWNED); 428151467Srwatson sig = ksi->ksi_signo; 42956044Snewton#if defined(DEBUG_SVR4) 43056044Snewton printf("svr4_sendsig(%d)\n", sig); 43156044Snewton#endif 432151316Sdavidxu code = ksi->ksi_trapno; /* use trap No. */ 43371495Sjhb psp = p->p_sigacts; 434114983Sjhb mtx_assert(&psp->ps_mtx, MA_OWNED); 43556044Snewton 43683366Sjulian tf = td->td_frame; 43769379Smarcel oonstack = sigonstack(tf->tf_esp); 43843412Snewton 43943412Snewton /* 44043412Snewton * Allocate space for the signal handler context. 44143412Snewton */ 442124141Sobrien if ((td->td_pflags & TDP_ALTSTACK) && !oonstack && 44351793Smarcel SIGISMEMBER(psp->ps_sigonstack, sig)) { 444294930Sjhb fp = (struct svr4_sigframe *)((uintptr_t)td->td_sigstk.ss_sp + 445124141Sobrien td->td_sigstk.ss_size - sizeof(struct svr4_sigframe)); 446124141Sobrien td->td_sigstk.ss_flags |= SS_ONSTACK; 44743412Snewton } else { 44843412Snewton fp = (struct svr4_sigframe *)tf->tf_esp - 1; 44943412Snewton } 450114983Sjhb mtx_unlock(&psp->ps_mtx); 45183641Sjhb PROC_UNLOCK(p); 45243412Snewton 45343412Snewton /* 45443412Snewton * Build the argument list for the signal handler. 45543412Snewton * Notes: 45643412Snewton * - we always build the whole argument list, even when we 45743412Snewton * don't need to [when SA_SIGINFO is not set, we don't need 45843412Snewton * to pass all sf_si and sf_uc] 45943412Snewton * - we don't pass the correct signal address [we need to 46043412Snewton * modify many kernel files to enable that] 46143412Snewton */ 46243412Snewton 46383366Sjulian svr4_getcontext(td, &frame.sf_uc, mask, oonstack); 46456044Snewton#if defined(DEBUG_SVR4) 46556044Snewton printf("obtained ucontext\n"); 46656044Snewton#endif 46743412Snewton svr4_getsiginfo(&frame.sf_si, sig, code, (caddr_t) tf->tf_eip); 46856044Snewton#if defined(DEBUG_SVR4) 46956044Snewton printf("obtained siginfo\n"); 47056044Snewton#endif 471151467Srwatson frame.sf_signum = frame.sf_si.svr4_si_signo; 47243412Snewton frame.sf_sip = &fp->sf_si; 47343412Snewton frame.sf_ucp = &fp->sf_uc; 47443412Snewton frame.sf_handler = catcher; 47556044Snewton#if defined(DEBUG_SVR4) 47643412Snewton printf("sig = %d, sip %p, ucp = %p, handler = %p\n", 47743412Snewton frame.sf_signum, frame.sf_sip, frame.sf_ucp, frame.sf_handler); 47843412Snewton#endif 47943412Snewton 48043412Snewton if (copyout(&frame, fp, sizeof(frame)) != 0) { 48143412Snewton /* 48243412Snewton * Process has trashed its stack; give it an illegal 48343412Snewton * instruction to halt it in its tracks. 48443412Snewton */ 48583641Sjhb PROC_LOCK(p); 48683366Sjulian sigexit(td, SIGILL); 48743412Snewton /* NOTREACHED */ 48843412Snewton } 48943412Snewton#if defined(__NetBSD__) 49043412Snewton /* 49143412Snewton * Build context to run handler in. 49243412Snewton */ 49343412Snewton tf->tf_es = GSEL(GUSERLDT_SEL, SEL_UPL); 49443412Snewton tf->tf_ds = GSEL(GUSERLDT_SEL, SEL_UPL); 49543412Snewton tf->tf_eip = (int)(((char *)PS_STRINGS) - 49643412Snewton svr4_szsigcode); 49743412Snewton tf->tf_cs = GSEL(GUSERLDT_SEL, SEL_UPL); 49843412Snewton 499177145Skib tf->tf_eflags &= ~(PSL_T|PSL_VM|PSL_AC|PSL_D); 50043412Snewton tf->tf_esp = (int)fp; 50143412Snewton tf->tf_ss = GSEL(GUSERLDT_SEL, SEL_UPL); 50243412Snewton#else 50343412Snewton tf->tf_esp = (int)fp; 50443412Snewton tf->tf_eip = (int)(((char *)PS_STRINGS) - *(p->p_sysent->sv_szsigcode)); 505177145Skib tf->tf_eflags &= ~(PSL_T | PSL_D); 50643412Snewton tf->tf_cs = _ucodesel; 50743412Snewton tf->tf_ds = _udatasel; 50843412Snewton tf->tf_es = _udatasel; 50946129Sluoqi tf->tf_fs = _udatasel; 51052140Sluoqi load_gs(_udatasel); 51143412Snewton tf->tf_ss = _udatasel; 51283163Sjhb PROC_LOCK(p); 513114983Sjhb mtx_lock(&psp->ps_mtx); 51443412Snewton#endif 51543412Snewton} 51643412Snewton 51743412Snewton 51843412Snewton 51943412Snewtonint 52083366Sjuliansvr4_sys_sysarch(td, v) 52183366Sjulian struct thread *td; 52243412Snewton struct svr4_sys_sysarch_args *v; 52343412Snewton{ 52443412Snewton struct svr4_sys_sysarch_args *uap = v; 52572930Speter#if 0 /* USER_LDT */ 52671495Sjhb#if defined(__NetBSD__) 52743412Snewton caddr_t sg = stackgap_init(p->p_emul); 52871495Sjhb#else 52971495Sjhb caddr_t sg = stackgap_init(); 53071495Sjhb#endif 53143412Snewton int error; 53243412Snewton#endif 53372930Speter 53443412Snewton switch (uap->op) { 53543412Snewton case SVR4_SYSARCH_FPHW: 53643412Snewton return 0; 53743412Snewton 53843412Snewton case SVR4_SYSARCH_DSCR: 53972930Speter#if 0 /* USER_LDT */ 54056044Snewton#warning "USER_LDT doesn't work - are you sure you want this?" 54143412Snewton { 54243412Snewton struct i386_set_ldt_args sa, *sap; 54343412Snewton struct sys_sysarch_args ua; 54443412Snewton 54543412Snewton struct svr4_ssd ssd; 54643412Snewton union descriptor bsd; 54743412Snewton 548107849Salfred if ((error = copyin(uap->a1, &ssd, 54943412Snewton sizeof(ssd))) != 0) { 55043412Snewton printf("Cannot copy arg1\n"); 55143412Snewton return error; 55243412Snewton } 55343412Snewton 55443412Snewton printf("s=%x, b=%x, l=%x, a1=%x a2=%x\n", 55543412Snewton ssd.selector, ssd.base, ssd.limit, 55643412Snewton ssd.access1, ssd.access2); 55743412Snewton 55843412Snewton /* We can only set ldt's for now. */ 55943412Snewton if (!ISLDT(ssd.selector)) { 56043412Snewton printf("Not an ldt\n"); 56143412Snewton return EPERM; 56243412Snewton } 56343412Snewton 56443412Snewton /* Oh, well we don't cleanup either */ 56543412Snewton if (ssd.access1 == 0) 56643412Snewton return 0; 56743412Snewton 56843412Snewton bsd.sd.sd_lobase = ssd.base & 0xffffff; 56943412Snewton bsd.sd.sd_hibase = (ssd.base >> 24) & 0xff; 57043412Snewton 57143412Snewton bsd.sd.sd_lolimit = ssd.limit & 0xffff; 57243412Snewton bsd.sd.sd_hilimit = (ssd.limit >> 16) & 0xf; 57343412Snewton 57443412Snewton bsd.sd.sd_type = ssd.access1 & 0x1f; 57543412Snewton bsd.sd.sd_dpl = (ssd.access1 >> 5) & 0x3; 57643412Snewton bsd.sd.sd_p = (ssd.access1 >> 7) & 0x1; 57743412Snewton 57843412Snewton bsd.sd.sd_xx = ssd.access2 & 0x3; 57943412Snewton bsd.sd.sd_def32 = (ssd.access2 >> 2) & 0x1; 58043412Snewton bsd.sd.sd_gran = (ssd.access2 >> 3)& 0x1; 58143412Snewton 58243412Snewton sa.start = IDXSEL(ssd.selector); 58343412Snewton sa.desc = stackgap_alloc(&sg, sizeof(union descriptor)); 58443412Snewton sa.num = 1; 58543412Snewton sap = stackgap_alloc(&sg, 58643412Snewton sizeof(struct i386_set_ldt_args)); 58743412Snewton 58843412Snewton if ((error = copyout(&sa, sap, sizeof(sa))) != 0) { 58943412Snewton printf("Cannot copyout args\n"); 59043412Snewton return error; 59143412Snewton } 59243412Snewton 593107849Salfred ua.op = I386_SET_LDT; 594107849Salfred ua.parms = (char *) sap; 59543412Snewton 59643412Snewton if ((error = copyout(&bsd, sa.desc, sizeof(bsd))) != 0) { 59743412Snewton printf("Cannot copyout desc\n"); 59843412Snewton return error; 59943412Snewton } 60043412Snewton 60183366Sjulian return sys_sysarch(td, &ua, retval); 60243412Snewton } 60343412Snewton#endif 60443412Snewton 60543412Snewton default: 60643412Snewton printf("svr4_sysarch(%d), a1 %p\n", uap->op, 60743412Snewton uap->a1); 60843412Snewton return 0; 60943412Snewton } 61043412Snewton} 611