linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 00/10] tools/nolibc: add a new syscall helper
@ 2023-06-19 15:40 Zhangjin Wu
  2023-06-19 15:41 ` [PATCH v4 01/10] tools/nolibc: sys.h: add a syscall return helper Zhangjin Wu
                   ` (10 more replies)
  0 siblings, 11 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-19 15:40 UTC (permalink / raw)
  To: w
  Cc: david.laight, arnd, falcon, linux-kernel, linux-kselftest,
	linux-riscv, thomas

Hi, Thomas, David, Willy

Thanks very much for your kindly review.

This is the revision of v3 "tools/nolibc: add a new syscall helper" [1],
this mainly applies the suggestion from David in this reply [2] and
rebased everything on the dev.2023.06.14a branch of linux-rcu [3].

The old __sysret() doesn't support the syscalls with pointer return
value, this revision now supports such syscalls. The left mmap() syscall
is converted to use this new __sysret() with additional test cases.

Changes from v3 -> v4:

* tools/nolibc: sys.h: add a syscall return helper
  tools/nolibc: unistd.h: apply __sysret() helper
  tools/nolibc: sys.h: apply __sysret() helper

  The original v3 series, no code change, except the Reviewed-by lines
  from Thomas.

* tools/nolibc: unistd.h: reorder the syscall macros

  reorder the syscall macros in using order and align most of them.

* tools/nolibc: add missing my_syscall6() for mips

  required by mmap() syscall, this is the last missing my_syscall6().

* tools/nolibc: __sysret: support syscalls who return a pointer

  Apply suggestion from David.  

  Let __sysret() also supports syscalls with pointer return value, so, the
  return value is converted to unsigned long and the comparing of < 0 is
  converted to the comparing of [(unsigned long)-MAX_ERRNO, (unsigned long)-1].

  This also allows return a huge value (not pointer) with highest bit as 1.

  It is able to merge this one to the first one if necessary.

* tools/nolibc: clean up mmap() support

  Apply new __sysret(), clean up #ifdef and some macros.

* selftests/nolibc: add EXPECT_PTREQ, EXPECT_PTRNE and EXPECT_PTRER
  selftests/nolibc: add sbrk_0 to test current brk getting
  selftests/nolibc: add mmap and munmap test cases

  Add some mmap & munmap test cases and the corresponding helpers, to
  verify one of the new helpers, a sbrk_0 test case is also added.

Best regards,
Zhangjin
---
[1]: https://lore.kernel.org/linux-riscv/87e7a391-b97b-4001-b12a-76d20790563e@t-8ch.de/
[2]: https://lore.kernel.org/linux-riscv/94dd5170929f454fbc0a10a2eb3b108d@AcuMS.aculab.com/
[3]: https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git/

Zhangjin Wu (10):
  tools/nolibc: sys.h: add a syscall return helper
  tools/nolibc: unistd.h: apply __sysret() helper
  tools/nolibc: sys.h: apply __sysret() helper
  tools/nolibc: unistd.h: reorder the syscall macros
  tools/nolibc: add missing my_syscall6() for mips
  tools/nolibc: __sysret: support syscalls who return a pointer
  tools/nolibc: clean up mmap() support
  selftests/nolibc: add EXPECT_PTREQ, EXPECT_PTRNE and EXPECT_PTRER
  selftests/nolibc: add sbrk_0 to test current brk getting
  selftests/nolibc: add mmap and munmap test cases

 tools/include/nolibc/arch-mips.h             |  26 ++
 tools/include/nolibc/nolibc.h                |   9 +-
 tools/include/nolibc/sys.h                   | 391 +++----------------
 tools/include/nolibc/types.h                 |  11 +
 tools/include/nolibc/unistd.h                |  13 +-
 tools/testing/selftests/nolibc/nolibc-test.c |  90 +++++
 6 files changed, 191 insertions(+), 349 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v4 01/10] tools/nolibc: sys.h: add a syscall return helper
  2023-06-19 15:40 [PATCH v4 00/10] tools/nolibc: add a new syscall helper Zhangjin Wu
@ 2023-06-19 15:41 ` Zhangjin Wu
  2023-06-19 15:42 ` [PATCH v4 02/10] tools/nolibc: unistd.h: apply __sysret() helper Zhangjin Wu
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-19 15:41 UTC (permalink / raw)
  To: w
  Cc: david.laight, arnd, falcon, linux-kernel, linux-kselftest,
	linux-riscv, thomas, Thomas Weißschuh

Most of the library routines share the same syscall return logic:

  In general, a 0 return value indicates success.  A -1 return value
  indicates an error, and an error number is stored in errno. [1]

Let's add a __sysret() helper for the above logic to simplify the coding
and shrink the code lines too.

Thomas suggested to use inline function instead of macro for __sysret().

Willy suggested to make __sysret() be always inline.

[1]: https://man7.org/linux/man-pages/man2/syscall.2.html

Suggested-by: Willy Tarreau <w@1wt.eu>
Link: https://lore.kernel.org/linux-riscv/ZH1+hkhiA2+ItSvX@1wt.eu/
Suggested-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://lore.kernel.org/linux-riscv/ea4e7442-7223-4211-ba29-70821e907888@t-8ch.de/
Reviewed-by: Thomas Weißschuh <linux@weissschuh.net>
Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/sys.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index 856249a11890..150777207468 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -28,6 +28,16 @@
 #include "errno.h"
 #include "types.h"
 
+/* Syscall return helper, set errno as -ret when ret < 0 */
+static __inline__ __attribute__((unused, always_inline))
+long __sysret(long ret)
+{
+	if (ret < 0) {
+		SET_ERRNO(-ret);
+		ret = -1;
+	}
+	return ret;
+}
 
 /* Functions in this file only describe syscalls. They're declared static so
  * that the compiler usually decides to inline them while still being allowed
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v4 02/10] tools/nolibc: unistd.h: apply __sysret() helper
  2023-06-19 15:40 [PATCH v4 00/10] tools/nolibc: add a new syscall helper Zhangjin Wu
  2023-06-19 15:41 ` [PATCH v4 01/10] tools/nolibc: sys.h: add a syscall return helper Zhangjin Wu
@ 2023-06-19 15:42 ` Zhangjin Wu
  2023-06-19 15:44 ` [PATCH v4 03/10] tools/nolibc: sys.h: " Zhangjin Wu
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-19 15:42 UTC (permalink / raw)
  To: w
  Cc: david.laight, arnd, falcon, linux-kernel, linux-kselftest,
	linux-riscv, thomas, Thomas Weißschuh

Use __sysret() to shrink the whole _syscall() to oneline code.

Reviewed-by: Thomas Weißschuh <linux@weissschuh.net>
Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/unistd.h | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/tools/include/nolibc/unistd.h b/tools/include/nolibc/unistd.h
index 0e832e10a0b2..fabc846f797b 100644
--- a/tools/include/nolibc/unistd.h
+++ b/tools/include/nolibc/unistd.h
@@ -56,16 +56,7 @@ int tcsetpgrp(int fd, pid_t pid)
 	return ioctl(fd, TIOCSPGRP, &pid);
 }
 
-#define _syscall(N, ...)                                                      \
-({                                                                            \
-	long _ret = my_syscall##N(__VA_ARGS__);                               \
-	if (_ret < 0) {                                                       \
-		SET_ERRNO(-_ret);                                             \
-		_ret = -1;                                                    \
-	}                                                                     \
-	_ret;                                                                 \
-})
-
+#define _syscall(N, ...) __sysret(my_syscall##N(__VA_ARGS__))
 #define _syscall_narg(...) __syscall_narg(__VA_ARGS__, 6, 5, 4, 3, 2, 1, 0)
 #define __syscall_narg(_0, _1, _2, _3, _4, _5, _6, N, ...) N
 #define _syscall_n(N, ...) _syscall(N, __VA_ARGS__)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v4 03/10] tools/nolibc: sys.h: apply __sysret() helper
  2023-06-19 15:40 [PATCH v4 00/10] tools/nolibc: add a new syscall helper Zhangjin Wu
  2023-06-19 15:41 ` [PATCH v4 01/10] tools/nolibc: sys.h: add a syscall return helper Zhangjin Wu
  2023-06-19 15:42 ` [PATCH v4 02/10] tools/nolibc: unistd.h: apply __sysret() helper Zhangjin Wu
@ 2023-06-19 15:44 ` Zhangjin Wu
  2023-06-19 15:45 ` [PATCH v4 04/10] tools/nolibc: unistd.h: reorder the syscall macros Zhangjin Wu
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-19 15:44 UTC (permalink / raw)
  To: w
  Cc: david.laight, arnd, falcon, linux-kernel, linux-kselftest,
	linux-riscv, thomas, Thomas Weißschuh

Use __sysret() to shrink most of the library routines to oneline code.

Removed 266 lines of duplicated code.

Reviewed-by: Thomas Weißschuh <linux@weissschuh.net>
Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/sys.h | 354 +++++--------------------------------
 1 file changed, 44 insertions(+), 310 deletions(-)

diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index 150777207468..4fbefe5adf93 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -76,13 +76,7 @@ void *sys_brk(void *addr)
 static __attribute__((unused))
 int brk(void *addr)
 {
-	void *ret = sys_brk(addr);
-
-	if (!ret) {
-		SET_ERRNO(ENOMEM);
-		return -1;
-	}
-	return 0;
+	return __sysret(sys_brk(addr) ? 0 : -ENOMEM);
 }
 
 static __attribute__((unused))
@@ -112,13 +106,7 @@ int sys_chdir(const char *path)
 static __attribute__((unused))
 int chdir(const char *path)
 {
-	int ret = sys_chdir(path);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_chdir(path));
 }
 
 
@@ -141,13 +129,7 @@ int sys_chmod(const char *path, mode_t mode)
 static __attribute__((unused))
 int chmod(const char *path, mode_t mode)
 {
-	int ret = sys_chmod(path, mode);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_chmod(path, mode));
 }
 
 
@@ -170,13 +152,7 @@ int sys_chown(const char *path, uid_t owner, gid_t group)
 static __attribute__((unused))
 int chown(const char *path, uid_t owner, gid_t group)
 {
-	int ret = sys_chown(path, owner, group);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_chown(path, owner, group));
 }
 
 
@@ -193,13 +169,7 @@ int sys_chroot(const char *path)
 static __attribute__((unused))
 int chroot(const char *path)
 {
-	int ret = sys_chroot(path);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_chroot(path));
 }
 
 
@@ -216,13 +186,7 @@ int sys_close(int fd)
 static __attribute__((unused))
 int close(int fd)
 {
-	int ret = sys_close(fd);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_close(fd));
 }
 
 
@@ -239,13 +203,7 @@ int sys_dup(int fd)
 static __attribute__((unused))
 int dup(int fd)
 {
-	int ret = sys_dup(fd);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_dup(fd));
 }
 
 
@@ -268,13 +226,7 @@ int sys_dup2(int old, int new)
 static __attribute__((unused))
 int dup2(int old, int new)
 {
-	int ret = sys_dup2(old, new);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_dup2(old, new));
 }
 
 
@@ -292,13 +244,7 @@ int sys_dup3(int old, int new, int flags)
 static __attribute__((unused))
 int dup3(int old, int new, int flags)
 {
-	int ret = sys_dup3(old, new, flags);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_dup3(old, new, flags));
 }
 #endif
 
@@ -316,13 +262,7 @@ int sys_execve(const char *filename, char *const argv[], char *const envp[])
 static __attribute__((unused))
 int execve(const char *filename, char *const argv[], char *const envp[])
 {
-	int ret = sys_execve(filename, argv, envp);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_execve(filename, argv, envp));
 }
 
 
@@ -369,13 +309,7 @@ pid_t sys_fork(void)
 static __attribute__((unused))
 pid_t fork(void)
 {
-	pid_t ret = sys_fork();
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_fork());
 }
 
 
@@ -392,13 +326,7 @@ int sys_fsync(int fd)
 static __attribute__((unused))
 int fsync(int fd)
 {
-	int ret = sys_fsync(fd);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_fsync(fd));
 }
 
 
@@ -415,13 +343,7 @@ int sys_getdents64(int fd, struct linux_dirent64 *dirp, int count)
 static __attribute__((unused))
 int getdents64(int fd, struct linux_dirent64 *dirp, int count)
 {
-	int ret = sys_getdents64(fd, dirp, count);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_getdents64(fd, dirp, count));
 }
 
 
@@ -459,13 +381,7 @@ pid_t sys_getpgid(pid_t pid)
 static __attribute__((unused))
 pid_t getpgid(pid_t pid)
 {
-	pid_t ret = sys_getpgid(pid);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_getpgid(pid));
 }
 
 
@@ -545,15 +461,7 @@ static unsigned long getauxval(unsigned long key);
 static __attribute__((unused))
 long getpagesize(void)
 {
-	long ret;
-
-	ret = getauxval(AT_PAGESZ);
-	if (!ret) {
-		SET_ERRNO(ENOENT);
-		return -1;
-	}
-
-	return ret;
+	return __sysret(getauxval(AT_PAGESZ) ?: -ENOENT);
 }
 
 
@@ -570,13 +478,7 @@ int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
 static __attribute__((unused))
 int gettimeofday(struct timeval *tv, struct timezone *tz)
 {
-	int ret = sys_gettimeofday(tv, tz);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_gettimeofday(tv, tz));
 }
 
 
@@ -614,13 +516,7 @@ int sys_ioctl(int fd, unsigned long req, void *value)
 static __attribute__((unused))
 int ioctl(int fd, unsigned long req, void *value)
 {
-	int ret = sys_ioctl(fd, req, value);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_ioctl(fd, req, value));
 }
 
 /*
@@ -636,13 +532,7 @@ int sys_kill(pid_t pid, int signal)
 static __attribute__((unused))
 int kill(pid_t pid, int signal)
 {
-	int ret = sys_kill(pid, signal);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_kill(pid, signal));
 }
 
 
@@ -665,13 +555,7 @@ int sys_link(const char *old, const char *new)
 static __attribute__((unused))
 int link(const char *old, const char *new)
 {
-	int ret = sys_link(old, new);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_link(old, new));
 }
 
 
@@ -688,13 +572,7 @@ off_t sys_lseek(int fd, off_t offset, int whence)
 static __attribute__((unused))
 off_t lseek(int fd, off_t offset, int whence)
 {
-	off_t ret = sys_lseek(fd, offset, whence);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_lseek(fd, offset, whence));
 }
 
 
@@ -717,13 +595,7 @@ int sys_mkdir(const char *path, mode_t mode)
 static __attribute__((unused))
 int mkdir(const char *path, mode_t mode)
 {
-	int ret = sys_mkdir(path, mode);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_mkdir(path, mode));
 }
 
 
@@ -746,13 +618,7 @@ long sys_mknod(const char *path, mode_t mode, dev_t dev)
 static __attribute__((unused))
 int mknod(const char *path, mode_t mode, dev_t dev)
 {
-	int ret = sys_mknod(path, mode, dev);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_mknod(path, mode, dev));
 }
 
 #ifndef MAP_SHARED
@@ -810,13 +676,7 @@ int sys_munmap(void *addr, size_t length)
 static __attribute__((unused))
 int munmap(void *addr, size_t length)
 {
-	int ret = sys_munmap(addr, length);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_munmap(addr, length));
 }
 
 /*
@@ -836,13 +696,7 @@ int mount(const char *src, const char *tgt,
           const char *fst, unsigned long flags,
           const void *data)
 {
-	int ret = sys_mount(src, tgt, fst, flags, data);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_mount(src, tgt, fst, flags, data));
 }
 
 
@@ -876,13 +730,7 @@ int open(const char *path, int flags, ...)
 		va_end(args);
 	}
 
-	ret = sys_open(path, flags, mode);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_open(path, flags, mode));
 }
 
 
@@ -902,13 +750,7 @@ static __attribute__((unused))
 int prctl(int option, unsigned long arg2, unsigned long arg3,
 		      unsigned long arg4, unsigned long arg5)
 {
-	int ret = sys_prctl(option, arg2, arg3, arg4, arg5);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_prctl(option, arg2, arg3, arg4, arg5));
 }
 
 
@@ -925,13 +767,7 @@ int sys_pivot_root(const char *new, const char *old)
 static __attribute__((unused))
 int pivot_root(const char *new, const char *old)
 {
-	int ret = sys_pivot_root(new, old);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_pivot_root(new, old));
 }
 
 
@@ -960,13 +796,7 @@ int sys_poll(struct pollfd *fds, int nfds, int timeout)
 static __attribute__((unused))
 int poll(struct pollfd *fds, int nfds, int timeout)
 {
-	int ret = sys_poll(fds, nfds, timeout);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_poll(fds, nfds, timeout));
 }
 
 
@@ -983,13 +813,7 @@ ssize_t sys_read(int fd, void *buf, size_t count)
 static __attribute__((unused))
 ssize_t read(int fd, void *buf, size_t count)
 {
-	ssize_t ret = sys_read(fd, buf, count);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_read(fd, buf, count));
 }
 
 
@@ -1007,13 +831,7 @@ ssize_t sys_reboot(int magic1, int magic2, int cmd, void *arg)
 static __attribute__((unused))
 int reboot(int cmd)
 {
-	int ret = sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, 0);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, 0));
 }
 
 
@@ -1030,13 +848,7 @@ int sys_sched_yield(void)
 static __attribute__((unused))
 int sched_yield(void)
 {
-	int ret = sys_sched_yield();
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_sched_yield());
 }
 
 
@@ -1076,13 +888,7 @@ int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeva
 static __attribute__((unused))
 int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout)
 {
-	int ret = sys_select(nfds, rfds, wfds, efds, timeout);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_select(nfds, rfds, wfds, efds, timeout));
 }
 
 
@@ -1099,13 +905,7 @@ int sys_setpgid(pid_t pid, pid_t pgid)
 static __attribute__((unused))
 int setpgid(pid_t pid, pid_t pgid)
 {
-	int ret = sys_setpgid(pid, pgid);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_setpgid(pid, pgid));
 }
 
 
@@ -1122,13 +922,7 @@ pid_t sys_setsid(void)
 static __attribute__((unused))
 pid_t setsid(void)
 {
-	pid_t ret = sys_setsid();
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_setsid());
 }
 
 #if defined(__NR_statx)
@@ -1145,13 +939,7 @@ int sys_statx(int fd, const char *path, int flags, unsigned int mask, struct sta
 static __attribute__((unused))
 int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
 {
-	int ret = sys_statx(fd, path, flags, mask, buf);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_statx(fd, path, flags, mask, buf));
 }
 #endif
 
@@ -1231,13 +1019,7 @@ int sys_stat(const char *path, struct stat *buf)
 static __attribute__((unused))
 int stat(const char *path, struct stat *buf)
 {
-	int ret = sys_stat(path, buf);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_stat(path, buf));
 }
 
 
@@ -1260,13 +1042,7 @@ int sys_symlink(const char *old, const char *new)
 static __attribute__((unused))
 int symlink(const char *old, const char *new)
 {
-	int ret = sys_symlink(old, new);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_symlink(old, new));
 }
 
 
@@ -1300,13 +1076,7 @@ int sys_umount2(const char *path, int flags)
 static __attribute__((unused))
 int umount2(const char *path, int flags)
 {
-	int ret = sys_umount2(path, flags);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_umount2(path, flags));
 }
 
 
@@ -1329,13 +1099,7 @@ int sys_unlink(const char *path)
 static __attribute__((unused))
 int unlink(const char *path)
 {
-	int ret = sys_unlink(path);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_unlink(path));
 }
 
 
@@ -1354,38 +1118,20 @@ pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage)
 static __attribute__((unused))
 pid_t wait(int *status)
 {
-	pid_t ret = sys_wait4(-1, status, 0, NULL);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_wait4(-1, status, 0, NULL));
 }
 
 static __attribute__((unused))
 pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage)
 {
-	pid_t ret = sys_wait4(pid, status, options, rusage);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_wait4(pid, status, options, rusage));
 }
 
 
 static __attribute__((unused))
 pid_t waitpid(pid_t pid, int *status, int options)
 {
-	pid_t ret = sys_wait4(pid, status, options, NULL);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_wait4(pid, status, options, NULL));
 }
 
 
@@ -1402,13 +1148,7 @@ ssize_t sys_write(int fd, const void *buf, size_t count)
 static __attribute__((unused))
 ssize_t write(int fd, const void *buf, size_t count)
 {
-	ssize_t ret = sys_write(fd, buf, count);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_write(fd, buf, count));
 }
 
 
@@ -1425,13 +1165,7 @@ int sys_memfd_create(const char *name, unsigned int flags)
 static __attribute__((unused))
 int memfd_create(const char *name, unsigned int flags)
 {
-	ssize_t ret = sys_memfd_create(name, flags);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_memfd_create(name, flags));
 }
 
 /* make sure to include all global symbols */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v4 04/10] tools/nolibc: unistd.h: reorder the syscall macros
  2023-06-19 15:40 [PATCH v4 00/10] tools/nolibc: add a new syscall helper Zhangjin Wu
                   ` (2 preceding siblings ...)
  2023-06-19 15:44 ` [PATCH v4 03/10] tools/nolibc: sys.h: " Zhangjin Wu
@ 2023-06-19 15:45 ` Zhangjin Wu
  2023-06-19 15:47 ` [PATCH v4 05/10] tools/nolibc: add missing my_syscall6() for mips Zhangjin Wu
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-19 15:45 UTC (permalink / raw)
  To: w
  Cc: david.laight, arnd, falcon, linux-kernel, linux-kselftest,
	linux-riscv, thomas

Tune the macros in the using order and align most of them.

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/unistd.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/include/nolibc/unistd.h b/tools/include/nolibc/unistd.h
index fabc846f797b..e38f3660c051 100644
--- a/tools/include/nolibc/unistd.h
+++ b/tools/include/nolibc/unistd.h
@@ -56,9 +56,9 @@ int tcsetpgrp(int fd, pid_t pid)
 	return ioctl(fd, TIOCSPGRP, &pid);
 }
 
-#define _syscall(N, ...) __sysret(my_syscall##N(__VA_ARGS__))
-#define _syscall_narg(...) __syscall_narg(__VA_ARGS__, 6, 5, 4, 3, 2, 1, 0)
 #define __syscall_narg(_0, _1, _2, _3, _4, _5, _6, N, ...) N
+#define _syscall_narg(...) __syscall_narg(__VA_ARGS__, 6, 5, 4, 3, 2, 1, 0)
+#define _syscall(N, ...) __sysret(my_syscall##N(__VA_ARGS__))
 #define _syscall_n(N, ...) _syscall(N, __VA_ARGS__)
 #define syscall(...) _syscall_n(_syscall_narg(__VA_ARGS__), ##__VA_ARGS__)
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v4 05/10] tools/nolibc: add missing my_syscall6() for mips
  2023-06-19 15:40 [PATCH v4 00/10] tools/nolibc: add a new syscall helper Zhangjin Wu
                   ` (3 preceding siblings ...)
  2023-06-19 15:45 ` [PATCH v4 04/10] tools/nolibc: unistd.h: reorder the syscall macros Zhangjin Wu
@ 2023-06-19 15:47 ` Zhangjin Wu
  2023-06-19 15:48 ` [PATCH v4 06/10] tools/nolibc: __sysret: support syscalls who return a pointer Zhangjin Wu
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-19 15:47 UTC (permalink / raw)
  To: w
  Cc: david.laight, arnd, falcon, linux-kernel, linux-kselftest,
	linux-riscv, thomas

It is able to pass the 6th argument like the 5th argument via the stack
for mips, let's add a new my_syscall6() now, see [1] for details:

  The mips/o32 system call convention passes arguments 5 through 8 on
  the user stack.

Both mmap() and pselect6() require my_syscall6().

[1]: https://man7.org/linux/man-pages/man2/syscall.2.html

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/arch-mips.h | 26 ++++++++++++++++++++++++++
 tools/include/nolibc/nolibc.h    |  9 ++++-----
 2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/tools/include/nolibc/arch-mips.h b/tools/include/nolibc/arch-mips.h
index db24e0837a39..48dd42b4abc3 100644
--- a/tools/include/nolibc/arch-mips.h
+++ b/tools/include/nolibc/arch-mips.h
@@ -178,6 +178,32 @@ struct sys_stat_struct {
 	_arg4 ? -_num : _num;                                                 \
 })
 
+#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \
+({                                                                            \
+	register long _num __asm__ ("v0") = (num);                            \
+	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
+	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
+	register long _arg3 __asm__ ("a2") = (long)(arg3);                    \
+	register long _arg4 __asm__ ("a3") = (long)(arg4);                    \
+	register long _arg5 = (long)(arg5);                                   \
+	register long _arg6 = (long)(arg6);                                   \
+	                                                                      \
+	__asm__  volatile (                                                   \
+		"addiu $sp, $sp, -32\n"                                       \
+		"sw %7, 16($sp)\n"                                            \
+		"sw %8, 20($sp)\n"                                            \
+		"syscall\n  "                                                 \
+		"addiu $sp, $sp, 32\n"                                        \
+		: "=r" (_num), "=r"(_arg4)                                    \
+		: "0"(_num),                                                  \
+		  "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
+		  "r"(_arg6)                                                  \
+		: "memory", "cc", "at", "v1", "hi", "lo",                     \
+	          "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"  \
+	);                                                                    \
+	_arg4 ? -_num : _num;                                                 \
+})
+
 char **environ __attribute__((weak));
 const unsigned long *_auxv __attribute__((weak));
 
diff --git a/tools/include/nolibc/nolibc.h b/tools/include/nolibc/nolibc.h
index 05a228a6ee78..1f8d821000ac 100644
--- a/tools/include/nolibc/nolibc.h
+++ b/tools/include/nolibc/nolibc.h
@@ -13,11 +13,10 @@
  * Syscalls are split into 3 levels:
  *   - The lower level is the arch-specific syscall() definition, consisting in
  *     assembly code in compound expressions. These are called my_syscall0() to
- *     my_syscall6() depending on the number of arguments. The MIPS
- *     implementation is limited to 5 arguments. All input arguments are cast
- *     to a long stored in a register. These expressions always return the
- *     syscall's return value as a signed long value which is often either a
- *     pointer or the negated errno value.
+ *     my_syscall6() depending on the number of arguments. All input arguments
+ *     are castto a long stored in a register. These expressions always return
+ *     the syscall's return value as a signed long value which is often either
+ *     a pointer or the negated errno value.
  *
  *   - The second level is mostly architecture-independent. It is made of
  *     static functions called sys_<name>() which rely on my_syscallN()
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v4 06/10] tools/nolibc: __sysret: support syscalls who return a pointer
  2023-06-19 15:40 [PATCH v4 00/10] tools/nolibc: add a new syscall helper Zhangjin Wu
                   ` (4 preceding siblings ...)
  2023-06-19 15:47 ` [PATCH v4 05/10] tools/nolibc: add missing my_syscall6() for mips Zhangjin Wu
@ 2023-06-19 15:48 ` Zhangjin Wu
  2023-06-19 15:51 ` [PATCH v4 07/10] tools/nolibc: clean up mmap() support Zhangjin Wu
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-19 15:48 UTC (permalink / raw)
  To: w
  Cc: david.laight, arnd, falcon, linux-kernel, linux-kselftest,
	linux-riscv, thomas, David Laight

To support syscalls (e.g. mmap()) who return a pointer and to allow the
pointer as big as possible, we should convert the negated errno value to
unsigned long (uintptr_t), otherwise, in signed long, a potential big
pointer (whose highest bit is 1) will be treated as a failure.

tools/include/nolibc/errno.h defines the MAX_ERRNO, let's use it
directly. after converting to unsigned long, the negative errno value
from -1 to -MAX_ERRNO becomes something like '~1 + 1' (every bit is 1)
to '~MAX_ERRNO + 1', '~1 + 1' is the biggest, '~MAX_ERRNO + 1' is the
smallest, so, the check becomes:

    if (ret <= (unsigned long)-1 && ret >= (unsigned long)-MAX_ERRNO) {
        ...
    }

Since (unsigned long)-1 is the biggest unsigned long value, it is always
true if bigger than (unsigned long)-MAX_ERRNO, so, just reserve the
following check is enough:

    if (ret >= (unsigned long)-MAX_ERRNO) {
        ...
    }

Suggested-by: David Laight <David.Laight@ACULAB.COM>
Link: https://lore.kernel.org/linux-riscv/94dd5170929f454fbc0a10a2eb3b108d@AcuMS.aculab.com/
Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/sys.h | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index 4fbefe5adf93..8a6e16472d54 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -28,13 +28,16 @@
 #include "errno.h"
 #include "types.h"
 
-/* Syscall return helper, set errno as -ret when ret < 0 */
+
+/* Syscall return helper for library routines
+ * set errno as -ret when ret in [-MAX_ERRNO, -1]
+ */
 static __inline__ __attribute__((unused, always_inline))
-long __sysret(long ret)
+long __sysret(unsigned long ret)
 {
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
+	if (ret >= (unsigned long)-MAX_ERRNO) {
+		SET_ERRNO(-(long)ret);
+		return -1;
 	}
 	return ret;
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v4 07/10] tools/nolibc: clean up mmap() support
  2023-06-19 15:40 [PATCH v4 00/10] tools/nolibc: add a new syscall helper Zhangjin Wu
                   ` (5 preceding siblings ...)
  2023-06-19 15:48 ` [PATCH v4 06/10] tools/nolibc: __sysret: support syscalls who return a pointer Zhangjin Wu
