ia32_signal.c revision 123629
1100384Speter/*- 2100384Speter * Copyright (c) 2002 Doug Rabson 3100384Speter * All rights reserved. 4100384Speter * 5100384Speter * Redistribution and use in source and binary forms, with or without 6100384Speter * modification, are permitted provided that the following conditions 7100384Speter * are met: 8100384Speter * 1. Redistributions of source code must retain the above copyright 9100384Speter * notice, this list of conditions and the following disclaimer. 10100384Speter * 2. Redistributions in binary form must reproduce the above copyright 11100384Speter * notice, this list of conditions and the following disclaimer in the 12100384Speter * documentation and/or other materials provided with the distribution. 13100384Speter * 14100384Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15100384Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16100384Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17100384Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18100384Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19100384Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20100384Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21100384Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22100384Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23100384Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24100384Speter * SUCH DAMAGE. 25100384Speter * 26100384Speter * $FreeBSD: head/sys/ia64/ia32/ia32_signal.c 123629 2003-12-18 06:59:18Z peter $ 27100384Speter */ 28100384Speter 29123629Speter#include "opt_compat.h" 30123629Speter 31100384Speter#define __ELF_WORD_SIZE 32 32100384Speter 33100384Speter#include <sys/param.h> 34100384Speter#include <sys/exec.h> 35100384Speter#include <sys/fcntl.h> 36100384Speter#include <sys/imgact.h> 37100384Speter#include <sys/kernel.h> 38100384Speter#include <sys/lock.h> 39100384Speter#include <sys/malloc.h> 40100384Speter#include <sys/mutex.h> 41100384Speter#include <sys/mman.h> 42100384Speter#include <sys/namei.h> 43100384Speter#include <sys/pioctl.h> 44100384Speter#include <sys/proc.h> 45100384Speter#include <sys/procfs.h> 46100384Speter#include <sys/resourcevar.h> 47100384Speter#include <sys/systm.h> 48100384Speter#include <sys/signalvar.h> 49100384Speter#include <sys/stat.h> 50100384Speter#include <sys/sx.h> 51100384Speter#include <sys/syscall.h> 52100384Speter#include <sys/sysctl.h> 53100384Speter#include <sys/sysent.h> 54100384Speter#include <sys/vnode.h> 55100384Speter#include <sys/imgact_elf.h> 56123423Speter#include <sys/sysproto.h> 57100384Speter 58115084Smarcel#include <machine/frame.h> 59115084Smarcel#include <machine/md_var.h> 60115084Smarcel#include <machine/pcb.h> 61115084Smarcel 62100384Speter#include <vm/vm.h> 63100384Speter#include <vm/vm_kern.h> 64100384Speter#include <vm/vm_param.h> 65100384Speter#include <vm/pmap.h> 66100384Speter#include <vm/vm_map.h> 67100384Speter#include <vm/vm_object.h> 68100384Speter#include <vm/vm_extern.h> 69100384Speter 70123423Speter#include <compat/freebsd32/freebsd32_util.h> 71123423Speter#include <compat/freebsd32/freebsd32_proto.h> 72123423Speter#include <compat/ia32/ia32_signal.h> 73100384Speter#include <i386/include/psl.h> 74100384Speter#include <i386/include/segments.h> 75100384Speter#include <i386/include/specialreg.h> 76100384Speter 77123423Speter/* 78123423Speter * Signal sending has not been implemented on ia64. This causes 79123423Speter * the sigtramp code to not understand the arguments and the application 80123423Speter * will generally crash if it tries to handle a signal. Calling 81123423Speter * sendsig() means that at least untrapped signals will work. 82123423Speter */ 83123423Spetervoid 84123423Speteria32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 85123423Speter{ 86123423Speter sendsig(catcher, sig, mask, code); 87123423Speter} 88100384Speter 89123423Speter#ifdef COMPAT_FREEBSD4 90123423Speterint 91123423Speterfreebsd4_freebsd32_sigreturn(struct thread *td, struct freebsd4_freebsd32_sigreturn_args *uap) 92123423Speter{ 93123423Speter return (sigreturn(td, (struct sigreturn_args *)uap)); 94123423Speter} 95123423Speter#endif 96100384Speter 97123423Speterint 98123423Speterfreebsd32_sigreturn(struct thread *td, struct freebsd32_sigreturn_args *uap) 99100384Speter{ 100123423Speter return (sigreturn(td, (struct sigreturn_args *)uap)); 101123423Speter} 102100384Speter 103100384Speter 104123423Spetervoid 105100384Speteria32_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) 106100384Speter{ 107115084Smarcel struct trapframe *tf = td->td_frame; 108100384Speter vm_offset_t gdt, ldt; 109100384Speter u_int64_t codesel, datasel, ldtsel; 110100384Speter u_int64_t codeseg, dataseg, gdtseg, ldtseg; 111100384Speter struct segment_descriptor desc; 112100384Speter struct vmspace *vmspace = td->td_proc->p_vmspace; 113100384Speter 114115084Smarcel exec_setregs(td, entry, stack, ps_strings); 115100384Speter 116115084Smarcel /* Non-syscall frames are cleared by exec_setregs() */ 117115084Smarcel if (tf->tf_flags & FRAME_SYSCALL) { 118115084Smarcel bzero(&tf->tf_scratch, sizeof(tf->tf_scratch)); 119115084Smarcel bzero(&tf->tf_scratch_fp, sizeof(tf->tf_scratch_fp)); 120115084Smarcel } else 121115084Smarcel tf->tf_special.ndirty = 0; 122100384Speter 123115084Smarcel tf->tf_special.psr |= IA64_PSR_IS; 124115084Smarcel tf->tf_special.sp = stack; 125100384Speter 126115084Smarcel /* Point the RSE backstore to something harmless. */ 127123423Speter tf->tf_special.bspstore = (FREEBSD32_PS_STRINGS - sz_ia32_sigcode - 128123423Speter SPARE_USRSPACE + 15) & ~15; 129115084Smarcel 130100384Speter codesel = LSEL(LUCODE_SEL, SEL_UPL); 131100384Speter datasel = LSEL(LUDATA_SEL, SEL_UPL); 132100384Speter ldtsel = GSEL(GLDT_SEL, SEL_UPL); 133100384Speter 134115084Smarcel /* Setup ia32 segment registers. */ 135115084Smarcel tf->tf_scratch.gr16 = (datasel << 48) | (datasel << 32) | 136115084Smarcel (datasel << 16) | datasel; 137115084Smarcel tf->tf_scratch.gr17 = (ldtsel << 32) | (datasel << 16) | codesel; 138100384Speter 139100384Speter /* 140100384Speter * Build the GDT and LDT. 141100384Speter */ 142123423Speter gdt = FREEBSD32_USRSTACK; 143115084Smarcel vm_map_find(&vmspace->vm_map, 0, 0, &gdt, IA32_PAGE_SIZE << 1, 0, 144115084Smarcel VM_PROT_ALL, VM_PROT_ALL, 0); 145115084Smarcel ldt = gdt + IA32_PAGE_SIZE; 146100384Speter 147100384Speter desc.sd_lolimit = 8*NLDT-1; 148100384Speter desc.sd_lobase = ldt & 0xffffff; 149100384Speter desc.sd_type = SDT_SYSLDT; 150100384Speter desc.sd_dpl = SEL_UPL; 151100384Speter desc.sd_p = 1; 152100384Speter desc.sd_hilimit = 0; 153100384Speter desc.sd_def32 = 0; 154100384Speter desc.sd_gran = 0; 155100384Speter desc.sd_hibase = ldt >> 24; 156100384Speter copyout(&desc, (caddr_t) gdt + 8*GLDT_SEL, sizeof(desc)); 157100384Speter 158123423Speter desc.sd_lolimit = ((FREEBSD32_USRSTACK >> 12) - 1) & 0xffff; 159100384Speter desc.sd_lobase = 0; 160100384Speter desc.sd_type = SDT_MEMERA; 161100384Speter desc.sd_dpl = SEL_UPL; 162100384Speter desc.sd_p = 1; 163123423Speter desc.sd_hilimit = ((FREEBSD32_USRSTACK >> 12) - 1) >> 16; 164100384Speter desc.sd_def32 = 1; 165100384Speter desc.sd_gran = 1; 166100384Speter desc.sd_hibase = 0; 167100384Speter copyout(&desc, (caddr_t) ldt + 8*LUCODE_SEL, sizeof(desc)); 168100384Speter desc.sd_type = SDT_MEMRWA; 169100384Speter copyout(&desc, (caddr_t) ldt + 8*LUDATA_SEL, sizeof(desc)); 170100384Speter 171100384Speter codeseg = 0 /* base */ 172123423Speter + (((FREEBSD32_USRSTACK >> 12) - 1) << 32) /* limit */ 173100384Speter + ((long)SDT_MEMERA << 52) 174100384Speter + ((long)SEL_UPL << 57) 175100384Speter + (1L << 59) /* present */ 176100384Speter + (1L << 62) /* 32 bits */ 177100384Speter + (1L << 63); /* page granularity */ 178100384Speter dataseg = 0 /* base */ 179123423Speter + (((FREEBSD32_USRSTACK >> 12) - 1) << 32) /* limit */ 180100384Speter + ((long)SDT_MEMRWA << 52) 181100384Speter + ((long)SEL_UPL << 57) 182100384Speter + (1L << 59) /* present */ 183100384Speter + (1L << 62) /* 32 bits */ 184100384Speter + (1L << 63); /* page granularity */ 185100384Speter 186115084Smarcel tf->tf_scratch.csd = codeseg; 187115084Smarcel tf->tf_scratch.ssd = dataseg; 188115084Smarcel tf->tf_scratch.gr24 = dataseg; /* ESD */ 189115084Smarcel tf->tf_scratch.gr27 = dataseg; /* DSD */ 190115084Smarcel tf->tf_scratch.gr28 = dataseg; /* FSD */ 191115084Smarcel tf->tf_scratch.gr29 = dataseg; /* GSD */ 192115084Smarcel 193100384Speter gdtseg = gdt /* base */ 194100384Speter + ((8L*NGDT - 1) << 32) /* limit */ 195100384Speter + ((long)SDT_SYSNULL << 52) 196100384Speter + ((long)SEL_UPL << 57) 197100384Speter + (1L << 59) /* present */ 198100384Speter + (0L << 62) /* 16 bits */ 199100384Speter + (0L << 63); /* byte granularity */ 200100384Speter ldtseg = ldt /* base */ 201100384Speter + ((8L*NLDT - 1) << 32) /* limit */ 202100384Speter + ((long)SDT_SYSLDT << 52) 203100384Speter + ((long)SEL_UPL << 57) 204100384Speter + (1L << 59) /* present */ 205100384Speter + (0L << 62) /* 16 bits */ 206100384Speter + (0L << 63); /* byte granularity */ 207100384Speter 208115084Smarcel tf->tf_scratch.gr30 = ldtseg; /* LDTD */ 209115084Smarcel tf->tf_scratch.gr31 = gdtseg; /* GDTD */ 210115084Smarcel 211115084Smarcel /* Set ia32 control registers on this processor. */ 212115084Smarcel ia64_set_cflg(CR0_PE | CR0_PG | ((long)(CR4_XMM | CR4_FXSR) << 32)); 213100384Speter ia64_set_eflag(PSL_USER); 214100384Speter 215100384Speter /* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */ 216123423Speter tf->tf_scratch.gr11 = FREEBSD32_PS_STRINGS; 217100384Speter 218100384Speter /* 219100384Speter * XXX - Linux emulator 220100384Speter * Make sure sure edx is 0x0 on entry. Linux binaries depend 221100384Speter * on it. 222100384Speter */ 223100384Speter td->td_retval[1] = 0; 224100384Speter} 225115084Smarcel 226115084Smarcelvoid 227115084Smarcelia32_restorectx(struct pcb *pcb) 228115084Smarcel{ 229115084Smarcel 230115084Smarcel ia64_set_cflg(pcb->pcb_ia32_cflg); 231115084Smarcel ia64_set_eflag(pcb->pcb_ia32_eflag); 232115084Smarcel ia64_set_fcr(pcb->pcb_ia32_fcr); 233115084Smarcel ia64_set_fdr(pcb->pcb_ia32_fdr); 234115084Smarcel ia64_set_fir(pcb->pcb_ia32_fir); 235115084Smarcel ia64_set_fsr(pcb->pcb_ia32_fsr); 236115084Smarcel} 237115084Smarcel 238115084Smarcelvoid 239115084Smarcelia32_savectx(struct pcb *pcb) 240115084Smarcel{ 241115084Smarcel 242115084Smarcel pcb->pcb_ia32_cflg = ia64_get_cflg(); 243115084Smarcel pcb->pcb_ia32_eflag = ia64_get_eflag(); 244115084Smarcel pcb->pcb_ia32_fcr = ia64_get_fcr(); 245115084Smarcel pcb->pcb_ia32_fdr = ia64_get_fdr(); 246115084Smarcel pcb->pcb_ia32_fir = ia64_get_fir(); 247115084Smarcel pcb->pcb_ia32_fsr = ia64_get_fsr(); 248115084Smarcel} 249