svr4_sysvec.c revision 177785
1167465Smp/*- 259243Sobrien * Copyright (c) 1998 Mark Newton 359243Sobrien * All rights reserved. 459243Sobrien * 559243Sobrien * Redistribution and use in source and binary forms, with or without 659243Sobrien * modification, are permitted provided that the following conditions 759243Sobrien * are met: 859243Sobrien * 1. Redistributions of source code must retain the above copyright 959243Sobrien * notice, this list of conditions and the following disclaimer. 1059243Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1159243Sobrien * notice, this list of conditions and the following disclaimer in the 1259243Sobrien * documentation and/or other materials provided with the distribution. 1359243Sobrien * 3. All advertising materials mentioning features or use of this software 1459243Sobrien * must display the following acknowledgement: 1559243Sobrien * This product includes software developed by Christos Zoulas. 1659243Sobrien * 4. The name of the author may not be used to endorse or promote products 17100616Smp * derived from this software without specific prior written permission. 1859243Sobrien * 1959243Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2059243Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2159243Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2259243Sobrien * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2359243Sobrien * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2459243Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2559243Sobrien * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2659243Sobrien * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2759243Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2859243Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2959243Sobrien */ 3059243Sobrien 3159243Sobrien#include <sys/cdefs.h> 3259243Sobrien__FBSDID("$FreeBSD: head/sys/compat/svr4/svr4_sysvec.c 177785 2008-03-31 12:01:21Z kib $"); 3359243Sobrien 3459243Sobrien/* XXX we use functions that might not exist. */ 35167465Smp#include "opt_compat.h" 3659243Sobrien 3759243Sobrien#ifndef COMPAT_43 3859243Sobrien#error "Unable to compile SVR4-emulator due to missing COMPAT_43 option!" 3959243Sobrien#endif 4059243Sobrien 4169408Sache#include <sys/param.h> 4259243Sobrien#include <sys/systm.h> 43167465Smp#include <sys/proc.h> 44167465Smp#include <sys/sysent.h> 4569408Sache#include <sys/imgact.h> 4659243Sobrien#include <sys/imgact_elf.h> 4759243Sobrien#include <sys/fcntl.h> 4859243Sobrien#include <sys/lock.h> 4959243Sobrien#include <sys/malloc.h> 5059243Sobrien#include <sys/module.h> 5159243Sobrien#include <sys/mutex.h> 5259243Sobrien#include <sys/namei.h> 5359243Sobrien#include <sys/socket.h> 5459243Sobrien#include <sys/syscallsubr.h> 5559243Sobrien#include <sys/vnode.h> 5659243Sobrien#include <vm/vm.h> 5759243Sobrien#include <sys/exec.h> 58145479Smp#include <sys/kernel.h> 59145479Smp#include <machine/cpu.h> 60145479Smp#include <netinet/in.h> 61145479Smp 62145479Smp#include <compat/svr4/svr4.h> 63145479Smp#include <compat/svr4/svr4_types.h> 64167465Smp#include <compat/svr4/svr4_syscall.h> 6559243Sobrien#include <compat/svr4/svr4_signal.h> 66167465Smp#include <compat/svr4/svr4_socket.h> 67167465Smp#include <compat/svr4/svr4_sockio.h> 68167465Smp#include <compat/svr4/svr4_errno.h> 6959243Sobrien#include <compat/svr4/svr4_proto.h> 70167465Smp#include <compat/svr4/svr4_siginfo.h> 71167465Smp#include <compat/svr4/svr4_util.h> 72167465Smp 7359243Sobrienint bsd_to_svr4_errno[ELAST+1] = { 74167465Smp 0, 75167465Smp SVR4_EPERM, 7659243Sobrien SVR4_ENOENT, 77167465Smp SVR4_ESRCH, 78167465Smp SVR4_EINTR, 7959243Sobrien SVR4_EIO, 8059243Sobrien SVR4_ENXIO, 8159243Sobrien SVR4_E2BIG, 8259243Sobrien SVR4_ENOEXEC, 8359243Sobrien SVR4_EBADF, 8459243Sobrien SVR4_ECHILD, 8559243Sobrien SVR4_EDEADLK, 86167465Smp SVR4_ENOMEM, 87167465Smp SVR4_EACCES, 88167465Smp SVR4_EFAULT, 8961524Sobrien SVR4_ENOTBLK, 9061524Sobrien SVR4_EBUSY, 9161524Sobrien SVR4_EEXIST, 9261524Sobrien SVR4_EXDEV, 9361524Sobrien SVR4_ENODEV, 9459243Sobrien SVR4_ENOTDIR, 9559243Sobrien SVR4_EISDIR, 9659243Sobrien SVR4_EINVAL, 9759243Sobrien SVR4_ENFILE, 9859243Sobrien SVR4_EMFILE, 99167465Smp SVR4_ENOTTY, 10059243Sobrien SVR4_ETXTBSY, 101167465Smp SVR4_EFBIG, 102167465Smp SVR4_ENOSPC, 103167465Smp SVR4_ESPIPE, 104145479Smp SVR4_EROFS, 105145479Smp SVR4_EMLINK, 10659243Sobrien SVR4_EPIPE, 10759243Sobrien SVR4_EDOM, 10859243Sobrien SVR4_ERANGE, 109167465Smp SVR4_EAGAIN, 110167465Smp SVR4_EINPROGRESS, 11159243Sobrien SVR4_EALREADY, 112167465Smp SVR4_ENOTSOCK, 11359243Sobrien SVR4_EDESTADDRREQ, 114167465Smp SVR4_EMSGSIZE, 11559243Sobrien SVR4_EPROTOTYPE, 11659243Sobrien SVR4_ENOPROTOOPT, 11759243Sobrien SVR4_EPROTONOSUPPORT, 11859243Sobrien SVR4_ESOCKTNOSUPPORT, 11959243Sobrien SVR4_EOPNOTSUPP, 12059243Sobrien SVR4_EPFNOSUPPORT, 12159243Sobrien SVR4_EAFNOSUPPORT, 12259243Sobrien SVR4_EADDRINUSE, 12359243Sobrien SVR4_EADDRNOTAVAIL, 12459243Sobrien SVR4_ENETDOWN, 125167465Smp SVR4_ENETUNREACH, 12659243Sobrien SVR4_ENETRESET, 127167465Smp SVR4_ECONNABORTED, 12859243Sobrien SVR4_ECONNRESET, 12959243Sobrien SVR4_ENOBUFS, 130167465Smp SVR4_EISCONN, 13159243Sobrien SVR4_ENOTCONN, 13259243Sobrien SVR4_ESHUTDOWN, 13359243Sobrien SVR4_ETOOMANYREFS, 13459243Sobrien SVR4_ETIMEDOUT, 13559243Sobrien SVR4_ECONNREFUSED, 136167465Smp SVR4_ELOOP, 137167465Smp SVR4_ENAMETOOLONG, 13859243Sobrien SVR4_EHOSTDOWN, 139167465Smp SVR4_EHOSTUNREACH, 14059243Sobrien SVR4_ENOTEMPTY, 14159243Sobrien SVR4_EPROCLIM, 14259243Sobrien SVR4_EUSERS, 143167465Smp SVR4_EDQUOT, 14459243Sobrien SVR4_ESTALE, 145167465Smp SVR4_EREMOTE, 14659243Sobrien SVR4_EBADRPC, 14759243Sobrien SVR4_ERPCMISMATCH, 14859243Sobrien SVR4_EPROGUNAVAIL, 14959243Sobrien SVR4_EPROGMISMATCH, 150167465Smp SVR4_EPROCUNAVAIL, 15159243Sobrien SVR4_ENOLCK, 15259243Sobrien SVR4_ENOSYS, 15359243Sobrien SVR4_EFTYPE, 15459243Sobrien SVR4_EAUTH, 15559243Sobrien SVR4_ENEEDAUTH, 15659243Sobrien SVR4_EIDRM, 15759243Sobrien SVR4_ENOMSG, 15859243Sobrien}; 15959243Sobrien 16059243Sobrien 16159243Sobrienstatic int svr4_fixup(register_t **stack_base, struct image_params *imgp); 162167465Smp 16359243Sobrienextern struct sysent svr4_sysent[]; 16459243Sobrien#undef szsigcode 16559243Sobrien#undef sigcode 166167465Smp 16759243Sobrienextern int svr4_szsigcode; 16859243Sobrienextern char svr4_sigcode[]; 16959243Sobrien 170167465Smpstruct sysentvec svr4_sysvec = { 17159243Sobrien SVR4_SYS_MAXSYSCALL, 17259243Sobrien svr4_sysent, 17359243Sobrien 0xff, 17459243Sobrien SVR4_NSIG-1, /* NB: signal trans table indexed with signno-1 */ 17559243Sobrien bsd_to_svr4_sig+1, 17659243Sobrien ELAST, /* ELAST */ 17759243Sobrien bsd_to_svr4_errno, 17859243Sobrien NULL, 179167465Smp svr4_fixup, 180167465Smp svr4_sendsig, 181167465Smp svr4_sigcode, 182167465Smp &svr4_szsigcode, 18359243Sobrien NULL, 18459243Sobrien "SVR4", 18559243Sobrien elf32_coredump, 18659243Sobrien NULL, 187167465Smp SVR4_MINSIGSTKSZ, 18859243Sobrien PAGE_SIZE, 18959243Sobrien VM_MIN_ADDRESS, 19059243Sobrien VM_MAXUSER_ADDRESS, 19159243Sobrien USRSTACK, 19259243Sobrien PS_STRINGS, 193167465Smp VM_PROT_ALL, 19459243Sobrien exec_copyout_strings, 195167465Smp exec_setregs, 19659243Sobrien NULL 19759243Sobrien}; 19859243Sobrien 19959243Sobrienconst char svr4_emul_path[] = "/compat/svr4"; 20059243Sobrien 201167465SmpElf32_Brandinfo svr4_brand = { 202167465Smp ELFOSABI_SYSV, 203167465Smp EM_386, /* XXX only implemented for x86 so far. */ 204167465Smp "SVR4", 205167465Smp svr4_emul_path, 206167465Smp "/lib/libc.so.1", 20759243Sobrien &svr4_sysvec, 20859243Sobrien NULL, 209167465Smp}; 210167465Smp 211167465Smpstatic int 21259243Sobriensvr4_fixup(register_t **stack_base, struct image_params *imgp) 21359243Sobrien{ 21459243Sobrien Elf32_Auxargs *args; 21559243Sobrien register_t *pos; 21659243Sobrien 21759243Sobrien KASSERT(curthread->td_proc == imgp->proc, 21859243Sobrien ("unsafe svr4_fixup(), should be curproc")); 21959243Sobrien args = (Elf32_Auxargs *)imgp->auxargs; 22059243Sobrien pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2); 22159243Sobrien 22259243Sobrien if (args->trace) 22359243Sobrien AUXARGS_ENTRY(pos, AT_DEBUG, 1); 224167465Smp if (args->execfd != -1) 225167465Smp AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); 226167465Smp AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); 227167465Smp AUXARGS_ENTRY(pos, AT_PHENT, args->phent); 22859243Sobrien AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum); 229167465Smp AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz); 23059243Sobrien AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); 23159243Sobrien AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); 23259243Sobrien AUXARGS_ENTRY(pos, AT_BASE, args->base); 23359243Sobrien AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid); 23459243Sobrien AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid); 23559243Sobrien AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid); 23659243Sobrien AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid); 23759243Sobrien AUXARGS_ENTRY(pos, AT_NULL, 0); 238100616Smp 239100616Smp free(imgp->auxargs, M_TEMP); 24059243Sobrien imgp->auxargs = NULL; 24159243Sobrien 24259243Sobrien (*stack_base)--; 24359243Sobrien **stack_base = (register_t)imgp->args->argc; 24459243Sobrien return 0; 24559243Sobrien} 24659243Sobrien 24759243Sobrien/* 24859243Sobrien * Search an alternate path before passing pathname arguments on 24959243Sobrien * to system calls. Useful for keeping a separate 'emulation tree'. 25059243Sobrien * 25159243Sobrien * If cflag is set, we check if an attempt can be made to create 25259243Sobrien * the named file, i.e. we check if the directory it should 25359243Sobrien * be in exists. 25459243Sobrien */ 25559243Sobrienint 25659243Sobriensvr4_emul_find(struct thread *td, char *path, enum uio_seg pathseg, 25759243Sobrien char **pbuf, int create) 25859243Sobrien{ 25959243Sobrien 260167465Smp return (kern_alternate_path(td, svr4_emul_path, path, pathseg, pbuf, 26159243Sobrien create)); 26259243Sobrien} 26359243Sobrien 26459243Sobrienstatic int 265167465Smpsvr4_elf_modevent(module_t mod, int type, void *data) 26659243Sobrien{ 26759243Sobrien int error; 26859243Sobrien 26959243Sobrien error = 0; 27059243Sobrien 27159243Sobrien switch(type) { 272167465Smp case MOD_LOAD: 27359243Sobrien if (elf32_insert_brand_entry(&svr4_brand) < 0) { 27459243Sobrien printf("cannot insert svr4 elf brand handler\n"); 27559243Sobrien error = EINVAL; 27659243Sobrien break; 27759243Sobrien } 27859243Sobrien if (bootverbose) 27959243Sobrien printf("svr4 ELF exec handler installed\n"); 28059243Sobrien svr4_sockcache_init(); 281167465Smp break; 28259243Sobrien case MOD_UNLOAD: 28359243Sobrien /* Only allow the emulator to be removed if it isn't in use. */ 28459243Sobrien if (elf32_brand_inuse(&svr4_brand) != 0) { 28559243Sobrien error = EBUSY; 28659243Sobrien } else if (elf32_remove_brand_entry(&svr4_brand) < 0) { 28759243Sobrien error = EINVAL; 28859243Sobrien } 289167465Smp 290100616Smp if (error) { 29159243Sobrien printf("Could not deinstall ELF interpreter entry (error %d)\n", 29259243Sobrien error); 29359243Sobrien break; 29459243Sobrien } 29559243Sobrien if (bootverbose) 29659243Sobrien printf("svr4 ELF exec handler removed\n"); 297167465Smp svr4_sockcache_destroy(); 29859243Sobrien break; 29959243Sobrien default: 30059243Sobrien return (EOPNOTSUPP); 301167465Smp break; 30259243Sobrien } 30359243Sobrien return error; 30459243Sobrien} 30559243Sobrien 30659243Sobrienstatic moduledata_t svr4_elf_mod = { 307100616Smp "svr4elf", 30859243Sobrien svr4_elf_modevent, 309167465Smp 0 31059243Sobrien}; 311167465SmpDECLARE_MODULE(svr4elf, svr4_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY); 31259243SobrienMODULE_DEPEND(svr4elf, streams, 1, 1, 1); 31359243Sobrien