@ 2023-06-19 15:51 ` Zhangjin Wu
  2023-06-21 18:48   ` Thomas Weißschuh
  2023-06-19 15:52 ` [PATCH v4 08/10] selftests/nolibc: add EXPECT_PTREQ, EXPECT_PTRNE and EXPECT_PTRER Zhangjin Wu
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-19 15:51 UTC (permalink / raw)
  To: w
  Cc: david.laight, arnd, falcon, linux-kernel, linux-kselftest,
	linux-riscv, thomas

Do several cleanups together:

- Since all supported architectures have my_syscall6() now, remove the
  #ifdef check.

- Move the mmap() related macros to tools/include/nolibc/types.h

- Apply the new __sysret() to convert the calling of sys_map() to
  oneline code

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/sys.h   | 24 +-----------------------
 tools/include/nolibc/types.h | 11 +++++++++++
 2 files changed, 12 insertions(+), 23 deletions(-)

diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index 8a6e16472d54..1c02cec3bcd9 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -624,26 +624,11 @@ int mknod(const char *path, mode_t mode, dev_t dev)
 	return __sysret(sys_mknod(path, mode, dev));
 }
 
-#ifndef MAP_SHARED
-#define MAP_SHARED		0x01	/* Share changes */
-#define MAP_PRIVATE		0x02	/* Changes are private */
-#define MAP_SHARED_VALIDATE	0x03	/* share + validate extension flags */
-#endif
-
-#ifndef MAP_FAILED
-#define MAP_FAILED ((void *)-1)
-#endif
-
 #ifndef sys_mmap
 static __attribute__((unused))
 void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
 	       off_t offset)
 {
-#ifndef my_syscall6
-	/* Function not implemented. */
-	return (void *)-ENOSYS;
-#else
-
 	int n;
 
 #if defined(__NR_mmap2)
@@ -654,20 +639,13 @@ void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
 #endif
 
 	return (void *)my_syscall6(n, addr, length, prot, flags, fd, offset);
-#endif
 }
 #endif
 
 static __attribute__((unused))
 void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
 {
-	void *ret = sys_mmap(addr, length, prot, flags, fd, offset);
-
-	if ((unsigned long)ret >= -4095UL) {
-		SET_ERRNO(-(long)ret);
-		ret = MAP_FAILED;
-	}
-	return ret;
+	return (void *)__sysret((unsigned long)sys_mmap(addr, length, prot, flags, fd, offset));
 }
 
 static __attribute__((unused))
diff --git a/tools/include/nolibc/types.h b/tools/include/nolibc/types.h
index f96e28bff4ba..f889d4e0ac7e 100644
--- a/tools/include/nolibc/types.h
+++ b/tools/include/nolibc/types.h
@@ -81,6 +81,17 @@
 #define MAXPATHLEN     (PATH_MAX)
 #endif
 
+/* flags for mmap */
+#ifndef MAP_SHARED
+#define MAP_SHARED		0x01	/* Share changes */
+#define MAP_PRIVATE		0x02	/* Changes are private */
+#define MAP_SHARED_VALIDATE	0x03	/* share + validate extension flags */
+#endif
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
 /* whence values for lseek() */
 #define SEEK_SET       0
 #define SEEK_CUR       1
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v4 08/10] selftests/nolibc: add EXPECT_PTREQ, EXPECT_PTRNE and EXPECT_PTRER
  2023-06-19 15:40 [PATCH v4 00/10] tools/nolibc: add a new syscall helper Zhangjin Wu
                   ` (6 preceding siblings ...)
  2023-06-19 15:51 ` [PATCH v4 07/10] tools/nolibc: clean up mmap() support Zhangjin Wu
@ 2023-06-19 15:52 ` Zhangjin Wu
  2023-06-19 15:54 ` [PATCH v4 09/10] selftests/nolibc: add sbrk_0 to test current brk getting Zhangjin Wu
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-19 15:52 UTC (permalink / raw)
  To: w
  Cc: david.laight, arnd, falcon, linux-kernel, linux-kselftest,
	linux-riscv, thomas

The syscalls like sbrk() and mmap() return pointers, to test them, more
pointer compare test macros are required, add them:

- EXPECT_PTREQ() expects two equal pointers.
- EXPECT_PTRNE() expects two non-equal pointers.
- EXPECT_PTRER() expects failure with a specified errno.
- EXPECT_PTRER2() expects failure with two specified errnos.

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/testing/selftests/nolibc/nolibc-test.c | 58 ++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 486334981e60..34af802dadfd 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -361,6 +361,64 @@ static int expect_ptrnz(const void *expr, int llen)
 	return ret;
 }
 
+#define EXPECT_PTREQ(cond, expr, cmp)				\
+	do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ptreq(expr, llen, cmp); } while (0)
+
+static int expect_ptreq(const void *expr, int llen, const void *cmp)
+{
+	int ret = 0;
+
+	llen += printf(" = <%p> ", expr);
+	if (expr != cmp) {
+		ret = 1;
+		llen += pad_spc(llen, 64, "[FAIL]\n");
+	} else {
+		llen += pad_spc(llen, 64, " [OK]\n");
+	}
+	return ret;
+}
+
+#define EXPECT_PTRNE(cond, expr, cmp)				\
+	do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ptrne(expr, llen, cmp); } while (0)
+
+static int expect_ptrne(const void *expr, int llen, const void *cmp)
+{
+	int ret = 0;
+
+	llen += printf(" = <%p> ", expr);
+	if (expr == cmp) {
+		ret = 1;
+		llen += pad_spc(llen, 64, "[FAIL]\n");
+	} else {
+		llen += pad_spc(llen, 64, " [OK]\n");
+	}
+	return ret;
+}
+
+#define EXPECT_PTRER2(cond, expr, expret, experr1, experr2)		\
+	do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ptrerr2(expr, expret, experr1, experr2, llen); } while (0)
+
+#define EXPECT_PTRER(cond, expr, expret, experr)			\
+	EXPECT_PTRER2(cond, expr, expret, experr, 0)
+
+static int expect_ptrerr2(const void *expr, const void *expret, int experr1, int experr2, int llen)
+{
+	int ret = 0;
+	int _errno = errno;
+
+	llen += printf(" = <%p> %s ", expr, errorname(_errno));
+	if (expr != expret || (_errno != experr1 && _errno != experr2)) {
+		ret = 1;
+		if (experr2 == 0)
+			llen += printf(" != (<%p> %s) ", expret, errorname(experr1));
+		else
+			llen += printf(" != (<%p> %s %s) ", expret, errorname(experr1), errorname(experr2));
+		llen += pad_spc(llen, 64, "[FAIL]\n");
+	} else {
+		llen += pad_spc(llen, 64, " [OK]\n");
+	}
+	return ret;
+}
 
 #define EXPECT_STRZR(cond, expr)				\
 	do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_strzr(expr, llen); } while (0)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v4 09/10] selftests/nolibc: add sbrk_0 to test current brk getting
  2023-06-19 15:40 [PATCH v4 00/10] tools/nolibc: add a new syscall helper Zhangjin Wu
                   ` (7 preceding siblings ...)
  2023-06-19 15:52 ` [PATCH v4 08/10] selftests/nolibc: add EXPECT_PTREQ, EXPECT_PTRNE and EXPECT_PTRER Zhangjin Wu
@ 2023-06-19 15:54 ` Zhangjin Wu
  2023-06-19 15:55 ` [PATCH v4 10/10] selftests/nolibc: add mmap and munmap test cases Zhangjin Wu
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
  10 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-19 15:54 UTC (permalink / raw)
  To: w
  Cc: david.laight, arnd, falcon, linux-kernel, linux-kselftest,
	linux-riscv, thomas

From musl 0.9.14 (to the latest version 1.2.3), both sbrk() and brk()
have almost been disabled for they conflict with malloc, only sbrk(0) is
still permitted as a way to get the current brk, let's support such
case.

EXPECT_PTRNE() is used to expect sbrk() always successfully getting the
current brk.

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/testing/selftests/nolibc/nolibc-test.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 34af802dadfd..80ab29e2887c 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -630,6 +630,7 @@ int run_syscall(int min, int max)
 		CASE_TEST(kill_0);            EXPECT_SYSZR(1, kill(getpid(), 0)); break;
 		CASE_TEST(kill_CONT);         EXPECT_SYSZR(1, kill(getpid(), 0)); break;
 		CASE_TEST(kill_BADPID);       EXPECT_SYSER(1, kill(INT_MAX, 0), -1, ESRCH); break;
+		CASE_TEST(sbrk_0);            EXPECT_PTRNE(1, sbrk(0), (void *)-1); break;
 		CASE_TEST(sbrk);              if ((p1 = p2 = sbrk(4096)) != (void *)-1) p2 = sbrk(-4096); EXPECT_SYSZR(1, (p2 == (void *)-1) || p2 == p1); break;
 		CASE_TEST(brk);               EXPECT_SYSZR(1, brk(sbrk(0))); break;
 		CASE_TEST(chdir_root);        EXPECT_SYSZR(1, chdir("/")); break;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v4 10/10] selftests/nolibc: add mmap and munmap test cases
  2023-06-19 15:40 [PATCH v4 00/10] tools/nolibc: add a new syscall helper Zhangjin Wu
                   ` (8 preceding siblings ...)
  2023-06-19 15:54 ` [PATCH v4 09/10] selftests/nolibc: add sbrk_0 to test current brk getting Zhangjin Wu
@ 2023-06-19 15:55 ` Zhangjin Wu
  2023-06-19 16:14   ` Zhangjin Wu
  2023-06-21 18:58   ` Thomas Weißschuh
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
  10 siblings, 2 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-19 15:55 UTC (permalink / raw)
  To: w
  Cc: david.laight, arnd, falcon, linux-kernel, linux-kselftest,
	linux-riscv, thomas

Three mmap/munmap related test cases are added:

- mmap(NULL, 0, PROT_READ, MAP_PRIVATE, 0, 0), MAP_FAILED, EINVAL)

  The length argument must be greater than 0, otherwise, fail with -EINVAL.

- munmap((void *)-1, 4*1024), -1, EINVAL)

  Invalid (void *)-1 address fail with -EINVAL.

- test_mmap_munmap(4*1024)

  It finds a init file, mmap() it and then munmap().

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/testing/selftests/nolibc/nolibc-test.c | 31 ++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 80ab29e2887c..f7c0ca72cb28 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -592,6 +592,34 @@ static int test_stat_timestamps(void)
 	return 0;
 }
 
+int test_mmap_munmap(int size)
+{
+	char init_files[5][20] = {"/init", "/sbin/init", "/etc/init", "/bin/init", "/bin/sh"};
+	int ret, fd, i;
+	void *mem;
+
+	for (i = 0; i < 5; i++) {
+		ret = fd = open(init_files[i], O_RDONLY);
+		if (ret < 0)
+			continue;
+		else
+			break;
+	}
+	if (ret < 0)
+		return ret;
+
+	mem = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
+	if (mem == MAP_FAILED)
+		return -1;
+
+	ret = munmap(mem, size);
+	if (ret < 0)
+		return ret;
+
+	return close(fd);
+}
+
+
 /* Run syscall tests between IDs <min> and <max>.
  * Return 0 on success, non-zero on failure.
  */
@@ -666,6 +694,9 @@ int run_syscall(int min, int max)
 		CASE_TEST(lseek_m1);          EXPECT_SYSER(1, lseek(-1, 0, SEEK_SET), -1, EBADF); break;
 		CASE_TEST(lseek_0);           EXPECT_SYSER(1, lseek(0, 0, SEEK_SET), -1, ESPIPE); break;
 		CASE_TEST(mkdir_root);        EXPECT_SYSER(1, mkdir("/", 0755), -1, EEXIST); break;
+		CASE_TEST(mmap_bad);          EXPECT_PTRER(1, mmap(NULL, 0, PROT_READ, MAP_PRIVATE, 0, 0), MAP_FAILED, EINVAL); break;
+		CASE_TEST(munmap_bad);        EXPECT_SYSER(1, munmap((void *)-1, 0), -1, EINVAL); break;
+		CASE_TEST(mmap_good);         EXPECT_SYSZR(1, test_mmap_munmap(4*1024)); break;
 		CASE_TEST(open_tty);          EXPECT_SYSNE(1, tmp = open("/dev/null", 0), -1); if (tmp != -1) close(tmp); break;
 		CASE_TEST(open_blah);         EXPECT_SYSER(1, tmp = open("/proc/self/blah", 0), -1, ENOENT); if (tmp != -1) close(tmp); break;
 		CASE_TEST(poll_null);         EXPECT_SYSZR(1, poll(NULL, 0, 0)); break;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v4 10/10] selftests/nolibc: add mmap and munmap test cases
  2023-06-19 15:55 ` [PATCH v4 10/10] selftests/nolibc: add mmap and munmap test cases Zhangjin Wu
@ 2023-06-19 16:14   ` Zhangjin Wu
  2023-06-21 18:58   ` Thomas Weißschuh
  1 sibling, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-19 16:14 UTC (permalink / raw)
  To: falcon
  Cc: arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv,
	thomas, w

Hi,

> Three mmap/munmap related test cases are added:
> 
> - mmap(NULL, 0, PROT_READ, MAP_PRIVATE, 0, 0), MAP_FAILED, EINVAL)
> 
>   The length argument must be greater than 0, otherwise, fail with -EINVAL.
> 
> - munmap((void *)-1, 4*1024), -1, EINVAL)
>

Sorry, this message doesn't match the code, will change it in new revison.

>   Invalid (void *)-1 address fail with -EINVAL.
> 
> - test_mmap_munmap(4*1024)
> 
>   It finds a init file, mmap() it and then munmap().
> 
> Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
> ---
>  tools/testing/selftests/nolibc/nolibc-test.c | 31 ++++++++++++++++++++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
> index 80ab29e2887c..f7c0ca72cb28 100644
> --- a/tools/testing/selftests/nolibc/nolibc-test.c
> +++ b/tools/testing/selftests/nolibc/nolibc-test.c
> @@ -592,6 +592,34 @@ static int test_stat_timestamps(void)
>  	return 0;
>  }
>  
> +int test_mmap_munmap(int size)
> +{
> +	char init_files[5][20] = {"/init", "/sbin/init", "/etc/init", "/bin/init", "/bin/sh"};
> +	int ret, fd, i;
> +	void *mem;
> +
> +	for (i = 0; i < 5; i++) {
> +		ret = fd = open(init_files[i], O_RDONLY);
> +		if (ret < 0)
> +			continue;
> +		else
> +			break;
> +	}
> +	if (ret < 0)
> +		return ret;
> +
> +	mem = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
> +	if (mem == MAP_FAILED)
> +		return -1;
> +

And here need a close(fd):

	if (mem == MAP_FAILED) {
		close(fd);
		return -1;
	}

> +	ret = munmap(mem, size);
> +	if (ret < 0)
> +		return ret;
> +

And here too:

	if (ret < 0) {
		close(fd);
		return ret;
	}


> +	return close(fd);

	close(fd);
	return 0;

Thanks,
Zhangjin

> +}
> +
> +
>  /* Run syscall tests between IDs <min> and <max>.
>   * Return 0 on success, non-zero on failure.
>   */
> @@ -666,6 +694,9 @@ int run_syscall(int min, int max)
>  		CASE_TEST(lseek_m1);          EXPECT_SYSER(1, lseek(-1, 0, SEEK_SET), -1, EBADF); break;
>  		CASE_TEST(lseek_0);           EXPECT_SYSER(1, lseek(0, 0, SEEK_SET), -1, ESPIPE); break;
>  		CASE_TEST(mkdir_root);        EXPECT_SYSER(1, mkdir("/", 0755), -1, EEXIST); break;
> +		CASE_TEST(mmap_bad);          EXPECT_PTRER(1, mmap(NULL, 0, PROT_READ, MAP_PRIVATE, 0, 0), MAP_FAILED, EINVAL); break;
> +		CASE_TEST(munmap_bad);        EXPECT_SYSER(1, munmap((void *)-1, 0), -1, EINVAL); break;
> +		CASE_TEST(mmap_good);         EXPECT_SYSZR(1, test_mmap_munmap(4*1024)); break;
>  		CASE_TEST(open_tty);          EXPECT_SYSNE(1, tmp = open("/dev/null", 0), -1); if (tmp != -1) close(tmp); break;
>  		CASE_TEST(open_blah);         EXPECT_SYSER(1, tmp = open("/proc/self/blah", 0), -1, ENOENT); if (tmp != -1) close(tmp); break;
>  		CASE_TEST(poll_null);         EXPECT_SYSZR(1, poll(NULL, 0, 0)); break;
> -- 
> 2.25.1

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v4 07/10] tools/nolibc: clean up mmap() support
  2023-06-19 15:51 ` [PATCH v4 07/10] tools/nolibc: clean up mmap() support Zhangjin Wu
@ 2023-06-21 18:48   ` Thomas Weißschuh
  2023-06-22 19:08     ` Zhangjin Wu
  0 siblings, 1 reply; 54+ messages in thread
From: Thomas Weißschuh @ 2023-06-21 18:48 UTC (permalink / raw)
  To: Zhangjin Wu
  Cc: w, david.laight, arnd, linux-kernel, linux-kselftest, linux-riscv

On 2023-06-19 23:51:20+0800, Zhangjin Wu wrote:
> Do several cleanups together:
> 
> - Since all supported architectures have my_syscall6() now, remove the
>   #ifdef check.
> 
> - Move the mmap() related macros to tools/include/nolibc/types.h
> 
> - Apply the new __sysret() to convert the calling of sys_map() to
>   oneline code
> 
> Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
> ---
>  tools/include/nolibc/sys.h   | 24 +-----------------------
>  tools/include/nolibc/types.h | 11 +++++++++++
>  2 files changed, 12 insertions(+), 23 deletions(-)
> 
> diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
> index 8a6e16472d54..1c02cec3bcd9 100644
> --- a/tools/include/nolibc/sys.h
> +++ b/tools/include/nolibc/sys.h
> @@ -624,26 +624,11 @@ int mknod(const char *path, mode_t mode, dev_t dev)
>  	return __sysret(sys_mknod(path, mode, dev));
>  }
>  
> -#ifndef MAP_SHARED
> -#define MAP_SHARED		0x01	/* Share changes */
> -#define MAP_PRIVATE		0x02	/* Changes are private */
> -#define MAP_SHARED_VALIDATE	0x03	/* share + validate extension flags */
> -#endif
> -
> -#ifndef MAP_FAILED
> -#define MAP_FAILED ((void *)-1)
> -#endif
> -
>  #ifndef sys_mmap
>  static __attribute__((unused))
>  void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
>  	       off_t offset)

This could return a plain integer type instead to save some casts.
Not sure if API compatibility is guaranteed for the raw sys_ functions.

>  {
> -#ifndef my_syscall6
> -	/* Function not implemented. */
> -	return (void *)-ENOSYS;
> -#else
> -
>  	int n;
>  
>  #if defined(__NR_mmap2)
> @@ -654,20 +639,13 @@ void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
>  #endif
>  
>  	return (void *)my_syscall6(n, addr, length, prot, flags, fd, offset);
> -#endif
>  }
>  #endif
>  
>  static __attribute__((unused))
>  void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
>  {
> -	void *ret = sys_mmap(addr, length, prot, flags, fd, offset);
> -
> -	if ((unsigned long)ret >= -4095UL) {
> -		SET_ERRNO(-(long)ret);
> -		ret = MAP_FAILED;
> -	}
> -	return ret;
> +	return (void *)__sysret((unsigned long)sys_mmap(addr, length, prot, flags, fd, offset));
>  }
>  
>  static __attribute__((unused))
> diff --git a/tools/include/nolibc/types.h b/tools/include/nolibc/types.h
> index f96e28bff4ba..f889d4e0ac7e 100644
> --- a/tools/include/nolibc/types.h
> +++ b/tools/include/nolibc/types.h
> @@ -81,6 +81,17 @@
>  #define MAXPATHLEN     (PATH_MAX)
>  #endif
>  
> +/* flags for mmap */
> +#ifndef MAP_SHARED
> +#define MAP_SHARED		0x01	/* Share changes */
> +#define MAP_PRIVATE		0x02	/* Changes are private */
> +#define MAP_SHARED_VALIDATE	0x03	/* share + validate extension flags */
> +#endif
> +
> +#ifndef MAP_FAILED
> +#define MAP_FAILED ((void *)-1)
> +#endif
> +
>  /* whence values for lseek() */
>  #define SEEK_SET       0
>  #define SEEK_CUR       1
> -- 
> 2.25.1
> 

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v4 10/10] selftests/nolibc: add mmap and munmap test cases
  2023-06-19 15:55 ` [PATCH v4 10/10] selftests/nolibc: add mmap and munmap test cases Zhangjin Wu
  2023-06-19 16:14   ` Zhangjin Wu
@ 2023-06-21 18:58   ` Thomas Weißschuh
  2023-06-22 19:32     ` Zhangjin Wu
  1 sibling, 1 reply; 54+ messages in thread
From: Thomas Weißschuh @ 2023-06-21 18:58 UTC (permalink / raw)
  To: Zhangjin Wu
  Cc: w, david.laight, arnd, linux-kernel, linux-kselftest, linux-riscv

On 2023-06-19 23:55:41+0800, Zhangjin Wu wrote:
> Three mmap/munmap related test cases are added:
> 
> - mmap(NULL, 0, PROT_READ, MAP_PRIVATE, 0, 0), MAP_FAILED, EINVAL)
> 
>   The length argument must be greater than 0, otherwise, fail with -EINVAL.
> 
> - munmap((void *)-1, 4*1024), -1, EINVAL)
> 
>   Invalid (void *)-1 address fail with -EINVAL.
> 
> - test_mmap_munmap(4*1024)
> 
>   It finds a init file, mmap() it and then munmap().
> 
> Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
> ---
>  tools/testing/selftests/nolibc/nolibc-test.c | 31 ++++++++++++++++++++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
> index 80ab29e2887c..f7c0ca72cb28 100644
> --- a/tools/testing/selftests/nolibc/nolibc-test.c
> +++ b/tools/testing/selftests/nolibc/nolibc-test.c
> @@ -592,6 +592,34 @@ static int test_stat_timestamps(void)
>  	return 0;
>  }
>  
> +int test_mmap_munmap(int size)
> +{
> +	char init_files[5][20] = {"/init", "/sbin/init", "/etc/init", "/bin/init", "/bin/sh"};

Why not /proc/1/exe or even /proc/self/exe?

I know your other series tries to remove the procfs dependency, but
we're not there yet :-).

Also does it make sense to pass a size parameter?
Why not use either PAGE_SIZE or the real size of the binary from
fstat().

> +	int ret, fd, i;
> +	void *mem;
> +
> +	for (i = 0; i < 5; i++) {
> +		ret = fd = open(init_files[i], O_RDONLY);
> +		if (ret < 0)
> +			continue;
> +		else
> +			break;
> +	}
> +	if (ret < 0)
> +		return ret;
> +
> +	mem = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
> +	if (mem == MAP_FAILED)
> +		return -1;
> +
> +	ret = munmap(mem, size);
> +	if (ret < 0)
> +		return ret;
> +
> +	return close(fd);
> +}
> +
> +
>  /* Run syscall tests between IDs <min> and <max>.
>   * Return 0 on success, non-zero on failure.
>   */
> @@ -666,6 +694,9 @@ int run_syscall(int min, int max)
>  		CASE_TEST(lseek_m1);          EXPECT_SYSER(1, lseek(-1, 0, SEEK_SET), -1, EBADF); break;
>  		CASE_TEST(lseek_0);           EXPECT_SYSER(1, lseek(0, 0, SEEK_SET), -1, ESPIPE); break;
>  		CASE_TEST(mkdir_root);        EXPECT_SYSER(1, mkdir("/", 0755), -1, EEXIST); break;
> +		CASE_TEST(mmap_bad);          EXPECT_PTRER(1, mmap(NULL, 0, PROT_READ, MAP_PRIVATE, 0, 0), MAP_FAILED, EINVAL); break;
> +		CASE_TEST(munmap_bad);        EXPECT_SYSER(1, munmap((void *)-1, 0), -1, EINVAL); break;
> +		CASE_TEST(mmap_good);         EXPECT_SYSZR(1, test_mmap_munmap(4*1024)); break;
>  		CASE_TEST(open_tty);          EXPECT_SYSNE(1, tmp = open("/dev/null", 0), -1); if (tmp != -1) close(tmp); break;
>  		CASE_TEST(open_blah);         EXPECT_SYSER(1, tmp = open("/proc/self/blah", 0), -1, ENOENT); if (tmp != -1) close(tmp); break;
>  		CASE_TEST(poll_null);         EXPECT_SYSZR(1, poll(NULL, 0, 0)); break;
> -- 
> 2.25.1
> 

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v4 07/10] tools/nolibc: clean up mmap() support
  2023-06-21 18:48   ` Thomas Weißschuh
@ 2023-06-22 19:08     ` Zhangjin Wu
  0 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-22 19:08 UTC (permalink / raw)
  To: thomas
  Cc: arnd, david.laight, falcon, linux-kernel, linux-kselftest,
	linux-riscv, w

Hi, Thomas

> On 2023-06-19 23:51:20+0800, Zhangjin Wu wrote:
> > Do several cleanups together:
> > 
> > - Since all supported architectures have my_syscall6() now, remove the
> >   #ifdef check.
> > 
> > - Move the mmap() related macros to tools/include/nolibc/types.h
> > 
> > - Apply the new __sysret() to convert the calling of sys_map() to
> >   oneline code
> > 
> > Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
> > ---
> >  tools/include/nolibc/sys.h   | 24 +-----------------------
> >  tools/include/nolibc/types.h | 11 +++++++++++
> >  2 files changed, 12 insertions(+), 23 deletions(-)
> > 
> > diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
> > index 8a6e16472d54..1c02cec3bcd9 100644
> > --- a/tools/include/nolibc/sys.h
> > +++ b/tools/include/nolibc/sys.h
> > @@ -624,26 +624,11 @@ int mknod(const char *path, mode_t mode, dev_t dev)
> >  	return __sysret(sys_mknod(path, mode, dev));
> >  }
> >  
> > -#ifndef MAP_SHARED
> > -#define MAP_SHARED		0x01	/* Share changes */
> > -#define MAP_PRIVATE		0x02	/* Changes are private */
> > -#define MAP_SHARED_VALIDATE	0x03	/* share + validate extension flags */
> > -#endif
> > -
> > -#ifndef MAP_FAILED
> > -#define MAP_FAILED ((void *)-1)
> > -#endif
> > -
> >  #ifndef sys_mmap
> >  static __attribute__((unused))
> >  void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
> >  	       off_t offset)
> 
> This could return a plain integer type instead to save some casts.
> Not sure if API compatibility is guaranteed for the raw sys_ functions.
>

Seems musl simply not provide the sys_xxx() functions, but let the library
routines call __syscall() directly. If we can treat these sys_xxx() as internal
functions, perhaps we can simply let the return type of sys_xxx() as 'long' to.

    $ grep "^void \*sys_" -ur tools/include/nolibc/sys.h 
    void *sys_brk(void *addr)
    void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,

Thanks,
Zhangjin


> >  {
> > -#ifndef my_syscall6
> > -	/* Function not implemented. */
> > -	return (void *)-ENOSYS;
> > -#else
> > -
> >  	int n;
> >  
> >  #if defined(__NR_mmap2)
> > @@ -654,20 +639,13 @@ void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
> >  #endif
> >  
> >  	return (void *)my_syscall6(n, addr, length, prot, flags, fd, offset);
> > -#endif
> >  }
> >  #endif
> >  
> >  static __attribute__((unused))
> >  void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
> >  {
> > -	void *ret = sys_mmap(addr, length, prot, flags, fd, offset);
> > -
> > -	if ((unsigned long)ret >= -4095UL) {
> > -		SET_ERRNO(-(long)ret);
> > -		ret = MAP_FAILED;
> > -	}
> > -	return ret;
> > +	return (void *)__sysret((unsigned long)sys_mmap(addr, length, prot, flags, fd, offset));
> >  }
> >  
> >  static __attribute__((unused))
> > diff --git a/tools/include/nolibc/types.h b/tools/include/nolibc/types.h
> > index f96e28bff4ba..f889d4e0ac7e 100644
> > --- a/tools/include/nolibc/types.h
> > +++ b/tools/include/nolibc/types.h
> > @@ -81,6 +81,17 @@
> >  #define MAXPATHLEN     (PATH_MAX)
> >  #endif
> >  
> > +/* flags for mmap */
> > +#ifndef MAP_SHARED
> > +#define MAP_SHARED		0x01	/* Share changes */
> > +#define MAP_PRIVATE		0x02	/* Changes are private */
> > +#define MAP_SHARED_VALIDATE	0x03	/* share + validate extension flags */
> > +#endif
> > +
> > +#ifndef MAP_FAILED
> > +#define MAP_FAILED ((void *)-1)
> > +#endif
> > +
> >  /* whence values for lseek() */
> >  #define SEEK_SET       0
> >  #define SEEK_CUR       1
> > -- 
> > 2.25.1
> > 

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v4 10/10] selftests/nolibc: add mmap and munmap test cases
  2023-06-21 18:58   ` Thomas Weißschuh
@ 2023-06-22 19:32     ` Zhangjin Wu
  2023-06-22 19:56       ` Thomas Weißschuh
  0 siblings, 1 reply; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-22 19:32 UTC (permalink / raw)
  To: thomas
  Cc: arnd, david.laight, falcon, linux-kernel, linux-kselftest,
	linux-riscv, w

Hi, Thomas

> On 2023-06-19 23:55:41+0800, Zhangjin Wu wrote:
> > Three mmap/munmap related test cases are added:
> > 
> > - mmap(NULL, 0, PROT_READ, MAP_PRIVATE, 0, 0), MAP_FAILED, EINVAL)
> > 
> >   The length argument must be greater than 0, otherwise, fail with -EINVAL.
> > 
> > - munmap((void *)-1, 4*1024), -1, EINVAL)
> > 
> >   Invalid (void *)-1 address fail with -EINVAL.
> > 
> > - test_mmap_munmap(4*1024)
> > 
> >   It finds a init file, mmap() it and then munmap().
> > 
> > Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
> > ---
> >  tools/testing/selftests/nolibc/nolibc-test.c | 31 ++++++++++++++++++++
> >  1 file changed, 31 insertions(+)
> > 
> > diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
> > index 80ab29e2887c..f7c0ca72cb28 100644
> > --- a/tools/testing/selftests/nolibc/nolibc-test.c
> > +++ b/tools/testing/selftests/nolibc/nolibc-test.c
> > @@ -592,6 +592,34 @@ static int test_stat_timestamps(void)
> >  	return 0;
> >  }
> >  
> > +int test_mmap_munmap(int size)
> > +{
> > +	char init_files[5][20] = {"/init", "/sbin/init", "/etc/init", "/bin/init", "/bin/sh"};
> 
> Why not /proc/1/exe or even /proc/self/exe?
> 
> I know your other series tries to remove the procfs dependency, but
> we're not there yet :-).
> 

Yeah, '/proc/self/exe' is a choice, if so, the 'has_proc' should be added ;-)

> Also does it make sense to pass a size parameter?
> Why not use either PAGE_SIZE or the real size of the binary from
> fstat().
> 

Ok, as the manpage of mmap shows:

       For mmap(), offset must be a multiple of the underlying huge page
       size.  The system automatically aligns length to be a multiple of
       the underlying huge page size.

       For munmap(), addr, and length must both be a multiple of the
       underlying huge page size.

perhaps we should do further tests:

* the real size/length
* even > the real size
* the PAGE_SIZE
* not aligned with PAGE_SIZE

If such tests are required, the 'size' and even 'offset' arguments could be
provided to cover different combination or we do such tests internally, then,
the arguments are not required.

Thanks,
Zhangjin

> > +	int ret, fd, i;
> > +	void *mem;
> > +
> > +	for (i = 0; i < 5; i++) {
> > +		ret = fd = open(init_files[i], O_RDONLY);
> > +		if (ret < 0)
> > +			continue;
> > +		else
> > +			break;
> > +	}
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	mem = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
> > +	if (mem == MAP_FAILED)
> > +		return -1;
> > +
> > +	ret = munmap(mem, size);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	return close(fd);
> > +}
> > +
> > +
> >  /* Run syscall tests between IDs <min> and <max>.
> >   * Return 0 on success, non-zero on failure.
> >   */
> > @@ -666,6 +694,9 @@ int run_syscall(int min, int max)
> >  		CASE_TEST(lseek_m1);          EXPECT_SYSER(1, lseek(-1, 0, SEEK_SET), -1, EBADF); break;
> >  		CASE_TEST(lseek_0);           EXPECT_SYSER(1, lseek(0, 0, SEEK_SET), -1, ESPIPE); break;
> >  		CASE_TEST(mkdir_root);        EXPECT_SYSER(1, mkdir("/", 0755), -1, EEXIST); break;
> > +		CASE_TEST(mmap_bad);          EXPECT_PTRER(1, mmap(NULL, 0, PROT_READ, MAP_PRIVATE, 0, 0), MAP_FAILED, EINVAL); break;
> > +		CASE_TEST(munmap_bad);        EXPECT_SYSER(1, munmap((void *)-1, 0), -1, EINVAL); break;
> > +		CASE_TEST(mmap_good);         EXPECT_SYSZR(1, test_mmap_munmap(4*1024)); break;
> >  		CASE_TEST(open_tty);          EXPECT_SYSNE(1, tmp = open("/dev/null", 0), -1); if (tmp != -1) close(tmp); break;
> >  		CASE_TEST(open_blah);         EXPECT_SYSER(1, tmp = open("/proc/self/blah", 0), -1, ENOENT); if (tmp != -1) close(tmp); break;
> >  		CASE_TEST(poll_null);         EXPECT_SYSZR(1, poll(NULL, 0, 0)); break;
> > -- 
> > 2.25.1
> > 

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v4 10/10] selftests/nolibc: add mmap and munmap test cases
  2023-06-22 19:32     ` Zhangjin Wu
@ 2023-06-22 19:56       ` Thomas Weißschuh
  2023-06-24  7:47         ` Zhangjin Wu
  0 siblings, 1 reply; 54+ messages in thread
From: Thomas Weißschuh @ 2023-06-22 19:56 UTC (permalink / raw)
  To: Zhangjin Wu
  Cc: arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv, w

Hi Zhangjin,

On 2023-06-23 03:32:49+0800, Zhangjin Wu wrote:
> > On 2023-06-19 23:55:41+0800, Zhangjin Wu wrote:
> > > Three mmap/munmap related test cases are added:
> > > 
> > > - mmap(NULL, 0, PROT_READ, MAP_PRIVATE, 0, 0), MAP_FAILED, EINVAL)
> > > 
> > >   The length argument must be greater than 0, otherwise, fail with -EINVAL.
> > > 
> > > - munmap((void *)-1, 4*1024), -1, EINVAL)
> > > 
> > >   Invalid (void *)-1 address fail with -EINVAL.
> > > 
> > > - test_mmap_munmap(4*1024)
> > > 
> > >   It finds a init file, mmap() it and then munmap().
> > > 
> > > Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
> > > ---
> > >  tools/testing/selftests/nolibc/nolibc-test.c | 31 ++++++++++++++++++++
> > >  1 file changed, 31 insertions(+)
> > > 
> > > diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
> > > index 80ab29e2887c..f7c0ca72cb28 100644
> > > --- a/tools/testing/selftests/nolibc/nolibc-test.c
> > > +++ b/tools/testing/selftests/nolibc/nolibc-test.c
> > > @@ -592,6 +592,34 @@ static int test_stat_timestamps(void)
> > >  	return 0;
> > >  }
> > >  
> > > +int test_mmap_munmap(int size)
> > > +{
> > > +	char init_files[5][20] = {"/init", "/sbin/init", "/etc/init", "/bin/init", "/bin/sh"};
> > 
> > Why not /proc/1/exe or even /proc/self/exe?
> > 
> > I know your other series tries to remove the procfs dependency, but
> > we're not there yet :-).
> > 
> 
> Yeah, '/proc/self/exe' is a choice, if so, the 'has_proc' should be added ;-)

Currently procfs is a hard requirement. So I would leave 'has_proc' to
the other series that may change this.

> > Also does it make sense to pass a size parameter?
> > Why not use either PAGE_SIZE or the real size of the binary from
> > fstat().
> > 
> 
> Ok, as the manpage of mmap shows:
> 
>        For mmap(), offset must be a multiple of the underlying huge page
>        size.  The system automatically aligns length to be a multiple of
>        the underlying huge page size.
> 
>        For munmap(), addr, and length must both be a multiple of the
>        underlying huge page size.
> 
> perhaps we should do further tests:
> 
> * the real size/length
> * even > the real size
> * the PAGE_SIZE
> * not aligned with PAGE_SIZE
> 
> If such tests are required, the 'size' and even 'offset' arguments could be
> provided to cover different combination or we do such tests internally, then,
> the arguments are not required.

