ia32_sysvec.c revision 274817
1100384Speter/*- 2100384Speter * Copyright (c) 2002 Doug Rabson 3114987Speter * Copyright (c) 2003 Peter Wemm 4100384Speter * All rights reserved. 5100384Speter * 6100384Speter * Redistribution and use in source and binary forms, with or without 7100384Speter * modification, are permitted provided that the following conditions 8100384Speter * are met: 9100384Speter * 1. Redistributions of source code must retain the above copyright 10100384Speter * notice, this list of conditions and the following disclaimer. 11100384Speter * 2. Redistributions in binary form must reproduce the above copyright 12100384Speter * notice, this list of conditions and the following disclaimer in the 13100384Speter * documentation and/or other materials provided with the distribution. 14100384Speter * 15100384Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16100384Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17100384Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18100384Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19100384Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20100384Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21100384Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22100384Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23100384Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24100384Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25100384Speter * SUCH DAMAGE. 26100384Speter */ 27100384Speter 28118031Sobrien#include <sys/cdefs.h> 29118031Sobrien__FBSDID("$FreeBSD: head/sys/compat/ia32/ia32_sysvec.c 274817 2014-11-21 20:53:17Z jhb $"); 30118031Sobrien 31114987Speter#include "opt_compat.h" 32114987Speter 33100384Speter#define __ELF_WORD_SIZE 32 34100384Speter 35100384Speter#include <sys/param.h> 36100384Speter#include <sys/exec.h> 37100384Speter#include <sys/fcntl.h> 38100384Speter#include <sys/imgact.h> 39100384Speter#include <sys/kernel.h> 40100384Speter#include <sys/lock.h> 41100384Speter#include <sys/malloc.h> 42100384Speter#include <sys/mutex.h> 43100384Speter#include <sys/mman.h> 44100384Speter#include <sys/namei.h> 45100384Speter#include <sys/pioctl.h> 46100384Speter#include <sys/proc.h> 47100384Speter#include <sys/procfs.h> 48100384Speter#include <sys/resourcevar.h> 49100384Speter#include <sys/systm.h> 50100384Speter#include <sys/signalvar.h> 51100384Speter#include <sys/stat.h> 52100384Speter#include <sys/sx.h> 53100384Speter#include <sys/syscall.h> 54100384Speter#include <sys/sysctl.h> 55100384Speter#include <sys/sysent.h> 56100384Speter#include <sys/vnode.h> 57100384Speter#include <sys/imgact_elf.h> 58100384Speter 59100384Speter#include <vm/vm.h> 60100384Speter#include <vm/vm_kern.h> 61100384Speter#include <vm/vm_param.h> 62100384Speter#include <vm/pmap.h> 63100384Speter#include <vm/vm_map.h> 64100384Speter#include <vm/vm_object.h> 65100384Speter#include <vm/vm_extern.h> 66100384Speter 67163018Sdavidxu#include <compat/freebsd32/freebsd32_signal.h> 68119336Speter#include <compat/freebsd32/freebsd32_util.h> 69119336Speter#include <compat/freebsd32/freebsd32_proto.h> 70123422Speter#include <compat/freebsd32/freebsd32_syscall.h> 71119336Speter#include <compat/ia32/ia32_signal.h> 72100384Speter#include <machine/frame.h> 73100384Speter#include <machine/md_var.h> 74114987Speter#include <machine/pcb.h> 75114987Speter#include <machine/cpufunc.h> 76100384Speter 77121720SpeterCTASSERT(sizeof(struct ia32_mcontext) == 640); 78121720SpeterCTASSERT(sizeof(struct ia32_ucontext) == 704); 79121720SpeterCTASSERT(sizeof(struct ia32_sigframe) == 800); 80163018SdavidxuCTASSERT(sizeof(struct siginfo32) == 64); 81121720Speter#ifdef COMPAT_FREEBSD4 82121720SpeterCTASSERT(sizeof(struct ia32_mcontext4) == 260); 83121720SpeterCTASSERT(sizeof(struct ia32_ucontext4) == 324); 84121720SpeterCTASSERT(sizeof(struct ia32_sigframe4) == 408); 85121720Speter#endif 86121720Speter 87208453Skibextern const char *freebsd32_syscallnames[]; 88208453Skib 89227309Sedstatic SYSCTL_NODE(_compat, OID_AUTO, ia32, CTLFLAG_RW, 0, "ia32 mode"); 90120422Speter 91171410Sjhbstatic u_long ia32_maxdsiz = IA32_MAXDSIZ; 92267992ShselaskySYSCTL_ULONG(_compat_ia32, OID_AUTO, maxdsiz, CTLFLAG_RWTUN, &ia32_maxdsiz, 0, ""); 93220238Skibu_long ia32_maxssiz = IA32_MAXSSIZ; 94267992ShselaskySYSCTL_ULONG(_compat_ia32, OID_AUTO, maxssiz, CTLFLAG_RWTUN, &ia32_maxssiz, 0, ""); 95171410Sjhbstatic u_long ia32_maxvmem = IA32_MAXVMEM; 96267992ShselaskySYSCTL_ULONG(_compat_ia32, OID_AUTO, maxvmem, CTLFLAG_RWTUN, &ia32_maxvmem, 0, ""); 97171410Sjhb 98100384Speterstruct sysentvec ia32_freebsd_sysvec = { 99183322Skib .sv_size = FREEBSD32_SYS_MAXSYSCALL, 100183322Skib .sv_table = freebsd32_sysent, 101183322Skib .sv_mask = 0, 102183322Skib .sv_sigsize = 0, 103183322Skib .sv_sigtbl = NULL, 104183322Skib .sv_errsize = 0, 105183322Skib .sv_errtbl = NULL, 106183322Skib .sv_transtrap = NULL, 107183322Skib .sv_fixup = elf32_freebsd_fixup, 108183322Skib .sv_sendsig = ia32_sendsig, 109183322Skib .sv_sigcode = ia32_sigcode, 110183322Skib .sv_szsigcode = &sz_ia32_sigcode, 111183322Skib .sv_prepsyscall = NULL, 112183322Skib .sv_name = "FreeBSD ELF32", 113183322Skib .sv_coredump = elf32_coredump, 114183322Skib .sv_imgact_try = NULL, 115183322Skib .sv_minsigstksz = MINSIGSTKSZ, 116183322Skib .sv_pagesize = IA32_PAGE_SIZE, 117238687Skib .sv_minuser = FREEBSD32_MINUSER, 118217151Skib .sv_maxuser = FREEBSD32_MAXUSER, 119183322Skib .sv_usrstack = FREEBSD32_USRSTACK, 120183322Skib .sv_psstrings = FREEBSD32_PS_STRINGS, 121183322Skib .sv_stackprot = VM_PROT_ALL, 122205014Snwhitehorn .sv_copyout_strings = freebsd32_copyout_strings, 123183322Skib .sv_setregs = ia32_setregs, 124183322Skib .sv_fixlimit = ia32_fixlimit, 125185169Skib .sv_maxssiz = &ia32_maxssiz, 126217151Skib .sv_flags = SV_ABI_FREEBSD | SV_IA32 | SV_ILP32 | 127217151Skib#ifdef __amd64__ 128217151Skib SV_SHP 129217151Skib#else 130217151Skib 0 131217151Skib#endif 132217151Skib , 133208453Skib .sv_set_syscall_retval = ia32_set_syscall_retval, 134208453Skib .sv_fetch_syscall_args = ia32_fetch_syscall_args, 135208453Skib .sv_syscallnames = freebsd32_syscallnames, 136217151Skib .sv_shared_page_base = FREEBSD32_SHAREDPAGE, 137217151Skib .sv_shared_page_len = PAGE_SIZE, 138219405Sdchagin .sv_schedtail = NULL, 139100384Speter}; 140217151SkibINIT_SYSENTVEC(elf_ia32_sysvec, &ia32_freebsd_sysvec); 141100384Speter 142100384Speterstatic Elf32_Brandinfo ia32_brand_info = { 143183322Skib .brand = ELFOSABI_FREEBSD, 144183322Skib .machine = EM_386, 145183322Skib .compat_3_brand = "FreeBSD", 146183322Skib .emul_path = NULL, 147183322Skib .interp_path = "/libexec/ld-elf.so.1", 148183322Skib .sysvec = &ia32_freebsd_sysvec, 149183322Skib .interp_newpath = "/libexec/ld-elf32.so.1", 150189771Sdchagin .brand_note = &elf32_freebsd_brandnote, 151190708Sdchagin .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE 152183322Skib}; 153100384Speter 154197729SbzSYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_MIDDLE, 155100384Speter (sysinit_cfunc_t) elf32_insert_brand_entry, 156100384Speter &ia32_brand_info); 157100384Speter 158123742Speterstatic Elf32_Brandinfo ia32_brand_oinfo = { 159183322Skib .brand = ELFOSABI_FREEBSD, 160183322Skib .machine = EM_386, 161183322Skib .compat_3_brand = "FreeBSD", 162183322Skib .emul_path = NULL, 163183322Skib .interp_path = "/usr/libexec/ld-elf.so.1", 164183322Skib .sysvec = &ia32_freebsd_sysvec, 165183322Skib .interp_newpath = "/libexec/ld-elf32.so.1", 166189771Sdchagin .brand_note = &elf32_freebsd_brandnote, 167190708Sdchagin .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE 168183322Skib}; 169123742Speter 170123742SpeterSYSINIT(oia32, SI_SUB_EXEC, SI_ORDER_ANY, 171123742Speter (sysinit_cfunc_t) elf32_insert_brand_entry, 172123742Speter &ia32_brand_oinfo); 173123742Speter 174196512Sbzstatic Elf32_Brandinfo kia32_brand_info = { 175196512Sbz .brand = ELFOSABI_FREEBSD, 176196512Sbz .machine = EM_386, 177196512Sbz .compat_3_brand = "FreeBSD", 178196512Sbz .emul_path = NULL, 179196512Sbz .interp_path = "/lib/ld.so.1", 180196512Sbz .sysvec = &ia32_freebsd_sysvec, 181196512Sbz .brand_note = &elf32_kfreebsd_brandnote, 182196653Sbz .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE_MANDATORY 183196512Sbz}; 184133464Smarcel 185196512SbzSYSINIT(kia32, SI_SUB_EXEC, SI_ORDER_ANY, 186196512Sbz (sysinit_cfunc_t) elf32_insert_brand_entry, 187196512Sbz &kia32_brand_info); 188196512Sbz 189133464Smarcelvoid 190274817Sjhbelf32_dump_thread(struct thread *td, void *dst, size_t *off) 191133464Smarcel{ 192274817Sjhb void *buf; 193274817Sjhb size_t len; 194274817Sjhb 195274817Sjhb len = 0; 196274817Sjhb if (use_xsave) { 197274817Sjhb if (dst != NULL) { 198274817Sjhb fpugetregs(td); 199274817Sjhb len += elf32_populate_note(NT_X86_XSTATE, 200274817Sjhb get_pcb_user_save_td(td), dst, 201274817Sjhb cpu_max_ext_state_size, &buf); 202274817Sjhb *(uint64_t *)((char *)buf + X86_XSTATE_XCR0_OFFSET) = 203274817Sjhb xsave_mask; 204274817Sjhb } else 205274817Sjhb len += elf32_populate_note(NT_X86_XSTATE, NULL, NULL, 206274817Sjhb cpu_max_ext_state_size, NULL); 207274817Sjhb } 208274817Sjhb *off = len; 209133464Smarcel} 210133464Smarcel 211220238Skibvoid 212169565Sjhbia32_fixlimit(struct rlimit *rl, int which) 213120422Speter{ 214120422Speter 215169565Sjhb switch (which) { 216169565Sjhb case RLIMIT_DATA: 217169565Sjhb if (ia32_maxdsiz != 0) { 218169565Sjhb if (rl->rlim_cur > ia32_maxdsiz) 219169565Sjhb rl->rlim_cur = ia32_maxdsiz; 220169565Sjhb if (rl->rlim_max > ia32_maxdsiz) 221169565Sjhb rl->rlim_max = ia32_maxdsiz; 222169565Sjhb } 223169565Sjhb break; 224169565Sjhb case RLIMIT_STACK: 225169565Sjhb if (ia32_maxssiz != 0) { 226169565Sjhb if (rl->rlim_cur > ia32_maxssiz) 227169565Sjhb rl->rlim_cur = ia32_maxssiz; 228169565Sjhb if (rl->rlim_max > ia32_maxssiz) 229169565Sjhb rl->rlim_max = ia32_maxssiz; 230169565Sjhb } 231169565Sjhb break; 232169565Sjhb case RLIMIT_VMEM: 233169565Sjhb if (ia32_maxvmem != 0) { 234169565Sjhb if (rl->rlim_cur > ia32_maxvmem) 235169565Sjhb rl->rlim_cur = ia32_maxvmem; 236169565Sjhb if (rl->rlim_max > ia32_maxvmem) 237169565Sjhb rl->rlim_max = ia32_maxvmem; 238169565Sjhb } 239169565Sjhb break; 240120422Speter } 241120422Speter} 242