Skip to content

Commit 556fb71

Browse files
committed
tools/nolibc: avoid undesired casts in the __sysret() macro
Having __sysret() as an inline function has the unfortunate effect of adding casts and large constants comparisons after the syscall returns that significantly inflate some light code that's otherwise syscall- heavy. Even nolibc-test grew by ~1%. Let's switch back to a macro for this, and use it only with signed arguments. Note that it is also possible to design a slightly more complex macro covering unsigned and pointers but we only have 3 such syscalls so it is pointless, and these were just addressed not to use this macro anymore. Now for the argument (the local variable containing the syscall return value), any negative value is an error, that results in -1 being returned and errno to be assigned the opposite value. This may be revisited again in the future if really needed but for now let's get back to something sane. Fixes: 428905d ("tools/nolibc: sys.h: add a syscall return helper") Link: https://lore.kernel.org/lkml/[email protected]/ Link: https://lore.kernel.org/lkml/[email protected]/ Cc: Zhangjin Wu <[email protected]> Cc: David Laight <[email protected]> Cc: Thomas Weißschuh <[email protected]> Signed-off-by: Willy Tarreau <[email protected]>
1 parent fb01ff6 commit 556fb71

File tree

1 file changed

+13
-14
lines changed
  • tools/include/nolibc

1 file changed

+13
-14
lines changed

tools/include/nolibc/sys.h

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,21 @@
2828
#include "types.h"
2929

3030

31-
/* Syscall return helper for library routines, set errno as -ret when ret is in
32-
* range of [-MAX_ERRNO, -1]
33-
*
34-
* Note, No official reference states the errno range here aligns with musl
35-
* (src/internal/syscall_ret.c) and glibc (sysdeps/unix/sysv/linux/sysdep.h)
31+
/* Syscall return helper: takes the syscall value in argument and checks for an
32+
* error in it. This may only be used with signed returns (int or long), but
33+
* not with pointers. An error is any value < 0. When an error is encountered,
34+
* -ret is set into errno and -1 is returned. Otherwise the returned value is
35+
* passed as-is with its type preserved.
3636
*/
3737

38-
static __inline__ __attribute__((unused, always_inline))
39-
long __sysret(unsigned long ret)
40-
{
41-
if (ret >= (unsigned long)-MAX_ERRNO) {
42-
SET_ERRNO(-(long)ret);
43-
return -1;
44-
}
45-
return ret;
46-
}
38+
#define __sysret(arg) \
39+
({ \
40+
__typeof__(arg) __sysret_arg = (arg); \
41+
(__sysret_arg < 0) /* error ? */ \
42+
? (({ SET_ERRNO(-__sysret_arg); }), -1) /* ret -1 with errno = -arg */ \
43+
: __sysret_arg; /* return original value */ \
44+
})
45+
4746

4847
/* Functions in this file only describe syscalls. They're declared static so
4948
* that the compiler usually decides to inline them while still being allowed

0 commit comments

Comments
 (0)