All the *-users generally use the negative errno return codes to signal errno for a system call. FreeBSD's system calls, on the other hand, returns errno, not -errno. Add ifdefs for FreeBSD to make the adjustment on the 4 hosts that we have support for.
Signed-off-by: Warner Losh <i...@bsdimp.com> --- common-user/host/aarch64/safe-syscall.inc.S | 8 ++++++++ common-user/host/arm/safe-syscall.inc.S | 7 +++++++ common-user/host/i386/safe-syscall.inc.S | 9 +++++++++ common-user/host/x86_64/safe-syscall.inc.S | 9 +++++++++ 4 files changed, 33 insertions(+) diff --git a/common-user/host/aarch64/safe-syscall.inc.S b/common-user/host/aarch64/safe-syscall.inc.S index bc1f5a9792..9f9525fe25 100644 --- a/common-user/host/aarch64/safe-syscall.inc.S +++ b/common-user/host/aarch64/safe-syscall.inc.S @@ -64,6 +64,14 @@ safe_syscall_start: svc 0x0 safe_syscall_end: /* code path for having successfully executed the syscall */ +#ifdef __FreeBSD__ + /* + * FreeBSD kernel returns C bit set with positive errno. + * Encode this for use in bsd-user as -errno: + * x0 = !c ? x0 : -x0 + */ + csneg x0, x0, x0, cc +#endif ret 0: diff --git a/common-user/host/arm/safe-syscall.inc.S b/common-user/host/arm/safe-syscall.inc.S index 88c4958504..459e5f87c2 100644 --- a/common-user/host/arm/safe-syscall.inc.S +++ b/common-user/host/arm/safe-syscall.inc.S @@ -78,6 +78,13 @@ safe_syscall_start: swi 0 safe_syscall_end: /* code path for having successfully executed the syscall */ +#ifdef __FreeBSD__ + /* + * FreeBSD kernel returns C bit set with positive errno. + * Encode this for use in bsd-user as -errno: + */ + negcs r0, r0 +#endif pop { r4, r5, r6, r7, r8, pc } 1: diff --git a/common-user/host/i386/safe-syscall.inc.S b/common-user/host/i386/safe-syscall.inc.S index 9e58fc6504..ba55a35e92 100644 --- a/common-user/host/i386/safe-syscall.inc.S +++ b/common-user/host/i386/safe-syscall.inc.S @@ -75,6 +75,15 @@ safe_syscall_start: int $0x80 safe_syscall_end: /* code path for having successfully executed the syscall */ +#ifdef __FreeBSD__ + /* + * FreeBSD kernel returns C bit set with positive errno. + * Encode this for use in bsd-user as -errno: + */ + jnb 2f + neg %eax +2: +#endif pop %ebx .cfi_remember_state .cfi_adjust_cfa_offset -4 diff --git a/common-user/host/x86_64/safe-syscall.inc.S b/common-user/host/x86_64/safe-syscall.inc.S index f36992daa3..46c527e058 100644 --- a/common-user/host/x86_64/safe-syscall.inc.S +++ b/common-user/host/x86_64/safe-syscall.inc.S @@ -72,6 +72,15 @@ safe_syscall_start: syscall safe_syscall_end: /* code path for having successfully executed the syscall */ +#ifdef __FreeBSD__ + /* + * FreeBSD kernel returns C bit set with positive errno. + * Encode this for use in bsd-user as -errno: + */ + jnb 2f + neg %rax +2: +#endif pop %rbp .cfi_remember_state .cfi_def_cfa_offset 8 -- 2.33.0