usr/src/lib/brand/lx/lx_brand/common/lx_brand.c
author Saurabh Misra <Saurabh.Mishra@Sun.COM>
Thu Aug 27 13:21:41 2009 -0700 (6 months ago)
changeset 10393 f08ea7a5507b
parent 51440d37e3365863
child 11338e8c975bf2038
permissions -rw-r--r--
PSARC/2009/405 Atheros/Attansic Ethernet Gigbit Ethernet Driver
6736491 Need to Support Attansic Ethernet L1E chipset on ASUS Eee PC
     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 2008 Sun Microsystems, Inc.  All rights reserved.
    24  * Use is subject to license terms.
    25  */
    26 
    27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
    28 
    29 #include <sys/types.h>
    30 #include <sys/syscall.h>
    31 #include <sys/utsname.h>
    32 #include <sys/inttypes.h>
    33 #include <sys/stat.h>
    34 #include <sys/mman.h>
    35 #include <sys/fstyp.h>
    36 #include <sys/fsid.h>
    37 #include <sys/systm.h>
    38 #include <sys/auxv.h>
    39 #include <sys/frame.h>
    40 #include <sys/brand.h>
    41 
    42 #include <assert.h>
    43 #include <stdio.h>
    44 #include <stdarg.h>
    45 #include <stdlib.h>
    46 #include <strings.h>
    47 #include <unistd.h>
    48 #include <errno.h>
    49 #include <syslog.h>
    50 #include <signal.h>
    51 #include <fcntl.h>
    52 #include <synch.h>
    53 #include <libelf.h>
    54 #include <libgen.h>
    55 #include <pthread.h>
    56 #include <utime.h>
    57 #include <dirent.h>
    58 #include <ucontext.h>
    59 #include <libintl.h>
    60 #include <locale.h>
    61 
    62 #include <sys/lx_misc.h>
    63 #include <sys/lx_debug.h>
    64 #include <sys/lx_brand.h>
    65 #include <sys/lx_types.h>
    66 #include <sys/lx_stat.h>
    67 #include <sys/lx_statfs.h>
    68 #include <sys/lx_ioctl.h>
    69 #include <sys/lx_signal.h>
    70 #include <sys/lx_syscall.h>
    71 #include <sys/lx_thread.h>
    72 #include <sys/lx_thunk_server.h>
    73 
    74 /*
    75  * Map solaris errno to the linux equivalent.
    76  */
    77 static int stol_errno[] = {
    78 	0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
    79 	10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
    80 	20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
    81 	30,  31,  32,  33,  34,  42,  43,  44,  45,  46,
    82 	47,  48,  49,  50,  51,  35,  47,  22,  38,  22, /* 49 */
    83 	52,  53,  54,  55,  56,  57,  58,  59,  22,  22,
    84 	61,  61,  62,  63,  64,  65,  66,  67,  68,  69,
    85 	70,  71,  22,  22,  72,  22,  22,  74,  36,  75,
    86 	76,  77,  78,  79,  80,  81,  82,  83,  84,  38,
    87 	40,  85,  86,  39,  87,  88,  89,  90,  91,  92, /* 99 */
    88 	22,  22,  22,  22,  22,  22,  22,  22,  22,  22,
    89 	22,  22,  22,  22,  22,  22,  22,  22,  22,  22,
    90 	93,  94,  95,  96,  97,  98,  99, 100, 101, 102,
    91 	103, 104, 105, 106, 107,  22,  22,  22,  22,  22,
    92 	22,  22,  22, 108, 109, 110, 111, 112, 113, 114, /* 149 */
    93 	115, 116
    94 };
    95 
    96 char lx_release[128];
    97 
    98 /*
    99  * Map a linux locale ending string to the solaris equivalent.
   100  */
   101 struct lx_locale_ending {
   102 	const char	*linux_end;	/* linux ending string */
   103 	const char	*solaris_end;	/* to transform with this string */
   104 	int		le_size;	/* linux ending string length */
   105 	int		se_size;	/* solaris ending string length */
   106 };
   107 
   108 #define	l2s_locale(lname, sname) \
   109 	{(lname), (sname), sizeof ((lname)) - 1, sizeof ((sname)) - 1}
   110 
   111 static struct lx_locale_ending lx_locales[] = {
   112 	l2s_locale(".utf8",	 ".UTF-8"),
   113 	l2s_locale(".utf8@euro", ".UTF-8"),
   114 	l2s_locale("@euro",	 ".ISO8859-15"),
   115 	l2s_locale(".iso885915", ".ISO8859-15"),
   116 	l2s_locale(".euckr",	 ".EUC"),
   117 	l2s_locale(".euctw",	 ".EUC"),
   118 	l2s_locale(".koi8r",	 ".KOI8-R"),
   119 	l2s_locale(".gb18030",	 ".GB18030"),
   120 	l2s_locale(".gbk",	 ".GBK"),
   121 	l2s_locale("@cyrillic",	 ".ISO8859-5")
   122 };
   123 
   124 #define	MAXLOCALENAMELEN	30
   125 #if !defined(TEXT_DOMAIN)		/* should be defined by cc -D */
   126 #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it wasn't */
   127 #endif
   128 
   129 /*
   130  * This flag is part of the registration with the in-kernel brand module. It's
   131  * used in lx_handler() to determine if we should go back into the kernel after
   132  * a system call in case the kernel needs to perform some post-syscall work
   133  * like tracing for example.
   134  */
   135 int lx_traceflag;
   136 
   137 #define	NOSYS_NULL		1
   138 #define	NOSYS_NO_EQUIV		2
   139 #define	NOSYS_KERNEL		3
   140 #define	NOSYS_UNDOC		4
   141 #define	NOSYS_OBSOLETE		5
   142 
   143 /*
   144  * SYS_PASSTHRU denotes a system call we can just call on behalf of the
   145  * branded process without having to translate the arguments.
   146  *
   147  * The restriction on this is that the call in question MUST return -1 to
   148  * denote an error.
   149  */
   150 #define	SYS_PASSTHRU		5
   151 
   152 static char *nosys_msgs[] = {
   153 	"Either not yet done, or we haven't come up with an excuse",
   154 	"No such Linux system call",
   155 	"No equivalent Solaris functionality",
   156 	"Reads/modifies Linux kernel state",
   157 	"Undocumented and/or rarely used system call",
   158 	"Unsupported, obsolete system call"
   159 };
   160 
   161 struct lx_sysent {
   162 	char    *sy_name;
   163 	int	(*sy_callc)();
   164 	char	sy_flags;
   165 	char	sy_narg;
   166 };
   167 
   168 static struct lx_sysent sysents[LX_NSYSCALLS + 1];
   169 
   170 static uintptr_t stack_bottom;
   171 
   172 int lx_install = 0;		/* install mode enabled if non-zero */
   173 boolean_t lx_is_rpm = B_FALSE;
   174 int lx_rpm_delay = 1;
   175 int lx_strict = 0;		/* "strict" mode enabled if non-zero */
   176 int lx_verbose = 0;		/* verbose mode enabled if non-zero */
   177 int lx_debug_enabled = 0;	/* debugging output enabled if non-zero */
   178 
   179 pid_t zoneinit_pid;		/* zone init PID */
   180 
   181 thread_key_t lx_tsd_key;
   182 
   183 int
   184 uucopy_unsafe(const void *src, void *dst, size_t n)
   185 {
   186 	bcopy(src, dst, n);
   187 	return (0);
   188 }
   189 
   190 int
   191 uucopystr_unsafe(const void *src, void *dst, size_t n)
   192 {
   193 	(void) strncpy((char *)src, dst, n);
   194 	return (0);
   195 }
   196 
   197 static void
   198 i_lx_msg(int fd, char *msg, va_list ap)
   199 {
   200 	int	i;
   201 	char	buf[LX_MSG_MAXLEN];
   202 
   203 	/* LINTED [possible expansion issues] */
   204 	i = vsnprintf(buf, sizeof (buf), msg, ap);
   205 	buf[LX_MSG_MAXLEN - 1] = '\0';
   206 	if (i == -1)
   207 		return;
   208 
   209 	/* if debugging is enabled, send this message to debug output */
   210 	if (lx_debug_enabled != 0)
   211 		lx_debug(buf);
   212 
   213 	/*
   214 	 * If we are trying to print to stderr, we also want to send the
   215 	 * message to syslog.
   216 	 */
   217 	if (fd == 2) {
   218 		syslog(LOG_ERR, "%s", buf);
   219 
   220 		/*
   221 		 * We let the user choose whether or not to see these
   222 		 * messages on the console.
   223 		 */
   224 		if (lx_verbose == 0)
   225 			return;
   226 	}
   227 
   228 	/* we retry in case of EINTR */
   229 	do {
   230 		i = write(fd, buf, strlen(buf));
   231 	} while ((i == -1) && (errno == EINTR));
   232 }
   233 
   234 /*PRINTFLIKE1*/
   235 void
   236 lx_err(char *msg, ...)
   237 {
   238 	va_list	ap;
   239 
   240 	assert(msg != NULL);
   241 
   242 	va_start(ap, msg);
   243 	i_lx_msg(STDERR_FILENO, msg, ap);
   244 	va_end(ap);
   245 }
   246 
   247 /*
   248  * This is just a non-zero exit value which also isn't one that would allow
   249  * us to easily detect if a branded process exited because of a recursive
   250  * fatal error.
   251  */
   252 #define	LX_ERR_FATAL	42
   253 
   254 /*
   255  * Our own custom version of abort(), this routine will be used in place
   256  * of the one located in libc.  The primary difference is that this version
   257  * will first reset the signal handler for SIGABRT to SIG_DFL, ensuring the
   258  * SIGABRT sent causes us to dump core and is not caught by a user program.
   259  */
   260 void
   261 abort(void)
   262 {
   263 	static int aborting = 0;
   264 
   265 	struct sigaction sa;
   266 	sigset_t sigmask;
   267 
   268 	/* watch out for recursive calls to this function */
   269 	if (aborting != 0)
   270 		exit(LX_ERR_FATAL);
   271 
   272 	aborting = 1;
   273 
   274 	/*
   275 	 * Block all signals here to avoid taking any signals while exiting
   276 	 * in an effort to avoid any strange user interaction with our death.
   277 	 */
   278 	(void) sigfillset(&sigmask);
   279 	(void) sigprocmask(SIG_BLOCK, &sigmask, NULL);
   280 
   281 	/*
   282 	 * Our own version of abort(3C) that we know will never call
   283 	 * a user-installed SIGABRT handler first.  We WANT to die.
   284 	 *
   285 	 * Do this by resetting the handler to SIG_DFL, and releasing any
   286 	 * held SIGABRTs.
   287 	 *
   288 	 * If no SIGABRTs are pending, send ourselves one.
   289 	 *
   290 	 * The while loop is a bit of overkill, but abort(3C) does it to
   291 	 * assure it never returns so we will as well.
   292 	 */
   293 	(void) sigemptyset(&sa.sa_mask);
   294 	sa.sa_sigaction = SIG_DFL;
   295 	sa.sa_flags = 0;
   296 
   297 	for (;;) {
   298 		(void) sigaction(SIGABRT, &sa, NULL);
   299 		(void) sigrelse(SIGABRT);
   300 		(void) thr_kill(thr_self(), SIGABRT);
   301 	}
   302 
   303 	/*NOTREACHED*/
   304 }
   305 
   306 /*PRINTFLIKE1*/
   307 void
   308 lx_msg(char *msg, ...)
   309 {
   310 	va_list	ap;
   311 
   312 	assert(msg != NULL);
   313 	va_start(ap, msg);
   314 	i_lx_msg(STDOUT_FILENO, msg, ap);
   315 	va_end(ap);
   316 }
   317 
   318 /*PRINTFLIKE1*/
   319 void
   320 lx_err_fatal(char *msg, ...)
   321 {
   322 	va_list	ap;
   323 
   324 	assert(msg != NULL);
   325 
   326 	va_start(ap, msg);
   327 	i_lx_msg(STDERR_FILENO, msg, ap);
   328 	va_end(ap);
   329 	abort();
   330 }
   331 
   332 /*
   333  * See if it is safe to alloca() sz bytes.  Return 1 for yes, 0 for no.
   334  */
   335 int
   336 lx_check_alloca(size_t sz)
   337 {
   338 	uintptr_t sp = (uintptr_t)&sz;
   339 	uintptr_t end = sp - sz;
   340 
   341 	return ((end < sp) && (end >= stack_bottom));
   342 }
   343 
   344 /*PRINTFLIKE1*/
   345 void
   346 lx_unsupported(char *msg, ...)
   347 {
   348 	va_list	ap;
   349 
   350 	assert(msg != NULL);
   351 
   352 	/* send the msg to the error stream */
   353 	va_start(ap, msg);
   354 	i_lx_msg(STDERR_FILENO, msg, ap);
   355 	va_end(ap);
   356 
   357 	/*
   358 	 * If the user doesn't trust the application to responsibly
   359 	 * handle ENOTSUP, we kill the application.
   360 	 */
   361 	if (lx_strict)
   362 		(void) kill(getpid(), SIGSYS);
   363 }
   364 
   365 extern void lx_runexe(void *argv, int32_t entry);
   366 int lx_init(int argc, char *argv[], char *envp[]);
   367 
   368 static int
   369 lx_emulate_args(lx_regs_t *rp, struct lx_sysent *s, uintptr_t *args)
   370 {
   371 	/*
   372 	 * If the system call takes 6 args, then libc has stashed them in
   373 	 * memory at the address contained in %ebx. Except for some syscalls
   374 	 * which store the 6th argument in %ebp.
   375 	 */
   376 	if (s->sy_narg == 6 && !(s->sy_flags & EBP_HAS_ARG6)) {
   377 		if (uucopy((void *)rp->lxr_ebx, args,
   378 		    sizeof (args[0]) * 6) != 0)
   379 			return (-stol_errno[errno]);
   380 	} else {
   381 		args[0] = rp->lxr_ebx;
   382 		args[1] = rp->lxr_ecx;
   383 		args[2] = rp->lxr_edx;
   384 		args[3] = rp->lxr_esi;
   385 		args[4] = rp->lxr_edi;
   386 		args[5] = rp->lxr_ebp;
   387 	}
   388 
   389 	return (0);
   390 }
   391 
   392 void
   393 lx_emulate(lx_regs_t *rp)
   394 {
   395 	struct lx_sysent *s;
   396 	uintptr_t args[6];
   397 	uintptr_t gs = rp->lxr_gs & 0xffff;	/* %gs is only 16 bits */
   398 	int syscall_num, ret;
   399 
   400 	syscall_num = rp->lxr_eax;
   401 
   402 	/*
   403 	 * lx_brand_int80_callback() ensures that the syscall_num is sane;
   404 	 * Use it as is.
   405 	 */
   406 	assert(syscall_num >= 0);
   407 	assert(syscall_num < (sizeof (sysents) / sizeof (sysents[0])));
   408 	s = &sysents[syscall_num];
   409 
   410 	if ((ret = lx_emulate_args(rp, s, args)) != 0)
   411 		goto out;
   412 
   413 	/*
   414 	 * If the tracing flag is enabled we call into the brand-specific
   415 	 * kernel module to handle the tracing activity (DTrace or ptrace).
   416 	 * It would be tempting to perform DTrace activity in the brand
   417 	 * module's syscall trap callback, rather than having to return
   418 	 * to the kernel here, but -- since argument encoding can vary
   419 	 * according to the specific system call -- that would require
   420 	 * replicating the knowledge of argument decoding in the kernel
   421 	 * module as well as here in the brand library.
   422 	 */
   423 	if (lx_traceflag != 0) {
   424 		/*
   425 		 * Part of the ptrace "interface" is that on syscall entry
   426 		 * %eax should be reported as -ENOSYS while the orig_eax
   427 		 * field of the user structure needs to contain the actual
   428 		 * system call number. If we end up stopping here, the
   429 		 * controlling process will dig the lx_regs_t structure out of
   430 		 * our stack.
   431 		 */
   432 		rp->lxr_orig_eax = syscall_num;
   433 		rp->lxr_eax = -stol_errno[ENOSYS];
   434 
   435 		(void) syscall(SYS_brand, B_SYSENTRY, syscall_num, args);
   436 
   437 		/*
   438 		 * The external tracer may have modified the arguments to this
   439 		 * system call. Refresh the argument cache to account for this.
   440 		 */
   441 		if ((ret = lx_emulate_args(rp, s, args)) != 0)
   442 			goto out;
   443 	}
   444 
   445 	if (s->sy_callc == NULL) {
   446 		lx_unsupported(gettext("unimplemented syscall #%d (%s): %s\n"),
   447 		    syscall_num, s->sy_name, nosys_msgs[s->sy_flags]);
   448 		ret = -stol_errno[ENOTSUP];
   449 		goto out;
   450 	}
   451 
   452 	if (lx_debug_enabled != 0) {
   453 		const char *fmt;
   454 
   455 		switch (s->sy_narg) {
   456 		case 0:
   457 			fmt = "calling %s()";
   458 			break;
   459 		case 1:
   460 			fmt = "calling %s(0x%p)";
   461 			break;
   462 		case 2:
   463 			fmt = "calling %s(0x%p, 0x%p)";
   464 			break;
   465 		case 3:
   466 			fmt = "calling %s(0x%p, 0x%p, 0x%p)";
   467 			break;
   468 		case 4:
   469 			fmt = "calling %s(0x%p, 0x%p, 0x%p, 0x%p)";
   470 			break;
   471 		case 5:
   472 			fmt = "calling %s(0x%p, 0x%p, 0x%p, 0x%p, 0x%p)";
   473 			break;
   474 		case 6:
   475 			fmt = "calling %s(0x%p, 0x%p, 0x%p, 0x%p, 0x%p, 0x%p)";
   476 			break;
   477 		}
   478 
   479 		lx_debug(fmt, s->sy_name, args[0], args[1], args[2], args[3],
   480 		    args[4], args[5]);
   481 	}
   482 
   483 	if (gs != LWPGS_SEL) {
   484 		lx_tsd_t *lx_tsd;
   485 
   486 		/*
   487 		 * While a %gs of 0 is technically legal (as long as the
   488 		 * application never dereferences memory using %gs), Solaris
   489 		 * has its own ideas as to how a zero %gs should be handled in
   490 		 * _update_sregs(), such that any 32-bit user process with a
   491 		 * %gs of zero running on a system with a 64-bit kernel will
   492 		 * have its %gs hidden base register stomped on on return from
   493 		 * a system call, leaving an incorrect base address in place
   494 		 * until the next time %gs is actually reloaded (forcing a
   495 		 * reload of the base address from the appropriate descriptor
   496 		 * table.)
   497 		 *
   498 		 * Of course the kernel will once again stomp on THAT base
   499 		 * address when returning from a system call, resulting in an
   500 		 * an application segmentation fault.
   501 		 *
   502 		 * To avoid this situation, disallow a save of a zero %gs
   503 		 * here in order to try and capture any Linux process that
   504 		 * attempts to make a syscall with a zero %gs installed.
   505 		 */
   506 		assert(gs != 0);
   507 
   508 		if ((ret = thr_getspecific(lx_tsd_key,
   509 		    (void **)&lx_tsd)) != 0)
   510 			lx_err_fatal(gettext(
   511 			    "%s: unable to read thread-specific data: %s"),
   512 			    "lx_emulate", strerror(ret));
   513 
   514 		assert(lx_tsd != 0);
   515 
   516 		lx_tsd->lxtsd_gs = gs;
   517 
   518 		lx_debug("lx_emulate(): gsp 0x%p, saved gs: 0x%x", lx_tsd, gs);
   519 	}
   520 
   521 	if (s->sy_flags == SYS_PASSTHRU)
   522 		lx_debug("\tCalling Solaris %s()", s->sy_name);
   523 
   524 	ret = s->sy_callc(args[0], args[1], args[2], args[3], args[4], args[5]);
   525 
   526 	if (ret > -65536 && ret < 65536)
   527 		lx_debug("\t= %d", ret);
   528 	else
   529 		lx_debug("\t= 0x%x", ret);
   530 
   531 	if ((s->sy_flags == SYS_PASSTHRU) && (ret == -1)) {
   532 		ret = -stol_errno[errno];
   533 	} else {
   534 		/*
   535 		 * If the return value is between -4096 and 0 we assume it's an
   536 		 * error, so we translate the Solaris error number into the
   537 		 * Linux equivalent.
   538 		 */
   539 		if (ret < 0 && ret > -4096) {
   540 			if (-ret >=
   541 			    sizeof (stol_errno) / sizeof (stol_errno[0])) {
   542 				lx_debug("Invalid return value from emulated "
   543 				    "syscall %d (%s): %d\n",
   544 				    syscall_num, s->sy_name, ret);
   545 				assert(0);
   546 			}
   547 
   548 			ret = -stol_errno[-ret];
   549 		}
   550 	}
   551 
   552 out:
   553 	/*
   554 	 * %eax holds the return code from the system call.
   555 	 */
   556 	rp->lxr_eax = ret;
   557 
   558 	/*
   559 	 * If the trace flag is set, bounce into the kernel to let it do
   560 	 * any necessary tracing (DTrace or ptrace).
   561 	 */
   562 	if (lx_traceflag != 0) {
   563 		rp->lxr_orig_eax = syscall_num;
   564 		(void) syscall(SYS_brand, B_SYSRETURN, syscall_num, ret);
   565 	}
   566 }
   567 
   568 /* Transform the Linux locale name to make it look like a Solaris locale name */
   569 static const char *
   570 lx_translate_locale(char *translated_name_mem, int mem_size)
   571 {
   572 	char *loc;
   573 	int i;
   574 	size_t len;
   575 
   576 	if ((loc = getenv("LC_ALL")) == NULL)
   577 		if ((loc = getenv("LANG")) == NULL)
   578 			return ("C");
   579 
   580 	if (strlcpy(translated_name_mem, loc, mem_size) >= mem_size)
   581 		return ("");
   582 
   583 	len = strlen(loc);
   584 
   585 	/* replace the end of the locale name if it's a known pattern */
   586 	for (i = 0; i < sizeof (lx_locales) / sizeof (struct lx_locale_ending);
   587 	    i++) {
   588 		if (len <= lx_locales[i].le_size)
   589 			continue;
   590 
   591 		if (strncmp(loc + len - lx_locales[i].le_size,
   592 		    lx_locales[i].linux_end, lx_locales[i].le_size))
   593 			continue; /* don't match */
   594 
   595 		if (len - lx_locales[i].le_size + lx_locales[i].se_size
   596 		    >= mem_size)
   597 			return ("C"); /* size too small for the new name */
   598 
   599 		(void) strlcpy(translated_name_mem + len -
   600 		    lx_locales[i].le_size, lx_locales[i].solaris_end,
   601 		    lx_locales[i].se_size + 1);
   602 
   603 		return ((const char *)translated_name_mem);
   604 	}
   605 
   606 	/* no match */
   607 	return ("");
   608 }
   609 
   610 static void
   611 lx_close_fh(FILE *file)
   612 {
   613 	int fd, fd_new;
   614 
   615 	if (file == NULL)
   616 		return;
   617 
   618 	if ((fd = fileno(file)) < 0)
   619 		return;
   620 
   621 	fd_new = dup(fd);
   622 	if (fd_new == -1)
   623 		return;
   624 
   625 	(void) fclose(file);
   626 	(void) dup2(fd_new, fd);
   627 	(void) close(fd_new);
   628 }
   629 
   630 extern int set_l10n_alternate_root(char *path);
   631 
   632 /*ARGSUSED*/
   633 int
   634 lx_init(int argc, char *argv[], char *envp[])
   635 {
   636 	char		*r;
   637 	auxv_t		*ap;
   638 	int		*p, err;
   639 	lx_elf_data_t	edp;
   640 	lx_brand_registration_t reg;
   641 	char 		locale_translated_name[MAXLOCALENAMELEN];
   642 	static lx_tsd_t lx_tsd;
   643 
   644 	/* Look up the PID that serves as init for this zone */
   645 	if ((err = lx_lpid_to_spid(1, &zoneinit_pid)) < 0)
   646 		lx_err_fatal(gettext(
   647 		    "Unable to find PID for zone init process: %s"),
   648 		    strerror(err));
   649 
   650 	/*
   651 	 * Ubuntu init will fail if its TERM environment variable is not set
   652 	 * so if we are running init, and TERM is not set, we set term and
   653 	 * reexec so that the new environment variable is propagated to the
   654 	 * linux application stack.
   655 	 */
   656 	if ((getpid() == zoneinit_pid) && (getenv("TERM") == NULL)) {
   657 		if (setenv("TERM", "vt100", 1) < 0 || execv(argv[0], argv) < 0)
   658 			lx_err_fatal(gettext("failed to set TERM"));
   659 	}
   660 
   661 	if ((set_l10n_alternate_root("/native") == 0) &&
   662 	    (setlocale(LC_ALL, lx_translate_locale(locale_translated_name,
   663 	    sizeof (locale_translated_name))) != NULL) &&
   664 	    (bindtextdomain(TEXT_DOMAIN, "/native/usr/lib/locale") != NULL)) {
   665 		(void) textdomain(TEXT_DOMAIN);
   666 	}
   667 
   668 	stack_bottom = 2 * sysconf(_SC_PAGESIZE);
   669 
   670 	/*
   671 	 * We need to shutdown all libc stdio.  libc stdio normally goes to
   672 	 * file descriptors, but since we're actually part of a linux
   673 	 * process we don't own these file descriptors and we can't make
   674 	 * any assumptions about their state.
   675 	 */
   676 	lx_close_fh(stdin);
   677 	lx_close_fh(stdout);
   678 	lx_close_fh(stderr);
   679 
   680 	lx_debug_init();
   681 
   682 	r = getenv("LX_RELEASE");
   683 	if (r == NULL) {
   684 		if (lx_get_kern_version() == LX_KERN_2_6)
   685 			(void) strlcpy(lx_release, LX_UNAME_RELEASE_2_6,
   686 			    sizeof (lx_release));
   687 		else
   688 			(void) strlcpy(lx_release, LX_UNAME_RELEASE_2_4,
   689 			    sizeof (lx_release));
   690 	} else {
   691 		(void) strlcpy(lx_release, r, 128);
   692 	}
   693 
   694 	lx_debug("lx_release: %s\n", lx_release);
   695 
   696 	/*
   697 	 * Should we kill an application that attempts an unimplemented
   698 	 * system call?
   699 	 */
   700 	if (getenv("LX_STRICT") != NULL) {
   701 		lx_strict = 1;
   702 		lx_debug("STRICT mode enabled.\n");
   703 	}
   704 
   705 	/*
   706 	 * Are we in install mode?
   707 	 */
   708 	if (getenv("LX_INSTALL") != NULL) {
   709 		lx_install = 1;
   710 		lx_debug("INSTALL mode enabled.\n");
   711 	}
   712 
   713 	/*
   714 	 * Should we attempt to send messages to the screen?
   715 	 */
   716 	if (getenv("LX_VERBOSE") != NULL) {
   717 		lx_verbose = 1;
   718 		lx_debug("VERBOSE mode enabled.\n");
   719 	}
   720 
   721 	lx_debug("executing linux process: %s", argv[0]);
   722 	lx_debug("branding myself and setting handler to 0x%p",
   723 	    (void *)lx_handler_table);
   724 
   725 	/*
   726 	 * The version of rpm that ships with CentOS/RHEL 3.x has a race
   727 	 * condition in it.  If it creates a child process to run a
   728 	 * post-install script, and that child process completes too
   729 	 * quickly, it will disappear before the parent notices.  This
   730 	 * causes the parent to hang forever waiting for the already dead
   731 	 * child to die.  I'm sure there's a Lazarus joke buried in here
   732 	 * somewhere.
   733 	 *
   734 	 * Anyway, as a workaround, we make every child of an 'rpm' process
   735 	 * sleep for 1 second, giving the parent a chance to enter its
   736 	 * wait-for-the-child-to-die loop.  Thay may be the hackiest trick
   737 	 * in all of our Linux emulation code - and that's saying
   738 	 * something.
   739 	 */
   740 	if (strcmp("rpm", basename(argv[0])) == NULL)
   741 		lx_is_rpm = B_TRUE;
   742 
   743 	reg.lxbr_version = LX_VERSION;
   744 	reg.lxbr_handler = (void *)&lx_handler_table;
   745 	reg.lxbr_tracehandler = (void *)&lx_handler_trace_table;
   746 	reg.lxbr_traceflag = &lx_traceflag;
   747 
   748 	/*
   749 	 * Register the address of the user-space handler with the lx
   750 	 * brand module.
   751 	 */
   752 	if (syscall(SYS_brand, B_REGISTER, &reg))
   753 		lx_err_fatal(gettext("failed to brand the process"));
   754 
   755 	/*
   756 	 * Download data about the lx executable from the kernel.
   757 	 */
   758 	if (syscall(SYS_brand, B_ELFDATA, (void *)&edp))
   759 		lx_err_fatal(gettext(
   760 		    "failed to get required ELF data from the kernel"));
   761 
   762 	if (lx_ioctl_init() != 0)
   763 		lx_err_fatal(gettext("failed to setup the %s translator"),
   764 		    "ioctl");
   765 
   766 	if (lx_stat_init() != 0)
   767 		lx_err_fatal(gettext("failed to setup the %s translator"),
   768 		    "stat");
   769 
   770 	if (lx_statfs_init() != 0)
   771 		lx_err_fatal(gettext("failed to setup the %s translator"),
   772 		    "statfs");
   773 
   774 	/*
   775 	 * Find the aux vector on the stack.
   776 	 */
   777 	p = (int *)envp;
   778 	while (*p != NULL)
   779 		p++;
   780 	/*
   781 	 * p is now pointing at the 0 word after the environ pointers. After
   782 	 * that is the aux vectors.
   783 	 */
   784 	p++;
   785 	for (ap = (auxv_t *)p; ap->a_type != 0; ap++) {
   786 		switch (ap->a_type) {
   787 			case AT_BASE:
   788 				ap->a_un.a_val = edp.ed_base;
   789 				break;
   790 			case AT_ENTRY:
   791 				ap->a_un.a_val = edp.ed_entry;
   792 				break;
   793 			case AT_PHDR:
   794 				ap->a_un.a_val = edp.ed_phdr;
   795 				break;
   796 			case AT_PHENT:
   797 				ap->a_un.a_val = edp.ed_phent;
   798 				break;
   799 			case AT_PHNUM:
   800 				ap->a_un.a_val = edp.ed_phnum;
   801 				break;
   802 			default:
   803 				break;
   804 		}
   805 	}
   806 
   807 	/* Do any thunk server initalization. */
   808 	lxt_server_init(argc, argv);
   809 
   810 	/* Setup signal handler information. */
   811 	if (lx_siginit())
   812 		lx_err_fatal(gettext(
   813 		    "failed to initialize lx signals for the branded process"));
   814 
   815 	/* Setup thread-specific data area for managing linux threads. */
   816 	if ((err = thr_keycreate(&lx_tsd_key, NULL)) != 0)
   817 		lx_err_fatal(
   818 		    gettext("%s failed: %s"), "thr_keycreate(lx_tsd_key)",
   819 		    strerror(err));
   820 
   821 	lx_debug("thr_keycreate created lx_tsd_key (%d)", lx_tsd_key);
   822 
   823 	/* Initialize the thread specific data for this thread. */
   824 	bzero(&lx_tsd, sizeof (lx_tsd));
   825 	lx_tsd.lxtsd_gs = LWPGS_SEL;
   826 
   827 	if ((err = thr_setspecific(lx_tsd_key, &lx_tsd)) != 0)
   828 		lx_err_fatal(gettext(
   829 		    "Unable to initialize thread-specific data: %s"),
   830 		    strerror(err));
   831 
   832 	/*
   833 	 * Save the current context of this thread.
   834 	 * We'll restore this context when this thread attempts to exit.
   835 	 */
   836 	if (getcontext(&lx_tsd.lxtsd_exit_context) != 0)
   837 		lx_err_fatal(gettext(
   838 		    "Unable to initialize thread-specific exit context: %s"),
   839 		    strerror(errno));
   840 
   841 	if (lx_tsd.lxtsd_exit == 0) {
   842 		lx_runexe(argv, edp.ed_ldentry);
   843 		/* lx_runexe() never returns. */
   844 		assert(0);
   845 	}
   846 
   847 	/*
   848 	 * We are here because the Linux application called the exit() or
   849 	 * exit_group() system call.  In turn the brand library did a
   850 	 * setcontext() to jump to the thread context state we saved above.
   851 	 */
   852 	if (lx_tsd.lxtsd_exit == 1)
   853 		thr_exit((void *)lx_tsd.lxtsd_exit_status);
   854 	else
   855 		exit(lx_tsd.lxtsd_exit_status);
   856 
   857 	assert(0);
   858 
   859 	/*NOTREACHED*/
   860 	return (0);
   861 }
   862 
   863 /*
   864  * Walk back through the stack until we find the lx_emulate() frame.
   865  */
   866 lx_regs_t *
   867 lx_syscall_regs(void)
   868 {
   869 	/* LINTED - alignment */
   870 	struct frame *fr = (struct frame *)_getfp();
   871 
   872 	while (fr->fr_savpc != (uintptr_t)&lx_emulate_done) {
   873 		fr = (struct frame *)fr->fr_savfp;
   874 		assert(fr->fr_savpc != NULL);
   875 	}
   876 
   877 	return ((lx_regs_t *)((uintptr_t *)fr)[2]);
   878 }
   879 
   880 int
   881 lx_lpid_to_spair(pid_t lpid, pid_t *spid, lwpid_t *slwp)
   882 {
   883 	pid_t pid;
   884 	lwpid_t tid;
   885 
   886 	if (lpid == 0) {
   887 		pid = getpid();
   888 		tid = thr_self();
   889 	} else {
   890 		if (syscall(SYS_brand, B_LPID_TO_SPAIR, lpid, &pid, &tid) < 0)
   891 			return (-errno);
   892 
   893 		/*
   894 		 * If the returned pid is -1, that indicates we tried to
   895 		 * look up the PID for init, but that process no longer
   896 		 * exists.
   897 		 */
   898 		if (pid == -1)
   899 			return (-ESRCH);
   900 	}
   901 
   902 	if (uucopy(&pid, spid, sizeof (pid_t)) != 0)
   903 		return (-errno);
   904 
   905 	if (uucopy(&tid, slwp, sizeof (lwpid_t)) != 0)
   906 		return (-errno);
   907 
   908 	return (0);
   909 }
   910 
   911 int
   912 lx_lpid_to_spid(pid_t lpid, pid_t *spid)
   913 {
   914 	lwpid_t slwp;
   915 
   916 	return (lx_lpid_to_spair(lpid, spid, &slwp));
   917 }
   918 
   919 char *
   920 lx_fd_to_path(int fd, char *buf, int buf_size)
   921 {
   922 	char	path_proc[MAXPATHLEN];
   923 	pid_t	pid;
   924 	int	n;
   925 
   926 	assert((buf != NULL) && (buf_size >= 0));
   927 
   928 	if (fd < 0)
   929 		return (NULL);
   930 
   931 	if ((pid = getpid()) == -1)
   932 		return (NULL);
   933 
   934 	(void) snprintf(path_proc, MAXPATHLEN,
   935 	    "/native/proc/%d/path/%d", pid, fd);
   936 
   937 	if ((n = readlink(path_proc, buf, buf_size - 1)) == -1)
   938 		return (NULL);
   939 	buf[n] = '\0';
   940 
   941 	return (buf);
   942 }
   943 
   944 /*
   945  * Create a translation routine that jumps to a particular emulation
   946  * module syscall.
   947  */
   948 #define	IN_KERNEL_SYSCALL(name, num)		\
   949 int						\
   950 lx_##name(uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4,	\
   951 	uintptr_t p5, uintptr_t p6)		\
   952 {						\
   953 	int r;					\
   954 	lx_debug("\tsyscall %d re-vectoring to lx kernel module "	\
   955 	    "for " #name "()", num);		\
   956 	r = syscall(SYS_brand, B_EMULATE_SYSCALL + num, p1, p2,		\
   957 	    p3, p4, p5, p6);			\
   958 	return ((r == -1) ? -errno : r);		\
   959 }
   960 
   961 IN_KERNEL_SYSCALL(kill, 37)
   962 IN_KERNEL_SYSCALL(brk, 45)
   963 IN_KERNEL_SYSCALL(ustat, 62)
   964 IN_KERNEL_SYSCALL(getppid, 64)
   965 IN_KERNEL_SYSCALL(sysinfo, 116)
   966 IN_KERNEL_SYSCALL(modify_ldt, 123)
   967 IN_KERNEL_SYSCALL(adjtimex, 124)
   968 IN_KERNEL_SYSCALL(setresuid16, 164)
   969 IN_KERNEL_SYSCALL(setresgid16, 170)
   970 IN_KERNEL_SYSCALL(setresuid, 208)
   971 IN_KERNEL_SYSCALL(setresgid, 210)
   972 IN_KERNEL_SYSCALL(gettid, 224)
   973 IN_KERNEL_SYSCALL(tkill, 238)
   974 IN_KERNEL_SYSCALL(futex, 240)
   975 IN_KERNEL_SYSCALL(set_thread_area, 243)
   976 IN_KERNEL_SYSCALL(get_thread_area, 244)
   977 IN_KERNEL_SYSCALL(set_tid_address, 258)
   978 
   979 static struct lx_sysent sysents[] = {
   980 	{"nosys",	NULL,		NOSYS_NULL,	0},	/*  0 */
   981 	{"exit",	lx_exit,	0,		1},	/*  1 */
   982 	{"fork",	lx_fork,	0,		0},	/*  2 */
   983 	{"read",	lx_read,	0,		3},	/*  3 */
   984 	{"write",	write,		SYS_PASSTHRU,	3},	/*  4 */
   985 	{"open",	lx_open,	0,		3},	/*  5 */
   986 	{"close",	close,		SYS_PASSTHRU,	1},	/*  6 */
   987 	{"waitpid",	lx_waitpid,	0,		3},	/*  7 */
   988 	{"creat",	creat,		SYS_PASSTHRU,	2},	/*  8 */
   989 	{"link",	lx_link,	0,		2},	/*  9 */
   990 	{"unlink",	lx_unlink,	0,		1},	/* 10 */
   991 	{"execve",	lx_execve,	0,		3},	/* 11 */
   992 	{"chdir",	chdir,		SYS_PASSTHRU,	1},	/* 12 */
   993 	{"time",	lx_time,	0,		1},	/* 13 */
   994 	{"mknod",	lx_mknod,	0,		3},	/* 14 */
   995 	{"chmod",	lx_chmod,	0,		2},	/* 15 */
   996 	{"lchown16",	lx_lchown16,	0,		3},	/* 16 */
   997 	{"break",	NULL,		NOSYS_OBSOLETE,	0},	/* 17 */
   998 	{"stat",	NULL,		NOSYS_OBSOLETE,	0},	/* 18 */
   999 	{"lseek",	lx_lseek,	0,		3},	/* 19 */
  1000 	{"getpid",	lx_getpid,	0,		0},	/* 20 */
  1001 	{"mount",	lx_mount,	0,		5},	/* 21 */
  1002 	{"umount",	lx_umount,	0,		1},	/* 22 */
  1003 	{"setuid16",	lx_setuid16,	0,		1},	/* 23 */
  1004 	{"getuid16",	lx_getuid16,	0,		0},	/* 24 */
  1005 	{"stime",	stime,		SYS_PASSTHRU,	1},	/* 25 */
  1006 	{"ptrace",	lx_ptrace,	0,		4},	/* 26 */
  1007 	{"alarm",	(int (*)())alarm, SYS_PASSTHRU,	1},	/* 27 */
  1008 	{"fstat",	NULL,		NOSYS_OBSOLETE,	0},	/* 28 */
  1009 	{"pause",	pause,		SYS_PASSTHRU,	0},	/* 29 */
  1010 	{"utime",	lx_utime,	0,		2},	/* 30 */
  1011 	{"stty",	NULL,		NOSYS_OBSOLETE,	0},	/* 31 */
  1012 	{"gtty",	NULL,		NOSYS_OBSOLETE,	0},	/* 32 */
  1013 	{"access",	access,		SYS_PASSTHRU,	2},	/* 33 */
  1014 	{"nice",	nice,		SYS_PASSTHRU,	1},	/* 34 */
  1015 	{"ftime",	NULL,		NOSYS_OBSOLETE,	0},	/* 35 */
  1016 	{"sync",	lx_sync, 	0, 		0},	/* 36 */
  1017 	{"kill",	lx_kill,	0,		2},	/* 37 */
  1018 	{"rename",	lx_rename,	0,		2},	/* 38 */
  1019 	{"mkdir",	mkdir,		SYS_PASSTHRU,	2},	/* 39 */
  1020 	{"rmdir",	lx_rmdir,	0,		1},	/* 40 */
  1021 	{"dup",		dup,		SYS_PASSTHRU,	1},	/* 41 */
  1022 	{"pipe",	lx_pipe,	0,		1},	/* 42 */
  1023 	{"times",	lx_times,	0,		1},	/* 43 */
  1024 	{"prof",	NULL,		NOSYS_OBSOLETE,	0},	/* 44 */
  1025 	{"brk",		lx_brk,		0,		1},	/* 45 */
  1026 	{"setgid16",	lx_setgid16,	0,		1},	/* 46 */
  1027 	{"getgid16",	lx_getgid16,	0,		0},	/* 47 */
  1028 	{"signal",	lx_signal,	0,		2},	/* 48 */
  1029 	{"geteuid16",	lx_geteuid16,	0,		0},	/* 49 */
  1030 	{"getegid16",	lx_getegid16,	0,		0},	/* 50 */
  1031 	{"acct",	NULL,		NOSYS_NO_EQUIV,	0},	/* 51 */
  1032 	{"umount2",	lx_umount2,	0,		2},	/* 52 */
  1033 	{"lock",	NULL,		NOSYS_OBSOLETE,	0},	/* 53 */
  1034 	{"ioctl",	lx_ioctl,	0,		3},	/* 54 */
  1035 	{"fcntl",	lx_fcntl,	0,		3},	/* 55 */
  1036 	{"mpx",		NULL,		NOSYS_OBSOLETE,	0},	/* 56 */
  1037 	{"setpgid",	lx_setpgid,	0,		2},	/* 57 */
  1038 	{"ulimit",	NULL,		NOSYS_OBSOLETE,	0},	/* 58 */
  1039 	{"olduname",	NULL,		NOSYS_OBSOLETE,	0},	/* 59 */
  1040 	{"umask",	(int (*)())umask, SYS_PASSTHRU,	1},	/* 60 */
  1041 	{"chroot",	chroot,		SYS_PASSTHRU,	1},	/* 61 */
  1042 	{"ustat",	lx_ustat,	0,		2},	/* 62 */
  1043 	{"dup2",	lx_dup2,	0,		2},	/* 63 */
  1044 	{"getppid",	lx_getppid,	0,		0},	/* 64 */
  1045 	{"getpgrp",	lx_getpgrp,	0,		0},	/* 65 */
  1046 	{"setsid",	lx_setsid,	0,		0},	/* 66 */
  1047 	{"sigaction",	lx_sigaction,	0,		3},	/* 67 */
  1048 	{"sgetmask",	NULL,		NOSYS_OBSOLETE,	0},	/* 68 */
  1049 	{"ssetmask",	NULL,		NOSYS_OBSOLETE,	0},	/* 69 */
  1050 	{"setreuid16",	lx_setreuid16,	0,		2},	/* 70 */
  1051 	{"setregid16",	lx_setregid16,	0,		2},	/* 71 */
  1052 	{"sigsuspend",	lx_sigsuspend,	0,		1},	/* 72 */
  1053 	{"sigpending",	lx_sigpending,	0,		1},	/* 73 */
  1054 	{"sethostname",	lx_sethostname,	0,		2},	/* 74 */
  1055 	{"setrlimit",	lx_setrlimit,	0,		2},	/* 75 */
  1056 	{"getrlimit",	lx_oldgetrlimit, 0,		2},	/* 76 */
  1057 	{"getrusage",	lx_getrusage,	0,		2},	/* 77 */
  1058 	{"gettimeofday", lx_gettimeofday, 0,		2},	/* 78 */
  1059 	{"settimeofday", lx_settimeofday, 0,		2},	/* 79 */
  1060 	{"getgroups16",	lx_getgroups16,	0,		2},	/* 80 */
  1061 	{"setgroups16",	lx_setgroups16,	0,		2},	/* 81 */
  1062 	{"select",	NULL,		NOSYS_OBSOLETE,	0},	/* 82 */
  1063 	{"symlink",	symlink,	SYS_PASSTHRU,	2},	/* 83 */
  1064 	{"oldlstat",	NULL,		NOSYS_OBSOLETE,	0},	/* 84 */
  1065 	{"readlink",	readlink,	SYS_PASSTHRU,	3},	/* 85 */
  1066 	{"uselib",	NULL,		NOSYS_KERNEL,	0},	/* 86 */
  1067 	{"swapon",	NULL,		NOSYS_KERNEL,	0},	/* 87 */
  1068 	{"reboot",	lx_reboot,	0,		4},	/* 88 */
  1069 	{"readdir",	lx_readdir,	0,		3},	/* 89 */
  1070 	{"mmap",	lx_mmap,	0,		6},	/* 90 */
  1071 	{"munmap",	munmap,		SYS_PASSTHRU,	2},	/* 91 */
  1072 	{"truncate",	lx_truncate,	0,		2},	/* 92 */
  1073 	{"ftruncate",	lx_ftruncate,	0,		2},	/* 93 */
  1074 	{"fchmod",	fchmod,		SYS_PASSTHRU,	2},	/* 94 */
  1075 	{"fchown16",	lx_fchown16,	0,		3},	/* 95 */
  1076 	{"getpriority",	lx_getpriority,	0,		2},	/* 96 */
  1077 	{"setpriority",	lx_setpriority,	0,		3},	/* 97 */
  1078 	{"profil",	NULL,		NOSYS_NO_EQUIV,	0},	/* 98 */
  1079 	{"statfs",	lx_statfs,	0,		2},	/* 99 */
  1080 	{"fstatfs",	lx_fstatfs,	0,		2},	/* 100 */
  1081 	{"ioperm",	NULL,		NOSYS_NO_EQUIV,	0},	/* 101 */
  1082 	{"socketcall",	lx_socketcall,	0,		2},	/* 102 */
  1083 	{"syslog",	NULL,		NOSYS_KERNEL,	0},	/* 103 */
  1084 	{"setitimer",	lx_setitimer,	0,		3},	/* 104 */
  1085 	{"getitimer",	getitimer,	SYS_PASSTHRU,	2},	/* 105 */
  1086 	{"stat",	lx_stat,	0,		2},	/* 106 */
  1087 	{"lstat",	lx_lstat,	0,		2},	/* 107 */
  1088 	{"fstat",	lx_fstat,	0,		2},	/* 108 */
  1089 	{"uname",	NULL,		NOSYS_OBSOLETE,	0},	/* 109 */
  1090 	{"oldiopl",	NULL,		NOSYS_NO_EQUIV,	0},	/* 110 */
  1091 	{"vhangup",	lx_vhangup,	0,		0},	/* 111 */
  1092 	{"idle",	NULL,		NOSYS_NO_EQUIV,	0},	/* 112 */
  1093 	{"vm86old",	NULL,		NOSYS_OBSOLETE,	0},	/* 113 */
  1094 	{"wait4",	lx_wait4,	0,		4},	/* 114 */
  1095 	{"swapoff",	NULL,		NOSYS_KERNEL,	0},	/* 115 */
  1096 	{"sysinfo",	lx_sysinfo,	0,		1},	/* 116 */
  1097 	{"ipc",		lx_ipc,		0,		5},	/* 117 */
  1098 	{"fsync",	lx_fsync,	0,		1},	/* 118 */
  1099 	{"sigreturn",	lx_sigreturn,	0,		1},	/* 119 */
  1100 	{"clone",	lx_clone,	0,		5},	/* 120 */
  1101 	{"setdomainname", lx_setdomainname, 0,		2},	/* 121 */
  1102 	{"uname",	lx_uname,	0,		1},	/* 122 */
  1103 	{"modify_ldt",	lx_modify_ldt,	0,		3},	/* 123 */
  1104 	{"adjtimex",	lx_adjtimex,	0,		1},	/* 124 */
  1105 	{"mprotect",	lx_mprotect,	0,		3},	/* 125 */
  1106 	{"sigprocmask",	lx_sigprocmask,	0,		3},	/* 126 */
  1107 	{"create_module", NULL,		NOSYS_KERNEL,	0},	/* 127 */
  1108 	{"init_module",	NULL,		NOSYS_KERNEL,	0},	/* 128 */
  1109 	{"delete_module", NULL,		NOSYS_KERNEL,	0},	/* 129 */
  1110 	{"get_kernel_syms", NULL,	NOSYS_KERNEL,	0},	/* 130 */
  1111 	{"quotactl",	NULL,		NOSYS_KERNEL,	0},	/* 131 */
  1112 	{"getpgid",	lx_getpgid,	0,		1},	/* 132 */
  1113 	{"fchdir",	fchdir,		SYS_PASSTHRU,	1},	/* 133 */
  1114 	{"bdflush",	NULL,		NOSYS_KERNEL,	0},	/* 134 */
  1115 	{"sysfs",	lx_sysfs, 	0,		3},	/* 135 */
  1116 	{"personality",	lx_personality,	0,		1},	/* 136 */
  1117 	{"afs_syscall",	NULL,		NOSYS_KERNEL,	0},	/* 137 */
  1118 	{"setfsuid16",	lx_setfsuid16,	0,		1},	/* 138 */
  1119 	{"setfsgid16",	lx_setfsgid16,	0,		1},	/* 139 */
  1120 	{"llseek",	lx_llseek,	0,		5},	/* 140 */
  1121 	{"getdents",	getdents,	SYS_PASSTHRU,	3},	/* 141 */
  1122 	{"select",	lx_select,	0,		5},	/* 142 */
  1123 	{"flock",	lx_flock,	0,		2},	/* 143 */
  1124 	{"msync",	lx_msync,	0,		3},	/* 144 */
  1125 	{"readv",	lx_readv,	0,		3},	/* 145 */
  1126 	{"writev",	lx_writev,	0,		3},	/* 146 */
  1127 	{"getsid",	lx_getsid,	0,		1},	/* 147 */
  1128 	{"fdatasync",	lx_fdatasync,	0,		1},	/* 148 */
  1129 	{"sysctl",	lx_sysctl,	0,		1},	/* 149 */
  1130 	{"mlock",	lx_mlock,	0,		2},	/* 150 */
  1131 	{"munlock",	lx_munlock,	0,		2},	/* 151 */
  1132 	{"mlockall",	lx_mlockall,	0,		1},	/* 152 */
  1133 	{"munlockall",	lx_munlockall,	0,		0},	/* 153 */
  1134 	{"sched_setparam", lx_sched_setparam,	0,	2},	/* 154 */
  1135 	{"sched_getparam", lx_sched_getparam,	0,	2},	/* 155 */
  1136 	{"sched_setscheduler", lx_sched_setscheduler, 0, 3},	/* 156 */
  1137 	{"sched_getscheduler", lx_sched_getscheduler, 0, 1},	/* 157 */
  1138 	{"sched_yield",	(int (*)())yield, SYS_PASSTHRU,	0},	/* 158 */
  1139 	{"sched_get_priority_max", lx_sched_get_priority_max, 0, 1}, /* 159 */
  1140 	{"sched_get_priority_min", lx_sched_get_priority_min, 0, 1}, /* 160 */
  1141 	{"sched_rr_get_interval", lx_sched_rr_get_interval, 0,	2},  /* 161 */
  1142 	{"nanosleep",	nanosleep,	SYS_PASSTHRU,	2},	/* 162 */
  1143 	{"mremap",	NULL,		NOSYS_NO_EQUIV,	0},	/* 163 */
  1144 	{"setresuid16",	lx_setresuid16,	0,		3},	/* 164 */
  1145 	{"getresuid16",	lx_getresuid16,	0,		3},	/* 165 */
  1146 	{"vm86",	NULL,		NOSYS_NO_EQUIV,	0},	/* 166 */
  1147 	{"query_module", lx_query_module, NOSYS_KERNEL,	5},	/* 167 */
  1148 	{"poll",	lx_poll,	0,		3},	/* 168 */
  1149 	{"nfsservctl",	NULL,		NOSYS_KERNEL,	0},	/* 169 */
  1150 	{"setresgid16",	lx_setresgid16,	0,		3},	/* 170 */
  1151 	{"getresgid16",	lx_getresgid16,	0,		3},	/* 171 */
  1152 	{"prctl",	NULL,		NOSYS_UNDOC,	0},	/* 172 */
  1153 	{"rt_sigreturn", lx_rt_sigreturn, 0,		0},	/* 173 */
  1154 	{"rt_sigaction", lx_rt_sigaction, 0,		4},	/* 174 */
  1155 	{"rt_sigprocmask", lx_rt_sigprocmask, 0,	4},	/* 175 */
  1156 	{"rt_sigpending", lx_rt_sigpending, 0,		2},	/* 176 */
  1157 	{"rt_sigtimedwait", lx_rt_sigtimedwait,	0,	4},	/* 177 */
  1158 	{"sigqueueinfo", NULL,		NOSYS_UNDOC,	0},	/* 178 */
  1159 	{"rt_sigsuspend", lx_rt_sigsuspend, 0,		2},	/* 179 */
  1160 	{"pread64",	lx_pread64,	0,		5},	/* 180 */
  1161 	{"pwrite64",	lx_pwrite64,	0,		5},	/* 181 */
  1162 	{"chown16",	lx_chown16,	0,		3},	/* 182 */
  1163 	{"getcwd",	lx_getcwd,	0,		2},	/* 183 */
  1164 	{"capget",	NULL,		NOSYS_NO_EQUIV,	0},	/* 184 */
  1165 	{"capset",	NULL,		NOSYS_NO_EQUIV,	0},	/* 185 */
  1166 	{"sigaltstack",	lx_sigaltstack,	0,		2},	/* 186 */
  1167 	{"sendfile",	lx_sendfile,	0,		4},	/* 187 */
  1168 	{"getpmsg",	NULL,		NOSYS_OBSOLETE,	0},	/* 188 */
  1169 	{"putpmsg",	NULL,		NOSYS_OBSOLETE,	0},	/* 189 */
  1170 	{"vfork",	lx_vfork,	0,		0},	/* 190 */
  1171 	{"getrlimit",	lx_getrlimit,	0,		2},	/* 191 */
  1172 	{"mmap2",	lx_mmap2,	EBP_HAS_ARG6,	6},	/* 192 */
  1173 	{"truncate64",	lx_truncate64,	0,		3},	/* 193 */
  1174 	{"ftruncate64",	lx_ftruncate64,	0,		3},	/* 194 */
  1175 	{"stat64",	lx_stat64,	0,		2},	/* 195 */
  1176 	{"lstat64",	lx_lstat64,	0,		2},	/* 196 */
  1177 	{"fstat64",	lx_fstat64,	0,		2},	/* 197 */
  1178 	{"lchown",	lchown,		SYS_PASSTHRU,	3},	/* 198 */
  1179 	{"getuid",	(int (*)())getuid, SYS_PASSTHRU, 0},	/* 199 */
  1180 	{"getgid",	(int (*)())getgid, SYS_PASSTHRU, 0},	/* 200 */
  1181 	{"geteuid",	lx_geteuid,	0,		0},	/* 201 */
  1182 	{"getegid",	lx_getegid,	0,		0},	/* 202 */
  1183 	{"setreuid",	setreuid,	SYS_PASSTHRU,	0},	/* 203 */
  1184 	{"setregid",	setregid,	SYS_PASSTHRU,	0},	/* 204 */
  1185 	{"getgroups",	getgroups,	SYS_PASSTHRU,	2},	/* 205 */
  1186 	{"setgroups",	lx_setgroups,	0,		2},	/* 206 */
  1187 	{"fchown",	lx_fchown,	0,		3},	/* 207 */
  1188 	{"setresuid",	lx_setresuid,	0,		3},	/* 208 */
  1189 	{"getresuid",	lx_getresuid,	0,		3},	/* 209 */
  1190 	{"setresgid",	lx_setresgid,	0,		3},	/* 210 */
  1191 	{"getresgid",	lx_getresgid,	0,		3},	/* 211 */
  1192 	{"chown",	lx_chown,	0,		3},	/* 212 */
  1193 	{"setuid",	setuid,		SYS_PASSTHRU,	1},	/* 213 */
  1194 	{"setgid",	setgid,		SYS_PASSTHRU,	1},	/* 214 */
  1195 	{"setfsuid",	lx_setfsuid,	0,		1},	/* 215 */
  1196 	{"setfsgid",	lx_setfsgid,	0,		1},	/* 216 */
  1197 	{"pivot_root",	NULL,		NOSYS_KERNEL,	0},	/* 217 */
  1198 	{"mincore",	mincore,	SYS_PASSTHRU,	3},	/* 218 */
  1199 	{"madvise",	lx_madvise,	0,		3},	/* 219 */
  1200 	{"getdents64",	lx_getdents64,	0,		3},	/* 220 */
  1201 	{"fcntl64",	lx_fcntl64,	0,		3},	/* 221 */
  1202 	{"tux",		NULL,		NOSYS_NO_EQUIV,	0},	/* 222 */
  1203 	{"security",	NULL,		NOSYS_NO_EQUIV,	0},	/* 223 */
  1204 	{"gettid",	lx_gettid,	0,		0},	/* 224 */
  1205 	{"readahead",	NULL,		NOSYS_NO_EQUIV,	0},	/* 225 */
  1206 	{"setxattr",	NULL,		NOSYS_NO_EQUIV,	0},	/* 226 */
  1207 	{"lsetxattr",	NULL,		NOSYS_NO_EQUIV,	0},	/* 227 */
  1208 	{"fsetxattr",	NULL,		NOSYS_NO_EQUIV,	0},	/* 228 */
  1209 	{"getxattr",	NULL,		NOSYS_NO_EQUIV,	0},	/* 229 */
  1210 	{"lgetxattr",	NULL,		NOSYS_NO_EQUIV,	0},	/* 230 */
  1211 	{"fgetxattr",	NULL,		NOSYS_NO_EQUIV,	0},	/* 231 */
  1212 	{"listxattr",	NULL,		NOSYS_NO_EQUIV,	0},	/* 232 */
  1213 	{"llistxattr",	NULL,		NOSYS_NO_EQUIV,	0},	/* 233 */
  1214 	{"flistxattr",	NULL,		NOSYS_NO_EQUIV,	0},	/* 234 */
  1215 	{"removexattr",	NULL,		NOSYS_NO_EQUIV,	0},	/* 235 */
  1216 	{"lremovexattr", NULL,		NOSYS_NO_EQUIV,	0},	/* 236 */
  1217 	{"fremovexattr", NULL,		NOSYS_NO_EQUIV,	0},	/* 237 */
  1218 	{"tkill",	lx_tkill,	0,		2},	/* 238 */
  1219 	{"sendfile64",	lx_sendfile64,	0,		4},	/* 239 */
  1220 	{"futex",	lx_futex,	EBP_HAS_ARG6,	6},	/* 240 */
  1221 	{"sched_setaffinity",	lx_sched_setaffinity,	0, 3},	/* 241 */
  1222 	{"sched_getaffinity",	lx_sched_getaffinity,	0, 3},	/* 242 */
  1223 	{"set_thread_area", lx_set_thread_area,	0,	1},	/* 243 */
  1224 	{"get_thread_area", lx_get_thread_area,	0,	1},	/* 244 */
  1225 	{"io_setup",	NULL,		NOSYS_NO_EQUIV,	0},	/* 245 */
  1226 	{"io_destroy",	NULL,		NOSYS_NO_EQUIV,	0},	/* 246 */
  1227 	{"io_getevents", NULL,		NOSYS_NO_EQUIV,	0},	/* 247 */
  1228 	{"io_submit",	NULL,		NOSYS_NO_EQUIV,	0},	/* 248 */
  1229 	{"io_cancel",	NULL,		NOSYS_NO_EQUIV,	0},	/* 249 */
  1230 	{"fadvise64",	NULL,		NOSYS_UNDOC,	0},	/* 250 */
  1231 	{"nosys",	NULL,		0,		0},	/* 251 */
  1232 	{"group_exit",	lx_group_exit,	0,		1},	/* 252 */
  1233 	{"lookup_dcookie", NULL,	NOSYS_NO_EQUIV,	0},	/* 253 */
  1234 	{"epoll_create", NULL,		NOSYS_NO_EQUIV,	0},	/* 254 */
  1235 	{"epoll_ctl",	NULL,		NOSYS_NO_EQUIV,	0},	/* 255 */
  1236 	{"epoll_wait",	NULL,		NOSYS_NO_EQUIV,	0},	/* 256 */
  1237 	{"remap_file_pages", NULL,	NOSYS_NO_EQUIV,	0},	/* 257 */
  1238 	{"set_tid_address", lx_set_tid_address,	0,	1},	/* 258 */
  1239 	{"timer_create", NULL,		NOSYS_UNDOC,	0},	/* 259 */
  1240 	{"timer_settime", NULL,		NOSYS_UNDOC,	0},	/* 260 */
  1241 	{"timer_gettime", NULL,		NOSYS_UNDOC,	0},	/* 261 */
  1242 	{"timer_getoverrun", NULL,	NOSYS_UNDOC,	0},	/* 262 */
  1243 	{"timer_delete", NULL,		NOSYS_UNDOC,	0},	/* 263 */
  1244 	{"clock_settime", lx_clock_settime,	0,	2},	/* 264 */
  1245 	{"clock_gettime", lx_clock_gettime,	0,	2},	/* 265 */
  1246 	{"clock_getres", lx_clock_getres,	0,	2},	/* 266 */
  1247 	{"clock_nanosleep", lx_clock_nanosleep,	0,	4},	/* 267 */
  1248 	{"statfs64",	lx_statfs64,	0,		2},	/* 268 */
  1249 	{"fstatfs64",	lx_fstatfs64,	0,		2},	/* 269 */
  1250 	{"tgkill",	lx_tgkill,	0,		3},	/* 270 */
  1251 
  1252 	/* The following system calls only exist in kernel 2.6 and greater */
  1253 	{"utimes",	utimes,		SYS_PASSTHRU,	2},	/* 271 */
  1254 	{"fadvise64_64", NULL,		NOSYS_NULL,	0},	/* 272 */
  1255 	{"vserver",	NULL,		NOSYS_NULL,	0},	/* 273 */
  1256 	{"mbind",	NULL,		NOSYS_NULL,	0},	/* 274 */
  1257 	{"get_mempolicy", NULL,		NOSYS_NULL,	0},	/* 275 */
  1258 	{"set_mempolicy", NULL,		NOSYS_NULL,	0},	/* 276 */
  1259 	{"mq_open",	NULL,		NOSYS_NULL,	0},	/* 277 */
  1260 	{"mq_unlink",	NULL,		NOSYS_NULL,	0},	/* 278 */
  1261 	{"mq_timedsend", NULL,		NOSYS_NULL,	0},	/* 279 */
  1262 	{"mq_timedreceive", NULL,	NOSYS_NULL,	0},	/* 280 */
  1263 	{"mq_notify",	NULL,		NOSYS_NULL,	0},	/* 281 */
  1264 	{"mq_getsetattr", NULL,		NOSYS_NULL,	0},	/* 282 */
  1265 	{"kexec_load",	NULL,		NOSYS_NULL,	0},	/* 283 */
  1266 	{"waitid",	lx_waitid,	0,		4},	/* 284 */
  1267 	{"sys_setaltroot", NULL,	NOSYS_NULL,	0},	/* 285 */
  1268 	{"add_key",	NULL,		NOSYS_NULL,	0},	/* 286 */
  1269 	{"request_key",	NULL,		NOSYS_NULL,	0},	/* 287 */
  1270 	{"keyctl",	NULL,		NOSYS_NULL,	0},	/* 288 */
  1271 	{"ioprio_set",	NULL,		NOSYS_NULL,	0},	/* 289 */
  1272 	{"ioprio_get",	NULL,		NOSYS_NULL,	0},	/* 290 */
  1273 	{"inotify_init", NULL,		NOSYS_NULL,	0},	/* 291 */
  1274 	{"inotify_add_watch", NULL,	NOSYS_NULL,	0},	/* 292 */
  1275 	{"inotify_rm_watch", NULL,	NOSYS_NULL,	0},	/* 293 */
  1276 	{"migrate_pages", NULL,		NOSYS_NULL,	0},	/* 294 */
  1277 	{"openat",	NULL,		NOSYS_NULL,	0},	/* 295 */
  1278 	{"mkdirat",	NULL,		NOSYS_NULL,	0},	/* 296 */
  1279 	{"mknodat",	NULL,		NOSYS_NULL,	0},	/* 297 */
  1280 	{"fchownat",	NULL,		NOSYS_NULL,	0},	/* 298 */
  1281 	{"futimesat",	NULL,		NOSYS_NULL,	0},	/* 299 */
  1282 	{"fstatat64",	NULL,		NOSYS_NULL,	0},	/* 300 */
  1283 	{"unlinkat",	NULL,		NOSYS_NULL,	0},	/* 301 */
  1284 	{"renameat",	NULL,		NOSYS_NULL,	0},	/* 302 */
  1285 	{"linkat",	NULL,		NOSYS_NULL,	0},	/* 303 */
  1286 	{"symlinkat",	NULL,		NOSYS_NULL,	0},	/* 304 */
  1287 	{"readlinkat",	NULL,		NOSYS_NULL,	0},	/* 305 */
  1288 	{"fchmodat",	NULL,		NOSYS_NULL,	0},	/* 306 */
  1289 	{"faccessat",	NULL,		NOSYS_NULL,	0},	/* 307 */
  1290 	{"pselect6",	NULL,		NOSYS_NULL,	0},	/* 308 */
  1291 	{"ppoll",	NULL,		NOSYS_NULL,	0},	/* 309 */
  1292 	{"unshare",	NULL,		NOSYS_NULL,	0},	/* 310 */
  1293 	{"set_robust_list", NULL,	NOSYS_NULL,	0},	/* 311 */
  1294 	{"get_robust_list", NULL,	NOSYS_NULL,	0},	/* 312 */
  1295 	{"splice",	NULL,		NOSYS_NULL,	0},	/* 313 */
  1296 	{"sync_file_range", NULL,	NOSYS_NULL,	0},	/* 314 */
  1297 	{"tee",		NULL,		NOSYS_NULL,	0},	/* 315 */
  1298 	{"vmsplice",	NULL,		NOSYS_NULL,	0},	/* 316 */
  1299 	{"move_pages",	NULL,		NOSYS_NULL,	0},	/* 317 */
  1300 };