From 4e108b7a31ae23038d2e0a3cd77055c1e9db8291 Mon Sep 17 00:00:00 2001 From: dchagin Date: Sun, 28 Apr 2019 13:33:35 +0000 Subject: [PATCH] MFC r331056: Share a single bsd-linux errno table across MD consumers Three copies of the linuxulator linux_sysvec.c contained identical BSD to Linux errno translation tables, and future work to support other architectures will also use the same table. Move the table to a common file to be used by all. Make it 'const int' to place it in .rodata. (Some existing Linux architectures use MD errno values, but x86 and Arm share the generic set.) This change should introduce no functional change; a followup will add missing errno values. MFC r331057: linux_errno.c: add newer errno values Also introduce a static assert to ensure the list is kept up to date. MFC r331060: Chase r331057 in libsysdecode erno table --- lib/libsysdecode/errno.c | 6 +- sys/amd64/linux/linux_sysvec.c | 22 +---- sys/amd64/linux32/linux32_sysvec.c | 22 +---- sys/compat/linux/linux_emul.h | 2 + sys/compat/linux/linux_errno.c | 151 +++++++++++++++++++++++++++++ sys/conf/files.amd64 | 1 + sys/conf/files.i386 | 1 + sys/i386/linux/linux_sysvec.c | 24 +---- sys/modules/linux/Makefile | 2 +- sys/modules/linux_common/Makefile | 2 + 10 files changed, 165 insertions(+), 68 deletions(-) create mode 100644 sys/compat/linux/linux_errno.c diff --git a/lib/libsysdecode/errno.c b/lib/libsysdecode/errno.c index 512b76d0e0d..d4d9ca1a836 100644 --- a/lib/libsysdecode/errno.c +++ b/lib/libsysdecode/errno.c @@ -41,8 +41,8 @@ __FBSDID("$FreeBSD$"); * Linux syscalls return negative errno's, we do positive and map them * Reference: * FreeBSD: src/sys/sys/errno.h - * Linux: linux-2.6.17.8/include/asm-generic/errno-base.h - * linux-2.6.17.8/include/asm-generic/errno.h + * Linux: include/uapi/asm-generic/errno-base.h + * include/uapi/asm-generic/errno.h */ static int bsd_to_linux_errno[ELAST + 1] = { -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, @@ -54,7 +54,7 @@ static int bsd_to_linux_errno[ELAST + 1] = { -110,-111, -40, -36,-112,-113, -39, -11, -87,-122, -116, -66, -6, -6, -6, -6, -6, -37, -38, -9, -6, -6, -43, -42, -75,-125, -84, -61, -16, -74, - -72, -67, -71 + -72, -67, -71, -1, -1, -131, -130 }; #endif diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c index 443a524c3d0..77e94a444b1 100644 --- a/sys/amd64/linux/linux_sysvec.c +++ b/sys/amd64/linux/linux_sysvec.c @@ -130,26 +130,6 @@ static void linux_exec_setregs(struct thread *td, struct image_params *imgp, u_long stack); static int linux_vsyscall(struct thread *td); -/* - * Linux syscalls return negative errno's, we do positive and map them - * Reference: - * FreeBSD: src/sys/sys/errno.h - * Linux: linux-2.6.17.8/include/asm-generic/errno-base.h - * linux-2.6.17.8/include/asm-generic/errno.h - */ -static int bsd_to_linux_errno[ELAST + 1] = { - -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, - -10, -35, -12, -13, -14, -15, -16, -17, -18, -19, - -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, - -30, -31, -32, -33, -34, -11,-115,-114, -88, -89, - -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, - -100,-101,-102,-103,-104,-105,-106,-107,-108,-109, - -110,-111, -40, -36,-112,-113, -39, -11, -87,-122, - -116, -66, -6, -6, -6, -6, -6, -37, -38, -9, - -6, -6, -43, -42, -75,-125, -84, -61, -16, -74, - -72, -67, -71 -}; - #define LINUX_T_UNKNOWN 255 static int _bsd_to_linux_trapcode[] = { LINUX_T_UNKNOWN, /* 0 */ @@ -773,7 +753,7 @@ struct sysentvec elf_linux_sysvec = { .sv_table = linux_sysent, .sv_mask = 0, .sv_errsize = ELAST + 1, - .sv_errtbl = bsd_to_linux_errno, + .sv_errtbl = bsd_to_linux_errno_generic, .sv_transtrap = translate_traps, .sv_fixup = elf_linux_fixup, .sv_sendsig = linux_rt_sendsig, diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index 4eaf10ad3a6..a25e2451176 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -131,26 +131,6 @@ static bool linux32_trans_osrel(const Elf_Note *note, int32_t *osrel); static void linux_vdso_install(void *param); static void linux_vdso_deinstall(void *param); -/* - * Linux syscalls return negative errno's, we do positive and map them - * Reference: - * FreeBSD: src/sys/sys/errno.h - * Linux: linux-2.6.17.8/include/asm-generic/errno-base.h - * linux-2.6.17.8/include/asm-generic/errno.h - */ -static int bsd_to_linux_errno[ELAST + 1] = { - -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, - -10, -35, -12, -13, -14, -15, -16, -17, -18, -19, - -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, - -30, -31, -32, -33, -34, -11,-115,-114, -88, -89, - -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, - -100,-101,-102,-103,-104,-105,-106,-107,-108,-109, - -110,-111, -40, -36,-112,-113, -39, -11, -87,-122, - -116, -66, -6, -6, -6, -6, -6, -37, -38, -9, - -6, -6, -43, -42, -75,-125, -84, -61, -16, -74, - -72, -67, -71 -}; - #define LINUX_T_UNKNOWN 255 static int _bsd_to_linux_trapcode[] = { LINUX_T_UNKNOWN, /* 0 */ @@ -973,7 +953,7 @@ struct sysentvec elf_linux_sysvec = { .sv_table = linux32_sysent, .sv_mask = 0, .sv_errsize = ELAST + 1, - .sv_errtbl = bsd_to_linux_errno, + .sv_errtbl = bsd_to_linux_errno_generic, .sv_transtrap = translate_traps, .sv_fixup = elf_linux_fixup, .sv_sendsig = linux_sendsig, diff --git a/sys/compat/linux/linux_emul.h b/sys/compat/linux/linux_emul.h index 5d79e76f2a0..cfe0f2db4b7 100644 --- a/sys/compat/linux/linux_emul.h +++ b/sys/compat/linux/linux_emul.h @@ -77,4 +77,6 @@ struct linux_pemuldata { struct linux_pemuldata *pem_find(struct proc *); +extern const int bsd_to_linux_errno_generic[]; + #endif /* !_LINUX_EMUL_H_ */ diff --git a/sys/compat/linux/linux_errno.c b/sys/compat/linux/linux_errno.c new file mode 100644 index 00000000000..002d2592974 --- /dev/null +++ b/sys/compat/linux/linux_errno.c @@ -0,0 +1,151 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 1994-1996 Søren Schmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include + +/* + * Linux syscalls return negative errno's, we do positive and map them + * Reference: + * FreeBSD: src/sys/sys/errno.h + * Linux: include/uapi/asm-generic/errno-base.h + * include/uapi/asm-generic/errno.h + */ +const int bsd_to_linux_errno_generic[ELAST + 1] = { + -0, + -1, + -2, + -3, + -4, + -5, + -6, + -7, + -8, + -9, + + -10, + -35, /* EDEADLK */ + -12, + -13, + -14, + -15, + -16, + -17, + -18, + -19, + + -20, + -21, + -22, + -23, + -24, + -25, + -26, + -27, + -28, + -29, + + -30, + -31, + -32, + -33, + -34, + -11, /* EAGAIN */ + -115, + -114, + -88, + -89, + + -90, + -91, + -92, + -93, + -94, + -95, + -96, + -97, + -98, + -99, + + -100, + -101, + -102, + -103, + -104, + -105, + -106, + -107, + -108, + -109, + + -110, + -111, + -40, + -36, + -112, + -113, + -39, + -11, + -87, + -122, + + -116, + -66, + -6, /* EBADRPC -> ENXIO */ + -6, /* ERPCMISMATCH -> ENXIO */ + -6, /* EPROGUNAVAIL -> ENXIO */ + -6, /* EPROGMISMATCH -> ENXIO */ + -6, /* EPROCUNAVAIL -> ENXIO */ + -37, + -38, + -9, + + -6, /* EAUTH -> ENXIO */ + -6, /* ENEEDAUTH -> ENXIO */ + -43, + -42, + -75, + -125, + -84, + -61, + -16, /* EDOOFUS -> EBUSY */ + -74, + + -72, + -67, + -71, + -1, /* ENOTCAPABLE -> EPERM */ + -1, /* ECAPMODE -> EPERM */ + -131, /* ENOTRECOVERABLE */ + -130, /* EOWNERDEAD */ +}; + +_Static_assert(ELAST == 96, + "missing errno entries in bsd_to_linux_errno_generic"); diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 46b0578b1dc..ec91f3e566b 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -623,6 +623,7 @@ amd64/linux32/linux32_support.s optional compat_linux32 \ amd64/linux32/linux32_sysent.c optional compat_linux32 amd64/linux32/linux32_sysvec.c optional compat_linux32 compat/linux/linux_emul.c optional compat_linux32 +compat/linux/linux_errno.c optional compat_linux32 compat/linux/linux_file.c optional compat_linux32 compat/linux/linux_fork.c optional compat_linux32 compat/linux/linux_futex.c optional compat_linux32 diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index e5761b9dce1..b7e5b00dcc6 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -100,6 +100,7 @@ compat/linprocfs/linprocfs.c optional linprocfs compat/linsysfs/linsysfs.c optional linsysfs compat/linux/linux_event.c optional compat_linux compat/linux/linux_emul.c optional compat_linux +compat/linux/linux_errno.c optional compat_linux compat/linux/linux_file.c optional compat_linux compat/linux/linux_fork.c optional compat_linux compat/linux/linux_futex.c optional compat_linux diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index 5ef0d8ba207..99beb8e63e4 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -126,26 +126,6 @@ static eventhandler_tag linux_exit_tag; static eventhandler_tag linux_exec_tag; static eventhandler_tag linux_thread_dtor_tag; -/* - * Linux syscalls return negative errno's, we do positive and map them - * Reference: - * FreeBSD: src/sys/sys/errno.h - * Linux: linux-2.6.17.8/include/asm-generic/errno-base.h - * linux-2.6.17.8/include/asm-generic/errno.h - */ -static int bsd_to_linux_errno[ELAST + 1] = { - -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, - -10, -35, -12, -13, -14, -15, -16, -17, -18, -19, - -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, - -30, -31, -32, -33, -34, -11,-115,-114, -88, -89, - -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, - -100,-101,-102,-103,-104,-105,-106,-107,-108,-109, - -110,-111, -40, -36,-112,-113, -39, -11, -87,-122, - -116, -66, -6, -6, -6, -6, -6, -37, -38, -9, - -6, -6, -43, -42, -75,-125, -84, -61, -16, -74, - -72, -67, -71 -}; - #define LINUX_T_UNKNOWN 255 static int _bsd_to_linux_trapcode[] = { LINUX_T_UNKNOWN, /* 0 */ @@ -905,7 +885,7 @@ struct sysentvec linux_sysvec = { .sv_table = linux_sysent, .sv_mask = 0, .sv_errsize = ELAST + 1, - .sv_errtbl = bsd_to_linux_errno, + .sv_errtbl = bsd_to_linux_errno_generic, .sv_transtrap = translate_traps, .sv_fixup = linux_fixup, .sv_sendsig = linux_sendsig, @@ -942,7 +922,7 @@ struct sysentvec elf_linux_sysvec = { .sv_table = linux_sysent, .sv_mask = 0, .sv_errsize = ELAST + 1, - .sv_errtbl = bsd_to_linux_errno, + .sv_errtbl = bsd_to_linux_errno_generic, .sv_transtrap = translate_traps, .sv_fixup = elf_linux_fixup, .sv_sendsig = linux_sendsig, diff --git a/sys/modules/linux/Makefile b/sys/modules/linux/Makefile index 89f3aeb80bf..94227fbdc1b 100644 --- a/sys/modules/linux/Makefile +++ b/sys/modules/linux/Makefile @@ -31,7 +31,7 @@ OBJS= ${VDSO}.so .if ${MACHINE_CPUARCH} == "i386" SRCS+= linux_ptrace.c imgact_linux.c linux_util.c linux_mib.c linux_mmap.c \ - linux_emul.c opt_cpu.h linux.c + linux_emul.c linux_errno.c opt_cpu.h linux.c .endif .if ${MACHINE_CPUARCH} == "i386" diff --git a/sys/modules/linux_common/Makefile b/sys/modules/linux_common/Makefile index 8e08b39674b..1583e88f704 100644 --- a/sys/modules/linux_common/Makefile +++ b/sys/modules/linux_common/Makefile @@ -4,9 +4,11 @@ KMOD= linux_common SRCS= linux_common.c linux_mib.c linux_mmap.c linux_util.c linux_emul.c \ + linux_errno.c \ linux.c opt_compat.h device_if.h vnode_if.h bus_if.h EXPORT_SYMS= +EXPORT_SYMS+= bsd_to_linux_errno_generic EXPORT_SYMS+= linux_emul_path EXPORT_SYMS+= linux_ioctl_register_handler EXPORT_SYMS+= linux_ioctl_unregister_handler -- 2.45.0