Skip to contentSkip to conversation

rcutorture: minor nolibc fixes

PATCH New Willy Tarreau 4 participants 14 messages Dec 29, 2018 – Jan 1, 2019

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

v2 cover rcutorture: minor nolibc fixes

While working on adding some documentation to the nolibc header provided with rcutorture, I noticed a few accidently deleted lines losing clobbered registers and some leftover spaces that I fixed. In addition, I finally added some documentation to the file, as requested by Ingo.

v2: fixed some spelling mistakes after Randy's review

Willy Tarreau (3):
rcutorture/nolibc: fix the clobbered registers in the MIPS syscall
definition
rcutorture/nolibc: fix some poor indentation and alignment rcutorture/nolibc: add a bit of documentation to explain how to use
nolibc

 tools/testing/selftests/rcutorture/bin/nolibc.h | 116 +++++++++++++++++++-----
 1 file changed, 91 insertions(+), 25 deletions(-)
Signature · 1 line
2.9.0
#1 lore raw

PATCH 1/4 rcutorture/nolibc: fix the clobbered registers in the MIPS syscall definition

A last-minute checkpatch cleanup caused most of list of clobbered registers to be lost in the MIPS syscall definition. As it is right now the code is not used on MIPS, but it's better to fix it before it gets used.

Cc Paul E. McKenney <[email protected]>
---
 tools/testing/selftests/rcutorture/bin/nolibc.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
tools/testing/selftests/rcutorture/bin/nolibc.h +6 -6
index f98f5b9..30bd27b 100644
@@ -1006,7 +1006,7 @@ struct sys_stat_struct {
 		: "=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;                                                 \
 })
@@ -1025,7 +1025,7 @@ struct sys_stat_struct {
 		: "0"(_num),                                                  \
 		  "r"(_arg1)                                                  \
 		: "memory", "cc", "at", "v1", "hi", "lo",                     \
-									      \
+	          "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"  \
 	);                                                                    \
 	_arg4 ? -_num : _num;                                                 \
 })
@@ -1045,7 +1045,7 @@ struct sys_stat_struct {
 		: "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;                                                 \
 })
@@ -1066,7 +1066,7 @@ struct sys_stat_struct {
 		: "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;                                                 \
 })
@@ -1087,7 +1087,7 @@ struct sys_stat_struct {
 		: "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;                                                 \
 })
@@ -1110,7 +1110,7 @@ struct sys_stat_struct {
 		: "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;                                                 \
 })
Signature · 1 line
2.9.0
#2 lore raw

PATCH 2/4 rcutorture/nolibc: fix some poor indentation and alignment

In reply to Willy Tarreau

A few macros had their rightmost backslash misaligned, and the pollfd struct definition resisted the previous code reindent. Nothing else changed.

Cc Paul E. McKenney <[email protected]>
---
 tools/testing/selftests/rcutorture/bin/nolibc.h | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
tools/testing/selftests/rcutorture/bin/nolibc.h +7 -7
index 30bd27b..985364c 100644
@@ -81,9 +81,9 @@ typedef   signed long        time_t;
 
 /* for poll() */
 struct pollfd {
-    int fd;
-    short int events;
-    short int revents;
+	int fd;
+	short int events;
+	short int revents;
 };
 
 /* for select() */
@@ -239,7 +239,7 @@ struct stat {
 		"syscall\n"                                                   \
 		: "=a" (_ret)                                                 \
 		: "0"(_num)                                                   \
-		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"                                \
+		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"             \
 	);                                                                    \
 	_ret;                                                                 \
 })
@@ -255,7 +255,7 @@ struct stat {
 		: "=a" (_ret)                                                 \
 		: "r"(_arg1),                                                 \
 		  "0"(_num)                                                   \
-		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"                                \
+		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"             \
 	);                                                                    \
 	_ret;                                                                 \
 })
@@ -272,7 +272,7 @@ struct stat {
 		: "=a" (_ret)                                                 \
 		: "r"(_arg1), "r"(_arg2),                                     \
 		  "0"(_num)                                                   \
-		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"                                \
+		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"             \
 	);                                                                    \
 	_ret;                                                                 \
 })
@@ -290,7 +290,7 @@ struct stat {
 		: "=a" (_ret)                                                 \
 		: "r"(_arg1), "r"(_arg2), "r"(_arg3),                         \
 		  "0"(_num)                                                   \
-		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"                                \
+		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"             \
 	);                                                                    \
 	_ret;                                                                 \
 })