I think task of nolibc-test is to test the code in nolibc itself.
The custom mmap implementation is trivial and directly calls the
syscall. These additionally proposed tests would effectively test the
core kernels implementation of mmap() and not the code of nolibc.

Therefore I don't think they are necessary in nolibc-test and the
functionality is hopefully already be tested in another testsuite.


Note:

Testing mmap is indeed useful to test the implementation of
my_syscall6() by providing a bogus value in the 'offset' parameter.
I think we do have such a testcase.

<snip>

Thomas

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v4 10/10] selftests/nolibc: add mmap and munmap test cases
  2023-06-22 19:56       ` Thomas Weißschuh
@ 2023-06-24  7:47         ` Zhangjin Wu
  0 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-24  7:47 UTC (permalink / raw)
  To: thomas
  Cc: arnd, david.laight, falcon, linux-kernel, linux-kselftest,
	linux-riscv, w

Hi, Thomas

> Hi Zhangjin,
> 
> On 2023-06-23 03:32:49+0800, Zhangjin Wu wrote:
> > > On 2023-06-19 23:55:41+0800, Zhangjin Wu wrote:
> > > > Three mmap/munmap related test cases are added:
> > > > 
(snipped)
> > > >  
> > > > +int test_mmap_munmap(int size)
> > > > +{
> > > > +	char init_files[5][20] = {"/init", "/sbin/init", "/etc/init", "/bin/init", "/bin/sh"};
> > > 
> > > Why not /proc/1/exe or even /proc/self/exe?
> > > 
> > > I know your other series tries to remove the procfs dependency, but
> > > we're not there yet :-).
> > > 
> > 
> > Yeah, '/proc/self/exe' is a choice, if so, the 'has_proc' should be added ;-)
> 
> Currently procfs is a hard requirement. So I would leave 'has_proc' to
> the other series that may change this.
>

Yeah, but to be consistent with the already existing 'proc' condition
check, 'proc' will be used at first ;-)

    $ grep '(proc,' -ur tools/testing/selftests/nolibc/nolibc-test.c 
		CASE_TEST(chmod_net);         EXPECT_SYSZR(proc, chmod("/proc/self/net", 0555)); break;
		CASE_TEST(chmod_self);        EXPECT_SYSER(proc, chmod("/proc/self", 0555), -1, EPERM); break;
		CASE_TEST(chown_self);        EXPECT_SYSER(proc, chown("/proc/self", 0, 0), -1, EPERM); break;
		CASE_TEST(chroot_exe);        EXPECT_SYSER(proc, chroot("/proc/self/exe"), -1, ENOTDIR); break;
		CASE_TEST(link_cross);        EXPECT_SYSER(proc, link("/proc/self/net", "/blah"), -1, EXDEV); break;

Btw, for the /proc/self used in test_stat_timestamps, in the revision of the
'minimal' config support series, instead of using '/', a 'proc' should be added
like above test cases.

> > > Also does it make sense to pass a size parameter?
> > > Why not use either PAGE_SIZE or the real size of the binary from
> > > fstat().
> > > 
> > 
> > Ok, as the manpage of mmap shows:
> > 
> >        For mmap(), offset must be a multiple of the underlying huge page
> >        size.  The system automatically aligns length to be a multiple of
> >        the underlying huge page size.
> > 
> >        For munmap(), addr, and length must both be a multiple of the
> >        underlying huge page size.
> > 
> > perhaps we should do further tests:
> > 
> > * the real size/length
> > * even > the real size
> > * the PAGE_SIZE
> > * not aligned with PAGE_SIZE
> > 
> > If such tests are required, the 'size' and even 'offset' arguments could be
> > provided to cover different combination or we do such tests internally, then,
> > the arguments are not required.
> 
> I think task of nolibc-test is to test the code in nolibc itself.
> The custom mmap implementation is trivial and directly calls the
> syscall. These additionally proposed tests would effectively test the
> core kernels implementation of mmap() and not the code of nolibc.
> 
> Therefore I don't think they are necessary in nolibc-test and the
> functionality is hopefully already be tested in another testsuite.
>

Ok, it is reasonable.
 
> 
> Note:
> 
> Testing mmap is indeed useful to test the implementation of
> my_syscall6() by providing a bogus value in the 'offset' parameter.
> I think we do have such a testcase.
>

Ok, we can pass a valid offset (n*PAGE_SIZE) to mmap() in test_mmap_munmap() or
add a whole new mmap_offset test case with a PAGE_SIZE not aligned offset (such
as 1).

Thanks,
Zhangjin

> <snip>
> 
> Thomas


^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v5 00/14] tools/nolibc: add a new syscall helper
  2023-06-19 15:40 [PATCH v4 00/10] tools/nolibc: add a new syscall helper Zhangjin Wu
                   ` (9 preceding siblings ...)
  2023-06-19 15:55 ` [PATCH v4 10/10] selftests/nolibc: add mmap and munmap test cases Zhangjin Wu
@ 2023-06-28 13:07 ` Zhangjin Wu
  2023-06-28 13:08   ` [PATCH v5 01/14] tools/nolibc: sys.h: add a syscall return helper Zhangjin Wu
                     ` (14 more replies)
  10 siblings, 15 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-28 13:07 UTC (permalink / raw)
  To: thomas, w
  Cc: falcon, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

Willy, Thomas

This is the revision of our 'tools/nolibc: add a new syscall helper'
series [1].

It mainly applies the core part of suggestions from Thomas (Many thanks)
and cleans up the multiple whitespaces issues reported by
scripts/checkpatch.pl.

Changes from v4 --> v5:

* tools/nolibc: sys.h: add a syscall return helper
  tools/nolibc: unistd.h: apply __sysret() helper
  tools/nolibc: sys.h: apply __sysret() helper
  tools/nolibc: unistd.h: reorder the syscall macros
  tools/nolibc: __sysret: support syscalls who return a pointer
  selftests/nolibc: add EXPECT_PTREQ, EXPECT_PTRNE and EXPECT_PTRER
  selftests/nolibc: add sbrk_0 to test current brk getting

    The same to original v4 series, no code change.

* tools/nolibc: string.h: clean up multiple whitespaces with tab
  tools/nolibc: arch-*.h: clean up multiple whitespaces
  tools/nolibc: arch-loongarch.h: shrink with SYSCALL_CLOBBERLIST
  tools/nolibc: arch-mips.h: shrink with SYSCALL_CLOBBERLIST

    Clean up the multiple whitespaces issues reported by
    scripts/checkpatch.pl, prepare for the coming mips my_syscall6()

    This cleanup is also required by another new arch shrink patchset.

    In v4, we didn't touch multiple whitespaces, because the
    changes are huge, but it is really important to do this
    before being always 'complained' by scripts/checkpatch.pl in the
    future.

* tools/nolibc: add missing my_syscall6() for mips

    Use tab instead of multiple whitespaces, let scripts/checkpatch.pl
    happy, also apply SYSCALL_CLOBBERLIST

* tools/nolibc: clean up mmap() support

    Include <linux/mman.h> and remove more macros from nolibc side.

    The return type of sys_mmap() is reserved as before, not changed
    currently.
  
* selftests/nolibc: add mmap and munmap test cases

    Applies some suggestions from Thomas,

    - Rebase length and offset on page_size and file_size

    - make sure the last offset argument is not always zero to test
      my_syscall6()

    - easier the for loop with NULL check

    - use /proc/1/exe and /proc/self/exe for run, run-user and libc-test

      but still reserve the old init files to align our another attempt
      to remove the unnecessary dependency on procfs (this is important
      to let developers happy to do all-architectures-test, the
      accumulated time cost and wait is really appreciable, it is really
      a pain for me to do repeated all-architectures-test for the new
      'minimal' kernel config patchset [2], a v2 is ready for it).

Best regards,
Zhangjin
---
[1]: https://lore.kernel.org/lkml/cover.1687187451.git.falcon@tinylab.org/
[2]: https://lore.kernel.org/lkml/cover.1687706332.git.falcon@tinylab.org/

Zhangjin Wu (14):
  tools/nolibc: sys.h: add a syscall return helper
  tools/nolibc: unistd.h: apply __sysret() helper
  tools/nolibc: sys.h: apply __sysret() helper
  tools/nolibc: unistd.h: reorder the syscall macros
  tools/nolibc: string.h: clean up multiple whitespaces with tab
  tools/nolibc: arch-*.h: clean up multiple whitespaces
  tools/nolibc: arch-loongarch.h: shrink with SYSCALL_CLOBBERLIST
  tools/nolibc: arch-mips.h: shrink with SYSCALL_CLOBBERLIST
  tools/nolibc: add missing my_syscall6() for mips
  tools/nolibc: __sysret: support syscalls who return a pointer
  tools/nolibc: clean up mmap() support
  selftests/nolibc: add EXPECT_PTREQ, EXPECT_PTRNE and EXPECT_PTRER
  selftests/nolibc: add sbrk_0 to test current brk getting
  selftests/nolibc: add mmap and munmap test cases

 tools/include/nolibc/arch-aarch64.h          | 210 +++++-----
 tools/include/nolibc/arch-arm.h              | 240 ++++++------
 tools/include/nolibc/arch-i386.h             | 226 +++++------
 tools/include/nolibc/arch-loongarch.h        | 219 +++++------
 tools/include/nolibc/arch-mips.h             | 241 ++++++------
 tools/include/nolibc/arch-riscv.h            | 208 +++++-----
 tools/include/nolibc/arch-s390.h             | 202 +++++-----
 tools/include/nolibc/arch-x86_64.h           | 222 +++++------
 tools/include/nolibc/nolibc.h                |   9 +-
 tools/include/nolibc/string.h                |   8 +-
 tools/include/nolibc/sys.h                   | 391 +++----------------
 tools/include/nolibc/types.h                 |   6 +
 tools/include/nolibc/unistd.h                |  13 +-
 tools/testing/selftests/nolibc/nolibc-test.c | 115 ++++++
 14 files changed, 1083 insertions(+), 1227 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v5 01/14] tools/nolibc: sys.h: add a syscall return helper
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
@ 2023-06-28 13:08   ` Zhangjin Wu
  2023-06-28 13:11   ` [PATCH v5 02/14] tools/nolibc: unistd.h: apply __sysret() helper Zhangjin Wu
                     ` (13 subsequent siblings)
  14 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-28 13:08 UTC (permalink / raw)
  To: thomas, w
  Cc: falcon, arnd, david.laight, linux-kernel, linux-kselftest,
	linux-riscv, Thomas Weißschuh

Most of the library routines share the same syscall return logic:

  In general, a 0 return value indicates success.  A -1 return value
  indicates an error, and an error number is stored in errno. [1]

Let's add a __sysret() helper for the above logic to simplify the coding
and shrink the code lines too.

Thomas suggested to use inline function instead of macro for __sysret().

Willy suggested to make __sysret() be always inline.

[1]: https://man7.org/linux/man-pages/man2/syscall.2.html

Suggested-by: Willy Tarreau <w@1wt.eu>
Link: https://lore.kernel.org/linux-riscv/ZH1+hkhiA2+ItSvX@1wt.eu/
Suggested-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://lore.kernel.org/linux-riscv/ea4e7442-7223-4211-ba29-70821e907888@t-8ch.de/
Reviewed-by: Thomas Weißschuh <linux@weissschuh.net>
Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/sys.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index 5464f93e863e..097eef88cf7e 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -28,6 +28,16 @@
 #include "errno.h"
 #include "types.h"
 
+/* Syscall return helper, set errno as -ret when ret < 0 */
+static __inline__ __attribute__((unused, always_inline))
+long __sysret(long ret)
+{
+	if (ret < 0) {
+		SET_ERRNO(-ret);
+		ret = -1;
+	}
+	return ret;
+}
 
 /* Functions in this file only describe syscalls. They're declared static so
  * that the compiler usually decides to inline them while still being allowed
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 02/14] tools/nolibc: unistd.h: apply __sysret() helper
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
  2023-06-28 13:08   ` [PATCH v5 01/14] tools/nolibc: sys.h: add a syscall return helper Zhangjin Wu
@ 2023-06-28 13:11   ` Zhangjin Wu
  2023-06-28 13:13   ` [PATCH v5 03/14] tools/nolibc: sys.h: " Zhangjin Wu
                     ` (12 subsequent siblings)
  14 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-28 13:11 UTC (permalink / raw)
  To: thomas, w
  Cc: falcon, arnd, david.laight, linux-kernel, linux-kselftest,
	linux-riscv, Thomas Weißschuh

Use __sysret() to shrink the whole _syscall() to oneline code.

Reviewed-by: Thomas Weißschuh <linux@weissschuh.net>
Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/unistd.h | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/tools/include/nolibc/unistd.h b/tools/include/nolibc/unistd.h
index 0e832e10a0b2..fabc846f797b 100644
--- a/tools/include/nolibc/unistd.h
+++ b/tools/include/nolibc/unistd.h
@@ -56,16 +56,7 @@ int tcsetpgrp(int fd, pid_t pid)
 	return ioctl(fd, TIOCSPGRP, &pid);
 }
 
-#define _syscall(N, ...)                                                      \
-({                                                                            \
-	long _ret = my_syscall##N(__VA_ARGS__);                               \
-	if (_ret < 0) {                                                       \
-		SET_ERRNO(-_ret);                                             \
-		_ret = -1;                                                    \
-	}                                                                     \
-	_ret;                                                                 \
-})
-
+#define _syscall(N, ...) __sysret(my_syscall##N(__VA_ARGS__))
 #define _syscall_narg(...) __syscall_narg(__VA_ARGS__, 6, 5, 4, 3, 2, 1, 0)
 #define __syscall_narg(_0, _1, _2, _3, _4, _5, _6, N, ...) N
 #define _syscall_n(N, ...) _syscall(N, __VA_ARGS__)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 03/14] tools/nolibc: sys.h: apply __sysret() helper
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
  2023-06-28 13:08   ` [PATCH v5 01/14] tools/nolibc: sys.h: add a syscall return helper Zhangjin Wu
  2023-06-28 13:11   ` [PATCH v5 02/14] tools/nolibc: unistd.h: apply __sysret() helper Zhangjin Wu
@ 2023-06-28 13:13   ` Zhangjin Wu
  2023-06-28 13:14   ` [PATCH v5 04/14] tools/nolibc: unistd.h: reorder the syscall macros Zhangjin Wu
                     ` (11 subsequent siblings)
  14 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-28 13:13 UTC (permalink / raw)
  To: thomas, w
  Cc: falcon, arnd, david.laight, linux-kernel, linux-kselftest,
	linux-riscv, Thomas Weißschuh

Use __sysret() to shrink most of the library routines to oneline code.

Removed 266 lines of duplicated code.

Reviewed-by: Thomas Weißschuh <linux@weissschuh.net>
Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/sys.h | 354 +++++--------------------------------
 1 file changed, 44 insertions(+), 310 deletions(-)

diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index 097eef88cf7e..53bc3ad6593e 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -76,13 +76,7 @@ void *sys_brk(void *addr)
 static __attribute__((unused))
 int brk(void *addr)
 {
-	void *ret = sys_brk(addr);
-
-	if (!ret) {
-		SET_ERRNO(ENOMEM);
-		return -1;
-	}
-	return 0;
+	return __sysret(sys_brk(addr) ? 0 : -ENOMEM);
 }
 
 static __attribute__((unused))
@@ -112,13 +106,7 @@ int sys_chdir(const char *path)
 static __attribute__((unused))
 int chdir(const char *path)
 {
-	int ret = sys_chdir(path);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_chdir(path));
 }
 
 
@@ -141,13 +129,7 @@ int sys_chmod(const char *path, mode_t mode)
 static __attribute__((unused))
 int chmod(const char *path, mode_t mode)
 {
-	int ret = sys_chmod(path, mode);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_chmod(path, mode));
 }
 
 
@@ -170,13 +152,7 @@ int sys_chown(const char *path, uid_t owner, gid_t group)
 static __attribute__((unused))
 int chown(const char *path, uid_t owner, gid_t group)
 {
-	int ret = sys_chown(path, owner, group);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_chown(path, owner, group));
 }
 
 
@@ -193,13 +169,7 @@ int sys_chroot(const char *path)
 static __attribute__((unused))
 int chroot(const char *path)
 {
-	int ret = sys_chroot(path);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_chroot(path));
 }
 
 
@@ -216,13 +186,7 @@ int sys_close(int fd)
 static __attribute__((unused))
 int close(int fd)
 {
-	int ret = sys_close(fd);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_close(fd));
 }
 
 
@@ -239,13 +203,7 @@ int sys_dup(int fd)
 static __attribute__((unused))
 int dup(int fd)
 {
-	int ret = sys_dup(fd);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_dup(fd));
 }
 
 
@@ -268,13 +226,7 @@ int sys_dup2(int old, int new)
 static __attribute__((unused))
 int dup2(int old, int new)
 {
-	int ret = sys_dup2(old, new);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_dup2(old, new));
 }
 
 
@@ -292,13 +244,7 @@ int sys_dup3(int old, int new, int flags)
 static __attribute__((unused))
 int dup3(int old, int new, int flags)
 {
-	int ret = sys_dup3(old, new, flags);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_dup3(old, new, flags));
 }
 #endif
 
@@ -316,13 +262,7 @@ int sys_execve(const char *filename, char *const argv[], char *const envp[])
 static __attribute__((unused))
 int execve(const char *filename, char *const argv[], char *const envp[])
 {
-	int ret = sys_execve(filename, argv, envp);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_execve(filename, argv, envp));
 }
 
 
@@ -369,13 +309,7 @@ pid_t sys_fork(void)
 static __attribute__((unused))
 pid_t fork(void)
 {
-	pid_t ret = sys_fork();
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_fork());
 }
 
 
@@ -392,13 +326,7 @@ int sys_fsync(int fd)
 static __attribute__((unused))
 int fsync(int fd)
 {
-	int ret = sys_fsync(fd);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_fsync(fd));
 }
 
 
@@ -415,13 +343,7 @@ int sys_getdents64(int fd, struct linux_dirent64 *dirp, int count)
 static __attribute__((unused))
 int getdents64(int fd, struct linux_dirent64 *dirp, int count)
 {
-	int ret = sys_getdents64(fd, dirp, count);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_getdents64(fd, dirp, count));
 }
 
 
@@ -459,13 +381,7 @@ pid_t sys_getpgid(pid_t pid)
 static __attribute__((unused))
 pid_t getpgid(pid_t pid)
 {
-	pid_t ret = sys_getpgid(pid);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_getpgid(pid));
 }
 
 
@@ -545,15 +461,7 @@ static unsigned long getauxval(unsigned long key);
 static __attribute__((unused))
 long getpagesize(void)
 {
-	long ret;
-
-	ret = getauxval(AT_PAGESZ);
-	if (!ret) {
-		SET_ERRNO(ENOENT);
-		return -1;
-	}
-
-	return ret;
+	return __sysret(getauxval(AT_PAGESZ) ?: -ENOENT);
 }
 
 
@@ -574,13 +482,7 @@ int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
 static __attribute__((unused))
 int gettimeofday(struct timeval *tv, struct timezone *tz)
 {
-	int ret = sys_gettimeofday(tv, tz);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_gettimeofday(tv, tz));
 }
 
 
@@ -618,13 +520,7 @@ int sys_ioctl(int fd, unsigned long req, void *value)
 static __attribute__((unused))
 int ioctl(int fd, unsigned long req, void *value)
 {
-	int ret = sys_ioctl(fd, req, value);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_ioctl(fd, req, value));
 }
 
 /*
@@ -640,13 +536,7 @@ int sys_kill(pid_t pid, int signal)
 static __attribute__((unused))
 int kill(pid_t pid, int signal)
 {
-	int ret = sys_kill(pid, signal);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_kill(pid, signal));
 }
 
 
@@ -669,13 +559,7 @@ int sys_link(const char *old, const char *new)
 static __attribute__((unused))
 int link(const char *old, const char *new)
 {
-	int ret = sys_link(old, new);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_link(old, new));
 }
 
 
@@ -696,13 +580,7 @@ off_t sys_lseek(int fd, off_t offset, int whence)
 static __attribute__((unused))
 off_t lseek(int fd, off_t offset, int whence)
 {
-	off_t ret = sys_lseek(fd, offset, whence);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_lseek(fd, offset, whence));
 }
 
 
@@ -725,13 +603,7 @@ int sys_mkdir(const char *path, mode_t mode)
 static __attribute__((unused))
 int mkdir(const char *path, mode_t mode)
 {
-	int ret = sys_mkdir(path, mode);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_mkdir(path, mode));
 }
 
 
@@ -754,13 +626,7 @@ long sys_mknod(const char *path, mode_t mode, dev_t dev)
 static __attribute__((unused))
 int mknod(const char *path, mode_t mode, dev_t dev)
 {
-	int ret = sys_mknod(path, mode, dev);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_mknod(path, mode, dev));
 }
 
 #ifndef MAP_SHARED
@@ -818,13 +684,7 @@ int sys_munmap(void *addr, size_t length)
 static __attribute__((unused))
 int munmap(void *addr, size_t length)
 {
-	int ret = sys_munmap(addr, length);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_munmap(addr, length));
 }
 
 /*
@@ -844,13 +704,7 @@ int mount(const char *src, const char *tgt,
           const char *fst, unsigned long flags,
           const void *data)
 {
-	int ret = sys_mount(src, tgt, fst, flags, data);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_mount(src, tgt, fst, flags, data));
 }
 
 
@@ -884,13 +738,7 @@ int open(const char *path, int flags, ...)
 		va_end(args);
 	}
 
-	ret = sys_open(path, flags, mode);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_open(path, flags, mode));
 }
 
 
@@ -910,13 +758,7 @@ static __attribute__((unused))
 int prctl(int option, unsigned long arg2, unsigned long arg3,
 		      unsigned long arg4, unsigned long arg5)
 {
-	int ret = sys_prctl(option, arg2, arg3, arg4, arg5);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_prctl(option, arg2, arg3, arg4, arg5));
 }
 
 
@@ -933,13 +775,7 @@ int sys_pivot_root(const char *new, const char *old)
 static __attribute__((unused))
 int pivot_root(const char *new, const char *old)
 {
-	int ret = sys_pivot_root(new, old);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_pivot_root(new, old));
 }
 
 
@@ -968,13 +804,7 @@ int sys_poll(struct pollfd *fds, int nfds, int timeout)
 static __attribute__((unused))
 int poll(struct pollfd *fds, int nfds, int timeout)
 {
-	int ret = sys_poll(fds, nfds, timeout);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_poll(fds, nfds, timeout));
 }
 
 
@@ -991,13 +821,7 @@ ssize_t sys_read(int fd, void *buf, size_t count)
 static __attribute__((unused))
 ssize_t read(int fd, void *buf, size_t count)
 {
-	ssize_t ret = sys_read(fd, buf, count);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_read(fd, buf, count));
 }
 
 
@@ -1015,13 +839,7 @@ ssize_t sys_reboot(int magic1, int magic2, int cmd, void *arg)
 static __attribute__((unused))
 int reboot(int cmd)
 {
-	int ret = sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, 0);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, 0));
 }
 
 
@@ -1038,13 +856,7 @@ int sys_sched_yield(void)
 static __attribute__((unused))
 int sched_yield(void)
 {
-	int ret = sys_sched_yield();
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_sched_yield());
 }
 
 
@@ -1084,13 +896,7 @@ int sys_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeva
 static __attribute__((unused))
 int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout)
 {
-	int ret = sys_select(nfds, rfds, wfds, efds, timeout);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_select(nfds, rfds, wfds, efds, timeout));
 }
 
 
@@ -1107,13 +913,7 @@ int sys_setpgid(pid_t pid, pid_t pgid)
 static __attribute__((unused))
 int setpgid(pid_t pid, pid_t pgid)
 {
-	int ret = sys_setpgid(pid, pgid);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_setpgid(pid, pgid));
 }
 
 
@@ -1130,13 +930,7 @@ pid_t sys_setsid(void)
 static __attribute__((unused))
 pid_t setsid(void)
 {
-	pid_t ret = sys_setsid();
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_setsid());
 }
 
 #if defined(__NR_statx)
@@ -1153,13 +947,7 @@ int sys_statx(int fd, const char *path, int flags, unsigned int mask, struct sta
 static __attribute__((unused))
 int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
 {
-	int ret = sys_statx(fd, path, flags, mask, buf);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_statx(fd, path, flags, mask, buf));
 }
 #endif
 
@@ -1239,13 +1027,7 @@ int sys_stat(const char *path, struct stat *buf)
 static __attribute__((unused))
 int stat(const char *path, struct stat *buf)
 {
-	int ret = sys_stat(path, buf);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_stat(path, buf));
 }
 
 
@@ -1268,13 +1050,7 @@ int sys_symlink(const char *old, const char *new)
 static __attribute__((unused))
 int symlink(const char *old, const char *new)
 {
-	int ret = sys_symlink(old, new);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_symlink(old, new));
 }
 
 
@@ -1308,13 +1084,7 @@ int sys_umount2(const char *path, int flags)
 static __attribute__((unused))
 int umount2(const char *path, int flags)
 {
-	int ret = sys_umount2(path, flags);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_umount2(path, flags));
 }
 
 
@@ -1337,13 +1107,7 @@ int sys_unlink(const char *path)
 static __attribute__((unused))
 int unlink(const char *path)
 {
-	int ret = sys_unlink(path);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_unlink(path));
 }
 
 
@@ -1366,38 +1130,20 @@ pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage)
 static __attribute__((unused))
 pid_t wait(int *status)
 {
-	pid_t ret = sys_wait4(-1, status, 0, NULL);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_wait4(-1, status, 0, NULL));
 }
 
 static __attribute__((unused))
 pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage)
 {
-	pid_t ret = sys_wait4(pid, status, options, rusage);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_wait4(pid, status, options, rusage));
 }
 
 
 static __attribute__((unused))
 pid_t waitpid(pid_t pid, int *status, int options)
 {
-	pid_t ret = sys_wait4(pid, status, options, NULL);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_wait4(pid, status, options, NULL));
 }
 
 
@@ -1414,13 +1160,7 @@ ssize_t sys_write(int fd, const void *buf, size_t count)
 static __attribute__((unused))
 ssize_t write(int fd, const void *buf, size_t count)
 {
-	ssize_t ret = sys_write(fd, buf, count);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_write(fd, buf, count));
 }
 
 
@@ -1437,13 +1177,7 @@ int sys_memfd_create(const char *name, unsigned int flags)
 static __attribute__((unused))
 int memfd_create(const char *name, unsigned int flags)
 {
-	ssize_t ret = sys_memfd_create(name, flags);
-
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
-	}
-	return ret;
+	return __sysret(sys_memfd_create(name, flags));
 }
 
 /* make sure to include all global symbols */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 04/14] tools/nolibc: unistd.h: reorder the syscall macros
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
                     ` (2 preceding siblings ...)
  2023-06-28 13:13   ` [PATCH v5 03/14] tools/nolibc: sys.h: " Zhangjin Wu
@ 2023-06-28 13:14   ` Zhangjin Wu
  2023-06-28 13:17   ` [PATCH v5 05/14] tools/nolibc: string.h: clean up multiple whitespaces with tab Zhangjin Wu
                     ` (10 subsequent siblings)
  14 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-28 13:14 UTC (permalink / raw)
  To: thomas, w
  Cc: falcon, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

Tune the macros in the using order and align most of them.

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/unistd.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/include/nolibc/unistd.h b/tools/include/nolibc/unistd.h
index fabc846f797b..e38f3660c051 100644
--- a/tools/include/nolibc/unistd.h
+++ b/tools/include/nolibc/unistd.h
@@ -56,9 +56,9 @@ int tcsetpgrp(int fd, pid_t pid)
 	return ioctl(fd, TIOCSPGRP, &pid);
 }
 
-#define _syscall(N, ...) __sysret(my_syscall##N(__VA_ARGS__))
-#define _syscall_narg(...) __syscall_narg(__VA_ARGS__, 6, 5, 4, 3, 2, 1, 0)
 #define __syscall_narg(_0, _1, _2, _3, _4, _5, _6, N, ...) N
+#define _syscall_narg(...) __syscall_narg(__VA_ARGS__, 6, 5, 4, 3, 2, 1, 0)
+#define _syscall(N, ...) __sysret(my_syscall##N(__VA_ARGS__))
 #define _syscall_n(N, ...) _syscall(N, __VA_ARGS__)
 #define syscall(...) _syscall_n(_syscall_narg(__VA_ARGS__), ##__VA_ARGS__)
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 05/14] tools/nolibc: string.h: clean up multiple whitespaces with tab
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
                     ` (3 preceding siblings ...)
  2023-06-28 13:14   ` [PATCH v5 04/14] tools/nolibc: unistd.h: reorder the syscall macros Zhangjin Wu
@ 2023-06-28 13:17   ` Zhangjin Wu
  2023-06-28 13:19   ` [PATCH v5 06/14] tools/nolibc: arch-*.h: clean up multiple whitespaces Zhangjin Wu
                     ` (9 subsequent siblings)
  14 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-28 13:17 UTC (permalink / raw)
  To: thomas, w
  Cc: falcon, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

To align with Linux code style and let scripts/checkpatch.pl happy, the
multiple whitespaces in arch-<ARCH>.h files are cleaned up with tab.

It is detected by:

    $ grep '  *\\$' tools/include/nolibc/string.h

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/string.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/include/nolibc/string.h b/tools/include/nolibc/string.h
index 0c2e06c7c477..e8f471ce09f3 100644
--- a/tools/include/nolibc/string.h
+++ b/tools/include/nolibc/string.h
@@ -148,10 +148,10 @@ size_t strlen(const char *str)
  */
 #if defined(__OPTIMIZE__)
 #define nolibc_strlen(x) strlen(x)
-#define strlen(str) ({                          \
-	__builtin_constant_p((str)) ?           \
-		__builtin_strlen((str)) :       \
-		nolibc_strlen((str));           \
+#define strlen(str) ({				\
+	__builtin_constant_p((str)) ?		\
+		__builtin_strlen((str)) :	\
+		nolibc_strlen((str));		\
 })
 #endif
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 06/14] tools/nolibc: arch-*.h: clean up multiple whitespaces
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
                     ` (4 preceding siblings ...)
  2023-06-28 13:17   ` [PATCH v5 05/14] tools/nolibc: string.h: clean up multiple whitespaces with tab Zhangjin Wu
@ 2023-06-28 13:19   ` Zhangjin Wu
  2023-07-02 18:44     ` Willy Tarreau
  2023-06-28 13:22   ` [PATCH v5 07/14] tools/nolibc: arch-loongarch.h: shrink with SYSCALL_CLOBBERLIST Zhangjin Wu
                     ` (8 subsequent siblings)
  14 siblings, 1 reply; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-28 13:19 UTC (permalink / raw)
  To: thomas, w
  Cc: falcon, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

To align with Linux code style and let scripts/checkpatch.pl happy, the
multiple whitespaces in arch-<ARCH>.h files are cleaned up.

Most of them are modified by these commands automatically:

    $ sed -i -e '/#define my_syscall/,/})/{s/        /\t/g}' tools/include/nolibc/arch-*.h
    $ sed -i -e '/#define my_syscall/,/})/{s/ *\\$/\t\\/g}' tools/include/nolibc/arch-*.h

And checked with:

    $ grep '  *\\$' tools/include/nolibc/arch-*.h

Besides, more multiple whitespaces are cleaned up:

- convert "__asm__  volatile" to "__asm__ volatile"
- "foo _num  bar" should be "foo _num bar"

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/arch-aarch64.h   | 210 +++++++++++-----------
 tools/include/nolibc/arch-arm.h       | 240 +++++++++++++-------------
 tools/include/nolibc/arch-i386.h      | 226 ++++++++++++------------
 tools/include/nolibc/arch-loongarch.h | 222 ++++++++++++------------
 tools/include/nolibc/arch-mips.h      | 218 +++++++++++------------
 tools/include/nolibc/arch-riscv.h     | 208 +++++++++++-----------
 tools/include/nolibc/arch-s390.h      | 202 +++++++++++-----------
 tools/include/nolibc/arch-x86_64.h    | 222 ++++++++++++------------
 8 files changed, 874 insertions(+), 874 deletions(-)

