svr4_sysvec.c revision 177127
1139743Simp/*-
249267Snewton * Copyright (c) 1998 Mark Newton
349267Snewton * All rights reserved.
449267Snewton *
549267Snewton * Redistribution and use in source and binary forms, with or without
649267Snewton * modification, are permitted provided that the following conditions
749267Snewton * are met:
849267Snewton * 1. Redistributions of source code must retain the above copyright
949267Snewton *    notice, this list of conditions and the following disclaimer.
1049267Snewton * 2. Redistributions in binary form must reproduce the above copyright
1149267Snewton *    notice, this list of conditions and the following disclaimer in the
1249267Snewton *    documentation and/or other materials provided with the distribution.
1349267Snewton * 3. All advertising materials mentioning features or use of this software
1449267Snewton *    must display the following acknowledgement:
1549267Snewton *      This product includes software developed by Christos Zoulas.
1649267Snewton * 4. The name of the author may not be used to endorse or promote products
1749267Snewton *    derived from this software without specific prior written permission.
1849267Snewton *
1949267Snewton * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2049267Snewton * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2149267Snewton * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2249267Snewton * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2349267Snewton * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2449267Snewton * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2549267Snewton * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2649267Snewton * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2749267Snewton * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2849267Snewton * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2949267Snewton */
3049267Snewton
31116174Sobrien#include <sys/cdefs.h>
32116174Sobrien__FBSDID("$FreeBSD: head/sys/compat/svr4/svr4_sysvec.c 177127 2008-03-12 22:17:06Z jeff $");
33116174Sobrien
3443412Snewton/* XXX we use functions that might not exist. */
3543412Snewton#include "opt_compat.h"
3643412Snewton
3743412Snewton#ifndef COMPAT_43
3843412Snewton#error "Unable to compile SVR4-emulator due to missing COMPAT_43 option!"
3943412Snewton#endif
4043412Snewton
4143412Snewton#include <sys/param.h>
4248503Sgreen#include <sys/systm.h>
4343412Snewton#include <sys/proc.h>
4443412Snewton#include <sys/sysent.h>
4543412Snewton#include <sys/imgact.h>
4643412Snewton#include <sys/imgact_elf.h>
4794455Sjhb#include <sys/lock.h>
4843412Snewton#include <sys/malloc.h>
49141486Sjhb#include <sys/module.h>
5094455Sjhb#include <sys/mutex.h>
5143412Snewton#include <sys/namei.h>
52141486Sjhb#include <sys/socket.h>
53141486Sjhb#include <sys/syscallsubr.h>
5443412Snewton#include <sys/vnode.h>
5543412Snewton#include <vm/vm.h>
5643412Snewton#include <sys/exec.h>
5743412Snewton#include <sys/kernel.h>
5843412Snewton#include <machine/cpu.h>
5943412Snewton#include <netinet/in.h>
6043412Snewton
6165302Sobrien#include <compat/svr4/svr4.h>
6265302Sobrien#include <compat/svr4/svr4_types.h>
6365302Sobrien#include <compat/svr4/svr4_syscall.h>
6465302Sobrien#include <compat/svr4/svr4_signal.h>
65160558Sjhb#include <compat/svr4/svr4_socket.h>
6665302Sobrien#include <compat/svr4/svr4_sockio.h>
6765302Sobrien#include <compat/svr4/svr4_errno.h>
6865302Sobrien#include <compat/svr4/svr4_proto.h>
6965302Sobrien#include <compat/svr4/svr4_siginfo.h>
7065302Sobrien#include <compat/svr4/svr4_util.h>
7143412Snewton
7243412Snewtonint bsd_to_svr4_errno[ELAST+1] = {
7343412Snewton        0,
7443412Snewton        SVR4_EPERM,
7543412Snewton        SVR4_ENOENT,
7643412Snewton        SVR4_ESRCH,
7743412Snewton        SVR4_EINTR,
7843412Snewton        SVR4_EIO,
7943412Snewton        SVR4_ENXIO,
8043412Snewton        SVR4_E2BIG,
8143412Snewton        SVR4_ENOEXEC,
8243412Snewton        SVR4_EBADF,
8343412Snewton        SVR4_ECHILD,
8443412Snewton        SVR4_EDEADLK,
8543412Snewton        SVR4_ENOMEM,
8643412Snewton        SVR4_EACCES,
8743412Snewton        SVR4_EFAULT,
8843412Snewton        SVR4_ENOTBLK,
8943412Snewton        SVR4_EBUSY,
9043412Snewton        SVR4_EEXIST,
9143412Snewton        SVR4_EXDEV,
9243412Snewton        SVR4_ENODEV,
9343412Snewton        SVR4_ENOTDIR,
9443412Snewton        SVR4_EISDIR,
9543412Snewton        SVR4_EINVAL,
9643412Snewton        SVR4_ENFILE,
9743412Snewton        SVR4_EMFILE,
9843412Snewton        SVR4_ENOTTY,
9943412Snewton        SVR4_ETXTBSY,
10043412Snewton        SVR4_EFBIG,
10143412Snewton        SVR4_ENOSPC,
10243412Snewton        SVR4_ESPIPE,
10343412Snewton        SVR4_EROFS,
10443412Snewton        SVR4_EMLINK,
10543412Snewton        SVR4_EPIPE,
10643412Snewton        SVR4_EDOM,
10743412Snewton        SVR4_ERANGE,
10843412Snewton        SVR4_EAGAIN,
10943412Snewton        SVR4_EINPROGRESS,
11043412Snewton        SVR4_EALREADY,
11143412Snewton        SVR4_ENOTSOCK,
11243412Snewton        SVR4_EDESTADDRREQ,
11343412Snewton        SVR4_EMSGSIZE,
11443412Snewton        SVR4_EPROTOTYPE,
11543412Snewton        SVR4_ENOPROTOOPT,
11643412Snewton        SVR4_EPROTONOSUPPORT,
11743412Snewton        SVR4_ESOCKTNOSUPPORT,
11843412Snewton        SVR4_EOPNOTSUPP,
11943412Snewton        SVR4_EPFNOSUPPORT,
12043412Snewton        SVR4_EAFNOSUPPORT,
12143412Snewton        SVR4_EADDRINUSE,
12243412Snewton        SVR4_EADDRNOTAVAIL,
12343412Snewton        SVR4_ENETDOWN,
12443412Snewton        SVR4_ENETUNREACH,
12543412Snewton        SVR4_ENETRESET,
12643412Snewton        SVR4_ECONNABORTED,
12743412Snewton        SVR4_ECONNRESET,
12843412Snewton        SVR4_ENOBUFS,
12943412Snewton        SVR4_EISCONN,
13043412Snewton        SVR4_ENOTCONN,
13143412Snewton        SVR4_ESHUTDOWN,
13243412Snewton        SVR4_ETOOMANYREFS,
13343412Snewton        SVR4_ETIMEDOUT,
13443412Snewton        SVR4_ECONNREFUSED,
13543412Snewton        SVR4_ELOOP,
13643412Snewton        SVR4_ENAMETOOLONG,
13743412Snewton        SVR4_EHOSTDOWN,
13843412Snewton        SVR4_EHOSTUNREACH,
13943412Snewton        SVR4_ENOTEMPTY,
14043412Snewton        SVR4_EPROCLIM,
14143412Snewton        SVR4_EUSERS,
14243412Snewton        SVR4_EDQUOT,
14343412Snewton        SVR4_ESTALE,
14443412Snewton        SVR4_EREMOTE,
14543412Snewton        SVR4_EBADRPC,
14643412Snewton        SVR4_ERPCMISMATCH,
14743412Snewton        SVR4_EPROGUNAVAIL,
14843412Snewton        SVR4_EPROGMISMATCH,
14943412Snewton        SVR4_EPROCUNAVAIL,
15043412Snewton        SVR4_ENOLCK,
15143412Snewton        SVR4_ENOSYS,
15243412Snewton        SVR4_EFTYPE,
15343412Snewton        SVR4_EAUTH,
15443412Snewton        SVR4_ENEEDAUTH,
15543412Snewton        SVR4_EIDRM,
15643412Snewton        SVR4_ENOMSG,
15743412Snewton};
15843412Snewton
15943412Snewton
16059342Sobrienstatic int 	svr4_fixup(register_t **stack_base, struct image_params *imgp);
16143412Snewton
16243412Snewtonextern struct sysent svr4_sysent[];
16343412Snewton#undef szsigcode
16443412Snewton#undef sigcode
16543412Snewton
16643412Snewtonextern int svr4_szsigcode;
16743412Snewtonextern char svr4_sigcode[];
16843412Snewton
16943412Snewtonstruct sysentvec svr4_sysvec = {
17043412Snewton  SVR4_SYS_MAXSYSCALL,
17143412Snewton  svr4_sysent,
17243412Snewton  0xff,
173142500Ssam  SVR4_NSIG-1,		/* NB: signal trans table indexed with signno-1 */
174142500Ssam  bsd_to_svr4_sig+1,
17543412Snewton  ELAST,  /* ELAST */
17643412Snewton  bsd_to_svr4_errno,
177102808Sjake  NULL,
17843412Snewton  svr4_fixup,
17943412Snewton  svr4_sendsig,
18043412Snewton  svr4_sigcode,
18143412Snewton  &svr4_szsigcode,
18249267Snewton  NULL,
18349267Snewton  "SVR4",
184100384Speter  elf32_coredump,
18568520Smarcel  NULL,
186102808Sjake  SVR4_MINSIGSTKSZ,
187102808Sjake  PAGE_SIZE,
188102808Sjake  VM_MIN_ADDRESS,
189102808Sjake  VM_MAXUSER_ADDRESS,
190102808Sjake  USRSTACK,
191102808Sjake  PS_STRINGS,
192102808Sjake  VM_PROT_ALL,
193102808Sjake  exec_copyout_strings,
194120422Speter  exec_setregs,
195120422Speter  NULL
19643412Snewton};
19743412Snewton
198141486Sjhbconst char      svr4_emul_path[] = "/compat/svr4";
199141486Sjhb
20043412SnewtonElf32_Brandinfo svr4_brand = {
20199669Srobert  ELFOSABI_SYSV,
202100384Speter  EM_386,			/* XXX only implemented for x86 so far. */
20372999Sobrien  "SVR4",
20459342Sobrien  svr4_emul_path,
20543412Snewton  "/lib/libc.so.1",
206123742Speter  &svr4_sysvec,
207123742Speter  NULL,
20843412Snewton};
20943412Snewton
21043412Snewtonstatic int
21159342Sobriensvr4_fixup(register_t **stack_base, struct image_params *imgp)
21243412Snewton{
213112470Sjhb	Elf32_Auxargs *args;
21459342Sobrien	register_t *pos;
21543412Snewton
216177127Sjeff	KASSERT(curthread->td_proc == imgp->proc,
217112470Sjhb	    ("unsafe svr4_fixup(), should be curproc"));
218112470Sjhb	args = (Elf32_Auxargs *)imgp->auxargs;
219140992Ssobomax	pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);
22043412Snewton
221112470Sjhb	if (args->trace)
22243412Snewton		AUXARGS_ENTRY(pos, AT_DEBUG, 1);
223112470Sjhb	if (args->execfd != -1)
22443412Snewton		AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
22543412Snewton	AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
22643412Snewton	AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
22743412Snewton	AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
22843412Snewton	AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
22943412Snewton	AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
23043412Snewton	AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
23143412Snewton	AUXARGS_ENTRY(pos, AT_BASE, args->base);
23277183Srwatson	AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
23377183Srwatson	AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid);
23477183Srwatson	AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
23577183Srwatson	AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
23643412Snewton	AUXARGS_ENTRY(pos, AT_NULL, 0);
23743412Snewton
23843412Snewton	free(imgp->auxargs, M_TEMP);
23943412Snewton	imgp->auxargs = NULL;
24043412Snewton
24143412Snewton	(*stack_base)--;
242140992Ssobomax	**stack_base = (register_t)imgp->args->argc;
24343412Snewton	return 0;
24443412Snewton}
24543412Snewton
24643412Snewton/*
24743412Snewton * Search an alternate path before passing pathname arguments on
24872091Sasmodai * to system calls. Useful for keeping a separate 'emulation tree'.
24943412Snewton *
25043412Snewton * If cflag is set, we check if an attempt can be made to create
25143412Snewton * the named file, i.e. we check if the directory it should
25243412Snewton * be in exists.
25343412Snewton */
25443412Snewtonint
255141486Sjhbsvr4_emul_find(struct thread *td, char *path, enum uio_seg pathseg,
256141486Sjhb    char **pbuf, int create)
25743412Snewton{
25843412Snewton
259141486Sjhb	return (kern_alternate_path(td, svr4_emul_path, path, pathseg, pbuf,
260141486Sjhb	    create));
26143412Snewton}
26243412Snewton
26343412Snewtonstatic int
26443412Snewtonsvr4_elf_modevent(module_t mod, int type, void *data)
26543412Snewton{
26643412Snewton	int error;
26743412Snewton
26843412Snewton	error = 0;
26943412Snewton
27043412Snewton	switch(type) {
27143412Snewton	case MOD_LOAD:
272160558Sjhb		if (elf32_insert_brand_entry(&svr4_brand) < 0) {
273160558Sjhb			printf("cannot insert svr4 elf brand handler\n");
27443412Snewton			error = EINVAL;
275160558Sjhb			break;
276160558Sjhb		}
277160558Sjhb		if (bootverbose)
27843412Snewton			printf("svr4 ELF exec handler installed\n");
279160558Sjhb		svr4_sockcache_init();
28043412Snewton		break;
28143412Snewton	case MOD_UNLOAD:
28243597Snewton		/* Only allow the emulator to be removed if it isn't in use. */
283100384Speter		if (elf32_brand_inuse(&svr4_brand) != 0) {
28443597Snewton			error = EBUSY;
285100384Speter		} else if (elf32_remove_brand_entry(&svr4_brand) < 0) {
28643412Snewton			error = EINVAL;
28743597Snewton		}
28843597Snewton
289160558Sjhb		if (error) {
29043597Snewton			printf("Could not deinstall ELF interpreter entry (error %d)\n",
29143597Snewton			       error);
292160558Sjhb			break;
293160558Sjhb		}
294160558Sjhb		if (bootverbose)
29543412Snewton			printf("svr4 ELF exec handler removed\n");
296160558Sjhb		svr4_sockcache_destroy();
29743412Snewton		break;
29843412Snewton	default:
299132199Sphk		return (EOPNOTSUPP);
30043412Snewton		break;
30143412Snewton	}
30243412Snewton	return error;
30343412Snewton}
30443412Snewton
30543412Snewtonstatic moduledata_t svr4_elf_mod = {
30643412Snewton	"svr4elf",
30743412Snewton	svr4_elf_modevent,
30843412Snewton	0
30943412Snewton};
31043412SnewtonDECLARE_MODULE(svr4elf, svr4_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
31160060SgreenMODULE_DEPEND(svr4elf, streams, 1, 1, 1);
312