Signature · 1 line
2.9.0
Reviewed-by on v1 2/4
#3 lore raw

Re: [PATCH 2/4] rcutorture/nolibc: fix some poor indentation and alignment

Quoted 6 lines · Willy Tarreau

A few macros had their rightmost backslash misaligned, and the pollfd struct definition resisted the previous code reindent. Nothing else changed.

Cc Paul E. McKenney <[email protected]>
Quoted 60 lines
---
 tools/testing/selftests/rcutorture/bin/nolibc.h | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
tools/testing/selftests/rcutorture/bin/nolibc.h +7 -7
index 30bd27b..985364c 100644
@@ -81,9 +81,9 @@ typedef   signed long        time_t;
 
 /* for poll() */
 struct pollfd {
-    int fd;
-    short int events;
-    short int revents;
+	int fd;
+	short int events;
+	short int revents;
 };
 
 /* for select() */
@@ -239,7 +239,7 @@ struct stat {
 		"syscall\n"                                                   \
 		: "=a" (_ret)                                                 \
 		: "0"(_num)                                                   \
-		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"                                \
+		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"             \
 	);                                                                    \
 	_ret;                                                                 \
 })
@@ -255,7 +255,7 @@ struct stat {
 		: "=a" (_ret)                                                 \
 		: "r"(_arg1),                                                 \
 		  "0"(_num)                                                   \
-		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"                                \
+		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"             \
 	);                                                                    \
 	_ret;                                                                 \
 })
@@ -272,7 +272,7 @@ struct stat {
 		: "=a" (_ret)                                                 \
 		: "r"(_arg1), "r"(_arg2),                                     \
 		  "0"(_num)                                                   \
-		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"                                \
+		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"             \
 	);                                                                    \
 	_ret;                                                                 \
 })
@@ -290,7 +290,7 @@ struct stat {
 		: "=a" (_ret)                                                 \
 		: "r"(_arg1), "r"(_arg2), "r"(_arg3),                         \
 		  "0"(_num)                                                   \
-		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"                                \
+		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"             \
 	);                                                                    \
 	_ret;                                                                 \
 })
Signature · 1 line
2.9.0
Signature · 2 lines
Cheers,
Joey Pabalinas
#4 lore raw

Re: [PATCH 2/4] rcutorture/nolibc: fix some poor indentation and alignment

Quoted 9 lines · Joey Pabalinas
Quoted 6 lines · Willy Tarreau

A few macros had their rightmost backslash misaligned, and the pollfd struct definition resisted the previous code reindent. Nothing else changed.

Cc Paul E. McKenney <[email protected]>

Applied, thank you both!

Thanx, Paul

Quoted 64 lines
Quoted 60 lines
---
 tools/testing/selftests/rcutorture/bin/nolibc.h | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
tools/testing/selftests/rcutorture/bin/nolibc.h +7 -7
index 30bd27b..985364c 100644
@@ -81,9 +81,9 @@ typedef   signed long        time_t;
 
 /* for poll() */
 struct pollfd {
-    int fd;
-    short int events;
-    short int revents;
+	int fd;
+	short int events;
+	short int revents;
 };
 
 /* for select() */
@@ -239,7 +239,7 @@ struct stat {
 		"syscall\n"                                                   \
 		: "=a" (_ret)                                                 \
 		: "0"(_num)                                                   \
-		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"                                \
+		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"             \
 	);                                                                    \
 	_ret;                                                                 \
 })
@@ -255,7 +255,7 @@ struct stat {
 		: "=a" (_ret)                                                 \
 		: "r"(_arg1),                                                 \
 		  "0"(_num)                                                   \
-		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"                                \
+		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"             \
 	);                                                                    \
 	_ret;                                                                 \
 })
@@ -272,7 +272,7 @@ struct stat {
 		: "=a" (_ret)                                                 \
 		: "r"(_arg1), "r"(_arg2),                                     \
 		  "0"(_num)                                                   \
-		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"                                \
+		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"             \
 	);                                                                    \
 	_ret;                                                                 \
 })
