[RFC v2 4/6] common-user: Adjust system call return on FreeBSD

Warner Losh posted 6 patches 4 years, 2 months ago
Maintainers: "Philippe Mathieu-Daudé" <f4bug@amsat.org>, Jiaxun Yang <jiaxun.yang@flygoat.com>, Laurent Vivier <laurent@vivier.eu>
There is a newer version of this series
[RFC v2 4/6] common-user: Adjust system call return on FreeBSD
Posted by Warner Losh 4 years, 2 months ago
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


Re: [RFC v2 4/6] common-user: Adjust system call return on FreeBSD
Posted by Richard Henderson 4 years, 2 months ago
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~

Re: [RFC v2 4/6] common-user: Adjust system call return on FreeBSD
Posted by Warner Losh 4 years, 2 months ago
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