OpenGrok

Cross Reference: s10_brand.c
xref: /onnv/onnv-gate/usr/src/lib/brand/solaris10/s10_brand/common/s10_brand.c
Home | History | Annotate | Line # | Download | only in common
      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 <errno.h>
     27 #include <fcntl.h>
     28 #include <dirent.h>
     29 #include <stddef.h>
     30 #include <stdio.h>
     31 #include <stdlib.h>
     32 #include <strings.h>
     33 #include <unistd.h>
     34 #include <thread.h>
     35 #include <sys/auxv.h>
     36 #include <sys/brand.h>
     37 #include <sys/inttypes.h>
     38 #include <sys/lwp.h>
     39 #include <sys/syscall.h>
     40 #include <sys/systm.h>
     41 #include <sys/utsname.h>
     42 #include <sys/sysconfig.h>
     43 #include <sys/systeminfo.h>
     44 #include <sys/zone.h>
     45 #include <sys/stat.h>
     46 #include <sys/mntent.h>
     47 #include <sys/ctfs.h>
     48 #include <sys/priv.h>
     49 #include <sys/acctctl.h>
     50 #include <libgen.h>
     51 #include <bsm/audit.h>
     52 #include <sys/crypto/ioctl.h>
     53 #include <sys/fs/zfs.h>
     54 #include <sys/zfs_ioctl.h>
     55 #include <sys/ucontext.h>
     56 #include <sys/mntio.h>
     57 #include <sys/mnttab.h>
     58 #include <sys/attr.h>
     59 #include <sys/lofi.h>
     60 #include <atomic.h>
     61 #include <sys/acl.h>
     62 
     63 #include <s10_brand.h>
     64 #include <brand_misc.h>
     65 #include <s10_misc.h>
     66 #include <s10_signal.h>
     67 
     68 /*
     69  * See usr/src/lib/brand/shared/brand/common/brand_util.c for general
     70  * emulation notes.
     71  */
     72 
     73 static zoneid_t zoneid;
     74 static boolean_t emul_global_zone = B_FALSE;
     75 static s10_emul_bitmap_t emul_bitmap;
     76 pid_t zone_init_pid;
     77 
     78 /*
     79  * S10_FEATURE_IS_PRESENT is a macro that helps facilitate conditional
     80  * emulation.  For each constant N defined in the s10_emulated_features
     81  * enumeration in usr/src/uts/common/brand/solaris10/s10_brand.h,
     82  * S10_FEATURE_IS_PRESENT(N) is true iff the feature/backport represented by N
     83  * is present in the Solaris 10 image hosted within the zone.  In other words,
     84  * S10_FEATURE_IS_PRESENT(N) is true iff the file /usr/lib/brand/solaris10/M,
     85  * where M is the enum value of N, was present in the zone when the zone booted.
     86  *
     87  *
     88  * *** Sample Usage
     89  *
     90  * Suppose that you need to backport a fix to Solaris 10 and there is
     91  * emulation in place for the fix.  Suppose further that the emulation won't be
     92  * needed if the fix is backported (i.e., if the fix is present in the hosted
     93  * Solaris 10 environment, then the brand won't need the emulation).  Then if
     94  * you add a constant named "S10_FEATURE_X" to the end of the
     95  * s10_emulated_features enumeration that represents the backported fix and
     96  * S10_FEATURE_X evaluates to four, then you should create a file named
     97  * /usr/lib/brand/solaris10/4 as part of your backport.  Additionally, you
     98  * should retain the aforementioned emulation but modify it so that it's
     99  * performed only when S10_FEATURE_IS_PRESENT(S10_FEATURE_X) is false.  Thus the
    100  * emulation function should look something like the following:
    101  *
    102  *	static int
    103  *	my_emul_function(sysret_t *rv, ...)
    104  *	{
    105  *		if (S10_FEATURE_IS_PRESENT(S10_FEATURE_X)) {
    106  *			// Don't emulate
    107  *			return (__systemcall(rv, ...));
    108  *		} else {
    109  *			// Emulate whatever needs to be emulated when the
    110  *			// backport isn't present in the Solaris 10 image.
    111  *		}
    112  *	}
    113  */
    114 #define	S10_FEATURE_IS_PRESENT(s10_emulated_features_constant)	\
    115 	((emul_bitmap[(s10_emulated_features_constant) >> 3] &	\
    116 	(1 << ((s10_emulated_features_constant) & 0x7))) != 0)
    117 
    118 brand_sysent_table_t brand_sysent_table[];
    119 
    120 #define	S10_UTS_RELEASE	"5.10"
    121 #define	S10_UTS_VERSION	"Generic_Virtual"
    122 
    123 /*
    124  * If the ioctl fd's major doesn't match "major", then pass through the
    125  * ioctl, since it is not the expected device.  major should be a
    126  * pointer to a static dev_t initialized to -1, and devname should be
    127  * the path of the device.
    128  *
    129  * Returns 1 if the ioctl was handled (in which case *err contains the
    130  * error code), or 0 if it still needs handling.
    131  */
    132 static int
    133 passthru_otherdev_ioctl(dev_t *majordev, const char *devname, int *err,
    134     sysret_t *rval, int fdes, int cmd, intptr_t arg)
    135 {
    136 	struct stat sbuf;
    137 
    138 	if (*majordev == (dev_t)-1) {
    139 		if ((*err = __systemcall(rval, SYS_fstatat + 1024,
    140 		    AT_FDCWD, devname, &sbuf, 0) != 0) != 0)
    141 			goto doioctl;
    142 
    143 		*majordev = major(sbuf.st_rdev);
    144 	}
    145 
    146 	if ((*err = __systemcall(rval, SYS_fstatat + 1024, fdes,
    147 	    NULL, &sbuf, 0)) != 0)
    148 		goto doioctl;
    149 
    150 	if (major(sbuf.st_rdev) == *majordev)
    151 		return (0);
    152 
    153 doioctl:
    154 	*err = (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg));
    155 	return (1);
    156 }
    157 
    158 /*
    159  * Figures out the PID of init for the zone.  Also returns a boolean
    160  * indicating whether this process currently has that pid: if so,
    161  * then at this moment, we are init.
    162  */
    163 static boolean_t
    164 get_initpid_info(void)
    165 {
    166 	pid_t pid;
    167 	sysret_t rval;
    168 	int err;
    169 
    170 	/*
    171 	 * Determine the current process PID and the PID of the zone's init.
    172 	 * We use care not to call getpid() here, because we're not supposed
    173 	 * to call getpid() until after the program is fully linked-- the
    174 	 * first call to getpid() is a signal from the linker to debuggers
    175 	 * that linking has been completed.
    176 	 */
    177 	if ((err = __systemcall(&rval, SYS_brand,
    178 	    B_S10_PIDINFO, &pid, &zone_init_pid)) != 0) {
    179 		brand_abort(err, "Failed to get init's pid");
    180 	}
    181 
    182 	/*
    183 	 * Note that we need to be cautious with the pid we get back--
    184 	 * it should not be stashed and used in place of getpid(), since
    185 	 * we might fork(2).  So we keep zone_init_pid and toss the pid
    186 	 * we otherwise got.
    187 	 */
    188 	if (pid == zone_init_pid)
    189 		return (B_TRUE);
    190 
    191 	return (B_FALSE);
    192 }
    193 
    194 /* Free the thread-local storage provided by mntfs_get_mntentbuf(). */
    195 static void
    196 mntfs_free_mntentbuf(void *arg)
    197 {
    198 	struct mntentbuf *embufp = arg;
    199 
    200 	if (embufp == NULL)
    201 		return;
    202 	if (embufp->mbuf_emp)
    203 		free(embufp->mbuf_emp);
    204 	if (embufp->mbuf_buf)
    205 		free(embufp->mbuf_buf);
    206 	bzero(embufp, sizeof (struct mntentbuf));
    207 	free(embufp);
    208 }
    209 
    210 /* Provide the thread-local storage required by mntfs_ioctl(). */
    211 static struct mntentbuf *
    212 mntfs_get_mntentbuf(size_t size)
    213 {
    214 	static mutex_t keylock;
    215 	static thread_key_t key;
    216 	static int once_per_keyname = 0;
    217 	void *tsd = NULL;
    218 	struct mntentbuf *embufp;
    219 
    220 	/* Create the key. */
    221 	if (!once_per_keyname) {
    222 		(void) mutex_lock(&keylock);
    223 		if (!once_per_keyname) {
    224 			if (thr_keycreate(&key, mntfs_free_mntentbuf)) {
    225 				(void) mutex_unlock(&keylock);
    226 				return (NULL);
    227 			} else {
    228 				once_per_keyname++;
    229 			}
    230 		}
    231 		(void) mutex_unlock(&keylock);
    232 	}
    233 
    234 	/*
    235 	 * The thread-specific datum for this key is the address of a struct
    236 	 * mntentbuf. If this is the first time here then we allocate the struct
    237 	 * and its contents, and associate its address with the thread; if there
    238 	 * are any problems then we abort.
    239 	 */
    240 	if (thr_getspecific(key, &tsd))
    241 		return (NULL);
    242 	if (tsd == NULL) {
    243 		if (!(embufp = calloc(1, sizeof (struct mntentbuf))) ||
    244 		    !(embufp->mbuf_emp = malloc(sizeof (struct extmnttab))) ||
    245 		    thr_setspecific(key, embufp)) {
    246 			mntfs_free_mntentbuf(embufp);
    247 			return (NULL);
    248 		}
    249 	} else {
    250 		embufp = tsd;
    251 	}
    252 
    253 	/* Return the buffer, resizing it if necessary. */
    254 	if (size > embufp->mbuf_bufsize) {
    255 		if (embufp->mbuf_buf)
    256 			free(embufp->mbuf_buf);
    257 		if ((embufp->mbuf_buf = malloc(size)) == NULL) {
    258 			embufp->mbuf_bufsize = 0;
    259 			return (NULL);
    260 		} else {
    261 			embufp->mbuf_bufsize = size;
    262 		}
    263 	}
    264 	return (embufp);
    265 }
    266 
    267 /*
    268  * The MNTIOC_GETMNTENT command in this release differs from that in early
    269  * versions of Solaris 10.
    270  *
    271  * Previously, the command would copy a pointer to a struct extmnttab to an
    272  * address provided as an argument. The pointer would be somewhere within a
    273  * mapping already present within the user's address space. In addition, the
    274  * text to which the struct's members pointed would also be within a
    275  * pre-existing mapping. Now, the user is required to allocate memory for both
    276  * the struct and the text buffer, and to pass the address of each within a
    277  * struct mntentbuf. In order to conceal these details from a Solaris 10 client
    278  * we allocate some thread-local storage in which to create the necessary data
    279  * structures; this is static, thread-safe memory that will be cleaned up
    280  * without the caller's intervention.
    281  *
    282  * MNTIOC_GETEXTMNTENT and MNTIOC_GETMNTANY are new in this release; they should
    283  * not work for older clients.
    284  */
    285 int
    286 mntfs_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
    287 {
    288 	int err;
    289 	struct stat statbuf;
    290 	struct mntentbuf *embufp;
    291 	static size_t bufsize = MNT_LINE_MAX;
    292 
    293 	/* Do not emulate mntfs commands from up-to-date clients. */
    294 	if (S10_FEATURE_IS_PRESENT(S10_FEATURE_ALTERED_MNTFS_IOCTL))
    295 		return (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg));
    296 
    297 	/* Do not emulate mntfs commands directed at other file systems. */
    298 	if ((err = __systemcall(rval, SYS_fstatat + 1024,
    299 	    fdes, NULL, &statbuf, 0)) != 0)
    300 		return (err);
    301 	if (strcmp(statbuf.st_fstype, MNTTYPE_MNTFS) != 0)
    302 		return (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg));
    303 
    304 	if (cmd == MNTIOC_GETEXTMNTENT || cmd == MNTIOC_GETMNTANY)
    305 		return (EINVAL);
    306 
    307 	if ((embufp = mntfs_get_mntentbuf(bufsize)) == NULL)
    308 		return (ENOMEM);
    309 
    310 	/*
    311 	 * MNTIOC_GETEXTMNTENT advances the file pointer once it has
    312 	 * successfully copied out the result to the address provided. We
    313 	 * therefore need to check the user-supplied address now since the
    314 	 * one we'll be providing is guaranteed to work.
    315 	 */
    316 	if (brand_uucopy(&embufp->mbuf_emp, (void *)arg, sizeof (void *)) != 0)
    317 		return (EFAULT);
    318 
    319 	/*
    320 	 * Keep retrying for as long as we fail for want of a large enough
    321 	 * buffer.
    322 	 */
    323 	for (;;) {
    324 		if ((err = __systemcall(rval, SYS_ioctl + 1024, fdes,
    325 		    MNTIOC_GETEXTMNTENT, embufp)) != 0)
    326 			return (err);
    327 
    328 		if (rval->sys_rval1 == MNTFS_TOOLONG) {
    329 			/* The buffer wasn't large enough. */
    330 			(void) atomic_swap_ulong((unsigned long *)&bufsize,
    331 			    2 * embufp->mbuf_bufsize);
    332 			if ((embufp = mntfs_get_mntentbuf(bufsize)) == NULL)
    333 				return (ENOMEM);
    334 		} else {
    335 			break;
    336 		}
    337 	}
    338 
    339 	if (brand_uucopy(&embufp->mbuf_emp, (void *)arg, sizeof (void *)) != 0)
    340 		return (EFAULT);
    341 
    342 	return (0);
    343 }
    344 
    345 /*
    346  * Assign the structure member value from the s (source) structure to the
    347  * d (dest) structure.
    348  */
    349 #define	struct_assign(d, s, val)	(((d).val) = ((s).val))
    350 
    351 /*
    352  * The CRYPTO_GET_FUNCTION_LIST parameter structure crypto_function_list_t
    353  * changed between S10 and Nevada, so we have to emulate the old S10
    354  * crypto_function_list_t structure when interposing on the ioctl syscall.
    355  */
    356 typedef struct s10_crypto_function_list {
    357 	boolean_t fl_digest_init;
    358 	boolean_t fl_digest;
    359 	boolean_t fl_digest_update;
    360 	boolean_t fl_digest_key;
    361 	boolean_t fl_digest_final;
    362 
    363 	boolean_t fl_encrypt_init;
    364 	boolean_t fl_encrypt;
    365 	boolean_t fl_encrypt_update;
    366 	boolean_t fl_encrypt_final;
    367 
    368 	boolean_t fl_decrypt_init;
    369 	boolean_t fl_decrypt;
    370 	boolean_t fl_decrypt_update;
    371 	boolean_t fl_decrypt_final;
    372 
    373 	boolean_t fl_mac_init;
    374 	boolean_t fl_mac;
    375 	boolean_t fl_mac_update;
    376 	boolean_t fl_mac_final;
    377 
    378 	boolean_t fl_sign_init;
    379 	boolean_t fl_sign;
    380 	boolean_t fl_sign_update;
    381 	boolean_t fl_sign_final;
    382 	boolean_t fl_sign_recover_init;
    383 	boolean_t fl_sign_recover;
    384 
    385 	boolean_t fl_verify_init;
    386 	boolean_t fl_verify;
    387 	boolean_t fl_verify_update;
    388 	boolean_t fl_verify_final;
    389 	boolean_t fl_verify_recover_init;
    390 	boolean_t fl_verify_recover;
    391 
    392 	boolean_t fl_digest_encrypt_update;
    393 	boolean_t fl_decrypt_digest_update;
    394 	boolean_t fl_sign_encrypt_update;
    395 	boolean_t fl_decrypt_verify_update;
    396 
    397 	boolean_t fl_seed_random;
    398 	boolean_t fl_generate_random;
    399 
    400 	boolean_t fl_session_open;
    401 	boolean_t fl_session_close;
    402 	boolean_t fl_session_login;
    403 	boolean_t fl_session_logout;
    404 
    405 	boolean_t fl_object_create;
    406 	boolean_t fl_object_copy;
    407 	boolean_t fl_object_destroy;
    408 	boolean_t fl_object_get_size;
    409 	boolean_t fl_object_get_attribute_value;
    410 	boolean_t fl_object_set_attribute_value;
    411 	boolean_t fl_object_find_init;
    412 	boolean_t fl_object_find;
    413 	boolean_t fl_object_find_final;
    414 
    415 	boolean_t fl_key_generate;
    416 	boolean_t fl_key_generate_pair;
    417 	boolean_t fl_key_wrap;
    418 	boolean_t fl_key_unwrap;
    419 	boolean_t fl_key_derive;
    420 
    421 	boolean_t fl_init_token;
    422 	boolean_t fl_init_pin;
    423 	boolean_t fl_set_pin;
    424 
    425 	boolean_t prov_is_hash_limited;
    426 	uint32_t prov_hash_threshold;
    427 	uint32_t prov_hash_limit;
    428 } s10_crypto_function_list_t;
    429 
    430 typedef struct s10_crypto_get_function_list {
    431 	uint_t				fl_return_value;
    432 	crypto_provider_id_t		fl_provider_id;
    433 	s10_crypto_function_list_t	fl_list;
    434 } s10_crypto_get_function_list_t;
    435 
    436 /*
    437  * The structure returned by the CRYPTO_GET_FUNCTION_LIST ioctl on /dev/crypto
    438  * increased in size due to:
    439  *	6482533 Threshold for HW offload via PKCS11 interface
    440  * between S10 and Nevada.  This is a relatively simple process of filling
    441  * in the S10 structure fields with the Nevada data.
    442  *
    443  * We stat the device to make sure that the ioctl is meant for /dev/crypto.
    444  *
    445  */
    446 static int
    447 crypto_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
    448 {
    449 	int				err;
    450 	s10_crypto_get_function_list_t	s10_param;
    451 	crypto_get_function_list_t	native_param;
    452 	static dev_t			crypto_dev = (dev_t)-1;
    453 
    454 	if (passthru_otherdev_ioctl(&crypto_dev, "/dev/crypto", &err,
    455 	    rval, fdes, cmd, arg) == 1)
    456 		return (err);
    457 
    458 	if (brand_uucopy((const void *)arg, &s10_param, sizeof (s10_param))
    459 	    != 0)
    460 		return (EFAULT);
    461 	struct_assign(native_param, s10_param, fl_provider_id);
    462 	if ((err = __systemcall(rval, SYS_ioctl + 1024, fdes, cmd,
    463 	    &native_param)) != 0)
    464 		return (err);
    465 
    466 	struct_assign(s10_param, native_param, fl_return_value);
    467 	struct_assign(s10_param, native_param, fl_provider_id);
    468 
    469 	struct_assign(s10_param, native_param, fl_list.fl_digest_init);
    470 	struct_assign(s10_param, native_param, fl_list.fl_digest);
    471 	struct_assign(s10_param, native_param, fl_list.fl_digest_update);
    472 	struct_assign(s10_param, native_param, fl_list.fl_digest_key);
    473 	struct_assign(s10_param, native_param, fl_list.fl_digest_final);
    474 
    475 	struct_assign(s10_param, native_param, fl_list.fl_encrypt_init);
    476 	struct_assign(s10_param, native_param, fl_list.fl_encrypt);
    477 	struct_assign(s10_param, native_param, fl_list.fl_encrypt_update);
    478 	struct_assign(s10_param, native_param, fl_list.fl_encrypt_final);
    479 
    480 	struct_assign(s10_param, native_param, fl_list.fl_decrypt_init);
    481 	struct_assign(s10_param, native_param, fl_list.fl_decrypt);
    482 	struct_assign(s10_param, native_param, fl_list.fl_decrypt_update);
    483 	struct_assign(s10_param, native_param, fl_list.fl_decrypt_final);
    484 
    485 	struct_assign(s10_param, native_param, fl_list.fl_mac_init);
    486 	struct_assign(s10_param, native_param, fl_list.fl_mac);
    487 	struct_assign(s10_param, native_param, fl_list.fl_mac_update);
    488 	struct_assign(s10_param, native_param, fl_list.fl_mac_final);
    489 
    490 	struct_assign(s10_param, native_param, fl_list.fl_sign_init);
    491 	struct_assign(s10_param, native_param, fl_list.fl_sign);
    492 	struct_assign(s10_param, native_param, fl_list.fl_sign_update);
    493 	struct_assign(s10_param, native_param, fl_list.fl_sign_final);
    494 	struct_assign(s10_param, native_param, fl_list.fl_sign_recover_init);
    495 	struct_assign(s10_param, native_param, fl_list.fl_sign_recover);
    496 
    497 	struct_assign(s10_param, native_param, fl_list.fl_verify_init);
    498 	struct_assign(s10_param, native_param, fl_list.fl_verify);
    499 	struct_assign(s10_param, native_param, fl_list.fl_verify_update);
    500 	struct_assign(s10_param, native_param, fl_list.fl_verify_final);
    501 	struct_assign(s10_param, native_param, fl_list.fl_verify_recover_init);
    502 	struct_assign(s10_param, native_param, fl_list.fl_verify_recover);
    503 
    504 	struct_assign(s10_param, native_param,
    505 	    fl_list.fl_digest_encrypt_update);
    506 	struct_assign(s10_param, native_param,
    507 	    fl_list.fl_decrypt_digest_update);
    508 	struct_assign(s10_param, native_param, fl_list.fl_sign_encrypt_update);
    509 	struct_assign(s10_param, native_param,
    510 	    fl_list.fl_decrypt_verify_update);
    511 
    512 	struct_assign(s10_param, native_param, fl_list.fl_seed_random);
    513 	struct_assign(s10_param, native_param, fl_list.fl_generate_random);
    514 
    515 	struct_assign(s10_param, native_param, fl_list.fl_session_open);
    516 	struct_assign(s10_param, native_param, fl_list.fl_session_close);
    517 	struct_assign(s10_param, native_param, fl_list.fl_session_login);
    518 	struct_assign(s10_param, native_param, fl_list.fl_session_logout);
    519 
    520 	struct_assign(s10_param, native_param, fl_list.fl_object_create);
    521 	struct_assign(s10_param, native_param, fl_list.fl_object_copy);
    522 	struct_assign(s10_param, native_param, fl_list.fl_object_destroy);
    523 	struct_assign(s10_param, native_param, fl_list.fl_object_get_size);
    524 	struct_assign(s10_param, native_param,
    525 	    fl_list.fl_object_get_attribute_value);
    526 	struct_assign(s10_param, native_param,
    527 	    fl_list.fl_object_set_attribute_value);
    528 	struct_assign(s10_param, native_param, fl_list.fl_object_find_init);
    529 	struct_assign(s10_param, native_param, fl_list.fl_object_find);
    530 	struct_assign(s10_param, native_param, fl_list.fl_object_find_final);
    531 
    532 	struct_assign(s10_param, native_param, fl_list.fl_key_generate);
    533 	struct_assign(s10_param, native_param, fl_list.fl_key_generate_pair);
    534 	struct_assign(s10_param, native_param, fl_list.fl_key_wrap);
    535 	struct_assign(s10_param, native_param, fl_list.fl_key_unwrap);
    536 	struct_assign(s10_param, native_param, fl_list.fl_key_derive);
    537 
    538 	struct_assign(s10_param, native_param, fl_list.fl_init_token);
    539 	struct_assign(s10_param, native_param, fl_list.fl_init_pin);
    540 	struct_assign(s10_param, native_param, fl_list.fl_set_pin);
    541 
    542 	struct_assign(s10_param, native_param, fl_list.prov_is_hash_limited);
    543 	struct_assign(s10_param, native_param, fl_list.prov_hash_threshold);
    544 	struct_assign(s10_param, native_param, fl_list.prov_hash_limit);
    545 
    546 	return (brand_uucopy(&s10_param, (void *)arg, sizeof (s10_param)));
    547 }
    548 
    549 /*
    550  * The process contract CT_TGET and CT_TSET parameter structure ct_param_t
    551  * changed between S10 and Nevada, so we have to emulate the old S10
    552  * ct_param_t structure when interposing on the ioctl syscall.
    553  */
    554 typedef struct s10_ct_param {
    555 	uint32_t ctpm_id;
    556 	uint32_t ctpm_pad;
    557 	uint64_t ctpm_value;
    558 } s10_ct_param_t;
    559 
    560 /*
    561  * We have to emulate process contract ioctls for init(1M) because the
    562  * ioctl parameter structure changed between S10 and Nevada.  This is
    563  * a relatively simple process of filling Nevada structure fields,
    564  * shuffling values, and initiating a native system call.
    565  *
    566  * For now, we'll assume that all consumers of CT_TGET and CT_TSET will
    567  * need emulation.  We'll issue a stat to make sure that the ioctl
    568  * is meant for the contract file system.
    569  *
    570  */
    571 static int
    572 ctfs_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
    573 {
    574 	int err;
    575 	s10_ct_param_t s10param;
    576 	ct_param_t param;
    577 	struct stat statbuf;
    578 
    579 	if ((err = __systemcall(rval, SYS_fstatat + 1024,
    580 	    fdes, NULL, &statbuf, 0)) != 0)
    581 		return (err);
    582 	if (strcmp(statbuf.st_fstype, MNTTYPE_CTFS) != 0)
    583 		return (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg));
    584 
    585 	if (brand_uucopy((const void *)arg, &s10param, sizeof (s10param)) != 0)
    586 		return (EFAULT);
    587 	param.ctpm_id = s10param.ctpm_id;
    588 	param.ctpm_size = sizeof (uint64_t);
    589 	param.ctpm_value = &s10param.ctpm_value;
    590 	if ((err = __systemcall(rval, SYS_ioctl + 1024, fdes, cmd, &param))
    591 	    != 0)
    592 		return (err);
    593 
    594 	if (cmd == CT_TGET)
    595 		return (brand_uucopy(&s10param, (void *)arg,
    596 		    sizeof (s10param)));
    597 
    598 	return (0);
    599 }
    600 
    601 /*
    602  * ZFS ioctls have changed in each Solaris 10 (S10) release as well as in
    603  * Solaris Next.  The brand wraps ZFS commands so that the native commands
    604  * are used, but we want to be sure no command sneaks in that uses ZFS
    605  * without our knowledge.  We'll abort the process if we see a ZFS ioctl.
    606  */
    607 static int
    608 zfs_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
    609 {
    610 	static dev_t zfs_dev = (dev_t)-1;
    611 	int err;
    612 
    613 	if (passthru_otherdev_ioctl(&zfs_dev, ZFS_DEV, &err,
    614 	    rval, fdes, cmd, arg) == 1)
    615 		return (err);
    616 
    617 	brand_abort(0, "ZFS ioctl!");
    618 	/*NOTREACHED*/
    619 	return (0);
    620 }
    621 
    622 struct s10_lofi_ioctl {
    623 	uint32_t li_minor;
    624 	boolean_t li_force;
    625 	char li_filename[MAXPATHLEN + 1];
    626 };
    627 
    628 static int
    629 lofi_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
    630 {
    631 	static dev_t lofi_dev = (dev_t)-1;
    632 	struct s10_lofi_ioctl s10_param;
    633 	struct lofi_ioctl native_param;
    634 	int err;
    635 
    636 	if (passthru_otherdev_ioctl(&lofi_dev, "/dev/lofictl", &err,
    637 	    rval, fdes, cmd, arg) == 1)
    638 		return (err);
    639 
    640 	if (brand_uucopy((const void *)arg, &s10_param,
    641 	    sizeof (s10_param)) != 0)
    642 		return (EFAULT);
    643 
    644 	/*
    645 	 * Somewhat weirdly, EIO is what the S10 lofi driver would
    646 	 * return for unrecognised cmds.
    647 	 */
    648 	if (cmd >= LOFI_CHECK_COMPRESSED)
    649 		return (EIO);
    650 
    651 	bzero(&native_param, sizeof (native_param));
    652 
    653 	struct_assign(native_param, s10_param, li_minor);
    654 	struct_assign(native_param, s10_param, li_force);
    655 
    656 	/*
    657 	 * Careful here, this has changed from [MAXPATHLEN + 1] to
    658 	 * [MAXPATHLEN].
    659 	 */
    660 	bcopy(s10_param.li_filename, native_param.li_filename,
    661 	    sizeof (native_param.li_filename));
    662 	native_param.li_filename[MAXPATHLEN - 1] = '\0';
    663 
    664 	err = __systemcall(rval, SYS_ioctl + 1024, fdes, cmd, &native_param);
    665 
    666 	struct_assign(s10_param, native_param, li_minor);
    667 	/* li_force is input-only */
    668 
    669 	bcopy(native_param.li_filename, s10_param.li_filename,
    670 	    sizeof (native_param.li_filename));
    671 
    672 	(void) brand_uucopy(&s10_param, (void *)arg, sizeof (s10_param));
    673 	return (err);
    674 }
    675 
    676 int
    677 s10_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
    678 {
    679 	switch (cmd) {
    680 	case CRYPTO_GET_FUNCTION_LIST:
    681 		return (crypto_ioctl(rval, fdes, cmd, arg));
    682 	case CT_TGET:
    683 		/*FALLTHRU*/
    684 	case CT_TSET:
    685 		return (ctfs_ioctl(rval, fdes, cmd, arg));
    686 	case MNTIOC_GETMNTENT:
    687 		/*FALLTHRU*/
    688 	case MNTIOC_GETEXTMNTENT:
    689 		/*FALLTHRU*/
    690 	case MNTIOC_GETMNTANY:
    691 		return (mntfs_ioctl(rval, fdes, cmd, arg));
    692 	}
    693 
    694 	switch (cmd & ~0xff) {
    695 	case ZFS_IOC:
    696 		return (zfs_ioctl(rval, fdes, cmd, arg));
    697 
    698 	case LOFI_IOC_BASE:
    699 		return (lofi_ioctl(rval, fdes, cmd, arg));
    700 
    701 	default:
    702 		break;
    703 	}
    704 
    705 	return (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg));
    706 }
    707 
    708 /*
    709  * Unfortunately, pwrite()'s behavior differs between S10 and Nevada when
    710  * applied to files opened with O_APPEND.  The offset argument is ignored and
    711  * the buffer is appended to the target file in S10, whereas the current file
    712  * position is ignored in Nevada (i.e., pwrite() acts as though the target file
    713  * wasn't opened with O_APPEND).  This is a result of the fix for CR 6655660
    714  * (pwrite() must ignore the O_APPEND/FAPPEND flag).
    715  *
    716  * We emulate the old S10 pwrite() behavior by checking whether the target file
    717  * was opened with O_APPEND.  If it was, then invoke the write() system call
    718  * instead of pwrite(); otherwise, invoke the pwrite() system call as usual.
    719  */
    720 static int
    721 s10_pwrite(sysret_t *rval, int fd, const void *bufferp, size_t num_bytes,
    722     off_t offset)
    723 {
    724 	int err;
    725 
    726 	if ((err = __systemcall(rval, SYS_fcntl + 1024, fd, F_GETFL)) != 0)
    727 		return (err);
    728 	if (rval->sys_rval1 & O_APPEND)
    729 		return (__systemcall(rval, SYS_write + 1024, fd, bufferp,
    730 		    num_bytes));
    731 	return (__systemcall(rval, SYS_pwrite + 1024, fd, bufferp, num_bytes,
    732 	    offset));
    733 }
    734 
    735 #if !defined(_LP64)
    736 /*
    737  * This is the large file version of the pwrite() system call for 32-bit
    738  * processes.  This exists for the same reason that s10_pwrite() exists; see
    739  * the comment above s10_pwrite().
    740  */
    741 static int
    742 s10_pwrite64(sysret_t *rval, int fd, const void *bufferp, size32_t num_bytes,
    743     uint32_t offset_1, uint32_t offset_2)
    744 {
    745 	int err;
    746 
    747 	if ((err = __systemcall(rval, SYS_fcntl + 1024, fd, F_GETFL)) != 0)
    748 		return (err);
    749 	if (rval->sys_rval1 & O_APPEND)
    750 		return (__systemcall(rval, SYS_write + 1024, fd, bufferp,
    751 		    num_bytes));
    752 	return (__systemcall(rval, SYS_pwrite64 + 1024, fd, bufferp,
    753 	    num_bytes, offset_1, offset_2));
    754 }
    755 #endif	/* !_LP64 */
    756 
    757 /*
    758  * These are convenience macros that s10_getdents_common() uses.  Both treat
    759  * their arguments, which should be character pointers, as dirent pointers or
    760  * dirent64 pointers and yield their d_name and d_reclen fields.  These
    761  * macros shouldn't be used outside of s10_getdents_common().
    762  */
    763 #define	dirent_name(charptr)	((charptr) + name_offset)
    764 #define	dirent_reclen(charptr)	\
    765 	(*(unsigned short *)(uintptr_t)((charptr) + reclen_offset))
    766 
    767 /*
    768  * This function contains code that is common to both s10_getdents() and
    769  * s10_getdents64().  See the comment above s10_getdents() for details.
    770  *
    771  * rval, fd, buf, and nbyte should be passed unmodified from s10_getdents()
    772  * and s10_getdents64().  getdents_syscall_id should be either SYS_getdents
    773  * or SYS_getdents64.  name_offset should be the the byte offset of
    774  * the d_name field in the dirent structures passed to the kernel via the
    775  * syscall represented by getdents_syscall_id.  reclen_offset should be
    776  * the byte offset of the d_reclen field in the aforementioned dirent
    777  * structures.
    778  */
    779 static int
    780 s10_getdents_common(sysret_t *rval, int fd, char *buf, size_t nbyte,
    781     int getdents_syscall_id, size_t name_offset, size_t reclen_offset)
    782 {
    783 	int err;
    784 	size_t buf_size;
    785 	char *local_buf;
    786 	char *buf_current;
    787 
    788 	/*
    789 	 * Use a special brand operation, B_S10_ISFDXATTRDIR, to determine
    790 	 * whether the specified file descriptor refers to an extended file
    791 	 * attribute directory.  If it doesn't, then SYS_getdents won't
    792 	 * reveal extended file attributes, in which case we can simply
    793 	 * hand the syscall to the native kernel.
    794 	 */
    795 	if ((err = __systemcall(rval, SYS_brand + 1024, B_S10_ISFDXATTRDIR,
    796 	    fd)) != 0)
    797 		return (err);
    798 	if (rval->sys_rval1 == 0)
    799 		return (__systemcall(rval, getdents_syscall_id + 1024, fd, buf,
    800 		    nbyte));
    801 
    802 	/*
    803 	 * The file descriptor refers to an extended file attributes directory.
    804 	 * We need to create a dirent buffer that's as large as buf into which
    805 	 * the native SYS_getdents will store the special extended file
    806 	 * attribute directory's entries.  We can't dereference buf because
    807 	 * it might be an invalid pointer!
    808 	 */
    809 	if (nbyte > MAXGETDENTS_SIZE)
    810 		nbyte = MAXGETDENTS_SIZE;
    811 	local_buf = (char *)malloc(nbyte);
    812 	if (local_buf == NULL) {
    813 		/*
    814 		 * getdents(2) doesn't return an error code indicating a memory
    815 		 * allocation error and it doesn't make sense to return any of
    816 		 * its documented error codes for a malloc(3C) failure.  We'll
    817 		 * use ENOMEM even though getdents(2) doesn't use it because it
    818 		 * best describes the failure.
    819 		 */
    820 		(void) B_TRUSS_POINT_3(rval, getdents_syscall_id, ENOMEM, fd,
    821 		    buf, nbyte);
    822 		rval->sys_rval1 = -1;
    823 		rval->sys_rval2 = 0;
    824 		return (EIO);
    825 	}
    826 
    827 	/*
    828 	 * Issue a native SYS_getdents syscall but use our local dirent buffer
    829 	 * instead of buf.  This will allow us to examine the returned dirent
    830 	 * structures immediately and copy them to buf later.  That way the
    831 	 * calling process won't be able to see the dirent structures until
    832 	 * we finish examining them.
    833 	 */
    834 	if ((err = __systemcall(rval, getdents_syscall_id + 1024, fd, local_buf,
    835 	    nbyte)) != 0) {
    836 		free(local_buf);
    837 		return (err);
    838 	}
    839 	buf_size = rval->sys_rval1;
    840 	if (buf_size == 0) {
    841 		free(local_buf);
    842 		return (0);
    843 	}
    844 
    845 	/*
    846 	 * Look for SUNWattr_ro (VIEW_READONLY) and SUNWattr_rw
    847 	 * (VIEW_READWRITE) in the directory entries and remove them
    848 	 * from the dirent buffer.
    849 	 */
    850 	for (buf_current = local_buf;
    851 	    (size_t)(buf_current - local_buf) < buf_size; /* cstyle */) {
    852 		if (strcmp(dirent_name(buf_current), VIEW_READONLY) != 0 &&
    853 		    strcmp(dirent_name(buf_current), VIEW_READWRITE) != 0) {
    854 			/*
    855 			 * The dirent refers to an attribute that should
    856 			 * be visible to Solaris 10 processes.  Keep it
    857 			 * and examine the next entry in the buffer.
    858 			 */
    859 			buf_current += dirent_reclen(buf_current);
    860 		} else {
    861 			/*
    862 			 * We found either SUNWattr_ro (VIEW_READONLY)
    863 			 * or SUNWattr_rw (VIEW_READWRITE).  Remove it
    864 			 * from the dirent buffer by decrementing
    865 			 * buf_size by the size of the entry and
    866 			 * overwriting the entry with the remaining
    867 			 * entries.
    868 			 */
    869 			buf_size -= dirent_reclen(buf_current);
    870 			(void) memmove(buf_current, buf_current +
    871 			    dirent_reclen(buf_current), buf_size -
    872 			    (size_t)(buf_current - local_buf));
    873 		}
    874 	}
    875 
    876 	/*
    877 	 * Copy local_buf into buf so that the calling process can see
    878 	 * the results.
    879 	 */
    880 	if ((err = brand_uucopy(local_buf, buf, buf_size)) != 0) {
    881 		free(local_buf);
    882 		rval->sys_rval1 = -1;
    883 		rval->sys_rval2 = 0;
    884 		return (err);
    885 	}
    886 	rval->sys_rval1 = buf_size;
    887 	free(local_buf);
    888 	return (0);
    889 }
    890 
    891 /*
    892  * Solaris Next added two special extended file attributes, SUNWattr_ro and
    893  * SUNWattr_rw, which are called "extended system attributes".  They have
    894  * special semantics (e.g., a process cannot unlink SUNWattr_ro) and should
    895  * not appear in solaris10-branded zones because no Solaris 10 applications,
    896  * including system commands such as tar(1), are coded to correctly handle these
    897  * special attributes.
    898  *
    899  * This emulation function solves the aforementioned problem by emulating
    900  * the getdents(2) syscall and filtering both system attributes out of resulting
    901  * directory entry lists.  The emulation function only filters results when
    902  * the given file descriptor refers to an extended file attribute directory.
    903  * Filtering getdents(2) results is expensive because it requires dynamic
    904  * memory allocation; however, the performance cost is tolerable because
    905  * we don't expect Solaris 10 processes to frequently examine extended file
    906  * attribute directories.
    907  *
    908  * The brand's emulation library needs two getdents(2) emulation functions
    909  * because getdents(2) comes in two flavors: non-largefile-aware getdents(2)
    910  * and largefile-aware getdents64(2).  s10_getdents() handles the non-largefile-
    911  * aware case for 32-bit processes and all getdents(2) syscalls for 64-bit
    912  * processes (64-bit processes use largefile-aware interfaces by default).
    913  * See s10_getdents64() below for the largefile-aware getdents64(2) emulation
    914  * function for 32-bit processes.
    915  */
    916 static int
    917 s10_getdents(sysret_t *rval, int fd, struct dirent *buf, size_t nbyte)
    918 {
    919 	return (s10_getdents_common(rval, fd, (char *)buf, nbyte, SYS_getdents,
    920 	    offsetof(struct dirent, d_name),
    921 	    offsetof(struct dirent, d_reclen)));
    922 }
    923 
    924 #ifndef	_LP64
    925 /*
    926  * This is the largefile-aware version of getdents(2) for 32-bit processes.
    927  * This exists for the same reason that s10_getdents() exists.  See the comment
    928  * above s10_getdents().
    929  */
    930 static int
    931 s10_getdents64(sysret_t *rval, int fd, struct dirent64 *buf, size_t nbyte)
    932 {
    933 	return (s10_getdents_common(rval, fd, (char *)buf, nbyte,
    934 	    SYS_getdents64, offsetof(struct dirent64, d_name),
    935 	    offsetof(struct dirent64, d_reclen)));
    936 }
    937 #endif	/* !_LP64 */
    938 
    939 #define	S10_TRIVIAL_ACL_CNT	6
    940 #define	NATIVE_TRIVIAL_ACL_CNT	3
    941 
    942 /*
    943  * Check if the ACL qualifies as a trivial ACL based on the native
    944  * interpretation.
    945  */
    946 static boolean_t
    947 has_trivial_native_acl(int cmd, int cnt, const char *fname, int fd)
    948 {
    949 	int i, err;
    950 	sysret_t rval;
    951 	ace_t buf[NATIVE_TRIVIAL_ACL_CNT];
    952 
    953 	if (fname != NULL)
    954 		err = __systemcall(&rval, SYS_pathconf + 1024, fname,
    955 		    _PC_ACL_ENABLED);
    956 	else
    957 		err = __systemcall(&rval, SYS_fpathconf + 1024, fd,
    958 		    _PC_ACL_ENABLED);
    959 	if (err != 0 || rval.sys_rval1 != _ACL_ACE_ENABLED)
    960 		return (B_FALSE);
    961 
    962 	/*
    963 	 * If we just got the ACL cnt, we don't need to get it again, its
    964 	 * passed in as the cnt arg.
    965 	 */
    966 	if (cmd != ACE_GETACLCNT) {
    967 		if (fname != NULL) {
    968 			if (__systemcall(&rval, SYS_acl + 1024, fname,
    969 			    ACE_GETACLCNT, 0, NULL) != 0)
    970 				return (B_FALSE);
    971 		} else {
    972 			if (__systemcall(&rval, SYS_facl + 1024, fd,
    973 			    ACE_GETACLCNT, 0, NULL) != 0)
    974 				return (B_FALSE);
    975 		}
    976 		cnt = rval.sys_rval1;
    977 	}
    978 
    979 	if (cnt != NATIVE_TRIVIAL_ACL_CNT)
    980 		return (B_FALSE);
    981 
    982 	if (fname != NULL) {
    983 		if (__systemcall(&rval, SYS_acl + 1024, fname, ACE_GETACL, cnt,
    984 		    buf) != 0)
    985 			return (B_FALSE);
    986 	} else {
    987 		if (__systemcall(&rval, SYS_facl + 1024, fd, ACE_GETACL, cnt,
    988 		    buf) != 0)
    989 			return (B_FALSE);
    990 	}
    991 
    992 	/*
    993 	 * The following is based on the logic from the native OS
    994 	 * ace_trivial_common() to determine if the native ACL is trivial.
    995 	 */
    996 	for (i = 0; i < cnt; i++) {
    997 		switch (buf[i].a_flags & ACE_TYPE_FLAGS) {
    998 		case ACE_OWNER:
    999 		case ACE_GROUP|ACE_IDENTIFIER_GROUP:
   1000 		case ACE_EVERYONE:
   1001 			break;
   1002 		default:
   1003 			return (B_FALSE);
   1004 		}
   1005 
   1006 		if (buf[i].a_flags & (ACE_FILE_INHERIT_ACE|
   1007 		    ACE_DIRECTORY_INHERIT_ACE|ACE_NO_PROPAGATE_INHERIT_ACE|
   1008 		    ACE_INHERIT_ONLY_ACE))
   1009 			return (B_FALSE);
   1010 
   1011 		/*
   1012 		 * Special check for some special bits
   1013 		 *
   1014 		 * Don't allow anybody to deny reading basic
   1015 		 * attributes or a files ACL.
   1016 		 */
   1017 		if (buf[i].a_access_mask & (ACE_READ_ACL|ACE_READ_ATTRIBUTES) &&
   1018 		    buf[i].a_type == ACE_ACCESS_DENIED_ACE_TYPE)
   1019 			return (B_FALSE);
   1020 
   1021 		/*
   1022 		 * Delete permissions are never set by default
   1023 		 */
   1024 		if (buf[i].a_access_mask & (ACE_DELETE|ACE_DELETE_CHILD))
   1025 			return (B_FALSE);
   1026 		/*
   1027 		 * only allow owner@ to have
   1028 		 * write_acl/write_owner/write_attributes/write_xattr/
   1029 		 */
   1030 		if (buf[i].a_type == ACE_ACCESS_ALLOWED_ACE_TYPE &&
   1031 		    (!(buf[i].a_flags & ACE_OWNER) && (buf[i].a_access_mask &
   1032 		    (ACE_WRITE_OWNER|ACE_WRITE_ACL| ACE_WRITE_ATTRIBUTES|
   1033 		    ACE_WRITE_NAMED_ATTRS))))
   1034 			return (B_FALSE);
   1035 
   1036 	}
   1037 
   1038 	return (B_TRUE);
   1039 }
   1040 
   1041 /*
   1042  * The following logic is based on the S10 adjust_ace_pair_common() code.
   1043  */
   1044 static void
   1045 s10_adjust_ace_mask(void *pair, size_t access_off, size_t pairsize, mode_t mode)
   1046 {
   1047 	char *datap = (char *)pair;
   1048 	uint32_t *amask0 = (uint32_t *)(uintptr_t)(datap + access_off);
   1049 	uint32_t *amask1 = (uint32_t *)(uintptr_t)(datap + pairsize +
   1050 	    access_off);
   1051 
   1052 	if (mode & S_IROTH)
   1053 		*amask1 |= ACE_READ_DATA;
   1054 	else
   1055 		*amask0 |= ACE_READ_DATA;
   1056 	if (mode & S_IWOTH)
   1057 		*amask1 |= ACE_WRITE_DATA|ACE_APPEND_DATA;
   1058 	else
   1059 		*amask0 |= ACE_WRITE_DATA|ACE_APPEND_DATA;
   1060 	if (mode & S_IXOTH)
   1061 		*amask1 |= ACE_EXECUTE;
   1062 	else
   1063 		*amask0 |= ACE_EXECUTE;
   1064 }
   1065 
   1066 /*
   1067  * Construct a trivial S10 style ACL.
   1068  */
   1069 static int
   1070 make_trivial_s10_acl(const char *fname, int fd, ace_t *bp)
   1071 {
   1072 	int err;
   1073 	sysret_t rval;
   1074 	struct stat64 buf;
   1075 	ace_t trivial_s10_acl[] = {
   1076 		{(uint_t)-1, 0, ACE_OWNER, ACE_ACCESS_DENIED_ACE_TYPE},
   1077 		{(uint_t)-1, ACE_WRITE_ACL|ACE_WRITE_OWNER|ACE_WRITE_ATTRIBUTES|
   1078 		    ACE_WRITE_NAMED_ATTRS, ACE_OWNER,
   1079 		    ACE_ACCESS_ALLOWED_ACE_TYPE},
   1080 		{(uint_t)-1, 0, ACE_GROUP|ACE_IDENTIFIER_GROUP,
   1081 		    ACE_ACCESS_DENIED_ACE_TYPE},
   1082 		{(uint_t)-1, 0, ACE_GROUP|ACE_IDENTIFIER_GROUP,
   1083 		    ACE_ACCESS_ALLOWED_ACE_TYPE},
   1084 		{(uint_t)-1, ACE_WRITE_ACL|ACE_WRITE_OWNER|ACE_WRITE_ATTRIBUTES|
   1085 		    ACE_WRITE_NAMED_ATTRS, ACE_EVERYONE,
   1086 		    ACE_ACCESS_DENIED_ACE_TYPE},
   1087 		{(uint_t)-1, ACE_READ_ACL|ACE_READ_ATTRIBUTES|
   1088 		    ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE, ACE_EVERYONE,
   1089 		    ACE_ACCESS_ALLOWED_ACE_TYPE}
   1090 	};
   1091 
   1092 	if (fname != NULL) {
   1093 		if ((err = __systemcall(&rval, SYS_fstatat64 + 1024, AT_FDCWD,
   1094 		    fname, &buf, 0)) != 0)
   1095 			return (err);
   1096 	} else {
   1097 		if ((err = __systemcall(&rval, SYS_fstatat64 + 1024, fd,
   1098 		    NULL, &buf, 0)) != 0)
   1099 			return (err);
   1100 	}
   1101 
   1102 	s10_adjust_ace_mask(&trivial_s10_acl[0], offsetof(ace_t, a_access_mask),
   1103 	    sizeof (ace_t), (buf.st_mode & 0700) >> 6);
   1104 	s10_adjust_ace_mask(&trivial_s10_acl[2], offsetof(ace_t, a_access_mask),
   1105 	    sizeof (ace_t), (buf.st_mode & 0070) >> 3);
   1106 	s10_adjust_ace_mask(&trivial_s10_acl[4], offsetof(ace_t, a_access_mask),
   1107 	    sizeof (ace_t), buf.st_mode & 0007);
   1108 
   1109 	if (brand_uucopy(&trivial_s10_acl, bp, sizeof (trivial_s10_acl)) != 0)
   1110 		return (EFAULT);
   1111 
   1112 	return (0);
   1113 }
   1114 
   1115 /*
   1116  * The definition of a trivial ace-style ACL (used by ZFS and NFSv4) has been
   1117  * simplified since S10.  Instead of 6 entries on a trivial S10 ACE ACL we now
   1118  * have 3 streamlined entries.  The new, simpler trivial style confuses S10
   1119  * commands such as 'ls -v' or 'cp -p' which don't see the expected S10 trivial
   1120  * ACL entries and thus assume that there is a complex ACL on the file.
   1121  *
   1122  * See: PSARC/2010/029 Improved ACL interoperability
   1123  *
   1124  * Note that the trival ACL detection code is implemented in acl_trival() in
   1125  * lib/libsec/common/aclutils.c.  It always uses the acl() syscall (not the
   1126  * facl syscall) to determine if an ACL is trivial.  However, we emulate both
   1127  * acl() and facl() so that the two provide consistent results.
   1128  *
   1129  * We don't currently try to emulate setting of ACLs since the primary
   1130  * consumer of this feature is SMB or NFSv4 servers, neither of which are
   1131  * supported in solaris10-branded zones.  If ACLs are used they must be set on
   1132  * files using the native OS interpretation.
   1133  */
   1134 int
   1135 s10_acl(sysret_t *rval, const char *fname, int cmd, int nentries, void *aclbufp)
   1136 {
   1137 	int res;
   1138 
   1139 	res = __systemcall(rval, SYS_acl + 1024, fname, cmd, nentries, aclbufp);
   1140 
   1141 	switch (cmd) {
   1142 	case ACE_GETACLCNT:
   1143 		if (res == 0 && has_trivial_native_acl(ACE_GETACLCNT,
   1144 		    rval->sys_rval1, fname, 0)) {
   1145 			rval->sys_rval1 = S10_TRIVIAL_ACL_CNT;
   1146 		}
   1147 		break;
   1148 	case ACE_GETACL:
   1149 		if (res == 0 &&
   1150 		    has_trivial_native_acl(ACE_GETACL, 0, fname, 0) &&
   1151 		    nentries >= S10_TRIVIAL_ACL_CNT) {
   1152 			res = make_trivial_s10_acl(fname, 0, aclbufp);
   1153 			rval->sys_rval1 = S10_TRIVIAL_ACL_CNT;
   1154 		}
   1155 		break;
   1156 	}
   1157 
   1158 	return (res);
   1159 }
   1160 
   1161 int
   1162 s10_facl(sysret_t *rval, int fdes, int cmd, int nentries, void *aclbufp)
   1163 {
   1164 	int res;
   1165 
   1166 	res = __systemcall(rval, SYS_facl + 1024, fdes, cmd, nentries, aclbufp);
   1167 
   1168 	switch (cmd) {
   1169 	case ACE_GETACLCNT:
   1170 		if (res == 0 && has_trivial_native_acl(ACE_GETACLCNT,
   1171 		    rval->sys_rval1, NULL, fdes)) {
   1172 			rval->sys_rval1 = S10_TRIVIAL_ACL_CNT;
   1173 		}
   1174 		break;
   1175 	case ACE_GETACL:
   1176 		if (res == 0 &&
   1177 		    has_trivial_native_acl(ACE_GETACL, 0, NULL, fdes) &&
   1178 		    nentries >= S10_TRIVIAL_ACL_CNT) {
   1179 			res = make_trivial_s10_acl(NULL, fdes, aclbufp);
   1180 			rval->sys_rval1 = S10_TRIVIAL_ACL_CNT;
   1181 		}
   1182 		break;
   1183 	}
   1184 
   1185 	return (res);
   1186 }
   1187 
   1188 #define	S10_AC_PROC		(0x1 << 28)
   1189 #define	S10_AC_TASK		(0x2 << 28)
   1190 #define	S10_AC_FLOW		(0x4 << 28)
   1191 #define	S10_AC_MODE(x)		((x) & 0xf0000000)
   1192 #define	S10_AC_OPTION(x)	((x) & 0x0fffffff)
   1193 
   1194 /*
   1195  * The mode shift, mode mask and option mask for acctctl have changed.  The
   1196  * mode is currently the top full byte and the option is the lower 3 full bytes.
   1197  */
   1198 int
   1199 s10_acctctl(sysret_t *rval, int cmd, void *buf, size_t bufsz)
   1200 {
   1201 	int mode = S10_AC_MODE(cmd);
   1202 	int option = S10_AC_OPTION(cmd);
   1203 
   1204 	switch (mode) {
   1205 	case S10_AC_PROC:
   1206 		mode = AC_PROC;
   1207 		break;
   1208 	case S10_AC_TASK:
   1209 		mode = AC_TASK;
   1210 		break;
   1211 	case S10_AC_FLOW:
   1212 		mode = AC_FLOW;
   1213 		break;
   1214 	default:
   1215 		return (B_TRUSS_POINT_3(rval, SYS_acctctl, EINVAL, cmd, buf,
   1216 		    bufsz));
   1217 	}
   1218 
   1219 	return (__systemcall(rval, SYS_acctctl + 1024, mode | option, buf,
   1220 	    bufsz));
   1221 }
   1222 
   1223 /*
   1224  * The Audit Policy parameters have changed due to:
   1225  *    6466722 audituser and AUDIT_USER are defined, unused, undocumented and
   1226  *            should be removed.
   1227  *
   1228  * In S10 we had the following flag:
   1229  *	#define AUDIT_USER 0x0040
   1230  * which doesn't exist in Solaris Next where the subsequent flags are shifted
   1231  * down.  For example, in S10 we had:
   1232  *	#define AUDIT_GROUP     0x0080
   1233  * but on Solaris Next we have:
   1234  *	#define AUDIT_GROUP     0x0040
   1235  * AUDIT_GROUP has the value AUDIT_USER had in S10 and all of the subsequent
   1236  * bits are also shifted one place.
   1237  *
   1238  * When we're getting or setting the Audit Policy parameters we need to
   1239  * shift the outgoing or incoming bits into their proper positions.  Since
   1240  * S10_AUDIT_USER was always unused, we always clear that bit on A_GETPOLICY.
   1241  *
   1242  * The command we care about, BSM_AUDITCTL, passes the most parameters (3),
   1243  * so declare this function to take up to 4 args and just pass them on.
   1244  * The number of parameters for s10_auditsys needs to be equal to the BSM_*
   1245  * subcommand that has the most parameters, since we want to pass all
   1246  * parameters through, regardless of which subcommands we interpose on.
   1247  *
   1248  * Note that the auditsys system call uses the SYSENT_AP macro wrapper instead
   1249  * of the more common SYSENT_CI macro.  This means the return value is a
   1250  * SE_64RVAL so the syscall table uses RV_64RVAL.
   1251  */
   1252 
   1253 #define	S10_AUDIT_HMASK	0xffffffc0
   1254 #define	S10_AUDIT_LMASK	0x3f
   1255 #define	S10_AUC_NOSPACE	0x3
   1256 
   1257 int
   1258 s10_auditsys(sysret_t *rval, int bsmcmd, intptr_t a0, intptr_t a1, intptr_t a2)
   1259 {
   1260 	int	    err;
   1261 	uint32_t    m;
   1262 
   1263 	if (bsmcmd != BSM_AUDITCTL)
   1264 		return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, a1,
   1265 		    a2));
   1266 
   1267 	if ((int)a0 == A_GETPOLICY) {
   1268 		if ((err = __systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0,
   1269 		    &m, a2)) != 0)
   1270 			return (err);
   1271 		m = ((m & S10_AUDIT_HMASK) << 1) | (m & S10_AUDIT_LMASK);
   1272 		if (brand_uucopy(&m, (void *)a1, sizeof (m)) != 0)
   1273 			return (EFAULT);
   1274 		return (0);
   1275 
   1276 	} else if ((int)a0 == A_SETPOLICY) {
   1277 		if (brand_uucopy((const void *)a1, &m, sizeof (m)) != 0)
   1278 			return (EFAULT);
   1279 		m = ((m >> 1) & S10_AUDIT_HMASK) | (m & S10_AUDIT_LMASK);
   1280 		return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, &m,
   1281 		    a2));
   1282 	} else if ((int)a0 == A_GETCOND) {
   1283 		if ((err = __systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0,
   1284 		    &m, a2)) != 0)
   1285 			return (err);
   1286 		if (m == AUC_NOSPACE)
   1287 			m = S10_AUC_NOSPACE;
   1288 		if (brand_uucopy(&m, (void *)a1, sizeof (m)) != 0)
   1289 			return (EFAULT);
   1290 		return (0);
   1291 	} else if ((int)a0 == A_SETCOND) {
   1292 		if (brand_uucopy((const void *)a1, &m, sizeof (m)) != 0)
   1293 			return (EFAULT);
   1294 		if (m == S10_AUC_NOSPACE)
   1295 			m = AUC_NOSPACE;
   1296 		return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, &m,
   1297 		    a2));
   1298 	}
   1299 
   1300 	return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, a1, a2));
   1301 }
   1302 
   1303 /*
   1304  * Determine whether the executable passed to SYS_exec or SYS_execve is a
   1305  * native executable.  The s10_npreload.so invokes the B_S10_NATIVE brand
   1306  * operation which patches up the processes exec info to eliminate any trace
   1307  * of the wrapper.  That will make pgrep and other commands that examine
   1308  * process' executable names and command-line parameters work properly.
   1309  */
   1310 static int
   1311 s10_exec_native(sysret_t *rval, const char *fname, const char **argp,
   1312     const char **envp)
   1313 {
   1314 	const char *filename = fname;
   1315 	char path[64];
   1316 	int err;
   1317 
   1318 	/* Get a copy of the executable we're trying to run */
   1319 	path[0] = '\0';
   1320 	(void) brand_uucopystr(filename, path, sizeof (path));
   1321 
   1322 	/* Check if we're trying to run a native binary */
   1323 	if (strncmp(path, "/.SUNWnative/usr/lib/brand/solaris10/s10_native",
   1324 	    sizeof (path)) != 0)
   1325 		return (0);
   1326 
   1327 	/* Skip the first element in the argv array */
   1328 	argp++;
   1329 
   1330 	/*
   1331 	 * The the path of the dynamic linker is the second parameter
   1332 	 * of s10_native_exec().
   1333 	 */
   1334 	if (brand_uucopy(argp, &filename, sizeof (char *)) != 0)
   1335 		return (EFAULT);
   1336 
   1337 	/* If an exec call succeeds, it never returns */
   1338 	err = __systemcall(rval, SYS_brand + 1024, B_EXEC_NATIVE, filename,
   1339 	    argp, envp, NULL, NULL, NULL);
   1340 	brand_assert(err != 0);
   1341 	return (err);
   1342 }
   1343 
   1344 /*
   1345  * Interpose on the SYS_exec syscall to detect native wrappers.
   1346  */
   1347 int
   1348 s10_exec(sysret_t *rval, const char *fname, const char **argp)
   1349 {
   1350 	int err;
   1351 
   1352 	if ((err = s10_exec_native(rval, fname, argp, NULL)) != 0)
   1353 		return (err);
   1354 
   1355 	/* If an exec call succeeds, it never returns */
   1356 	err = __systemcall(rval, SYS_execve + 1024, fname, argp, NULL);
   1357 	brand_assert(err != 0);
   1358 	return (err);
   1359 }
   1360 
   1361 /*
   1362  * Interpose on the SYS_execve syscall to detect native wrappers.
   1363  */
   1364 int
   1365 s10_execve(sysret_t *rval, const char *fname, const char **argp,
   1366     const char **envp)
   1367 {
   1368 	int err;
   1369 
   1370 	if ((err = s10_exec_native(rval, fname, argp, envp)) != 0)
   1371 		return (err);
   1372 
   1373 	/* If an exec call succeeds, it never returns */
   1374 	err = __systemcall(rval, SYS_execve + 1024, fname, argp, envp);
   1375 	brand_assert(err != 0);
   1376 	return (err);
   1377 }
   1378 
   1379 /*
   1380  * S10's issetugid() syscall is now a subcode to privsys().
   1381  */
   1382 static int
   1383 s10_issetugid(sysret_t *rval)
   1384 {
   1385 	return (__systemcall(rval, SYS_privsys + 1024, PRIVSYS_ISSETUGID,
   1386 	    0, 0, 0, 0, 0));
   1387 }
   1388 
   1389 static long
   1390 s10_uname(sysret_t *rv, uintptr_t p1)
   1391 {
   1392 	struct utsname un, *unp = (struct utsname *)p1;
   1393 	int rev, err;
   1394 
   1395 	if ((err = __systemcall(rv, SYS_uname + 1024, &un)) != 0)
   1396 		return (err);
   1397 
   1398 	rev = atoi(&un.release[2]);
   1399 	brand_assert(rev >= 11);
   1400 	bzero(un.release, _SYS_NMLN);
   1401 	(void) strlcpy(un.release, S10_UTS_RELEASE, _SYS_NMLN);
   1402 	bzero(un.version, _SYS_NMLN);
   1403 	(void) strlcpy(un.version, S10_UTS_VERSION, _SYS_NMLN);
   1404 
   1405 	/* copy out the modified uname info */
   1406 	return (brand_uucopy(&un, unp, sizeof (un)));
   1407 }
   1408 
   1409 int
   1410 s10_sysconfig(sysret_t *rv, int which)
   1411 {
   1412 	long value;
   1413 
   1414 	/*
   1415 	 * We must interpose on the sysconfig(2) requests
   1416 	 * that deal with the realtime signal number range.
   1417 	 * All others get passed to the native sysconfig(2).
   1418 	 */
   1419 	switch (which) {
   1420 	case _CONFIG_RTSIG_MAX:
   1421 		value = S10_SIGRTMAX - S10_SIGRTMIN + 1;
   1422 		break;
   1423 	case _CONFIG_SIGRT_MIN:
   1424 		value = S10_SIGRTMIN;
   1425 		break;
   1426 	case _CONFIG_SIGRT_MAX:
   1427 		value = S10_SIGRTMAX;
   1428 		break;
   1429 	default:
   1430 		return (__systemcall(rv, SYS_sysconfig + 1024, which));
   1431 	}
   1432 
   1433 	(void) B_TRUSS_POINT_1(rv, SYS_sysconfig, 0, which);
   1434 	rv->sys_rval1 = value;
   1435 	rv->sys_rval2 = 0;
   1436 
   1437 	return (0);
   1438 }
   1439 
   1440 int
   1441 s10_sysinfo(sysret_t *rv, int command, char *buf, long count)
   1442 {
   1443 	char *value;
   1444 	int len;
   1445 
   1446 	/*
   1447 	 * We must interpose on the sysinfo(2) commands SI_RELEASE and
   1448 	 * SI_VERSION; all others get passed to the native sysinfo(2)
   1449 	 * command.
   1450 	 */
   1451 	switch (command) {
   1452 		case SI_RELEASE:
   1453 			value = S10_UTS_RELEASE;
   1454 			break;
   1455 
   1456 		case SI_VERSION:
   1457 			value = S10_UTS_VERSION;
   1458 			break;
   1459 
   1460 		default:
   1461 			/*
   1462 			 * The default action is to pass the command to the
   1463 			 * native sysinfo(2) syscall.
   1464 			 */
   1465 			return (__systemcall(rv, SYS_systeminfo + 1024,
   1466 			    command, buf, count));
   1467 	}
   1468 
   1469 	len = strlen(value) + 1;
   1470 	if (count > 0) {
   1471 		if (brand_uucopystr(value, buf, count) != 0)
   1472 			return (EFAULT);
   1473 
   1474 		/*
   1475 		 * Assure NULL termination of buf as brand_uucopystr() doesn't.
   1476 		 */
   1477 		if (len > count && brand_uucopy("\0", buf + (count - 1), 1)
   1478 		    != 0)
   1479 			return (EFAULT);
   1480 	}
   1481 
   1482 	/*
   1483 	 * On success, sysinfo(2) returns the size of buffer required to hold
   1484 	 * the complete value plus its terminating NULL byte.
   1485 	 */
   1486 	(void) B_TRUSS_POINT_3(rv, SYS_systeminfo, 0, command, buf, count);
   1487 	rv->sys_rval1 = len;
   1488 	rv->sys_rval2 = 0;
   1489 	return (0);
   1490 }
   1491 
   1492 #if defined(__x86)
   1493 #if defined(__amd64)
   1494 /*
   1495  * 64-bit x86 LWPs created by SYS_lwp_create start here if they need to set
   1496  * their %fs registers to the legacy Solaris 10 selector value.
   1497  *
   1498  * This function does three things:
   1499  *
   1500  *	1.  Trap to the kernel so that it can set %fs to the legacy Solaris 10
   1501  *	    selector value.
   1502  *	2.  Read the LWP's true entry point (the entry point supplied by libc
   1503  *	    when SYS_lwp_create was invoked) from %r14.
   1504  *	3.  Eliminate this function's stack frame and pass control to the LWP's
   1505  *	    true entry point.
   1506  *
   1507  * See the comment above s10_lwp_create_correct_fs() (see below) for the reason
   1508  * why this function exists.
   1509  */
   1510 /*ARGSUSED*/
   1511 static void
   1512 s10_lwp_create_entry_point(void *ulwp_structp)
   1513 {
   1514 	sysret_t rval;
   1515 
   1516 	/*
   1517 	 * The new LWP's %fs register is initially zero, but libc won't
   1518 	 * function correctly when %fs is zero.  Change the LWP's %fs register
   1519 	 * via SYS_brand.
   1520 	 */
   1521 	(void) __systemcall(&rval, SYS_brand + 1024, B_S10_FSREGCORRECTION);
   1522 
   1523 	/*
   1524 	 * Jump to the true entry point, which is stored in %r14.
   1525 	 * Remove our stack frame before jumping so that
   1526 	 * s10_lwp_create_entry_point() won't be seen in stack traces.
   1527 	 *
   1528 	 * NOTE: s10_lwp_create_entry_point() pushes %r12 onto its stack frame
   1529 	 * so that it can use it as a temporary register.  We don't restore %r12
   1530 	 * in this assembly block because we don't care about its value (and
   1531 	 * neither does _lwp_start()).  Besides, the System V ABI AMD64
   1532 	 * Actirecture Processor Supplement doesn't specify that %r12 should
   1533 	 * have a special value when LWPs start, so we can ignore its value when
   1534 	 * we jump to the true entry point.  Furthermore, %r12 is a callee-saved
   1535 	 * register, so the true entry point should push %r12 onto its stack
   1536 	 * before using the register.  We ignore %r14 after we read it for
   1537 	 * similar reasons.
   1538 	 *
   1539 	 * NOTE: The compiler will generate a function epilogue for this
   1540 	 * function despite the fact that the LWP will never execute it.
   1541 	 * We could hand-code this entire function in assembly to eliminate
   1542 	 * the epilogue, but the epilogue is only three or four instructions,
   1543 	 * so we wouldn't save much space.  Besides, why would we want
   1544 	 * to create yet another ugly, hard-to-maintain assembly function when
   1545 	 * we could write most of it in C?
   1546 	 */
   1547 	__asm__ __volatile__(
   1548 	    "movq %0, %%rdi\n\t"	/* pass ulwp_structp as arg1 */
   1549 	    "movq %%rbp, %%rsp\n\t"	/* eliminate the stack frame */
   1550 	    "popq %%rbp\n\t"
   1551 	    "jmp *%%r14\n\t"		/* jump to the true entry point */
   1552 	    : : "r" (ulwp_structp));
   1553 	/*NOTREACHED*/
   1554 }
   1555 
   1556 /*
   1557  * The S10 libc expects that %fs will be nonzero for new 64-bit x86 LWPs but the
   1558  * Nevada kernel clears %fs for such LWPs.  Unforunately, new LWPs do not issue
   1559  * SYS_lwp_private (see s10_lwp_private() below) after they are created, so
   1560  * we must ensure that new LWPs invoke a brand operation that sets %fs to a
   1561  * nonzero value immediately after their creation.
   1562  *
   1563  * The easiest way to do this is to make new LWPs start at a special function,
   1564  * s10_lwp_create_entry_point() (see its definition above), that invokes the
   1565  * brand operation that corrects %fs.  We'll store the entry points of new LWPs
   1566  * in their %r14 registers so that s10_lwp_create_entry_point() can find and
   1567  * call them after invoking the special brand operation.  %r14 is a callee-saved
   1568  * register; therefore, any functions invoked by s10_lwp_create_entry_point()
   1569  * and all functions dealing with signals (e.g., sigacthandler()) will preserve
   1570  * %r14 for s10_lwp_create_entry_point().
   1571  *
   1572  * The Nevada kernel can safely work with nonzero %fs values because the kernel
   1573  * configures per-thread %fs segment descriptors so that the legacy %fs selector
   1574  * value will still work.  See the comment in lwp_load() regarding %fs and
   1575  * %fsbase in 64-bit x86 processes.
   1576  *
   1577  * This emulation exists thanks to CRs 6467491 and 6501650.
   1578  */
   1579 static int
   1580 s10_lwp_create_correct_fs(sysret_t *rval, ucontext_t *ucp, int flags,
   1581     id_t *new_lwp)
   1582 {
   1583 	ucontext_t s10_uc;
   1584 
   1585 	/*
   1586 	 * Copy the supplied ucontext_t structure to the local stack
   1587 	 * frame and store the new LWP's entry point (the value of %rip
   1588 	 * stored in the ucontext_t) in the new LWP's %r14 register.
   1589 	 * Then make s10_lwp_create_entry_point() the new LWP's entry
   1590 	 * point.
   1591 	 */
   1592 	if (brand_uucopy(ucp, &s10_uc, sizeof (s10_uc)) != 0)
   1593 		return (EFAULT);
   1594 
   1595 	s10_uc.uc_mcontext.gregs[REG_R14] = s10_uc.uc_mcontext.gregs[REG_RIP];
   1596 	s10_uc.uc_mcontext.gregs[REG_RIP] = (greg_t)s10_lwp_create_entry_point;
   1597 
   1598 	/*  fix up the signal mask */
   1599 	if (s10_uc.uc_flags & UC_SIGMASK)
   1600 		(void) s10sigset_to_native(&s10_uc.uc_sigmask,
   1601 		    &s10_uc.uc_sigmask);
   1602 
   1603 	/*
   1604 	 * Issue SYS_lwp_create to create the new LWP.  We pass the
   1605 	 * modified ucontext_t to make sure that the new LWP starts at
   1606 	 * s10_lwp_create_entry_point().
   1607 	 */
   1608 	return (__systemcall(rval, SYS_lwp_create + 1024, &s10_uc,
   1609 	    flags, new_lwp));
   1610 }
   1611 #endif	/* __amd64 */
   1612 
   1613 /*
   1614  * SYS_lwp_private is issued by libc_init() to set %fsbase in 64-bit x86
   1615  * processes.  The Nevada kernel sets %fs to zero but the S10 libc expects
   1616  * %fs to be nonzero.  We'll pass the issued system call to the kernel untouched
   1617  * and invoke a brand operation to set %fs to the legacy S10 selector value.
   1618  *
   1619  * This emulation exists thanks to CRs 6467491 and 6501650.
   1620  */
   1621 static int
   1622 s10_lwp_private(sysret_t *rval, int cmd, int which, uintptr_t base)
   1623 {
   1624 #if defined(__amd64)
   1625 	int err;
   1626 
   1627 	/*
   1628 	 * The current LWP's %fs register should be zero.  Determine whether the
   1629 	 * Solaris 10 libc with which we're working functions correctly when %fs
   1630 	 * is zero by calling thr_main() after issuing the SYS_lwp_private
   1631 	 * syscall.  If thr_main() barfs (returns -1), then change the LWP's %fs
   1632 	 * register via SYS_brand and patch brand_sysent_table so that issuing
   1633 	 * SYS_lwp_create executes s10_lwp_create_correct_fs() rather than the
   1634 	 * default s10_lwp_create().  s10_lwp_create_correct_fs() will
   1635 	 * guarantee that new LWPs will have correct %fs values.
   1636 	 */
   1637 	if ((err = __systemcall(rval, SYS_lwp_private + 1024, cmd, which,
   1638 	    base)) != 0)
   1639 		return (err);
   1640 	if (thr_main() == -1) {
   1641 		/*
   1642 		 * SYS_lwp_private is only issued by libc_init(), which is
   1643 		 * executed when libc is first loaded by ld.so.1.  Thus we
   1644 		 * are guaranteed to be single-threaded at this point.  Even
   1645 		 * if we were multithreaded at this point, writing a 64-bit
   1646 		 * value to the st_callc field of a brand_sysent_table
   1647 		 * entry is guaranteed to be atomic on 64-bit x86 chips
   1648 		 * as long as the field is not split across cache lines
   1649 		 * (It shouldn't be.).  See chapter 8, section 1.1 of
   1650 		 * "The Intel 64 and IA32 Architectures Software Developer's
   1651 		 * Manual," Volume 3A for more details.
   1652 		 */
   1653 		brand_sysent_table[SYS_lwp_create].st_callc =
   1654 		    (sysent_cb_t)s10_lwp_create_correct_fs;
   1655 		return (__systemcall(rval, SYS_brand + 1024,
   1656 		    B_S10_FSREGCORRECTION));
   1657 	}
   1658 	return (0);
   1659 #else	/* !__amd64 */
   1660 	return (__systemcall(rval, SYS_lwp_private + 1024, cmd, which, base));
   1661 #endif	/* !__amd64 */
   1662 }
   1663 #endif	/* __x86 */
   1664 
   1665 /*
   1666  * The Opensolaris versions of lwp_mutex_timedlock() and lwp_mutex_trylock()
   1667  * add an extra argument to the interfaces, a uintptr_t value for the mutex's
   1668  * mutex_owner field.  The Solaris 10 libc assigns the mutex_owner field at
   1669  * user-level, so we just make the extra argument be zero in both syscalls.
   1670  */
   1671 
   1672 static int
   1673 s10_lwp_mutex_timedlock(sysret_t *rval, lwp_mutex_t *lp, timespec_t *tsp)
   1674 {
   1675 	return (__systemcall(rval, SYS_lwp_mutex_timedlock + 1024, lp, tsp, 0));
   1676 }
   1677 
   1678 static int
   1679 s10_lwp_mutex_trylock(sysret_t *rval, lwp_mutex_t *lp)
   1680 {
   1681 	return (__systemcall(rval, SYS_lwp_mutex_trylock + 1024, lp, 0));
   1682 }
   1683 
   1684 /*
   1685  * If the emul_global_zone flag is set then emulate some aspects of the
   1686  * zone system call.  In particular, emulate the global zone ID on the
   1687  * ZONE_LOOKUP subcommand and emulate some of the global zone attributes
   1688  * on the ZONE_GETATTR subcommand.  If the flag is not set or we're performing
   1689  * some other operation, simply pass the calls through.
   1690  */
   1691 int
   1692 s10_zone(sysret_t *rval, int cmd, void *arg1, void *arg2, void *arg3,
   1693     void *arg4)
   1694 {
   1695 	char		*aval;
   1696 	int		len;
   1697 	zoneid_t	zid;
   1698 	int		attr;
   1699 	char		*buf;
   1700 	size_t		bufsize;
   1701 
   1702 	/*
   1703 	 * We only emulate the zone syscall for a subset of specific commands,
   1704 	 * otherwise we just pass the call through.
   1705 	 */
   1706 	if (!emul_global_zone)
   1707 		return (__systemcall(rval, SYS_zone + 1024, cmd, arg1, arg2,
   1708 		    arg3, arg4));
   1709 
   1710 	switch (cmd) {
   1711 	case ZONE_LOOKUP:
   1712 		(void) B_TRUSS_POINT_1(rval, SYS_zone, 0, cmd);
   1713 		rval->sys_rval1 = GLOBAL_ZONEID;
   1714 		rval->sys_rval2 = 0;
   1715 		return (0);
   1716 
   1717 	case ZONE_GETATTR:
   1718 		zid = (zoneid_t)(uintptr_t)arg1;
   1719 		attr = (int)(uintptr_t)arg2;
   1720 		buf = (char *)arg3;
   1721 		bufsize = (size_t)arg4;
   1722 
   1723 		/*
   1724 		 * If the request is for the global zone then we're emulating
   1725 		 * that, otherwise pass this thru.
   1726 		 */
   1727 		if (zid != GLOBAL_ZONEID)
   1728 			goto passthru;
   1729 
   1730 		switch (attr) {
   1731 		case ZONE_ATTR_NAME:
   1732 			aval = GLOBAL_ZONENAME;
   1733 			break;
   1734 
   1735 		case ZONE_ATTR_BRAND:
   1736 			aval = NATIVE_BRAND_NAME;
   1737 			break;
   1738 		default:
   1739 			/*
   1740 			 * We only emulate a subset of the attrs, use the
   1741 			 * real zone id to pass thru the rest.
   1742 			 */
   1743 			arg1 = (void *)(uintptr_t)zoneid;
   1744 			goto passthru;
   1745 		}
   1746 
   1747 		(void) B_TRUSS_POINT_5(rval, SYS_zone, 0, cmd, zid, attr,
   1748 		    buf, bufsize);
   1749 
   1750 		len = strlen(aval) + 1;
   1751 		if (len > bufsize)
   1752 			return (ENAMETOOLONG);
   1753 
   1754 		if (buf != NULL) {
   1755 			if (len == 1) {
   1756 				if (brand_uucopy("\0", buf, 1) != 0)
   1757 					return (EFAULT);
   1758 			} else {
   1759 				if (brand_uucopystr(aval, buf, len) != 0)
   1760 					return (EFAULT);
   1761 
   1762 				/*
   1763 				 * Assure NULL termination of "buf" as
   1764 				 * brand_uucopystr() does NOT.
   1765 				 */
   1766 				if (brand_uucopy("\0", buf + (len - 1), 1) != 0)
   1767 					return (EFAULT);
   1768 			}
   1769 		}
   1770 
   1771 		rval->sys_rval1 = len;
   1772 		rval->sys_rval2 = 0;
   1773 		return (0);
   1774 
   1775 	default:
   1776 		break;
   1777 	}
   1778 
   1779 passthru:
   1780 	return (__systemcall(rval, SYS_zone + 1024, cmd, arg1, arg2, arg3,
   1781 	    arg4));
   1782 }
   1783 
   1784 /*ARGSUSED*/
   1785 int
   1786 brand_init(int argc, char *argv[], char *envp[])
   1787 {
   1788 	sysret_t		rval;
   1789 	ulong_t			ldentry;
   1790 	int			err;
   1791 	char			*bname;
   1792 
   1793 	brand_pre_init();
   1794 
   1795 	/*
   1796 	 * Cache the pid of the zone's init process and determine if
   1797 	 * we're init(1m) for the zone.  Remember: we might be init
   1798 	 * now, but as soon as we fork(2) we won't be.
   1799 	 */
   1800 	(void) get_initpid_info();
   1801 
   1802 	/* get the current zoneid */
   1803 	err = __systemcall(&rval, SYS_zone, ZONE_LOOKUP, NULL);
   1804 	brand_assert(err == 0);
   1805 	zoneid = (zoneid_t)rval.sys_rval1;
   1806 
   1807 	/* Get the zone's emulation bitmap. */
   1808 	if ((err = __systemcall(&rval, SYS_zone, ZONE_GETATTR, zoneid,
   1809 	    S10_EMUL_BITMAP, emul_bitmap, sizeof (emul_bitmap))) != 0) {
   1810 		brand_abort(err, "The zone's patch level is unsupported");
   1811 		/*NOTREACHED*/
   1812 	}
   1813 
   1814 	bname = basename(argv[0]);
   1815 
   1816 	/*
   1817 	 * In general we want the S10 commands that are zone-aware to continue
   1818 	 * to behave as they normally do within a zone.  Since these commands
   1819 	 * are zone-aware, they should continue to "do the right thing".
   1820 	 * However, some zone-aware commands aren't going to work the way
   1821 	 * we expect them to inside the branded zone.  In particular, the pkg
   1822 	 * and patch commands will not properly manage all pkgs/patches
   1823 	 * unless the commands think they are running in the global zone.  For
   1824 	 * these commands we want to emulate the global zone.
   1825 	 *
   1826 	 * We don't do any emulation for pkgcond since it is typically used
   1827 	 * in pkg/patch postinstall scripts and we want those scripts to do
   1828 	 * the right thing inside a zone.
   1829 	 *
   1830 	 * One issue is the handling of hollow pkgs.  Since the pkgs are
   1831 	 * hollow, they won't use pkgcond in their postinstall scripts.  These
   1832 	 * pkgs typically are installing drivers so we handle that by
   1833 	 * replacing add_drv and rem_drv in the s10_boot script.
   1834 	 */
   1835 	if (strcmp("pkgadd", bname) == 0 || strcmp("pkgrm", bname) == 0 ||
   1836 	    strcmp("patchadd", bname) == 0 || strcmp("patchrm", bname) == 0)
   1837 		emul_global_zone = B_TRUE;
   1838 
   1839 	ldentry = brand_post_init(S10_VERSION, argc, argv, envp);
   1840 
   1841 	brand_runexe(argv, ldentry);
   1842 	/*NOTREACHED*/
   1843 	brand_abort(0, "brand_runexe() returned");
   1844 	return (-1);
   1845 }
   1846 
   1847 /*
   1848  * This table must have at least NSYSCALL entries in it.
   1849  *
   1850  * The second parameter of each entry in the brand_sysent_table
   1851  * contains the number of parameters and flags that describe the
   1852  * syscall return value encoding.  See the block comments at the
   1853  * top of this file for more information about the syscall return
   1854  * value flags and when they should be used.
   1855  */
   1856 brand_sysent_table_t brand_sysent_table[] = {
   1857 #if defined(__sparc) && !defined(__sparcv9)
   1858 	EMULATE(brand_indir, 9 | RV_64RVAL),	/*  0 */
   1859 #else
   1860 	NOSYS,					/*  0 */
   1861 #endif
   1862 	NOSYS,					/*   1 */
   1863 	EMULATE(s10_forkall, 0 | RV_32RVAL2),	/*   2 */
   1864 	NOSYS,					/*   3 */
   1865 	NOSYS,					/*   4 */
   1866 	EMULATE(s10_open, 3 | RV_DEFAULT),	/*   5 */
   1867 	NOSYS,					/*   6 */
   1868 	EMULATE(s10_wait, 0 | RV_32RVAL2),	/*   7 */
   1869 	EMULATE(s10_creat, 2 | RV_DEFAULT),	/*   8 */
   1870 	EMULATE(s10_link, 2 | RV_DEFAULT),	/*   9 */
   1871 	EMULATE(s10_unlink, 1 | RV_DEFAULT),	/*  10 */
   1872 	EMULATE(s10_exec, 2 | RV_DEFAULT),	/*  11 */
   1873 	NOSYS,					/*  12 */
   1874 	NOSYS,					/*  13 */
   1875 	EMULATE(s10_mknod, 3 | RV_DEFAULT),	/*  14 */
   1876 	EMULATE(s10_chmod, 2 | RV_DEFAULT),	/*  15 */
   1877 	EMULATE(s10_chown, 3 | RV_DEFAULT),	/*  16 */
   1878 	NOSYS,					/*  17 */
   1879 	EMULATE(s10_stat, 2 | RV_DEFAULT),	/*  18 */
   1880 	NOSYS,					/*  19 */
   1881 	NOSYS,					/*  20 */
   1882 	NOSYS,					/*  21 */
   1883 	EMULATE(s10_umount, 1 | RV_DEFAULT),	/*  22 */
   1884 	NOSYS,					/*  23 */
   1885 	NOSYS,					/*  24 */
   1886 	NOSYS,					/*  25 */
   1887 	NOSYS,					/*  26 */
   1888 	NOSYS,					/*  27 */
   1889 	EMULATE(s10_fstat, 2 | RV_DEFAULT),	/*  28 */
   1890 	NOSYS,					/*  29 */
   1891 	EMULATE(s10_utime, 2 | RV_DEFAULT),	/*  30 */
   1892 	NOSYS,					/*  31 */
   1893 	NOSYS,					/*  32 */
   1894 	EMULATE(s10_access, 2 | RV_DEFAULT),	/*  33 */
   1895 	NOSYS,					/*  34 */
   1896 	NOSYS,					/*  35 */
   1897 	NOSYS,					/*  36 */
   1898 	EMULATE(s10_kill, 2 | RV_DEFAULT),	/*  37 */
   1899 	NOSYS,					/*  38 */
   1900 	NOSYS,					/*  39 */
   1901 	NOSYS,					/*  40 */
   1902 	EMULATE(s10_dup, 1 | RV_DEFAULT),	/*  41 */
   1903 	NOSYS,					/*  42 */
   1904 	NOSYS,					/*  43 */
   1905 	NOSYS,					/*  44 */
   1906 	NOSYS,					/*  45 */
   1907 	NOSYS,					/*  46 */
   1908 	NOSYS,					/*  47 */
   1909 	NOSYS,					/*  48 */
   1910 	NOSYS,					/*  49 */
   1911 	NOSYS,					/*  50 */
   1912 	NOSYS,					/*  51 */
   1913 	NOSYS,					/*  52 */
   1914 	NOSYS,					/*  53 */
   1915 	EMULATE(s10_ioctl, 3 | RV_DEFAULT),	/*  54 */
   1916 	NOSYS,					/*  55 */
   1917 	NOSYS,					/*  56 */
   1918 	NOSYS,					/*  57 */
   1919 	NOSYS,					/*  58 */
   1920 	EMULATE(s10_execve, 3 | RV_DEFAULT),	/*  59 */
   1921 	NOSYS,					/*  60 */
   1922 	NOSYS,					/*  61 */
   1923 	NOSYS,					/*  62 */
   1924 	NOSYS,					/*  63 */
   1925 	NOSYS,					/*  64 */
   1926 	NOSYS,					/*  65 */
   1927 	NOSYS,					/*  66 */
   1928 	NOSYS,					/*  67 */
   1929 	NOSYS,					/*  68 */
   1930 	NOSYS,					/*  69 */
   1931 	NOSYS,					/*  70 */
   1932 	EMULATE(s10_acctctl, 3 | RV_DEFAULT),	/*  71 */
   1933 	NOSYS,					/*  72 */
   1934 	NOSYS,					/*  73 */
   1935 	NOSYS,					/*  74 */
   1936 	EMULATE(s10_issetugid, 0 | RV_DEFAULT),	/*  75 */
   1937 	EMULATE(s10_fsat, 6 | RV_DEFAULT),	/*  76 */
   1938 	NOSYS,					/*  77 */
   1939 	NOSYS,					/*  78 */
   1940 	EMULATE(s10_rmdir, 1 | RV_DEFAULT),	/*  79 */
   1941 	EMULATE(s10_mkdir, 2 | RV_DEFAULT),	/*  80 */
   1942 	EMULATE(s10_getdents, 3 | RV_DEFAULT),	/*  81 */
   1943 	NOSYS,					/*  82 */
   1944 	NOSYS,					/*  83 */
   1945 	NOSYS,					/*  84 */
   1946 	NOSYS,					/*  85 */
   1947 	NOSYS,					/*  86 */
   1948 	EMULATE(s10_poll, 3 | RV_DEFAULT),	/*  87 */
   1949 	EMULATE(s10_lstat, 2 | RV_DEFAULT),	/*  88 */
   1950 	EMULATE(s10_symlink, 2 | RV_DEFAULT),	/*  89 */
   1951 	EMULATE(s10_readlink, 3 | RV_DEFAULT),	/*  90 */
   1952 	NOSYS,					/*  91 */
   1953 	NOSYS,					/*  92 */
   1954 	EMULATE(s10_fchmod, 2 | RV_DEFAULT),	/*  93 */
   1955 	EMULATE(s10_fchown, 3 | RV_DEFAULT),	/*  94 */
   1956 	EMULATE(s10_sigprocmask, 3 | RV_DEFAULT), /*  95 */
   1957 	EMULATE(s10_sigsuspend, 1 | RV_DEFAULT), /*  96 */
   1958 	NOSYS,					/*  97 */
   1959 	EMULATE(s10_sigaction, 3 | RV_DEFAULT),	/*  98 */
   1960 	EMULATE(s10_sigpending, 2 | RV_DEFAULT), /*  99 */
   1961 	NOSYS,					/* 100 */
   1962 	NOSYS,					/* 101 */
   1963 	NOSYS,					/* 102 */
   1964 	NOSYS,					/* 103 */
   1965 	NOSYS,					/* 104 */
   1966 	NOSYS,					/* 105 */
   1967 	NOSYS,					/* 106 */
   1968 	EMULATE(s10_waitid, 4 | RV_DEFAULT),	/* 107 */
   1969 	EMULATE(s10_sigsendsys, 2 | RV_DEFAULT), /* 108 */
   1970 	NOSYS,					/* 109 */
   1971 	NOSYS,					/* 110 */
   1972 	NOSYS,					/* 111 */
   1973 	NOSYS,					/* 112 */
   1974 	NOSYS,					/* 113 */
   1975 	NOSYS,					/* 114 */
   1976 	NOSYS,					/* 115 */
   1977 	NOSYS,					/* 116 */
   1978 	NOSYS,					/* 117 */
   1979 	NOSYS,					/* 118 */
   1980 	NOSYS,					/* 119 */
   1981 	NOSYS,					/* 120 */
   1982 	NOSYS,					/* 121 */
   1983 	NOSYS,					/* 122 */
   1984 #if defined(__x86)
   1985 	EMULATE(s10_xstat, 3 | RV_DEFAULT),	/* 123 */
   1986 	EMULATE(s10_lxstat, 3 | RV_DEFAULT),	/* 124 */
   1987 	EMULATE(s10_fxstat, 3 | RV_DEFAULT),	/* 125 */
   1988 	EMULATE(s10_xmknod, 4 | RV_DEFAULT),	/* 126 */
   1989 #else
   1990 	NOSYS,					/* 123 */
   1991 	NOSYS,					/* 124 */
   1992 	NOSYS,					/* 125 */
   1993 	NOSYS,					/* 126 */
   1994 #endif
   1995 	NOSYS,					/* 127 */
   1996 	NOSYS,					/* 128 */
   1997 	NOSYS,					/* 129 */
   1998 	EMULATE(s10_lchown, 3 | RV_DEFAULT),	/* 130 */
   1999 	NOSYS,					/* 131 */
   2000 	NOSYS,					/* 132 */
   2001 	NOSYS,					/* 133 */
   2002 	EMULATE(s10_rename, 2 | RV_DEFAULT),	/* 134 */
   2003 	EMULATE(s10_uname, 1 | RV_DEFAULT),	/* 135 */
   2004 	NOSYS,					/* 136 */
   2005 	EMULATE(s10_sysconfig, 1 | RV_DEFAULT),	/* 137 */
   2006 	NOSYS,					/* 138 */
   2007 	EMULATE(s10_sysinfo, 3 | RV_DEFAULT),	/* 139 */
   2008 	NOSYS,					/* 140 */
   2009 	NOSYS,					/* 141 */
   2010 	NOSYS,					/* 142 */
   2011 	EMULATE(s10_fork1, 0 | RV_32RVAL2),	/* 143 */
   2012 	EMULATE(s10_sigtimedwait, 3 | RV_DEFAULT), /* 144 */
   2013 	NOSYS,					/* 145 */
   2014 	NOSYS,					/* 146 */
   2015 	EMULATE(s10_lwp_sema_wait, 1 | RV_DEFAULT), /* 147 */
   2016 	NOSYS,					/* 148 */
   2017 	NOSYS,					/* 149 */
   2018 	NOSYS,					/* 150 */
   2019 	NOSYS,					/* 151 */
   2020 	NOSYS,					/* 152 */
   2021 	NOSYS,					/* 153 */
   2022 	EMULATE(s10_utimes, 2 | RV_DEFAULT),	/* 154 */
   2023 	NOSYS,					/* 155 */
   2024 	NOSYS,					/* 156 */
   2025 	NOSYS,					/* 157 */
   2026 	NOSYS,					/* 158 */
   2027 	EMULATE(s10_lwp_create, 3 | RV_DEFAULT), /* 159 */
   2028 	NOSYS,					/* 160 */
   2029 	NOSYS,					/* 161 */
   2030 	NOSYS,					/* 162 */
   2031 	EMULATE(s10_lwp_kill, 2 | RV_DEFAULT),	/* 163 */
   2032 	NOSYS,					/* 164 */
   2033 	EMULATE(s10_lwp_sigmask, 3 | RV_32RVAL2), /* 165 */
   2034 #if defined(__x86)
   2035 	EMULATE(s10_lwp_private, 3 | RV_DEFAULT), /* 166 */
   2036 #else
   2037 	NOSYS,					/* 166 */
   2038 #endif
   2039 	NOSYS,					/* 167 */
   2040 	NOSYS,					/* 168 */
   2041 	EMULATE(s10_lwp_mutex_lock, 1 | RV_DEFAULT), /* 169 */
   2042 	NOSYS,					/* 170 */
   2043 	NOSYS,					/* 171 */
   2044 	NOSYS,					/* 172 */
   2045 	NOSYS,					/* 173 */
   2046 	EMULATE(s10_pwrite, 4 | RV_DEFAULT),	/* 174 */
   2047 	NOSYS,					/* 175 */
   2048 	NOSYS,					/* 176 */
   2049 	NOSYS,					/* 177 */
   2050 	NOSYS,					/* 178 */
   2051 	NOSYS,					/* 179 */
   2052 	NOSYS,					/* 180 */
   2053 	NOSYS,					/* 181 */
   2054 	NOSYS,					/* 182 */
   2055 	NOSYS,					/* 183 */
   2056 	NOSYS,					/* 184 */
   2057 	EMULATE(s10_acl, 4 | RV_DEFAULT),	/* 185 */
   2058 	EMULATE(s10_auditsys, 4 | RV_64RVAL),	/* 186 */
   2059 	NOSYS,					/* 187 */
   2060 	NOSYS,					/* 188 */
   2061 	NOSYS,					/* 189 */
   2062 	EMULATE(s10_sigqueue, 4 | RV_DEFAULT),	/* 190 */
   2063 	NOSYS,					/* 191 */
   2064 	NOSYS,					/* 192 */
   2065 	NOSYS,					/* 193 */
   2066 	NOSYS,					/* 194 */
   2067 	NOSYS,					/* 195 */
   2068 	NOSYS,					/* 196 */
   2069 	NOSYS,					/* 197 */
   2070 	NOSYS,					/* 198 */
   2071 	NOSYS,					/* 199 */
   2072 	EMULATE(s10_facl, 4 | RV_DEFAULT),	/* 200 */
   2073 	NOSYS,					/* 201 */
   2074 	NOSYS,					/* 202 */
   2075 	NOSYS,					/* 203 */
   2076 	NOSYS,					/* 204 */
   2077 	EMULATE(s10_signotify, 3 | RV_DEFAULT),	/* 205 */
   2078 	NOSYS,					/* 206 */
   2079 	NOSYS,					/* 207 */
   2080 	NOSYS,					/* 208 */
   2081 	NOSYS,					/* 209 */
   2082 	EMULATE(s10_lwp_mutex_timedlock, 2 | RV_DEFAULT), /* 210 */
   2083 	NOSYS,					/* 211 */
   2084 	NOSYS,					/* 212 */
   2085 #if defined(_LP64)
   2086 	NOSYS,					/* 213 */
   2087 #else
   2088 	EMULATE(s10_getdents64, 3 | RV_DEFAULT), /* 213 */
   2089 #endif
   2090 	NOSYS,					/* 214 */
   2091 #if defined(_LP64)
   2092 	NOSYS,					/* 215 */
   2093 	NOSYS,					/* 216 */
   2094 	NOSYS,					/* 217 */
   2095 #else
   2096 	EMULATE(s10_stat64, 2 | RV_DEFAULT),	/* 215 */
   2097 	EMULATE(s10_lstat64, 2 | RV_DEFAULT),	/* 216 */
   2098 	EMULATE(s10_fstat64, 2 | RV_DEFAULT),	/* 217 */
   2099 #endif
   2100 	NOSYS,					/* 218 */
   2101 	NOSYS,					/* 219 */
   2102 	NOSYS,					/* 220 */
   2103 	NOSYS,					/* 221 */
   2104 	NOSYS,					/* 222 */
   2105 #if defined(_LP64)
   2106 	NOSYS,					/* 223 */
   2107 	NOSYS,					/* 224 */
   2108 	NOSYS,					/* 225 */
   2109 #else
   2110 	EMULATE(s10_pwrite64, 5 | RV_DEFAULT),	/* 223 */
   2111 	EMULATE(s10_creat64, 2 | RV_DEFAULT),	/* 224 */
   2112 	EMULATE(s10_open64, 3 | RV_DEFAULT),	/* 225 */
   2113 #endif
   2114 	NOSYS,					/* 226 */
   2115 	EMULATE(s10_zone, 5 | RV_DEFAULT),	/* 227 */
   2116 	NOSYS,					/* 228 */
   2117 	NOSYS,					/* 229 */
   2118 	NOSYS,					/* 230 */
   2119 	NOSYS,					/* 231 */
   2120 	NOSYS,					/* 232 */
   2121 	NOSYS,					/* 233 */
   2122 	NOSYS,					/* 234 */
   2123 	NOSYS,					/* 235 */
   2124 	NOSYS,					/* 236 */
   2125 	NOSYS,					/* 237 */
   2126 	NOSYS,					/* 238 */
   2127 	NOSYS,					/* 239 */
   2128 	NOSYS,					/* 240 */
   2129 	NOSYS,					/* 241 */
   2130 	NOSYS,					/* 242 */
   2131 	NOSYS,					/* 243 */
   2132 	NOSYS,					/* 244 */
   2133 	NOSYS,					/* 245 */
   2134 	NOSYS,					/* 246 */
   2135 	NOSYS,					/* 247 */
   2136 	NOSYS,					/* 248 */
   2137 	NOSYS,					/* 249 */
   2138 	NOSYS,					/* 250 */
   2139 	EMULATE(s10_lwp_mutex_trylock, 1 | RV_DEFAULT), /* 251 */
   2140 	NOSYS,					/* 252 */
   2141 	NOSYS,					/* 253 */
   2142 	NOSYS,					/* 254 */
   2143 	NOSYS					/* 255 */
   2144 };
   2145