Browse Source

nios2: return -errno from INTERNAL_SYSCALL

nios2 reports syscall errors in r7 and the positive errno in r2, and the
arch header passed that flag out through the err parameter.  The generic
lowlevellock.h, however, hands the raw return value to its callers, which
read it as -errno: lll_futex_timed_wait() comparisons against
-EWOULDBLOCK and -ETIMEDOUT never matched, and sem_post() silently
swallowed errors.  Fold the flag into a negative return value in the asm,
like the kernel does for the arches that have no flag register, and let
the generic ERROR_P/ERRNO macros from syscalls-common.h do the rest.

The same conversion is due for the other arches that still hand the flag
back separately -- mips, alpha, ia64 and tile -- and for powerpc, where it
is the reason sem_wait() and sem_post() misread their return value.

Signed-off-by: Ramin Moussavi <lordrasmus@gmail.com>
ramin 3 days ago
parent
commit
523b4723b9
1 changed files with 2 additions and 11 deletions
  1. 2 11
      libc/sysdeps/linux/nios2/bits/syscalls.h

+ 2 - 11
libc/sysdeps/linux/nios2/bits/syscalls.h

@@ -24,15 +24,6 @@
 
 #include <errno.h>
 
-#undef INTERNAL_SYSCALL_DECL
-#define INTERNAL_SYSCALL_DECL(err) unsigned int err __attribute__((unused))
-
-#undef INTERNAL_SYSCALL_ERROR_P
-#define INTERNAL_SYSCALL_ERROR_P(val, err) ((void) (val), (unsigned int) (err))
-
-#undef INTERNAL_SYSCALL_ERRNO
-#define INTERNAL_SYSCALL_ERRNO(val, err)   ((void) (err), val)
-
 #undef INTERNAL_SYSCALL_NCS
 #define INTERNAL_SYSCALL_NCS(name, err, nr, args...)            \
   ({ unsigned int _sys_result;                                  \
@@ -45,8 +36,8 @@
                      : "+r" (_r2), "=r" (_sys_err)              \
                      : ASM_ARGS_##nr				\
                      : "memory");                               \
-       _sys_result = _r2;                                       \
-       err = _sys_err;						\
+       /* r7 signals the error; fold it into a negative return value.  */ \
+       _sys_result = _sys_err ? -_r2 : _r2;			\
      }                                                          \
      (int) _sys_result; })