summaryrefslogtreecommitdiff
path: root/usr/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/common')
-rw-r--r--usr/src/common/brand/lx/lx_auxv.c96
-rw-r--r--usr/src/common/brand/lx/lx_auxv.h32
-rw-r--r--usr/src/common/brand/lx/lx_errno.c206
-rw-r--r--usr/src/common/brand/lx/lx_errno.h29
-rw-r--r--usr/src/common/brand/lx/lx_signum.c339
-rw-r--r--usr/src/common/brand/lx/lx_signum.h114
-rw-r--r--usr/src/common/brand/lx/lx_syscall.h123
-rw-r--r--usr/src/common/brand/lx/tools/Makefile47
-rw-r--r--usr/src/common/brand/lx/tools/README.md39
-rw-r--r--usr/src/common/brand/lx/tools/gen_errno.c444
-rw-r--r--usr/src/common/crypto/chacha/chacha.c24
-rw-r--r--usr/src/common/crypto/chacha/chacha.h6
-rw-r--r--usr/src/common/net/dhcp/octet.c3
-rw-r--r--usr/src/common/pnglite/pnglite.c1
-rw-r--r--usr/src/common/refhash/refhash.c231
-rw-r--r--usr/src/common/zfs/zfs_prop.c17
-rw-r--r--usr/src/common/zfs/zfs_prop.h2
17 files changed, 1744 insertions, 9 deletions
diff --git a/usr/src/common/brand/lx/lx_auxv.c b/usr/src/common/brand/lx/lx_auxv.c
new file mode 100644
index 0000000000..2ed5fd0517
--- /dev/null
+++ b/usr/src/common/brand/lx/lx_auxv.c
@@ -0,0 +1,96 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2016 Joyent, Inc.
+ */
+
+#include <sys/auxv.h>
+#include <sys/lx_brand.h>
+
+/*
+ * Linux does not make the distinction between 'int' and 'long' when it comes
+ * to the format of the aux vector. In order to properly clear the struct
+ * padding present in the native auxv_t in 64-bit, we employ the Linux format.
+ */
+struct lx_auxv {
+ long la_type;
+ long la_val;
+};
+
+int
+lx_auxv_stol(const auxv_t *ap, auxv_t *oap, const lx_elf_data_t *edp)
+{
+ struct lx_auxv *loap = (struct lx_auxv *)oap;
+
+ switch (ap->a_type) {
+ case AT_BASE:
+ loap->la_val = edp->ed_base;
+ break;
+ case AT_ENTRY:
+ loap->la_val = edp->ed_entry;
+ break;
+ case AT_PHDR:
+ loap->la_val = edp->ed_phdr;
+ break;
+ case AT_PHENT:
+ loap->la_val = edp->ed_phent;
+ break;
+ case AT_PHNUM:
+ loap->la_val = edp->ed_phnum;
+ break;
+ case AT_SUN_BRAND_LX_SYSINFO_EHDR:
+ loap->la_type = AT_SYSINFO_EHDR;
+ loap->la_val = ap->a_un.a_val;
+ return (0);
+ case AT_SUN_BRAND_LX_CLKTCK:
+ loap->la_type = AT_CLKTCK;
+ loap->la_val = ap->a_un.a_val;
+ return (0);
+ case AT_SUN_AUXFLAGS:
+ if ((ap->a_un.a_val & AF_SUN_SETUGID) != 0) {
+ loap->la_type = AT_SECURE;
+ loap->la_val = 1;
+ return (0);
+ } else {
+ return (1);
+ }
+ case AT_SUN_GID:
+ loap->la_type = AT_LX_EGID;
+ loap->la_val = ap->a_un.a_val;
+ return (0);
+ case AT_SUN_RGID:
+ loap->la_type = AT_LX_GID;
+ loap->la_val = ap->a_un.a_val;
+ return (0);
+ case AT_SUN_UID:
+ loap->la_type = AT_LX_EUID;
+ loap->la_val = ap->a_un.a_val;
+ return (0);
+ case AT_SUN_RUID:
+ loap->la_type = AT_LX_UID;
+ loap->la_val = ap->a_un.a_val;
+ return (0);
+ case AT_EXECFD:
+ case AT_PAGESZ:
+ case AT_FLAGS:
+ case AT_RANDOM:
+ case AT_NULL:
+ /* No translate needed */
+ loap->la_val = ap->a_un.a_val;
+ break;
+ default:
+ /* All other unrecognized entries are ignored */
+ return (1);
+ }
+ loap->la_type = ap->a_type;
+ return (0);
+}
diff --git a/usr/src/common/brand/lx/lx_auxv.h b/usr/src/common/brand/lx/lx_auxv.h
new file mode 100644
index 0000000000..190d939f35
--- /dev/null
+++ b/usr/src/common/brand/lx/lx_auxv.h
@@ -0,0 +1,32 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2015 Joyent, Inc.
+ */
+
+#ifndef _LX_AUXV_H
+#define _LX_AUXV_H
+
+#include <sys/auxv.h>
+#include <sys/lx_brand.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int lx_auxv_stol(const auxv_t *, auxv_t *, const lx_elf_data_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LX_AUXV_H */
diff --git a/usr/src/common/brand/lx/lx_errno.c b/usr/src/common/brand/lx/lx_errno.c
new file mode 100644
index 0000000000..269ed470dc
--- /dev/null
+++ b/usr/src/common/brand/lx/lx_errno.c
@@ -0,0 +1,206 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2015 Joyent, Inc.
+ */
+
+/*
+ * This file contains a mapping table and lookup function for converting
+ * illumos native error numbers into error numbers appropriate for Linux
+ * emulation.
+ *
+ * The translation table is generated by the "gen_errno", built from and
+ * documented in "usr/src/common/brand/lx/tools".
+ */
+
+#include <sys/debug.h>
+
+const int
+lx_stol_errno[] = {
+ 0, /* 0: No Error */
+ 1, /* 1: EPERM --> 1: EPERM */
+ 2, /* 2: ENOENT --> 2: ENOENT */
+ 3, /* 3: ESRCH --> 3: ESRCH */
+ 4, /* 4: EINTR --> 4: EINTR */
+ 5, /* 5: EIO --> 5: EIO */
+ 6, /* 6: ENXIO --> 6: ENXIO */
+ 7, /* 7: E2BIG --> 7: E2BIG */
+ 8, /* 8: ENOEXEC --> 8: ENOEXEC */
+ 9, /* 9: EBADF --> 9: EBADF */
+ 10, /* 10: ECHILD --> 10: ECHILD */
+ 11, /* 11: EAGAIN --> 11: EAGAIN */
+ 12, /* 12: ENOMEM --> 12: ENOMEM */
+ 13, /* 13: EACCES --> 13: EACCES */
+ 14, /* 14: EFAULT --> 14: EFAULT */
+ 15, /* 15: ENOTBLK --> 15: ENOTBLK */
+ 16, /* 16: EBUSY --> 16: EBUSY */
+ 17, /* 17: EEXIST --> 17: EEXIST */
+ 18, /* 18: EXDEV --> 18: EXDEV */
+ 19, /* 19: ENODEV --> 19: ENODEV */
+ 20, /* 20: ENOTDIR --> 20: ENOTDIR */
+ 21, /* 21: EISDIR --> 21: EISDIR */
+ 22, /* 22: EINVAL --> 22: EINVAL */
+ 23, /* 23: ENFILE --> 23: ENFILE */
+ 24, /* 24: EMFILE --> 24: EMFILE */
+ 25, /* 25: ENOTTY --> 25: ENOTTY */
+ 26, /* 26: ETXTBSY --> 26: ETXTBSY */
+ 27, /* 27: EFBIG --> 27: EFBIG */
+ 28, /* 28: ENOSPC --> 28: ENOSPC */
+ 29, /* 29: ESPIPE --> 29: ESPIPE */
+ 30, /* 30: EROFS --> 30: EROFS */
+ 31, /* 31: EMLINK --> 31: EMLINK */
+ 32, /* 32: EPIPE --> 32: EPIPE */
+ 33, /* 33: EDOM --> 33: EDOM */
+ 34, /* 34: ERANGE --> 34: ERANGE */
+ 42, /* 35: ENOMSG --> 42: ENOMSG */
+ 43, /* 36: EIDRM --> 43: EIDRM */
+ 44, /* 37: ECHRNG --> 44: ECHRNG */
+ 45, /* 38: EL2NSYNC --> 45: EL2NSYNC */
+ 46, /* 39: EL3HLT --> 46: EL3HLT */
+ 47, /* 40: EL3RST --> 47: EL3RST */
+ 48, /* 41: ELNRNG --> 48: ELNRNG */
+ 49, /* 42: EUNATCH --> 49: EUNATCH */
+ 50, /* 43: ENOCSI --> 50: ENOCSI */
+ 51, /* 44: EL2HLT --> 51: EL2HLT */
+ 35, /* 45: EDEADLK --> 35: EDEADLK */
+ 37, /* 46: ENOLCK --> 37: ENOLCK */
+ 125, /* 47: ECANCELED --> 125: ECANCELED */
+ 38, /* 48: ENOTSUP --> 38: ENOSYS */
+ 122, /* 49: EDQUOT --> 122: EDQUOT */
+ 52, /* 50: EBADE --> 52: EBADE */
+ 53, /* 51: EBADR --> 53: EBADR */
+ 54, /* 52: EXFULL --> 54: EXFULL */
+ 55, /* 53: ENOANO --> 55: ENOANO */
+ 56, /* 54: EBADRQC --> 56: EBADRQC */
+ 57, /* 55: EBADSLT --> 57: EBADSLT */
+ 35, /* 56: EDEADLOCK --> 35: EDEADLK */
+ 59, /* 57: EBFONT --> 59: EBFONT */
+ 130, /* 58: EOWNERDEAD --> 130: EOWNERDEAD */
+ 131, /* 59: ENOTRECOVERABLE --> 131: ENOTRECOVERABLE */
+ 60, /* 60: ENOSTR --> 60: ENOSTR */
+ 61, /* 61: ENODATA --> 61: ENODATA */
+ 62, /* 62: ETIME --> 62: ETIME */
+ 63, /* 63: ENOSR --> 63: ENOSR */
+ 64, /* 64: ENONET --> 64: ENONET */
+ 65, /* 65: ENOPKG --> 65: ENOPKG */
+ 66, /* 66: EREMOTE --> 66: EREMOTE */
+ 67, /* 67: ENOLINK --> 67: ENOLINK */
+ 68, /* 68: EADV --> 68: EADV */
+ 69, /* 69: ESRMNT --> 69: ESRMNT */
+ 70, /* 70: ECOMM --> 70: ECOMM */
+ 71, /* 71: EPROTO --> 71: EPROTO */
+ -2, /* 72: ELOCKUNMAPPED --> -2: No Analogue */
+ -2, /* 73: ENOTACTIVE --> -2: No Analogue */
+ 72, /* 74: EMULTIHOP --> 72: EMULTIHOP */
+ -1, /* 75: Unused Number */
+ -1, /* 76: Unused Number */
+ 74, /* 77: EBADMSG --> 74: EBADMSG */
+ 36, /* 78: ENAMETOOLONG --> 36: ENAMETOOLONG */
+ 75, /* 79: EOVERFLOW --> 75: EOVERFLOW */
+ 76, /* 80: ENOTUNIQ --> 76: ENOTUNIQ */
+ 77, /* 81: EBADFD --> 77: EBADFD */
+ 78, /* 82: EREMCHG --> 78: EREMCHG */
+ 79, /* 83: ELIBACC --> 79: ELIBACC */
+ 80, /* 84: ELIBBAD --> 80: ELIBBAD */
+ 81, /* 85: ELIBSCN --> 81: ELIBSCN */
+ 82, /* 86: ELIBMAX --> 82: ELIBMAX */
+ 83, /* 87: ELIBEXEC --> 83: ELIBEXEC */
+ 84, /* 88: EILSEQ --> 84: EILSEQ */
+ 38, /* 89: ENOSYS --> 38: ENOSYS */
+ 40, /* 90: ELOOP --> 40: ELOOP */
+ 85, /* 91: ERESTART --> 85: ERESTART */
+ 86, /* 92: ESTRPIPE --> 86: ESTRPIPE */
+ 39, /* 93: ENOTEMPTY --> 39: ENOTEMPTY */
+ 87, /* 94: EUSERS --> 87: EUSERS */
+ 88, /* 95: ENOTSOCK --> 88: ENOTSOCK */
+ 89, /* 96: EDESTADDRREQ --> 89: EDESTADDRREQ */
+ 90, /* 97: EMSGSIZE --> 90: EMSGSIZE */
+ 91, /* 98: EPROTOTYPE --> 91: EPROTOTYPE */
+ 92, /* 99: ENOPROTOOPT --> 92: ENOPROTOOPT */
+ -1, /* 100: Unused Number */
+ -1, /* 101: Unused Number */
+ -1, /* 102: Unused Number */
+ -1, /* 103: Unused Number */
+ -1, /* 104: Unused Number */
+ -1, /* 105: Unused Number */
+ -1, /* 106: Unused Number */
+ -1, /* 107: Unused Number */
+ -1, /* 108: Unused Number */
+ -1, /* 109: Unused Number */
+ -1, /* 110: Unused Number */
+ -1, /* 111: Unused Number */
+ -1, /* 112: Unused Number */
+ -1, /* 113: Unused Number */
+ -1, /* 114: Unused Number */
+ -1, /* 115: Unused Number */
+ -1, /* 116: Unused Number */
+ -1, /* 117: Unused Number */
+ -1, /* 118: Unused Number */
+ -1, /* 119: Unused Number */
+ 93, /* 120: EPROTONOSUPPORT --> 93: EPROTONOSUPPORT */
+ 94, /* 121: ESOCKTNOSUPPORT --> 94: ESOCKTNOSUPPORT */
+ 95, /* 122: EOPNOTSUPP --> 95: EOPNOTSUPP */
+ 96, /* 123: EPFNOSUPPORT --> 96: EPFNOSUPPORT */
+ 97, /* 124: EAFNOSUPPORT --> 97: EAFNOSUPPORT */
+ 98, /* 125: EADDRINUSE --> 98: EADDRINUSE */
+ 99, /* 126: EADDRNOTAVAIL --> 99: EADDRNOTAVAIL */
+ 100, /* 127: ENETDOWN --> 100: ENETDOWN */
+ 101, /* 128: ENETUNREACH --> 101: ENETUNREACH */
+ 102, /* 129: ENETRESET --> 102: ENETRESET */
+ 103, /* 130: ECONNABORTED --> 103: ECONNABORTED */
+ 104, /* 131: ECONNRESET --> 104: ECONNRESET */
+ 105, /* 132: ENOBUFS --> 105: ENOBUFS */
+ 106, /* 133: EISCONN --> 106: EISCONN */
+ 107, /* 134: ENOTCONN --> 107: ENOTCONN */
+ -1, /* 135: Unused Number */
+ -1, /* 136: Unused Number */
+ -1, /* 137: Unused Number */
+ -1, /* 138: Unused Number */
+ -1, /* 139: Unused Number */
+ -1, /* 140: Unused Number */
+ -1, /* 141: Unused Number */
+ -1, /* 142: Unused Number */
+ 108, /* 143: ESHUTDOWN --> 108: ESHUTDOWN */
+ 109, /* 144: ETOOMANYREFS --> 109: ETOOMANYREFS */
+ 110, /* 145: ETIMEDOUT --> 110: ETIMEDOUT */
+ 111, /* 146: ECONNREFUSED --> 111: ECONNREFUSED */
+ 112, /* 147: EHOSTDOWN --> 112: EHOSTDOWN */
+ 113, /* 148: EHOSTUNREACH --> 113: EHOSTUNREACH */
+ 114, /* 149: EALREADY --> 114: EALREADY */
+ 115, /* 150: EINPROGRESS --> 115: EINPROGRESS */
+ 116 /* 151: ESTALE --> 116: ESTALE */
+};
+
+/*
+ * Convert an illumos native error number to a Linux error number and return
+ * it. If no valid conversion is possible, the function fails back to the
+ * value of "defval". In userland, passing a default error number of "-1"
+ * will abort the program if the error number could not be converted.
+ */
+int
+lx_errno(int native_errno, int defval)
+{
+#ifdef _KERNEL
+ VERIFY3S(defval, >=, 0);
+#endif
+
+ if (native_errno < 0 || native_errno >= (sizeof (lx_stol_errno) /
+ sizeof (lx_stol_errno[0]))) {
+#ifndef _KERNEL
+ VERIFY3S(defval, >=, 0);
+#endif
+
+ return (defval);
+ }
+
+ return (lx_stol_errno[native_errno]);
+}
diff --git a/usr/src/common/brand/lx/lx_errno.h b/usr/src/common/brand/lx/lx_errno.h
new file mode 100644
index 0000000000..10b6b3066c
--- /dev/null
+++ b/usr/src/common/brand/lx/lx_errno.h
@@ -0,0 +1,29 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2015 Joyent, Inc.
+ */
+
+#ifndef _LX_ERRNO_H
+#define _LX_ERRNO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int lx_errno(int, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LX_ERRNO_H */
diff --git a/usr/src/common/brand/lx/lx_signum.c b/usr/src/common/brand/lx/lx_signum.c
new file mode 100644
index 0000000000..9c861c282a
--- /dev/null
+++ b/usr/src/common/brand/lx/lx_signum.c
@@ -0,0 +1,339 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ * Copyright 2015 Joyent, Inc.
+ */
+
+#include <sys/signal.h>
+#include <sys/lx_siginfo.h>
+#include <lx_signum.h>
+#include <sys/debug.h>
+
+/*
+ * Delivering signals to a Linux process is complicated by differences in
+ * signal numbering, stack structure and contents, and the action taken when a
+ * signal handler exits. In addition, many signal-related structures, such as
+ * sigset_ts, vary between Solaris and Linux.
+ *
+ * The simplest transformation that must be done when sending signals is to
+ * translate between Linux and Solaris signal numbers.
+ *
+ * These are the major signal number differences between Linux and Solaris:
+ *
+ * ====================================
+ * | Number | Linux | Solaris |
+ * | ====== | ========= | ========== |
+ * | 7 | SIGBUS | SIGEMT |
+ * | 10 | SIGUSR1 | SIGBUS |
+ * | 12 | SIGUSR2 | SIGSYS |
+ * | 16 | SIGSTKFLT | SIGUSR1 |
+ * | 17 | SIGCHLD | SIGUSR2 |
+ * | 18 | SIGCONT | SIGCHLD |
+ * | 19 | SIGSTOP | SIGPWR |
+ * | 20 | SIGTSTP | SIGWINCH |
+ * | 21 | SIGTTIN | SIGURG |
+ * | 22 | SIGTTOU | SIGPOLL |
+ * | 23 | SIGURG | SIGSTOP |
+ * | 24 | SIGXCPU | SIGTSTP |
+ * | 25 | SIGXFSZ | SIGCONT |
+ * | 26 | SIGVTALARM | SIGTTIN |
+ * | 27 | SIGPROF | SIGTTOU |
+ * | 28 | SIGWINCH | SIGVTALARM |
+ * | 29 | SIGPOLL | SIGPROF |
+ * | 30 | SIGPWR | SIGXCPU |
+ * | 31 | SIGSYS | SIGXFSZ |
+ * ====================================
+ *
+ * Not every Linux signal maps to a Solaris signal, nor does every Solaris
+ * signal map to a Linux counterpart. However, when signals do map, the
+ * mapping is unique.
+ *
+ * One mapping issue is that Linux supports 33 real time signals, with SIGRTMIN
+ * typically starting at or near 32 (SIGRTMIN) and proceeding to 64 (SIGRTMAX)
+ * (SIGRTMIN is "at or near" 32 because glibc usually "steals" one ore more of
+ * these signals for its own internal use, adjusting SIGRTMIN and SIGRTMAX as
+ * needed.) Conversely, Solaris actively uses signals 32-40 for other purposes
+ * and supports exactly 32 real time signals, in the range 41 (SIGRTMIN)
+ * to 72 (SIGRTMAX).
+ *
+ * At present, attempting to translate a Linux signal equal to 63
+ * will generate an error (we allow SIGRTMAX because a program
+ * should be able to send SIGRTMAX without getting an EINVAL, though obviously
+ * anything that loops through the signals from SIGRTMIN to SIGRTMAX will
+ * fail.)
+ *
+ * Similarly, attempting to translate a native Solaris signal in the range
+ * 32-40 will also generate an error as we don't want to support the receipt of
+ * those signals from the Solaris global zone.
+ */
+
+/*
+ * Linux to Solaris signal map
+ *
+ * Usage: solaris_signal = ltos_signum[lx_signal];
+ */
+const int
+ltos_signo[LX_NSIG + 1] = {
+ 0,
+ SIGHUP,
+ SIGINT,
+ SIGQUIT,
+ SIGILL,
+ SIGTRAP,
+ SIGABRT,
+ SIGBUS,
+ SIGFPE,
+ SIGKILL,
+ SIGUSR1,
+ SIGSEGV,
+ SIGUSR2,
+ SIGPIPE,
+ SIGALRM,
+ SIGTERM,
+ SIGEMT, /* 16: Linux SIGSTKFLT; use Solaris SIGEMT */
+ SIGCHLD,
+ SIGCONT,
+ SIGSTOP,
+ SIGTSTP,
+ SIGTTIN,
+ SIGTTOU,
+ SIGURG,
+ SIGXCPU,
+ SIGXFSZ,
+ SIGVTALRM,
+ SIGPROF,
+ SIGWINCH,
+ SIGPOLL,
+ SIGPWR,
+ SIGSYS,
+ _SIGRTMIN, /* 32: Linux SIGRTMIN */
+ _SIGRTMIN + 1,
+ _SIGRTMIN + 2,
+ _SIGRTMIN + 3,
+ _SIGRTMIN + 4,
+ _SIGRTMIN + 5,
+ _SIGRTMIN + 6,
+ _SIGRTMIN + 7,
+ _SIGRTMIN + 8,
+ _SIGRTMIN + 9,
+ _SIGRTMIN + 10,
+ _SIGRTMIN + 11,
+ _SIGRTMIN + 12,
+ _SIGRTMIN + 13,
+ _SIGRTMIN + 14,
+ _SIGRTMIN + 15,
+ _SIGRTMIN + 16,
+ _SIGRTMIN + 17,
+ _SIGRTMIN + 18,
+ _SIGRTMIN + 19,
+ _SIGRTMIN + 20,
+ _SIGRTMIN + 21,
+ _SIGRTMIN + 22,
+ _SIGRTMIN + 23,
+ _SIGRTMIN + 24,
+ _SIGRTMIN + 25,
+ _SIGRTMIN + 26,
+ _SIGRTMIN + 27,
+ _SIGRTMIN + 28,
+ _SIGRTMIN + 29,
+ _SIGRTMIN + 30,
+ _SIGRTMIN + 31,
+ _SIGRTMAX, /* 64: Linux SIGRTMAX */
+};
+
+/*
+ * Solaris to Linux signal map
+ *
+ * Usage: lx_signal = stol_signo[solaris_signal];
+ */
+const int
+stol_signo[NSIG] = {
+ 0,
+ LX_SIGHUP,
+ LX_SIGINT,
+ LX_SIGQUIT,
+ LX_SIGILL,
+ LX_SIGTRAP,
+ LX_SIGABRT,
+ LX_SIGSTKFLT, /* 7: Solaris SIGEMT; use for LX_SIGSTKFLT */
+ LX_SIGFPE,
+ LX_SIGKILL,
+ LX_SIGBUS,
+ LX_SIGSEGV,
+ LX_SIGSYS,
+ LX_SIGPIPE,
+ LX_SIGALRM,
+ LX_SIGTERM,
+ LX_SIGUSR1,
+ LX_SIGUSR2,
+ LX_SIGCHLD,
+ LX_SIGPWR,
+ LX_SIGWINCH,
+ LX_SIGURG,
+ LX_SIGPOLL,
+ LX_SIGSTOP,
+ LX_SIGTSTP,
+ LX_SIGCONT,
+ LX_SIGTTIN,
+ LX_SIGTTOU,
+ LX_SIGVTALRM,
+ LX_SIGPROF,
+ LX_SIGXCPU,
+ LX_SIGXFSZ,
+ -1, /* 32: Solaris SIGWAITING */
+ -1, /* 33: Solaris SIGLWP */
+ -1, /* 34: Solaris SIGFREEZE */
+ -1, /* 35: Solaris SIGTHAW */
+ -1, /* 36: Solaris SIGCANCEL */
+ -1, /* 37: Solaris SIGLOST */
+ -1, /* 38: Solaris SIGXRES */
+ -1, /* 39: Solaris SIGJVM1 */
+ -1, /* 40: Solaris SIGJVM2 */
+ -1, /* 41: Solaris SIGINFO */
+ LX_SIGRTMIN, /* 42: Solaris _SIGRTMIN */
+ LX_SIGRTMIN + 1,
+ LX_SIGRTMIN + 2,
+ LX_SIGRTMIN + 3,
+ LX_SIGRTMIN + 4,
+ LX_SIGRTMIN + 5,
+ LX_SIGRTMIN + 6,
+ LX_SIGRTMIN + 7,
+ LX_SIGRTMIN + 8,
+ LX_SIGRTMIN + 9,
+ LX_SIGRTMIN + 10,
+ LX_SIGRTMIN + 11,
+ LX_SIGRTMIN + 12,
+ LX_SIGRTMIN + 13,
+ LX_SIGRTMIN + 14,
+ LX_SIGRTMIN + 15,
+ LX_SIGRTMIN + 16,
+ LX_SIGRTMIN + 17,
+ LX_SIGRTMIN + 18,
+ LX_SIGRTMIN + 19,
+ LX_SIGRTMIN + 20,
+ LX_SIGRTMIN + 21,
+ LX_SIGRTMIN + 22,
+ LX_SIGRTMIN + 23,
+ LX_SIGRTMIN + 24,
+ LX_SIGRTMIN + 25,
+ LX_SIGRTMIN + 26,
+ LX_SIGRTMIN + 27,
+ LX_SIGRTMIN + 28,
+ LX_SIGRTMIN + 29,
+ LX_SIGRTMIN + 30,
+ LX_SIGRTMIN + 31,
+ LX_SIGRTMAX, /* 74: Solaris _SIGRTMAX */
+};
+
+/*
+ * Convert an illumos native signal number to a Linux signal number and return
+ * it. If no valid conversion is possible, the function fails back to the
+ * value of "defsig". In userland, passing a default signal number of "-1"
+ * will abort the program if the signal number could not be converted.
+ */
+int
+lx_stol_signo(int signo, int defsig)
+{
+ int rval;
+
+#ifdef _KERNEL
+ VERIFY3S(defsig, >=, 0);
+#endif
+
+ if (signo < 0 || signo >= NSIG || (rval = stol_signo[signo]) < 1) {
+#ifndef _KERNEL
+ VERIFY3S(defsig, >=, 0);
+#endif
+ return (defsig);
+ }
+
+ return (rval);
+}
+
+
+/*
+ * Convert a Linux signal number to an illumos signal number and return it.
+ * Error behavior is identical to lx_stol_signo.
+ */
+int
+lx_ltos_signo(int signo, int defsig)
+{
+#ifdef _KERNEL
+ VERIFY3S(defsig, >=, 0);
+#endif
+
+ if (signo < 1 || signo >= NSIG) {
+#ifndef _KERNEL
+ VERIFY3S(defsig, >=, 0);
+#endif
+ return (defsig);
+ }
+
+ return (ltos_signo[signo]);
+}
+
+/*
+ * Convert the "status" field of a SIGCLD siginfo_t. We need to extract the
+ * illumos signal number and convert it to a Linux signal number while leaving
+ * the ptrace(2) event bits intact. In userland, passing a default signal
+ * number of "-1" will abort the program if the signal number could not be
+ * converted, as for lx_stol_signo().
+ */
+int
+lx_stol_status(int s, int defsig)
+{
+ /*
+ * We mask out the top bit here in case PTRACE_O_TRACESYSGOOD
+ * is in use and 0x80 has been ORed with the signal number.
+ */
+ int stat = lx_stol_signo(s & 0x7f, defsig);
+
+ /*
+ * We must mix in the ptrace(2) event which may be stored in
+ * the second byte of the status code. We also re-include the
+ * PTRACE_O_TRACESYSGOOD bit.
+ */
+ return ((s & 0xff80) | stat);
+}
+
+int
+lx_stol_sigcode(int code)
+{
+ switch (code) {
+ case SI_USER:
+ return (LX_SI_USER);
+ case SI_LWP:
+ return (LX_SI_TKILL);
+ case SI_QUEUE:
+ return (LX_SI_QUEUE);
+ case SI_TIMER:
+ return (LX_SI_TIMER);
+ case SI_ASYNCIO:
+ return (LX_SI_ASYNCIO);
+ case SI_MESGQ:
+ return (LX_SI_MESGQ);
+ default:
+ return (code);
+ }
+}
diff --git a/usr/src/common/brand/lx/lx_signum.h b/usr/src/common/brand/lx/lx_signum.h
new file mode 100644
index 0000000000..b6c5f32731
--- /dev/null
+++ b/usr/src/common/brand/lx/lx_signum.h
@@ -0,0 +1,114 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ * Copyright 2015 Joyent, Inc.
+ */
+
+#ifndef _LX_SIGNUM_H
+#define _LX_SIGNUM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LX_SIGHUP 1
+#define LX_SIGINT 2
+#define LX_SIGQUIT 3
+#define LX_SIGILL 4
+#define LX_SIGTRAP 5
+#define LX_SIGABRT 6
+#define LX_SIGIOT 6
+#define LX_SIGBUS 7
+#define LX_SIGFPE 8
+#define LX_SIGKILL 9
+#define LX_SIGUSR1 10
+#define LX_SIGSEGV 11
+#define LX_SIGUSR2 12
+#define LX_SIGPIPE 13
+#define LX_SIGALRM 14
+#define LX_SIGTERM 15
+#define LX_SIGSTKFLT 16
+#define LX_SIGCHLD 17
+#define LX_SIGCONT 18
+#define LX_SIGSTOP 19
+#define LX_SIGTSTP 20
+#define LX_SIGTTIN 21
+#define LX_SIGTTOU 22
+#define LX_SIGURG 23
+#define LX_SIGXCPU 24
+#define LX_SIGXFSZ 25
+#define LX_SIGVTALRM 26
+#define LX_SIGPROF 27
+#define LX_SIGWINCH 28
+#define LX_SIGIO 29
+#define LX_SIGPOLL LX_SIGIO
+#define LX_SIGPWR 30
+#define LX_SIGSYS 31
+#define LX_SIGUNUSED 31
+
+#define LX_NSIG 64 /* Linux _NSIG */
+
+#define LX_SIGRTMIN 32
+#define LX_SIGRTMAX LX_NSIG
+
+extern const int ltos_signo[];
+extern const int stol_signo[];
+
+extern int lx_stol_signo(int, int);
+extern int lx_ltos_signo(int, int);
+extern int lx_stol_status(int, int);
+extern int lx_stol_sigcode(int);
+
+/*
+ * NOTE: Linux uses different definitions for 'sigset_t's and 'sigaction_t's
+ * depending on whether the definition is for user space or the kernel.
+ *
+ * The definitions below MUST correspond to the Linux kernel versions,
+ * as glibc will do the necessary translation from the Linux user
+ * versions.
+ */
+#if defined(_LP64)
+#define LX_NSIG_WORDS 1
+#define LX_WSHIFT 6
+#elif defined(_ILP32)
+#define LX_NSIG_WORDS 2
+#define LX_WSHIFT 5
+#else
+#error "LX only supports LP64 and ILP32"
+#endif
+
+typedef struct {
+ ulong_t __bits[LX_NSIG_WORDS];
+} lx_sigset_t;
+
+#define LX_NBITS (sizeof (ulong_t) * NBBY)
+#define lx_sigmask(n) (1UL << (((n) - 1) % LX_NBITS))
+#define lx_sigword(n) (((ulong_t)((n) - 1)) >> LX_WSHIFT)
+#define lx_sigismember(s, n) (lx_sigmask(n) & (s)->__bits[lx_sigword(n)])
+#define lx_sigaddset(s, n) ((s)->__bits[lx_sigword(n)] |= lx_sigmask(n))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LX_SIGNUM_H */
diff --git a/usr/src/common/brand/lx/lx_syscall.h b/usr/src/common/brand/lx/lx_syscall.h
new file mode 100644
index 0000000000..01e8b79512
--- /dev/null
+++ b/usr/src/common/brand/lx/lx_syscall.h
@@ -0,0 +1,123 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2015 Joyent, Inc.
+ */
+
+#ifndef _LX_SYSCALL_H
+#define _LX_SYSCALL_H
+
+#include <sys/lx_brand.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The br_scall_args field of lx_lwp_data is going to be populated with
+ * pointers to structs. The types of these structs should be defined in this
+ * header file. These are Linux specific arguments to system calls that don't
+ * exist in illumos. Each section should be labelled with which system call it
+ * belongs to.
+ */
+
+/* arguments for waitpid(2) */
+/* see comments in usr/src/lib/brand/lx/lx_brand/common/wait.c */
+#define LX_WNOTHREAD 0x20000000 /* Do not wait on siblings' children */
+#define LX_WALL 0x40000000 /* Wait on all children */
+#define LX_WCLONE 0x80000000 /* Wait only on clone children */
+
+/* For arch_prctl(2) */
+#define LX_ARCH_SET_GS 0x1001
+#define LX_ARCH_SET_FS 0x1002
+#define LX_ARCH_GET_FS 0x1003
+#define LX_ARCH_GET_GS 0x1004
+
+/*
+ * For ptrace(2):
+ */
+#define LX_PTRACE_TRACEME 0
+#define LX_PTRACE_PEEKTEXT 1
+#define LX_PTRACE_PEEKDATA 2
+#define LX_PTRACE_PEEKUSER 3
+#define LX_PTRACE_POKETEXT 4
+#define LX_PTRACE_POKEDATA 5
+#define LX_PTRACE_POKEUSER 6
+#define LX_PTRACE_CONT 7
+#define LX_PTRACE_KILL 8
+#define LX_PTRACE_SINGLESTEP 9
+#define LX_PTRACE_GETREGS 12
+#define LX_PTRACE_SETREGS 13
+#define LX_PTRACE_GETFPREGS 14
+#define LX_PTRACE_SETFPREGS 15
+#define LX_PTRACE_ATTACH 16
+#define LX_PTRACE_DETACH 17
+#define LX_PTRACE_GETFPXREGS 18
+#define LX_PTRACE_SETFPXREGS 19
+#define LX_PTRACE_SYSCALL 24
+#define LX_PTRACE_SETOPTIONS 0x4200
+#define LX_PTRACE_GETEVENTMSG 0x4201
+#define LX_PTRACE_GETSIGINFO 0x4202
+
+/*
+ * For clone(2):
+ */
+#define LX_CSIGNAL 0x000000ff
+#define LX_CLONE_VM 0x00000100
+#define LX_CLONE_FS 0x00000200
+#define LX_CLONE_FILES 0x00000400
+#define LX_CLONE_SIGHAND 0x00000800
+#define LX_CLONE_PID 0x00001000
+#define LX_CLONE_PTRACE 0x00002000
+#define LX_CLONE_VFORK 0x00004000
+#define LX_CLONE_PARENT 0x00008000
+#define LX_CLONE_THREAD 0x00010000
+#define LX_CLONE_NEWNS 0x00020000
+#define LX_CLONE_SYSVSEM 0x00040000
+#define LX_CLONE_SETTLS 0x00080000
+#define LX_CLONE_PARENT_SETTID 0x00100000
+#define LX_CLONE_CHILD_CLEARTID 0x00200000
+#define LX_CLONE_DETACH 0x00400000
+#define LX_CLONE_UNTRACED 0x00800000
+#define LX_CLONE_CHILD_SETTID 0x01000000
+#define LX_CLONE_NEWCGROUP 0x02000000
+#define LX_CLONE_NEWUTS 0x04000000
+#define LX_CLONE_NEWIPC 0x08000000
+#define LX_CLONE_NEWUSER 0x10000000
+#define LX_CLONE_NEWPID 0x20000000
+#define LX_CLONE_NEWNET 0x40000000
+#define LX_CLONE_IO 0x80000000
+
+#define SHARED_AS \
+ (LX_CLONE_VM | LX_CLONE_FS | LX_CLONE_FILES | LX_CLONE_SIGHAND | \
+ LX_CLONE_THREAD)
+
+/*
+ * Valid clone flags when not a full process or full thread (SHARED_AS), This
+ * can be expanded as additional clone-group support is added.
+ */
+#define LX_CLONE_GRP_SUBSET (LX_CLONE_FS)
+
+#define LX_IS_CLONE_GRP(X) ((X & SHARED_AS) != 0 && \
+ (X & SHARED_AS) != SHARED_AS && \
+ ((X & SHARED_AS) & ~LX_CLONE_GRP_SUBSET) == 0)
+
+#define LX_CLONE_NS_UNSUP (LX_CLONE_NEWNS | LX_CLONE_NEWCGROUP | \
+ LX_CLONE_NEWUTS | LX_CLONE_NEWIPC | \
+ LX_CLONE_NEWUSER | LX_CLONE_NEWPID | \
+ LX_CLONE_NEWNET | LX_CLONE_IO)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LX_SYSCALL_H */
diff --git a/usr/src/common/brand/lx/tools/Makefile b/usr/src/common/brand/lx/tools/Makefile
new file mode 100644
index 0000000000..2b5bb92251
--- /dev/null
+++ b/usr/src/common/brand/lx/tools/Makefile
@@ -0,0 +1,47 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2018 Joyent, Inc.
+#
+
+PROG = gen_errno
+
+include ../../../../cmd/Makefile.cmd
+
+OBJS = gen_errno.o
+
+CLOBBERFILES += $(PROG)
+
+NATIVECC_CFLAGS += $(CFLAGS) $(CCVERBOSE)
+# As evidenced by the use of the NATIVE_ variables, gen_errno is intended
+# to be able to run on the build host. We continue to link it against
+# libcmdutils.so instead of libcustr.so in order to allow it to run on
+# older build hosts (relying on the libcmdutil filter entries if run on
+# newer hosts with libcustr.so).
+NATIVECC_LDLIBS += -lcmdutils -lnvpair
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all
+
+lint: lint_PROG
+
+clean:
+ $(RM) $(OBJS)
+
+$(PROG): $(OBJS)
+ $(NATIVECC) $(NATIVECC_CFLAGS) $(NATIVECC_LDLIBS) $(OBJS) -o $@
+ $(POST_PROCESS)
+
+include ../../../../cmd/Makefile.targ
diff --git a/usr/src/common/brand/lx/tools/README.md b/usr/src/common/brand/lx/tools/README.md
new file mode 100644
index 0000000000..5e4976f200
--- /dev/null
+++ b/usr/src/common/brand/lx/tools/README.md
@@ -0,0 +1,39 @@
+# Updating Error Number Translations
+
+To create an updated error number translation table, you can use the
+`gen_errno` tool. This tool requires, as input:
+
+* the illumos native `errno.h` file
+* a set of foreign operating system `errno.h` files
+
+The output is a set of translation table entries suitable for inclusion in a
+cstyled C array. The index of the array is the native error number and the
+value at each index is the translated error number for use with the foreign
+operating system.
+
+## Example
+
+To generate a translation table for the LX Brand, you will require two files
+from the current Linux source:
+
+* `include/uapi/asm-generic/errno-base.h` (low-valued, or base, error numbers)
+* `include/uapi/asm-generic/errno.h` (extended error numbers)
+
+Assuming the files are in the current directory, you should run the tool as
+follows:
+
+ $ dmake
+ ...
+ $ ./gen_errno -F errno-base.h -F errno.h \
+ -N $SRC/uts/common/sys/errno.h
+ 0, /* 0: No Error */
+ 1, /* 1: EPERM --> 1: EPERM */
+ 2, /* 2: ENOENT --> 2: ENOENT */
+ 3, /* 3: ESRCH --> 3: ESRCH */
+ 4, /* 4: EINTR --> 4: EINTR */
+ 5, /* 5: EIO --> 5: EIO */
+ 6, /* 6: ENXIO --> 6: ENXIO */
+ 7, /* 7: E2BIG --> 7: E2BIG */
+ ...
+
+The output may be used in the `$SRC/common/brand/lx/lx_errno.c` file.
diff --git a/usr/src/common/brand/lx/tools/gen_errno.c b/usr/src/common/brand/lx/tools/gen_errno.c
new file mode 100644
index 0000000000..6089fed3bd
--- /dev/null
+++ b/usr/src/common/brand/lx/tools/gen_errno.c
@@ -0,0 +1,444 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2018 Joyent, Inc.
+ */
+
+/*
+ * Take the error number definitions from a foreign system and generate a
+ * translation table that converts illumos native error numbers to foreign
+ * system error numbers.
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <err.h>
+#include <sys/sysmacros.h>
+#include <libcustr.h>
+#include <libnvpair.h>
+
+nvlist_t *native_errors;
+nvlist_t *foreign_errors;
+
+struct override {
+ const char *ovr_from;
+ const char *ovr_to;
+} overrides[] = {
+ { "ENOTSUP", "ENOSYS" },
+ { 0 }
+};
+
+static const char *
+lookup_override(const char *from)
+{
+ int i;
+
+ for (i = 0; overrides[i].ovr_from != NULL; i++) {
+ if (strcmp(overrides[i].ovr_from, from) == 0) {
+ return (overrides[i].ovr_to);
+ }
+ }
+
+ return (NULL);
+}
+
+static int
+parse_int(const char *number, int *rval)
+{
+ long n;
+ char *endpos;
+
+ errno = 0;
+ if ((n = strtol(number, &endpos, 10)) == 0 && errno != 0) {
+ return (-1);
+ }
+
+ if (endpos != NULL && *endpos != '\0') {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (n > INT_MAX || n < INT_MIN) {
+ errno = EOVERFLOW;
+ return (-1);
+ }
+
+ *rval = (int)n;
+ return (0);
+}
+
+static int
+errnum_add(nvlist_t *nvl, const char *name, const char *number)
+{
+ int val;
+
+ if (nvlist_exists(nvl, name)) {
+ (void) fprintf(stderr, "ERROR: duplicate definition: %s -> "
+ "%s\n", name, number);
+ errno = EEXIST;
+ return (-1);
+ }
+
+ /*
+ * Try and parse the error number:
+ */
+ if (parse_int(number, &val) == 0) {
+ /*
+ * The name refers to a number.
+ */
+ if (nvlist_add_int32(nvl, name, val) != 0) {
+ (void) fprintf(stderr, "ERROR: nvlist_add_int32: %s\n",
+ strerror(errno));
+ return (-1);
+ }
+ } else {
+ /*
+ * The name refers to another definition.
+ */
+ if (nvlist_add_string(nvl, name, number) != 0) {
+ (void) fprintf(stderr, "ERROR: nvlist_add_string: %s\n",
+ strerror(errno));
+ return (-1);
+ }
+ }
+
+ return (0);
+}
+
+static int
+errnum_max(nvlist_t *nvl)
+{
+ int max = 0;
+ nvpair_t *nvp = NULL;
+
+ while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
+ if (nvpair_type(nvp) != DATA_TYPE_INT32) {
+ continue;
+ }
+
+ max = MAX(fnvpair_value_int32(nvp), max);
+ }
+
+ return (max);
+}
+
+static int
+errname_by_num(nvlist_t *nvl, int num, const char **name)
+{
+ nvpair_t *nvp = NULL;
+
+ while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
+ if (nvpair_type(nvp) != DATA_TYPE_INT32) {
+ continue;
+ }
+
+ if (fnvpair_value_int32(nvp) == num) {
+ *name = nvpair_name(nvp);
+ return (0);
+ }
+ }
+
+ errno = ENOENT;
+ return (-1);
+}
+
+static int
+errno_by_name(nvlist_t *nvl, const char *name, int *rval, const char **rname)
+{
+ nvpair_t *nvp = NULL;
+
+ if (nvlist_lookup_nvpair(nvl, name, &nvp) != 0) {
+ errno = ENOENT;
+ return (-1);
+ }
+
+ if (nvpair_type(nvp) == DATA_TYPE_STRING) {
+ return (errno_by_name(nvl, fnvpair_value_string(nvp), rval,
+ rname));
+ } else {
+ *rval = fnvpair_value_int32(nvp);
+ if (rname != NULL) {
+ *rname = name;
+ }
+ return (0);
+ }
+}
+
+static int
+process_line(const char *line, nvlist_t *nvl)
+{
+ custr_t *nam = NULL, *num = NULL;
+ const char *c = line;
+
+ if (custr_alloc(&nam) != 0 || custr_alloc(&num) != 0) {
+ int en = errno;
+
+ custr_free(nam);
+ custr_free(num);
+
+ errno = en;
+ return (-1);
+ }
+
+ /*
+ * Valid lines begin with "#define":
+ */
+ if (*c++ != '#' || *c++ != 'd' || *c++ != 'e' || *c++ != 'f' ||
+ *c++ != 'i' || *c++ != 'n' || *c++ != 'e') {
+ return (0);
+ }
+
+ /*
+ * Eat whitespace:
+ */
+ for (;;) {
+ if (*c == '\0') {
+ return (0);
+ }
+
+ if (*c != ' ' && *c != '\t') {
+ break;
+ }
+
+ c++;
+ }
+
+ /*
+ * Read error number token:
+ */
+ for (;;) {
+ if (*c == '\0') {
+ return (0);
+ }
+
+ if (*c == ' ' || *c == '\t') {
+ break;
+ }
+
+ if (custr_appendc(nam, *c) != 0) {
+ return (-1);
+ }
+
+ c++;
+ }
+
+ /*
+ * Eat whitespace:
+ */
+ for (;;) {
+ if (*c == '\0') {
+ return (0);
+ }
+
+ if (*c != ' ' && *c != '\t') {
+ break;
+ }
+
+ c++;
+ }
+
+ /*
+ * Read error number token:
+ */
+ for (;;) {
+ if (*c == '\0') {
+ break;
+ }
+
+ if (*c == ' ' || *c == '\t') {
+ break;
+ }
+
+ if (custr_appendc(num, *c) != 0) {
+ return (-1);
+ }
+
+ c++;
+ }
+
+ return (errnum_add(nvl, custr_cstr(nam), custr_cstr(num)));
+}
+
+static int
+read_file_into_list(const char *path, nvlist_t *nvl)
+{
+ int rval = 0, en = 0;
+ FILE *f;
+ custr_t *cu = NULL;
+
+ if (custr_alloc(&cu) != 0) {
+ return (-1);
+ }
+
+ if ((f = fopen(path, "r")) == NULL) {
+ custr_free(cu);
+ return (-1);
+ }
+
+ for (;;) {
+ int c;
+
+ errno = 0;
+ switch (c = fgetc(f)) {
+ case '\n':
+ case EOF:
+ if (errno != 0) {
+ en = errno;
+ rval = -1;
+ goto out;
+ }
+ if (process_line(custr_cstr(cu), nvl) != 0) {
+ en = errno;
+ rval = -1;
+ goto out;
+ }
+ custr_reset(cu);
+ if (c == EOF) {
+ goto out;
+ }
+ break;
+
+ case '\r':
+ case '\0':
+ /*
+ * Ignore these characters.
+ */
+ break;
+
+ default:
+ if (custr_appendc(cu, c) != 0) {
+ en = errno;
+ rval = -1;
+ goto out;
+ }
+ break;
+ }
+ }
+
+out:
+ (void) fclose(f);
+ custr_free(cu);
+ errno = en;
+ return (rval);
+}
+
+int
+main(int argc, char **argv)
+{
+ int max;
+ int fval;
+ int c;
+
+ if (nvlist_alloc(&native_errors, NV_UNIQUE_NAME, 0) != 0 ||
+ nvlist_alloc(&foreign_errors, NV_UNIQUE_NAME, 0) != 0) {
+ err(1, "could not allocate memory");
+ }
+
+ while ((c = getopt(argc, argv, ":N:F:")) != -1) {
+ switch (c) {
+ case 'N':
+ if (read_file_into_list(optarg, native_errors) != 0) {
+ err(1, "could not read file: %s", optarg);
+ }
+ break;
+
+ case 'F':
+ if (read_file_into_list(optarg, foreign_errors) != 0) {
+ err(1, "could not read file: %s", optarg);
+ }
+ break;
+
+ case ':':
+ errx(1, "option -%c requires an operand", c);
+ break;
+
+ case '?':
+ errx(1, "option -%c unrecognised", c);
+ break;
+ }
+ }
+
+ /*
+ * Print an array entry for each error number:
+ */
+ max = errnum_max(native_errors);
+ for (fval = 0; fval <= max; fval++) {
+ const char *fname;
+ const char *tname = NULL;
+ int32_t tval;
+ const char *msg = NULL;
+ const char *comma = (fval != max) ? "," : "";
+
+ if (errname_by_num(native_errors, fval, &fname) == -1) {
+ fname = NULL;
+ }
+
+ if (fval == 0) {
+ /*
+ * The error number "0" is special: it means no worries.
+ */
+ msg = "No Error";
+ tval = 0;
+ } else if (fname == NULL) {
+ /*
+ * There is no defined name for this error number; it
+ * is unused.
+ */
+ msg = "Unused Number";
+ tval = -1;
+ } else {
+ /*
+ * Check if we want to override the name of this error
+ * in the foreign error number lookup:
+ */
+ const char *oname = lookup_override(fname);
+
+ /*
+ * Do the lookup:
+ */
+ if (errno_by_name(foreign_errors, oname != NULL ?
+ oname : fname, &tval, &tname) != 0) {
+ /*
+ * There was no foreign error number by that
+ * name.
+ */
+ tname = "No Analogue";
+ tval = -2;
+ }
+ }
+
+ if (msg == NULL) {
+ size_t flen = strlen(fname);
+ size_t tlen = strlen(tname);
+ const char *t = flen > 7 ? "\t" : "\t\t";
+ const char *tt = tlen < 7 ? "\t\t\t" : tlen < 15 ?
+ "\t\t" : "\t";
+
+ (void) fprintf(stdout, "\t%d%s\t/* %3d: %s%s--> %3d: "
+ "%s%s*/\n", tval, comma, fval, fname, t, tval,
+ tname, tt);
+ } else {
+ const char *t = "\t\t\t\t\t";
+
+ (void) fprintf(stdout, "\t%d%s\t/* %3d: %s%s*/\n", tval,
+ comma, fval, msg, t);
+ }
+ }
+
+ (void) nvlist_free(native_errors);
+ (void) nvlist_free(foreign_errors);
+
+ return (0);
+}
diff --git a/usr/src/common/crypto/chacha/chacha.c b/usr/src/common/crypto/chacha/chacha.c
index cef4aac466..3665ae28d4 100644
--- a/usr/src/common/crypto/chacha/chacha.c
+++ b/usr/src/common/crypto/chacha/chacha.c
@@ -1,13 +1,25 @@
/*
+ * This implementation of ChaCha20 comes from the initial Dan Bernstein
+ * implementation, including a 256-bit key, a 64-bit nonce and a 64-bit
+ * counter. This is in contrast to ChaCha20 as defined in RFC 7539, which
+ * defines a 256-bit key, a 96-bit nonce and a 32-bit counter. In particular,
+ * kernel crash dump encryption relies on the fact that our larger counter
+ * allows for the encryption of very large messages (many gigabytes in
+ * length); any change to this implementation that reduces the size of the
+ * counter should be mindful of this use case.
+ */
+
+/*
chacha-merged.c version 20080118
D. J. Bernstein
Public domain.
*/
-/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */
+/* $OpenBSD: chacha.c,v 1.1 2013/11/21 00:45:44 djm Exp $ */
-#include <chacha.h>
-#include <stddef.h>
+#include "chacha.h"
+#include <sys/stddef.h>
+#include <sys/null.h>
typedef unsigned char u8;
typedef unsigned int u32;
@@ -76,10 +88,10 @@ chacha_keysetup(chacha_ctx_t *x, const u8 *k, u32 kbits, u32 ivbits __unused)
}
void
-chacha_ivsetup(chacha_ctx_t *x, const u8 *iv)
+chacha_ivsetup(chacha_ctx_t *x,const u8 *iv, const u8 *counter)
{
- x->chacha_input[12] = 0;
- x->chacha_input[13] = 0;
+ x->chacha_input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
+ x->chacha_input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
x->chacha_input[14] = U8TO32_LITTLE(iv + 0);
x->chacha_input[15] = U8TO32_LITTLE(iv + 4);
}
diff --git a/usr/src/common/crypto/chacha/chacha.h b/usr/src/common/crypto/chacha/chacha.h
index ac9993a8a4..edadca4934 100644
--- a/usr/src/common/crypto/chacha/chacha.h
+++ b/usr/src/common/crypto/chacha/chacha.h
@@ -10,7 +10,7 @@
*/
/*
- * Copyright (c) 2015, Joyent, Inc.
+ * Copyright 2019 Joyent, Inc.
*/
#ifndef _CHACHA_H
@@ -27,7 +27,7 @@
* over the data and xoring it with the generated cipher.
*/
-#include <inttypes.h>
+#include <sys/inttypes.h>
#ifdef __cplusplus
extern "C" {
@@ -39,7 +39,7 @@ typedef struct chacha_ctx {
extern void chacha_keysetup(chacha_ctx_t *, const uint8_t *, uint32_t,
uint32_t);
-extern void chacha_ivsetup(chacha_ctx_t *, const uint8_t *);
+extern void chacha_ivsetup(chacha_ctx_t *, const uint8_t *, const uint8_t *);
extern void chacha_encrypt_bytes(chacha_ctx_t *, const uint8_t *, uint8_t *,
uint32_t);
diff --git a/usr/src/common/net/dhcp/octet.c b/usr/src/common/net/dhcp/octet.c
index d8367bbf0b..370604c4e3 100644
--- a/usr/src/common/net/dhcp/octet.c
+++ b/usr/src/common/net/dhcp/octet.c
@@ -77,6 +77,9 @@ octet_to_hexascii(const void *nump, uint_t nlen, char *bufp, uint_t *blen)
* Converts an ASCII string into an octet string.
*
* Returns 0 for success, errno otherwise.
+ *
+ * If the string contains invalid hexadecimal characters, or an odd number of
+ * characters then this function returns EINVAL.
*/
int
hexascii_to_octet(const char *asp, uint_t alen, void *bufp, uint_t *blen)
diff --git a/usr/src/common/pnglite/pnglite.c b/usr/src/common/pnglite/pnglite.c
index 7a30bdc609..5d8b41f9e9 100644
--- a/usr/src/common/pnglite/pnglite.c
+++ b/usr/src/common/pnglite/pnglite.c
@@ -9,6 +9,7 @@
#else
#include <stdio.h>
#include <stdlib.h>
+#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
diff --git a/usr/src/common/refhash/refhash.c b/usr/src/common/refhash/refhash.c
new file mode 100644
index 0000000000..02ba869ef9
--- /dev/null
+++ b/usr/src/common/refhash/refhash.c
@@ -0,0 +1,231 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright (c) 2018, Joyent, Inc.
+ */
+
+#include <sys/refhash.h>
+#include <sys/types.h>
+#include <sys/list.h>
+#include <sys/debug.h>
+
+#ifdef _KERNEL
+#include <sys/sysmacros.h>
+#include <sys/ddi.h>
+#include <sys/kmem.h>
+#define REFHASH_ALLOC kmem_alloc
+#define REFHASH_ZALLOC kmem_zalloc
+#define REFHASH_FREE kmem_free
+#else
+#include <stddef.h>
+#include <umem.h>
+#define REFHASH_ALLOC umem_alloc
+#define REFHASH_ZALLOC umem_zalloc
+#define REFHASH_FREE umem_free
+#endif
+
+#define RHL_F_DEAD 0x01
+
+#ifdef lint
+extern refhash_link_t *obj_to_link(refhash_t *, void *);
+extern void *link_to_obj(refhash_t *, refhash_link_t *);
+extern void *obj_to_tag(refhash_t *, void *);
+#else
+#define obj_to_link(_h, _o) \
+ ((refhash_link_t *)(((char *)(_o)) + (_h)->rh_link_off))
+#define link_to_obj(_h, _l) \
+ ((void *)(((char *)(_l)) - (_h)->rh_link_off))
+#define obj_to_tag(_h, _o) \
+ ((void *)(((char *)(_o)) + (_h)->rh_tag_off))
+#endif
+
+refhash_t *
+refhash_create(uint_t bucket_count, refhash_hash_f hash,
+ refhash_cmp_f cmp, refhash_dtor_f dtor, size_t obj_size, size_t link_off,
+ size_t tag_off, int km_flags)
+{
+ refhash_t *hp;
+ uint_t i;
+
+ hp = REFHASH_ALLOC(sizeof (refhash_t), km_flags);
+ if (hp == NULL)
+ return (NULL);
+ hp->rh_buckets = REFHASH_ZALLOC(bucket_count * sizeof (list_t),
+ km_flags);
+ if (hp->rh_buckets == NULL) {
+ REFHASH_FREE(hp, sizeof (refhash_t));
+ return (NULL);
+ }
+ hp->rh_bucket_count = bucket_count;
+
+ for (i = 0; i < bucket_count; i++) {
+ list_create(&hp->rh_buckets[i], sizeof (refhash_link_t),
+ offsetof(refhash_link_t, rhl_chain_link));
+ }
+ list_create(&hp->rh_objs, sizeof (refhash_link_t),
+ offsetof(refhash_link_t, rhl_global_link));
+
+ hp->rh_obj_size = obj_size;
+ hp->rh_link_off = link_off;
+ hp->rh_tag_off = tag_off;
+ hp->rh_hash = hash;
+ hp->rh_cmp = cmp;
+ hp->rh_dtor = dtor;
+
+ return (hp);
+}
+
+void
+refhash_destroy(refhash_t *hp)
+{
+ ASSERT(list_is_empty(&hp->rh_objs));
+
+ REFHASH_FREE(hp->rh_buckets, hp->rh_bucket_count * sizeof (list_t));
+ REFHASH_FREE(hp, sizeof (refhash_t));
+}
+
+void
+refhash_insert(refhash_t *hp, void *op)
+{
+ uint_t bucket;
+ refhash_link_t *lp = obj_to_link(hp, op);
+
+ bucket = hp->rh_hash(obj_to_tag(hp, op)) % hp->rh_bucket_count;
+ list_link_init(&lp->rhl_chain_link);
+ list_link_init(&lp->rhl_global_link);
+ lp->rhl_flags = 0;
+ lp->rhl_refcnt = 0;
+ list_insert_tail(&hp->rh_buckets[bucket], lp);
+ list_insert_tail(&hp->rh_objs, lp);
+}
+
+static void
+refhash_delete(refhash_t *hp, void *op)
+{
+ refhash_link_t *lp = obj_to_link(hp, op);
+ uint_t bucket;
+
+ bucket = hp->rh_hash(obj_to_tag(hp, op)) % hp->rh_bucket_count;
+ list_remove(&hp->rh_buckets[bucket], lp);
+ list_remove(&hp->rh_objs, lp);
+ hp->rh_dtor(op);
+}
+
+void
+refhash_remove(refhash_t *hp, void *op)
+{
+ refhash_link_t *lp = obj_to_link(hp, op);
+
+ if (lp->rhl_refcnt > 0) {
+ lp->rhl_flags |= RHL_F_DEAD;
+ } else {
+ refhash_delete(hp, op);
+ }
+}
+
+void *
+refhash_lookup(refhash_t *hp, const void *tp)
+{
+ uint_t bucket;
+ refhash_link_t *lp;
+ void *op;
+
+ bucket = hp->rh_hash(tp) % hp->rh_bucket_count;
+ for (lp = list_head(&hp->rh_buckets[bucket]); lp != NULL;
+ lp = list_next(&hp->rh_buckets[bucket], lp)) {
+ op = link_to_obj(hp, lp);
+ if (hp->rh_cmp(obj_to_tag(hp, op), tp) == 0 &&
+ !(lp->rhl_flags & RHL_F_DEAD)) {
+ return (op);
+ }
+ }
+
+ return (NULL);
+}
+
+void *
+refhash_linear_search(refhash_t *hp, refhash_eval_f eval, void *arg)
+{
+ void *op;
+ refhash_link_t *lp;
+
+ for (lp = list_head(&hp->rh_objs); lp != NULL;
+ lp = list_next(&hp->rh_objs, lp)) {
+ op = link_to_obj(hp, lp);
+ if (eval(op, arg) == 0)
+ return (op);
+ }
+
+ return (NULL);
+}
+
+void
+refhash_hold(refhash_t *hp, void *op)
+{
+ refhash_link_t *lp = obj_to_link(hp, op);
+
+ ++lp->rhl_refcnt;
+}
+
+void
+refhash_rele(refhash_t *hp, void *op)
+{
+ refhash_link_t *lp = obj_to_link(hp, op);
+
+ ASSERT(lp->rhl_refcnt > 0);
+
+ if (--lp->rhl_refcnt == 0 && (lp->rhl_flags & RHL_F_DEAD))
+ refhash_remove(hp, op);
+}
+
+void *
+refhash_first(refhash_t *hp)
+{
+ refhash_link_t *lp;
+
+ lp = list_head(&hp->rh_objs);
+ if (lp == NULL)
+ return (NULL);
+
+ ++lp->rhl_refcnt;
+
+ return (link_to_obj(hp, lp));
+}
+
+void *
+refhash_next(refhash_t *hp, void *op)
+{
+ refhash_link_t *lp;
+
+ lp = obj_to_link(hp, op);
+ while ((lp = list_next(&hp->rh_objs, lp)) != NULL) {
+ if (!(lp->rhl_flags & RHL_F_DEAD))
+ break;
+ }
+
+ refhash_rele(hp, op);
+ if (lp == NULL)
+ return (NULL);
+
+ ++lp->rhl_refcnt;
+
+ return (link_to_obj(hp, lp));
+}
+
+boolean_t
+refhash_obj_valid(refhash_t *hp, const void *op)
+{
+ /* LINTED - E_ARG_INCOMPATIBLE_WITH_ARG_L */
+ const refhash_link_t *lp = obj_to_link(hp, op);
+
+ return ((lp->rhl_flags & RHL_F_DEAD) != 0);
+}
diff --git a/usr/src/common/zfs/zfs_prop.c b/usr/src/common/zfs/zfs_prop.c
index dd79442179..434e5bc90d 100644
--- a/usr/src/common/zfs/zfs_prop.c
+++ b/usr/src/common/zfs/zfs_prop.c
@@ -547,6 +547,23 @@ zfs_prop_delegatable(zfs_prop_t prop)
return (pd->pd_attr != PROP_READONLY);
}
+boolean_t
+zfs_prop_cacheable(zfs_prop_t prop)
+{
+ /*
+ * It'd be nice if each prop had a flags field which could have flag
+ * like PROP_CACHEABLE, but since zprop_attr_t is an enum and this
+ * setting is orthogonal to the concepts of PROP_READONLY, etc., we have
+ * this function.
+ */
+ return (prop == ZFS_PROP_VERSION ||
+ prop == ZFS_PROP_NORMALIZE ||
+ prop == ZFS_PROP_UTF8ONLY ||
+ prop == ZFS_PROP_CASE ||
+ prop == ZFS_PROP_VOLSIZE ||
+ prop == ZFS_PROP_VOLBLOCKSIZE);
+}
+
/*
* Given a zfs dataset property name, returns the corresponding property ID.
*/
diff --git a/usr/src/common/zfs/zfs_prop.h b/usr/src/common/zfs/zfs_prop.h
index 45423cc72f..3f34ad64a6 100644
--- a/usr/src/common/zfs/zfs_prop.h
+++ b/usr/src/common/zfs/zfs_prop.h
@@ -21,6 +21,7 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#ifndef _ZFS_PROP_H
@@ -89,6 +90,7 @@ typedef struct {
void zfs_prop_init(void);
zprop_type_t zfs_prop_get_type(zfs_prop_t);
boolean_t zfs_prop_delegatable(zfs_prop_t prop);
+boolean_t zfs_prop_cacheable(zfs_prop_t prop);
zprop_desc_t *zfs_prop_get_table(void);
/*