diff --git a/tools/include/nolibc/arch-aarch64.h b/tools/include/nolibc/arch-aarch64.h
index 11f294a406b7..e30056f996db 100644
--- a/tools/include/nolibc/arch-aarch64.h
+++ b/tools/include/nolibc/arch-aarch64.h
@@ -52,123 +52,123 @@ struct sys_stat_struct {
  */
 #define __ARCH_WANT_SYS_PSELECT6
 
-#define my_syscall0(num)                                                      \
-({                                                                            \
-	register long _num  __asm__ ("x8") = (num);                           \
-	register long _arg1 __asm__ ("x0");                                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"svc #0\n"                                                    \
-		: "=r"(_arg1)                                                 \
-		: "r"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall0(num)							\
+({										\
+	register long _num __asm__ ("x8") = (num);				\
+	register long _arg1 __asm__ ("x0");					\
+										\
+	__asm__ volatile (							\
+		"svc #0\n"							\
+		: "=r"(_arg1)							\
+		: "r"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall1(num, arg1)                                                \
-({                                                                            \
-	register long _num  __asm__ ("x8") = (num);                           \
-	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"svc #0\n"                                                    \
-		: "=r"(_arg1)                                                 \
-		: "r"(_arg1),                                                 \
-		  "r"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall1(num, arg1)							\
+({										\
+	register long _num __asm__ ("x8")  = (num);				\
+	register long _arg1 __asm__ ("x0") = (long)(arg1);			\
+										\
+	__asm__ volatile (							\
+		"svc #0\n"							\
+		: "=r"(_arg1)							\
+		: "r"(_arg1),							\
+		  "r"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall2(num, arg1, arg2)                                          \
-({                                                                            \
-	register long _num  __asm__ ("x8") = (num);                           \
-	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"svc #0\n"                                                    \
-		: "=r"(_arg1)                                                 \
-		: "r"(_arg1), "r"(_arg2),                                     \
-		  "r"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall2(num, arg1, arg2)						\
+({										\
+	register long _num __asm__ ("x8")  = (num);				\
+	register long _arg1 __asm__ ("x0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("x1") = (long)(arg2);			\
+										\
+	__asm__ volatile (							\
+		"svc #0\n"							\
+		: "=r"(_arg1)							\
+		: "r"(_arg1), "r"(_arg2),					\
+		  "r"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall3(num, arg1, arg2, arg3)                                    \
-({                                                                            \
-	register long _num  __asm__ ("x8") = (num);                           \
-	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"svc #0\n"                                                    \
-		: "=r"(_arg1)                                                 \
-		: "r"(_arg1), "r"(_arg2), "r"(_arg3),                         \
-		  "r"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall3(num, arg1, arg2, arg3)					\
+({										\
+	register long _num __asm__ ("x8")  = (num);				\
+	register long _arg1 __asm__ ("x0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("x1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("x2") = (long)(arg3);			\
+										\
+	__asm__ volatile (							\
+		"svc #0\n"							\
+		: "=r"(_arg1)							\
+		: "r"(_arg1), "r"(_arg2), "r"(_arg3),				\
+		  "r"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
-({                                                                            \
-	register long _num  __asm__ ("x8") = (num);                           \
-	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
-	register long _arg4 __asm__ ("x3") = (long)(arg4);                    \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"svc #0\n"                                                    \
-		: "=r"(_arg1)                                                 \
-		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),             \
-		  "r"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall4(num, arg1, arg2, arg3, arg4)				\
+({										\
+	register long _num __asm__ ("x8")  = (num);				\
+	register long _arg1 __asm__ ("x0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("x1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("x2") = (long)(arg3);			\
+	register long _arg4 __asm__ ("x3") = (long)(arg4);			\
+										\
+	__asm__ volatile (							\
+		"svc #0\n"							\
+		: "=r"(_arg1)							\
+		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),		\
+		  "r"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
-({                                                                            \
-	register long _num  __asm__ ("x8") = (num);                           \
-	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
-	register long _arg4 __asm__ ("x3") = (long)(arg4);                    \
-	register long _arg5 __asm__ ("x4") = (long)(arg5);                    \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"svc #0\n"                                                    \
-		: "=r" (_arg1)                                                \
-		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
-		  "r"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)				\
+({										\
+	register long _num __asm__ ("x8")  = (num);				\
+	register long _arg1 __asm__ ("x0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("x1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("x2") = (long)(arg3);			\
+	register long _arg4 __asm__ ("x3") = (long)(arg4);			\
+	register long _arg5 __asm__ ("x4") = (long)(arg5);			\
+										\
+	__asm__ volatile (							\
+		"svc #0\n"							\
+		: "=r" (_arg1)							\
+		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),	\
+		  "r"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \
-({                                                                            \
-	register long _num  __asm__ ("x8") = (num);                           \
-	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
-	register long _arg4 __asm__ ("x3") = (long)(arg4);                    \
-	register long _arg5 __asm__ ("x4") = (long)(arg5);                    \
-	register long _arg6 __asm__ ("x5") = (long)(arg6);                    \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"svc #0\n"                                                    \
-		: "=r" (_arg1)                                                \
-		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
-		  "r"(_arg6), "r"(_num)                                       \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)			\
+({										\
+	register long _num __asm__ ("x8")  = (num);				\
+	register long _arg1 __asm__ ("x0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("x1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("x2") = (long)(arg3);			\
+	register long _arg4 __asm__ ("x3") = (long)(arg4);			\
+	register long _arg5 __asm__ ("x4") = (long)(arg5);			\
+	register long _arg6 __asm__ ("x5") = (long)(arg6);			\
+										\
+	__asm__ volatile (							\
+		"svc #0\n"							\
+		: "=r" (_arg1)							\
+		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),	\
+		  "r"(_arg6), "r"(_num)						\
+		: "memory", "cc"						\
+	);									\
+	_arg1;									\
 })
 
 char **environ __attribute__((weak));
diff --git a/tools/include/nolibc/arch-arm.h b/tools/include/nolibc/arch-arm.h
index ca4c66987497..7a64290fc518 100644
--- a/tools/include/nolibc/arch-arm.h
+++ b/tools/include/nolibc/arch-arm.h
@@ -86,138 +86,138 @@ struct sys_stat_struct {
 
 #endif /* end THUMB */
 
-#define my_syscall0(num)                                                      \
-({                                                                            \
-	register long _num  __asm__(_NOLIBC_SYSCALL_REG) = (num);             \
-	register long _arg1 __asm__ ("r0");                                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		_NOLIBC_THUMB_SET_R7                                          \
-		"svc #0\n"                                                    \
-		_NOLIBC_THUMB_RESTORE_R7                                      \
-		: "=r"(_arg1), "=r"(_num)                                     \
-		: "r"(_arg1),                                                 \
-		  "r"(_num)                                                   \
-		: "memory", "cc", "lr"                                        \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall0(num)							\
+({										\
+	register long _num __asm__ (_NOLIBC_SYSCALL_REG) = (num);		\
+	register long _arg1 __asm__ ("r0");					\
+										\
+	__asm__ volatile (							\
+		_NOLIBC_THUMB_SET_R7						\
+		"svc #0\n"							\
+		_NOLIBC_THUMB_RESTORE_R7					\
+		: "=r"(_arg1), "=r"(_num)					\
+		: "r"(_arg1),							\
+		  "r"(_num)							\
+		: "memory", "cc", "lr"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall1(num, arg1)                                                \
-({                                                                            \
-	register long _num  __asm__(_NOLIBC_SYSCALL_REG) = (num);             \
-	register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		_NOLIBC_THUMB_SET_R7                                          \
-		"svc #0\n"                                                    \
-		_NOLIBC_THUMB_RESTORE_R7                                      \
-		: "=r"(_arg1), "=r" (_num)                                    \
-		: "r"(_arg1),                                                 \
-		  "r"(_num)                                                   \
-		: "memory", "cc", "lr"                                        \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall1(num, arg1)							\
+({										\
+	register long _num __asm__ (_NOLIBC_SYSCALL_REG) = (num);		\
+	register long _arg1 __asm__ ("r0") = (long)(arg1);			\
+										\
+	__asm__ volatile (							\
+		_NOLIBC_THUMB_SET_R7						\
+		"svc #0\n"							\
+		_NOLIBC_THUMB_RESTORE_R7					\
+		: "=r"(_arg1), "=r" (_num)					\
+		: "r"(_arg1),							\
+		  "r"(_num)							\
+		: "memory", "cc", "lr"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall2(num, arg1, arg2)                                          \
-({                                                                            \
-	register long _num  __asm__(_NOLIBC_SYSCALL_REG) = (num);             \
-	register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("r1") = (long)(arg2);                    \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		_NOLIBC_THUMB_SET_R7                                          \
-		"svc #0\n"                                                    \
-		_NOLIBC_THUMB_RESTORE_R7                                      \
-		: "=r"(_arg1), "=r" (_num)                                    \
-		: "r"(_arg1), "r"(_arg2),                                     \
-		  "r"(_num)                                                   \
-		: "memory", "cc", "lr"                                        \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall2(num, arg1, arg2)						\
+({										\
+	register long _num __asm__ (_NOLIBC_SYSCALL_REG) = (num);		\
+	register long _arg1 __asm__ ("r0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("r1") = (long)(arg2);			\
+										\
+	__asm__ volatile (							\
+		_NOLIBC_THUMB_SET_R7						\
+		"svc #0\n"							\
+		_NOLIBC_THUMB_RESTORE_R7					\
+		: "=r"(_arg1), "=r" (_num)					\
+		: "r"(_arg1), "r"(_arg2),					\
+		  "r"(_num)							\
+		: "memory", "cc", "lr"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall3(num, arg1, arg2, arg3)                                    \
-({                                                                            \
-	register long _num  __asm__(_NOLIBC_SYSCALL_REG) = (num);             \
-	register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("r1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("r2") = (long)(arg3);                    \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		_NOLIBC_THUMB_SET_R7                                          \
-		"svc #0\n"                                                    \
-		_NOLIBC_THUMB_RESTORE_R7                                      \
-		: "=r"(_arg1), "=r" (_num)                                    \
-		: "r"(_arg1), "r"(_arg2), "r"(_arg3),                         \
-		  "r"(_num)                                                   \
-		: "memory", "cc", "lr"                                        \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall3(num, arg1, arg2, arg3)					\
+({										\
+	register long _num __asm__ (_NOLIBC_SYSCALL_REG) = (num);		\
+	register long _arg1 __asm__ ("r0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("r1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("r2") = (long)(arg3);			\
+										\
+	__asm__ volatile (							\
+		_NOLIBC_THUMB_SET_R7						\
+		"svc #0\n"							\
+		_NOLIBC_THUMB_RESTORE_R7					\
+		: "=r"(_arg1), "=r" (_num)					\
+		: "r"(_arg1), "r"(_arg2), "r"(_arg3),				\
+		  "r"(_num)							\
+		: "memory", "cc", "lr"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
-({                                                                            \
-	register long _num  __asm__(_NOLIBC_SYSCALL_REG) = (num);             \
-	register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("r1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("r2") = (long)(arg3);                    \
-	register long _arg4 __asm__ ("r3") = (long)(arg4);                    \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		_NOLIBC_THUMB_SET_R7                                          \
-		"svc #0\n"                                                    \
-		_NOLIBC_THUMB_RESTORE_R7                                      \
-		: "=r"(_arg1), "=r" (_num)                                    \
-		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),             \
-		  "r"(_num)                                                   \
-		: "memory", "cc", "lr"                                        \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall4(num, arg1, arg2, arg3, arg4)				\
+({										\
+	register long _num __asm__ (_NOLIBC_SYSCALL_REG) = (num);		\
+	register long _arg1 __asm__ ("r0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("r1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("r2") = (long)(arg3);			\
+	register long _arg4 __asm__ ("r3") = (long)(arg4);			\
+										\
+	__asm__ volatile (							\
+		_NOLIBC_THUMB_SET_R7						\
+		"svc #0\n"							\
+		_NOLIBC_THUMB_RESTORE_R7					\
+		: "=r"(_arg1), "=r" (_num)					\
+		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),		\
+		  "r"(_num)							\
+		: "memory", "cc", "lr"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
-({                                                                            \
-	register long _num  __asm__(_NOLIBC_SYSCALL_REG) = (num);             \
-	register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("r1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("r2") = (long)(arg3);                    \
-	register long _arg4 __asm__ ("r3") = (long)(arg4);                    \
-	register long _arg5 __asm__ ("r4") = (long)(arg5);                    \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		_NOLIBC_THUMB_SET_R7                                          \
-		"svc #0\n"                                                    \
-		_NOLIBC_THUMB_RESTORE_R7                                      \
-		: "=r"(_arg1), "=r" (_num)                                    \
-		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
-		  "r"(_num)                                                   \
-		: "memory", "cc", "lr"                                        \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)				\
+({										\
+	register long _num __asm__ (_NOLIBC_SYSCALL_REG) = (num);		\
+	register long _arg1 __asm__ ("r0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("r1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("r2") = (long)(arg3);			\
+	register long _arg4 __asm__ ("r3") = (long)(arg4);			\
+	register long _arg5 __asm__ ("r4") = (long)(arg5);			\
+										\
+	__asm__ volatile (							\
+		_NOLIBC_THUMB_SET_R7						\
+		"svc #0\n"							\
+		_NOLIBC_THUMB_RESTORE_R7					\
+		: "=r"(_arg1), "=r" (_num)					\
+		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),	\
+		  "r"(_num)							\
+		: "memory", "cc", "lr"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \
-({                                                                            \
-	register long _num  __asm__(_NOLIBC_SYSCALL_REG) = (num);             \
-	register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("r1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("r2") = (long)(arg3);                    \
-	register long _arg4 __asm__ ("r3") = (long)(arg4);                    \
-	register long _arg5 __asm__ ("r4") = (long)(arg5);                    \
-	register long _arg6 __asm__ ("r5") = (long)(arg6);                    \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		_NOLIBC_THUMB_SET_R7                                          \
-		"svc #0\n"                                                    \
-		_NOLIBC_THUMB_RESTORE_R7                                      \
-		: "=r"(_arg1), "=r" (_num)                                    \
-		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
-		  "r"(_arg6), "r"(_num)                                       \
-		: "memory", "cc", "lr"                                        \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)			\
+({										\
+	register long _num __asm__ (_NOLIBC_SYSCALL_REG) = (num);		\
+	register long _arg1 __asm__ ("r0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("r1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("r2") = (long)(arg3);			\
+	register long _arg4 __asm__ ("r3") = (long)(arg4);			\
+	register long _arg5 __asm__ ("r4") = (long)(arg5);			\
+	register long _arg6 __asm__ ("r5") = (long)(arg6);			\
+										\
+	__asm__ volatile (							\
+		_NOLIBC_THUMB_SET_R7						\
+		"svc #0\n"							\
+		_NOLIBC_THUMB_RESTORE_R7					\
+		: "=r"(_arg1), "=r" (_num)					\
+		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),	\
+		  "r"(_arg6), "r"(_num)						\
+		: "memory", "cc", "lr"						\
+	);									\
+	_arg1;									\
 })
 
 
diff --git a/tools/include/nolibc/arch-i386.h b/tools/include/nolibc/arch-i386.h
index 3d672d925e9e..c2e75ba91b6b 100644
--- a/tools/include/nolibc/arch-i386.h
+++ b/tools/include/nolibc/arch-i386.h
@@ -53,131 +53,131 @@ struct sys_stat_struct {
  */
 #define __ARCH_WANT_SYS_OLD_SELECT
 
-#define my_syscall0(num)                                                      \
-({                                                                            \
-	long _ret;                                                            \
-	register long _num __asm__ ("eax") = (num);                           \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"int $0x80\n"                                                 \
-		: "=a" (_ret)                                                 \
-		: "0"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_ret;                                                                 \
+#define my_syscall0(num)							\
+({										\
+	long _ret;								\
+	register long _num __asm__ ("eax") = (num);				\
+										\
+	__asm__ volatile (							\
+		"int $0x80\n"							\
+		: "=a" (_ret)							\
+		: "0"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_ret;									\
 })
 
-#define my_syscall1(num, arg1)                                                \
-({                                                                            \
-	long _ret;                                                            \
-	register long _num __asm__ ("eax") = (num);                           \
-	register long _arg1 __asm__ ("ebx") = (long)(arg1);                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"int $0x80\n"                                                 \
-		: "=a" (_ret)                                                 \
-		: "r"(_arg1),                                                 \
-		  "0"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_ret;                                                                 \
+#define my_syscall1(num, arg1)							\
+({										\
+	long _ret;								\
+	register long _num __asm__ ("eax")  = (num);				\
+	register long _arg1 __asm__ ("ebx") = (long)(arg1);			\
+										\
+	__asm__ volatile (							\
+		"int $0x80\n"							\
+		: "=a" (_ret)							\
+		: "r"(_arg1),							\
+		  "0"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_ret;									\
 })
 
-#define my_syscall2(num, arg1, arg2)                                          \
-({                                                                            \
-	long _ret;                                                            \
-	register long _num __asm__ ("eax") = (num);                           \
-	register long _arg1 __asm__ ("ebx") = (long)(arg1);                   \
-	register long _arg2 __asm__ ("ecx") = (long)(arg2);                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"int $0x80\n"                                                 \
-		: "=a" (_ret)                                                 \
-		: "r"(_arg1), "r"(_arg2),                                     \
-		  "0"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_ret;                                                                 \
+#define my_syscall2(num, arg1, arg2)						\
+({										\
+	long _ret;								\
+	register long _num __asm__ ("eax")  = (num);				\
+	register long _arg1 __asm__ ("ebx") = (long)(arg1);			\
+	register long _arg2 __asm__ ("ecx") = (long)(arg2);			\
+										\
+	__asm__ volatile (							\
+		"int $0x80\n"							\
+		: "=a" (_ret)							\
+		: "r"(_arg1), "r"(_arg2),					\
+		  "0"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_ret;									\
 })
 
-#define my_syscall3(num, arg1, arg2, arg3)                                    \
-({                                                                            \
-	long _ret;                                                            \
-	register long _num __asm__ ("eax") = (num);                           \
-	register long _arg1 __asm__ ("ebx") = (long)(arg1);                   \
-	register long _arg2 __asm__ ("ecx") = (long)(arg2);                   \
-	register long _arg3 __asm__ ("edx") = (long)(arg3);                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"int $0x80\n"                                                 \
-		: "=a" (_ret)                                                 \
-		: "r"(_arg1), "r"(_arg2), "r"(_arg3),                         \
-		  "0"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_ret;                                                                 \
+#define my_syscall3(num, arg1, arg2, arg3)					\
+({										\
+	long _ret;								\
+	register long _num __asm__ ("eax")  = (num);				\
+	register long _arg1 __asm__ ("ebx") = (long)(arg1);			\
+	register long _arg2 __asm__ ("ecx") = (long)(arg2);			\
+	register long _arg3 __asm__ ("edx") = (long)(arg3);			\
+										\
+	__asm__ volatile (							\
+		"int $0x80\n"							\
+		: "=a" (_ret)							\
+		: "r"(_arg1), "r"(_arg2), "r"(_arg3),				\
+		  "0"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_ret;									\
 })
 
-#define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
-({                                                                            \
-	long _ret;                                                            \
-	register long _num __asm__ ("eax") = (num);                           \
-	register long _arg1 __asm__ ("ebx") = (long)(arg1);                   \
-	register long _arg2 __asm__ ("ecx") = (long)(arg2);                   \
-	register long _arg3 __asm__ ("edx") = (long)(arg3);                   \
-	register long _arg4 __asm__ ("esi") = (long)(arg4);                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"int $0x80\n"                                                 \
-		: "=a" (_ret)                                                 \
-		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),             \
-		  "0"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_ret;                                                                 \
+#define my_syscall4(num, arg1, arg2, arg3, arg4)				\
+({										\
+	long _ret;								\
+	register long _num __asm__ ("eax")  = (num);				\
+	register long _arg1 __asm__ ("ebx") = (long)(arg1);			\
+	register long _arg2 __asm__ ("ecx") = (long)(arg2);			\
+	register long _arg3 __asm__ ("edx") = (long)(arg3);			\
+	register long _arg4 __asm__ ("esi") = (long)(arg4);			\
+										\
+	__asm__ volatile (							\
+		"int $0x80\n"							\
+		: "=a" (_ret)							\
+		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),		\
+		  "0"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_ret;									\
 })
 
-#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
-({                                                                            \
-	long _ret;                                                            \
-	register long _num __asm__ ("eax") = (num);                           \
-	register long _arg1 __asm__ ("ebx") = (long)(arg1);                   \
-	register long _arg2 __asm__ ("ecx") = (long)(arg2);                   \
-	register long _arg3 __asm__ ("edx") = (long)(arg3);                   \
-	register long _arg4 __asm__ ("esi") = (long)(arg4);                   \
-	register long _arg5 __asm__ ("edi") = (long)(arg5);                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"int $0x80\n"                                                 \
-		: "=a" (_ret)                                                 \
-		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
-		  "0"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_ret;                                                                 \
+#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)				\
+({										\
+	long _ret;								\
+	register long _num __asm__ ("eax")  = (num);				\
+	register long _arg1 __asm__ ("ebx") = (long)(arg1);			\
+	register long _arg2 __asm__ ("ecx") = (long)(arg2);			\
+	register long _arg3 __asm__ ("edx") = (long)(arg3);			\
+	register long _arg4 __asm__ ("esi") = (long)(arg4);			\
+	register long _arg5 __asm__ ("edi") = (long)(arg5);			\
+										\
+	__asm__ volatile (							\
+		"int $0x80\n"							\
+		: "=a" (_ret)							\
+		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),	\
+		  "0"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_ret;									\
 })
 
-#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)	\
-({								\
-	long _eax  = (long)(num);				\
-	long _arg6 = (long)(arg6); /* Always in memory */	\
-	__asm__ volatile (					\
-		"pushl	%[_arg6]\n\t"				\
-		"pushl	%%ebp\n\t"				\
-		"movl	4(%%esp),%%ebp\n\t"			\
-		"int	$0x80\n\t"				\
-		"popl	%%ebp\n\t"				\
-		"addl	$4,%%esp\n\t"				\
-		: "+a"(_eax)		/* %eax */		\
-		: "b"(arg1),		/* %ebx */		\
-		  "c"(arg2),		/* %ecx */		\
-		  "d"(arg3),		/* %edx */		\
-		  "S"(arg4),		/* %esi */		\
-		  "D"(arg5),		/* %edi */		\
-		  [_arg6]"m"(_arg6)	/* memory */		\
-		: "memory", "cc"				\
-	);							\
-	_eax;							\
+#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)		\
+({									\
+	long _eax  = (long)(num);					\
+	long _arg6 = (long)(arg6); /* Always in memory */		\
+	__asm__ volatile (						\
+		"pushl	%[_arg6]\n\t"					\
+		"pushl	%%ebp\n\t"					\
+		"movl	4(%%esp),%%ebp\n\t"				\
+		"int	$0x80\n\t"					\
+		"popl	%%ebp\n\t"					\
+		"addl	$4,%%esp\n\t"					\
+		: "+a"(_eax)		/* %eax */			\
+		: "b"(arg1),		/* %ebx */			\
+		  "c"(arg2),		/* %ecx */			\
+		  "d"(arg3),		/* %edx */			\
+		  "S"(arg4),		/* %esi */			\
+		  "D"(arg5),		/* %edi */			\
+		  [_arg6]"m"(_arg6)	/* memory */			\
+		: "memory", "cc"					\
+	);								\
+	_eax;								\
 })
 
 char **environ __attribute__((weak));
diff --git a/tools/include/nolibc/arch-loongarch.h b/tools/include/nolibc/arch-loongarch.h
index ad3f266e7093..292d6a58dc87 100644
--- a/tools/include/nolibc/arch-loongarch.h
+++ b/tools/include/nolibc/arch-loongarch.h
@@ -23,129 +23,129 @@
  */
 #define __ARCH_WANT_SYS_PSELECT6
 
-#define my_syscall0(num)                                                      \
-({                                                                            \
-	register long _num  __asm__ ("a7") = (num);                           \
-	register long _arg1 __asm__ ("a0");                                   \
-									      \
-	__asm__  volatile (                                                   \
-		"syscall 0\n"                                                 \
-		: "=r"(_arg1)                                                 \
-		: "r"(_num)                                                   \
-		: "memory", "$t0", "$t1", "$t2", "$t3",                       \
-		  "$t4", "$t5", "$t6", "$t7", "$t8"                           \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall0(num)							\
+({										\
+	register long _num __asm__ ("a7") = (num);				\
+	register long _arg1 __asm__ ("a0");					\
+										\
+	__asm__ volatile (							\
+		"syscall 0\n"							\
+		: "=r"(_arg1)							\
+		: "r"(_num)							\
+		: "memory", "$t0", "$t1", "$t2", "$t3",				\
+		  "$t4", "$t5", "$t6", "$t7", "$t8"				\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall1(num, arg1)                                                \
-({                                                                            \
-	register long _num  __asm__ ("a7") = (num);                           \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);		      \
-									      \
-	__asm__  volatile (                                                   \
-		"syscall 0\n"                                                 \
-		: "+r"(_arg1)                                                 \
-		: "r"(_num)                                                   \
-		: "memory", "$t0", "$t1", "$t2", "$t3",                       \
-		  "$t4", "$t5", "$t6", "$t7", "$t8"                           \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall1(num, arg1)							\
+({										\
+	register long _num __asm__ ("a7")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+										\
+	__asm__ volatile (							\
+		"syscall 0\n"							\
+		: "+r"(_arg1)							\
+		: "r"(_num)							\
+		: "memory", "$t0", "$t1", "$t2", "$t3",				\
+		  "$t4", "$t5", "$t6", "$t7", "$t8"				\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall2(num, arg1, arg2)                                          \
-({                                                                            \
-	register long _num  __asm__ ("a7") = (num);                           \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
-									      \
-	__asm__  volatile (                                                   \
-		"syscall 0\n"                                                 \
-		: "+r"(_arg1)                                                 \
-		: "r"(_arg2),                                                 \
-		  "r"(_num)                                                   \
-		: "memory", "$t0", "$t1", "$t2", "$t3",                       \
-		  "$t4", "$t5", "$t6", "$t7", "$t8"                           \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall2(num, arg1, arg2)						\
+({										\
+	register long _num __asm__ ("a7")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);			\
+										\
+	__asm__ volatile (							\
+		"syscall 0\n"							\
+		: "+r"(_arg1)							\
+		: "r"(_arg2),							\
+		  "r"(_num)							\
+		: "memory", "$t0", "$t1", "$t2", "$t3",				\
+		  "$t4", "$t5", "$t6", "$t7", "$t8"				\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall3(num, arg1, arg2, arg3)                                    \
-({                                                                            \
-	register long _num  __asm__ ("a7") = (num);                           \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("a2") = (long)(arg3);                    \
-									      \
-	__asm__  volatile (                                                   \
-		"syscall 0\n"                                                 \
-		: "+r"(_arg1)                                                 \
-		: "r"(_arg2), "r"(_arg3),                                     \
-		  "r"(_num)                                                   \
-		: "memory", "$t0", "$t1", "$t2", "$t3",                       \
-		  "$t4", "$t5", "$t6", "$t7", "$t8"                           \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall3(num, arg1, arg2, arg3)					\
+({										\
+	register long _num __asm__ ("a7")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("a2") = (long)(arg3);			\
+										\
+	__asm__ volatile (							\
+		"syscall 0\n"							\
+		: "+r"(_arg1)							\
+		: "r"(_arg2), "r"(_arg3),					\
+		  "r"(_num)							\
+		: "memory", "$t0", "$t1", "$t2", "$t3",				\
+		  "$t4", "$t5", "$t6", "$t7", "$t8"				\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
-({                                                                            \
-	register long _num  __asm__ ("a7") = (num);                           \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("a2") = (long)(arg3);                    \
-	register long _arg4 __asm__ ("a3") = (long)(arg4);                    \
-									      \
-	__asm__  volatile (                                                   \
-		"syscall 0\n"                                                 \
-		: "+r"(_arg1)                                                 \
-		: "r"(_arg2), "r"(_arg3), "r"(_arg4),                         \
-		  "r"(_num)                                                   \
-		: "memory", "$t0", "$t1", "$t2", "$t3",                       \
-		  "$t4", "$t5", "$t6", "$t7", "$t8"                           \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall4(num, arg1, arg2, arg3, arg4)				\
+({										\
+	register long _num __asm__ ("a7")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("a2") = (long)(arg3);			\
+	register long _arg4 __asm__ ("a3") = (long)(arg4);			\
+										\
+	__asm__ volatile (							\
+		"syscall 0\n"							\
+		: "+r"(_arg1)							\
+		: "r"(_arg2), "r"(_arg3), "r"(_arg4),				\
+		  "r"(_num)							\
+		: "memory", "$t0", "$t1", "$t2", "$t3",				\
+		  "$t4", "$t5", "$t6", "$t7", "$t8"				\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
-({                                                                            \
-	register long _num  __asm__ ("a7") = (num);                           \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("a2") = (long)(arg3);                    \
-	register long _arg4 __asm__ ("a3") = (long)(arg4);                    \
-	register long _arg5 __asm__ ("a4") = (long)(arg5);                    \
-									      \
-	__asm__  volatile (                                                   \
-		"syscall 0\n"                                                 \
-		: "+r"(_arg1)                                                 \
-		: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),             \
-		  "r"(_num)                                                   \
-		: "memory", "$t0", "$t1", "$t2", "$t3",                       \
-		  "$t4", "$t5", "$t6", "$t7", "$t8"                           \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)				\
+({										\
+	register long _num __asm__ ("a7")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("a2") = (long)(arg3);			\
+	register long _arg4 __asm__ ("a3") = (long)(arg4);			\
+	register long _arg5 __asm__ ("a4") = (long)(arg5);			\
+										\
+	__asm__ volatile (							\
+		"syscall 0\n"							\
+		: "+r"(_arg1)							\
+		: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),		\
+		  "r"(_num)							\
+		: "memory", "$t0", "$t1", "$t2", "$t3",				\
+		  "$t4", "$t5", "$t6", "$t7", "$t8"				\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \
-({                                                                            \
-	register long _num  __asm__ ("a7") = (num);                           \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("a2") = (long)(arg3);                    \
-	register long _arg4 __asm__ ("a3") = (long)(arg4);                    \
-	register long _arg5 __asm__ ("a4") = (long)(arg5);                    \
-	register long _arg6 __asm__ ("a5") = (long)(arg6);                    \
-									      \
-	__asm__  volatile (                                                   \
-		"syscall 0\n"                                                 \
-		: "+r"(_arg1)                                                 \
-		: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), "r"(_arg6), \
-		  "r"(_num)                                                   \
-		: "memory", "$t0", "$t1", "$t2", "$t3",                       \
-		  "$t4", "$t5", "$t6", "$t7", "$t8"                           \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)			\
+({										\
+	register long _num __asm__ ("a7")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("a2") = (long)(arg3);			\
+	register long _arg4 __asm__ ("a3") = (long)(arg4);			\
+	register long _arg5 __asm__ ("a4") = (long)(arg5);			\
+	register long _arg6 __asm__ ("a5") = (long)(arg6);			\
+										\
+	__asm__ volatile (							\
+		"syscall 0\n"							\
+		: "+r"(_arg1)							\
+		: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), "r"(_arg6),	\
+		  "r"(_num)							\
+		: "memory", "$t0", "$t1", "$t2", "$t3",				\
+		  "$t4", "$t5", "$t6", "$t7", "$t8"				\
+	);									\
+	_arg1;									\
 })
 
 char **environ __attribute__((weak));
diff --git a/tools/include/nolibc/arch-mips.h b/tools/include/nolibc/arch-mips.h
index db24e0837a39..1fd1eedc12a6 100644
--- a/tools/include/nolibc/arch-mips.h
+++ b/tools/include/nolibc/arch-mips.h
@@ -57,125 +57,125 @@ struct sys_stat_struct {
  *     don't have to experience issues with register constraints.
  */
 
-#define my_syscall0(num)                                                      \
-({                                                                            \
-	register long _num __asm__ ("v0") = (num);                            \
-	register long _arg4 __asm__ ("a3");                                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"addiu $sp, $sp, -32\n"                                       \
-		"syscall\n"                                                   \
-		"addiu $sp, $sp, 32\n"                                        \
-		: "=r"(_num), "=r"(_arg4)                                     \
-		: "r"(_num)                                                   \
-		: "memory", "cc", "at", "v1", "hi", "lo",                     \
-	          "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"  \
-	);                                                                    \
-	_arg4 ? -_num : _num;                                                 \
+#define my_syscall0(num)							\
+({										\
+	register long _num __asm__ ("v0") = (num);				\
+	register long _arg4 __asm__ ("a3");					\
+										\
+	__asm__ volatile (							\
+		"addiu $sp, $sp, -32\n"						\
+		"syscall\n"							\
+		"addiu $sp, $sp, 32\n"						\
+		: "=r"(_num), "=r"(_arg4)					\
+		: "r"(_num)							\
+		: "memory", "cc", "at", "v1", "hi", "lo",			\
+		  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"	\
+	);									\
+	_arg4 ? -_num : _num;							\
 })
 
-#define my_syscall1(num, arg1)                                                \
-({                                                                            \
-	register long _num __asm__ ("v0") = (num);                            \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
-	register long _arg4 __asm__ ("a3");                                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"addiu $sp, $sp, -32\n"                                       \
-		"syscall\n"                                                   \
-		"addiu $sp, $sp, 32\n"                                        \
-		: "=r"(_num), "=r"(_arg4)                                     \
-		: "0"(_num),                                                  \
-		  "r"(_arg1)                                                  \
-		: "memory", "cc", "at", "v1", "hi", "lo",                     \
-	          "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"  \
-	);                                                                    \
-	_arg4 ? -_num : _num;                                                 \
+#define my_syscall1(num, arg1)							\
+({										\
+	register long _num __asm__ ("v0")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+	register long _arg4 __asm__ ("a3");					\
+										\
+	__asm__ volatile (							\
+		"addiu $sp, $sp, -32\n"						\
+		"syscall\n"							\
+		"addiu $sp, $sp, 32\n"						\
+		: "=r"(_num), "=r"(_arg4)					\
+		: "0"(_num),							\
+		  "r"(_arg1)							\
+		: "memory", "cc", "at", "v1", "hi", "lo",			\
+		  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"	\
+	);									\
+	_arg4 ? -_num : _num;							\
 })
 
-#define my_syscall2(num, arg1, arg2)                                          \
-({                                                                            \
-	register long _num __asm__ ("v0") = (num);                            \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
-	register long _arg4 __asm__ ("a3");                                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"addiu $sp, $sp, -32\n"                                       \
-		"syscall\n"                                                   \
-		"addiu $sp, $sp, 32\n"                                        \
-		: "=r"(_num), "=r"(_arg4)                                     \
-		: "0"(_num),                                                  \
-		  "r"(_arg1), "r"(_arg2)                                      \
-		: "memory", "cc", "at", "v1", "hi", "lo",                     \
-	          "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"  \
-	);                                                                    \
-	_arg4 ? -_num : _num;                                                 \
+#define my_syscall2(num, arg1, arg2)						\
+({										\
+	register long _num __asm__ ("v0")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);			\
+	register long _arg4 __asm__ ("a3");					\
+										\
+	__asm__ volatile (							\
+		"addiu $sp, $sp, -32\n"						\
+		"syscall\n"							\
+		"addiu $sp, $sp, 32\n"						\
+		: "=r"(_num), "=r"(_arg4)					\
+		: "0"(_num),							\
+		  "r"(_arg1), "r"(_arg2)					\
+		: "memory", "cc", "at", "v1", "hi", "lo",			\
+		  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"	\
+	);									\
+	_arg4 ? -_num : _num;							\
 })
 
-#define my_syscall3(num, arg1, arg2, arg3)                                    \
-({                                                                            \
-	register long _num __asm__ ("v0")  = (num);                           \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("a2") = (long)(arg3);                    \
-	register long _arg4 __asm__ ("a3");                                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"addiu $sp, $sp, -32\n"                                       \
-		"syscall\n"                                                   \
-		"addiu $sp, $sp, 32\n"                                        \
-		: "=r"(_num), "=r"(_arg4)                                     \
-		: "0"(_num),                                                  \
-		  "r"(_arg1), "r"(_arg2), "r"(_arg3)                          \
-		: "memory", "cc", "at", "v1", "hi", "lo",                     \
-	          "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"  \
-	);                                                                    \
-	_arg4 ? -_num : _num;                                                 \
+#define my_syscall3(num, arg1, arg2, arg3)					\
+({										\
+	register long _num __asm__ ("v0")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("a2") = (long)(arg3);			\
+	register long _arg4 __asm__ ("a3");					\
+										\
+	__asm__ volatile (							\
+		"addiu $sp, $sp, -32\n"						\
+		"syscall\n"							\
+		"addiu $sp, $sp, 32\n"						\
+		: "=r"(_num), "=r"(_arg4)					\
+		: "0"(_num),							\
+		  "r"(_arg1), "r"(_arg2), "r"(_arg3)				\
+		: "memory", "cc", "at", "v1", "hi", "lo",			\
+		  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"	\
+	);									\
+	_arg4 ? -_num : _num;							\
 })
 
-#define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
-({                                                                            \
-	register long _num __asm__ ("v0") = (num);                            \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("a2") = (long)(arg3);                    \
-	register long _arg4 __asm__ ("a3") = (long)(arg4);                    \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"addiu $sp, $sp, -32\n"                                       \
-		"syscall\n"                                                   \
-		"addiu $sp, $sp, 32\n"                                        \
-		: "=r" (_num), "=r"(_arg4)                                    \
-		: "0"(_num),                                                  \
-		  "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4)              \
-		: "memory", "cc", "at", "v1", "hi", "lo",                     \
-	          "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"  \
-	);                                                                    \
-	_arg4 ? -_num : _num;                                                 \
+#define my_syscall4(num, arg1, arg2, arg3, arg4)				\
+({										\
+	register long _num __asm__ ("v0")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("a2") = (long)(arg3);			\
+	register long _arg4 __asm__ ("a3") = (long)(arg4);			\
+										\
+	__asm__ volatile (							\
+		"addiu $sp, $sp, -32\n"						\
+		"syscall\n"							\
+		"addiu $sp, $sp, 32\n"						\
+		: "=r" (_num), "=r"(_arg4)					\
+		: "0"(_num),							\
+		  "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4)		\
+		: "memory", "cc", "at", "v1", "hi", "lo",			\
+		  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"	\
+	);									\
+	_arg4 ? -_num : _num;							\
 })
 
-#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
-({                                                                            \
-	register long _num __asm__ ("v0") = (num);                            \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("a2") = (long)(arg3);                    \
-	register long _arg4 __asm__ ("a3") = (long)(arg4);                    \
-	register long _arg5 = (long)(arg5);                                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"addiu $sp, $sp, -32\n"                                       \
-		"sw %7, 16($sp)\n"                                            \
-		"syscall\n  "                                                 \
-		"addiu $sp, $sp, 32\n"                                        \
-		: "=r" (_num), "=r"(_arg4)                                    \
-		: "0"(_num),                                                  \
-		  "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5)  \
-		: "memory", "cc", "at", "v1", "hi", "lo",                     \
-	          "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"  \
-	);                                                                    \
-	_arg4 ? -_num : _num;                                                 \
+#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)				\
+({										\
+	register long _num __asm__ ("v0")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("a2") = (long)(arg3);			\
+	register long _arg4 __asm__ ("a3") = (long)(arg4);			\
+	register long _arg5 = (long)(arg5);					\
+										\
+	__asm__ volatile (							\
+		"addiu $sp, $sp, -32\n"						\
+		"sw %7, 16($sp)\n"						\
+		"syscall\n  "							\
+		"addiu $sp, $sp, 32\n"						\
+		: "=r" (_num), "=r"(_arg4)					\
+		: "0"(_num),							\
+		  "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5)	\
+		: "memory", "cc", "at", "v1", "hi", "lo",			\
+		  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"	\
+	);									\
+	_arg4 ? -_num : _num;							\
 })
 
 char **environ __attribute__((weak));
diff --git a/tools/include/nolibc/arch-riscv.h b/tools/include/nolibc/arch-riscv.h
index a2e8564e66d6..4f21e862b412 100644
--- a/tools/include/nolibc/arch-riscv.h
+++ b/tools/include/nolibc/arch-riscv.h
@@ -58,122 +58,122 @@ struct sys_stat_struct {
  */
 #define __ARCH_WANT_SYS_PSELECT6
 
-#define my_syscall0(num)                                                      \
-({                                                                            \
-	register long _num  __asm__ ("a7") = (num);                           \
-	register long _arg1 __asm__ ("a0");                                   \
-									      \
-	__asm__  volatile (                                                   \
-		"ecall\n\t"                                                   \
-		: "=r"(_arg1)                                                 \
-		: "r"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall0(num)							\
+({										\
+	register long _num __asm__ ("a7") = (num);				\
+	register long _arg1 __asm__ ("a0");					\
+										\
+	__asm__ volatile (							\
+		"ecall\n\t"							\
+		: "=r"(_arg1)							\
+		: "r"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall1(num, arg1)                                                \
-({                                                                            \
-	register long _num  __asm__ ("a7") = (num);                           \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);		      \
-									      \
-	__asm__  volatile (                                                   \
-		"ecall\n"                                                     \
-		: "+r"(_arg1)                                                 \
-		: "r"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall1(num, arg1)							\
+({										\
+	register long _num __asm__ ("a7")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+										\
+	__asm__ volatile (							\
+		"ecall\n"							\
+		: "+r"(_arg1)							\
+		: "r"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall2(num, arg1, arg2)                                          \
-({                                                                            \
-	register long _num  __asm__ ("a7") = (num);                           \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
-									      \
-	__asm__  volatile (                                                   \
-		"ecall\n"                                                     \
-		: "+r"(_arg1)                                                 \
-		: "r"(_arg2),                                                 \
-		  "r"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall2(num, arg1, arg2)						\
+({										\
+	register long _num __asm__ ("a7")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);			\
+										\
+	__asm__ volatile (							\
+		"ecall\n"							\
+		: "+r"(_arg1)							\
+		: "r"(_arg2),							\
+		  "r"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall3(num, arg1, arg2, arg3)                                    \
-({                                                                            \
-	register long _num  __asm__ ("a7") = (num);                           \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("a2") = (long)(arg3);                    \
-									      \
-	__asm__  volatile (                                                   \
-		"ecall\n\t"                                                   \
-		: "+r"(_arg1)                                                 \
-		: "r"(_arg2), "r"(_arg3),                                     \
-		  "r"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall3(num, arg1, arg2, arg3)					\
+({										\
+	register long _num __asm__ ("a7")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("a2") = (long)(arg3);			\
+										\
+	__asm__ volatile (							\
+		"ecall\n\t"							\
+		: "+r"(_arg1)							\
+		: "r"(_arg2), "r"(_arg3),					\
+		  "r"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
-({                                                                            \
-	register long _num  __asm__ ("a7") = (num);                           \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("a2") = (long)(arg3);                    \
-	register long _arg4 __asm__ ("a3") = (long)(arg4);                    \
-									      \
-	__asm__  volatile (                                                   \
-		"ecall\n"                                                     \
-		: "+r"(_arg1)                                                 \
-		: "r"(_arg2), "r"(_arg3), "r"(_arg4),                         \
-		  "r"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall4(num, arg1, arg2, arg3, arg4)				\
+({										\
+	register long _num __asm__ ("a7")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("a2") = (long)(arg3);			\
+	register long _arg4 __asm__ ("a3") = (long)(arg4);			\
+										\
+	__asm__ volatile (							\
+		"ecall\n"							\
+		: "+r"(_arg1)							\
+		: "r"(_arg2), "r"(_arg3), "r"(_arg4),				\
+		  "r"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
-({                                                                            \
-	register long _num  __asm__ ("a7") = (num);                           \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("a2") = (long)(arg3);                    \
-	register long _arg4 __asm__ ("a3") = (long)(arg4);                    \
-	register long _arg5 __asm__ ("a4") = (long)(arg5);                    \
-									      \
-	__asm__  volatile (                                                   \
-		"ecall\n"                                                     \
-		: "+r"(_arg1)                                                 \
-		: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),             \
-		  "r"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)				\
+({										\
+	register long _num __asm__ ("a7")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("a2") = (long)(arg3);			\
+	register long _arg4 __asm__ ("a3") = (long)(arg4);			\
+	register long _arg5 __asm__ ("a4") = (long)(arg5);			\
+										\
+	__asm__ volatile (							\
+		"ecall\n"							\
+		: "+r"(_arg1)							\
+		: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),		\
+		  "r"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_arg1;									\
 })
 
-#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \
-({                                                                            \
-	register long _num  __asm__ ("a7") = (num);                           \
-	register long _arg1 __asm__ ("a0") = (long)(arg1);                    \
-	register long _arg2 __asm__ ("a1") = (long)(arg2);                    \
-	register long _arg3 __asm__ ("a2") = (long)(arg3);                    \
-	register long _arg4 __asm__ ("a3") = (long)(arg4);                    \
-	register long _arg5 __asm__ ("a4") = (long)(arg5);                    \
-	register long _arg6 __asm__ ("a5") = (long)(arg6);                    \
-									      \
-	__asm__  volatile (                                                   \
-		"ecall\n"                                                     \
-		: "+r"(_arg1)                                                 \
-		: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), "r"(_arg6), \
-		  "r"(_num)                                                   \
-		: "memory", "cc"                                              \
-	);                                                                    \
-	_arg1;                                                                \
+#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)			\
+({										\
+	register long _num __asm__ ("a7")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("a2") = (long)(arg3);			\
+	register long _arg4 __asm__ ("a3") = (long)(arg4);			\
+	register long _arg5 __asm__ ("a4") = (long)(arg5);			\
+	register long _arg6 __asm__ ("a5") = (long)(arg6);			\
+										\
+	__asm__ volatile (							\
+		"ecall\n"							\
+		: "+r"(_arg1)							\
+		: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), "r"(_arg6),	\
+		  "r"(_num)							\
+		: "memory", "cc"						\
+	);									\
+	_arg1;									\
 })
 
 char **environ __attribute__((weak));
diff --git a/tools/include/nolibc/arch-s390.h b/tools/include/nolibc/arch-s390.h
index 516dff5bff8b..8cff5b05e841 100644
--- a/tools/include/nolibc/arch-s390.h
+++ b/tools/include/nolibc/arch-s390.h
@@ -47,119 +47,119 @@ struct sys_stat_struct {
  *
  */
 
-#define my_syscall0(num)						\
-({									\
-	register long _num __asm__ ("1") = (num);			\
-	register long _rc __asm__ ("2");				\
-									\
-	__asm__  volatile (						\
-		"svc 0\n"						\
-		: "=d"(_rc)						\
-		: "d"(_num)						\
-		: "memory", "cc"					\
-		);							\
-	_rc;								\
+#define my_syscall0(num)							\
+({										\
+	register long _num __asm__ ("1") = (num);				\
+	register long _rc __asm__ ("2");					\
+										\
+	__asm__ volatile (							\
+		"svc 0\n"							\
+		: "=d"(_rc)							\
+		: "d"(_num)							\
+		: "memory", "cc"						\
+		);								\
+	_rc;									\
 })
 
-#define my_syscall1(num, arg1)						\
-({									\
-	register long _num __asm__ ("1") = (num);			\
-	register long _arg1 __asm__ ("2") = (long)(arg1);		\
-									\
-	__asm__  volatile (						\
-		"svc 0\n"						\
-		: "+d"(_arg1)						\
-		: "d"(_num)						\
-		: "memory", "cc"					\
-		);							\
-	_arg1;								\
+#define my_syscall1(num, arg1)							\
+({										\
+	register long _num __asm__ ("1")  = (num);				\
+	register long _arg1 __asm__ ("2") = (long)(arg1);			\
+										\
+	__asm__ volatile (							\
+		"svc 0\n"							\
+		: "+d"(_arg1)							\
+		: "d"(_num)							\
+		: "memory", "cc"						\
+		);								\
+	_arg1;									\
 })
 
-#define my_syscall2(num, arg1, arg2)					\
-({									\
-	register long _num __asm__ ("1") = (num);			\
-	register long _arg1 __asm__ ("2") = (long)(arg1);		\
-	register long _arg2 __asm__ ("3") = (long)(arg2);		\
-									\
-	__asm__  volatile (						\
-		"svc 0\n"						\
-		: "+d"(_arg1)						\
-		: "d"(_arg2), "d"(_num)					\
-		: "memory", "cc"					\
-		);							\
-	_arg1;								\
+#define my_syscall2(num, arg1, arg2)						\
+({										\
+	register long _num __asm__ ("1")  = (num);				\
+	register long _arg1 __asm__ ("2") = (long)(arg1);			\
+	register long _arg2 __asm__ ("3") = (long)(arg2);			\
+										\
+	__asm__ volatile (							\
+		"svc 0\n"							\
+		: "+d"(_arg1)							\
+		: "d"(_arg2), "d"(_num)						\
+		: "memory", "cc"						\
+		);								\
+	_arg1;									\
 })
 
-#define my_syscall3(num, arg1, arg2, arg3)				\
-({									\
-	register long _num __asm__ ("1") = (num);			\
-	register long _arg1 __asm__ ("2") = (long)(arg1);		\
-	register long _arg2 __asm__ ("3") = (long)(arg2);		\
-	register long _arg3 __asm__ ("4") = (long)(arg3);		\
-									\
-	__asm__  volatile (						\
-		"svc 0\n"						\
-		: "+d"(_arg1)						\
-		: "d"(_arg2), "d"(_arg3), "d"(_num)			\
-		: "memory", "cc"					\
-		);							\
-	_arg1;								\
+#define my_syscall3(num, arg1, arg2, arg3)					\
+({										\
+	register long _num __asm__ ("1")  = (num);				\
+	register long _arg1 __asm__ ("2") = (long)(arg1);			\
+	register long _arg2 __asm__ ("3") = (long)(arg2);			\
+	register long _arg3 __asm__ ("4") = (long)(arg3);			\
+										\
+	__asm__ volatile (							\
+		"svc 0\n"							\
+		: "+d"(_arg1)							\
+		: "d"(_arg2), "d"(_arg3), "d"(_num)				\
+		: "memory", "cc"						\
+		);								\
+	_arg1;									\
 })
 
-#define my_syscall4(num, arg1, arg2, arg3, arg4)			\
-({									\
-	register long _num __asm__ ("1") = (num);			\
-	register long _arg1 __asm__ ("2") = (long)(arg1);		\
-	register long _arg2 __asm__ ("3") = (long)(arg2);		\
-	register long _arg3 __asm__ ("4") = (long)(arg3);		\
-	register long _arg4 __asm__ ("5") = (long)(arg4);		\
-									\
-	__asm__  volatile (						\
-		"svc 0\n"						\
-		: "+d"(_arg1)						\
-		: "d"(_arg2), "d"(_arg3), "d"(_arg4), "d"(_num)		\
-		: "memory", "cc"					\
-		);							\
-	_arg1;								\
+#define my_syscall4(num, arg1, arg2, arg3, arg4)				\
+({										\
+	register long _num __asm__ ("1")  = (num);				\
+	register long _arg1 __asm__ ("2") = (long)(arg1);			\
+	register long _arg2 __asm__ ("3") = (long)(arg2);			\
+	register long _arg3 __asm__ ("4") = (long)(arg3);			\
+	register long _arg4 __asm__ ("5") = (long)(arg4);			\
+										\
+	__asm__ volatile (							\
+		"svc 0\n"							\
+		: "+d"(_arg1)							\
+		: "d"(_arg2), "d"(_arg3), "d"(_arg4), "d"(_num)			\
+		: "memory", "cc"						\
+		);								\
+	_arg1;									\
 })
 
-#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)			\
-({									\
-	register long _num __asm__ ("1") = (num);			\
-	register long _arg1 __asm__ ("2") = (long)(arg1);		\
-	register long _arg2 __asm__ ("3") = (long)(arg2);		\
-	register long _arg3 __asm__ ("4") = (long)(arg3);		\
-	register long _arg4 __asm__ ("5") = (long)(arg4);		\
-	register long _arg5 __asm__ ("6") = (long)(arg5);		\
-									\
-	__asm__  volatile (						\
-		"svc 0\n"						\
-		: "+d"(_arg1)						\
-		: "d"(_arg2), "d"(_arg3), "d"(_arg4), "d"(_arg5),	\
-		  "d"(_num)						\
-		: "memory", "cc"					\
-		);							\
-	_arg1;								\
+#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)				\
+({										\
+	register long _num __asm__ ("1")  = (num);				\
+	register long _arg1 __asm__ ("2") = (long)(arg1);			\
+	register long _arg2 __asm__ ("3") = (long)(arg2);			\
+	register long _arg3 __asm__ ("4") = (long)(arg3);			\
+	register long _arg4 __asm__ ("5") = (long)(arg4);			\
+	register long _arg5 __asm__ ("6") = (long)(arg5);			\
+										\
+	__asm__ volatile (							\
+		"svc 0\n"							\
+		: "+d"(_arg1)							\
+		: "d"(_arg2), "d"(_arg3), "d"(_arg4), "d"(_arg5),		\
+		  "d"(_num)							\
+		: "memory", "cc"						\
+		);								\
+	_arg1;									\
 })
 
-#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)		\
-({									\
-	register long _num __asm__ ("1") = (num);			\
-	register long _arg1 __asm__ ("2") = (long)(arg1);		\
-	register long _arg2 __asm__ ("3") = (long)(arg2);		\
-	register long _arg3 __asm__ ("4") = (long)(arg3);		\
-	register long _arg4 __asm__ ("5") = (long)(arg4);		\
-	register long _arg5 __asm__ ("6") = (long)(arg5);		\
-	register long _arg6 __asm__ ("7") = (long)(arg6);		\
-									\
-	__asm__  volatile (						\
-		"svc 0\n"						\
-		: "+d"(_arg1)						\
-		: "d"(_arg2), "d"(_arg3), "d"(_arg4), "d"(_arg5),	\
-		  "d"(_arg6), "d"(_num)					\
-		: "memory", "cc"					\
-		);							\
-	_arg1;								\
+#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)			\
+({										\
+	register long _num __asm__ ("1")  = (num);				\
+	register long _arg1 __asm__ ("2") = (long)(arg1);			\
+	register long _arg2 __asm__ ("3") = (long)(arg2);			\
+	register long _arg3 __asm__ ("4") = (long)(arg3);			\
+	register long _arg4 __asm__ ("5") = (long)(arg4);			\
+	register long _arg5 __asm__ ("6") = (long)(arg5);			\
+	register long _arg6 __asm__ ("7") = (long)(arg6);			\
+										\
+	__asm__ volatile (							\
+		"svc 0\n"							\
+		: "+d"(_arg1)							\
+		: "d"(_arg2), "d"(_arg3), "d"(_arg4), "d"(_arg5),		\
+		  "d"(_arg6), "d"(_num)						\
+		: "memory", "cc"						\
+		);								\
+	_arg1;									\
 })
 
 char **environ __attribute__((weak));
diff --git a/tools/include/nolibc/arch-x86_64.h b/tools/include/nolibc/arch-x86_64.h
index 6fc4d8392742..1dc8b60f5153 100644
--- a/tools/include/nolibc/arch-x86_64.h
+++ b/tools/include/nolibc/arch-x86_64.h
@@ -55,129 +55,129 @@ struct sys_stat_struct {
  *
  */
 
-#define my_syscall0(num)                                                      \
-({                                                                            \
-	long _ret;                                                            \
-	register long _num  __asm__ ("rax") = (num);                          \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"syscall\n"                                                   \
-		: "=a"(_ret)                                                  \
-		: "0"(_num)                                                   \
-		: "rcx", "r11", "memory", "cc"                                \
-	);                                                                    \
-	_ret;                                                                 \
+#define my_syscall0(num)							\
+({										\
+	long _ret;								\
+	register long _num __asm__ ("rax") = (num);				\
+										\
+	__asm__ volatile (							\
+		"syscall\n"							\
+		: "=a"(_ret)							\
+		: "0"(_num)							\
+		: "rcx", "r11", "memory", "cc"					\
+	);									\
+	_ret;									\
 })
 
-#define my_syscall1(num, arg1)                                                \
-({                                                                            \
-	long _ret;                                                            \
-	register long _num  __asm__ ("rax") = (num);                          \
-	register long _arg1 __asm__ ("rdi") = (long)(arg1);                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"syscall\n"                                                   \
-		: "=a"(_ret)                                                  \
-		: "r"(_arg1),                                                 \
-		  "0"(_num)                                                   \
-		: "rcx", "r11", "memory", "cc"                                \
-	);                                                                    \
-	_ret;                                                                 \
+#define my_syscall1(num, arg1)							\
+({										\
+	long _ret;								\
+	register long _num __asm__ ("rax")  = (num);				\
+	register long _arg1 __asm__ ("rdi") = (long)(arg1);			\
+										\
+	__asm__ volatile (							\
+		"syscall\n"							\
+		: "=a"(_ret)							\
+		: "r"(_arg1),							\
+		  "0"(_num)							\
+		: "rcx", "r11", "memory", "cc"					\
+	);									\
+	_ret;									\
 })
 
-#define my_syscall2(num, arg1, arg2)                                          \
-({                                                                            \
-	long _ret;                                                            \
-	register long _num  __asm__ ("rax") = (num);                          \
-	register long _arg1 __asm__ ("rdi") = (long)(arg1);                   \
-	register long _arg2 __asm__ ("rsi") = (long)(arg2);                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"syscall\n"                                                   \
-		: "=a"(_ret)                                                  \
-		: "r"(_arg1), "r"(_arg2),                                     \
-		  "0"(_num)                                                   \
-		: "rcx", "r11", "memory", "cc"                                \
-	);                                                                    \
-	_ret;                                                                 \
+#define my_syscall2(num, arg1, arg2)						\
+({										\
+	long _ret;								\
+	register long _num __asm__ ("rax")  = (num);				\
+	register long _arg1 __asm__ ("rdi") = (long)(arg1);			\
+	register long _arg2 __asm__ ("rsi") = (long)(arg2);			\
+										\
+	__asm__ volatile (							\
+		"syscall\n"							\
+		: "=a"(_ret)							\
+		: "r"(_arg1), "r"(_arg2),					\
+		  "0"(_num)							\
+		: "rcx", "r11", "memory", "cc"					\
+	);									\
+	_ret;									\
 })
 
-#define my_syscall3(num, arg1, arg2, arg3)                                    \
-({                                                                            \
-	long _ret;                                                            \
-	register long _num  __asm__ ("rax") = (num);                          \
-	register long _arg1 __asm__ ("rdi") = (long)(arg1);                   \
-	register long _arg2 __asm__ ("rsi") = (long)(arg2);                   \
-	register long _arg3 __asm__ ("rdx") = (long)(arg3);                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"syscall\n"                                                   \
-		: "=a"(_ret)                                                  \
-		: "r"(_arg1), "r"(_arg2), "r"(_arg3),                         \
-		  "0"(_num)                                                   \
-		: "rcx", "r11", "memory", "cc"                                \
-	);                                                                    \
-	_ret;                                                                 \
+#define my_syscall3(num, arg1, arg2, arg3)					\
+({										\
+	long _ret;								\
+	register long _num __asm__ ("rax")  = (num);				\
+	register long _arg1 __asm__ ("rdi") = (long)(arg1);			\
+	register long _arg2 __asm__ ("rsi") = (long)(arg2);			\
+	register long _arg3 __asm__ ("rdx") = (long)(arg3);			\
+										\
+	__asm__ volatile (							\
+		"syscall\n"							\
+		: "=a"(_ret)							\
+		: "r"(_arg1), "r"(_arg2), "r"(_arg3),				\
+		  "0"(_num)							\
+		: "rcx", "r11", "memory", "cc"					\
+	);									\
+	_ret;									\
 })
 
-#define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
-({                                                                            \
-	long _ret;                                                            \
-	register long _num  __asm__ ("rax") = (num);                          \
-	register long _arg1 __asm__ ("rdi") = (long)(arg1);                   \
-	register long _arg2 __asm__ ("rsi") = (long)(arg2);                   \
-	register long _arg3 __asm__ ("rdx") = (long)(arg3);                   \
-	register long _arg4 __asm__ ("r10") = (long)(arg4);                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"syscall\n"                                                   \
-		: "=a"(_ret)                                                  \
-		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),             \
-		  "0"(_num)                                                   \
-		: "rcx", "r11", "memory", "cc"                                \
-	);                                                                    \
-	_ret;                                                                 \
+#define my_syscall4(num, arg1, arg2, arg3, arg4)				\
+({										\
+	long _ret;								\
+	register long _num __asm__ ("rax")  = (num);				\
+	register long _arg1 __asm__ ("rdi") = (long)(arg1);			\
+	register long _arg2 __asm__ ("rsi") = (long)(arg2);			\
+	register long _arg3 __asm__ ("rdx") = (long)(arg3);			\
+	register long _arg4 __asm__ ("r10") = (long)(arg4);			\
+										\
+	__asm__ volatile (							\
+		"syscall\n"							\
+		: "=a"(_ret)							\
+		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),		\
+		  "0"(_num)							\
+		: "rcx", "r11", "memory", "cc"					\
+	);									\
+	_ret;									\
 })
 
-#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
-({                                                                            \
-	long _ret;                                                            \
-	register long _num  __asm__ ("rax") = (num);                          \
-	register long _arg1 __asm__ ("rdi") = (long)(arg1);                   \
-	register long _arg2 __asm__ ("rsi") = (long)(arg2);                   \
-	register long _arg3 __asm__ ("rdx") = (long)(arg3);                   \
-	register long _arg4 __asm__ ("r10") = (long)(arg4);                   \
-	register long _arg5 __asm__ ("r8")  = (long)(arg5);                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"syscall\n"                                                   \
-		: "=a"(_ret)                                                  \
-		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
-		  "0"(_num)                                                   \
-		: "rcx", "r11", "memory", "cc"                                \
-	);                                                                    \
-	_ret;                                                                 \
+#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)				\
+({										\
+	long _ret;								\
+	register long _num __asm__ ("rax")  = (num);				\
+	register long _arg1 __asm__ ("rdi") = (long)(arg1);			\
+	register long _arg2 __asm__ ("rsi") = (long)(arg2);			\
+	register long _arg3 __asm__ ("rdx") = (long)(arg3);			\
+	register long _arg4 __asm__ ("r10") = (long)(arg4);			\
+	register long _arg5 __asm__ ("r8")  = (long)(arg5);			\
+										\
+	__asm__ volatile (							\
+		"syscall\n"							\
+		: "=a"(_ret)							\
+		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),	\
+		  "0"(_num)							\
+		: "rcx", "r11", "memory", "cc"					\
+	);									\
+	_ret;									\
 })
 
-#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \
-({                                                                            \
-	long _ret;                                                            \
-	register long _num  __asm__ ("rax") = (num);                          \
-	register long _arg1 __asm__ ("rdi") = (long)(arg1);                   \
-	register long _arg2 __asm__ ("rsi") = (long)(arg2);                   \
-	register long _arg3 __asm__ ("rdx") = (long)(arg3);                   \
-	register long _arg4 __asm__ ("r10") = (long)(arg4);                   \
-	register long _arg5 __asm__ ("r8")  = (long)(arg5);                   \
-	register long _arg6 __asm__ ("r9")  = (long)(arg6);                   \
-	                                                                      \
-	__asm__  volatile (                                                   \
-		"syscall\n"                                                   \
-		: "=a"(_ret)                                                  \
-		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
-		  "r"(_arg6), "0"(_num)                                       \
-		: "rcx", "r11", "memory", "cc"                                \
-	);                                                                    \
-	_ret;                                                                 \
+#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)			\
+({										\
+	long _ret;								\
+	register long _num __asm__ ("rax")  = (num);				\
+	register long _arg1 __asm__ ("rdi") = (long)(arg1);			\
+	register long _arg2 __asm__ ("rsi") = (long)(arg2);			\
+	register long _arg3 __asm__ ("rdx") = (long)(arg3);			\
+	register long _arg4 __asm__ ("r10") = (long)(arg4);			\
+	register long _arg5 __asm__ ("r8")  = (long)(arg5);			\
+	register long _arg6 __asm__ ("r9")  = (long)(arg6);			\
+										\
+	__asm__ volatile (							\
+		"syscall\n"							\
+		: "=a"(_ret)							\
+		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),	\
+		  "r"(_arg6), "0"(_num)						\
+		: "rcx", "r11", "memory", "cc"					\
+	);									\
+	_ret;									\
 })
 
 char **environ __attribute__((weak));
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 07/14] tools/nolibc: arch-loongarch.h: shrink with SYSCALL_CLOBBERLIST
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
                     ` (5 preceding siblings ...)
  2023-06-28 13:19   ` [PATCH v5 06/14] tools/nolibc: arch-*.h: clean up multiple whitespaces Zhangjin Wu
@ 2023-06-28 13:22   ` Zhangjin Wu
  2023-07-02 18:50     ` Willy Tarreau
  2023-06-28 13:31   ` [PATCH v5 08/14] tools/nolibc: arch-mips.h: " Zhangjin Wu
                     ` (7 subsequent siblings)
  14 siblings, 1 reply; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-28 13:22 UTC (permalink / raw)
  To: thomas, w
  Cc: falcon, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

my_syscall<N> share a same long clobber list, define a macro for them.

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/arch-loongarch.h | 25 +++++++++++--------------
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/tools/include/nolibc/arch-loongarch.h b/tools/include/nolibc/arch-loongarch.h
index 292d6a58dc87..fbb4844f7993 100644
--- a/tools/include/nolibc/arch-loongarch.h
+++ b/tools/include/nolibc/arch-loongarch.h
@@ -23,6 +23,10 @@
  */
 #define __ARCH_WANT_SYS_PSELECT6
 
+#define SYSCALL_CLOBBERLIST			\
+	"memory", "$t0", "$t1", "$t2", "$t3",	\
+	"$t4", "$t5", "$t6", "$t7", "$t8"
+
 #define my_syscall0(num)							\
 ({										\
 	register long _num __asm__ ("a7") = (num);				\
@@ -32,8 +36,7 @@
 		"syscall 0\n"							\
 		: "=r"(_arg1)							\
 		: "r"(_num)							\
-		: "memory", "$t0", "$t1", "$t2", "$t3",				\
-		  "$t4", "$t5", "$t6", "$t7", "$t8"				\
+		: SYSCALL_CLOBBERLIST						\
 	);									\
 	_arg1;									\
 })
@@ -47,8 +50,7 @@
 		"syscall 0\n"							\
 		: "+r"(_arg1)							\
 		: "r"(_num)							\
-		: "memory", "$t0", "$t1", "$t2", "$t3",				\
-		  "$t4", "$t5", "$t6", "$t7", "$t8"				\
+		: SYSCALL_CLOBBERLIST						\
 	);									\
 	_arg1;									\
 })
@@ -64,8 +66,7 @@
 		: "+r"(_arg1)							\
 		: "r"(_arg2),							\
 		  "r"(_num)							\
-		: "memory", "$t0", "$t1", "$t2", "$t3",				\
-		  "$t4", "$t5", "$t6", "$t7", "$t8"				\
+		: SYSCALL_CLOBBERLIST						\
 	);									\
 	_arg1;									\
 })
@@ -82,8 +83,7 @@
 		: "+r"(_arg1)							\
 		: "r"(_arg2), "r"(_arg3),					\
 		  "r"(_num)							\
-		: "memory", "$t0", "$t1", "$t2", "$t3",				\
-		  "$t4", "$t5", "$t6", "$t7", "$t8"				\
+		: SYSCALL_CLOBBERLIST						\
 	);									\
 	_arg1;									\
 })
@@ -101,8 +101,7 @@
 		: "+r"(_arg1)							\
 		: "r"(_arg2), "r"(_arg3), "r"(_arg4),				\
 		  "r"(_num)							\
-		: "memory", "$t0", "$t1", "$t2", "$t3",				\
-		  "$t4", "$t5", "$t6", "$t7", "$t8"				\
+		: SYSCALL_CLOBBERLIST						\
 	);									\
 	_arg1;									\
 })
@@ -121,8 +120,7 @@
 		: "+r"(_arg1)							\
 		: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),		\
 		  "r"(_num)							\
-		: "memory", "$t0", "$t1", "$t2", "$t3",				\
-		  "$t4", "$t5", "$t6", "$t7", "$t8"				\
+		: SYSCALL_CLOBBERLIST						\
 	);									\
 	_arg1;									\
 })
@@ -142,8 +140,7 @@
 		: "+r"(_arg1)							\
 		: "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), "r"(_arg6),	\
 		  "r"(_num)							\
-		: "memory", "$t0", "$t1", "$t2", "$t3",				\
-		  "$t4", "$t5", "$t6", "$t7", "$t8"				\
+		: SYSCALL_CLOBBERLIST						\
 	);									\
 	_arg1;									\
 })
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 08/14] tools/nolibc: arch-mips.h: shrink with SYSCALL_CLOBBERLIST
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
                     ` (6 preceding siblings ...)
  2023-06-28 13:22   ` [PATCH v5 07/14] tools/nolibc: arch-loongarch.h: shrink with SYSCALL_CLOBBERLIST Zhangjin Wu
@ 2023-06-28 13:31   ` Zhangjin Wu
  2023-06-28 13:37   ` [PATCH v5 09/14] tools/nolibc: add missing my_syscall6() for mips Zhangjin Wu
                     ` (6 subsequent siblings)
  14 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-28 13:31 UTC (permalink / raw)
  To: thomas, w
  Cc: falcon, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

my_syscall<N> share a same long clobber list, define a macro for them.

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/arch-mips.h | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/tools/include/nolibc/arch-mips.h b/tools/include/nolibc/arch-mips.h
index 1fd1eedc12a6..55a9f01825e0 100644
--- a/tools/include/nolibc/arch-mips.h
+++ b/tools/include/nolibc/arch-mips.h
@@ -57,6 +57,10 @@ struct sys_stat_struct {
  *     don't have to experience issues with register constraints.
  */
 
+#define SYSCALL_CLOBBERLIST			\
+	"memory", "cc", "at", "v1", "hi", "lo",	\
+	"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"
+
 #define my_syscall0(num)							\
 ({										\
 	register long _num __asm__ ("v0") = (num);				\
@@ -68,8 +72,7 @@ struct sys_stat_struct {
 		"addiu $sp, $sp, 32\n"						\
 		: "=r"(_num), "=r"(_arg4)					\
 		: "r"(_num)							\
-		: "memory", "cc", "at", "v1", "hi", "lo",			\
-		  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"	\
+		: SYSCALL_CLOBBERLIST						\
 	);									\
 	_arg4 ? -_num : _num;							\
 })
@@ -87,8 +90,7 @@ struct sys_stat_struct {
 		: "=r"(_num), "=r"(_arg4)					\
 		: "0"(_num),							\
 		  "r"(_arg1)							\
-		: "memory", "cc", "at", "v1", "hi", "lo",			\
-		  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"	\
+		: SYSCALL_CLOBBERLIST						\
 	);									\
 	_arg4 ? -_num : _num;							\
 })
@@ -107,8 +109,7 @@ struct sys_stat_struct {
 		: "=r"(_num), "=r"(_arg4)					\
 		: "0"(_num),							\
 		  "r"(_arg1), "r"(_arg2)					\
-		: "memory", "cc", "at", "v1", "hi", "lo",			\
-		  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"	\
+		: SYSCALL_CLOBBERLIST						\
 	);									\
 	_arg4 ? -_num : _num;							\
 })
@@ -128,8 +129,7 @@ struct sys_stat_struct {
 		: "=r"(_num), "=r"(_arg4)					\
 		: "0"(_num),							\
 		  "r"(_arg1), "r"(_arg2), "r"(_arg3)				\
-		: "memory", "cc", "at", "v1", "hi", "lo",			\
-		  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"	\
+		: SYSCALL_CLOBBERLIST						\
 	);									\
 	_arg4 ? -_num : _num;							\
 })
@@ -149,8 +149,7 @@ struct sys_stat_struct {
 		: "=r" (_num), "=r"(_arg4)					\
 		: "0"(_num),							\
 		  "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4)		\
-		: "memory", "cc", "at", "v1", "hi", "lo",			\
-		  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"	\
+		: SYSCALL_CLOBBERLIST						\
 	);									\
 	_arg4 ? -_num : _num;							\
 })
@@ -172,8 +171,7 @@ struct sys_stat_struct {
 		: "=r" (_num), "=r"(_arg4)					\
 		: "0"(_num),							\
 		  "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5)	\
-		: "memory", "cc", "at", "v1", "hi", "lo",			\
-		  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"	\
+		: SYSCALL_CLOBBERLIST						\
 	);									\
 	_arg4 ? -_num : _num;							\
 })
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 09/14] tools/nolibc: add missing my_syscall6() for mips
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
                     ` (7 preceding siblings ...)
  2023-06-28 13:31   ` [PATCH v5 08/14] tools/nolibc: arch-mips.h: " Zhangjin Wu
@ 2023-06-28 13:37   ` Zhangjin Wu
  2023-07-02 18:55     ` Willy Tarreau
  2023-06-28 13:39   ` [PATCH v5 10/14] tools/nolibc: __sysret: support syscalls who return a pointer Zhangjin Wu
                     ` (5 subsequent siblings)
  14 siblings, 1 reply; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-28 13:37 UTC (permalink / raw)
  To: thomas, w
  Cc: falcon, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

It is able to pass the 6th argument like the 5th argument via the stack
for mips, let's add a new my_syscall6() now, see [1] for details:

  The mips/o32 system call convention passes arguments 5 through 8 on
  the user stack.

Both mmap() and pselect6() require my_syscall6().

[1]: https://man7.org/linux/man-pages/man2/syscall.2.html

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/arch-mips.h | 25 +++++++++++++++++++++++++
 tools/include/nolibc/nolibc.h    |  9 ++++-----
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/tools/include/nolibc/arch-mips.h b/tools/include/nolibc/arch-mips.h
index 55a9f01825e0..a8b33d6914a4 100644
--- a/tools/include/nolibc/arch-mips.h
+++ b/tools/include/nolibc/arch-mips.h
@@ -176,6 +176,31 @@ struct sys_stat_struct {
 	_arg4 ? -_num : _num;							\
 })
 
+#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)			\
+({										\
+	register long _num __asm__ ("v0")  = (num);				\
+	register long _arg1 __asm__ ("a0") = (long)(arg1);			\
+	register long _arg2 __asm__ ("a1") = (long)(arg2);			\
+	register long _arg3 __asm__ ("a2") = (long)(arg3);			\
+	register long _arg4 __asm__ ("a3") = (long)(arg4);			\
+	register long _arg5 = (long)(arg5);					\
+	register long _arg6 = (long)(arg6);					\
+										\
+	__asm__ volatile (							\
+		"addiu $sp, $sp, -32\n"						\
+		"sw %7, 16($sp)\n"						\
+		"sw %8, 20($sp)\n"						\
+		"syscall\n  "							\
+		"addiu $sp, $sp, 32\n"						\
+		: "=r" (_num), "=r"(_arg4)					\
+		: "0"(_num),							\
+		  "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5),	\
+		  "r"(_arg6)							\
+		: SYSCALL_CLOBBERLIST						\
+	);									\
+	_arg4 ? -_num : _num;							\
+})
+
 char **environ __attribute__((weak));
 const unsigned long *_auxv __attribute__((weak));
 
diff --git a/tools/include/nolibc/nolibc.h b/tools/include/nolibc/nolibc.h
index 05a228a6ee78..1f8d821000ac 100644
--- a/tools/include/nolibc/nolibc.h
+++ b/tools/include/nolibc/nolibc.h
@@ -13,11 +13,10 @@
  * Syscalls are split into 3 levels:
  *   - The lower level is the arch-specific syscall() definition, consisting in
  *     assembly code in compound expressions. These are called my_syscall0() to
- *     my_syscall6() depending on the number of arguments. The MIPS
- *     implementation is limited to 5 arguments. All input arguments are cast
- *     to a long stored in a register. These expressions always return the
- *     syscall's return value as a signed long value which is often either a
- *     pointer or the negated errno value.
+ *     my_syscall6() depending on the number of arguments. All input arguments
+ *     are castto a long stored in a register. These expressions always return
+ *     the syscall's return value as a signed long value which is often either
+ *     a pointer or the negated errno value.
  *
  *   - The second level is mostly architecture-independent. It is made of
  *     static functions called sys_<name>() which rely on my_syscallN()
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 10/14] tools/nolibc: __sysret: support syscalls who return a pointer
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
                     ` (8 preceding siblings ...)
  2023-06-28 13:37   ` [PATCH v5 09/14] tools/nolibc: add missing my_syscall6() for mips Zhangjin Wu
@ 2023-06-28 13:39   ` Zhangjin Wu
  2023-07-02 19:17     ` Willy Tarreau
  2023-06-28 13:41   ` [PATCH v5 11/14] tools/nolibc: clean up mmap() support Zhangjin Wu
                     ` (4 subsequent siblings)
  14 siblings, 1 reply; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-28 13:39 UTC (permalink / raw)
  To: thomas, w
  Cc: falcon, arnd, david.laight, linux-kernel, linux-kselftest,
	linux-riscv, David Laight

To support syscalls (e.g. mmap()) who return a pointer and to allow the
pointer as big as possible, we should convert the negated errno value to
unsigned long (uintptr_t), otherwise, in signed long, a potential big
pointer (whose highest bit is 1) will be treated as a failure.

tools/include/nolibc/errno.h defines the MAX_ERRNO, let's use it
directly. after converting to unsigned long, the negative errno value
from -1 to -MAX_ERRNO becomes something like '~1 + 1' (every bit is 1)
to '~MAX_ERRNO + 1', '~1 + 1' is the biggest, '~MAX_ERRNO + 1' is the
smallest, so, the check becomes:

    if (ret <= (unsigned long)-1 && ret >= (unsigned long)-MAX_ERRNO) {
        ...
    }

Since (unsigned long)-1 is the biggest unsigned long value, it is always
true if bigger than (unsigned long)-MAX_ERRNO, so, just reserve the
following check is enough:

    if (ret >= (unsigned long)-MAX_ERRNO) {
        ...
    }

Suggested-by: David Laight <David.Laight@ACULAB.COM>
Link: https://lore.kernel.org/linux-riscv/94dd5170929f454fbc0a10a2eb3b108d@AcuMS.aculab.com/
Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/sys.h | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index 53bc3ad6593e..b6125e600dc2 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -28,13 +28,16 @@
 #include "errno.h"
 #include "types.h"
 
-/* Syscall return helper, set errno as -ret when ret < 0 */
+
+/* Syscall return helper for library routines
+ * set errno as -ret when ret in [-MAX_ERRNO, -1]
+ */
 static __inline__ __attribute__((unused, always_inline))
-long __sysret(long ret)
+long __sysret(unsigned long ret)
 {
-	if (ret < 0) {
-		SET_ERRNO(-ret);
-		ret = -1;
+	if (ret >= (unsigned long)-MAX_ERRNO) {
+		SET_ERRNO(-(long)ret);
+		return -1;
 	}
 	return ret;
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 11/14] tools/nolibc: clean up mmap() support
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
                     ` (9 preceding siblings ...)
  2023-06-28 13:39   ` [PATCH v5 10/14] tools/nolibc: __sysret: support syscalls who return a pointer Zhangjin Wu
@ 2023-06-28 13:41   ` Zhangjin Wu
  2023-07-02 19:23     ` Willy Tarreau
  2023-06-28 13:44   ` [PATCH v5 12/14] selftests/nolibc: add EXPECT_PTREQ, EXPECT_PTRNE and EXPECT_PTRER Zhangjin Wu
                     ` (3 subsequent siblings)
  14 siblings, 1 reply; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-28 13:41 UTC (permalink / raw)
  To: thomas, w
  Cc: falcon, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

Do several cleanups together:

- Since all supported architectures have my_syscall6() now, remove the
  #ifdef check.

- Move the mmap() related macros to tools/include/nolibc/types.h and
  reuse most of them from <linux/mman.h>

- Apply the new __sysret() to convert the calling of sys_map() to
  oneline code

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/sys.h   | 24 +-----------------------
 tools/include/nolibc/types.h |  6 ++++++
 2 files changed, 7 insertions(+), 23 deletions(-)

diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index b6125e600dc2..e0ac95a4bfa1 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -632,26 +632,11 @@ int mknod(const char *path, mode_t mode, dev_t dev)
 	return __sysret(sys_mknod(path, mode, dev));
 }
 
-#ifndef MAP_SHARED
-#define MAP_SHARED		0x01	/* Share changes */
-#define MAP_PRIVATE		0x02	/* Changes are private */
-#define MAP_SHARED_VALIDATE	0x03	/* share + validate extension flags */
-#endif
-
-#ifndef MAP_FAILED
-#define MAP_FAILED ((void *)-1)
-#endif
-
 #ifndef sys_mmap
 static __attribute__((unused))
 void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
 	       off_t offset)
 {
-#ifndef my_syscall6
-	/* Function not implemented. */
-	return (void *)-ENOSYS;
-#else
-
 	int n;
 
 #if defined(__NR_mmap2)
@@ -662,20 +647,13 @@ void *sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
 #endif
 
 	return (void *)my_syscall6(n, addr, length, prot, flags, fd, offset);
-#endif
 }
 #endif
 
 static __attribute__((unused))
 void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
 {
-	void *ret = sys_mmap(addr, length, prot, flags, fd, offset);
-
-	if ((unsigned long)ret >= -4095UL) {
-		SET_ERRNO(-(long)ret);
-		ret = MAP_FAILED;
-	}
-	return ret;
+	return (void *)__sysret((unsigned long)sys_mmap(addr, length, prot, flags, fd, offset));
 }
 
 static __attribute__((unused))
diff --git a/tools/include/nolibc/types.h b/tools/include/nolibc/types.h
index f96e28bff4ba..bed62da7877c 100644
--- a/tools/include/nolibc/types.h
+++ b/tools/include/nolibc/types.h
@@ -10,6 +10,7 @@
 #include "std.h"
 #include <linux/time.h>
 #include <linux/stat.h>
+#include <linux/mman.h>
 
 
 /* Only the generic macros and types may be defined here. The arch-specific
@@ -81,6 +82,11 @@
 #define MAXPATHLEN     (PATH_MAX)
 #endif
 
+/* flags for mmap */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
 /* whence values for lseek() */
 #define SEEK_SET       0
 #define SEEK_CUR       1
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 12/14] selftests/nolibc: add EXPECT_PTREQ, EXPECT_PTRNE and EXPECT_PTRER
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
                     ` (10 preceding siblings ...)
  2023-06-28 13:41   ` [PATCH v5 11/14] tools/nolibc: clean up mmap() support Zhangjin Wu
@ 2023-06-28 13:44   ` Zhangjin Wu
  2023-06-28 13:46   ` [PATCH v5 13/14] selftests/nolibc: add sbrk_0 to test current brk getting Zhangjin Wu
                     ` (2 subsequent siblings)
  14 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-28 13:44 UTC (permalink / raw)
  To: thomas, w
  Cc: falcon, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

The syscalls like sbrk() and mmap() return pointers, to test them, more
pointer compare test macros are required, add them:

- EXPECT_PTREQ() expects two equal pointers.
- EXPECT_PTRNE() expects two non-equal pointers.
- EXPECT_PTRER() expects failure with a specified errno.
- EXPECT_PTRER2() expects failure with two specified errnos.

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/testing/selftests/nolibc/nolibc-test.c | 58 ++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 486334981e60..34af802dadfd 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -361,6 +361,64 @@ static int expect_ptrnz(const void *expr, int llen)
 	return ret;
 }
 
+#define EXPECT_PTREQ(cond, expr, cmp)				\
+	do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ptreq(expr, llen, cmp); } while (0)
+
+static int expect_ptreq(const void *expr, int llen, const void *cmp)
+{
+	int ret = 0;
+
+	llen += printf(" = <%p> ", expr);
+	if (expr != cmp) {
+		ret = 1;
+		llen += pad_spc(llen, 64, "[FAIL]\n");
+	} else {
+		llen += pad_spc(llen, 64, " [OK]\n");
+	}
+	return ret;
+}
+
+#define EXPECT_PTRNE(cond, expr, cmp)				\
+	do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ptrne(expr, llen, cmp); } while (0)
+
+static int expect_ptrne(const void *expr, int llen, const void *cmp)
+{
+	int ret = 0;
+
+	llen += printf(" = <%p> ", expr);
+	if (expr == cmp) {
+		ret = 1;
+		llen += pad_spc(llen, 64, "[FAIL]\n");
+	} else {
+		llen += pad_spc(llen, 64, " [OK]\n");
+	}
+	return ret;
+}
+
+#define EXPECT_PTRER2(cond, expr, expret, experr1, experr2)		\
+	do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_ptrerr2(expr, expret, experr1, experr2, llen); } while (0)
+
+#define EXPECT_PTRER(cond, expr, expret, experr)			\
+	EXPECT_PTRER2(cond, expr, expret, experr, 0)
+
+static int expect_ptrerr2(const void *expr, const void *expret, int experr1, int experr2, int llen)
+{
+	int ret = 0;
+	int _errno = errno;
+
+	llen += printf(" = <%p> %s ", expr, errorname(_errno));
+	if (expr != expret || (_errno != experr1 && _errno != experr2)) {
+		ret = 1;
+		if (experr2 == 0)
+			llen += printf(" != (<%p> %s) ", expret, errorname(experr1));
+		else
+			llen += printf(" != (<%p> %s %s) ", expret, errorname(experr1), errorname(experr2));
+		llen += pad_spc(llen, 64, "[FAIL]\n");
+	} else {
+		llen += pad_spc(llen, 64, " [OK]\n");
+	}
+	return ret;
+}
 
 #define EXPECT_STRZR(cond, expr)				\
 	do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_strzr(expr, llen); } while (0)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 13/14] selftests/nolibc: add sbrk_0 to test current brk getting
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
                     ` (11 preceding siblings ...)
  2023-06-28 13:44   ` [PATCH v5 12/14] selftests/nolibc: add EXPECT_PTREQ, EXPECT_PTRNE and EXPECT_PTRER Zhangjin Wu
@ 2023-06-28 13:46   ` Zhangjin Wu
  2023-06-28 13:51   ` [PATCH v5 14/14] selftests/nolibc: add mmap and munmap test cases Zhangjin Wu
  2023-07-02 19:34   ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Willy Tarreau
  14 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-28 13:46 UTC (permalink / raw)
  To: thomas, w
  Cc: falcon, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

From musl 0.9.14 (to the latest version 1.2.3), both sbrk() and brk()
have almost been disabled for they conflict with malloc, only sbrk(0) is
still permitted as a way to get the current brk, let's support such
case.

EXPECT_PTRNE() is used to expect sbrk() always successfully getting the
current brk.

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/testing/selftests/nolibc/nolibc-test.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 34af802dadfd..80ab29e2887c 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -630,6 +630,7 @@ int run_syscall(int min, int max)
 		CASE_TEST(kill_0);            EXPECT_SYSZR(1, kill(getpid(), 0)); break;
 		CASE_TEST(kill_CONT);         EXPECT_SYSZR(1, kill(getpid(), 0)); break;
 		CASE_TEST(kill_BADPID);       EXPECT_SYSER(1, kill(INT_MAX, 0), -1, ESRCH); break;
+		CASE_TEST(sbrk_0);            EXPECT_PTRNE(1, sbrk(0), (void *)-1); break;
 		CASE_TEST(sbrk);              if ((p1 = p2 = sbrk(4096)) != (void *)-1) p2 = sbrk(-4096); EXPECT_SYSZR(1, (p2 == (void *)-1) || p2 == p1); break;
 		CASE_TEST(brk);               EXPECT_SYSZR(1, brk(sbrk(0))); break;
 		CASE_TEST(chdir_root);        EXPECT_SYSZR(1, chdir("/")); break;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v5 14/14] selftests/nolibc: add mmap and munmap test cases
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
                     ` (12 preceding siblings ...)
  2023-06-28 13:46   ` [PATCH v5 13/14] selftests/nolibc: add sbrk_0 to test current brk getting Zhangjin Wu
@ 2023-06-28 13:51   ` Zhangjin Wu
  2023-07-02 19:33     ` Willy Tarreau
  2023-07-02 19:34   ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Willy Tarreau
  14 siblings, 1 reply; 54+ messages in thread
From: Zhangjin Wu @ 2023-06-28 13:51 UTC (permalink / raw)
  To: thomas, w
  Cc: falcon, arnd, david.laight, linux-kernel, linux-kselftest,
	linux-riscv, Thomas Weißschuh

Three mmap/munmap related test cases are added:

- mmap_bad: the length argument must be greater than 0, otherwise, fail
  with -EINVAL.

- munmap_bad: invalid (void *)-1 address fail with -EINVAL.

- mmap_munmap_good: mmap() a file with good offset and then munmap().

Note, it is not easy to find a unique file for mmap() in different
scenes, so, a file list is used to search the right one:

- /proc/1/exe, for 'run' and 'run-user' target
  'run-user' can not find '/proc/self/exe'

- /proc/self/exe, for 'libc-test' target
  normal program 'libc-test' has no permission to access '/proc/1/exe'

- the others, for kernel without procfs
  let it pass even with 'worst case' kernel configs

Suggested-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://lore.kernel.org/lkml/bff82ea6-610b-4471-a28b-6c76c28604a6@t-8ch.de/
Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/testing/selftests/nolibc/nolibc-test.c | 56 ++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 80ab29e2887c..b178bfa29ad9 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -592,6 +592,59 @@ static int test_stat_timestamps(void)
 	return 0;
 }
 
+int test_mmap_munmap(void)
+{
+	int ret, fd, i;
+	void *mem;
+	size_t page_size, file_size, length;
+	off_t offset, pa_offset;
+	struct stat stat_buf;
+	static const char * const files[] = {
+		"/proc/1/exe", "/proc/self/exe",
+		"/init", "/sbin/init", "/etc/init", "/bin/init", "/bin/sh",
+		NULL
+	};
+
+	page_size = getpagesize();
+	if (page_size < 0)
+		return -1;
+
+	/* find a right file to mmap, existed and accessible */
+	for (i = 0; files[i] != NULL; i++) {
+		ret = fd = open(files[i], O_RDONLY);
+		if (ret == -1)
+			continue;
+		else
+			break;
+	}
+	if (ret == -1)
+		return ret;
+
+	ret = stat(files[i], &stat_buf);
+	if (ret == -1)
+		goto end;
+
+	file_size = stat_buf.st_size;
+	offset = file_size - 1;
+	if (offset < 0)
+		offset = 0;
+	length = file_size - offset;
+	pa_offset = offset & ~(page_size - 1);
+
+	mem = mmap(NULL, length + offset - pa_offset, PROT_READ, MAP_SHARED, fd, pa_offset);
+	if (mem == MAP_FAILED) {
+		ret = -1;
+		goto end;
+	}
+
+	ret = munmap(mem, length + offset - pa_offset);
+
+end:
+	close(fd);
+	return ret;
+}
+
+
 /* Run syscall tests between IDs <min> and <max>.
  * Return 0 on success, non-zero on failure.
  */
@@ -666,6 +719,9 @@ int run_syscall(int min, int max)
 		CASE_TEST(lseek_m1);          EXPECT_SYSER(1, lseek(-1, 0, SEEK_SET), -1, EBADF); break;
 		CASE_TEST(lseek_0);           EXPECT_SYSER(1, lseek(0, 0, SEEK_SET), -1, ESPIPE); break;
 		CASE_TEST(mkdir_root);        EXPECT_SYSER(1, mkdir("/", 0755), -1, EEXIST); break;
+		CASE_TEST(mmap_bad);          EXPECT_PTRER(1, mmap(NULL, 0, PROT_READ, MAP_PRIVATE, 0, 0), MAP_FAILED, EINVAL); break;
+		CASE_TEST(munmap_bad);        EXPECT_SYSER(1, munmap((void *)-1, 0), -1, EINVAL); break;
+		CASE_TEST(mmap_munmap_good);  EXPECT_SYSZR(1, test_mmap_munmap()); break;
 		CASE_TEST(open_tty);          EXPECT_SYSNE(1, tmp = open("/dev/null", 0), -1); if (tmp != -1) close(tmp); break;
 		CASE_TEST(open_blah);         EXPECT_SYSER(1, tmp = open("/proc/self/blah", 0), -1, ENOENT); if (tmp != -1) close(tmp); break;
 		CASE_TEST(poll_null);         EXPECT_SYSZR(1, poll(NULL, 0, 0)); break;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 06/14] tools/nolibc: arch-*.h: clean up multiple whitespaces
  2023-06-28 13:19   ` [PATCH v5 06/14] tools/nolibc: arch-*.h: clean up multiple whitespaces Zhangjin Wu
@ 2023-07-02 18:44     ` Willy Tarreau
  2023-07-03 14:02       ` Zhangjin Wu
  0 siblings, 1 reply; 54+ messages in thread
From: Willy Tarreau @ 2023-07-02 18:44 UTC (permalink / raw)
  To: Zhangjin Wu
  Cc: thomas, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

Hi Zhangjin,

On Wed, Jun 28, 2023 at 09:19:33PM +0800, Zhangjin Wu wrote:
> To align with Linux code style and let scripts/checkpatch.pl happy, the
> multiple whitespaces in arch-<ARCH>.h files are cleaned up.
> 
> Most of them are modified by these commands automatically:
> 
>     $ sed -i -e '/#define my_syscall/,/})/{s/        /\t/g}' tools/include/nolibc/arch-*.h
>     $ sed -i -e '/#define my_syscall/,/})/{s/ *\\$/\t\\/g}' tools/include/nolibc/arch-*.h
> 
> And checked with:
> 
>     $ grep '  *\\$' tools/include/nolibc/arch-*.h

I'm surprised by this one, I never saw checkpatch complain here. For me,
putting a tab after a non-tab is an error. It makes the code harder to
edit and re-align, and diffs are harder to read on lines whose lengths
varies by +/-1 around a multiple of 8 as it makes the post-tab stuff
zigzag. You made me recheck the coding style file, and there's nothing
about alignment there, only about indent (and indent uses tabs here).
There are also other parts which use spaces for alignment (albeit not
that many), so unless there is a solid reason for changing that, I'd
rather not do it, as for me it's the exact opposite of a cleanup as it
will cause me quite some discomfort.

> Besides, more multiple whitespaces are cleaned up:
> 
> - convert "__asm__  volatile" to "__asm__ volatile"

I totally agree on this one, it's very likely the result of a mechanical
change.

> - "foo _num  bar" should be "foo _num bar"

In theory yes, except that for those where it appears it was only to
keep all declarations aligned given that this _num was shorter by one
char than all other local names. Especially when it comes to enumerating
register names, you definitely want to keep them aligned. It's sufficiently
difficult to avoid mistakes there, any help for visual check counts.

Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 07/14] tools/nolibc: arch-loongarch.h: shrink with SYSCALL_CLOBBERLIST
  2023-06-28 13:22   ` [PATCH v5 07/14] tools/nolibc: arch-loongarch.h: shrink with SYSCALL_CLOBBERLIST Zhangjin Wu
@ 2023-07-02 18:50     ` Willy Tarreau
  2023-07-03 11:28       ` Zhangjin Wu
  0 siblings, 1 reply; 54+ messages in thread
From: Willy Tarreau @ 2023-07-02 18:50 UTC (permalink / raw)
  To: Zhangjin Wu
  Cc: thomas, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

On Wed, Jun 28, 2023 at 09:22:21PM +0800, Zhangjin Wu wrote:
> my_syscall<N> share a same long clobber list, define a macro for them.
> 
> Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
> ---
>  tools/include/nolibc/arch-loongarch.h | 25 +++++++++++--------------
>  1 file changed, 11 insertions(+), 14 deletions(-)
> 
> diff --git a/tools/include/nolibc/arch-loongarch.h b/tools/include/nolibc/arch-loongarch.h
> index 292d6a58dc87..fbb4844f7993 100644
> --- a/tools/include/nolibc/arch-loongarch.h
> +++ b/tools/include/nolibc/arch-loongarch.h
> @@ -23,6 +23,10 @@
>   */
>  #define __ARCH_WANT_SYS_PSELECT6
>  
> +#define SYSCALL_CLOBBERLIST			\
> +	"memory", "$t0", "$t1", "$t2", "$t3",	\
> +	"$t4", "$t5", "$t6", "$t7", "$t8"
> +

That's a good idea, but please be careful when adding macro definitions,
we're in code that is used by user space we have no control on, and we're
polluting the end user's macro namespace with plenty of names. While one
could argue that it's unlikely that some program already defines and uses
SYSCALL_CLOBBERLIST, actually with low-level code it's fairly possible.

Till now most of the definitions were for stuff that user-space really
needs (e.g. STDIN_FILENO, various integer limits). If we start to declare
random macros for internal use, at least we should probably prefix them
with _NOLIBC_ or something like this to avoid the risk of collision.

Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 09/14] tools/nolibc: add missing my_syscall6() for mips
  2023-06-28 13:37   ` [PATCH v5 09/14] tools/nolibc: add missing my_syscall6() for mips Zhangjin Wu
@ 2023-07-02 18:55     ` Willy Tarreau
  2023-07-03 10:13       ` Zhangjin Wu
  0 siblings, 1 reply; 54+ messages in thread
From: Willy Tarreau @ 2023-07-02 18:55 UTC (permalink / raw)
  To: Zhangjin Wu
  Cc: thomas, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

Hi Zhangjin,

On Wed, Jun 28, 2023 at 09:37:29PM +0800, Zhangjin Wu wrote:
> It is able to pass the 6th argument like the 5th argument via the stack
> for mips, let's add a new my_syscall6() now, see [1] for details:
> 
>   The mips/o32 system call convention passes arguments 5 through 8 on
>   the user stack.
> 
> Both mmap() and pselect6() require my_syscall6().

Very interesting, I didn't manage to make it work previously. Did you
test it to confirm that it works ? I guess so but since you didn't
mention, I preferred to ask.

Thanks!
Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 10/14] tools/nolibc: __sysret: support syscalls who return a pointer
  2023-06-28 13:39   ` [PATCH v5 10/14] tools/nolibc: __sysret: support syscalls who return a pointer Zhangjin Wu
@ 2023-07-02 19:17     ` Willy Tarreau
  2023-07-03  8:36       ` Zhangjin Wu
  0 siblings, 1 reply; 54+ messages in thread
From: Willy Tarreau @ 2023-07-02 19:17 UTC (permalink / raw)
  To: Zhangjin Wu
  Cc: thomas, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

On Wed, Jun 28, 2023 at 09:39:56PM +0800, Zhangjin Wu wrote:
> To support syscalls (e.g. mmap()) who return a pointer and to allow the
> pointer as big as possible, we should convert the negated errno value to
> unsigned long (uintptr_t), otherwise, in signed long, a potential big
> pointer (whose highest bit is 1) will be treated as a failure.
> 
> tools/include/nolibc/errno.h defines the MAX_ERRNO, let's use it
> directly.

It might or might not work, it's an ABI change that, if validated, at
least needs a much more detailed explanation. What matters is not what
errno values we're willing to consider as an error, but what the
*syscalls* themselves return as an error. If a syscall says "< 0 is an
error equal to -errno", it means that we must treat it as an error,
and extract its value to get errno. If that errno is larger than
MAX_ERRNO it just means we don't know what the error is.

Syscalls that return pointer use that -MAX_ERRNO range to encode errors
(such as mmap()). I just do not know if there is a convention saying that
other ones also restrict themselves to that range or not. If you find
some info which guarantees that it's the case for all of them, then by
all means let's proceed like this, but in this case it should be mentioned
in the comment why we think it's valid to do this. For now it's presented
as an opportunity only.

Also, the rest of the commit message regarding uintptr_t (which we don't
use), bit values and modular arithmetics is extremely confusing and not
needed at all. What matters is only to know if we need to consider only
values -MAX_ERRNO..-1 as error or all negative ones. If so, then it's
obvious that ret >= (unsigned long)-MAX_ERRNO catches them all, as the
current mmap() function already does with -4095UL.

I just don't know where to check if we can generalize that test. In the
worst case we could have two __sys_ret(), the current one and a second
one for pointers. But I would suspect we could generalize due to ptrace,
as there it makes sense to be able to detect failures, even unknown ones.
I just need something more convincing than an intuition for a commit
message and to take such a change :-/

Thanks!
Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 11/14] tools/nolibc: clean up mmap() support
  2023-06-28 13:41   ` [PATCH v5 11/14] tools/nolibc: clean up mmap() support Zhangjin Wu
@ 2023-07-02 19:23     ` Willy Tarreau
  2023-07-03  6:51       ` Zhangjin Wu
  0 siblings, 1 reply; 54+ messages in thread
From: Willy Tarreau @ 2023-07-02 19:23 UTC (permalink / raw)
  To: Zhangjin Wu
  Cc: thomas, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

On Wed, Jun 28, 2023 at 09:41:13PM +0800, Zhangjin Wu wrote:
>  static __attribute__((unused))
>  void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
>  {
> -	void *ret = sys_mmap(addr, length, prot, flags, fd, offset);
> -
> -	if ((unsigned long)ret >= -4095UL) {
> -		SET_ERRNO(-(long)ret);
> -		ret = MAP_FAILED;
> -	}
> -	return ret;
> +	return (void *)__sysret((unsigned long)sys_mmap(addr, length, prot, flags, fd, offset));
>  }

One point regarding this one. By doing so, we're hard-coding the fact
that we consider that MAP_FAILED is always -1. I'm not necessarily
against it, but this implication can be confusing for those searching
where it's being set. I would suggest putting a comment before the
mmap() function saying:

 /* Note that on Linux MAP_FAILED is -1 so we can use the generic __sysret()
  * which returns -1 upon error and still satisfy user land that checks for
  * MAP_FAILED.
  */

Since it's an assumed choice that theoretically could affect portability,
it should be reflected in the commit message as well (and we all know it
does not have any impact).

Thanks!
Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 14/14] selftests/nolibc: add mmap and munmap test cases
  2023-06-28 13:51   ` [PATCH v5 14/14] selftests/nolibc: add mmap and munmap test cases Zhangjin Wu
@ 2023-07-02 19:33     ` Willy Tarreau
  2023-07-03  6:03       ` Zhangjin Wu
  0 siblings, 1 reply; 54+ messages in thread
From: Willy Tarreau @ 2023-07-02 19:33 UTC (permalink / raw)
  To: Zhangjin Wu
  Cc: thomas, arnd, david.laight, linux-kernel, linux-kselftest,
	linux-riscv, Thomas Weißschuh

Hi Zhangjin,

On Wed, Jun 28, 2023 at 09:51:57PM +0800, Zhangjin Wu wrote:
> Three mmap/munmap related test cases are added:
> 
> - mmap_bad: the length argument must be greater than 0, otherwise, fail
>   with -EINVAL.
> 
> - munmap_bad: invalid (void *)-1 address fail with -EINVAL.
> 
> - mmap_munmap_good: mmap() a file with good offset and then munmap().
> 
> Note, it is not easy to find a unique file for mmap() in different
> scenes, so, a file list is used to search the right one:
> 
> - /proc/1/exe, for 'run' and 'run-user' target
>   'run-user' can not find '/proc/self/exe'
> 
> - /proc/self/exe, for 'libc-test' target
>   normal program 'libc-test' has no permission to access '/proc/1/exe'

Strictly speaking, if your executable is not readable (e.g. chmod 111
due to a restrictive umask) it will also fail that one.

> - the others, for kernel without procfs
>   let it pass even with 'worst case' kernel configs

You should include /dev/zero, which is commonly used to allocate anonymous
memory and is more likely present and readable than any of the other files.
And another file of choice is obviously argv[0] ;-)  In this case you don't
need any of the other extra ones. Thus I could suggest that you try in this
order:

    /dev/zero, /proc/self/exe, /proc/1/exe, argv[0]

and be done with it. That doesn't prevent one from extending the list if
really needed later, but I doubt it would be needed. Also, it's already
arranged in a read-write, then read-only fallbacks mode, so if we later
need to add more complex tests involving writes, the writable /dev/zero
will have precedence.

Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 00/14] tools/nolibc: add a new syscall helper
  2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
                     ` (13 preceding siblings ...)
  2023-06-28 13:51   ` [PATCH v5 14/14] selftests/nolibc: add mmap and munmap test cases Zhangjin Wu
@ 2023-07-02 19:34   ` Willy Tarreau
  14 siblings, 0 replies; 54+ messages in thread
From: Willy Tarreau @ 2023-07-02 19:34 UTC (permalink / raw)
  To: Zhangjin Wu
  Cc: thomas, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

On Wed, Jun 28, 2023 at 09:07:16PM +0800, Zhangjin Wu wrote:
> Willy, Thomas
> 
> This is the revision of our 'tools/nolibc: add a new syscall helper'
> series [1].
(...)

just to let you know that I've read them all and am fine with the ones
I didn't comment on.

Thanks Zhangjin!
Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 14/14] selftests/nolibc: add mmap and munmap test cases
  2023-07-02 19:33     ` Willy Tarreau
@ 2023-07-03  6:03       ` Zhangjin Wu
  2023-07-03  7:25         ` Willy Tarreau
  0 siblings, 1 reply; 54+ messages in thread
From: Zhangjin Wu @ 2023-07-03  6:03 UTC (permalink / raw)
  To: w
  Cc: arnd, david.laight, falcon, linux-kernel, linux-kselftest,
	linux-riscv, linux, thomas

> Hi Zhangjin,
> 
> On Wed, Jun 28, 2023 at 09:51:57PM +0800, Zhangjin Wu wrote:
> > Three mmap/munmap related test cases are added:
> > 
> > - mmap_bad: the length argument must be greater than 0, otherwise, fail
> >   with -EINVAL.
> > 
> > - munmap_bad: invalid (void *)-1 address fail with -EINVAL.
> > 
> > - mmap_munmap_good: mmap() a file with good offset and then munmap().
> > 
> > Note, it is not easy to find a unique file for mmap() in different
> > scenes, so, a file list is used to search the right one:
> > 
> > - /proc/1/exe, for 'run' and 'run-user' target
> >   'run-user' can not find '/proc/self/exe'
> > 
> > - /proc/self/exe, for 'libc-test' target
> >   normal program 'libc-test' has no permission to access '/proc/1/exe'
> 
> Strictly speaking, if your executable is not readable (e.g. chmod 111
> due to a restrictive umask) it will also fail that one.
>

ok.

> > - the others, for kernel without procfs
> >   let it pass even with 'worst case' kernel configs
> 
> You should include /dev/zero, which is commonly used to allocate anonymous
> memory and is more likely present and readable than any of the other files.
> And another file of choice is obviously argv[0] ;-)  In this case you don't
> need any of the other extra ones. Thus I could suggest that you try in this
> order:
> 
>     /dev/zero, /proc/self/exe, /proc/1/exe, argv[0]
> 
> and be done with it. That doesn't prevent one from extending the list if
> really needed later, but I doubt it would be needed. Also, it's already
> arranged in a read-write, then read-only fallbacks mode, so if we later
> need to add more complex tests involving writes, the writable /dev/zero
> will have precedence.
>

Cool, both /dev/zero and argv[0] are very good candidates ;-)

Just verified both of them, works perfectly.

- /dev/zero

  we need to mknod it in prepare() and also, in test_mmap_munmap(),
  stat() return a zero size of /dev/zero, in this case, we should assign
  a non-zero file_size ourselves.

    -       file_size = stat_buf.st_size;
    +       /* file size of the special /dev/zero is 0, let's assign one manually */
    +       if (i == 0)
    +               file_size = 3*page_size - 1;
    +       else
    +               file_size = stat_buf.st_size;


- argv[0]

  since nolibc has no realpath() currently, we can simply
  support the current path and the absolute path like this:

    nolibc-test.c:

    /* assigned as argv[0] in main(), will be used by some tests */
    static char exe[PATH_MAX + 1];

    main():

    /* get absolute path of myself, nolibc has no realpath() currently */
    #ifndef NOLIBC
            realpath(argv[0], exe);
    #else
            /* assume absolute path has no "./" */
            if (strncmp(argv[0], "./", 2) != 0)
                    strncat(exe, argv[0], strlen(argv[0]) + 1);
            else {
                    pwd = getenv("PWD");
                    /* skip the ending '\0' */
                    strncat(exe, getenv("PWD"), strlen(pwd));
                    /* skip the first '.' */
                    strncat(exe, argv[0] + 1, strlen(argv[0]));
            }
    #endif

A full functional realpath() is a little complex, such as '../' support and
even symlink support, let's delay its requirement at current stage ;-)

one or both of them may also help the other test cases:

- chroot_exe (used '/init' before)

    CASE_TEST(chroot_exe);        EXPECT_SYSER(1, chroot(proc ? "/proc/self/exe" : exe), -1, ENOTDIR); break;

- chmod_exe (replace the one: chmod_tmpdir in another patchset)

    CASE_TEST(chmod_exe);       EXPECT_SYSZR(1, chmod(proc ? "/proc/self/exe" : exe, 0555)); break;

    It should be safe enough to only remove the writable attribute for the test
    program.

- stat_timestamps (used '/init' before)

    if (stat("/proc/self/", &st) && stat(exe, &st) && stat("/dev/zero", &st) && stat("/", &st))

Will update the related patches with them.

Thanks,
Zhangjin

> Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 11/14] tools/nolibc: clean up mmap() support
  2023-07-02 19:23     ` Willy Tarreau
@ 2023-07-03  6:51       ` Zhangjin Wu
  0 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-07-03  6:51 UTC (permalink / raw)
  To: w
  Cc: arnd, david.laight, falcon, linux-kernel, linux-kselftest,
	linux-riscv, thomas

> On Wed, Jun 28, 2023 at 09:41:13PM +0800, Zhangjin Wu wrote:
> >  static __attribute__((unused))
> >  void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
> >  {
> > -	void *ret = sys_mmap(addr, length, prot, flags, fd, offset);
> > -
> > -	if ((unsigned long)ret >= -4095UL) {
> > -		SET_ERRNO(-(long)ret);
> > -		ret = MAP_FAILED;
> > -	}
> > -	return ret;
> > +	return (void *)__sysret((unsigned long)sys_mmap(addr, length, prot, flags, fd, offset));
> >  }
> 
> One point regarding this one. By doing so, we're hard-coding the fact
> that we consider that MAP_FAILED is always -1. I'm not necessarily
> against it, but this implication can be confusing for those searching
> where it's being set. I would suggest putting a comment before the
> mmap() function saying:
> 
>  /* Note that on Linux MAP_FAILED is -1 so we can use the generic __sysret()
>   * which returns -1 upon error and still satisfy user land that checks for
>   * MAP_FAILED.
>   */
> 
> Since it's an assumed choice that theoretically could affect portability,
> it should be reflected in the commit message as well (and we all know it
> does not have any impact).
>

Yeah, we do need such a comment and commit message note, thanks.

Best regards,
Zhangjin

> Thanks!
> Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 14/14] selftests/nolibc: add mmap and munmap test cases
  2023-07-03  6:03       ` Zhangjin Wu
@ 2023-07-03  7:25         ` Willy Tarreau
  2023-07-03  8:06           ` Zhangjin Wu
  0 siblings, 1 reply; 54+ messages in thread
From: Willy Tarreau @ 2023-07-03  7:25 UTC (permalink / raw)
  To: Zhangjin Wu
  Cc: arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv,
	linux, thomas

On Mon, Jul 03, 2023 at 02:03:23PM +0800, Zhangjin Wu wrote:
> > > - the others, for kernel without procfs
> > >   let it pass even with 'worst case' kernel configs
> > 
> > You should include /dev/zero, which is commonly used to allocate anonymous
> > memory and is more likely present and readable than any of the other files.
> > And another file of choice is obviously argv[0] ;-)  In this case you don't
> > need any of the other extra ones. Thus I could suggest that you try in this
> > order:
> > 
> >     /dev/zero, /proc/self/exe, /proc/1/exe, argv[0]
> > 
> > and be done with it. That doesn't prevent one from extending the list if
> > really needed later, but I doubt it would be needed. Also, it's already
> > arranged in a read-write, then read-only fallbacks mode, so if we later
> > need to add more complex tests involving writes, the writable /dev/zero
> > will have precedence.
> >
> 
> Cool, both /dev/zero and argv[0] are very good candidates ;-)
> 
> Just verified both of them, works perfectly.
> 
> - /dev/zero
> 
>   we need to mknod it in prepare()

Indeed.

>   and also, in test_mmap_munmap(),
>   stat() return a zero size of /dev/zero, in this case, we should assign
>   a non-zero file_size ourselves.
> 
>     -       file_size = stat_buf.st_size;
>     +       /* file size of the special /dev/zero is 0, let's assign one manually */
>     +       if (i == 0)
>     +               file_size = 3*page_size - 1;
>     +       else
>     +               file_size = stat_buf.st_size;

OK but why this -1 ? That doesn't sound right, unless you explicitly want
a file size that's not multiple of a page size for whatever reason ?

> - argv[0]
> 
>   since nolibc has no realpath() currently, we can simply
>   support the current path and the absolute path like this:
> 
>     nolibc-test.c:
> 
>     /* assigned as argv[0] in main(), will be used by some tests */
>     static char exe[PATH_MAX + 1];
> 
>     main():
> 
>     /* get absolute path of myself, nolibc has no realpath() currently */
>     #ifndef NOLIBC
>             realpath(argv[0], exe);
>     #else
>             /* assume absolute path has no "./" */
>             if (strncmp(argv[0], "./", 2) != 0)
>                     strncat(exe, argv[0], strlen(argv[0]) + 1);
>             else {
>                     pwd = getenv("PWD");
>                     /* skip the ending '\0' */
>                     strncat(exe, getenv("PWD"), strlen(pwd));
>                     /* skip the first '.' */
>                     strncat(exe, argv[0] + 1, strlen(argv[0]));
>             }
>     #endif

No, please, not like this. Just copy argv[0] (the pointer not the
contents) and you're fine:

    static const char *argv0;

    int main(int argc, char **argv, char **envp)
    {
            argv0 = argv[0];
            ...
    }

Nothing more, nothing less. Your program will always have its correct
path when being called unless someone purposely forces it to something
different, which is not our concern at all since this is a test program.
And I'd rather call it "argv0" which exactly tells us what it contains
than "exe" which can be misleading for that precise reason.

> A full functional realpath() is a little complex, such as '../' support and
> even symlink support, let's delay its requirement at current stage ;-)

Please do not even engage into this, and keep in mind that the sole
purpose of this test program is to help developers simply add tests to
the set of existing ones. If the program becomes complex for doing stuff
that is out of its scope, it will become much harder to extend and users
will lose interest and motivation for updating it.

> one or both of them may also help the other test cases:
> 
> - chroot_exe (used '/init' before)
> 
>     CASE_TEST(chroot_exe);        EXPECT_SYSER(1, chroot(proc ? "/proc/self/exe" : exe), -1, ENOTDIR); break;
> 
> - chmod_exe (replace the one: chmod_tmpdir in another patchset)
> 
>     CASE_TEST(chmod_exe);       EXPECT_SYSZR(1, chmod(proc ? "/proc/self/exe" : exe, 0555)); break;
> 
>     It should be safe enough to only remove the writable attribute for the test
>     program.
> 
> - stat_timestamps (used '/init' before)
> 
>     if (stat("/proc/self/", &st) && stat(exe, &st) && stat("/dev/zero", &st) && stat("/", &st))

Indeed, why not!

> Will update the related patches with them.

OK thanks!
Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 14/14] selftests/nolibc: add mmap and munmap test cases
  2023-07-03  7:25         ` Willy Tarreau
@ 2023-07-03  8:06           ` Zhangjin Wu
  2023-07-03  8:20             ` Thomas Weißschuh
  2023-07-03  9:56             ` Willy Tarreau
  0 siblings, 2 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-07-03  8:06 UTC (permalink / raw)
  To: w
  Cc: arnd, david.laight, falcon, linux-kernel, linux-kselftest,
	linux-riscv, linux, thomas

Hi, Willy

> On Mon, Jul 03, 2023 at 02:03:23PM +0800, Zhangjin Wu wrote:
> > > > - the others, for kernel without procfs
> > > >   let it pass even with 'worst case' kernel configs
> > > 
> > > You should include /dev/zero, which is commonly used to allocate anonymous
> > > memory and is more likely present and readable than any of the other files.
> > > And another file of choice is obviously argv[0] ;-)  In this case you don't
> > > need any of the other extra ones. Thus I could suggest that you try in this
> > > order:
> > > 
> > >     /dev/zero, /proc/self/exe, /proc/1/exe, argv[0]
> > > 
> > > and be done with it. That doesn't prevent one from extending the list if
> > > really needed later, but I doubt it would be needed. Also, it's already
> > > arranged in a read-write, then read-only fallbacks mode, so if we later
> > > need to add more complex tests involving writes, the writable /dev/zero
> > > will have precedence.
> > >
> > 
> > Cool, both /dev/zero and argv[0] are very good candidates ;-)
> > 
> > Just verified both of them, works perfectly.
> > 
> > - /dev/zero
> > 
> >   we need to mknod it in prepare()
> 
> Indeed.
> 
> >   and also, in test_mmap_munmap(),
> >   stat() return a zero size of /dev/zero, in this case, we should assign
> >   a non-zero file_size ourselves.
> > 
> >     -       file_size = stat_buf.st_size;
> >     +       /* file size of the special /dev/zero is 0, let's assign one manually */
> >     +       if (i == 0)
> >     +               file_size = 3*page_size - 1;
> >     +       else
> >     +               file_size = stat_buf.st_size;
> 
> OK but why this -1 ? That doesn't sound right, unless you explicitly want
> a file size that's not multiple of a page size for whatever reason ?
>

Just make sure the file size is a litle random, not just aligned with
PAGE_SIZE, it is ok without '-1' ;-)

> > - argv[0]
> > 
> >   since nolibc has no realpath() currently, we can simply
> >   support the current path and the absolute path like this:
> > 
> >     nolibc-test.c:
> > 
> >     /* assigned as argv[0] in main(), will be used by some tests */
> >     static char exe[PATH_MAX + 1];
> > 
> >     main():
> > 
> >     /* get absolute path of myself, nolibc has no realpath() currently */
> >     #ifndef NOLIBC
> >             realpath(argv[0], exe);
> >     #else
> >             /* assume absolute path has no "./" */
> >             if (strncmp(argv[0], "./", 2) != 0)
> >                     strncat(exe, argv[0], strlen(argv[0]) + 1);
> >             else {
> >                     pwd = getenv("PWD");
> >                     /* skip the ending '\0' */
> >                     strncat(exe, getenv("PWD"), strlen(pwd));
> >                     /* skip the first '.' */
> >                     strncat(exe, argv[0] + 1, strlen(argv[0]));
> >             }
> >     #endif
> 
> No, please, not like this. Just copy argv[0] (the pointer not the
> contents) and you're fine:
>
>     static const char *argv0;
> 
>     int main(int argc, char **argv, char **envp)
>     {
>             argv0 = argv[0];
>             ...
>     }
> 
> Nothing more, nothing less. Your program will always have its correct
> path when being called unless someone purposely forces it to something
> different, which is not our concern at all since this is a test program.
> And I'd rather call it "argv0" which exactly tells us what it contains
> than "exe" which can be misleading for that precise reason.
>

Yeah, locally, I just used a global argv0 pointer directly, but
chroot_exe("./nolibc-test") not work when run 'libc-test' in host
system, that is why I tried to get an absolute path ;-)

    CASE_TEST(chroot_exe);        EXPECT_SYSER(1, chroot(exe), -1, ENOTDIR); break;

    -->

    19 chroot_exe = -1 ENOENT  != (-1 ENOTDIR)                      [FAIL]

I removed the "proc ?" check manually to test if it also work with
CONFIG_PROC_FS=n. it doesn't work, without absolute path, we need to add
the ENOENT errno back to the errno check list.

I'm not sure if the other syscalls require an absolute path, so, the
realpath() is called in this proposed method.

> > A full functional realpath() is a little complex, such as '../' support and
> > even symlink support, let's delay its requirement at current stage ;-)
> 
> Please do not even engage into this, and keep in mind that the sole
> purpose of this test program is to help developers simply add tests to
> the set of existing ones. If the program becomes complex for doing stuff
> that is out of its scope, it will become much harder to extend and users
> will lose interest and motivation for updating it.
> 
> > one or both of them may also help the other test cases:
> > 
> > - chroot_exe (used '/init' before)
> > 
> >     CASE_TEST(chroot_exe);        EXPECT_SYSER(1, chroot(proc ? "/proc/self/exe" : exe), -1, ENOTDIR); break;
> > 
> > - chmod_exe (replace the one: chmod_tmpdir in another patchset)
> > 
> >     CASE_TEST(chmod_exe);       EXPECT_SYSZR(1, chmod(proc ? "/proc/self/exe" : exe, 0555)); break;
> > 
> >     It should be safe enough to only remove the writable attribute for the test
> >     program.
> > 
> > - stat_timestamps (used '/init' before)
> > 
> >     if (stat("/proc/self/", &st) && stat(exe, &st) && stat("/dev/zero", &st) && stat("/", &st))
> 
> Indeed, why not!
>

Ok, without absolute path, the chroot_exe() will be changed back to
something like this:

    CASE_TEST(chroot_exe);        EXPECT_SYSER2(1, chroot(proc ? "/proc/self/exe" : argv0), -1, ENOTDIR, ENOENT); break;

Best regards,
Zhangjin

> > Will update the related patches with them.
> 
> OK thanks!
> Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 14/14] selftests/nolibc: add mmap and munmap test cases
  2023-07-03  8:06           ` Zhangjin Wu
@ 2023-07-03  8:20             ` Thomas Weißschuh
  2023-07-03  9:15               ` Zhangjin Wu
  2023-07-03  9:56             ` Willy Tarreau
  1 sibling, 1 reply; 54+ messages in thread
From: Thomas Weißschuh @ 2023-07-03  8:20 UTC (permalink / raw)
  To: Zhangjin Wu
  Cc: w, arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv

On 2023-07-03 16:06:47+0800, Zhangjin Wu wrote:
> Hi, Willy

> [..]

> > > - argv[0]
> > > 
> > >   since nolibc has no realpath() currently, we can simply
> > >   support the current path and the absolute path like this:
> > > 
> > >     nolibc-test.c:
> > > 
> > >     /* assigned as argv[0] in main(), will be used by some tests */
> > >     static char exe[PATH_MAX + 1];
> > > 
> > >     main():
> > > 
> > >     /* get absolute path of myself, nolibc has no realpath() currently */
> > >     #ifndef NOLIBC
> > >             realpath(argv[0], exe);
> > >     #else
> > >             /* assume absolute path has no "./" */
> > >             if (strncmp(argv[0], "./", 2) != 0)
> > >                     strncat(exe, argv[0], strlen(argv[0]) + 1);
> > >             else {
> > >                     pwd = getenv("PWD");
> > >                     /* skip the ending '\0' */
> > >                     strncat(exe, getenv("PWD"), strlen(pwd));
> > >                     /* skip the first '.' */
> > >                     strncat(exe, argv[0] + 1, strlen(argv[0]));
> > >             }
> > >     #endif
> > 
> > No, please, not like this. Just copy argv[0] (the pointer not the
> > contents) and you're fine:
> >
> >     static const char *argv0;
> > 
> >     int main(int argc, char **argv, char **envp)
> >     {
> >             argv0 = argv[0];
> >             ...
> >     }
> > 
> > Nothing more, nothing less. Your program will always have its correct
> > path when being called unless someone purposely forces it to something
> > different, which is not our concern at all since this is a test program.
> > And I'd rather call it "argv0" which exactly tells us what it contains
> > than "exe" which can be misleading for that precise reason.
> >
> 
> Yeah, locally, I just used a global argv0 pointer directly, but
> chroot_exe("./nolibc-test") not work when run 'libc-test' in host
> system, that is why I tried to get an absolute path ;-)
> 
>     CASE_TEST(chroot_exe);        EXPECT_SYSER(1, chroot(exe), -1, ENOTDIR); break;
> 
>     -->
> 
>     19 chroot_exe = -1 ENOENT  != (-1 ENOTDIR)                      [FAIL]
> 
> I removed the "proc ?" check manually to test if it also work with
> CONFIG_PROC_FS=n. it doesn't work, without absolute path, we need to add
> the ENOENT errno back to the errno check list.
> 
> I'm not sure if the other syscalls require an absolute path, so, the
> realpath() is called in this proposed method.
> 
> > > A full functional realpath() is a little complex, such as '../' support and
> > > even symlink support, let's delay its requirement at current stage ;-)
> > 
> > Please do not even engage into this, and keep in mind that the sole
> > purpose of this test program is to help developers simply add tests to
> > the set of existing ones. If the program becomes complex for doing stuff
> > that is out of its scope, it will become much harder to extend and users
> > will lose interest and motivation for updating it.
> > 
> > > one or both of them may also help the other test cases:
> > > 
> > > - chroot_exe (used '/init' before)
> > > 
> > >     CASE_TEST(chroot_exe);        EXPECT_SYSER(1, chroot(proc ? "/proc/self/exe" : exe), -1, ENOTDIR); break;
> > > 
> > > - chmod_exe (replace the one: chmod_tmpdir in another patchset)
> > > 
> > >     CASE_TEST(chmod_exe);       EXPECT_SYSZR(1, chmod(proc ? "/proc/self/exe" : exe, 0555)); break;
> > > 
> > >     It should be safe enough to only remove the writable attribute for the test
> > >     program.
> > > 
> > > - stat_timestamps (used '/init' before)
> > > 
> > >     if (stat("/proc/self/", &st) && stat(exe, &st) && stat("/dev/zero", &st) && stat("/", &st))
> > 
> > Indeed, why not!
> >
> 
> Ok, without absolute path, the chroot_exe() will be changed back to
> something like this:
> 
>     CASE_TEST(chroot_exe);        EXPECT_SYSER2(1, chroot(proc ? "/proc/self/exe" : argv0), -1, ENOTDIR, ENOENT); break;

Are you sure the ENOENT is really correct?
I played with this before and got ENOENT because before the chroot test
we have a testcase that does chdir("/").
And therefore the relative name in argv[0] was not resolving correctly
anymore against the changed working directory.

(You can also test this by executing *only* the chroot test and it
should work)

In general chroot() should work just fine with relative paths.

This is really a lot of complexity and discussion only to avoid
depending on procfs for the tests.

Thomas

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 10/14] tools/nolibc: __sysret: support syscalls who return a pointer
  2023-07-02 19:17     ` Willy Tarreau
@ 2023-07-03  8:36       ` Zhangjin Wu
  2023-07-03 10:03         ` Willy Tarreau
  0 siblings, 1 reply; 54+ messages in thread
From: Zhangjin Wu @ 2023-07-03  8:36 UTC (permalink / raw)
  To: w, arnd, david.laight, thomas
  Cc: falcon, linux-kernel, linux-kselftest, linux-riscv

Hi, Willy

> On Wed, Jun 28, 2023 at 09:39:56PM +0800, Zhangjin Wu wrote:
> > To support syscalls (e.g. mmap()) who return a pointer and to allow the
> > pointer as big as possible, we should convert the negated errno value to
> > unsigned long (uintptr_t), otherwise, in signed long, a potential big
> > pointer (whose highest bit is 1) will be treated as a failure.
> > 
> > tools/include/nolibc/errno.h defines the MAX_ERRNO, let's use it
> > directly.
> 
> It might or might not work, it's an ABI change that, if validated, at
> least needs a much more detailed explanation. What matters is not what
> errno values we're willing to consider as an error, but what the
> *syscalls* themselves return as an error. If a syscall says "< 0 is an
> error equal to -errno", it means that we must treat it as an error,
> and extract its value to get errno. If that errno is larger than
> MAX_ERRNO it just means we don't know what the error is.
>

Yes, we do need to find a 'spec' or 'standard' to follow.

welcome suggestions from Arnd, Thomas and also David.

> Syscalls that return pointer use that -MAX_ERRNO range to encode errors
> (such as mmap()). I just do not know if there is a convention saying that
> other ones also restrict themselves to that range or not. If you find
> some info which guarantees that it's the case for all of them, then by
> all means let's proceed like this, but in this case it should be mentioned
> in the comment why we think it's valid to do this. For now it's presented
> as an opportunity only.

Currently, I only found a prove-in-use case in musl:

    https://elixir.bootlin.com/musl/latest/source/src/internal/syscall_ret.c:

    #include <errno.h>
    #include "syscall.h"

    long __syscall_ret(unsigned long r)
    {
    	if (r > -4096UL) {
    		errno = -r;
    		return -1;
    	}
    	return r;
    }

Our new implementation (based on the one used by mmap()) is almostly the same
as musl. Not sure if this is enough. I have tried to 'git blame' on
__syscall_ret() of musl to find some clue, but failed, because the function has
been added before importing into its git repo.

> 
> Also, the rest of the commit message regarding uintptr_t (which we don't
> use), bit values and modular arithmetics is extremely confusing and not
> needed at all. What matters is only to know if we need to consider only
> values -MAX_ERRNO..-1 as error or all negative ones. If so, then it's
> obvious that ret >= (unsigned long)-MAX_ERRNO catches them all, as the
> current mmap() function already does with -4095UL.
>

Yes, will clean up the commit message, but at first, let's continue get
more information about which one is ok:

- -MAX_ERRNO..-1 as error, for sys_mmap (we know in nolibc) currently

- all negative ones, for others currently

> I just don't know where to check if we can generalize that test. In the
> worst case we could have two __sys_ret(), the current one and a second
> one for pointers. But I would suspect we could generalize due to ptrace,
> as there it makes sense to be able to detect failures, even unknown ones.
> I just need something more convincing than an intuition for a commit
> message and to take such a change :-/
>

Of course, must be clear enough.

Best regards,
Zhangjin

> Thanks!
> Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 14/14] selftests/nolibc: add mmap and munmap test cases
  2023-07-03  8:20             ` Thomas Weißschuh
@ 2023-07-03  9:15               ` Zhangjin Wu
  0 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-07-03  9:15 UTC (permalink / raw)
  To: thomas
  Cc: arnd, david.laight, falcon, linux-kernel, linux-kselftest,
	linux-riscv, w

Hi, Thomas

> On 2023-07-03 16:06:47+0800, Zhangjin Wu wrote:
> > Hi, Willy
> 
> > [..]
> 
> > > > - argv[0]
> > > > 
> > > >   since nolibc has no realpath() currently, we can simply
> > > >   support the current path and the absolute path like this:
> > > > 
> > > >     nolibc-test.c:
> > > > 
> > > >     /* assigned as argv[0] in main(), will be used by some tests */
> > > >     static char exe[PATH_MAX + 1];
> > > > 
> > > >     main():
> > > > 
> > > >     /* get absolute path of myself, nolibc has no realpath() currently */
> > > >     #ifndef NOLIBC
> > > >             realpath(argv[0], exe);
> > > >     #else
> > > >             /* assume absolute path has no "./" */
> > > >             if (strncmp(argv[0], "./", 2) != 0)
> > > >                     strncat(exe, argv[0], strlen(argv[0]) + 1);
> > > >             else {
> > > >                     pwd = getenv("PWD");
> > > >                     /* skip the ending '\0' */
> > > >                     strncat(exe, getenv("PWD"), strlen(pwd));
> > > >                     /* skip the first '.' */
> > > >                     strncat(exe, argv[0] + 1, strlen(argv[0]));
> > > >             }
> > > >     #endif
> > > 
> > > No, please, not like this. Just copy argv[0] (the pointer not the
> > > contents) and you're fine:
> > >
> > >     static const char *argv0;
> > > 
> > >     int main(int argc, char **argv, char **envp)
> > >     {
> > >             argv0 = argv[0];
> > >             ...
> > >     }
> > > 
> > > Nothing more, nothing less. Your program will always have its correct
> > > path when being called unless someone purposely forces it to something
> > > different, which is not our concern at all since this is a test program.
> > > And I'd rather call it "argv0" which exactly tells us what it contains
> > > than "exe" which can be misleading for that precise reason.
> > >
> > 
> > Yeah, locally, I just used a global argv0 pointer directly, but
> > chroot_exe("./nolibc-test") not work when run 'libc-test' in host
> > system, that is why I tried to get an absolute path ;-)
> > 
> >     CASE_TEST(chroot_exe);        EXPECT_SYSER(1, chroot(exe), -1, ENOTDIR); break;
> > 
> >     -->
> > 
> >     19 chroot_exe = -1 ENOENT  != (-1 ENOTDIR)                      [FAIL]
> > 
> > I removed the "proc ?" check manually to test if it also work with
> > CONFIG_PROC_FS=n. it doesn't work, without absolute path, we need to add
> > the ENOENT errno back to the errno check list.
> > 
> > I'm not sure if the other syscalls require an absolute path, so, the
> > realpath() is called in this proposed method.
> > 
> > > > A full functional realpath() is a little complex, such as '../' support and
> > > > even symlink support, let's delay its requirement at current stage ;-)
> > > 
> > > Please do not even engage into this, and keep in mind that the sole
> > > purpose of this test program is to help developers simply add tests to
> > > the set of existing ones. If the program becomes complex for doing stuff
> > > that is out of its scope, it will become much harder to extend and users
> > > will lose interest and motivation for updating it.
> > > 
> > > > one or both of them may also help the other test cases:
> > > > 
> > > > - chroot_exe (used '/init' before)
> > > > 
> > > >     CASE_TEST(chroot_exe);        EXPECT_SYSER(1, chroot(proc ? "/proc/self/exe" : exe), -1, ENOTDIR); break;
> > > > 
> > > > - chmod_exe (replace the one: chmod_tmpdir in another patchset)
> > > > 
> > > >     CASE_TEST(chmod_exe);       EXPECT_SYSZR(1, chmod(proc ? "/proc/self/exe" : exe, 0555)); break;
> > > > 
> > > >     It should be safe enough to only remove the writable attribute for the test
> > > >     program.
> > > > 
> > > > - stat_timestamps (used '/init' before)
> > > > 
> > > >     if (stat("/proc/self/", &st) && stat(exe, &st) && stat("/dev/zero", &st) && stat("/", &st))
> > > 
> > > Indeed, why not!
> > >
> > 
> > Ok, without absolute path, the chroot_exe() will be changed back to
> > something like this:
> > 
> >     CASE_TEST(chroot_exe);        EXPECT_SYSER2(1, chroot(proc ? "/proc/self/exe" : argv0), -1, ENOTDIR, ENOENT); break;
> 
> Are you sure the ENOENT is really correct?
> I played with this before and got ENOENT because before the chroot test
> we have a testcase that does chdir("/").

Yes, there are some chdir tests before chroot, it does answer why
relative path not work and return ENOENT: no such file in the relative
path changed by chdir(), it differs from the one in PWD environment
variable.

> And therefore the relative name in argv[0] was not resolving correctly
> anymore against the changed working directory.
>
> (You can also test this by executing *only* the chroot test and it
> should work)
>

Yeah, If chdir() back to current path, it does work:

    CASE_TEST(chroot_exe);        chdir(getenv("PWD")); EXPECT_SYSER(1, chroot(exe), -1, ENOTDIR); break;

    -->

    11 chdir_root = 0                                                [OK]
    12 chdir_dot = 0                                                 [OK]
    13 chdir_blah = -1 ENOENT                                        [OK]
    14 chmod_self = -1 EPERM                                         [OK]
    15 chmod_exe = 0                                                 [OK]
    16 chown_self = -1 EPERM                                         [OK]
    17 chroot_root                                                  [SKIPPED]
    18 chroot_blah = -1 ENOENT                                       [OK]
    19 chroot_exe
    pwd: /home/ubuntu/Develop/src/examples/musl
    exe: ./nolibc-test
     = -1 ENOTDIR                                       [OK]


> In general chroot() should work just fine with relative paths.
>

it does work with relative path, to make sure argv0 always work as
expected, an extra 'chdir()' may really required, or let's clean up the
previous chdir() test cases to call chdir(getenv("PWD")) after every
test.

    CASE_TEST(chdir_root);        EXPECT_SYSZR(1, chdir("/")); break;
    CASE_TEST(chdir_dot);         EXPECT_SYSZR(1, chdir(".")); break;
    CASE_TEST(chdir_blah);        EXPECT_SYSER(1, chdir("/blah"), -1, ENOENT); break;

perhaps only call 'chdir(getenv("PWD"))' after chdir_root() is enough,
because the chdir(".") doesn't really change the directory:

    CASE_TEST(chdir_root);        EXPECT_SYSZR(1, chdir("/")); chdir(getenv("PWD")); break;
    CASE_TEST(chdir_dot);         EXPECT_SYSZR(1, chdir(".")); break;
    CASE_TEST(chdir_blah);        EXPECT_SYSER(1, chdir("/blah"), -1, ENOENT); break;

Which one do you prefer?

> This is really a lot of complexity and discussion only to avoid
> depending on procfs for the tests.
>

Yes, one step further to find more interesting info, thanks a lot ;-)

Mixing chdir and relative path really need to be more careful.

Best regards,
Zhangjin

> Thomas

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 14/14] selftests/nolibc: add mmap and munmap test cases
  2023-07-03  8:06           ` Zhangjin Wu
  2023-07-03  8:20             ` Thomas Weißschuh
@ 2023-07-03  9:56             ` Willy Tarreau
  2023-07-03 11:24               ` Zhangjin Wu
  1 sibling, 1 reply; 54+ messages in thread
From: Willy Tarreau @ 2023-07-03  9:56 UTC (permalink / raw)
  To: Zhangjin Wu
  Cc: arnd, david.laight, linux-kernel, linux-kselftest, linux-riscv,
	linux, thomas

On Mon, Jul 03, 2023 at 04:06:47PM +0800, Zhangjin Wu wrote:
> > >     /* get absolute path of myself, nolibc has no realpath() currently */
> > >     #ifndef NOLIBC
> > >             realpath(argv[0], exe);
> > >     #else
> > >             /* assume absolute path has no "./" */
> > >             if (strncmp(argv[0], "./", 2) != 0)
> > >                     strncat(exe, argv[0], strlen(argv[0]) + 1);
> > >             else {
> > >                     pwd = getenv("PWD");
> > >                     /* skip the ending '\0' */
> > >                     strncat(exe, getenv("PWD"), strlen(pwd));
> > >                     /* skip the first '.' */
> > >                     strncat(exe, argv[0] + 1, strlen(argv[0]));
> > >             }
> > >     #endif
> > 
> > No, please, not like this. Just copy argv[0] (the pointer not the
> > contents) and you're fine:
> >
> >     static const char *argv0;
> > 
> >     int main(int argc, char **argv, char **envp)
> >     {
> >             argv0 = argv[0];
> >             ...
> >     }
> > 
> > Nothing more, nothing less. Your program will always have its correct
> > path when being called unless someone purposely forces it to something
> > different, which is not our concern at all since this is a test program.
> > And I'd rather call it "argv0" which exactly tells us what it contains
> > than "exe" which can be misleading for that precise reason.
> >
> 
> Yeah, locally, I just used a global argv0 pointer directly, but
> chroot_exe("./nolibc-test") not work when run 'libc-test' in host
> system, that is why I tried to get an absolute path ;-)
> 
>     CASE_TEST(chroot_exe);        EXPECT_SYSER(1, chroot(exe), -1, ENOTDIR); break;
> 
>     -->
> 
>     19 chroot_exe = -1 ENOENT  != (-1 ENOTDIR)                      [FAIL]

Then we have a problem somewhere else and the test should be debugger
instead. Are you sure there isn't a successful chdir() test before it
for example, that would change the directory ? If so maybe we just need
to save the current dir before calling it and restore it later.

> I removed the "proc ?" check manually to test if it also work with
> CONFIG_PROC_FS=n. it doesn't work, without absolute path, we need to add
> the ENOENT errno back to the errno check list.

Same as above.

> I'm not sure if the other syscalls require an absolute path, so, the
> realpath() is called in this proposed method.

No, please do not overengineer tests. That's only hiding the dust under
the carpet and people adding more tests later that will randomly fail
will have a very hard time trying to figure what's happening under the
hood. If a test doesn't work as expected, we must not try to work around
it, but arrange to fix it.

Thanks,
Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 10/14] tools/nolibc: __sysret: support syscalls who return a pointer
  2023-07-03  8:36       ` Zhangjin Wu
@ 2023-07-03 10:03         ` Willy Tarreau
  2023-07-03 11:15           ` Zhangjin Wu
  0 siblings, 1 reply; 54+ messages in thread
From: Willy Tarreau @ 2023-07-03 10:03 UTC (permalink / raw)
  To: Zhangjin Wu
  Cc: arnd, david.laight, thomas, linux-kernel, linux-kselftest, linux-riscv

On Mon, Jul 03, 2023 at 04:36:51PM +0800, Zhangjin Wu wrote:
> > Syscalls that return pointer use that -MAX_ERRNO range to encode errors
> > (such as mmap()). I just do not know if there is a convention saying that
> > other ones also restrict themselves to that range or not. If you find
> > some info which guarantees that it's the case for all of them, then by
> > all means let's proceed like this, but in this case it should be mentioned
> > in the comment why we think it's valid to do this. For now it's presented
> > as an opportunity only.
> 
> Currently, I only found a prove-in-use case in musl:
> 
>     https://elixir.bootlin.com/musl/latest/source/src/internal/syscall_ret.c:
> 
>     #include <errno.h>
>     #include "syscall.h"
> 
>     long __syscall_ret(unsigned long r)
>     {
>     	if (r > -4096UL) {
>     		errno = -r;
>     		return -1;
>     	}
>     	return r;
>     }
> 
> Our new implementation (based on the one used by mmap()) is almostly the same
> as musl. Not sure if this is enough. I have tried to 'git blame' on
> __syscall_ret() of musl to find some clue, but failed, because the function has
> been added before importing into its git repo.

OK, we already used the glibc-saved registers in the past to determine
the official list of clobbered registers (and the ABI spec was even
updated based on this). Here, musl is sufficiently deployed to consider
this as valid. You can simply go that route and mention in the commit
message that while you found no official reference stating that this is
valid for int/long returns, you found at least one other implementation
relying on this (i.e. if the kernel ever changes it will cause breakage).

> > Also, the rest of the commit message regarding uintptr_t (which we don't
> > use), bit values and modular arithmetics is extremely confusing and not
> > needed at all. What matters is only to know if we need to consider only
> > values -MAX_ERRNO..-1 as error or all negative ones. If so, then it's
> > obvious that ret >= (unsigned long)-MAX_ERRNO catches them all, as the
> > current mmap() function already does with -4095UL.
> >
> 
> Yes, will clean up the commit message, but at first, let's continue get
> more information about which one is ok:
> 
> - -MAX_ERRNO..-1 as error, for sys_mmap (we know in nolibc) currently
> 
> - all negative ones, for others currently

You can double-check in glibc for example, but I'm starting to guess
you'll find the same test as above, i.e. errors are exclusively >-4096,
regardless of the expected return type.

Thanks!
Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 09/14] tools/nolibc: add missing my_syscall6() for mips
  2023-07-02 18:55     ` Willy Tarreau
@ 2023-07-03 10:13       ` Zhangjin Wu
  0 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-07-03 10:13 UTC (permalink / raw)
  To: w
  Cc: arnd, david.laight, falcon, linux-kernel, linux-kselftest,
	linux-riscv, thomas

Hi, Willy

> Hi Zhangjin,
> 
> On Wed, Jun 28, 2023 at 09:37:29PM +0800, Zhangjin Wu wrote:
> > It is able to pass the 6th argument like the 5th argument via the stack
> > for mips, let's add a new my_syscall6() now, see [1] for details:
> > 
> >   The mips/o32 system call convention passes arguments 5 through 8 on
> >   the user stack.
> > 
> > Both mmap() and pselect6() require my_syscall6().
> 
> Very interesting, I didn't manage to make it work previously. Did you
> test it to confirm that it works ? I guess so but since you didn't
> mention, I preferred to ask.
>

Yes, I'm curious too ;-) 

we did add the mmap test cases and run it for mips, as Thomas
suggested, we pass a none-zero pa_offset to mmap() to make sure the 6th
argument is used.

I just re-tested it for mips and printed something like this:

    44 mmap_bad = <0xffffffff> EINVAL                                [OK]
    45 munmap_bad = -1 EINVAL                                        [OK]
    46 mmap_munmap_good
    pa_offset: 8192
    length: 1
    file_size: 12287
     = 0                                          [OK]
    47 open_tty = 3                                                  [OK]
    48 open_blah = -1 ENOENT                                         [OK]

And I also checked the mips support of musl, it evan provide a
__syscall7, so, it should be ok ;-)

The only difference is, musl provide a different clobber list for
'__mips_isa_rev >= 6', I didn't look into the details yet:
https://elixir.bootlin.com/musl/latest/source/arch/mips/syscall_arch.h

Best regards,
Zhangjin

> Thanks!
> Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 10/14] tools/nolibc: __sysret: support syscalls who return a pointer
  2023-07-03 10:03         ` Willy Tarreau
@ 2023-07-03 11:15           ` Zhangjin Wu
  0 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-07-03 11:15 UTC (permalink / raw)
  To: w
  Cc: arnd, david.laight, falcon, linux-kernel, linux-kselftest,
	linux-riscv, thomas

Hi, Willy

> On Mon, Jul 03, 2023 at 04:36:51PM +0800, Zhangjin Wu wrote:
> > > Syscalls that return pointer use that -MAX_ERRNO range to encode errors
> > > (such as mmap()). I just do not know if there is a convention saying that
> > > other ones also restrict themselves to that range or not. If you find
> > > some info which guarantees that it's the case for all of them, then by
> > > all means let's proceed like this, but in this case it should be mentioned
> > > in the comment why we think it's valid to do this. For now it's presented
> > > as an opportunity only.
> > 
> > Currently, I only found a prove-in-use case in musl:
> > 
> >     https://elixir.bootlin.com/musl/latest/source/src/internal/syscall_ret.c:
> > 
> >     #include <errno.h>
> >     #include "syscall.h"
> > 
> >     long __syscall_ret(unsigned long r)
> >     {
> >     	if (r > -4096UL) {
> >     		errno = -r;
> >     		return -1;
> >     	}
> >     	return r;
> >     }
> > 
> > Our new implementation (based on the one used by mmap()) is almostly the same
> > as musl. Not sure if this is enough. I have tried to 'git blame' on
> > __syscall_ret() of musl to find some clue, but failed, because the function has
> > been added before importing into its git repo.
> 
> OK, we already used the glibc-saved registers in the past to determine
> the official list of clobbered registers (and the ABI spec was even
> updated based on this). Here, musl is sufficiently deployed to consider
> this as valid. You can simply go that route and mention in the commit
> message that while you found no official reference stating that this is
> valid for int/long returns, you found at least one other implementation
> relying on this (i.e. if the kernel ever changes it will cause breakage).
>

ok.

> > > Also, the rest of the commit message regarding uintptr_t (which we don't
> > > use), bit values and modular arithmetics is extremely confusing and not
> > > needed at all. What matters is only to know if we need to consider only
> > > values -MAX_ERRNO..-1 as error or all negative ones. If so, then it's
> > > obvious that ret >= (unsigned long)-MAX_ERRNO catches them all, as the
> > > current mmap() function already does with -4095UL.
> > >
> > 
> > Yes, will clean up the commit message, but at first, let's continue get
> > more information about which one is ok:
> > 
> > - -MAX_ERRNO..-1 as error, for sys_mmap (we know in nolibc) currently
> > 
> > - all negative ones, for others currently
> 
> You can double-check in glibc for example, but I'm starting to guess
> you'll find the same test as above, i.e. errors are exclusively >-4096,
> regardless of the expected return type.
>

Your guest is definitely true ;-)

Glibc has the same logic in its INLINE_SYSCALL() macro:

    https://elixir.bootlin.com/glibc/latest/source/sysdeps/unix/sysv/linux/sysdep.h

    #undef INTERNAL_SYSCALL_ERROR_P
    #define INTERNAL_SYSCALL_ERROR_P(val) \
      ((unsigned long int) (val) > -4096UL)
    
    #ifndef SYSCALL_ERROR_LABEL
    # define SYSCALL_ERROR_LABEL(sc_err)					\
      ({									\
        __set_errno (sc_err);						\
        -1L;								\
      })
    #endif
    
    /* Define a macro which expands into the inline wrapper code for a system
       call.  It sets the errno and returns -1 on a failure, or the syscall
       return value otherwise.  */
    #undef INLINE_SYSCALL
    #define INLINE_SYSCALL(name, nr, args...)				\
      ({									\
        long int sc_ret = INTERNAL_SYSCALL (name, nr, args);		\
        __glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (sc_ret))		\
        ? SYSCALL_ERROR_LABEL (INTERNAL_SYSCALL_ERRNO (sc_ret))		\
        : sc_ret;								\
      })

Nothing differs.

But 'git blame' has no clue to any 'spec' or 'standard' either.

- fcb78a55058fd, linux: Consolidate INLINE_SYSCALL

  Moved all of the arch specific INTERNAL_SYSCALL_ERROR_P() to common
  header

- 369b849f1a382, sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h (INTERNAL_SYSCALL,...

  Firstly defined this macro: INTERNAL_SYSCALL_ERROR_P()

    $ git show 369b849f1a3 | grep "define.*INTERNAL_SYSCALL_ERROR_P"
    +#define INTERNAL_SYSCALL_ERROR_P(val)	((unsigned int) (val) >= 0xfffff001u)
    +#define INTERNAL_SYSCALL_ERROR_P(val)	((unsigned int) (val) >= 0xfffff001u)
    +#define INTERNAL_SYSCALL_ERROR_P(val)	((unsigned long) (val) >= -515L)
    +#define INTERNAL_SYSCALL_ERROR_P(val)	((unsigned long) (val) >= -4095L)

Willy, I plan to further use something like, is it ok for you?

    tools/include/nolibc/errno.h:

    -#define MAX_ERRNO 4095
    +#define MAX_ERRNO 4095UL

    tools/include/nolibc/sys.h:

    /* Syscall return helper for library routines
     * set errno as -ret when ret in [-MAX_ERRNO, -1]
     *
     * Note, No official reference states the errno range
     * here aligns with musl (src/internal/syscall_ret.c)
     * and glibc (sysdeps/unix/sysv/linux/sysdep.h)
     */
    static __inline__ __attribute__((unused, always_inline))
    long __sysret(unsigned long ret)
    {
            if (ret >= -MAX_ERRNO) {
                    SET_ERRNO(-(long)ret);
                    return -1;
            }
            return ret;
    }

Or we also directly use 4096UL here.

    static __inline__ __attribute__((unused, always_inline))
    long __sysret(unsigned long ret)
    {
            if (ret > -4096UL) {
                    SET_ERRNO(-(long)ret);
                    return -1;
            }
            return ret;
    }

Best regards,
Zhangjin

> Thanks!
> Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 14/14] selftests/nolibc: add mmap and munmap test cases
  2023-07-03  9:56             ` Willy Tarreau
@ 2023-07-03 11:24               ` Zhangjin Wu
  0 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-07-03 11:24 UTC (permalink / raw)
  To: w
  Cc: arnd, david.laight, falcon, linux-kernel, linux-kselftest,
	linux-riscv, linux, thomas

> On Mon, Jul 03, 2023 at 04:06:47PM +0800, Zhangjin Wu wrote:
> > > >     /* get absolute path of myself, nolibc has no realpath() currently */
> > > >     #ifndef NOLIBC
> > > >             realpath(argv[0], exe);
> > > >     #else
> > > >             /* assume absolute path has no "./" */
> > > >             if (strncmp(argv[0], "./", 2) != 0)
> > > >                     strncat(exe, argv[0], strlen(argv[0]) + 1);
> > > >             else {
> > > >                     pwd = getenv("PWD");
> > > >                     /* skip the ending '\0' */
> > > >                     strncat(exe, getenv("PWD"), strlen(pwd));
> > > >                     /* skip the first '.' */
> > > >                     strncat(exe, argv[0] + 1, strlen(argv[0]));
> > > >             }
> > > >     #endif
> > > 
> > > No, please, not like this. Just copy argv[0] (the pointer not the
> > > contents) and you're fine:
> > >
> > >     static const char *argv0;
> > > 
> > >     int main(int argc, char **argv, char **envp)
> > >     {
> > >             argv0 = argv[0];
> > >             ...
> > >     }
> > > 
> > > Nothing more, nothing less. Your program will always have its correct
> > > path when being called unless someone purposely forces it to something
> > > different, which is not our concern at all since this is a test program.
> > > And I'd rather call it "argv0" which exactly tells us what it contains
> > > than "exe" which can be misleading for that precise reason.
> > >
> > 
> > Yeah, locally, I just used a global argv0 pointer directly, but
> > chroot_exe("./nolibc-test") not work when run 'libc-test' in host
> > system, that is why I tried to get an absolute path ;-)
> > 
> >     CASE_TEST(chroot_exe);        EXPECT_SYSER(1, chroot(exe), -1, ENOTDIR); break;
> > 
> >     -->
> > 
> >     19 chroot_exe = -1 ENOENT  != (-1 ENOTDIR)                      [FAIL]
> 
> Then we have a problem somewhere else and the test should be debugger
> instead. Are you sure there isn't a successful chdir() test before it
> for example, that would change the directory ? If so maybe we just need
> to save the current dir before calling it and restore it later.
>

Yes, as Thomas pointed out, the chdir test cases changed current
directory to "/" just before chroot_exe(), so, restore it with
chdir(getenv("PWD")) solves the issue.

> > I removed the "proc ?" check manually to test if it also work with
> > CONFIG_PROC_FS=n. it doesn't work, without absolute path, we need to add
> > the ENOENT errno back to the errno check list.
> 
> Same as above.
> 
> > I'm not sure if the other syscalls require an absolute path, so, the
> > realpath() is called in this proposed method.
> 
> No, please do not overengineer tests. That's only hiding the dust under
> the carpet and people adding more tests later that will randomly fail
> will have a very hard time trying to figure what's happening under the
> hood. If a test doesn't work as expected, we must not try to work around
> it, but arrange to fix it.

That's right, thanks.

Best regards,
Zhangjin

> 
> Thanks,
> Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 07/14] tools/nolibc: arch-loongarch.h: shrink with SYSCALL_CLOBBERLIST
  2023-07-02 18:50     ` Willy Tarreau
@ 2023-07-03 11:28       ` Zhangjin Wu
  0 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-07-03 11:28 UTC (permalink / raw)
  To: w
  Cc: arnd, david.laight, falcon, linux-kernel, linux-kselftest,
	linux-riscv, thomas

> On Wed, Jun 28, 2023 at 09:22:21PM +0800, Zhangjin Wu wrote:
> > my_syscall<N> share a same long clobber list, define a macro for them.
> > 
> > Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
> > ---
> >  tools/include/nolibc/arch-loongarch.h | 25 +++++++++++--------------
> >  1 file changed, 11 insertions(+), 14 deletions(-)
> > 
> > diff --git a/tools/include/nolibc/arch-loongarch.h b/tools/include/nolibc/arch-loongarch.h
> > index 292d6a58dc87..fbb4844f7993 100644
> > --- a/tools/include/nolibc/arch-loongarch.h
> > +++ b/tools/include/nolibc/arch-loongarch.h
> > @@ -23,6 +23,10 @@
> >   */
> >  #define __ARCH_WANT_SYS_PSELECT6
> >  
> > +#define SYSCALL_CLOBBERLIST			\
> > +	"memory", "$t0", "$t1", "$t2", "$t3",	\
> > +	"$t4", "$t5", "$t6", "$t7", "$t8"
> > +
> 
> That's a good idea, but please be careful when adding macro definitions,
> we're in code that is used by user space we have no control on, and we're
> polluting the end user's macro namespace with plenty of names. While one
> could argue that it's unlikely that some program already defines and uses
> SYSCALL_CLOBBERLIST, actually with low-level code it's fairly possible.
> 
> Till now most of the definitions were for stuff that user-space really
> needs (e.g. STDIN_FILENO, various integer limits). If we start to declare
> random macros for internal use, at least we should probably prefix them
> with _NOLIBC_ or something like this to avoid the risk of collision.
>

Ok, _NOLIBC_ prefix will be applied, Thanks.

Best regards,
Zhangjin

> Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v5 06/14] tools/nolibc: arch-*.h: clean up multiple whitespaces
  2023-07-02 18:44     ` Willy Tarreau
@ 2023-07-03 14:02       ` Zhangjin Wu
  0 siblings, 0 replies; 54+ messages in thread
From: Zhangjin Wu @ 2023-07-03 14:02 UTC (permalink / raw)
  To: w
  Cc: arnd, david.laight, falcon, linux-kernel, linux-kselftest,
	linux-riscv, thomas

Hi, Willy

> Hi Zhangjin,
> 
> On Wed, Jun 28, 2023 at 09:19:33PM +0800, Zhangjin Wu wrote:
> > To align with Linux code style and let scripts/checkpatch.pl happy, the
> > multiple whitespaces in arch-<ARCH>.h files are cleaned up.
> > 
> > Most of them are modified by these commands automatically:
> > 
> >     $ sed -i -e '/#define my_syscall/,/})/{s/        /\t/g}' tools/include/nolibc/arch-*.h
> >     $ sed -i -e '/#define my_syscall/,/})/{s/ *\\$/\t\\/g}' tools/include/nolibc/arch-*.h
> > 
> > And checked with:
> > 
> >     $ grep '  *\\$' tools/include/nolibc/arch-*.h
> 
> I'm surprised by this one, I never saw checkpatch complain here. For me,
> putting a tab after a non-tab is an error. It makes the code harder to
> edit and re-align, and diffs are harder to read on lines whose lengths
> varies by +/-1 around a multiple of 8 as it makes the post-tab stuff
> zigzag. You made me recheck the coding style file, and there's nothing
> about alignment there, only about indent (and indent uses tabs here).
> There are also other parts which use spaces for alignment (albeit not
> that many), so unless there is a solid reason for changing that, I'd
> rather not do it, as for me it's the exact opposite of a cleanup as it
> will cause me quite some discomfort.
>

Willy, it is not about alignment, just rechecked it, it is code indent
related:

    #32: FILE: tools/include/nolibc/arch-mips.h:160:
    +^I                                                                      \$
    
    ERROR: code indent should use tabs where possible
    #44: FILE: tools/include/nolibc/arch-mips.h:172:
    +^I          "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"  \$

The first one is here:

	register long _arg6 = (long)(arg6);                                   \
	<--     whitespaces                                                -->\
	__asm__  volatile (                                                   \

And the second one:

		: "memory", "cc", "at", "v1", "hi", "lo",                     \
	<-spaces->"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"  \

These two lines indent with "one tab + more than 8 whitespaces", the
other lines also have whitespaces code indent, but not more than 8, so,
not reported.

I have tried to replace whitespaces with tabs in the first one, but the first
one can not align with the other lines, so, the current modify method is
applied.

To only touch minimal lines, this may work (reserve the post-whitespaces):

    $ sed -i -e '/^\t*        /{s/        /\t/g}' tools/include/nolibc/arch-*.h

It will only fix up the lines the reported. The cleanup of the post-whitespaces
is not necessary and it does touch too many lines.

Sorry to disturb you with such cleanups, since I have seen the similar
reports when we added the arch-arm.h (for my_syscall6), because the code
style aligns with the others, so, I did touch it, but again encounter
the same issues with arch-mips.h and to avoid the future reports, I
checked the whole arch-xxx.h, and found more such reports, so, we
prepared such a patch.

To be honest, I do prefer post-tabs to whitespaces (less key press, less code
size ;-)), but as you pointed out, post-tabs have more side-effects, we
shouldn't touch them, Thanks.

> > Besides, more multiple whitespaces are cleaned up:
> > 
> > - convert "__asm__  volatile" to "__asm__ volatile"
> 
> I totally agree on this one, it's very likely the result of a mechanical
> change.

Ok, will split it to a standalone patch, one error report one patch.

> 
> > - "foo _num  bar" should be "foo _num bar"
> 
> In theory yes, except that for those where it appears it was only to
> keep all declarations aligned given that this _num was shorter by one
> char than all other local names. Especially when it comes to enumerating
> register names, you definitely want to keep them aligned. It's sufficiently
> difficult to avoid mistakes there, any help for visual check counts.
>

Agree, let's keep it as before.

Thanks,
Zhangjin

> Willy

^ permalink raw reply	[flat|nested] 54+ messages in thread

end of thread, other threads:[~2023-07-03 14:02 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-19 15:40 [PATCH v4 00/10] tools/nolibc: add a new syscall helper Zhangjin Wu
2023-06-19 15:41 ` [PATCH v4 01/10] tools/nolibc: sys.h: add a syscall return helper Zhangjin Wu
2023-06-19 15:42 ` [PATCH v4 02/10] tools/nolibc: unistd.h: apply __sysret() helper Zhangjin Wu
2023-06-19 15:44 ` [PATCH v4 03/10] tools/nolibc: sys.h: " Zhangjin Wu
2023-06-19 15:45 ` [PATCH v4 04/10] tools/nolibc: unistd.h: reorder the syscall macros Zhangjin Wu
2023-06-19 15:47 ` [PATCH v4 05/10] tools/nolibc: add missing my_syscall6() for mips Zhangjin Wu
2023-06-19 15:48 ` [PATCH v4 06/10] tools/nolibc: __sysret: support syscalls who return a pointer Zhangjin Wu
2023-06-19 15:51 ` [PATCH v4 07/10] tools/nolibc: clean up mmap() support Zhangjin Wu
2023-06-21 18:48   ` Thomas Weißschuh
2023-06-22 19:08     ` Zhangjin Wu
2023-06-19 15:52 ` [PATCH v4 08/10] selftests/nolibc: add EXPECT_PTREQ, EXPECT_PTRNE and EXPECT_PTRER Zhangjin Wu
2023-06-19 15:54 ` [PATCH v4 09/10] selftests/nolibc: add sbrk_0 to test current brk getting Zhangjin Wu
2023-06-19 15:55 ` [PATCH v4 10/10] selftests/nolibc: add mmap and munmap test cases Zhangjin Wu
2023-06-19 16:14   ` Zhangjin Wu
2023-06-21 18:58   ` Thomas Weißschuh
2023-06-22 19:32     ` Zhangjin Wu
2023-06-22 19:56       ` Thomas Weißschuh
2023-06-24  7:47         ` Zhangjin Wu
2023-06-28 13:07 ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Zhangjin Wu
2023-06-28 13:08   ` [PATCH v5 01/14] tools/nolibc: sys.h: add a syscall return helper Zhangjin Wu
2023-06-28 13:11   ` [PATCH v5 02/14] tools/nolibc: unistd.h: apply __sysret() helper Zhangjin Wu
2023-06-28 13:13   ` [PATCH v5 03/14] tools/nolibc: sys.h: " Zhangjin Wu
2023-06-28 13:14   ` [PATCH v5 04/14] tools/nolibc: unistd.h: reorder the syscall macros Zhangjin Wu
2023-06-28 13:17   ` [PATCH v5 05/14] tools/nolibc: string.h: clean up multiple whitespaces with tab Zhangjin Wu
2023-06-28 13:19   ` [PATCH v5 06/14] tools/nolibc: arch-*.h: clean up multiple whitespaces Zhangjin Wu
2023-07-02 18:44     ` Willy Tarreau
2023-07-03 14:02       ` Zhangjin Wu
2023-06-28 13:22   ` [PATCH v5 07/14] tools/nolibc: arch-loongarch.h: shrink with SYSCALL_CLOBBERLIST Zhangjin Wu
2023-07-02 18:50     ` Willy Tarreau
2023-07-03 11:28       ` Zhangjin Wu
2023-06-28 13:31   ` [PATCH v5 08/14] tools/nolibc: arch-mips.h: " Zhangjin Wu
2023-06-28 13:37   ` [PATCH v5 09/14] tools/nolibc: add missing my_syscall6() for mips Zhangjin Wu
2023-07-02 18:55     ` Willy Tarreau
2023-07-03 10:13       ` Zhangjin Wu
2023-06-28 13:39   ` [PATCH v5 10/14] tools/nolibc: __sysret: support syscalls who return a pointer Zhangjin Wu
2023-07-02 19:17     ` Willy Tarreau
2023-07-03  8:36       ` Zhangjin Wu
2023-07-03 10:03         ` Willy Tarreau
2023-07-03 11:15           ` Zhangjin Wu
2023-06-28 13:41   ` [PATCH v5 11/14] tools/nolibc: clean up mmap() support Zhangjin Wu
2023-07-02 19:23     ` Willy Tarreau
2023-07-03  6:51       ` Zhangjin Wu
2023-06-28 13:44   ` [PATCH v5 12/14] selftests/nolibc: add EXPECT_PTREQ, EXPECT_PTRNE and EXPECT_PTRER Zhangjin Wu
2023-06-28 13:46   ` [PATCH v5 13/14] selftests/nolibc: add sbrk_0 to test current brk getting Zhangjin Wu
2023-06-28 13:51   ` [PATCH v5 14/14] selftests/nolibc: add mmap and munmap test cases Zhangjin Wu
2023-07-02 19:33     ` Willy Tarreau
2023-07-03  6:03       ` Zhangjin Wu
2023-07-03  7:25         ` Willy Tarreau
2023-07-03  8:06           ` Zhangjin Wu
2023-07-03  8:20             ` Thomas Weißschuh
2023-07-03  9:15               ` Zhangjin Wu
2023-07-03  9:56             ` Willy Tarreau
2023-07-03 11:24               ` Zhangjin Wu
2023-07-02 19:34   ` [PATCH v5 00/14] tools/nolibc: add a new syscall helper Willy Tarreau

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).