ia32_signal.c revision 151316
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 27149924Smarcel#include <sys/cdefs.h> 28149924Smarcel__FBSDID("$FreeBSD: head/sys/ia64/ia32/ia32_signal.c 151316 2005-10-14 12:43:47Z davidxu $"); 29149924Smarcel 30123629Speter#include "opt_compat.h" 31123629Speter 32100384Speter#define __ELF_WORD_SIZE 32 33100384Speter 34100384Speter#include <sys/param.h> 35100384Speter#include <sys/exec.h> 36100384Speter#include <sys/fcntl.h> 37100384Speter#include <sys/imgact.h> 38100384Speter#include <sys/kernel.h> 39100384Speter#include <sys/lock.h> 40100384Speter#include <sys/malloc.h> 41100384Speter#include <sys/mutex.h> 42100384Speter#include <sys/mman.h> 43100384Speter#include <sys/namei.h> 44100384Speter#include <sys/pioctl.h> 45100384Speter#include <sys/proc.h> 46100384Speter#include <sys/procfs.h> 47100384Speter#include <sys/resourcevar.h> 48100384Speter#include <sys/systm.h> 49100384Speter#include <sys/signalvar.h> 50100384Speter#include <sys/stat.h> 51100384Speter#include <sys/sx.h> 52100384Speter#include <sys/syscall.h> 53100384Speter#include <sys/sysctl.h> 54100384Speter#include <sys/sysent.h> 55100384Speter#include <sys/vnode.h> 56100384Speter#include <sys/imgact_elf.h> 57123423Speter#include <sys/sysproto.h> 58100384Speter 59115084Smarcel#include <machine/frame.h> 60115084Smarcel#include <machine/md_var.h> 61115084Smarcel#include <machine/pcb.h> 62115084Smarcel 63100384Speter#include <vm/vm.h> 64100384Speter#include <vm/vm_kern.h> 65100384Speter#include <vm/vm_param.h> 66100384Speter#include <vm/pmap.h> 67100384Speter#include <vm/vm_map.h> 68100384Speter#include <vm/vm_object.h> 69100384Speter#include <vm/vm_extern.h> 70100384Speter 71123423Speter#include <compat/freebsd32/freebsd32_util.h> 72123423Speter#include <compat/freebsd32/freebsd32_proto.h> 73123423Speter#include <compat/ia32/ia32_signal.h> 74100384Speter#include <i386/include/psl.h> 75100384Speter#include <i386/include/segments.h> 76100384Speter#include <i386/include/specialreg.h> 77100384Speter 78149924Smarcelchar ia32_sigcode[] = { 79149924Smarcel 0xff, 0x54, 0x24, 0x10, /* call *SIGF_HANDLER(%esp) */ 80149924Smarcel 0x8d, 0x44, 0x24, 0x14, /* lea SIGF_UC(%esp),%eax */ 81149924Smarcel 0x50, /* pushl %eax */ 82149924Smarcel 0xf7, 0x40, 0x54, 0x00, 0x00, 0x02, 0x02, /* testl $PSL_VM,UC_EFLAGS(%ea 83149924Smarcelx) */ 84149924Smarcel 0x75, 0x03, /* jne 9f */ 85149924Smarcel 0x8e, 0x68, 0x14, /* movl UC_GS(%eax),%gs */ 86149924Smarcel 0xb8, 0x57, 0x01, 0x00, 0x00, /* 9: movl $SYS_sigreturn,%eax */ 87149924Smarcel 0x50, /* pushl %eax */ 88149924Smarcel 0xcd, 0x80, /* int $0x80 */ 89149924Smarcel 0xeb, 0xfe, /* 0: jmp 0b */ 90149924Smarcel 0 91149924Smarcel}; 92149924Smarcelint sz_ia32_sigcode = sizeof(ia32_sigcode); 93149924Smarcel 94123423Speter/* 95123423Speter * Signal sending has not been implemented on ia64. This causes 96123423Speter * the sigtramp code to not understand the arguments and the application 97123423Speter * will generally crash if it tries to handle a signal. Calling 98123423Speter * sendsig() means that at least untrapped signals will work. 99123423Speter */ 100123423Spetervoid 101151316Sdavidxuia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 102123423Speter{ 103151316Sdavidxu sendsig(catcher, ksi, mask); 104123423Speter} 105100384Speter 106123423Speter#ifdef COMPAT_FREEBSD4 107123423Speterint 108123423Speterfreebsd4_freebsd32_sigreturn(struct thread *td, struct freebsd4_freebsd32_sigreturn_args *uap) 109123423Speter{ 110123423Speter return (sigreturn(td, (struct sigreturn_args *)uap)); 111123423Speter} 112123423Speter#endif 113100384Speter 114123423Speterint 115123423Speterfreebsd32_sigreturn(struct thread *td, struct freebsd32_sigreturn_args *uap) 116100384Speter{ 117123423Speter return (sigreturn(td, (struct sigreturn_args *)uap)); 118123423Speter} 119100384Speter 120100384Speter 121123423Spetervoid 122100384Speteria32_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) 123100384Speter{ 124115084Smarcel struct trapframe *tf = td->td_frame; 125100384Speter vm_offset_t gdt, ldt; 126100384Speter u_int64_t codesel, datasel, ldtsel; 127100384Speter u_int64_t codeseg, dataseg, gdtseg, ldtseg; 128100384Speter struct segment_descriptor desc; 129100384Speter struct vmspace *vmspace = td->td_proc->p_vmspace; 130100384Speter 131115084Smarcel exec_setregs(td, entry, stack, ps_strings); 132100384Speter 133115084Smarcel /* Non-syscall frames are cleared by exec_setregs() */ 134115084Smarcel if (tf->tf_flags & FRAME_SYSCALL) { 135115084Smarcel bzero(&tf->tf_scratch, sizeof(tf->tf_scratch)); 136115084Smarcel bzero(&tf->tf_scratch_fp, sizeof(tf->tf_scratch_fp)); 137115084Smarcel } else 138115084Smarcel tf->tf_special.ndirty = 0; 139100384Speter 140115084Smarcel tf->tf_special.psr |= IA64_PSR_IS; 141115084Smarcel tf->tf_special.sp = stack; 142100384Speter 143115084Smarcel /* Point the RSE backstore to something harmless. */ 144123423Speter tf->tf_special.bspstore = (FREEBSD32_PS_STRINGS - sz_ia32_sigcode - 145123423Speter SPARE_USRSPACE + 15) & ~15; 146115084Smarcel 147100384Speter codesel = LSEL(LUCODE_SEL, SEL_UPL); 148100384Speter datasel = LSEL(LUDATA_SEL, SEL_UPL); 149100384Speter ldtsel = GSEL(GLDT_SEL, SEL_UPL); 150100384Speter 151115084Smarcel /* Setup ia32 segment registers. */ 152115084Smarcel tf->tf_scratch.gr16 = (datasel << 48) | (datasel << 32) | 153115084Smarcel (datasel << 16) | datasel; 154115084Smarcel tf->tf_scratch.gr17 = (ldtsel << 32) | (datasel << 16) | codesel; 155100384Speter 156100384Speter /* 157100384Speter * Build the GDT and LDT. 158100384Speter */ 159123423Speter gdt = FREEBSD32_USRSTACK; 160115084Smarcel vm_map_find(&vmspace->vm_map, 0, 0, &gdt, IA32_PAGE_SIZE << 1, 0, 161115084Smarcel VM_PROT_ALL, VM_PROT_ALL, 0); 162115084Smarcel ldt = gdt + IA32_PAGE_SIZE; 163100384Speter 164100384Speter desc.sd_lolimit = 8*NLDT-1; 165100384Speter desc.sd_lobase = ldt & 0xffffff; 166100384Speter desc.sd_type = SDT_SYSLDT; 167100384Speter desc.sd_dpl = SEL_UPL; 168100384Speter desc.sd_p = 1; 169100384Speter desc.sd_hilimit = 0; 170100384Speter desc.sd_def32 = 0; 171100384Speter desc.sd_gran = 0; 172100384Speter desc.sd_hibase = ldt >> 24; 173100384Speter copyout(&desc, (caddr_t) gdt + 8*GLDT_SEL, sizeof(desc)); 174100384Speter 175123423Speter desc.sd_lolimit = ((FREEBSD32_USRSTACK >> 12) - 1) & 0xffff; 176100384Speter desc.sd_lobase = 0; 177100384Speter desc.sd_type = SDT_MEMERA; 178100384Speter desc.sd_dpl = SEL_UPL; 179100384Speter desc.sd_p = 1; 180123423Speter desc.sd_hilimit = ((FREEBSD32_USRSTACK >> 12) - 1) >> 16; 181100384Speter desc.sd_def32 = 1; 182100384Speter desc.sd_gran = 1; 183100384Speter desc.sd_hibase = 0; 184100384Speter copyout(&desc, (caddr_t) ldt + 8*LUCODE_SEL, sizeof(desc)); 185100384Speter desc.sd_type = SDT_MEMRWA; 186100384Speter copyout(&desc, (caddr_t) ldt + 8*LUDATA_SEL, sizeof(desc)); 187100384Speter 188100384Speter codeseg = 0 /* base */ 189123423Speter + (((FREEBSD32_USRSTACK >> 12) - 1) << 32) /* limit */ 190100384Speter + ((long)SDT_MEMERA << 52) 191100384Speter + ((long)SEL_UPL << 57) 192100384Speter + (1L << 59) /* present */ 193100384Speter + (1L << 62) /* 32 bits */ 194100384Speter + (1L << 63); /* page granularity */ 195100384Speter dataseg = 0 /* base */ 196123423Speter + (((FREEBSD32_USRSTACK >> 12) - 1) << 32) /* limit */ 197100384Speter + ((long)SDT_MEMRWA << 52) 198100384Speter + ((long)SEL_UPL << 57) 199100384Speter + (1L << 59) /* present */ 200100384Speter + (1L << 62) /* 32 bits */ 201100384Speter + (1L << 63); /* page granularity */ 202100384Speter 203115084Smarcel tf->tf_scratch.csd = codeseg; 204115084Smarcel tf->tf_scratch.ssd = dataseg; 205115084Smarcel tf->tf_scratch.gr24 = dataseg; /* ESD */ 206115084Smarcel tf->tf_scratch.gr27 = dataseg; /* DSD */ 207115084Smarcel tf->tf_scratch.gr28 = dataseg; /* FSD */ 208115084Smarcel tf->tf_scratch.gr29 = dataseg; /* GSD */ 209115084Smarcel 210100384Speter gdtseg = gdt /* base */ 211100384Speter + ((8L*NGDT - 1) << 32) /* limit */ 212100384Speter + ((long)SDT_SYSNULL << 52) 213100384Speter + ((long)SEL_UPL << 57) 214100384Speter + (1L << 59) /* present */ 215100384Speter + (0L << 62) /* 16 bits */ 216100384Speter + (0L << 63); /* byte granularity */ 217100384Speter ldtseg = ldt /* base */ 218100384Speter + ((8L*NLDT - 1) << 32) /* limit */ 219100384Speter + ((long)SDT_SYSLDT << 52) 220100384Speter + ((long)SEL_UPL << 57) 221100384Speter + (1L << 59) /* present */ 222100384Speter + (0L << 62) /* 16 bits */ 223100384Speter + (0L << 63); /* byte granularity */ 224100384Speter 225115084Smarcel tf->tf_scratch.gr30 = ldtseg; /* LDTD */ 226115084Smarcel tf->tf_scratch.gr31 = gdtseg; /* GDTD */ 227115084Smarcel 228115084Smarcel /* Set ia32 control registers on this processor. */ 229115084Smarcel ia64_set_cflg(CR0_PE | CR0_PG | ((long)(CR4_XMM | CR4_FXSR) << 32)); 230100384Speter ia64_set_eflag(PSL_USER); 231100384Speter 232100384Speter /* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */ 233123423Speter tf->tf_scratch.gr11 = FREEBSD32_PS_STRINGS; 234100384Speter 235100384Speter /* 236100384Speter * XXX - Linux emulator 237100384Speter * Make sure sure edx is 0x0 on entry. Linux binaries depend 238100384Speter * on it. 239100384Speter */ 240100384Speter td->td_retval[1] = 0; 241100384Speter} 242115084Smarcel 243115084Smarcelvoid 244115084Smarcelia32_restorectx(struct pcb *pcb) 245115084Smarcel{ 246115084Smarcel 247115084Smarcel ia64_set_cflg(pcb->pcb_ia32_cflg); 248115084Smarcel ia64_set_eflag(pcb->pcb_ia32_eflag); 249115084Smarcel ia64_set_fcr(pcb->pcb_ia32_fcr); 250115084Smarcel ia64_set_fdr(pcb->pcb_ia32_fdr); 251115084Smarcel ia64_set_fir(pcb->pcb_ia32_fir); 252115084Smarcel ia64_set_fsr(pcb->pcb_ia32_fsr); 253115084Smarcel} 254115084Smarcel 255115084Smarcelvoid 256115084Smarcelia32_savectx(struct pcb *pcb) 257115084Smarcel{ 258115084Smarcel 259115084Smarcel pcb->pcb_ia32_cflg = ia64_get_cflg(); 260115084Smarcel pcb->pcb_ia32_eflag = ia64_get_eflag(); 261115084Smarcel pcb->pcb_ia32_fcr = ia64_get_fcr(); 262115084Smarcel pcb->pcb_ia32_fdr = ia64_get_fdr(); 263115084Smarcel pcb->pcb_ia32_fir = ia64_get_fir(); 264115084Smarcel pcb->pcb_ia32_fsr = ia64_get_fsr(); 265115084Smarcel} 266150631Speter 267150631Speterint 268150631Speterfreebsd32_getcontext(struct thread *td, struct freebsd32_getcontext_args *uap) 269150631Speter{ 270150631Speter 271150631Speter return (nosys(td, NULL)); 272150631Speter} 273150631Speter 274150631Speterint 275150631Speterfreebsd32_setcontext(struct thread *td, struct freebsd32_setcontext_args *uap) 276150631Speter{ 277150631Speter 278150631Speter return (nosys(td, NULL)); 279150631Speter} 280150631Speter 281150631Speterint 282150631Speterfreebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap) 283150631Speter{ 284150631Speter 285150631Speter return (nosys(td, NULL)); 286150631Speter} 287