@@ -290,7 +290,7 @@ struct stat {
 		: "=a" (_ret)                                                 \
 		: "r"(_arg1), "r"(_arg2), "r"(_arg3),                         \
 		  "0"(_num)                                                   \
-		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"                                \
+		: "rcx", "r8", "r9", "r10", "r11", "memory", "cc"             \
 	);                                                                    \
 	_ret;                                                                 \
 })
Signature · 1 line
2.9.0
Signature · 2 lines
Cheers,
Joey Pabalinas
#5 lore raw

PATCH 3/4 rcutorture/nolibc: add a bit of documentation to explain how to use nolibc

In reply to Willy Tarreau

Ingo rightfully asked for a bit more documentation in the nolibc header, so this patch adds some explanation about its purpose, how it's made, and how to use it.

Cc Ingo Molnar <[email protected]>
Cc Paul E. McKenney <[email protected]>
Cc Randy Dunlap <[email protected]>
---
 tools/testing/selftests/rcutorture/bin/nolibc.h | 90 +++++++++++++++++++++----
 1 file changed, 78 insertions(+), 12 deletions(-)
tools/testing/selftests/rcutorture/bin/nolibc.h +78 -12
index 985364c..6643ba9 100644
@@ -3,6 +3,84 @@
  * Copyright (C) 2017-2018 Willy Tarreau <[email protected]>
  */
 
+/*
+ * This file is designed to be used as a libc alternative for minimal programs
+ * with very limited requirements. It consists of a small number of syscall and
+ * type definitions, and the minimal startup code needed to call main().
+ * All syscalls are declared as static functions so that they can be optimized
+ * away by the compiler when not used.
+ *
+ * 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.
+ *
+ *   - the second level is mostly architecture-independent. It is made of
+ *     static functions called sys_<name>() which rely on my_syscallN()
+ *     depending on the syscall definition. These functions are responsible
+ *     for exposing the appropriate types for the syscall arguments (int,
+ *     pointers, etc) and for setting the appropriate return type (often int).
+ *     A few of them are architecture-specific because the syscalls are not all
+ *     mapped exactly the same among architectures. For example, some archs do
+ *     not implement select() and need pselect6() instead, so the sys_select()
+ *     function will have to abstract this.
+ *
+ *   - the third level is the libc call definition. It exposes the lower raw
+ *     sys_<name>() calls in a way that looks like what a libc usually does,
+ *     takes care of specific input values, and of setting errno upon error.
+ *     There can be minor variations compared to standard libc calls. For
+ *     example the open() call always takes 3 args here.
+ *
+ * The errno variable is declared static and unused. This way it can be
+ * optimized away if not used. However this means that a program made of
+ * multiple C files may observe different errno values (one per C file). For
+ * the type of programs this project targets it usually is not a problem. The
+ * resulting program may even be reduced by defining the NOLIBC_IGNORE_ERRNO
+ * macro, in which case the errno value will never be assigned.
+ *
+ * Some stdint-like integer types are defined. These are valid on all currently
+ * supported architectures, because signs are enforced, ints are assumed to be
+ * 32 bits, longs the size of a pointer and long long 64 bits. If more
+ * architectures have to be supported, this may need to be adapted.
+ *
+ * Some macro definitions like the O_* values passed to open(), and some
+ * structures like the sys_stat struct depend on the architecture.
+ *
+ * The definitions start with the architecture-specific parts, which are picked
+ * based on what the compiler knows about the target architecture, and are
+ * completed with the generic code. Since it is the compiler which sets the
+ * target architecture, cross-compiling normally works out of the box without
+ * having to specify anything.
+ *
+ * Finally some very common libc-level functions are provided. It is the case
+ * for a few functions usually found in string.h, ctype.h, or stdlib.h. Nothing
+ * is currently provided regarding stdio emulation.
+ *
+ * The macro NOLIBC is always defined, so that it is possible for a program to
+ * check this macro to know if it is being built against and decide to disable
+ * some features or simply not to include some standard libc files.
+ *
+ * Ideally this file should be split in multiple files for easier long term
+ * maintenance, but provided as a single file as it is now, it's quite
+ * convenient to use. Maybe some variations involving a set of includes at the
+ * top could work.
+ *
+ * A simple static executable may be built this way :
+ *      $ gcc -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \
+ *            -static -include nolibc.h -lgcc -o hello hello.c
+ *
+ * A very useful calling convention table may be found here :
+ *      http://man7.org/linux/man-pages/man2/syscall.2.html
+ *
+ * This doc is quite convenient though not necessarily up to date :
+ *      https://w3challs.com/syscalls/
+ *
+ */
+
 /* some archs (at least aarch64) don't expose the regular syscalls anymore by
  * default, either because they have an "_at" replacement, or because there are
  * more modern alternatives. For now we'd rather still use them.
@@ -19,18 +97,6 @@
 
 #define NOLIBC
 
-/* Build a static executable this way :
- *      $ gcc -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \
- *            -static -include nolibc.h -lgcc -o hello hello.c
- *
- * Useful calling convention table found here :
- *      http://man7.org/linux/man-pages/man2/syscall.2.html
- *
- * This doc is even better :
- *      https://w3challs.com/syscalls/
- */
-
-
 /* this way it will be removed if unused */
 static int errno;
 
Signature · 1 line
2.9.0
#6 lore raw

Re: [PATCH 3/4] rcutorture/nolibc: add a bit of documentation to explain how to use nolibc

Quoted 15 lines · Willy Tarreau

+ * - 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.
+ *
+ *   - the second level is mostly architecture-independent. It is made of
+ *     static functions called sys_<name>() which rely on my_syscallN()
+ *     depending on the syscall definition. These functions are responsible
+ *     for exposing the appropriate types for the syscall arguments (int,
+ *     pointers, etc) and for setting the appropriate return type (often int).
+ *     A few of them are architecture-specific because the syscalls are not all
+ *     mapped exactly the same among architectures. For example, some archs do
Quoted 8 lines
+ *     not implement select() and need pselect6() instead, so the sys_select()
+ *     function will have to abstract this.
+ *
+ *   - the third level is the libc call definition. It exposes the lower raw
+ *     sys_<name>() calls in a way that looks like what a libc usually does,
+ *     takes care of specific input values, and of setting errno upon error.
+ *     There can be minor variations compared to standard libc calls. For
+ *     example the open() call always takes 3 args here.

Shouldn't these sentences begin with a capitalized "The" for consistency?

Quoted 3 lines

/* some archs (at least aarch64) don't expose the regular syscalls anymore by
* default, either because they have an "_at" replacement, or because there are
* more modern alternatives. For now we'd rather still use them.

Also here. Shouldn't this begin with a capitalized "Some"?

Signature · 2 lines
Cheers,
Joey Pabalinas
#7 lore raw

Re: [PATCH 3/4] rcutorture/nolibc: add a bit of documentation to explain how to use nolibc

Quoted 25 lines · Joey Pabalinas
Quoted 15 lines · Willy Tarreau

+ * - 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.
+ *
+ *   - the second level is mostly architecture-independent. It is made of
+ *     static functions called sys_<name>() which rely on my_syscallN()
+ *     depending on the syscall definition. These functions are responsible
+ *     for exposing the appropriate types for the syscall arguments (int,
+ *     pointers, etc) and for setting the appropriate return type (often int).
+ *     A few of them are architecture-specific because the syscalls are not all
+ *     mapped exactly the same among architectures. For example, some archs do
Quoted 8 lines
+ *     not implement select() and need pselect6() instead, so the sys_select()
+ *     function will have to abstract this.
+ *
+ *   - the third level is the libc call definition. It exposes the lower raw
+ *     sys_<name>() calls in a way that looks like what a libc usually does,
+ *     takes care of specific input values, and of setting errno upon error.
+ *     There can be minor variations compared to standard libc calls. For
+ *     example the open() call always takes 3 args here.
Quoted 2 lines

Shouldn't these sentences begin with a capitalized "The" for consistency?

Not sure since they're just list items. But probably as such they should end with a semi-colon and not a dot. Anyway, this is minor and likely for a later update to the file.

Quoted 5 lines
Quoted 3 lines

/* some archs (at least aarch64) don't expose the regular syscalls anymore by
* default, either because they have an "_at" replacement, or because there are
* more modern alternatives. For now we'd rather still use them.

Also here. Shouldn't this begin with a capitalized "Some"?

Definitely! Same, I won't emit a patch just for this, Paul already queued it.

Thanks!
Willy

Reviewed-by
#8 lore raw

Re: [PATCH 3/4] rcutorture/nolibc: add a bit of documentation to explain how to use nolibc

Quoted 1 line · Willy Tarreau

Definitely! Same, I won't emit a patch just for this, Paul already queued it.

Yeah, not that big a deal :)

Signature · 2 lines
Cheers,
Joey Pabalinas
Reviewed-by Joey Pabalinas Reviewed-by Randy Dunlap
#9 lore raw

Re: [PATCH 3/4] rcutorture/nolibc: add a bit of documentation to explain how to use nolibc

Quoted 6 lines · Joey Pabalinas
Quoted 1 line · Willy Tarreau

Definitely! Same, I won't emit a patch just for this, Paul already queued it.

Yeah, not that big a deal :)

But as long as I am rebasing to add the Reviewed-by, might as well update the others.

The English rules for capitalization and lists are baroque and completely unsuited to word processors ("If any list item is longer than one line, capitalize all the items."), but in this case each item has multiple sentences, so it makes sense to capitalize.

Please see below for the updated commit, and thank you all!

And Happy New Year!!! ;-)

Thanx, Paul

------------------------------------------------------------------------

commit c12cd600666874ef43f2c555391dce47fe60fcd9

Author: Willy Tarreau <[email protected]>
Date:   Sat Dec 29 19:02:18 2018 +0100

rcutorture/nolibc: Add a bit of documentation to explain how to use nolibc

Ingo rightfully asked for a bit more documentation in the nolibc header, so this patch adds some explanation about its purpose, how it's made, and how to use it.

tools/testing/selftests/rcutorture/bin/nolibc.h +79 -13
index cfbbbad4bca4..1708e9f9f8aa 100644
@@ -3,7 +3,85 @@
  * Copyright (C) 2017-2018 Willy Tarreau <[email protected]>
  */
 
-/* some archs (at least aarch64) don't expose the regular syscalls anymore by
+/*
+ * This file is designed to be used as a libc alternative for minimal programs
+ * with very limited requirements. It consists of a small number of syscall and
+ * type definitions, and the minimal startup code needed to call main().
+ * All syscalls are declared as static functions so that they can be optimized
+ * away by the compiler when not used.
+ *
+ * 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.
+ *
+ *   - The second level is mostly architecture-independent. It is made of
+ *     static functions called sys_<name>() which rely on my_syscallN()
+ *     depending on the syscall definition. These functions are responsible
+ *     for exposing the appropriate types for the syscall arguments (int,
+ *     pointers, etc) and for setting the appropriate return type (often int).
+ *     A few of them are architecture-specific because the syscalls are not all
+ *     mapped exactly the same among architectures. For example, some archs do
+ *     not implement select() and need pselect6() instead, so the sys_select()
+ *     function will have to abstract this.
+ *
+ *   - The third level is the libc call definition. It exposes the lower raw
+ *     sys_<name>() calls in a way that looks like what a libc usually does,
+ *     takes care of specific input values, and of setting errno upon error.
+ *     There can be minor variations compared to standard libc calls. For
+ *     example the open() call always takes 3 args here.
+ *
+ * The errno variable is declared static and unused. This way it can be
+ * optimized away if not used. However this means that a program made of
+ * multiple C files may observe different errno values (one per C file). For
+ * the type of programs this project targets it usually is not a problem. The
+ * resulting program may even be reduced by defining the NOLIBC_IGNORE_ERRNO
+ * macro, in which case the errno value will never be assigned.
+ *
+ * Some stdint-like integer types are defined. These are valid on all currently
+ * supported architectures, because signs are enforced, ints are assumed to be
+ * 32 bits, longs the size of a pointer and long long 64 bits. If more
+ * architectures have to be supported, this may need to be adapted.
+ *
+ * Some macro definitions like the O_* values passed to open(), and some
+ * structures like the sys_stat struct depend on the architecture.
+ *
+ * The definitions start with the architecture-specific parts, which are picked
+ * based on what the compiler knows about the target architecture, and are
+ * completed with the generic code. Since it is the compiler which sets the
+ * target architecture, cross-compiling normally works out of the box without
+ * having to specify anything.
+ *
+ * Finally some very common libc-level functions are provided. It is the case
+ * for a few functions usually found in string.h, ctype.h, or stdlib.h. Nothing
+ * is currently provided regarding stdio emulation.
+ *
+ * The macro NOLIBC is always defined, so that it is possible for a program to
+ * check this macro to know if it is being built against and decide to disable
+ * some features or simply not to include some standard libc files.
+ *
+ * Ideally this file should be split in multiple files for easier long term
+ * maintenance, but provided as a single file as it is now, it's quite
+ * convenient to use. Maybe some variations involving a set of includes at the
+ * top could work.
+ *
+ * A simple static executable may be built this way :
+ *      $ gcc -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \
+ *            -static -include nolibc.h -lgcc -o hello hello.c
+ *
+ * A very useful calling convention table may be found here :
+ *      http://man7.org/linux/man-pages/man2/syscall.2.html
+ *
+ * This doc is quite convenient though not necessarily up to date :
+ *      https://w3challs.com/syscalls/
+ *
+ */
+
+/* Some archs (at least aarch64) don't expose the regular syscalls anymore by
  * default, either because they have an "_at" replacement, or because there are
  * more modern alternatives. For now we'd rather still use them.
  */
@@ -19,18 +97,6 @@
 
 #define NOLIBC
 
-/* Build a static executable this way :
- *      $ gcc -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \
- *            -static -include nolibc.h -lgcc -o hello hello.c
- *
- * Useful calling convention table found here :
- *      http://man7.org/linux/man-pages/man2/syscall.2.html
- *
- * This doc is even better :
- *      https://w3challs.com/syscalls/
- */
-
-
 /* this way it will be removed if unused */
 static int errno;
 
#10 lore raw

Re: [PATCH 3/4] rcutorture/nolibc: add a bit of documentation to explain how to use nolibc

Quoted 6 lines · Paul E. McKenney

The English rules for capitalization and lists are baroque and completely unsuited to word processors ("If any list item is longer than one line, capitalize all the items."), but in this case each item has multiple sentences, so it makes sense to capitalize.

Please see below for the updated commit, and thank you all!

OK, this looks fine to me, thank you Paul!

Quoted 1 line

And Happy New Year!!! ;-)

