OpenGrok

Cross Reference: s10_brand.c
xref: /onnv/onnv-gate/usr/src/uts/common/brand/solaris10/s10_brand.c
Home | History | Annotate | Line # | Download | only in solaris10
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
     24  */
     25 
     26 #include <sys/errno.h>
     27 #include <sys/exec.h>
     28 #include <sys/file.h>
     29 #include <sys/kmem.h>
     30 #include <sys/modctl.h>
     31 #include <sys/model.h>
     32 #include <sys/proc.h>
     33 #include <sys/syscall.h>
     34 #include <sys/systm.h>
     35 #include <sys/thread.h>
     36 #include <sys/cmn_err.h>
     37 #include <sys/archsystm.h>
     38 #include <sys/pathname.h>
     39 #include <sys/sunddi.h>
     40 
     41 #include <sys/machbrand.h>
     42 #include <sys/brand.h>
     43 #include "s10_brand.h"
     44 
     45 char *s10_emulation_table = NULL;
     46 
     47 void	s10_init_brand_data(zone_t *);
     48 void	s10_free_brand_data(zone_t *);
     49 void	s10_setbrand(proc_t *);
     50 int	s10_getattr(zone_t *, int, void *, size_t *);
     51 int	s10_setattr(zone_t *, int, void *, size_t);
     52 int	s10_brandsys(int, int64_t *, uintptr_t, uintptr_t, uintptr_t,
     53 		uintptr_t, uintptr_t, uintptr_t);
     54 void	s10_copy_procdata(proc_t *, proc_t *);
     55 void	s10_proc_exit(struct proc *, klwp_t *);
     56 void	s10_exec();
     57 int	s10_initlwp(klwp_t *);
     58 void	s10_forklwp(klwp_t *, klwp_t *);
     59 void	s10_freelwp(klwp_t *);
     60 void	s10_lwpexit(klwp_t *);
     61 int	s10_elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int,
     62 	long *, int, caddr_t, cred_t *, int);
     63 void	s10_sigset_native_to_s10(sigset_t *);
     64 void	s10_sigset_s10_to_native(sigset_t *);
     65 
     66 /* s10 brand */
     67 struct brand_ops s10_brops = {
     68 	s10_init_brand_data,
     69 	s10_free_brand_data,
     70 	s10_brandsys,
     71 	s10_setbrand,
     72 	s10_getattr,
     73 	s10_setattr,
     74 	s10_copy_procdata,
     75 	s10_proc_exit,
     76 	s10_exec,
     77 	lwp_setrval,
     78 	s10_initlwp,
     79 	s10_forklwp,
     80 	s10_freelwp,
     81 	s10_lwpexit,
     82 	s10_elfexec,
     83 	s10_sigset_native_to_s10,
     84 	s10_sigset_s10_to_native,
     85 	S10_NSIG,
     86 };
     87 
     88 #ifdef	sparc
     89 
     90 struct brand_mach_ops s10_mops = {
     91 	s10_brand_syscall_callback,
     92 	s10_brand_syscall32_callback
     93 };
     94 
     95 #else	/* sparc */
     96 
     97 #ifdef	__amd64
     98 
     99 struct brand_mach_ops s10_mops = {
    100 	s10_brand_sysenter_callback,
    101 	s10_brand_int91_callback,
    102 	s10_brand_syscall_callback,
    103 	s10_brand_syscall32_callback
    104 };
    105 
    106 #else	/* ! __amd64 */
    107 
    108 struct brand_mach_ops s10_mops = {
    109 	s10_brand_sysenter_callback,
    110 	NULL,
    111 	s10_brand_syscall_callback,
    112 	NULL
    113 };
    114 #endif	/* __amd64 */
    115 
    116 #endif	/* _sparc */
    117 
    118 struct brand	s10_brand = {
    119 	BRAND_VER_1,
    120 	"solaris10",
    121 	&s10_brops,
    122 	&s10_mops
    123 };
    124 
    125 static struct modlbrand modlbrand = {
    126 	&mod_brandops,		/* type of module */
    127 	"Solaris 10 Brand",	/* description of module */
    128 	&s10_brand		/* driver ops */
    129 };
    130 
    131 static struct modlinkage modlinkage = {
    132 	MODREV_1, (void *)&modlbrand, NULL
    133 };
    134 
    135 void
    136 s10_setbrand(proc_t *p)
    137 {
    138 	brand_solaris_setbrand(p, &s10_brand);
    139 }
    140 
    141 /*ARGSUSED*/
    142 int
    143 s10_getattr(zone_t *zone, int attr, void *buf, size_t *bufsize)
    144 {
    145 	ASSERT(zone->zone_brand == &s10_brand);
    146 	if (attr == S10_EMUL_BITMAP) {
    147 		if (buf == NULL || *bufsize != sizeof (s10_emul_bitmap_t))
    148 			return (EINVAL);
    149 		if (copyout(((s10_zone_data_t *)zone->zone_brand_data)->
    150 		    emul_bitmap, buf, sizeof (s10_emul_bitmap_t)) != 0)
    151 			return (EFAULT);
    152 		return (0);
    153 	}
    154 
    155 	return (EINVAL);
    156 }
    157 
    158 int
    159 s10_setattr(zone_t *zone, int attr, void *buf, size_t bufsize)
    160 {
    161 	ASSERT(zone->zone_brand == &s10_brand);
    162 	if (attr == S10_EMUL_BITMAP) {
    163 		if (buf == NULL || bufsize != sizeof (s10_emul_bitmap_t))
    164 			return (EINVAL);
    165 		if (copyin(buf, ((s10_zone_data_t *)zone->zone_brand_data)->
    166 		    emul_bitmap, sizeof (s10_emul_bitmap_t)) != 0)
    167 			return (EFAULT);
    168 		return (0);
    169 	}
    170 
    171 	return (EINVAL);
    172 }
    173 
    174 #ifdef	__amd64
    175 /*
    176  * The Nevada kernel clears %fs for threads in 64-bit x86 processes but S10's
    177  * libc expects %fs to be nonzero.  This causes some committed
    178  * libc/libthread interfaces (e.g., thr_main()) to fail, which impacts several
    179  * libraries, including libdoor.  This function sets the specified LWP's %fs
    180  * register to the legacy S10 selector value (LWPFS_SEL).
    181  *
    182  * The best solution to the aforementioned problem is backporting CRs
    183  * 6467491 to Solaris 10 so that 64-bit x86 Solaris 10 processes
    184  * would accept zero for %fs.  Backporting the CRs is a requirement for running
    185  * S10 Containers in PV domUs because 64-bit Xen clears %fsbase when %fs is
    186  * nonzero.  Such behavior breaks 64-bit processes because Xen has to fetch the
    187  * FS segments' base addresses from the LWPs' GDTs, which are only capable of
    188  * 32-bit addressing.
    189  */
    190 /*ARGSUSED*/
    191 static void
    192 s10_amd64_correct_fsreg(klwp_t *l)
    193 {
    194 	if (lwp_getdatamodel(l) == DATAMODEL_NATIVE) {
    195 		kpreempt_disable();
    196 		l->lwp_pcb.pcb_fs = LWPFS_SEL;
    197 		l->lwp_pcb.pcb_rupdate = 1;
    198 		lwptot(l)->t_post_sys = 1;	/* Guarantee update_sregs() */
    199 		kpreempt_enable();
    200 	}
    201 }
    202 #endif	/* __amd64 */
    203 
    204 /*
    205  * Native processes are started with the native ld.so.1 as the command.  This
    206  * brand op is invoked by s10_npreload to fix up the command and arguments
    207  * so that apps like pgrep or ps see the expected command strings.
    208  */
    209 int
    210 s10_native(void *cmd, void *args)
    211 {
    212 	struct user	*up = PTOU(curproc);
    213 	char		cmd_buf[MAXCOMLEN + 1];
    214 	char		arg_buf[PSARGSZ];
    215 
    216 	if (copyin(cmd, &cmd_buf, sizeof (cmd_buf)) != 0)
    217 		return (EFAULT);
    218 	if (copyin(args, &arg_buf, sizeof (arg_buf)) != 0)
    219 		return (EFAULT);
    220 
    221 	/*
    222 	 * Make sure that the process' interpreter is the native dynamic linker.
    223 	 * Convention dictates that native processes executing within solaris10-
    224 	 * branded zones are interpreted by the native dynamic linker (the
    225 	 * process and its arguments are specified as arguments to the dynamic
    226 	 * linker).  If this convention is violated (i.e.,
    227 	 * brandsys(B_S10_NATIVE, ...) is invoked by a process that shouldn't be
    228 	 * native), then do nothing and silently indicate success.
    229 	 */
    230 	if (strcmp(up->u_comm, S10_LINKER_NAME) != 0)
    231 		return (0);
    232 
    233 	/*
    234 	 * The sizeof has an extra value for the trailing '\0' so this covers
    235 	 * the appended " " in the following strcmps.
    236 	 */
    237 	if (strncmp(up->u_psargs, BRAND_NATIVE_LINKER64 " ",
    238 	    sizeof (BRAND_NATIVE_LINKER64)) != 0 &&
    239 	    strncmp(up->u_psargs, BRAND_NATIVE_LINKER32 " ",
    240 	    sizeof (BRAND_NATIVE_LINKER32)) != 0)
    241 		return (0);
    242 
    243 	mutex_enter(&curproc->p_lock);
    244 	(void) strlcpy(up->u_comm, cmd_buf, sizeof (up->u_comm));
    245 	(void) strlcpy(up->u_psargs, arg_buf, sizeof (up->u_psargs));
    246 	mutex_exit(&curproc->p_lock);
    247 
    248 	return (0);
    249 }
    250 
    251 /*ARGSUSED*/
    252 int
    253 s10_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2,
    254     uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6)
    255 {
    256 	proc_t	*p = curproc;
    257 	int	res;
    258 
    259 	*rval = 0;
    260 
    261 	if (cmd == B_S10_NATIVE)
    262 		return (s10_native((void *)arg1, (void *)arg2));
    263 
    264 	res = brand_solaris_cmd(cmd, arg1, arg2, arg3, &s10_brand, S10_VERSION);
    265 	if (res >= 0)
    266 		return (res);
    267 
    268 	switch ((cmd)) {
    269 	case B_S10_PIDINFO:
    270 		/*
    271 		 * The s10 brand needs to be able to get the pid of the
    272 		 * current process and the pid of the zone's init, and it
    273 		 * needs to do this on every process startup.  Early in
    274 		 * brand startup, we can't call getpid() because calls to
    275 		 * getpid() represent a magical signal to some old-skool
    276 		 * debuggers.  By merging all of this into one call, we
    277 		 * make this quite a bit cheaper and easier to handle in
    278 		 * the brand module.
    279 		 */
    280 		if (copyout(&p->p_pid, (void *)arg1, sizeof (pid_t)) != 0)
    281 			return (EFAULT);
    282 		if (copyout(&p->p_zone->zone_proc_initpid, (void *)arg2,
    283 		    sizeof (pid_t)) != 0)
    284 			return (EFAULT);
    285 		return (0);
    286 
    287 	case B_S10_ISFDXATTRDIR: {
    288 		/*
    289 		 * This subcommand enables the userland brand emulation library
    290 		 * to determine whether a file descriptor refers to an extended
    291 		 * file attributes directory.  There is no standard syscall or
    292 		 * libc function that can make such a determination.
    293 		 */
    294 		file_t *dir_filep;
    295 
    296 		dir_filep = getf((int)arg1);
    297 		if (dir_filep == NULL)
    298 			return (EBADF);
    299 		ASSERT(dir_filep->f_vnode != NULL);
    300 		*rval = IS_XATTRDIR(dir_filep->f_vnode);
    301 		releasef((int)arg1);
    302 		return (0);
    303 	}
    304 
    305 #ifdef	__amd64
    306 	case B_S10_FSREGCORRECTION:
    307 		/*
    308 		 * This subcommand exists so that the SYS_lwp_private and
    309 		 * SYS_lwp_create syscalls can manually set the current thread's
    310 		 * %fs register to the legacy S10 selector value for 64-bit x86
    311 		 * processes.
    312 		 */
    313 		s10_amd64_correct_fsreg(ttolwp(curthread));
    314 		return (0);
    315 #endif	/* __amd64 */
    316 	}
    317 
    318 	return (EINVAL);
    319 }
    320 
    321 void
    322 s10_copy_procdata(proc_t *child, proc_t *parent)
    323 {
    324 	brand_solaris_copy_procdata(child, parent, &s10_brand);
    325 }
    326 
    327 void
    328 s10_proc_exit(struct proc *p, klwp_t *l)
    329 {
    330 	brand_solaris_proc_exit(p, l, &s10_brand);
    331 }
    332 
    333 void
    334 s10_exec()
    335 {
    336 	brand_solaris_exec(&s10_brand);
    337 }
    338 
    339 int
    340 s10_initlwp(klwp_t *l)
    341 {
    342 	return (brand_solaris_initlwp(l, &s10_brand));
    343 }
    344 
    345 void
    346 s10_forklwp(klwp_t *p, klwp_t *c)
    347 {
    348 	brand_solaris_forklwp(p, c, &s10_brand);
    349 
    350 #ifdef	__amd64
    351 	/*
    352 	 * Only correct the child's %fs register if the parent's %fs register
    353 	 * is LWPFS_SEL.  If the parent's %fs register is zero, then the Solaris
    354 	 * 10 environment that we're emulating uses a version of libc that
    355 	 * works when %fs is zero (i.e., it contains backports of CRs 6467491
    356 	 * and 6501650).
    357 	 */
    358 	if (p->lwp_pcb.pcb_fs == LWPFS_SEL)
    359 		s10_amd64_correct_fsreg(c);
    360 #endif	/* __amd64 */
    361 }
    362 
    363 void
    364 s10_freelwp(klwp_t *l)
    365 {
    366 	brand_solaris_freelwp(l, &s10_brand);
    367 }
    368 
    369 void
    370 s10_lwpexit(klwp_t *l)
    371 {
    372 	brand_solaris_lwpexit(l, &s10_brand);
    373 }
    374 
    375 void
    376 s10_free_brand_data(zone_t *zone)
    377 {
    378 	kmem_free(zone->zone_brand_data, sizeof (s10_zone_data_t));
    379 }
    380 
    381 void
    382 s10_init_brand_data(zone_t *zone)
    383 {
    384 	ASSERT(zone->zone_brand == &s10_brand);
    385 	ASSERT(zone->zone_brand_data == NULL);
    386 	zone->zone_brand_data = kmem_zalloc(sizeof (s10_zone_data_t), KM_SLEEP);
    387 }
    388 
    389 int
    390 s10_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap,
    391 	int level, long *execsz, int setid, caddr_t exec_file, cred_t *cred,
    392 	int brand_action)
    393 {
    394 	return (brand_solaris_elfexec(vp, uap, args, idatap, level, execsz,
    395 	    setid, exec_file, cred, brand_action, &s10_brand, S10_BRANDNAME,
    396 	    S10_LIB, S10_LIB32, S10_LINKER, S10_LINKER32));
    397 }
    398 
    399 void
    400 s10_sigset_native_to_s10(sigset_t *set)
    401 {
    402 	int nativesig;
    403 	int s10sig;
    404 	sigset_t s10set;
    405 
    406 	/*
    407 	 * Shortcut: we know the first 32 signals are the same in both
    408 	 * s10 and native Solaris.  Just assign the first word.
    409 	 */
    410 	s10set.__sigbits[0] = set->__sigbits[0];
    411 	s10set.__sigbits[1] = 0;
    412 	s10set.__sigbits[2] = 0;
    413 	s10set.__sigbits[3] = 0;
    414 
    415 	/*
    416 	 * Copy the remainder of the initial set of common signals.
    417 	 */
    418 	for (nativesig = 33; nativesig < S10_SIGRTMIN; nativesig++)
    419 		if (sigismember(set, nativesig))
    420 			sigaddset(&s10set, nativesig);
    421 
    422 	/*
    423 	 * Convert any native RT signals to their S10 values.
    424 	 */
    425 	for (nativesig = _SIGRTMIN, s10sig = S10_SIGRTMIN;
    426 	    nativesig <= _SIGRTMAX && s10sig <= S10_SIGRTMAX;
    427 	    nativesig++, s10sig++) {
    428 		if (sigismember(set, nativesig))
    429 			sigaddset(&s10set, s10sig);
    430 	}
    431 
    432 	*set = s10set;
    433 }
    434 
    435 void
    436 s10_sigset_s10_to_native(sigset_t *set)
    437 {
    438 	int s10sig;
    439 	int nativesig;
    440 	sigset_t nativeset;
    441 
    442 	/*
    443 	 * Shortcut: we know the first 32 signals are the same in both
    444 	 * s10 and native Solaris.  Just assign the first word.
    445 	 */
    446 	nativeset.__sigbits[0] = set->__sigbits[0];
    447 	nativeset.__sigbits[1] = 0;
    448 	nativeset.__sigbits[2] = 0;
    449 	nativeset.__sigbits[3] = 0;
    450 
    451 	/*
    452 	 * Copy the remainder of the initial set of common signals.
    453 	 */
    454 	for (s10sig = 33; s10sig < S10_SIGRTMIN; s10sig++)
    455 		if (sigismember(set, s10sig))
    456 			sigaddset(&nativeset, s10sig);
    457 
    458 	/*
    459 	 * Convert any S10 RT signals to their native values.
    460 	 */
    461 	for (s10sig = S10_SIGRTMIN, nativesig = _SIGRTMIN;
    462 	    s10sig <= S10_SIGRTMAX && nativesig <= _SIGRTMAX;
    463 	    s10sig++, nativesig++) {
    464 		if (sigismember(set, s10sig))
    465 			sigaddset(&nativeset, nativesig);
    466 	}
    467 
    468 	*set = nativeset;
    469 }
    470 
    471 int
    472 _init(void)
    473 {
    474 	int err;
    475 
    476 	/*
    477 	 * Set up the table indicating which system calls we want to
    478 	 * interpose on.  We should probably build this automatically from
    479 	 * a list of system calls that is shared with the user-space
    480 	 * library.
    481 	 */
    482 	s10_emulation_table = kmem_zalloc(NSYSCALL, KM_SLEEP);
    483 	s10_emulation_table[S10_SYS_forkall] = 1;		/*   2 */
    484 	s10_emulation_table[S10_SYS_open] = 1;			/*   5 */
    485 	s10_emulation_table[S10_SYS_wait] = 1;			/*   7 */
    486 	s10_emulation_table[S10_SYS_creat] = 1;			/*   8 */
    487 	s10_emulation_table[S10_SYS_link] = 1;			/*   9 */
    488 	s10_emulation_table[S10_SYS_unlink] = 1;		/*  10 */
    489 	s10_emulation_table[S10_SYS_exec] = 1;			/*  11 */
    490 	s10_emulation_table[S10_SYS_mknod] = 1;			/*  14 */
    491 	s10_emulation_table[S10_SYS_chmod] = 1;			/*  15 */
    492 	s10_emulation_table[S10_SYS_chown] = 1;			/*  16 */
    493 	s10_emulation_table[S10_SYS_stat] = 1;			/*  18 */
    494 	s10_emulation_table[S10_SYS_umount] = 1;		/*  22 */
    495 	s10_emulation_table[S10_SYS_fstat] = 1;			/*  28 */
    496 	s10_emulation_table[S10_SYS_utime] = 1;			/*  30 */
    497 	s10_emulation_table[S10_SYS_access] = 1;		/*  33 */
    498 	s10_emulation_table[SYS_kill] = 1;			/*  37 */
    499 	s10_emulation_table[S10_SYS_dup] = 1;			/*  41 */
    500 	s10_emulation_table[SYS_ioctl] = 1;			/*  54 */
    501 	s10_emulation_table[SYS_execve] = 1;			/*  59 */
    502 	s10_emulation_table[SYS_acctctl] = 1;			/*  71 */
    503 	s10_emulation_table[S10_SYS_issetugid] = 1;		/*  75 */
    504 	s10_emulation_table[S10_SYS_fsat] = 1;			/*  76 */
    505 	s10_emulation_table[S10_SYS_rmdir] = 1;			/*  79 */
    506 	s10_emulation_table[S10_SYS_mkdir] = 1;			/*  80 */
    507 	s10_emulation_table[SYS_getdents] = 1;			/*  81 */
    508 	s10_emulation_table[S10_SYS_poll] = 1;			/*  87 */
    509 	s10_emulation_table[S10_SYS_lstat] = 1;			/*  88 */
    510 	s10_emulation_table[S10_SYS_symlink] = 1;		/*  89 */
    511 	s10_emulation_table[S10_SYS_readlink] = 1;		/*  90 */
    512 	s10_emulation_table[S10_SYS_fchmod] = 1;		/*  93 */
    513 	s10_emulation_table[S10_SYS_fchown] = 1;		/*  94 */
    514 	s10_emulation_table[SYS_sigprocmask] = 1;		/*  95 */
    515 	s10_emulation_table[SYS_sigsuspend] = 1;		/*  96 */
    516 	s10_emulation_table[SYS_sigaction] = 1;			/*  98 */
    517 	s10_emulation_table[SYS_sigpending] = 1;		/*  99 */
    518 	s10_emulation_table[SYS_waitid] = 1;			/* 107 */
    519 	s10_emulation_table[SYS_sigsendsys] = 1;		/* 108 */
    520 #if defined(__x86)
    521 	s10_emulation_table[S10_SYS_xstat] = 1;			/* 123 */
    522 	s10_emulation_table[S10_SYS_lxstat] = 1;		/* 124 */
    523 	s10_emulation_table[S10_SYS_fxstat] = 1;		/* 125 */
    524 	s10_emulation_table[S10_SYS_xmknod] = 1;		/* 126 */
    525 #endif
    526 	s10_emulation_table[S10_SYS_lchown] = 1;		/* 130 */
    527 	s10_emulation_table[S10_SYS_rename] = 1;		/* 134 */
    528 	s10_emulation_table[SYS_uname] = 1;			/* 135 */
    529 	s10_emulation_table[SYS_sysconfig] = 1;			/* 137 */
    530 	s10_emulation_table[SYS_systeminfo] = 1;		/* 139 */
    531 	s10_emulation_table[S10_SYS_fork1] = 1;			/* 143 */
    532 	s10_emulation_table[SYS_sigtimedwait] = 1;		/* 144 */
    533 	s10_emulation_table[S10_SYS_lwp_sema_wait] = 1;		/* 147 */
    534 	s10_emulation_table[S10_SYS_utimes] = 1;		/* 154 */
    535 	s10_emulation_table[SYS_lwp_create] = 1;		/* 159 */
    536 	s10_emulation_table[SYS_lwp_kill] = 1;			/* 163 */
    537 	s10_emulation_table[SYS_lwp_sigmask] = 1;		/* 165 */
    538 #if defined(__amd64)
    539 	s10_emulation_table[SYS_lwp_private] = 1;		/* 166 */
    540 #endif	/* __amd64 */
    541 	s10_emulation_table[S10_SYS_lwp_mutex_lock] = 1;	/* 169 */
    542 	s10_emulation_table[SYS_pwrite] = 1;			/* 174 */
    543 	s10_emulation_table[SYS_acl] = 1;			/* 185 */
    544 	s10_emulation_table[SYS_auditsys] = 1;			/* 186 */
    545 	s10_emulation_table[SYS_sigqueue] = 1;			/* 190 */
    546 	s10_emulation_table[SYS_facl] = 1;			/* 200 */
    547 	s10_emulation_table[SYS_signotify] = 1;			/* 205 */
    548 	s10_emulation_table[SYS_lwp_mutex_timedlock] = 1;	/* 210 */
    549 	s10_emulation_table[SYS_getdents64] = 1;		/* 213 */
    550 	s10_emulation_table[S10_SYS_stat64] = 1;		/* 215 */
    551 	s10_emulation_table[S10_SYS_lstat64] = 1;		/* 216 */
    552 	s10_emulation_table[S10_SYS_fstat64] = 1;		/* 217 */
    553 	s10_emulation_table[SYS_pwrite64] = 1;			/* 223 */
    554 	s10_emulation_table[S10_SYS_creat64] = 1;		/* 224 */
    555 	s10_emulation_table[S10_SYS_open64] = 1;		/* 225 */
    556 	s10_emulation_table[SYS_zone] = 1;			/* 227 */
    557 	s10_emulation_table[SYS_lwp_mutex_trylock] = 1;		/* 251 */
    558 
    559 	err = mod_install(&modlinkage);
    560 	if (err) {
    561 		cmn_err(CE_WARN, "Couldn't install brand module");
    562 		kmem_free(s10_emulation_table, NSYSCALL);
    563 	}
    564 
    565 	return (err);
    566 }
    567 
    568 int
    569 _info(struct modinfo *modinfop)
    570 {
    571 	return (mod_info(&modlinkage, modinfop));
    572 }
    573 
    574 int
    575 _fini(void)
    576 {
    577 	return (brand_solaris_fini(&s10_emulation_table, &modlinkage,
    578 	    &s10_brand));
    579 }
    580