diff options
| author | Willy Tarreau <w@1wt.eu> | 2018-12-29 13:02:18 -0500 |
|---|---|---|
| committer | Paul E. McKenney <paulmck@linux.ibm.com> | 2019-01-25 18:37:13 -0500 |
| commit | cc72a50994b4910e36445d750b2749b86c37d32b (patch) | |
| tree | 496cd106f65651a33518ff89d4e63ae9a6e79e7d /tools | |
| parent | 85ebb12c4e22c792738b69405f26b5c5948db83f (diff) | |
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.
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Paul E. McKenney <paulmck@linux.ibm.com>
Reviewed-by: Joey Pabalinas <joeypabalinas@gmail.com>
Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/testing/selftests/rcutorture/bin/nolibc.h | 92 |
1 files changed, 79 insertions, 13 deletions
diff --git a/tools/testing/selftests/rcutorture/bin/nolibc.h b/tools/testing/selftests/rcutorture/bin/nolibc.h index cfbbbad4bca4..1708e9f9f8aa 100644 --- a/tools/testing/selftests/rcutorture/bin/nolibc.h +++ b/tools/testing/selftests/rcutorture/bin/nolibc.h | |||
| @@ -3,7 +3,85 @@ | |||
| 3 | * Copyright (C) 2017-2018 Willy Tarreau <w@1wt.eu> | 3 | * Copyright (C) 2017-2018 Willy Tarreau <w@1wt.eu> |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | /* some archs (at least aarch64) don't expose the regular syscalls anymore by | 6 | /* |
| 7 | * This file is designed to be used as a libc alternative for minimal programs | ||
| 8 | * with very limited requirements. It consists of a small number of syscall and | ||
| 9 | * type definitions, and the minimal startup code needed to call main(). | ||
| 10 | * All syscalls are declared as static functions so that they can be optimized | ||
| 11 | * away by the compiler when not used. | ||
| 12 | * | ||
| 13 | * Syscalls are split into 3 levels: | ||
| 14 | * - The lower level is the arch-specific syscall() definition, consisting in | ||
| 15 | * assembly code in compound expressions. These are called my_syscall0() to | ||
| 16 | * my_syscall6() depending on the number of arguments. The MIPS | ||
| 17 | * implementation is limited to 5 arguments. All input arguments are cast | ||
| 18 | * to a long stored in a register. These expressions always return the | ||
| 19 | * syscall's return value as a signed long value which is often either a | ||
| 20 | * pointer or the negated errno value. | ||
| 21 | * | ||
| 22 | * - The second level is mostly architecture-independent. It is made of | ||
| 23 | * static functions called sys_<name>() which rely on my_syscallN() | ||
| 24 | * depending on the syscall definition. These functions are responsible | ||
| 25 | * for exposing the appropriate types for the syscall arguments (int, | ||
| 26 | * pointers, etc) and for setting the appropriate return type (often int). | ||
| 27 | * A few of them are architecture-specific because the syscalls are not all | ||
| 28 | * mapped exactly the same among architectures. For example, some archs do | ||
| 29 | * not implement select() and need pselect6() instead, so the sys_select() | ||
| 30 | * function will have to abstract this. | ||
| 31 | * | ||
| 32 | * - The third level is the libc call definition. It exposes the lower raw | ||
| 33 | * sys_<name>() calls in a way that looks like what a libc usually does, | ||
| 34 | * takes care of specific input values, and of setting errno upon error. | ||
| 35 | * There can be minor variations compared to standard libc calls. For | ||
| 36 | * example the open() call always takes 3 args here. | ||
| 37 | * | ||
| 38 | * The errno variable is declared static and unused. This way it can be | ||
| 39 | * optimized away if not used. However this means that a program made of | ||
| 40 | * multiple C files may observe different errno values (one per C file). For | ||
| 41 | * the type of programs this project targets it usually is not a problem. The | ||
| 42 | * resulting program may even be reduced by defining the NOLIBC_IGNORE_ERRNO | ||
| 43 | * macro, in which case the errno value will never be assigned. | ||
| 44 | * | ||
| 45 | * Some stdint-like integer types are defined. These are valid on all currently | ||
| 46 | * supported architectures, because signs are enforced, ints are assumed to be | ||
| 47 | * 32 bits, longs the size of a pointer and long long 64 bits. If more | ||
| 48 | * architectures have to be supported, this may need to be adapted. | ||
| 49 | * | ||
| 50 | * Some macro definitions like the O_* values passed to open(), and some | ||
| 51 | * structures like the sys_stat struct depend on the architecture. | ||
| 52 | * | ||
| 53 | * The definitions start with the architecture-specific parts, which are picked | ||
| 54 | * based on what the compiler knows about the target architecture, and are | ||
| 55 | * completed with the generic code. Since it is the compiler which sets the | ||
| 56 | * target architecture, cross-compiling normally works out of the box without | ||
| 57 | * having to specify anything. | ||
| 58 | * | ||
| 59 | * Finally some very common libc-level functions are provided. It is the case | ||
| 60 | * for a few functions usually found in string.h, ctype.h, or stdlib.h. Nothing | ||
| 61 | * is currently provided regarding stdio emulation. | ||
| 62 | * | ||
| 63 | * The macro NOLIBC is always defined, so that it is possible for a program to | ||
| 64 | * check this macro to know if it is being built against and decide to disable | ||
| 65 | * some features or simply not to include some standard libc files. | ||
| 66 | * | ||
| 67 | * Ideally this file should be split in multiple files for easier long term | ||
| 68 | * maintenance, but provided as a single file as it is now, it's quite | ||
| 69 | * convenient to use. Maybe some variations involving a set of includes at the | ||
| 70 | * top could work. | ||
| 71 | * | ||
| 72 | * A simple static executable may be built this way : | ||
| 73 | * $ gcc -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \ | ||
| 74 | * -static -include nolibc.h -lgcc -o hello hello.c | ||
| 75 | * | ||
| 76 | * A very useful calling convention table may be found here : | ||
| 77 | * http://man7.org/linux/man-pages/man2/syscall.2.html | ||
| 78 | * | ||
| 79 | * This doc is quite convenient though not necessarily up to date : | ||
| 80 | * https://w3challs.com/syscalls/ | ||
| 81 | * | ||
| 82 | */ | ||
| 83 | |||
| 84 | /* Some archs (at least aarch64) don't expose the regular syscalls anymore by | ||
| 7 | * default, either because they have an "_at" replacement, or because there are | 85 | * default, either because they have an "_at" replacement, or because there are |
| 8 | * more modern alternatives. For now we'd rather still use them. | 86 | * more modern alternatives. For now we'd rather still use them. |
| 9 | */ | 87 | */ |
| @@ -19,18 +97,6 @@ | |||
| 19 | 97 | ||
| 20 | #define NOLIBC | 98 | #define NOLIBC |
| 21 | 99 | ||
| 22 | /* Build a static executable this way : | ||
| 23 | * $ gcc -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \ | ||
| 24 | * -static -include nolibc.h -lgcc -o hello hello.c | ||
| 25 | * | ||
| 26 | * Useful calling convention table found here : | ||
| 27 | * http://man7.org/linux/man-pages/man2/syscall.2.html | ||
| 28 | * | ||
| 29 | * This doc is even better : | ||
| 30 | * https://w3challs.com/syscalls/ | ||
| 31 | */ | ||
| 32 | |||
| 33 | |||
| 34 | /* this way it will be removed if unused */ | 100 | /* this way it will be removed if unused */ |
| 35 | static int errno; | 101 | static int errno; |
| 36 | 102 | ||