Oh and same to you ;-)

willy

#11 lore raw

Re: [PATCH 3/4] rcutorture/nolibc: add a bit of documentation to explain how to use nolibc

In reply to Paul E. McKenney
Quoted 11 lines · Paul E. McKenney
Quoted 6 lines · Joey Pabalinas
Quoted 1 line · Willy Tarreau

Definitely! Same, I won't emit a patch just for this, Paul already queued it.

Yeah, not that big a deal :)

But as long as I am rebasing to add the Reviewed-by, might as well update the others.

Quoted 6 lines

The English rules for capitalization and lists are baroque and completely unsuited to word processors ("If any list item is longer than one line, capitalize all the items."), but in this case each item has multiple sentences, so it makes sense to capitalize.

Please see below for the updated commit, and thank you all!

Interesting, I had no idea it was actually that odd, hah.

Quoted 1 line

And Happy New Year!!! ;-)

Glad to help, and happy new year to you as well :)

Signature · 2 lines
Cheers,
Joey Pabalinas
#12 lore raw

Re: [PATCH 3/4] rcutorture/nolibc: add a bit of documentation to explain how to use nolibc

Quoted 12 lines · Joey Pabalinas
Quoted 11 lines · Paul E. McKenney
Quoted 6 lines · Joey Pabalinas
Quoted 1 line · Willy Tarreau

