Index: sys/amd64/amd64/elf_machdep.c =================================================================== --- sys/amd64/amd64/elf_machdep.c +++ sys/amd64/amd64/elf_machdep.c @@ -52,8 +52,6 @@ struct sysentvec elf64_freebsd_sysvec_la48 = { .sv_size = SYS_MAXSYSCALL, .sv_table = sysent, - .sv_errsize = 0, - .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = __elfN(freebsd_fixup), .sv_sendsig = sendsig, @@ -89,8 +87,6 @@ struct sysentvec elf64_freebsd_sysvec_la57 = { .sv_size = SYS_MAXSYSCALL, .sv_table = sysent, - .sv_errsize = 0, - .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = __elfN(freebsd_fixup), .sv_sendsig = sendsig, Index: sys/amd64/amd64/vm_machdep.c =================================================================== --- sys/amd64/amd64/vm_machdep.c +++ sys/amd64/amd64/vm_machdep.c @@ -543,7 +543,7 @@ break; default: - frame->tf_rax = SV_ABI_ERRNO(td->td_proc, error); + frame->tf_rax = error; frame->tf_rflags |= PSL_C; break; } Index: sys/amd64/linux/linux_sysvec.c =================================================================== --- sys/amd64/linux/linux_sysvec.c +++ sys/amd64/linux/linux_sysvec.c @@ -219,6 +219,11 @@ cpu_set_syscall_retval(td, error); + if (__predict_false(error != 0)) { + if (error != ERESTART && error != EJUSTRETURN) + frame->tf_rax = linux_to_bsd_errno(error); + } + /* Restore all registers. */ set_pcb_flags(td->td_pcb, PCB_FULL_IRET); } @@ -727,8 +732,6 @@ struct sysentvec elf_linux_sysvec = { .sv_size = LINUX_SYS_MAXSYSCALL, .sv_table = linux_sysent, - .sv_errsize = ELAST + 1, - .sv_errtbl = linux_errtbl, .sv_transtrap = linux_translate_traps, .sv_fixup = linux_fixup_elf, .sv_sendsig = linux_rt_sendsig, Index: sys/amd64/linux32/linux32_sysvec.c =================================================================== --- sys/amd64/linux32/linux32_sysvec.c +++ sys/amd64/linux32/linux32_sysvec.c @@ -112,6 +112,7 @@ 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); +static void linux32_set_syscall_retval(struct thread *td, int error); #define LINUX_T_UNKNOWN 255 static int _bsd_to_linux_trapcode[] = { @@ -669,6 +670,19 @@ return (0); } +static void +linux32_set_syscall_retval(struct thread *td, int error) +{ + struct trapframe *frame = td->td_frame; + + cpu_set_syscall_retval(td, error); + + if (__predict_false(error != 0)) { + if (error != ERESTART && error != EJUSTRETURN) + frame->tf_rax = linux_to_bsd_errno(error); + } +} + /* * Clear registers on exec * XXX copied from ia32_signal.c. @@ -884,8 +898,6 @@ struct sysentvec elf_linux_sysvec = { .sv_size = LINUX32_SYS_MAXSYSCALL, .sv_table = linux32_sysent, - .sv_errsize = ELAST + 1, - .sv_errtbl = linux_errtbl, .sv_transtrap = linux_translate_traps, .sv_fixup = linux_fixup_elf, .sv_sendsig = linux_sendsig, @@ -906,7 +918,7 @@ .sv_fixlimit = linux32_fixlimit, .sv_maxssiz = &linux32_maxssiz, .sv_flags = SV_ABI_LINUX | SV_ILP32 | SV_IA32 | SV_SHP, - .sv_set_syscall_retval = cpu_set_syscall_retval, + .sv_set_syscall_retval = linux32_set_syscall_retval, .sv_fetch_syscall_args = linux32_fetch_syscall_args, .sv_syscallnames = NULL, .sv_shared_page_base = LINUX32_SHAREDPAGE, Index: sys/arm/arm/elf_machdep.c =================================================================== --- sys/arm/arm/elf_machdep.c +++ sys/arm/arm/elf_machdep.c @@ -65,8 +65,6 @@ struct sysentvec elf32_freebsd_sysvec = { .sv_size = SYS_MAXSYSCALL, .sv_table = sysent, - .sv_errsize = 0, - .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = __elfN(freebsd_fixup), .sv_sendsig = sendsig, Index: sys/arm/arm/vm_machdep.c =================================================================== --- sys/arm/arm/vm_machdep.c +++ sys/arm/arm/vm_machdep.c @@ -219,7 +219,7 @@ /* nothing to do */ break; default: - frame->tf_r0 = SV_ABI_ERRNO(td->td_proc, error); + frame->tf_r0 = error; frame->tf_spsr |= PSR_C; /* carry bit */ break; } Index: sys/arm64/arm64/elf32_machdep.c =================================================================== --- sys/arm64/arm64/elf32_machdep.c +++ sys/arm64/arm64/elf32_machdep.c @@ -77,8 +77,6 @@ static struct sysentvec elf32_freebsd_sysvec = { .sv_size = SYS_MAXSYSCALL, .sv_table = freebsd32_sysent, - .sv_errsize = 0, - .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = elf32_freebsd_fixup, .sv_sendsig = freebsd32_sendsig, Index: sys/arm64/arm64/elf_machdep.c =================================================================== --- sys/arm64/arm64/elf_machdep.c +++ sys/arm64/arm64/elf_machdep.c @@ -61,8 +61,6 @@ static struct sysentvec elf64_freebsd_sysvec = { .sv_size = SYS_MAXSYSCALL, .sv_table = sysent, - .sv_errsize = 0, - .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = __elfN(freebsd_fixup), .sv_sendsig = sendsig, Index: sys/arm64/arm64/vm_machdep.c =================================================================== --- sys/arm64/arm64/vm_machdep.c +++ sys/arm64/arm64/vm_machdep.c @@ -153,7 +153,7 @@ break; default: frame->tf_spsr |= PSR_C; /* carry bit */ - frame->tf_x[0] = SV_ABI_ERRNO(td->td_proc, error); + frame->tf_x[0] = error; break; } } Index: sys/arm64/linux/linux_sysvec.c =================================================================== --- sys/arm64/linux/linux_sysvec.c +++ sys/arm64/linux/linux_sysvec.c @@ -141,6 +141,11 @@ td->td_retval[1] = td->td_frame->tf_x[1]; cpu_set_syscall_retval(td, error); + + if (__predict_false(error != 0)) { + if (error != ERESTART && error != EJUSTRETURN) + frame->tf_rax = linux_to_bsd_errno(error); + } } static int @@ -387,8 +392,6 @@ struct sysentvec elf_linux_sysvec = { .sv_size = LINUX_SYS_MAXSYSCALL, .sv_table = linux_sysent, - .sv_errsize = ELAST + 1, - .sv_errtbl = linux_errtbl, .sv_transtrap = linux_translate_traps, .sv_fixup = linux_elf_fixup, .sv_sendsig = linux_rt_sendsig, Index: sys/compat/ia32/ia32_sysvec.c =================================================================== --- sys/compat/ia32/ia32_sysvec.c +++ sys/compat/ia32/ia32_sysvec.c @@ -98,8 +98,6 @@ struct sysentvec ia32_freebsd_sysvec = { .sv_size = FREEBSD32_SYS_MAXSYSCALL, .sv_table = freebsd32_sysent, - .sv_errsize = 0, - .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = elf32_freebsd_fixup, .sv_sendsig = ia32_sendsig, Index: sys/compat/linux/linux.h =================================================================== --- sys/compat/linux/linux.h +++ sys/compat/linux/linux.h @@ -192,4 +192,6 @@ } #define BITMAP_1t1_LINUX(_name) BITMAP_EASY_LINUX(_name, LINUX_##_name) +int linux_to_bsd_errno(int error); + #endif /* _LINUX_MI_H_ */ Index: sys/compat/linux/linux_errno.c =================================================================== --- sys/compat/linux/linux_errno.c +++ sys/compat/linux/linux_errno.c @@ -1,6 +1,26 @@ /* $FreeBSD$ */ #include +__FBSDID("$FreeBSD$"); + +#include #include +#include +#include #include + +int +linux_to_bsd_errno(int error) +{ + + KASSERT(error >= 0, ("%s: error %d not >= 0", __func__, error)); + + if (error > ELAST) { + /* + * XXX: Turn it into a KASSERT, perhaps? + */ + return (-1); + } + return (linux_errtbl[error]); +} Index: sys/compat/linux/linux_socket.c =================================================================== --- sys/compat/linux/linux_socket.c +++ sys/compat/linux/linux_socket.c @@ -1553,7 +1553,7 @@ name, &newval, UIO_SYSSPACE, &len); if (error != 0) return (error); - newval = -SV_ABI_ERRNO(td->td_proc, newval); + newval = -linux_to_bsd_errno(newval); return (copyout(&newval, PTRIN(args->optval), len)); /* NOTREACHED */ default: Index: sys/i386/i386/elf_machdep.c =================================================================== --- sys/i386/i386/elf_machdep.c +++ sys/i386/i386/elf_machdep.c @@ -54,8 +54,6 @@ struct sysentvec elf32_freebsd_sysvec = { .sv_size = SYS_MAXSYSCALL, .sv_table = sysent, - .sv_errsize = 0, - .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = __elfN(freebsd_fixup), .sv_sendsig = sendsig, Index: sys/i386/i386/vm_machdep.c =================================================================== --- sys/i386/i386/vm_machdep.c +++ sys/i386/i386/vm_machdep.c @@ -407,7 +407,7 @@ break; default: - td->td_frame->tf_eax = SV_ABI_ERRNO(td->td_proc, error); + td->td_frame->tf_eax = error; td->td_frame->tf_eflags |= PSL_C; break; } Index: sys/i386/linux/linux_sysvec.c =================================================================== --- sys/i386/linux/linux_sysvec.c +++ sys/i386/linux/linux_sysvec.c @@ -792,6 +792,19 @@ return (0); } +static void +linux_set_syscall_retval(struct thread *td, int error) +{ + struct trapframe *frame = td->td_frame; + + cpu_set_syscall_retval(td, error); + + if (__predict_false(error != 0)) { + if (error != ERESTART && error != EJUSTRETURN) + frame->tf_rax = linux_to_bsd_errno(error); + } +} + /* * exec_setregs may initialize some registers differently than Linux * does, thus potentially confusing Linux binaries. If necessary, we @@ -834,8 +847,6 @@ struct sysentvec linux_sysvec = { .sv_size = LINUX_SYS_MAXSYSCALL, .sv_table = linux_sysent, - .sv_errsize = ELAST + 1, - .sv_errtbl = linux_errtbl, .sv_transtrap = linux_translate_traps, .sv_fixup = linux_fixup, .sv_sendsig = linux_sendsig, @@ -855,7 +866,7 @@ .sv_fixlimit = NULL, .sv_maxssiz = NULL, .sv_flags = SV_ABI_LINUX | SV_AOUT | SV_IA32 | SV_ILP32, - .sv_set_syscall_retval = cpu_set_syscall_retval, + .sv_set_syscall_retval = linux_set_syscall_retval, .sv_fetch_syscall_args = linux_fetch_syscall_args, .sv_syscallnames = NULL, .sv_shared_page_base = LINUX_SHAREDPAGE, @@ -869,8 +880,6 @@ struct sysentvec elf_linux_sysvec = { .sv_size = LINUX_SYS_MAXSYSCALL, .sv_table = linux_sysent, - .sv_errsize = ELAST + 1, - .sv_errtbl = linux_errtbl, .sv_transtrap = linux_translate_traps, .sv_fixup = linux_fixup_elf, .sv_sendsig = linux_sendsig, @@ -891,7 +900,7 @@ .sv_fixlimit = NULL, .sv_maxssiz = NULL, .sv_flags = SV_ABI_LINUX | SV_IA32 | SV_ILP32 | SV_SHP, - .sv_set_syscall_retval = cpu_set_syscall_retval, + .sv_set_syscall_retval = linux_set_syscall_retval, .sv_fetch_syscall_args = linux_fetch_syscall_args, .sv_syscallnames = NULL, .sv_shared_page_base = LINUX_SHAREDPAGE, Index: sys/kern/imgact_aout.c =================================================================== --- sys/kern/imgact_aout.c +++ sys/kern/imgact_aout.c @@ -76,8 +76,6 @@ struct sysentvec aout_sysvec = { .sv_size = SYS_MAXSYSCALL, .sv_table = sysent, - .sv_errsize = 0, - .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = aout_fixup, .sv_sendsig = sendsig, @@ -117,8 +115,6 @@ struct sysentvec aout_sysvec = { .sv_size = FREEBSD32_SYS_MAXSYSCALL, .sv_table = freebsd32_sysent, - .sv_errsize = 0, - .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = aout_fixup, .sv_sendsig = ia32_sendsig, Index: sys/kern/init_main.c =================================================================== --- sys/kern/init_main.c +++ sys/kern/init_main.c @@ -403,8 +403,6 @@ struct sysentvec null_sysvec = { .sv_size = 0, .sv_table = NULL, - .sv_errsize = 0, - .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = NULL, .sv_sendsig = NULL, Index: sys/mips/mips/elf_machdep.c =================================================================== --- sys/mips/mips/elf_machdep.c +++ sys/mips/mips/elf_machdep.c @@ -54,8 +54,6 @@ static struct sysentvec elf_freebsd_sysvec = { .sv_size = SYS_MAXSYSCALL, .sv_table = sysent, - .sv_errsize = 0, - .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = __elfN(freebsd_fixup), .sv_sendsig = sendsig, Index: sys/mips/mips/freebsd32_machdep.c =================================================================== --- sys/mips/mips/freebsd32_machdep.c +++ sys/mips/mips/freebsd32_machdep.c @@ -77,8 +77,6 @@ struct sysentvec elf32_freebsd_sysvec = { .sv_size = SYS_MAXSYSCALL, .sv_table = freebsd32_sysent, - .sv_errsize = 0, - .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = __elfN(freebsd_fixup), .sv_sendsig = freebsd32_sendsig, Index: sys/powerpc/powerpc/elf32_machdep.c =================================================================== --- sys/powerpc/powerpc/elf32_machdep.c +++ sys/powerpc/powerpc/elf32_machdep.c @@ -90,8 +90,6 @@ #else .sv_table = sysent, #endif - .sv_errsize = 0, - .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = __elfN(freebsd_fixup), .sv_copyout_auxargs = __elfN(powerpc_copyout_auxargs), Index: sys/powerpc/powerpc/elf64_machdep.c =================================================================== --- sys/powerpc/powerpc/elf64_machdep.c +++ sys/powerpc/powerpc/elf64_machdep.c @@ -62,8 +62,6 @@ struct sysentvec elf64_freebsd_sysvec_v1 = { .sv_size = SYS_MAXSYSCALL, .sv_table = sysent, - .sv_errsize = 0, - .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = __elfN(freebsd_fixup), .sv_sendsig = sendsig, @@ -100,8 +98,6 @@ struct sysentvec elf64_freebsd_sysvec_v2 = { .sv_size = SYS_MAXSYSCALL, .sv_table = sysent, - .sv_errsize = 0, - .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = __elfN(freebsd_fixup), .sv_sendsig = sendsig, Index: sys/powerpc/powerpc/exec_machdep.c =================================================================== --- sys/powerpc/powerpc/exec_machdep.c +++ sys/powerpc/powerpc/exec_machdep.c @@ -955,7 +955,7 @@ tf->srr0 -= 4; break; default: - tf->fixreg[FIRSTARG] = SV_ABI_ERRNO(p, error); + tf->fixreg[FIRSTARG] = error; tf->cr |= 0x10000000; /* Set summary overflow */ break; } Index: sys/riscv/riscv/elf_machdep.c =================================================================== --- sys/riscv/riscv/elf_machdep.c +++ sys/riscv/riscv/elf_machdep.c @@ -65,8 +65,6 @@ struct sysentvec elf64_freebsd_sysvec = { .sv_size = SYS_MAXSYSCALL, .sv_table = sysent, - .sv_errsize = 0, - .sv_errtbl = NULL, .sv_transtrap = NULL, .sv_fixup = __elfN(freebsd_fixup), .sv_sendsig = sendsig, Index: sys/sys/sysent.h =================================================================== --- sys/sys/sysent.h +++ sys/sys/sysent.h @@ -102,8 +102,6 @@ struct sysentvec { int sv_size; /* number of entries */ struct sysent *sv_table; /* pointer to sysent */ - int sv_errsize; /* size of errno translation table */ - const int *sv_errtbl; /* errno translation table */ int (*sv_transtrap)(int, int); /* translate trap-to-signal mapping */ int (*sv_fixup)(uintptr_t *, struct image_params *); @@ -158,8 +156,6 @@ #define SV_ASLR 0x080000 /* ASLR allowed. */ #define SV_ABI_MASK 0xff -#define SV_ABI_ERRNO(p, e) ((p)->p_sysent->sv_errsize <= 0 ? e : \ - ((e) >= (p)->p_sysent->sv_errsize ? -1 : (p)->p_sysent->sv_errtbl[e])) #define SV_PROC_FLAG(p, x) ((p)->p_sysent->sv_flags & (x)) #define SV_PROC_ABI(p) ((p)->p_sysent->sv_flags & SV_ABI_MASK) #define SV_CURPROC_FLAG(x) SV_PROC_FLAG(curproc, x)