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