All the *-users generally use the Linux style of negative return codes
for errno. FreeBSD 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 <imp@bsdimp.com>
---
common-user/host/aarch64/safe-syscall.inc.S | 5 +++++
common-user/host/arm/safe-syscall.inc.S | 5 +++++
common-user/host/i386/safe-syscall.inc.S | 5 +++++
common-user/host/x86_64/safe-syscall.inc.S | 5 +++++
4 files changed, 20 insertions(+)
diff --git a/common-user/host/aarch64/safe-syscall.inc.S b/common-user/host/aarch64/safe-syscall.inc.S
index bc1f5a9792..6584950ccf 100644
--- a/common-user/host/aarch64/safe-syscall.inc.S
+++ b/common-user/host/aarch64/safe-syscall.inc.S
@@ -64,6 +64,11 @@ safe_syscall_start:
svc 0x0
safe_syscall_end:
/* code path for having successfully executed the syscall */
+#ifdef __FreeBSD__
+ b.cc 2f /* Convert to Linux -ERRNO convention */
+ neg x0, x0
+2:
+#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..85c47387f9 100644
--- a/common-user/host/arm/safe-syscall.inc.S
+++ b/common-user/host/arm/safe-syscall.inc.S
@@ -78,6 +78,11 @@ safe_syscall_start:
swi 0
safe_syscall_end:
/* code path for having successfully executed the syscall */
+#ifdef __FreeBSD__
+ bcc 2f
+ neg r0, r0
+2:
+#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..7bb6a98a8b 100644
--- a/common-user/host/i386/safe-syscall.inc.S
+++ b/common-user/host/i386/safe-syscall.inc.S
@@ -75,6 +75,11 @@ safe_syscall_start:
int $0x80
safe_syscall_end:
/* code path for having successfully executed the syscall */
+#ifdef __FreeBSD__
+ jnb 2f /* Convert to Linux -ERRNO convention */
+ 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..7d8792c7ef 100644
--- a/common-user/host/x86_64/safe-syscall.inc.S
+++ b/common-user/host/x86_64/safe-syscall.inc.S
@@ -72,6 +72,11 @@ safe_syscall_start:
syscall
safe_syscall_end:
/* code path for having successfully executed the syscall */
+#ifdef __FreeBSD__
+ jnb 2f /* Convert to Linux -ERRNO convention */
+ neg %rax
+2:
+#endif
pop %rbp
.cfi_remember_state
.cfi_def_cfa_offset 8
--
2.33.0
On 11/10/21 5:31 PM, Warner Losh wrote:
> All the *-users generally use the Linux style of negative return codes
> for errno. FreeBSD 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 <imp@bsdimp.com>
> ---
> common-user/host/aarch64/safe-syscall.inc.S | 5 +++++
> common-user/host/arm/safe-syscall.inc.S | 5 +++++
> common-user/host/i386/safe-syscall.inc.S | 5 +++++
> common-user/host/x86_64/safe-syscall.inc.S | 5 +++++
> 4 files changed, 20 insertions(+)
>
> diff --git a/common-user/host/aarch64/safe-syscall.inc.S b/common-user/host/aarch64/safe-syscall.inc.S
> index bc1f5a9792..6584950ccf 100644
> --- a/common-user/host/aarch64/safe-syscall.inc.S
> +++ b/common-user/host/aarch64/safe-syscall.inc.S
> @@ -64,6 +64,11 @@ safe_syscall_start:
> svc 0x0
> safe_syscall_end:
> /* code path for having successfully executed the syscall */
> +#ifdef __FreeBSD__
> + b.cc 2f /* Convert to Linux -ERRNO convention */
> + neg x0, x0
> +2:
> +#endif
I think it should be a little odd to mention Linux.
How about
/*
* 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
> +++ b/common-user/host/arm/safe-syscall.inc.S
> @@ -78,6 +78,11 @@ safe_syscall_start:
> swi 0
> safe_syscall_end:
> /* code path for having successfully executed the syscall */
> +#ifdef __FreeBSD__
> + bcc 2f
> + neg r0, r0
negcs r0, r0
I just can't help myself. :-)
r~
On Wed, Nov 10, 2021 at 9:59 AM Richard Henderson < richard.henderson@linaro.org> wrote: > On 11/10/21 5:31 PM, Warner Losh wrote: > > All the *-users generally use the Linux style of negative return codes > > for errno. FreeBSD 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 <imp@bsdimp.com> > > --- > > common-user/host/aarch64/safe-syscall.inc.S | 5 +++++ > > common-user/host/arm/safe-syscall.inc.S | 5 +++++ > > common-user/host/i386/safe-syscall.inc.S | 5 +++++ > > common-user/host/x86_64/safe-syscall.inc.S | 5 +++++ > > 4 files changed, 20 insertions(+) > > > > diff --git a/common-user/host/aarch64/safe-syscall.inc.S > b/common-user/host/aarch64/safe-syscall.inc.S > > index bc1f5a9792..6584950ccf 100644 > > --- a/common-user/host/aarch64/safe-syscall.inc.S > > +++ b/common-user/host/aarch64/safe-syscall.inc.S > > @@ -64,6 +64,11 @@ safe_syscall_start: > > svc 0x0 > > safe_syscall_end: > > /* code path for having successfully executed the syscall */ > > +#ifdef __FreeBSD__ > > + b.cc 2f /* Convert to Linux -ERRNO convention */ > > + neg x0, x0 > > +2: > > +#endif > > I think it should be a little odd to mention Linux. > Yea, from my view of hacking on Unix and Unix-derived systems for the last 30 years, Linux is the outlier in returning -errno. However, the 'norms' have shifted, I guess, so I'm happy with your suggestion... > How about > > /* > * 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 > Ah, better assembler. Good! > > > +++ b/common-user/host/arm/safe-syscall.inc.S > > @@ -78,6 +78,11 @@ safe_syscall_start: > > swi 0 > > safe_syscall_end: > > /* code path for having successfully executed the syscall */ > > +#ifdef __FreeBSD__ > > + bcc 2f > > + neg r0, r0 > > negcs r0, r0 > > I just can't help myself. :-) I can relate... Really :) I'll rework and resend in the next round. Warner
© 2016 - 2026 Red Hat, Inc.