On Tue, Nov 16, 2021 at 4:03 AM Richard Henderson < richard.hender...@linaro.org> wrote:
> From: Warner Losh <i...@bsdimp.com> > > FreeBSD system calls return positive errno. On the 4 hosts for > which we have support, error is indicated by the C bit set or clear. > > Signed-off-by: Warner Losh <i...@bsdimp.com> > [rth: Rebase on new safe_syscall_base api; add #error check.] > Signed-off-by: Richard Henderson <richard.hender...@linaro.org> > --- > common-user/host/aarch64/safe-syscall.inc.S | 12 +++++++++++- > common-user/host/arm/safe-syscall.inc.S | 11 +++++++++++ > common-user/host/i386/safe-syscall.inc.S | 10 ++++++++++ > common-user/host/x86_64/safe-syscall.inc.S | 10 ++++++++++ > 4 files changed, 42 insertions(+), 1 deletion(-) > > diff --git a/common-user/host/aarch64/safe-syscall.inc.S > b/common-user/host/aarch64/safe-syscall.inc.S > index 95c60d8609..d3f065cdef 100644 > --- a/common-user/host/aarch64/safe-syscall.inc.S > +++ b/common-user/host/aarch64/safe-syscall.inc.S > @@ -65,12 +65,22 @@ safe_syscall_start: > safe_syscall_end: > > /* code path for having successfully executed the syscall */ > - cmn x0, #4095 > +#if defined(__linux__) > + /* Linux kernel returns (small) negative errno. */ > + cmn x0, #4096 > + b.hi 0f > +#elif defined(__FreeBSD__) > + /* FreeBSD kernel returns positive errno and C bit set. */ > b.cs 1f > +#else > +#error "unsupported os" > +#endif > ret > > /* code path setting errno */ > +#ifdef __linux__ > 0: neg w0, w0 /* create positive errno */ > +#endif > 1: str w0, [x11] /* store errno */ > mov x0, #-1 > ret > diff --git a/common-user/host/arm/safe-syscall.inc.S > b/common-user/host/arm/safe-syscall.inc.S > index 17839c6486..328299021d 100644 > --- a/common-user/host/arm/safe-syscall.inc.S > +++ b/common-user/host/arm/safe-syscall.inc.S > @@ -82,12 +82,23 @@ safe_syscall_start: > safe_syscall_end: > > /* code path for having successfully executed the syscall */ > +#if defined(__linux__) > + /* Linux kernel returns (small) negative errno. */ > cmp r0, #-4096 > bhi 0f > +#elif defined(__FreeBSD__) > + /* FreeBSD kernel returns positive errno and C bit set. */ > + bcs 1f > +#else > +#error "unsupported os" > +#endif > + > 9: pop { r4, r5, r6, r7, r8, r9, r10, pc } > > /* code path setting errno */ > +#ifdef __linux__ > 0: neg r0, r0 /* create positive errno */ > +#endif > 1: str r0, [r9] /* store errno */ > mov r0, #-1 > b 9b > diff --git a/common-user/host/i386/safe-syscall.inc.S > b/common-user/host/i386/safe-syscall.inc.S > index ad89521783..a9382f777e 100644 > --- a/common-user/host/i386/safe-syscall.inc.S > +++ b/common-user/host/i386/safe-syscall.inc.S > @@ -76,8 +76,16 @@ safe_syscall_start: > safe_syscall_end: > > /* code path for having successfully executed the syscall */ > +#if defined(__linux__) > + /* Linux kernel returns (small) negative errno. */ > cmp $-4095, %eax > jae 0f > +#elif defined(__FreeBSD__) > + /* FreeBSD kernel returns positive errno and C bit set. */ > + jcs 1f > I needed to change this to 'jc' and that's all google found for Intel. +#else > +#error "unsupported os" > +#endif > > 9: pop %ebx > .cfi_remember_state > @@ -97,7 +105,9 @@ safe_syscall_end: > .cfi_restore_state > > /* code path setting errno */ > +#ifdef __linux__ > 0: neg %eax /* create positive errno */ > +#endif > 1: mov 8+16(%esp), %ebx /* load errno pointer */ > mov %eax, (%ebx) /* store errno */ > mov $-1, %eax > diff --git a/common-user/host/x86_64/safe-syscall.inc.S > b/common-user/host/x86_64/safe-syscall.inc.S > index 9a0c4c93b4..36b7efe2ca 100644 > --- a/common-user/host/x86_64/safe-syscall.inc.S > +++ b/common-user/host/x86_64/safe-syscall.inc.S > @@ -75,8 +75,16 @@ safe_syscall_start: > safe_syscall_end: > > /* code path for having successfully executed the syscall */ > +#if defined(__linux__) > + /* Linux kernel returns (small) negative errno. */ > cmp $-4095, %rax > jae 0f > +#elif defined(__FreeBSD__) > + /* FreeBSD kernel returns positive errno and C bit set. */ > + jcs 1f > Likewise. > +#else > +#error "unsupported os" > +#endif > > 9: pop %rbp > .cfi_remember_state > @@ -86,7 +94,9 @@ safe_syscall_end: > .cfi_restore_state > > /* code path setting errno */ > +#ifdef __linux__ > 0: neg %eax /* create positive errno */ > +#endif > 1: mov %eax, (%rbp) /* store errno */ > mov $-1, %rax > jmp 9b > I've not yet tested this on my arm/aarch64 systems, but I think it will work there. Warner