summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorJoshua M. Clulow <jmc@joyent.com>2015-03-05 10:35:32 -0800
committerJoshua M. Clulow <jmc@joyent.com>2015-03-06 07:33:59 +0000
commita903d81a6a1064d056ff85dd0ff490cc2687755e (patch)
tree11893b919e7fe49475e1f175c806e9e47777f173 /usr/src
parentf50b0b2da0a5a431d4c2e027843710e4f8f2853b (diff)
downloadillumos-joyent-a903d81a6a1064d056ff85dd0ff490cc2687755e.tar.gz
OS-3892 lxbrand mispronounces ENOLCK and ENOSTR
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Diffstat (limited to 'usr/src')
-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.c10
-rw-r--r--usr/src/common/brand/lx/tools/Makefile42
-rw-r--r--usr/src/common/brand/lx/tools/README.md39
-rw-r--r--usr/src/common/brand/lx/tools/gen_errno.c450
-rw-r--r--usr/src/lib/brand/lx/lx_brand/Makefile.com3
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/lx_brand.c16
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/signal.c2
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/socket.c2
-rw-r--r--usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h3
-rw-r--r--usr/src/uts/common/brand/lx/os/lx_syscall.c15
-rw-r--r--usr/src/uts/common/brand/lx/sys/lx_brand.h27
-rw-r--r--usr/src/uts/common/brand/lx/syscall/lx_wait.c5
-rw-r--r--usr/src/uts/intel/Makefile.files1
-rw-r--r--usr/src/uts/intel/brand/lx/lx_archdep.c3
16 files changed, 782 insertions, 71 deletions
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
index 22afb99ac7..4a8560a411 100644
--- a/usr/src/common/brand/lx/lx_signum.c
+++ b/usr/src/common/brand/lx/lx_signum.c
@@ -28,11 +28,7 @@
#include <sys/signal.h>
#include <sys/lx_siginfo.h>
#include <lx_signum.h>
-#ifdef _KERNEL
#include <sys/debug.h>
-#else
-#include <assert.h>
-#endif
/*
* Delivering signals to a Linux process is complicated by differences in
@@ -261,14 +257,12 @@ lx_stol_signo(int signo, int defsig)
int rval;
#ifdef _KERNEL
- VERIFY(defsig != -1);
+ VERIFY3S(defsig, >=, 0);
#endif
if (signo < 0 || signo >= NSIG || (rval = stol_signo[signo]) < 1) {
#ifndef _KERNEL
- if (defsig == -1) {
- assert(0);
- }
+ VERIFY3S(defsig, >=, 0);
#endif
return (defsig);
}
diff --git a/usr/src/common/brand/lx/tools/Makefile b/usr/src/common/brand/lx/tools/Makefile
new file mode 100644
index 0000000000..5ad1240c55
--- /dev/null
+++ b/usr/src/common/brand/lx/tools/Makefile
@@ -0,0 +1,42 @@
+#
+# 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.
+#
+
+PROG = gen_errno
+
+include ../../../../cmd/Makefile.cmd
+
+OBJS = gen_errno.o
+
+CLOBBERFILES += $(PROG)
+
+NATIVECC_CFLAGS += $(CFLAGS) $(CCVERBOSE)
+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..1edd924edf
--- /dev/null
+++ b/usr/src/common/brand/lx/tools/gen_errno.c
@@ -0,0 +1,450 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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 <libcmdutils.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;
+
+ if (nam != NULL) {
+ custr_free(nam);
+ }
+ if (num != NULL) {
+ 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 || custr_append(cu, "") != 0) {
+ if (cu != NULL) {
+ custr_free(cu);
+ }
+ return (-1);
+ }
+
+ if ((f = fopen(path, "r")) == NULL) {
+ 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/lib/brand/lx/lx_brand/Makefile.com b/usr/src/lib/brand/lx/lx_brand/Makefile.com
index 804dccfce7..9c3b7b142c 100644
--- a/usr/src/lib/brand/lx/lx_brand/Makefile.com
+++ b/usr/src/lib/brand/lx/lx_brand/Makefile.com
@@ -63,7 +63,8 @@ COBJS = aio.o \
time.o \
truncate.o
-CMNOBJS = lx_signum.o
+CMNOBJS = lx_errno.o \
+ lx_signum.o
ASOBJS = lx_handler.o lx_crt.o
OBJECTS = $(CMNOBJS) $(COBJS) $(ASOBJS)
diff --git a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c
index edbb51b1f2..6f3f1248ce 100644
--- a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c
+++ b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c
@@ -88,11 +88,6 @@
* function should return -errno back to the Linux caller.
*/
-/*
- * Map Illumos errno to the Linux equivalent.
- */
-static int stol_errno[] = LX_STOL_ERRNO_INIT;
-
char lx_release[LX_VERS_MAX];
char lx_cmd_name[MAXNAMLEN];
@@ -145,17 +140,6 @@ pid_t zoneinit_pid; /* zone init PID */
thread_key_t lx_tsd_key;
int
-lx_errno(int err)
-{
- if (err >= sizeof (stol_errno) / sizeof (stol_errno[0])) {
- lx_debug("invalid errno %d\n", err);
- assert(0);
- }
-
- return (stol_errno[err]);
-}
-
-int
uucopy_unsafe(const void *src, void *dst, size_t n)
{
bcopy(src, dst, n);
diff --git a/usr/src/lib/brand/lx/lx_brand/common/signal.c b/usr/src/lib/brand/lx/lx_brand/common/signal.c
index 7591be5792..48efd24eeb 100644
--- a/usr/src/lib/brand/lx/lx_brand/common/signal.c
+++ b/usr/src/lib/brand/lx/lx_brand/common/signal.c
@@ -1451,7 +1451,7 @@ lx_call_user_handler(int sig, siginfo_t *sip, void *p)
if (lxsap->lxsa_flags & LX_SA_RESTART) {
uintptr_t flags = (uintptr_t)ucp->uc_brand_data[0];
long ret = (long)LX_REG(ucp, REG_R0);
- boolean_t interrupted = (ret == -lx_errno(EINTR));
+ boolean_t interrupted = (ret == -lx_errno(EINTR, -1));
/*
* If the system call returned EINTR, and the system
diff --git a/usr/src/lib/brand/lx/lx_brand/common/socket.c b/usr/src/lib/brand/lx/lx_brand/common/socket.c
index b8c2c31582..9a2e7fd845 100644
--- a/usr/src/lib/brand/lx/lx_brand/common/socket.c
+++ b/usr/src/lib/brand/lx/lx_brand/common/socket.c
@@ -2088,7 +2088,7 @@ lx_getsockopt(int sockfd, int level, int optname, void *optval, int *optlenp)
break;
case SO_ERROR:
- *(int *)optval = lx_errno(*(int *)optval);
+ *(int *)optval = lx_errno(*(int *)optval, -1);
break;
}
}
diff --git a/usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h b/usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h
index bed6a8da4b..c4edfc0b1a 100644
--- a/usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h
+++ b/usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h
@@ -41,6 +41,8 @@
#include <sys/lx_brand.h>
#include <sys/lx_thread.h>
+#include <lx_errno.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -168,7 +170,6 @@ struct ucontext;
extern ucontext_t *lx_syscall_regs(void);
extern uintptr_t lx_find_brand_sp(void);
extern const ucontext_t *lx_find_brand_uc(void);
-extern int lx_errno(int);
extern char *lx_fd_to_path(int fd, char *buf, int buf_size);
extern int lx_lpid_to_spair(pid_t, pid_t *, lwpid_t *);
diff --git a/usr/src/uts/common/brand/lx/os/lx_syscall.c b/usr/src/uts/common/brand/lx/os/lx_syscall.c
index c8b8560555..da6447ec9a 100644
--- a/usr/src/uts/common/brand/lx/os/lx_syscall.c
+++ b/usr/src/uts/common/brand/lx/os/lx_syscall.c
@@ -42,6 +42,7 @@
#include <sys/lx_brand.h>
#include <sys/lx_impl.h>
#include <sys/lx_misc.h>
+#include <lx_errno.h>
/*
@@ -95,11 +96,6 @@ int lx_nsysent64;
lx_sysent_t lx_sysent32[LX_NSYSCALLS + 1];
int lx_nsysent32;
-/*
- * Map Illumos errno to the Linux equivalent.
- */
-int lx_stol_errno[] = LX_STOL_ERRNO_INIT;
-
#if defined(_LP64)
struct lx_vsyscall
{
@@ -232,14 +228,7 @@ lx_syscall_return(klwp_t *lwp, int syscall_num, long ret)
/*
* Convert from illumos to Linux errno:
*/
- if (error < 1 || error >= (sizeof (lx_stol_errno) /
- sizeof (lx_stol_errno[0]))) {
- /*
- * The provided error number is not valid.
- */
- error = EINVAL;
- }
- ret = -lx_stol_errno[error];
+ ret = -lx_errno(error, EINVAL);
}
/*
diff --git a/usr/src/uts/common/brand/lx/sys/lx_brand.h b/usr/src/uts/common/brand/lx/sys/lx_brand.h
index f3c46dd7fd..473bbd8917 100644
--- a/usr/src/uts/common/brand/lx/sys/lx_brand.h
+++ b/usr/src/uts/common/brand/lx/sys/lx_brand.h
@@ -158,31 +158,6 @@ typedef enum lx_ptrace_options {
#define AT_SYSINFO_EHDR 33
/*
- * This table initialiser maps errno values from illumos to Linux numbers.
- * It is presently used in both the usermode and kernel emulation code,
- * so it is defined here.
- */
-/* BEGIN CSTYLED */
-#define LX_STOL_ERRNO_INIT { \
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, \
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, \
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, \
- 30, 31, 32, 33, 34, 42, 43, 44, 45, 46, \
- 47, 48, 49, 50, 51, 35, 47, 22, 38, 22, /* 49 */ \
- 52, 53, 54, 55, 56, 57, 58, 59, 22, 22, \
- 61, 61, 62, 63, 64, 65, 66, 67, 68, 69, \
- 70, 71, 22, 22, 72, 22, 22, 74, 36, 75, \
- 76, 77, 78, 79, 80, 81, 82, 83, 84, 38, \
- 40, 85, 86, 39, 87, 88, 89, 90, 91, 92, /* 99 */ \
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, \
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, \
- 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, \
- 103, 104, 105, 106, 107, 22, 22, 22, 22, 22, \
- 22, 22, 22, 108, 109, 110, 111, 112, 113, 114, /* 149 */ \
- 115, 116 }
-/* END CSTYLED */
-
-/*
* Usermode emulation routines are run on an alternate stack allocated by
* the brand library. Every LWP in a process will incur this overhead beyond
* the regular thread stack:
@@ -640,8 +615,6 @@ extern void lx_emulate_user32(klwp_t *, int, uintptr_t *);
extern int lx_debug;
#define lx_print if (lx_debug) printf
-extern int lx_stol_errno[];
-
/*
* In-Kernel Linux System Call Description.
*/
diff --git a/usr/src/uts/common/brand/lx/syscall/lx_wait.c b/usr/src/uts/common/brand/lx/syscall/lx_wait.c
index 7b10d2f90b..e6c5607e43 100644
--- a/usr/src/uts/common/brand/lx/syscall/lx_wait.c
+++ b/usr/src/uts/common/brand/lx/syscall/lx_wait.c
@@ -72,6 +72,7 @@
#include <sys/lx_types.h>
#include <sys/lx_siginfo.h>
#include <lx_signum.h>
+#include <lx_errno.h>
#include <lx_syscall.h>
/*
@@ -332,7 +333,7 @@ stol_ksiginfo(k_siginfo_t *sip, uintptr_t lxsip)
bzero(&lsi, sizeof (lsi));
lsi.lsi_signo = lx_stol_signo(sip->si_signo, SIGCLD);
lsi.lsi_code = lx_stol_sigcode(sip->si_code);
- lsi.lsi_errno = lx_stol_errno[sip->si_errno];
+ lsi.lsi_errno = lx_errno(sip->si_errno, EINVAL);
switch (lsi.lsi_signo) {
case LX_SIGPOLL:
@@ -380,7 +381,7 @@ stol_ksiginfo32(k_siginfo_t *sip, uintptr_t lxsip)
bzero(&lsi, sizeof (lsi));
lsi.lsi_signo = lx_stol_signo(sip->si_signo, SIGCLD);
lsi.lsi_code = lx_stol_sigcode(sip->si_code);
- lsi.lsi_errno = lx_stol_errno[sip->si_errno];
+ lsi.lsi_errno = lx_errno(sip->si_errno, EINVAL);
switch (lsi.lsi_signo) {
case LX_SIGPOLL:
diff --git a/usr/src/uts/intel/Makefile.files b/usr/src/uts/intel/Makefile.files
index b8127194ad..1f2cddbd61 100644
--- a/usr/src/uts/intel/Makefile.files
+++ b/usr/src/uts/intel/Makefile.files
@@ -282,6 +282,7 @@ LX_BRAND_OBJS = \
lx_chmod.o \
lx_chown.o \
lx_clone.o \
+ lx_errno.o \
lx_futex.o \
lx_getpid.o \
lx_id.o \
diff --git a/usr/src/uts/intel/brand/lx/lx_archdep.c b/usr/src/uts/intel/brand/lx/lx_archdep.c
index 49f2f12172..008044842d 100644
--- a/usr/src/uts/intel/brand/lx/lx_archdep.c
+++ b/usr/src/uts/intel/brand/lx/lx_archdep.c
@@ -28,6 +28,7 @@
#include <sys/stack.h>
#include <sys/sdt.h>
#include <sys/sysmacros.h>
+#include <lx_errno.h>
#define LX_REG(ucp, r) ((ucp)->uc_mcontext.gregs[(r)])
@@ -563,7 +564,7 @@ lx_regs_to_userregs(lx_lwp_data_t *lwpd, void *uregsp)
switch (lwpd->br_ptrace_whatstop) {
case LX_PR_SYSENTRY:
orig_r0 = lwpd->br_syscall_num;
- r0 = -lx_stol_errno[ENOTSUP];
+ r0 = -lx_errno(ENOTSUP, EINVAL);
break;
case LX_PR_SYSEXIT:
orig_r0 = lwpd->br_syscall_num;