Definitely! Same, I won't emit a patch just for this, Paul already queued it.

Yeah, not that big a deal :)

But as long as I am rebasing to add the Reviewed-by, might as well update the others.

Quoted 8 lines
Quoted 6 lines

The English rules for capitalization and lists are baroque and completely unsuited to word processors ("If any list item is longer than one line, capitalize all the items."), but in this case each item has multiple sentences, so it makes sense to capitalize.

Please see below for the updated commit, and thank you all!

Interesting, I had no idea it was actually that odd, hah.

The horrible thing is the guy that informed me of this had English as his third or fourth of something like seven languages. Yet he knew English better than I ever will. Worst of all, when I would complain about some inconsistency, his response was simply "Mr. McKenney, it is your language, not mine!" ;-)

Thanx, Paul

Reviewed-by on v1 3/4
#13 lore raw

Re: [PATCH 3/4] rcutorture/nolibc: add a bit of documentation to explain how to use nolibc

In reply to Willy Tarreau
Quoted 8 lines · Willy Tarreau

Ingo rightfully asked for a bit more documentation in the nolibc header, so this patch adds some explanation about its purpose, how it's made, and how to use it.

Cc Ingo Molnar <[email protected]>
Cc Paul E. McKenney <[email protected]>
Cc Randy Dunlap <[email protected]>

