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[]; 6843412Snewtonextern int _udatasel, _ucodesel; 6943412Snewton 7092765Salfredstatic void svr4_getsiginfo(union svr4_siginfo *, int, u_long, caddr_t); 7143412Snewton 7243412Snewton#if !defined(__NetBSD__) 7343412Snewton /* taken from /sys/arch/i386/include/psl.h on NetBSD-1.3 */ 7443412Snewton# define PSL_MBZ 0xffc08028 7543412Snewton# define PSL_USERSTATIC (PSL_USER | PSL_MBZ | PSL_IOPL | PSL_NT | PSL_VM | PSL_VIF | PSL_VIP) 7643412Snewton# define USERMODE(c, f) (ISPL(c) == SEL_UPL) 7743412Snewton#endif 7843412Snewton 7943412Snewton#if defined(__NetBSD__) 8043412Snewtonvoid 8183366Sjuliansvr4_setregs(td, epp, stack) 8283366Sjulian struct thread *td; 8343412Snewton struct exec_package *epp; 8443412Snewton u_long stack; 8543412Snewton{ 8683366Sjulian register struct pcb *pcb = td->td_pcb; 8743412Snewton 8843412Snewton pcb->pcb_savefpu.sv_env.en_cw = __SVR4_NPXCW__; 8983366Sjulian setregs(td, epp, stack, 0UL); 9043412Snewton} 9143412Snewton#endif /* __NetBSD__ */ 9243412Snewton 9343412Snewtonvoid 9483366Sjuliansvr4_getcontext(td, uc, mask, oonstack) 9583366Sjulian struct thread *td; 9643412Snewton struct svr4_ucontext *uc; 9751793Smarcel sigset_t *mask; 9851793Smarcel int oonstack; 9943412Snewton{ 10083366Sjulian struct proc *p = td->td_proc; 10183366Sjulian struct trapframe *tf = td->td_frame; 10243412Snewton svr4_greg_t *r = uc->uc_mcontext.greg; 10343412Snewton struct svr4_sigaltstack *s = &uc->uc_stack; 10456044Snewton#if defined(DONE_MORE_SIGALTSTACK_WORK) 10571495Sjhb struct sigacts *psp; 10671495Sjhb struct sigaltstack *sf; 10749270Snewton#endif 10843412Snewton 10983641Sjhb PROC_LOCK(p); 11071495Sjhb#if defined(DONE_MORE_SIGALTSTACK_WORK) 11171495Sjhb psp = p->p_sigacts; 11271495Sjhb sf = &p->p_sigstk; 11371495Sjhb#endif 11471495Sjhb 11543412Snewton memset(uc, 0, sizeof(struct svr4_ucontext)); 11643412Snewton 11744270Snewton uc->uc_link = p->p_emuldata; 11843412Snewton /* 11943412Snewton * Set the general purpose registers 12043412Snewton */ 12147694Snewton#ifdef VM86 12243412Snewton if (tf->tf_eflags & PSL_VM) { 12343412Snewton r[SVR4_X86_GS] = tf->tf_vm86_gs; 12443412Snewton r[SVR4_X86_FS] = tf->tf_vm86_fs; 12543412Snewton r[SVR4_X86_ES] = tf->tf_vm86_es; 12643412Snewton r[SVR4_X86_DS] = tf->tf_vm86_ds; 12783366Sjulian r[SVR4_X86_EFL] = get_vflags(td); 12843412Snewton } else 12947694Snewton#endif 13043412Snewton { 13146129Sluoqi#if defined(__NetBSD__) 13243412Snewton __asm("movl %%gs,%w0" : "=r" (r[SVR4_X86_GS])); 13343412Snewton __asm("movl %%fs,%w0" : "=r" (r[SVR4_X86_FS])); 13446129Sluoqi#else 13546129Sluoqi r[SVR4_X86_GS] = rgs(); 13646129Sluoqi r[SVR4_X86_FS] = tf->tf_fs; 13746129Sluoqi#endif 13843412Snewton r[SVR4_X86_ES] = tf->tf_es; 13943412Snewton r[SVR4_X86_DS] = tf->tf_ds; 14043412Snewton r[SVR4_X86_EFL] = tf->tf_eflags; 14143412Snewton } 14243412Snewton r[SVR4_X86_EDI] = tf->tf_edi; 14343412Snewton r[SVR4_X86_ESI] = tf->tf_esi; 14443412Snewton r[SVR4_X86_EBP] = tf->tf_ebp; 14543412Snewton r[SVR4_X86_ESP] = tf->tf_esp; 14643412Snewton r[SVR4_X86_EBX] = tf->tf_ebx; 14743412Snewton r[SVR4_X86_EDX] = tf->tf_edx; 14843412Snewton r[SVR4_X86_ECX] = tf->tf_ecx; 14943412Snewton r[SVR4_X86_EAX] = tf->tf_eax; 15044270Snewton r[SVR4_X86_TRAPNO] = tf->tf_trapno; 15144270Snewton r[SVR4_X86_ERR] = tf->tf_err; 15243412Snewton r[SVR4_X86_EIP] = tf->tf_eip; 15343412Snewton r[SVR4_X86_CS] = tf->tf_cs; 15443412Snewton r[SVR4_X86_UESP] = 0; 15543412Snewton r[SVR4_X86_SS] = tf->tf_ss; 15643412Snewton 15743412Snewton /* 15843412Snewton * Set the signal stack 15943412Snewton */ 16056044Snewton#if defined(DONE_MORE_SIGALTSTACK_WORK) 16143412Snewton bsd_to_svr4_sigaltstack(sf, s); 16244270Snewton#else 16344270Snewton s->ss_sp = (void *)(((u_long) tf->tf_esp) & ~(16384 - 1)); 16444270Snewton s->ss_size = 16384; 16544270Snewton s->ss_flags = 0; 16644270Snewton#endif 16783641Sjhb PROC_UNLOCK(p); 16843412Snewton 16943412Snewton /* 17043412Snewton * Set the signal mask 17143412Snewton */ 17251793Smarcel bsd_to_svr4_sigset(mask, &uc->uc_sigmask); 17343412Snewton 17443412Snewton /* 17543412Snewton * Set the flags 17643412Snewton */ 17756044Snewton uc->uc_flags = SVR4_UC_SIGMASK|SVR4_UC_CPU|SVR4_UC_STACK; 17843412Snewton} 17943412Snewton 18043412Snewton 18143412Snewton/* 18256044Snewton * Set to ucontext specified. Reset signal mask and 18343412Snewton * stack state from context. 18443412Snewton * Return to previous pc and psl as specified by 18543412Snewton * context left by sendsig. Check carefully to 18643412Snewton * make sure that the user has not modified the 18743412Snewton * psl to gain improper privileges or to cause 18843412Snewton * a machine fault. 18943412Snewton */ 19043412Snewtonint 19183366Sjuliansvr4_setcontext(td, uc) 19283366Sjulian struct thread *td; 19343412Snewton struct svr4_ucontext *uc; 19443412Snewton{ 19556044Snewton#if defined(DONE_MORE_SIGALTSTACK_WORK) 19671495Sjhb struct sigacts *psp; 19756044Snewton#endif 19883366Sjulian struct proc *p = td->td_proc; 19943412Snewton register struct trapframe *tf; 20043412Snewton svr4_greg_t *r = uc->uc_mcontext.greg; 20143412Snewton struct svr4_sigaltstack *s = &uc->uc_stack; 20271495Sjhb struct sigaltstack *sf; 20351793Smarcel sigset_t mask; 20443412Snewton 20583641Sjhb PROC_LOCK(p); 20671495Sjhb#if defined(DONE_MORE_SIGALTSTACK_WORK) 20783641Sjhb psp = p->p_sigacts; 20871495Sjhb#endif 209124141Sobrien sf = &td->td_sigstk; 21071495Sjhb 21143412Snewton /* 21243412Snewton * XXX: 21343412Snewton * Should we check the value of flags to determine what to restore? 21443412Snewton * What to do with uc_link? 21543412Snewton * What to do with floating point stuff? 21643412Snewton * Should we bother with the rest of the registers that we 21743412Snewton * set to 0 right now? 21843412Snewton */ 21943412Snewton 220113623Sjhb if ((uc->uc_flags & SVR4_UC_CPU) == 0) { 221113623Sjhb PROC_UNLOCK(p); 22244270Snewton return 0; 223113623Sjhb } 22444270Snewton 22556044Snewton DPRINTF(("svr4_setcontext(%d)\n", p->p_pid)); 22656044Snewton 22783366Sjulian tf = td->td_frame; 22843412Snewton 22943412Snewton /* 23043412Snewton * Restore register context. 23143412Snewton */ 23247694Snewton#ifdef VM86 23356044Snewton#warning "VM86 doesn't work yet, please don't try to use it." 23443412Snewton if (r[SVR4_X86_EFL] & PSL_VM) { 23543412Snewton tf->tf_vm86_gs = r[SVR4_X86_GS]; 23643412Snewton tf->tf_vm86_fs = r[SVR4_X86_FS]; 23743412Snewton tf->tf_vm86_es = r[SVR4_X86_ES]; 23843412Snewton tf->tf_vm86_ds = r[SVR4_X86_DS]; 23983366Sjulian set_vflags(td, r[SVR4_X86_EFL]); 24043412Snewton } else 24147694Snewton#endif 24243412Snewton { 24343412Snewton /* 24443412Snewton * Check for security violations. If we're returning to 24543412Snewton * protected mode, the CPU will validate the segment registers 24643412Snewton * automatically and generate a trap on violations. We handle 24743412Snewton * the trap, rather than doing all of the checking here. 24843412Snewton */ 24943412Snewton if (((r[SVR4_X86_EFL] ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 || 250113623Sjhb !USERMODE(r[SVR4_X86_CS], r[SVR4_X86_EFL])) { 251113623Sjhb PROC_UNLOCK(p); 25243412Snewton return (EINVAL); 253113623Sjhb } 25443412Snewton 25546129Sluoqi#if defined(__NetBSD__) 25643412Snewton /* %fs and %gs were restored by the trampoline. */ 25746129Sluoqi#else 25846129Sluoqi /* %gs was restored by the trampoline. */ 25946129Sluoqi tf->tf_fs = r[SVR4_X86_FS]; 26046129Sluoqi#endif 26143412Snewton tf->tf_es = r[SVR4_X86_ES]; 26243412Snewton tf->tf_ds = r[SVR4_X86_DS]; 26343412Snewton tf->tf_eflags = r[SVR4_X86_EFL]; 26443412Snewton } 26543412Snewton tf->tf_edi = r[SVR4_X86_EDI]; 26643412Snewton tf->tf_esi = r[SVR4_X86_ESI]; 26743412Snewton tf->tf_ebp = r[SVR4_X86_EBP]; 26843412Snewton tf->tf_ebx = r[SVR4_X86_EBX]; 26943412Snewton tf->tf_edx = r[SVR4_X86_EDX]; 27043412Snewton tf->tf_ecx = r[SVR4_X86_ECX]; 27143412Snewton tf->tf_eax = r[SVR4_X86_EAX]; 27244270Snewton tf->tf_trapno = r[SVR4_X86_TRAPNO]; 27344270Snewton tf->tf_err = r[SVR4_X86_ERR]; 27443412Snewton tf->tf_eip = r[SVR4_X86_EIP]; 27543412Snewton tf->tf_cs = r[SVR4_X86_CS]; 27643412Snewton tf->tf_ss = r[SVR4_X86_SS]; 27743412Snewton tf->tf_esp = r[SVR4_X86_ESP]; 27843412Snewton 27944270Snewton p->p_emuldata = uc->uc_link; 28043412Snewton /* 28143412Snewton * restore signal stack 28243412Snewton */ 28344270Snewton if (uc->uc_flags & SVR4_UC_STACK) { 28444270Snewton svr4_to_bsd_sigaltstack(s, sf); 28544270Snewton } 28643412Snewton 28743412Snewton /* 28843412Snewton * restore signal mask 28943412Snewton */ 29044270Snewton if (uc->uc_flags & SVR4_UC_SIGMASK) { 29156044Snewton#if defined(DEBUG_SVR4) 29256044Snewton { 29356044Snewton int i; 29456044Snewton for (i = 0; i < 4; i++) 29556044Snewton DPRINTF(("\tuc_sigmask[%d] = %lx\n", i, 29656044Snewton uc->uc_sigmask.bits[i])); 29756044Snewton } 29856044Snewton#endif 29944270Snewton svr4_to_bsd_sigset(&uc->uc_sigmask, &mask); 30052140Sluoqi SIG_CANTMASK(mask); 301112888Sjeff td->td_sigmask = mask; 302112888Sjeff signotify(td); 30344270Snewton } 30483641Sjhb PROC_UNLOCK(p); 30543412Snewton 30643412Snewton return 0; /*EJUSTRETURN;*/ 30743412Snewton} 30843412Snewton 30943412Snewton 31043412Snewtonstatic void 31143412Snewtonsvr4_getsiginfo(si, sig, code, addr) 31243412Snewton union svr4_siginfo *si; 31343412Snewton int sig; 31443412Snewton u_long code; 31543412Snewton caddr_t addr; 31643412Snewton{ 317151467Srwatson si->svr4_si_signo = bsd_to_svr4_sig[sig]; 318151467Srwatson si->svr4_si_errno = 0; 319151467Srwatson si->svr4_si_addr = addr; 32043412Snewton 32143412Snewton switch (code) { 32243412Snewton case T_PRIVINFLT: 323151467Srwatson si->svr4_si_code = SVR4_ILL_PRVOPC; 324151467Srwatson si->svr4_si_trap = SVR4_T_PRIVINFLT; 32543412Snewton break; 32643412Snewton 32743412Snewton case T_BPTFLT: 328151467Srwatson si->svr4_si_code = SVR4_TRAP_BRKPT; 329151467Srwatson si->svr4_si_trap = SVR4_T_BPTFLT; 33043412Snewton break; 33143412Snewton 33243412Snewton case T_ARITHTRAP: 333151467Srwatson si->svr4_si_code = SVR4_FPE_INTOVF; 334151467Srwatson si->svr4_si_trap = SVR4_T_DIVIDE; 33543412Snewton break; 33643412Snewton 33743412Snewton case T_PROTFLT: 338151467Srwatson si->svr4_si_code = SVR4_SEGV_ACCERR; 339151467Srwatson si->svr4_si_trap = SVR4_T_PROTFLT; 34043412Snewton break; 34143412Snewton 34243412Snewton case T_TRCTRAP: 343151467Srwatson si->svr4_si_code = SVR4_TRAP_TRACE; 344151467Srwatson si->svr4_si_trap = SVR4_T_TRCTRAP; 34543412Snewton break; 34643412Snewton 34743412Snewton case T_PAGEFLT: 348151467Srwatson si->svr4_si_code = SVR4_SEGV_ACCERR; 349151467Srwatson si->svr4_si_trap = SVR4_T_PAGEFLT; 35043412Snewton break; 35143412Snewton 35243412Snewton case T_ALIGNFLT: 353151467Srwatson si->svr4_si_code = SVR4_BUS_ADRALN; 354151467Srwatson si->svr4_si_trap = SVR4_T_ALIGNFLT; 35543412Snewton break; 35643412Snewton 35743412Snewton case T_DIVIDE: 358151467Srwatson si->svr4_si_code = SVR4_FPE_FLTDIV; 359151467Srwatson si->svr4_si_trap = SVR4_T_DIVIDE; 36043412Snewton break; 36143412Snewton 36243412Snewton case T_OFLOW: 363151467Srwatson si->svr4_si_code = SVR4_FPE_FLTOVF; 364151467Srwatson si->svr4_si_trap = SVR4_T_DIVIDE; 36543412Snewton break; 36643412Snewton 36743412Snewton case T_BOUND: 368151467Srwatson si->svr4_si_code = SVR4_FPE_FLTSUB; 369151467Srwatson si->svr4_si_trap = SVR4_T_BOUND; 37043412Snewton break; 37143412Snewton 37243412Snewton case T_DNA: 373151467Srwatson si->svr4_si_code = SVR4_FPE_FLTINV; 374151467Srwatson si->svr4_si_trap = SVR4_T_DNA; 37543412Snewton break; 37643412Snewton 37743412Snewton case T_FPOPFLT: 378151467Srwatson si->svr4_si_code = SVR4_FPE_FLTINV; 379151467Srwatson si->svr4_si_trap = SVR4_T_FPOPFLT; 38043412Snewton break; 38143412Snewton 38243412Snewton case T_SEGNPFLT: 383151467Srwatson si->svr4_si_code = SVR4_SEGV_MAPERR; 384151467Srwatson si->svr4_si_trap = SVR4_T_SEGNPFLT; 38543412Snewton break; 38643412Snewton 38743412Snewton case T_STKFLT: 388151467Srwatson si->svr4_si_code = SVR4_ILL_BADSTK; 389151467Srwatson si->svr4_si_trap = SVR4_T_STKFLT; 39043412Snewton break; 39143412Snewton 39243412Snewton default: 393151467Srwatson si->svr4_si_code = 0; 394151467Srwatson si->svr4_si_trap = 0; 39556044Snewton#if defined(DEBUG_SVR4) 39643412Snewton printf("sig %d code %ld\n", sig, code); 39756044Snewton/* panic("svr4_getsiginfo");*/ 39843412Snewton#endif 39943412Snewton break; 40043412Snewton } 40143412Snewton} 40243412Snewton 40343412Snewton 40443412Snewton/* 40543412Snewton * Send an interrupt to process. 40643412Snewton * 40743412Snewton * Stack is set up to allow sigcode stored 40843412Snewton * in u. to call routine. After the handler is 40943412Snewton * done svr4 will call setcontext for us 41043412Snewton * with the user context we just set up, and we 41143412Snewton * will return to the user pc, psl. 41243412Snewton */ 41343412Snewtonvoid 414151316Sdavidxusvr4_sendsig(catcher, ksi, mask) 41543412Snewton sig_t catcher; 416151366Sdavidxu ksiginfo_t *ksi; 41751793Smarcel sigset_t *mask; 41843412Snewton{ 41983366Sjulian register struct thread *td = curthread; 42083366Sjulian struct proc *p = td->td_proc; 42143412Snewton register struct trapframe *tf; 42243412Snewton struct svr4_sigframe *fp, frame; 42371495Sjhb struct sigacts *psp; 42443412Snewton int oonstack; 425151316Sdavidxu int sig; 426151316Sdavidxu int code; 42743412Snewton 428151467Srwatson PROC_LOCK_ASSERT(p, MA_OWNED); 429151467Srwatson sig = ksi->ksi_signo; 43056044Snewton#if defined(DEBUG_SVR4) 43156044Snewton printf("svr4_sendsig(%d)\n", sig); 43256044Snewton#endif 433151316Sdavidxu code = ksi->ksi_trapno; /* use trap No. */ 43471495Sjhb psp = p->p_sigacts; 435114983Sjhb mtx_assert(&psp->ps_mtx, MA_OWNED); 43656044Snewton 43783366Sjulian tf = td->td_frame; 43869379Smarcel oonstack = sigonstack(tf->tf_esp); 43943412Snewton 44043412Snewton /* 44143412Snewton * Allocate space for the signal handler context. 44243412Snewton */ 443124141Sobrien if ((td->td_pflags & TDP_ALTSTACK) && !oonstack && 44451793Smarcel SIGISMEMBER(psp->ps_sigonstack, sig)) { 445124141Sobrien fp = (struct svr4_sigframe *)(td->td_sigstk.ss_sp + 446124141Sobrien td->td_sigstk.ss_size - sizeof(struct svr4_sigframe)); 447124141Sobrien td->td_sigstk.ss_flags |= SS_ONSTACK; 44843412Snewton } else { 44943412Snewton fp = (struct svr4_sigframe *)tf->tf_esp - 1; 45043412Snewton } 451114983Sjhb mtx_unlock(&psp->ps_mtx); 45283641Sjhb PROC_UNLOCK(p); 45343412Snewton 45443412Snewton /* 45543412Snewton * Build the argument list for the signal handler. 45643412Snewton * Notes: 45743412Snewton * - we always build the whole argument list, even when we 45843412Snewton * don't need to [when SA_SIGINFO is not set, we don't need 45943412Snewton * to pass all sf_si and sf_uc] 46043412Snewton * - we don't pass the correct signal address [we need to 46143412Snewton * modify many kernel files to enable that] 46243412Snewton */ 46343412Snewton 46483366Sjulian svr4_getcontext(td, &frame.sf_uc, mask, oonstack); 46556044Snewton#if defined(DEBUG_SVR4) 46656044Snewton printf("obtained ucontext\n"); 46756044Snewton#endif 46843412Snewton svr4_getsiginfo(&frame.sf_si, sig, code, (caddr_t) tf->tf_eip); 46956044Snewton#if defined(DEBUG_SVR4) 47056044Snewton printf("obtained siginfo\n"); 47156044Snewton#endif 472151467Srwatson frame.sf_signum = frame.sf_si.svr4_si_signo; 47343412Snewton frame.sf_sip = &fp->sf_si; 47443412Snewton frame.sf_ucp = &fp->sf_uc; 47543412Snewton frame.sf_handler = catcher; 47656044Snewton#if defined(DEBUG_SVR4) 47743412Snewton printf("sig = %d, sip %p, ucp = %p, handler = %p\n", 47843412Snewton frame.sf_signum, frame.sf_sip, frame.sf_ucp, frame.sf_handler); 47943412Snewton#endif 48043412Snewton 48143412Snewton if (copyout(&frame, fp, sizeof(frame)) != 0) { 48243412Snewton /* 48343412Snewton * Process has trashed its stack; give it an illegal 48443412Snewton * instruction to halt it in its tracks. 48543412Snewton */ 48683641Sjhb PROC_LOCK(p); 48783366Sjulian sigexit(td, SIGILL); 48843412Snewton /* NOTREACHED */ 48943412Snewton } 49043412Snewton#if defined(__NetBSD__) 49143412Snewton /* 49243412Snewton * Build context to run handler in. 49343412Snewton */ 49443412Snewton tf->tf_es = GSEL(GUSERLDT_SEL, SEL_UPL); 49543412Snewton tf->tf_ds = GSEL(GUSERLDT_SEL, SEL_UPL); 49643412Snewton tf->tf_eip = (int)(((char *)PS_STRINGS) - 49743412Snewton svr4_szsigcode); 49843412Snewton tf->tf_cs = GSEL(GUSERLDT_SEL, SEL_UPL); 49943412Snewton 500177145Skib tf->tf_eflags &= ~(PSL_T|PSL_VM|PSL_AC|PSL_D); 50143412Snewton tf->tf_esp = (int)fp; 50243412Snewton tf->tf_ss = GSEL(GUSERLDT_SEL, SEL_UPL); 50343412Snewton#else 50443412Snewton tf->tf_esp = (int)fp; 50543412Snewton tf->tf_eip = (int)(((char *)PS_STRINGS) - *(p->p_sysent->sv_szsigcode)); 506177145Skib tf->tf_eflags &= ~(PSL_T | PSL_D); 50743412Snewton tf->tf_cs = _ucodesel; 50843412Snewton tf->tf_ds = _udatasel; 50943412Snewton tf->tf_es = _udatasel; 51046129Sluoqi tf->tf_fs = _udatasel; 51152140Sluoqi load_gs(_udatasel); 51243412Snewton tf->tf_ss = _udatasel; 51383163Sjhb PROC_LOCK(p); 514114983Sjhb mtx_lock(&psp->ps_mtx); 51543412Snewton#endif 51643412Snewton} 51743412Snewton 51843412Snewton 51943412Snewton 52043412Snewtonint 52183366Sjuliansvr4_sys_sysarch(td, v) 52283366Sjulian struct thread *td; 52343412Snewton struct svr4_sys_sysarch_args *v; 52443412Snewton{ 52543412Snewton struct svr4_sys_sysarch_args *uap = v; 52672930Speter#if 0 /* USER_LDT */ 52771495Sjhb#if defined(__NetBSD__) 52843412Snewton caddr_t sg = stackgap_init(p->p_emul); 52971495Sjhb#else 53071495Sjhb caddr_t sg = stackgap_init(); 53171495Sjhb#endif 53243412Snewton int error; 53343412Snewton#endif 53472930Speter 53543412Snewton switch (uap->op) { 53643412Snewton case SVR4_SYSARCH_FPHW: 53743412Snewton return 0; 53843412Snewton 53943412Snewton case SVR4_SYSARCH_DSCR: 54072930Speter#if 0 /* USER_LDT */ 54156044Snewton#warning "USER_LDT doesn't work - are you sure you want this?" 54243412Snewton { 54343412Snewton struct i386_set_ldt_args sa, *sap; 54443412Snewton struct sys_sysarch_args ua; 54543412Snewton 54643412Snewton struct svr4_ssd ssd; 54743412Snewton union descriptor bsd; 54843412Snewton 549107849Salfred if ((error = copyin(uap->a1, &ssd, 55043412Snewton sizeof(ssd))) != 0) { 55143412Snewton printf("Cannot copy arg1\n"); 55243412Snewton return error; 55343412Snewton } 55443412Snewton 55543412Snewton printf("s=%x, b=%x, l=%x, a1=%x a2=%x\n", 55643412Snewton ssd.selector, ssd.base, ssd.limit, 55743412Snewton ssd.access1, ssd.access2); 55843412Snewton 55943412Snewton /* We can only set ldt's for now. */ 56043412Snewton if (!ISLDT(ssd.selector)) { 56143412Snewton printf("Not an ldt\n"); 56243412Snewton return EPERM; 56343412Snewton } 56443412Snewton 56543412Snewton /* Oh, well we don't cleanup either */ 56643412Snewton if (ssd.access1 == 0) 56743412Snewton return 0; 56843412Snewton 56943412Snewton bsd.sd.sd_lobase = ssd.base & 0xffffff; 57043412Snewton bsd.sd.sd_hibase = (ssd.base >> 24) & 0xff; 57143412Snewton 57243412Snewton bsd.sd.sd_lolimit = ssd.limit & 0xffff; 57343412Snewton bsd.sd.sd_hilimit = (ssd.limit >> 16) & 0xf; 57443412Snewton 57543412Snewton bsd.sd.sd_type = ssd.access1 & 0x1f; 57643412Snewton bsd.sd.sd_dpl = (ssd.access1 >> 5) & 0x3; 57743412Snewton bsd.sd.sd_p = (ssd.access1 >> 7) & 0x1; 57843412Snewton 57943412Snewton bsd.sd.sd_xx = ssd.access2 & 0x3; 58043412Snewton bsd.sd.sd_def32 = (ssd.access2 >> 2) & 0x1; 58143412Snewton bsd.sd.sd_gran = (ssd.access2 >> 3)& 0x1; 58243412Snewton 58343412Snewton sa.start = IDXSEL(ssd.selector); 58443412Snewton sa.desc = stackgap_alloc(&sg, sizeof(union descriptor)); 58543412Snewton sa.num = 1; 58643412Snewton sap = stackgap_alloc(&sg, 58743412Snewton sizeof(struct i386_set_ldt_args)); 58843412Snewton 58943412Snewton if ((error = copyout(&sa, sap, sizeof(sa))) != 0) { 59043412Snewton printf("Cannot copyout args\n"); 59143412Snewton return error; 59243412Snewton } 59343412Snewton 594107849Salfred ua.op = I386_SET_LDT; 595107849Salfred ua.parms = (char *) sap; 59643412Snewton 59743412Snewton if ((error = copyout(&bsd, sa.desc, sizeof(bsd))) != 0) { 59843412Snewton printf("Cannot copyout desc\n"); 59943412Snewton return error; 60043412Snewton } 60143412Snewton 60283366Sjulian return sys_sysarch(td, &ua, retval); 60343412Snewton } 60443412Snewton#endif 60543412Snewton 60643412Snewton default: 60743412Snewton printf("svr4_sysarch(%d), a1 %p\n", uap->op, 60843412Snewton uap->a1); 60943412Snewton return 0; 61043412Snewton } 61143412Snewton} 612