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$"); 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 71163058Smarcel#include <compat/freebsd32/freebsd32_signal.h> 72123423Speter#include <compat/freebsd32/freebsd32_util.h> 73123423Speter#include <compat/freebsd32/freebsd32_proto.h> 74123423Speter#include <compat/ia32/ia32_signal.h> 75233204Stijl#include <x86/include/psl.h> 76233203Stijl#include <x86/include/segments.h> 77233207Stijl#include <x86/include/specialreg.h> 78100384Speter 79149924Smarcelchar ia32_sigcode[] = { 80149924Smarcel 0xff, 0x54, 0x24, 0x10, /* call *SIGF_HANDLER(%esp) */ 81149924Smarcel 0x8d, 0x44, 0x24, 0x14, /* lea SIGF_UC(%esp),%eax */ 82149924Smarcel 0x50, /* pushl %eax */ 83149924Smarcel 0xf7, 0x40, 0x54, 0x00, 0x00, 0x02, 0x02, /* testl $PSL_VM,UC_EFLAGS(%ea 84149924Smarcelx) */ 85149924Smarcel 0x75, 0x03, /* jne 9f */ 86149924Smarcel 0x8e, 0x68, 0x14, /* movl UC_GS(%eax),%gs */ 87149924Smarcel 0xb8, 0x57, 0x01, 0x00, 0x00, /* 9: movl $SYS_sigreturn,%eax */ 88149924Smarcel 0x50, /* pushl %eax */ 89149924Smarcel 0xcd, 0x80, /* int $0x80 */ 90149924Smarcel 0xeb, 0xfe, /* 0: jmp 0b */ 91149924Smarcel 0 92149924Smarcel}; 93149924Smarcelint sz_ia32_sigcode = sizeof(ia32_sigcode); 94149924Smarcel 95220238Skib#ifdef COMPAT_43 96220238Skibint 97220238Skibofreebsd32_sigreturn(struct thread *td, struct ofreebsd32_sigreturn_args *uap) 98220238Skib{ 99220238Skib 100220238Skib return (EOPNOTSUPP); 101220238Skib} 102220238Skib#endif 103220238Skib 104123423Speter/* 105123423Speter * Signal sending has not been implemented on ia64. This causes 106123423Speter * the sigtramp code to not understand the arguments and the application 107123423Speter * will generally crash if it tries to handle a signal. Calling 108123423Speter * sendsig() means that at least untrapped signals will work. 109123423Speter */ 110123423Spetervoid 111151316Sdavidxuia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 112123423Speter{ 113151316Sdavidxu sendsig(catcher, ksi, mask); 114123423Speter} 115100384Speter 116123423Speter#ifdef COMPAT_FREEBSD4 117123423Speterint 118123423Speterfreebsd4_freebsd32_sigreturn(struct thread *td, struct freebsd4_freebsd32_sigreturn_args *uap) 119123423Speter{ 120225617Skmacy return (sys_sigreturn(td, (struct sigreturn_args *)uap)); 121123423Speter} 122123423Speter#endif 123100384Speter 124123423Speterint 125123423Speterfreebsd32_sigreturn(struct thread *td, struct freebsd32_sigreturn_args *uap) 126100384Speter{ 127225617Skmacy return (sys_sigreturn(td, (struct sigreturn_args *)uap)); 128123423Speter} 129100384Speter 130100384Speter 131123423Spetervoid 132205642Snwhitehornia32_setregs(struct thread *td, struct image_params *imgp, u_long stack) 133100384Speter{ 134115084Smarcel struct trapframe *tf = td->td_frame; 135100384Speter vm_offset_t gdt, ldt; 136100384Speter u_int64_t codesel, datasel, ldtsel; 137100384Speter u_int64_t codeseg, dataseg, gdtseg, ldtseg; 138100384Speter struct segment_descriptor desc; 139100384Speter struct vmspace *vmspace = td->td_proc->p_vmspace; 140211006Skib struct sysentvec *sv; 141100384Speter 142211006Skib sv = td->td_proc->p_sysent; 143205642Snwhitehorn exec_setregs(td, imgp, stack); 144100384Speter 145115084Smarcel /* Non-syscall frames are cleared by exec_setregs() */ 146115084Smarcel if (tf->tf_flags & FRAME_SYSCALL) { 147115084Smarcel bzero(&tf->tf_scratch, sizeof(tf->tf_scratch)); 148115084Smarcel bzero(&tf->tf_scratch_fp, sizeof(tf->tf_scratch_fp)); 149115084Smarcel } else 150115084Smarcel tf->tf_special.ndirty = 0; 151100384Speter 152115084Smarcel tf->tf_special.psr |= IA64_PSR_IS; 153115084Smarcel tf->tf_special.sp = stack; 154100384Speter 155115084Smarcel /* Point the RSE backstore to something harmless. */ 156211006Skib tf->tf_special.bspstore = (sv->sv_psstrings - sz_ia32_sigcode - 157123423Speter SPARE_USRSPACE + 15) & ~15; 158115084Smarcel 159100384Speter codesel = LSEL(LUCODE_SEL, SEL_UPL); 160100384Speter datasel = LSEL(LUDATA_SEL, SEL_UPL); 161100384Speter ldtsel = GSEL(GLDT_SEL, SEL_UPL); 162100384Speter 163115084Smarcel /* Setup ia32 segment registers. */ 164115084Smarcel tf->tf_scratch.gr16 = (datasel << 48) | (datasel << 32) | 165115084Smarcel (datasel << 16) | datasel; 166115084Smarcel tf->tf_scratch.gr17 = (ldtsel << 32) | (datasel << 16) | codesel; 167100384Speter 168100384Speter /* 169100384Speter * Build the GDT and LDT. 170100384Speter */ 171211006Skib gdt = sv->sv_usrstack; 172255426Sjhb vm_map_find(&vmspace->vm_map, NULL, 0, &gdt, IA32_PAGE_SIZE << 1, 0, 173255426Sjhb VMFS_NO_SPACE, VM_PROT_ALL, VM_PROT_ALL, 0); 174115084Smarcel ldt = gdt + IA32_PAGE_SIZE; 175100384Speter 176100384Speter desc.sd_lolimit = 8*NLDT-1; 177100384Speter desc.sd_lobase = ldt & 0xffffff; 178100384Speter desc.sd_type = SDT_SYSLDT; 179100384Speter desc.sd_dpl = SEL_UPL; 180100384Speter desc.sd_p = 1; 181100384Speter desc.sd_hilimit = 0; 182100384Speter desc.sd_def32 = 0; 183100384Speter desc.sd_gran = 0; 184100384Speter desc.sd_hibase = ldt >> 24; 185100384Speter copyout(&desc, (caddr_t) gdt + 8*GLDT_SEL, sizeof(desc)); 186100384Speter 187211006Skib desc.sd_lolimit = ((sv->sv_usrstack >> 12) - 1) & 0xffff; 188100384Speter desc.sd_lobase = 0; 189100384Speter desc.sd_type = SDT_MEMERA; 190100384Speter desc.sd_dpl = SEL_UPL; 191100384Speter desc.sd_p = 1; 192211006Skib desc.sd_hilimit = ((sv->sv_usrstack >> 12) - 1) >> 16; 193100384Speter desc.sd_def32 = 1; 194100384Speter desc.sd_gran = 1; 195100384Speter desc.sd_hibase = 0; 196100384Speter copyout(&desc, (caddr_t) ldt + 8*LUCODE_SEL, sizeof(desc)); 197100384Speter desc.sd_type = SDT_MEMRWA; 198100384Speter copyout(&desc, (caddr_t) ldt + 8*LUDATA_SEL, sizeof(desc)); 199100384Speter 200100384Speter codeseg = 0 /* base */ 201211006Skib + (((sv->sv_usrstack >> 12) - 1) << 32) /* limit */ 202100384Speter + ((long)SDT_MEMERA << 52) 203100384Speter + ((long)SEL_UPL << 57) 204100384Speter + (1L << 59) /* present */ 205100384Speter + (1L << 62) /* 32 bits */ 206100384Speter + (1L << 63); /* page granularity */ 207100384Speter dataseg = 0 /* base */ 208211006Skib + (((sv->sv_usrstack >> 12) - 1) << 32) /* limit */ 209100384Speter + ((long)SDT_MEMRWA << 52) 210100384Speter + ((long)SEL_UPL << 57) 211100384Speter + (1L << 59) /* present */ 212100384Speter + (1L << 62) /* 32 bits */ 213100384Speter + (1L << 63); /* page granularity */ 214100384Speter 215115084Smarcel tf->tf_scratch.csd = codeseg; 216115084Smarcel tf->tf_scratch.ssd = dataseg; 217115084Smarcel tf->tf_scratch.gr24 = dataseg; /* ESD */ 218115084Smarcel tf->tf_scratch.gr27 = dataseg; /* DSD */ 219115084Smarcel tf->tf_scratch.gr28 = dataseg; /* FSD */ 220115084Smarcel tf->tf_scratch.gr29 = dataseg; /* GSD */ 221115084Smarcel 222100384Speter gdtseg = gdt /* base */ 223100384Speter + ((8L*NGDT - 1) << 32) /* limit */ 224100384Speter + ((long)SDT_SYSNULL << 52) 225100384Speter + ((long)SEL_UPL << 57) 226100384Speter + (1L << 59) /* present */ 227100384Speter + (0L << 62) /* 16 bits */ 228100384Speter + (0L << 63); /* byte granularity */ 229100384Speter ldtseg = ldt /* base */ 230100384Speter + ((8L*NLDT - 1) << 32) /* limit */ 231100384Speter + ((long)SDT_SYSLDT << 52) 232100384Speter + ((long)SEL_UPL << 57) 233100384Speter + (1L << 59) /* present */ 234100384Speter + (0L << 62) /* 16 bits */ 235100384Speter + (0L << 63); /* byte granularity */ 236100384Speter 237115084Smarcel tf->tf_scratch.gr30 = ldtseg; /* LDTD */ 238115084Smarcel tf->tf_scratch.gr31 = gdtseg; /* GDTD */ 239115084Smarcel 240115084Smarcel /* Set ia32 control registers on this processor. */ 241115084Smarcel ia64_set_cflg(CR0_PE | CR0_PG | ((long)(CR4_XMM | CR4_FXSR) << 32)); 242100384Speter ia64_set_eflag(PSL_USER); 243100384Speter 244100384Speter /* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */ 245211006Skib tf->tf_scratch.gr11 = td->td_proc->p_sysent->sv_psstrings; 246100384Speter 247100384Speter /* 248100384Speter * XXX - Linux emulator 249100384Speter * Make sure sure edx is 0x0 on entry. Linux binaries depend 250100384Speter * on it. 251100384Speter */ 252100384Speter td->td_retval[1] = 0; 253100384Speter} 254115084Smarcel 255115084Smarcelvoid 256115084Smarcelia32_restorectx(struct pcb *pcb) 257115084Smarcel{ 258115084Smarcel 259115084Smarcel ia64_set_cflg(pcb->pcb_ia32_cflg); 260115084Smarcel ia64_set_eflag(pcb->pcb_ia32_eflag); 261115084Smarcel ia64_set_fcr(pcb->pcb_ia32_fcr); 262115084Smarcel ia64_set_fdr(pcb->pcb_ia32_fdr); 263115084Smarcel ia64_set_fir(pcb->pcb_ia32_fir); 264115084Smarcel ia64_set_fsr(pcb->pcb_ia32_fsr); 265115084Smarcel} 266115084Smarcel 267115084Smarcelvoid 268115084Smarcelia32_savectx(struct pcb *pcb) 269115084Smarcel{ 270115084Smarcel 271115084Smarcel pcb->pcb_ia32_cflg = ia64_get_cflg(); 272115084Smarcel pcb->pcb_ia32_eflag = ia64_get_eflag(); 273115084Smarcel pcb->pcb_ia32_fcr = ia64_get_fcr(); 274115084Smarcel pcb->pcb_ia32_fdr = ia64_get_fdr(); 275115084Smarcel pcb->pcb_ia32_fir = ia64_get_fir(); 276115084Smarcel pcb->pcb_ia32_fsr = ia64_get_fsr(); 277115084Smarcel} 278150631Speter 279150631Speterint 280150631Speterfreebsd32_getcontext(struct thread *td, struct freebsd32_getcontext_args *uap) 281150631Speter{ 282150631Speter 283150631Speter return (nosys(td, NULL)); 284150631Speter} 285150631Speter 286150631Speterint 287150631Speterfreebsd32_setcontext(struct thread *td, struct freebsd32_setcontext_args *uap) 288150631Speter{ 289150631Speter 290150631Speter return (nosys(td, NULL)); 291150631Speter} 292150631Speter 293150631Speterint 294150631Speterfreebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap) 295150631Speter{ 296150631Speter 297150631Speter return (nosys(td, NULL)); 298150631Speter} 299