Thanks.

Quoted 113 lines
---
 tools/testing/selftests/rcutorture/bin/nolibc.h | 90 +++++++++++++++++++++----
 1 file changed, 78 insertions(+), 12 deletions(-)
tools/testing/selftests/rcutorture/bin/nolibc.h +78 -12
index 985364c..6643ba9 100644
@@ -3,6 +3,84 @@
  * Copyright (C) 2017-2018 Willy Tarreau <[email protected]>
  */
 
+/*
+ * This file is designed to be used as a libc alternative for minimal programs
+ * with very limited requirements. It consists of a small number of syscall and
+ * type definitions, and the minimal startup code needed to call main().
+ * All syscalls are declared as static functions so that they can be optimized
+ * away by the compiler when not used.
+ *
+ * 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.
+ *
+ *   - the second level is mostly architecture-independent. It is made of
+ *     static functions called sys_<name>() which rely on my_syscallN()
+ *     depending on the syscall definition. These functions are responsible
+ *     for exposing the appropriate types for the syscall arguments (int,
+ *     pointers, etc) and for setting the appropriate return type (often int).
+ *     A few of them are architecture-specific because the syscalls are not all
+ *     mapped exactly the same among architectures. For example, some archs do
+ *     not implement select() and need pselect6() instead, so the sys_select()
+ *     function will have to abstract this.
+ *
+ *   - the third level is the libc call definition. It exposes the lower raw
+ *     sys_<name>() calls in a way that looks like what a libc usually does,
+ *     takes care of specific input values, and of setting errno upon error.
+ *     There can be minor variations compared to standard libc calls. For
+ *     example the open() call always takes 3 args here.
+ *
+ * The errno variable is declared static and unused. This way it can be
+ * optimized away if not used. However this means that a program made of
+ * multiple C files may observe different errno values (one per C file). For
+ * the type of programs this project targets it usually is not a problem. The
+ * resulting program may even be reduced by defining the NOLIBC_IGNORE_ERRNO
+ * macro, in which case the errno value will never be assigned.
+ *
+ * Some stdint-like integer types are defined. These are valid on all currently
+ * supported architectures, because signs are enforced, ints are assumed to be
+ * 32 bits, longs the size of a pointer and long long 64 bits. If more
+ * architectures have to be supported, this may need to be adapted.
+ *
+ * Some macro definitions like the O_* values passed to open(), and some
+ * structures like the sys_stat struct depend on the architecture.
+ *
+ * The definitions start with the architecture-specific parts, which are picked
+ * based on what the compiler knows about the target architecture, and are
+ * completed with the generic code. Since it is the compiler which sets the
+ * target architecture, cross-compiling normally works out of the box without
+ * having to specify anything.
+ *
+ * Finally some very common libc-level functions are provided. It is the case
+ * for a few functions usually found in string.h, ctype.h, or stdlib.h. Nothing
+ * is currently provided regarding stdio emulation.
+ *
+ * The macro NOLIBC is always defined, so that it is possible for a program to
+ * check this macro to know if it is being built against and decide to disable
+ * some features or simply not to include some standard libc files.
+ *
+ * Ideally this file should be split in multiple files for easier long term
+ * maintenance, but provided as a single file as it is now, it's quite
+ * convenient to use. Maybe some variations involving a set of includes at the
+ * top could work.
+ *
+ * A simple static executable may be built this way :
+ *      $ gcc -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \
+ *            -static -include nolibc.h -lgcc -o hello hello.c
+ *
+ * A very useful calling convention table may be found here :
+ *      http://man7.org/linux/man-pages/man2/syscall.2.html
+ *
+ * This doc is quite convenient though not necessarily up to date :
+ *      https://w3challs.com/syscalls/
+ *
+ */
+
 /* some archs (at least aarch64) don't expose the regular syscalls anymore by
  * default, either because they have an "_at" replacement, or because there are
  * more modern alternatives. For now we'd rather still use them.
@@ -19,18 +97,6 @@
 
 #define NOLIBC
 
-/* Build a static executable this way :
- *      $ gcc -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \
- *            -static -include nolibc.h -lgcc -o hello hello.c
- *
- * Useful calling convention table found here :
- *      http://man7.org/linux/man-pages/man2/syscall.2.html
- *
- * This doc is even better :
- *      https://w3challs.com/syscalls/
- */
-
-
 /* this way it will be removed if unused */
 static int errno;
 
Signature · 1 line
~Randy