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