xref: /onnv-gate/usr/src/uts/common/brand/solaris10/s10_brand.c (revision 12808:eb600d5471d5)
110840SGerald.Jelinek@Sun.COM /*
210840SGerald.Jelinek@Sun.COM  * CDDL HEADER START
310840SGerald.Jelinek@Sun.COM  *
410840SGerald.Jelinek@Sun.COM  * The contents of this file are subject to the terms of the
510840SGerald.Jelinek@Sun.COM  * Common Development and Distribution License (the "License").
610840SGerald.Jelinek@Sun.COM  * You may not use this file except in compliance with the License.
710840SGerald.Jelinek@Sun.COM  *
810840SGerald.Jelinek@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910840SGerald.Jelinek@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1010840SGerald.Jelinek@Sun.COM  * See the License for the specific language governing permissions
1110840SGerald.Jelinek@Sun.COM  * and limitations under the License.
1210840SGerald.Jelinek@Sun.COM  *
1310840SGerald.Jelinek@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1410840SGerald.Jelinek@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510840SGerald.Jelinek@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1610840SGerald.Jelinek@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1710840SGerald.Jelinek@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1810840SGerald.Jelinek@Sun.COM  *
1910840SGerald.Jelinek@Sun.COM  * CDDL HEADER END
2010840SGerald.Jelinek@Sun.COM  */
2111798SRoger.Faulkner@Sun.COM 
2210840SGerald.Jelinek@Sun.COM /*
2312199Sgerald.jelinek@sun.com  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2410840SGerald.Jelinek@Sun.COM  */
2510840SGerald.Jelinek@Sun.COM 
2610840SGerald.Jelinek@Sun.COM #include <sys/errno.h>
2710840SGerald.Jelinek@Sun.COM #include <sys/exec.h>
2811315SJordan.Vaughan@Sun.com #include <sys/file.h>
2910840SGerald.Jelinek@Sun.COM #include <sys/kmem.h>
3010840SGerald.Jelinek@Sun.COM #include <sys/modctl.h>
3110840SGerald.Jelinek@Sun.COM #include <sys/model.h>
3210840SGerald.Jelinek@Sun.COM #include <sys/proc.h>
3310840SGerald.Jelinek@Sun.COM #include <sys/syscall.h>
3410840SGerald.Jelinek@Sun.COM #include <sys/systm.h>
3510840SGerald.Jelinek@Sun.COM #include <sys/thread.h>
3610840SGerald.Jelinek@Sun.COM #include <sys/cmn_err.h>
3710840SGerald.Jelinek@Sun.COM #include <sys/archsystm.h>
3810840SGerald.Jelinek@Sun.COM #include <sys/pathname.h>
3910840SGerald.Jelinek@Sun.COM #include <sys/sunddi.h>
4010840SGerald.Jelinek@Sun.COM 
4110840SGerald.Jelinek@Sun.COM #include <sys/machbrand.h>
4210840SGerald.Jelinek@Sun.COM #include <sys/brand.h>
4310840SGerald.Jelinek@Sun.COM #include "s10_brand.h"
4410840SGerald.Jelinek@Sun.COM 
4510840SGerald.Jelinek@Sun.COM char *s10_emulation_table = NULL;
4610840SGerald.Jelinek@Sun.COM 
4710840SGerald.Jelinek@Sun.COM void	s10_init_brand_data(zone_t *);
4810840SGerald.Jelinek@Sun.COM void	s10_free_brand_data(zone_t *);
4910840SGerald.Jelinek@Sun.COM void	s10_setbrand(proc_t *);
5010840SGerald.Jelinek@Sun.COM int	s10_getattr(zone_t *, int, void *, size_t *);
5110840SGerald.Jelinek@Sun.COM int	s10_setattr(zone_t *, int, void *, size_t);
5210840SGerald.Jelinek@Sun.COM int	s10_brandsys(int, int64_t *, uintptr_t, uintptr_t, uintptr_t,
5310840SGerald.Jelinek@Sun.COM 		uintptr_t, uintptr_t, uintptr_t);
5410840SGerald.Jelinek@Sun.COM void	s10_copy_procdata(proc_t *, proc_t *);
5510840SGerald.Jelinek@Sun.COM void	s10_proc_exit(struct proc *, klwp_t *);
5610840SGerald.Jelinek@Sun.COM void	s10_exec();
5710840SGerald.Jelinek@Sun.COM int	s10_initlwp(klwp_t *);
5810840SGerald.Jelinek@Sun.COM void	s10_forklwp(klwp_t *, klwp_t *);
5910840SGerald.Jelinek@Sun.COM void	s10_freelwp(klwp_t *);
6010840SGerald.Jelinek@Sun.COM void	s10_lwpexit(klwp_t *);
6110840SGerald.Jelinek@Sun.COM int	s10_elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int,
6210840SGerald.Jelinek@Sun.COM 	long *, int, caddr_t, cred_t *, int);
6311970SRoger.Faulkner@Sun.COM void	s10_sigset_native_to_s10(sigset_t *);
6411970SRoger.Faulkner@Sun.COM void	s10_sigset_s10_to_native(sigset_t *);
6510840SGerald.Jelinek@Sun.COM 
6610840SGerald.Jelinek@Sun.COM /* s10 brand */
6710840SGerald.Jelinek@Sun.COM struct brand_ops s10_brops = {
6810840SGerald.Jelinek@Sun.COM 	s10_init_brand_data,
6910840SGerald.Jelinek@Sun.COM 	s10_free_brand_data,
7010840SGerald.Jelinek@Sun.COM 	s10_brandsys,
7110840SGerald.Jelinek@Sun.COM 	s10_setbrand,
7210840SGerald.Jelinek@Sun.COM 	s10_getattr,
7310840SGerald.Jelinek@Sun.COM 	s10_setattr,
7410840SGerald.Jelinek@Sun.COM 	s10_copy_procdata,
7510840SGerald.Jelinek@Sun.COM 	s10_proc_exit,
7610840SGerald.Jelinek@Sun.COM 	s10_exec,
7710840SGerald.Jelinek@Sun.COM 	lwp_setrval,
7810840SGerald.Jelinek@Sun.COM 	s10_initlwp,
7910840SGerald.Jelinek@Sun.COM 	s10_forklwp,
8010840SGerald.Jelinek@Sun.COM 	s10_freelwp,
8110840SGerald.Jelinek@Sun.COM 	s10_lwpexit,
8211940SRoger.Faulkner@Sun.COM 	s10_elfexec,
8311970SRoger.Faulkner@Sun.COM 	s10_sigset_native_to_s10,
8411970SRoger.Faulkner@Sun.COM 	s10_sigset_s10_to_native,
8511970SRoger.Faulkner@Sun.COM 	S10_NSIG,
8610840SGerald.Jelinek@Sun.COM };
8710840SGerald.Jelinek@Sun.COM 
8810840SGerald.Jelinek@Sun.COM #ifdef	sparc
8910840SGerald.Jelinek@Sun.COM 
9010840SGerald.Jelinek@Sun.COM struct brand_mach_ops s10_mops = {
9110840SGerald.Jelinek@Sun.COM 	s10_brand_syscall_callback,
9210840SGerald.Jelinek@Sun.COM 	s10_brand_syscall32_callback
9310840SGerald.Jelinek@Sun.COM };
9410840SGerald.Jelinek@Sun.COM 
9510840SGerald.Jelinek@Sun.COM #else	/* sparc */
9610840SGerald.Jelinek@Sun.COM 
9710840SGerald.Jelinek@Sun.COM #ifdef	__amd64
9810840SGerald.Jelinek@Sun.COM 
9910840SGerald.Jelinek@Sun.COM struct brand_mach_ops s10_mops = {
10010840SGerald.Jelinek@Sun.COM 	s10_brand_sysenter_callback,
10110840SGerald.Jelinek@Sun.COM 	s10_brand_int91_callback,
10210840SGerald.Jelinek@Sun.COM 	s10_brand_syscall_callback,
10312613SSurya.Prakki@Sun.COM 	s10_brand_syscall32_callback
10410840SGerald.Jelinek@Sun.COM };
10510840SGerald.Jelinek@Sun.COM 
10610840SGerald.Jelinek@Sun.COM #else	/* ! __amd64 */
10710840SGerald.Jelinek@Sun.COM 
10810840SGerald.Jelinek@Sun.COM struct brand_mach_ops s10_mops = {
10910840SGerald.Jelinek@Sun.COM 	s10_brand_sysenter_callback,
11010840SGerald.Jelinek@Sun.COM 	NULL,
11110840SGerald.Jelinek@Sun.COM 	s10_brand_syscall_callback,
11210840SGerald.Jelinek@Sun.COM 	NULL
11310840SGerald.Jelinek@Sun.COM };
11410840SGerald.Jelinek@Sun.COM #endif	/* __amd64 */
11510840SGerald.Jelinek@Sun.COM 
11610840SGerald.Jelinek@Sun.COM #endif	/* _sparc */
11710840SGerald.Jelinek@Sun.COM 
11810840SGerald.Jelinek@Sun.COM struct brand	s10_brand = {
11910840SGerald.Jelinek@Sun.COM 	BRAND_VER_1,
12010840SGerald.Jelinek@Sun.COM 	"solaris10",
12110840SGerald.Jelinek@Sun.COM 	&s10_brops,
12210840SGerald.Jelinek@Sun.COM 	&s10_mops
12310840SGerald.Jelinek@Sun.COM };
12410840SGerald.Jelinek@Sun.COM 
12510840SGerald.Jelinek@Sun.COM static struct modlbrand modlbrand = {
12610840SGerald.Jelinek@Sun.COM 	&mod_brandops,		/* type of module */
12710840SGerald.Jelinek@Sun.COM 	"Solaris 10 Brand",	/* description of module */
12810840SGerald.Jelinek@Sun.COM 	&s10_brand		/* driver ops */
12910840SGerald.Jelinek@Sun.COM };
13010840SGerald.Jelinek@Sun.COM 
13110840SGerald.Jelinek@Sun.COM static struct modlinkage modlinkage = {
13210840SGerald.Jelinek@Sun.COM 	MODREV_1, (void *)&modlbrand, NULL
13310840SGerald.Jelinek@Sun.COM };
13410840SGerald.Jelinek@Sun.COM 
13510840SGerald.Jelinek@Sun.COM void
s10_setbrand(proc_t * p)13610840SGerald.Jelinek@Sun.COM s10_setbrand(proc_t *p)
13710840SGerald.Jelinek@Sun.COM {
13812199Sgerald.jelinek@sun.com 	brand_solaris_setbrand(p, &s10_brand);
13910840SGerald.Jelinek@Sun.COM }
14010840SGerald.Jelinek@Sun.COM 
14110840SGerald.Jelinek@Sun.COM /*ARGSUSED*/
14210840SGerald.Jelinek@Sun.COM int
s10_getattr(zone_t * zone,int attr,void * buf,size_t * bufsize)14310840SGerald.Jelinek@Sun.COM s10_getattr(zone_t *zone, int attr, void *buf, size_t *bufsize)
14410840SGerald.Jelinek@Sun.COM {
14510840SGerald.Jelinek@Sun.COM 	ASSERT(zone->zone_brand == &s10_brand);
14610963SJordan.Vaughan@Sun.com 	if (attr == S10_EMUL_BITMAP) {
14710963SJordan.Vaughan@Sun.com 		if (buf == NULL || *bufsize != sizeof (s10_emul_bitmap_t))
14810963SJordan.Vaughan@Sun.com 			return (EINVAL);
14910963SJordan.Vaughan@Sun.com 		if (copyout(((s10_zone_data_t *)zone->zone_brand_data)->
15010963SJordan.Vaughan@Sun.com 		    emul_bitmap, buf, sizeof (s10_emul_bitmap_t)) != 0)
15110840SGerald.Jelinek@Sun.COM 			return (EFAULT);
15210840SGerald.Jelinek@Sun.COM 		return (0);
15310840SGerald.Jelinek@Sun.COM 	}
15410840SGerald.Jelinek@Sun.COM 
15510840SGerald.Jelinek@Sun.COM 	return (EINVAL);
15610840SGerald.Jelinek@Sun.COM }
15710840SGerald.Jelinek@Sun.COM 
15810840SGerald.Jelinek@Sun.COM int
s10_setattr(zone_t * zone,int attr,void * buf,size_t bufsize)15910840SGerald.Jelinek@Sun.COM s10_setattr(zone_t *zone, int attr, void *buf, size_t bufsize)
16010840SGerald.Jelinek@Sun.COM {
16110840SGerald.Jelinek@Sun.COM 	ASSERT(zone->zone_brand == &s10_brand);
16210963SJordan.Vaughan@Sun.com 	if (attr == S10_EMUL_BITMAP) {
16310963SJordan.Vaughan@Sun.com 		if (buf == NULL || bufsize != sizeof (s10_emul_bitmap_t))
16410963SJordan.Vaughan@Sun.com 			return (EINVAL);
16510963SJordan.Vaughan@Sun.com 		if (copyin(buf, ((s10_zone_data_t *)zone->zone_brand_data)->
16610963SJordan.Vaughan@Sun.com 		    emul_bitmap, sizeof (s10_emul_bitmap_t)) != 0)
16710840SGerald.Jelinek@Sun.COM 			return (EFAULT);
16810840SGerald.Jelinek@Sun.COM 		return (0);
16910840SGerald.Jelinek@Sun.COM 	}
17010840SGerald.Jelinek@Sun.COM 
17110840SGerald.Jelinek@Sun.COM 	return (EINVAL);
17210840SGerald.Jelinek@Sun.COM }
17310840SGerald.Jelinek@Sun.COM 
17410840SGerald.Jelinek@Sun.COM #ifdef	__amd64
17510840SGerald.Jelinek@Sun.COM /*
17610840SGerald.Jelinek@Sun.COM  * The Nevada kernel clears %fs for threads in 64-bit x86 processes but S10's
17710840SGerald.Jelinek@Sun.COM  * libc expects %fs to be nonzero.  This causes some committed
17810840SGerald.Jelinek@Sun.COM  * libc/libthread interfaces (e.g., thr_main()) to fail, which impacts several
17910840SGerald.Jelinek@Sun.COM  * libraries, including libdoor.  This function sets the specified LWP's %fs
18010840SGerald.Jelinek@Sun.COM  * register to the legacy S10 selector value (LWPFS_SEL).
18110840SGerald.Jelinek@Sun.COM  *
18210840SGerald.Jelinek@Sun.COM  * The best solution to the aforementioned problem is backporting CRs
18310840SGerald.Jelinek@Sun.COM  * 6467491 to Solaris 10 so that 64-bit x86 Solaris 10 processes
18410840SGerald.Jelinek@Sun.COM  * would accept zero for %fs.  Backporting the CRs is a requirement for running
18510840SGerald.Jelinek@Sun.COM  * S10 Containers in PV domUs because 64-bit Xen clears %fsbase when %fs is
18610840SGerald.Jelinek@Sun.COM  * nonzero.  Such behavior breaks 64-bit processes because Xen has to fetch the
18710840SGerald.Jelinek@Sun.COM  * FS segments' base addresses from the LWPs' GDTs, which are only capable of
18810840SGerald.Jelinek@Sun.COM  * 32-bit addressing.
18910840SGerald.Jelinek@Sun.COM  */
19010840SGerald.Jelinek@Sun.COM /*ARGSUSED*/
19110840SGerald.Jelinek@Sun.COM static void
s10_amd64_correct_fsreg(klwp_t * l)19210840SGerald.Jelinek@Sun.COM s10_amd64_correct_fsreg(klwp_t *l)
19310840SGerald.Jelinek@Sun.COM {
19410840SGerald.Jelinek@Sun.COM 	if (lwp_getdatamodel(l) == DATAMODEL_NATIVE) {
19510840SGerald.Jelinek@Sun.COM 		kpreempt_disable();
19610840SGerald.Jelinek@Sun.COM 		l->lwp_pcb.pcb_fs = LWPFS_SEL;
19710840SGerald.Jelinek@Sun.COM 		l->lwp_pcb.pcb_rupdate = 1;
19810840SGerald.Jelinek@Sun.COM 		lwptot(l)->t_post_sys = 1;	/* Guarantee update_sregs() */
19910840SGerald.Jelinek@Sun.COM 		kpreempt_enable();
20010840SGerald.Jelinek@Sun.COM 	}
20110840SGerald.Jelinek@Sun.COM }
20210840SGerald.Jelinek@Sun.COM #endif	/* __amd64 */
20310840SGerald.Jelinek@Sun.COM 
20412760Sgerald.jelinek@sun.com /*
205*12808Sgerald.jelinek@sun.com  * Native processes are started with the native ld.so.1 as the command.  This
206*12808Sgerald.jelinek@sun.com  * brand op is invoked by s10_npreload to fix up the command and arguments
207*12808Sgerald.jelinek@sun.com  * so that apps like pgrep or ps see the expected command strings.
20812760Sgerald.jelinek@sun.com  */
20910840SGerald.Jelinek@Sun.COM int
s10_native(void * cmd,void * args)210*12808Sgerald.jelinek@sun.com s10_native(void *cmd, void *args)
21110840SGerald.Jelinek@Sun.COM {
21210840SGerald.Jelinek@Sun.COM 	struct user	*up = PTOU(curproc);
213*12808Sgerald.jelinek@sun.com 	char		cmd_buf[MAXCOMLEN + 1];
214*12808Sgerald.jelinek@sun.com 	char		arg_buf[PSARGSZ];
21510840SGerald.Jelinek@Sun.COM 
216*12808Sgerald.jelinek@sun.com 	if (copyin(cmd, &cmd_buf, sizeof (cmd_buf)) != 0)
217*12808Sgerald.jelinek@sun.com 		return (EFAULT);
218*12808Sgerald.jelinek@sun.com 	if (copyin(args, &arg_buf, sizeof (arg_buf)) != 0)
219*12808Sgerald.jelinek@sun.com 		return (EFAULT);
22010840SGerald.Jelinek@Sun.COM 
22110840SGerald.Jelinek@Sun.COM 	/*
22210840SGerald.Jelinek@Sun.COM 	 * Make sure that the process' interpreter is the native dynamic linker.
22310840SGerald.Jelinek@Sun.COM 	 * Convention dictates that native processes executing within solaris10-
22410840SGerald.Jelinek@Sun.COM 	 * branded zones are interpreted by the native dynamic linker (the
22510840SGerald.Jelinek@Sun.COM 	 * process and its arguments are specified as arguments to the dynamic
22610840SGerald.Jelinek@Sun.COM 	 * linker).  If this convention is violated (i.e.,
22710840SGerald.Jelinek@Sun.COM 	 * brandsys(B_S10_NATIVE, ...) is invoked by a process that shouldn't be
22810840SGerald.Jelinek@Sun.COM 	 * native), then do nothing and silently indicate success.
22910840SGerald.Jelinek@Sun.COM 	 */
23010840SGerald.Jelinek@Sun.COM 	if (strcmp(up->u_comm, S10_LINKER_NAME) != 0)
23110840SGerald.Jelinek@Sun.COM 		return (0);
232*12808Sgerald.jelinek@sun.com 
233*12808Sgerald.jelinek@sun.com 	/*
234*12808Sgerald.jelinek@sun.com 	 * The sizeof has an extra value for the trailing '\0' so this covers
235*12808Sgerald.jelinek@sun.com 	 * the appended " " in the following strcmps.
236*12808Sgerald.jelinek@sun.com 	 */
237*12808Sgerald.jelinek@sun.com 	if (strncmp(up->u_psargs, BRAND_NATIVE_LINKER64 " ",
238*12808Sgerald.jelinek@sun.com 	    sizeof (BRAND_NATIVE_LINKER64)) != 0 &&
239*12808Sgerald.jelinek@sun.com 	    strncmp(up->u_psargs, BRAND_NATIVE_LINKER32 " ",
240*12808Sgerald.jelinek@sun.com 	    sizeof (BRAND_NATIVE_LINKER32)) != 0)
24110840SGerald.Jelinek@Sun.COM 		return (0);
24210840SGerald.Jelinek@Sun.COM 
243*12808Sgerald.jelinek@sun.com 	mutex_enter(&curproc->p_lock);
244*12808Sgerald.jelinek@sun.com 	(void) strlcpy(up->u_comm, cmd_buf, sizeof (up->u_comm));
245*12808Sgerald.jelinek@sun.com 	(void) strlcpy(up->u_psargs, arg_buf, sizeof (up->u_psargs));
246*12808Sgerald.jelinek@sun.com 	mutex_exit(&curproc->p_lock);
24710840SGerald.Jelinek@Sun.COM 
24810840SGerald.Jelinek@Sun.COM 	return (0);
24910840SGerald.Jelinek@Sun.COM }
25010840SGerald.Jelinek@Sun.COM 
25110840SGerald.Jelinek@Sun.COM /*ARGSUSED*/
25210840SGerald.Jelinek@Sun.COM int
s10_brandsys(int cmd,int64_t * rval,uintptr_t arg1,uintptr_t arg2,uintptr_t arg3,uintptr_t arg4,uintptr_t arg5,uintptr_t arg6)25310840SGerald.Jelinek@Sun.COM s10_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2,
25410840SGerald.Jelinek@Sun.COM     uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6)
25510840SGerald.Jelinek@Sun.COM {
25612199Sgerald.jelinek@sun.com 	proc_t	*p = curproc;
25712199Sgerald.jelinek@sun.com 	int	res;
25810840SGerald.Jelinek@Sun.COM 
25910840SGerald.Jelinek@Sun.COM 	*rval = 0;
26010840SGerald.Jelinek@Sun.COM 
26110840SGerald.Jelinek@Sun.COM 	if (cmd == B_S10_NATIVE)
262*12808Sgerald.jelinek@sun.com 		return (s10_native((void *)arg1, (void *)arg2));
26310840SGerald.Jelinek@Sun.COM 
26412199Sgerald.jelinek@sun.com 	res = brand_solaris_cmd(cmd, arg1, arg2, arg3, &s10_brand, S10_VERSION);
26512199Sgerald.jelinek@sun.com 	if (res >= 0)
26612199Sgerald.jelinek@sun.com 		return (res);
26710840SGerald.Jelinek@Sun.COM 
26812199Sgerald.jelinek@sun.com 	switch ((cmd)) {
26910840SGerald.Jelinek@Sun.COM 	case B_S10_PIDINFO:
27010840SGerald.Jelinek@Sun.COM 		/*
27110840SGerald.Jelinek@Sun.COM 		 * The s10 brand needs to be able to get the pid of the
27210840SGerald.Jelinek@Sun.COM 		 * current process and the pid of the zone's init, and it
27310840SGerald.Jelinek@Sun.COM 		 * needs to do this on every process startup.  Early in
27410840SGerald.Jelinek@Sun.COM 		 * brand startup, we can't call getpid() because calls to
27510840SGerald.Jelinek@Sun.COM 		 * getpid() represent a magical signal to some old-skool
27610840SGerald.Jelinek@Sun.COM 		 * debuggers.  By merging all of this into one call, we
27710840SGerald.Jelinek@Sun.COM 		 * make this quite a bit cheaper and easier to handle in
27810840SGerald.Jelinek@Sun.COM 		 * the brand module.
27910840SGerald.Jelinek@Sun.COM 		 */
28010840SGerald.Jelinek@Sun.COM 		if (copyout(&p->p_pid, (void *)arg1, sizeof (pid_t)) != 0)
28110840SGerald.Jelinek@Sun.COM 			return (EFAULT);
28210840SGerald.Jelinek@Sun.COM 		if (copyout(&p->p_zone->zone_proc_initpid, (void *)arg2,
28310840SGerald.Jelinek@Sun.COM 		    sizeof (pid_t)) != 0)
28410840SGerald.Jelinek@Sun.COM 			return (EFAULT);
28510840SGerald.Jelinek@Sun.COM 		return (0);
28610840SGerald.Jelinek@Sun.COM 
28711315SJordan.Vaughan@Sun.com 	case B_S10_ISFDXATTRDIR: {
28811315SJordan.Vaughan@Sun.com 		/*
28911315SJordan.Vaughan@Sun.com 		 * This subcommand enables the userland brand emulation library
29011315SJordan.Vaughan@Sun.com 		 * to determine whether a file descriptor refers to an extended
29111315SJordan.Vaughan@Sun.com 		 * file attributes directory.  There is no standard syscall or
29211315SJordan.Vaughan@Sun.com 		 * libc function that can make such a determination.
29311315SJordan.Vaughan@Sun.com 		 */
29411315SJordan.Vaughan@Sun.com 		file_t *dir_filep;
29511315SJordan.Vaughan@Sun.com 
29611315SJordan.Vaughan@Sun.com 		dir_filep = getf((int)arg1);
29711315SJordan.Vaughan@Sun.com 		if (dir_filep == NULL)
29811315SJordan.Vaughan@Sun.com 			return (EBADF);
29911315SJordan.Vaughan@Sun.com 		ASSERT(dir_filep->f_vnode != NULL);
30011315SJordan.Vaughan@Sun.com 		*rval = IS_XATTRDIR(dir_filep->f_vnode);
30111315SJordan.Vaughan@Sun.com 		releasef((int)arg1);
30211315SJordan.Vaughan@Sun.com 		return (0);
30311315SJordan.Vaughan@Sun.com 	}
30411315SJordan.Vaughan@Sun.com 
30510840SGerald.Jelinek@Sun.COM #ifdef	__amd64
30610840SGerald.Jelinek@Sun.COM 	case B_S10_FSREGCORRECTION:
30710840SGerald.Jelinek@Sun.COM 		/*
30810840SGerald.Jelinek@Sun.COM 		 * This subcommand exists so that the SYS_lwp_private and
30910840SGerald.Jelinek@Sun.COM 		 * SYS_lwp_create syscalls can manually set the current thread's
31010840SGerald.Jelinek@Sun.COM 		 * %fs register to the legacy S10 selector value for 64-bit x86
31110840SGerald.Jelinek@Sun.COM 		 * processes.
31210840SGerald.Jelinek@Sun.COM 		 */
31310840SGerald.Jelinek@Sun.COM 		s10_amd64_correct_fsreg(ttolwp(curthread));
31410840SGerald.Jelinek@Sun.COM 		return (0);
31510840SGerald.Jelinek@Sun.COM #endif	/* __amd64 */
31610840SGerald.Jelinek@Sun.COM 	}
31710840SGerald.Jelinek@Sun.COM 
31810840SGerald.Jelinek@Sun.COM 	return (EINVAL);
31910840SGerald.Jelinek@Sun.COM }
32010840SGerald.Jelinek@Sun.COM 
32110840SGerald.Jelinek@Sun.COM void
s10_copy_procdata(proc_t * child,proc_t * parent)32210840SGerald.Jelinek@Sun.COM s10_copy_procdata(proc_t *child, proc_t *parent)
32310840SGerald.Jelinek@Sun.COM {
32412199Sgerald.jelinek@sun.com 	brand_solaris_copy_procdata(child, parent, &s10_brand);
32510840SGerald.Jelinek@Sun.COM }
32610840SGerald.Jelinek@Sun.COM 
32710840SGerald.Jelinek@Sun.COM void
s10_proc_exit(struct proc * p,klwp_t * l)32810840SGerald.Jelinek@Sun.COM s10_proc_exit(struct proc *p, klwp_t *l)
32910840SGerald.Jelinek@Sun.COM {
33012199Sgerald.jelinek@sun.com 	brand_solaris_proc_exit(p, l, &s10_brand);
33110840SGerald.Jelinek@Sun.COM }
33210840SGerald.Jelinek@Sun.COM 
33310840SGerald.Jelinek@Sun.COM void
s10_exec()33410840SGerald.Jelinek@Sun.COM s10_exec()
33510840SGerald.Jelinek@Sun.COM {
33612199Sgerald.jelinek@sun.com 	brand_solaris_exec(&s10_brand);
33710840SGerald.Jelinek@Sun.COM }
33810840SGerald.Jelinek@Sun.COM 
33910840SGerald.Jelinek@Sun.COM int
s10_initlwp(klwp_t * l)34010840SGerald.Jelinek@Sun.COM s10_initlwp(klwp_t *l)
34110840SGerald.Jelinek@Sun.COM {
34212199Sgerald.jelinek@sun.com 	return (brand_solaris_initlwp(l, &s10_brand));
34310840SGerald.Jelinek@Sun.COM }
34410840SGerald.Jelinek@Sun.COM 
34510840SGerald.Jelinek@Sun.COM void
s10_forklwp(klwp_t * p,klwp_t * c)34610840SGerald.Jelinek@Sun.COM s10_forklwp(klwp_t *p, klwp_t *c)
34710840SGerald.Jelinek@Sun.COM {
34812199Sgerald.jelinek@sun.com 	brand_solaris_forklwp(p, c, &s10_brand);
34910840SGerald.Jelinek@Sun.COM 
35010840SGerald.Jelinek@Sun.COM #ifdef	__amd64
35110840SGerald.Jelinek@Sun.COM 	/*
35210840SGerald.Jelinek@Sun.COM 	 * Only correct the child's %fs register if the parent's %fs register
35310840SGerald.Jelinek@Sun.COM 	 * is LWPFS_SEL.  If the parent's %fs register is zero, then the Solaris
35410840SGerald.Jelinek@Sun.COM 	 * 10 environment that we're emulating uses a version of libc that
35510840SGerald.Jelinek@Sun.COM 	 * works when %fs is zero (i.e., it contains backports of CRs 6467491
35610840SGerald.Jelinek@Sun.COM 	 * and 6501650).
35710840SGerald.Jelinek@Sun.COM 	 */
35810840SGerald.Jelinek@Sun.COM 	if (p->lwp_pcb.pcb_fs == LWPFS_SEL)
35910840SGerald.Jelinek@Sun.COM 		s10_amd64_correct_fsreg(c);
36010840SGerald.Jelinek@Sun.COM #endif	/* __amd64 */
36110840SGerald.Jelinek@Sun.COM }
36210840SGerald.Jelinek@Sun.COM 
36310840SGerald.Jelinek@Sun.COM void
s10_freelwp(klwp_t * l)36410840SGerald.Jelinek@Sun.COM s10_freelwp(klwp_t *l)
36510840SGerald.Jelinek@Sun.COM {
36612199Sgerald.jelinek@sun.com 	brand_solaris_freelwp(l, &s10_brand);
36710840SGerald.Jelinek@Sun.COM }
36810840SGerald.Jelinek@Sun.COM 
36910840SGerald.Jelinek@Sun.COM void
s10_lwpexit(klwp_t * l)37010840SGerald.Jelinek@Sun.COM s10_lwpexit(klwp_t *l)
37110840SGerald.Jelinek@Sun.COM {
37212199Sgerald.jelinek@sun.com 	brand_solaris_lwpexit(l, &s10_brand);
37310840SGerald.Jelinek@Sun.COM }
37410840SGerald.Jelinek@Sun.COM 
37510840SGerald.Jelinek@Sun.COM void
s10_free_brand_data(zone_t * zone)37610840SGerald.Jelinek@Sun.COM s10_free_brand_data(zone_t *zone)
37710840SGerald.Jelinek@Sun.COM {
37810840SGerald.Jelinek@Sun.COM 	kmem_free(zone->zone_brand_data, sizeof (s10_zone_data_t));
37910840SGerald.Jelinek@Sun.COM }
38010840SGerald.Jelinek@Sun.COM 
38110840SGerald.Jelinek@Sun.COM void
s10_init_brand_data(zone_t * zone)38210840SGerald.Jelinek@Sun.COM s10_init_brand_data(zone_t *zone)
38310840SGerald.Jelinek@Sun.COM {
38410840SGerald.Jelinek@Sun.COM 	ASSERT(zone->zone_brand == &s10_brand);
38510840SGerald.Jelinek@Sun.COM 	ASSERT(zone->zone_brand_data == NULL);
38610963SJordan.Vaughan@Sun.com 	zone->zone_brand_data = kmem_zalloc(sizeof (s10_zone_data_t), KM_SLEEP);
38710840SGerald.Jelinek@Sun.COM }
38810840SGerald.Jelinek@Sun.COM 
38910840SGerald.Jelinek@Sun.COM int
s10_elfexec(vnode_t * vp,execa_t * uap,uarg_t * args,intpdata_t * idatap,int level,long * execsz,int setid,caddr_t exec_file,cred_t * cred,int brand_action)39010840SGerald.Jelinek@Sun.COM s10_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap,
39110840SGerald.Jelinek@Sun.COM 	int level, long *execsz, int setid, caddr_t exec_file, cred_t *cred,
39210840SGerald.Jelinek@Sun.COM 	int brand_action)
39310840SGerald.Jelinek@Sun.COM {
39412199Sgerald.jelinek@sun.com 	return (brand_solaris_elfexec(vp, uap, args, idatap, level, execsz,
39512199Sgerald.jelinek@sun.com 	    setid, exec_file, cred, brand_action, &s10_brand, S10_BRANDNAME,
39612199Sgerald.jelinek@sun.com 	    S10_LIB, S10_LIB32, S10_LINKER, S10_LINKER32));
39710840SGerald.Jelinek@Sun.COM }
39810840SGerald.Jelinek@Sun.COM 
39911970SRoger.Faulkner@Sun.COM void
s10_sigset_native_to_s10(sigset_t * set)40011970SRoger.Faulkner@Sun.COM s10_sigset_native_to_s10(sigset_t *set)
40111970SRoger.Faulkner@Sun.COM {
40211970SRoger.Faulkner@Sun.COM 	int nativesig;
40311970SRoger.Faulkner@Sun.COM 	int s10sig;
40411970SRoger.Faulkner@Sun.COM 	sigset_t s10set;
40511970SRoger.Faulkner@Sun.COM 
40611970SRoger.Faulkner@Sun.COM 	/*
40711970SRoger.Faulkner@Sun.COM 	 * Shortcut: we know the first 32 signals are the same in both
40811970SRoger.Faulkner@Sun.COM 	 * s10 and native Solaris.  Just assign the first word.
40911970SRoger.Faulkner@Sun.COM 	 */
41011970SRoger.Faulkner@Sun.COM 	s10set.__sigbits[0] = set->__sigbits[0];
41111970SRoger.Faulkner@Sun.COM 	s10set.__sigbits[1] = 0;
41211970SRoger.Faulkner@Sun.COM 	s10set.__sigbits[2] = 0;
41311970SRoger.Faulkner@Sun.COM 	s10set.__sigbits[3] = 0;
41411970SRoger.Faulkner@Sun.COM 
41511970SRoger.Faulkner@Sun.COM 	/*
41611970SRoger.Faulkner@Sun.COM 	 * Copy the remainder of the initial set of common signals.
41711970SRoger.Faulkner@Sun.COM 	 */
41811970SRoger.Faulkner@Sun.COM 	for (nativesig = 33; nativesig < S10_SIGRTMIN; nativesig++)
41911970SRoger.Faulkner@Sun.COM 		if (sigismember(set, nativesig))
42011970SRoger.Faulkner@Sun.COM 			sigaddset(&s10set, nativesig);
42111970SRoger.Faulkner@Sun.COM 
42211970SRoger.Faulkner@Sun.COM 	/*
42311970SRoger.Faulkner@Sun.COM 	 * Convert any native RT signals to their S10 values.
42411970SRoger.Faulkner@Sun.COM 	 */
42511970SRoger.Faulkner@Sun.COM 	for (nativesig = _SIGRTMIN, s10sig = S10_SIGRTMIN;
42611970SRoger.Faulkner@Sun.COM 	    nativesig <= _SIGRTMAX && s10sig <= S10_SIGRTMAX;
42711970SRoger.Faulkner@Sun.COM 	    nativesig++, s10sig++) {
42811970SRoger.Faulkner@Sun.COM 		if (sigismember(set, nativesig))
42911970SRoger.Faulkner@Sun.COM 			sigaddset(&s10set, s10sig);
43011970SRoger.Faulkner@Sun.COM 	}
43111970SRoger.Faulkner@Sun.COM 
43211970SRoger.Faulkner@Sun.COM 	*set = s10set;
43311970SRoger.Faulkner@Sun.COM }
43411970SRoger.Faulkner@Sun.COM 
43511970SRoger.Faulkner@Sun.COM void
s10_sigset_s10_to_native(sigset_t * set)43611970SRoger.Faulkner@Sun.COM s10_sigset_s10_to_native(sigset_t *set)
43711970SRoger.Faulkner@Sun.COM {
43811970SRoger.Faulkner@Sun.COM 	int s10sig;
43911970SRoger.Faulkner@Sun.COM 	int nativesig;
44011970SRoger.Faulkner@Sun.COM 	sigset_t nativeset;
44111970SRoger.Faulkner@Sun.COM 
44211970SRoger.Faulkner@Sun.COM 	/*
44311970SRoger.Faulkner@Sun.COM 	 * Shortcut: we know the first 32 signals are the same in both
44411970SRoger.Faulkner@Sun.COM 	 * s10 and native Solaris.  Just assign the first word.
44511970SRoger.Faulkner@Sun.COM 	 */
44611970SRoger.Faulkner@Sun.COM 	nativeset.__sigbits[0] = set->__sigbits[0];
44711970SRoger.Faulkner@Sun.COM 	nativeset.__sigbits[1] = 0;
44811970SRoger.Faulkner@Sun.COM 	nativeset.__sigbits[2] = 0;
44911970SRoger.Faulkner@Sun.COM 	nativeset.__sigbits[3] = 0;
45011970SRoger.Faulkner@Sun.COM 
45111970SRoger.Faulkner@Sun.COM 	/*
45211970SRoger.Faulkner@Sun.COM 	 * Copy the remainder of the initial set of common signals.
45311970SRoger.Faulkner@Sun.COM 	 */
45411970SRoger.Faulkner@Sun.COM 	for (s10sig = 33; s10sig < S10_SIGRTMIN; s10sig++)
45511970SRoger.Faulkner@Sun.COM 		if (sigismember(set, s10sig))
45611970SRoger.Faulkner@Sun.COM 			sigaddset(&nativeset, s10sig);
45711970SRoger.Faulkner@Sun.COM 
45811970SRoger.Faulkner@Sun.COM 	/*
45911970SRoger.Faulkner@Sun.COM 	 * Convert any S10 RT signals to their native values.
46011970SRoger.Faulkner@Sun.COM 	 */
46111970SRoger.Faulkner@Sun.COM 	for (s10sig = S10_SIGRTMIN, nativesig = _SIGRTMIN;
46211970SRoger.Faulkner@Sun.COM 	    s10sig <= S10_SIGRTMAX && nativesig <= _SIGRTMAX;
46311970SRoger.Faulkner@Sun.COM 	    s10sig++, nativesig++) {
46411970SRoger.Faulkner@Sun.COM 		if (sigismember(set, s10sig))
46511970SRoger.Faulkner@Sun.COM 			sigaddset(&nativeset, nativesig);
46611970SRoger.Faulkner@Sun.COM 	}
46711970SRoger.Faulkner@Sun.COM 
46811970SRoger.Faulkner@Sun.COM 	*set = nativeset;
46911970SRoger.Faulkner@Sun.COM }
47010840SGerald.Jelinek@Sun.COM 
47110840SGerald.Jelinek@Sun.COM int
_init(void)47210840SGerald.Jelinek@Sun.COM _init(void)
47310840SGerald.Jelinek@Sun.COM {
47410840SGerald.Jelinek@Sun.COM 	int err;
47510840SGerald.Jelinek@Sun.COM 
47610840SGerald.Jelinek@Sun.COM 	/*
47710840SGerald.Jelinek@Sun.COM 	 * Set up the table indicating which system calls we want to
47810840SGerald.Jelinek@Sun.COM 	 * interpose on.  We should probably build this automatically from
47910840SGerald.Jelinek@Sun.COM 	 * a list of system calls that is shared with the user-space
48010840SGerald.Jelinek@Sun.COM 	 * library.
48110840SGerald.Jelinek@Sun.COM 	 */
48210840SGerald.Jelinek@Sun.COM 	s10_emulation_table = kmem_zalloc(NSYSCALL, KM_SLEEP);
48311798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_forkall] = 1;		/*   2 */
48411798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_open] = 1;			/*   5 */
48511798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_wait] = 1;			/*   7 */
48611798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_creat] = 1;			/*   8 */
48712789SRoger.Faulkner@Oracle.COM 	s10_emulation_table[S10_SYS_link] = 1;			/*   9 */
48811798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_unlink] = 1;		/*  10 */
48911798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_exec] = 1;			/*  11 */
49012789SRoger.Faulkner@Oracle.COM 	s10_emulation_table[S10_SYS_mknod] = 1;			/*  14 */
49112789SRoger.Faulkner@Oracle.COM 	s10_emulation_table[S10_SYS_chmod] = 1;			/*  15 */
49211798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_chown] = 1;			/*  16 */
49311798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_stat] = 1;			/*  18 */
49411798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_umount] = 1;		/*  22 */
49511798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_fstat] = 1;			/*  28 */
49611798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_utime] = 1;			/*  30 */
49711798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_access] = 1;		/*  33 */
49811913SRoger.Faulkner@Sun.COM 	s10_emulation_table[SYS_kill] = 1;			/*  37 */
49911798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_dup] = 1;			/*  41 */
50010840SGerald.Jelinek@Sun.COM 	s10_emulation_table[SYS_ioctl] = 1;			/*  54 */
50110840SGerald.Jelinek@Sun.COM 	s10_emulation_table[SYS_execve] = 1;			/*  59 */
50210840SGerald.Jelinek@Sun.COM 	s10_emulation_table[SYS_acctctl] = 1;			/*  71 */
50310840SGerald.Jelinek@Sun.COM 	s10_emulation_table[S10_SYS_issetugid] = 1;		/*  75 */
50411798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_fsat] = 1;			/*  76 */
50511798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_rmdir] = 1;			/*  79 */
50612789SRoger.Faulkner@Oracle.COM 	s10_emulation_table[S10_SYS_mkdir] = 1;			/*  80 */
50711315SJordan.Vaughan@Sun.com 	s10_emulation_table[SYS_getdents] = 1;			/*  81 */
50811798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_poll] = 1;			/*  87 */
50911798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_lstat] = 1;			/*  88 */
51012789SRoger.Faulkner@Oracle.COM 	s10_emulation_table[S10_SYS_symlink] = 1;		/*  89 */
51112789SRoger.Faulkner@Oracle.COM 	s10_emulation_table[S10_SYS_readlink] = 1;		/*  90 */
51212789SRoger.Faulkner@Oracle.COM 	s10_emulation_table[S10_SYS_fchmod] = 1;		/*  93 */
51311798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_fchown] = 1;		/*  94 */
51411913SRoger.Faulkner@Sun.COM 	s10_emulation_table[SYS_sigprocmask] = 1;		/*  95 */
51511913SRoger.Faulkner@Sun.COM 	s10_emulation_table[SYS_sigsuspend] = 1;		/*  96 */
51611913SRoger.Faulkner@Sun.COM 	s10_emulation_table[SYS_sigaction] = 1;			/*  98 */
51711913SRoger.Faulkner@Sun.COM 	s10_emulation_table[SYS_sigpending] = 1;		/*  99 */
51811913SRoger.Faulkner@Sun.COM 	s10_emulation_table[SYS_waitid] = 1;			/* 107 */
51911913SRoger.Faulkner@Sun.COM 	s10_emulation_table[SYS_sigsendsys] = 1;		/* 108 */
52011798SRoger.Faulkner@Sun.COM #if defined(__x86)
52111798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_xstat] = 1;			/* 123 */
52211798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_lxstat] = 1;		/* 124 */
52311798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_fxstat] = 1;		/* 125 */
52411798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_xmknod] = 1;		/* 126 */
52511798SRoger.Faulkner@Sun.COM #endif
52611798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_lchown] = 1;		/* 130 */
52711798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_rename] = 1;		/* 134 */
52810840SGerald.Jelinek@Sun.COM 	s10_emulation_table[SYS_uname] = 1;			/* 135 */
52911913SRoger.Faulkner@Sun.COM 	s10_emulation_table[SYS_sysconfig] = 1;			/* 137 */
53010840SGerald.Jelinek@Sun.COM 	s10_emulation_table[SYS_systeminfo] = 1;		/* 139 */
53111798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_fork1] = 1;			/* 143 */
53211913SRoger.Faulkner@Sun.COM 	s10_emulation_table[SYS_sigtimedwait] = 1;		/* 144 */
53311798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_lwp_sema_wait] = 1;		/* 147 */
53411798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_utimes] = 1;		/* 154 */
53511913SRoger.Faulkner@Sun.COM 	s10_emulation_table[SYS_lwp_create] = 1;		/* 159 */
53611913SRoger.Faulkner@Sun.COM 	s10_emulation_table[SYS_lwp_kill] = 1;			/* 163 */
53711913SRoger.Faulkner@Sun.COM 	s10_emulation_table[SYS_lwp_sigmask] = 1;		/* 165 */
53811798SRoger.Faulkner@Sun.COM #if defined(__amd64)
53910840SGerald.Jelinek@Sun.COM 	s10_emulation_table[SYS_lwp_private] = 1;		/* 166 */
54010840SGerald.Jelinek@Sun.COM #endif	/* __amd64 */
54111798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_lwp_mutex_lock] = 1;	/* 169 */
54210840SGerald.Jelinek@Sun.COM 	s10_emulation_table[SYS_pwrite] = 1;			/* 174 */
54312557Sgerald.jelinek@sun.com 	s10_emulation_table[SYS_acl] = 1;			/* 185 */
54410840SGerald.Jelinek@Sun.COM 	s10_emulation_table[SYS_auditsys] = 1;			/* 186 */
54510840SGerald.Jelinek@Sun.COM 	s10_emulation_table[SYS_sigqueue] = 1;			/* 190 */
54612557Sgerald.jelinek@sun.com 	s10_emulation_table[SYS_facl] = 1;			/* 200 */
54711913SRoger.Faulkner@Sun.COM 	s10_emulation_table[SYS_signotify] = 1;			/* 205 */
54810887SRoger.Faulkner@Sun.COM 	s10_emulation_table[SYS_lwp_mutex_timedlock] = 1;	/* 210 */
54911315SJordan.Vaughan@Sun.com 	s10_emulation_table[SYS_getdents64] = 1;		/* 213 */
55011798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_stat64] = 1;		/* 215 */
55111798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_lstat64] = 1;		/* 216 */
55211798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_fstat64] = 1;		/* 217 */
55310840SGerald.Jelinek@Sun.COM 	s10_emulation_table[SYS_pwrite64] = 1;			/* 223 */
55411798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_creat64] = 1;		/* 224 */
55511798SRoger.Faulkner@Sun.COM 	s10_emulation_table[S10_SYS_open64] = 1;		/* 225 */
55610840SGerald.Jelinek@Sun.COM 	s10_emulation_table[SYS_zone] = 1;			/* 227 */
55710887SRoger.Faulkner@Sun.COM 	s10_emulation_table[SYS_lwp_mutex_trylock] = 1;		/* 251 */
55810840SGerald.Jelinek@Sun.COM 
55910840SGerald.Jelinek@Sun.COM 	err = mod_install(&modlinkage);
56010840SGerald.Jelinek@Sun.COM 	if (err) {
56110840SGerald.Jelinek@Sun.COM 		cmn_err(CE_WARN, "Couldn't install brand module");
56210840SGerald.Jelinek@Sun.COM 		kmem_free(s10_emulation_table, NSYSCALL);
56310840SGerald.Jelinek@Sun.COM 	}
56410840SGerald.Jelinek@Sun.COM 
56510840SGerald.Jelinek@Sun.COM 	return (err);
56610840SGerald.Jelinek@Sun.COM }
56710840SGerald.Jelinek@Sun.COM 
56810840SGerald.Jelinek@Sun.COM int
_info(struct modinfo * modinfop)56910840SGerald.Jelinek@Sun.COM _info(struct modinfo *modinfop)
57010840SGerald.Jelinek@Sun.COM {
57110840SGerald.Jelinek@Sun.COM 	return (mod_info(&modlinkage, modinfop));
57210840SGerald.Jelinek@Sun.COM }
57310840SGerald.Jelinek@Sun.COM 
57410840SGerald.Jelinek@Sun.COM int
_fini(void)57510840SGerald.Jelinek@Sun.COM _fini(void)
57610840SGerald.Jelinek@Sun.COM {
57712199Sgerald.jelinek@sun.com 	return (brand_solaris_fini(&s10_emulation_table, &modlinkage,
57812199Sgerald.jelinek@sun.com 	    &s10_brand));
57910840SGerald.Jelinek@Sun.COM }
580