| 7f854858 | 10-Jan-2023 |
Willy Tarreau <w@1wt.eu> |
tools/nolibc: make compiler and assembler agree on the section around _start
The out-of-block asm() statement carrying _start does not allow the compiler to know what section the assembly code is be
tools/nolibc: make compiler and assembler agree on the section around _start
The out-of-block asm() statement carrying _start does not allow the compiler to know what section the assembly code is being emitted to, and there's no easy way to push/pop the current section and restore it. It sometimes causes issues depending on the include files ordering and compiler optimizations. For example if a variable is declared immediately before the asm() block and another one after, the compiler assumes that the current section is still .bss and doesn't re-emit it, making the second variable appear inside the .text section instead. Forcing .bss at the end of the _start block doesn't work either because at certain optimizations the compiler may reorder blocks and will make some real code appear just after this block.
A significant number of solutions were attempted, but many of them were still sensitive to section reordering. In the end, the best way to make sure the compiler and assembler agree on the current section is to place this code inside a function. Here the function is directly called _start and configured not to emit a frame-pointer, hence to have no prologue. If some future architectures would still emit some prologue, another working approach consists in naming the function differently and placing the _start label inside the asm statement. But the current solution is simpler.
It was tested with nolibc-test at -O,-O0,-O2,-O3,-Os for arm,arm64,i386, mips,riscv,s390 and x86_64.
Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| 18a5a09d | 09-Jan-2023 |
Sven Schnelle <svens@linux.ibm.com> |
nolibc: add support for s390
Use arch-x86_64 as a template. Not really different, but we have our own mmap syscall which takes a structure instead of discrete arguments.
Signed-off-by: Sven Schnell
nolibc: add support for s390
Use arch-x86_64 as a template. Not really different, but we have our own mmap syscall which takes a structure instead of discrete arguments.
Signed-off-by: Sven Schnelle <svens@linux.ibm.com> Acked-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| 00b18da4 | 09-Jan-2023 |
Willy Tarreau <w@1wt.eu> |
tools/nolibc: fix the O_* fcntl/open macro definitions for riscv
When RISCV port was imported in 5.2, the O_* macros were taken with their octal value and written as-is in hex, resulting in the getd
tools/nolibc: fix the O_* fcntl/open macro definitions for riscv
When RISCV port was imported in 5.2, the O_* macros were taken with their octal value and written as-is in hex, resulting in the getdents64() to fail in nolibc-test.
Fixes: 582e84f7b779 ("tool headers nolibc: add RISCV support") #5.2 Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| 1bfbe1f3 | 09-Jan-2023 |
Willy Tarreau <w@1wt.eu> |
tools/nolibc: prevent gcc from making memset() loop over itself
When building on ARM in thumb mode with gcc-11.3 at -O2 or -O3, nolibc-test segfaults during the select() tests. It turns out that at
tools/nolibc: prevent gcc from making memset() loop over itself
When building on ARM in thumb mode with gcc-11.3 at -O2 or -O3, nolibc-test segfaults during the select() tests. It turns out that at this level, gcc recognizes an opportunity for using memset() to zero the fd_set, but it miscompiles it because it also recognizes a memset pattern as well, and decides to call memset() from the memset() code:
000122bc <memset>: 122bc: b510 push {r4, lr} 122be: 0004 movs r4, r0 122c0: 2a00 cmp r2, #0 122c2: d003 beq.n 122cc <memset+0x10> 122c4: 23ff movs r3, #255 ; 0xff 122c6: 4019 ands r1, r3 122c8: f7ff fff8 bl 122bc <memset> 122cc: 0020 movs r0, r4 122ce: bd10 pop {r4, pc}
Simply placing an empty asm() statement inside the loop suffices to avoid this.
Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| 55abdd1f | 09-Jan-2023 |
Willy Tarreau <w@1wt.eu> |
tools/nolibc: fix missing includes causing build issues at -O0
After the nolibc includes were split to facilitate portability from standard libcs, programs that include only what they need may miss
tools/nolibc: fix missing includes causing build issues at -O0
After the nolibc includes were split to facilitate portability from standard libcs, programs that include only what they need may miss some symbols which are needed by libgcc. This is the case for raise() which is needed by the divide by zero code in some architectures for example.
Regardless, being able to include only the apparently needed files is convenient.
Instead of trying to move all exported definitions to a single file, since this can change over time, this patch takes another approach consisting in including the nolibc header at the end of all standard include files. This way their types and functions are already known at the moment of inclusion, and including any single one of them is sufficient to bring all the required ones.
Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| 184177c3 | 09-Jan-2023 |
Willy Tarreau <w@1wt.eu> |
tools/nolibc: restore mips branch ordering in the _start block
Depending on the compiler used and the optimization options, the sbrk() test was crashing, both on real hardware (mips-24kc) and in qem
tools/nolibc: restore mips branch ordering in the _start block
Depending on the compiler used and the optimization options, the sbrk() test was crashing, both on real hardware (mips-24kc) and in qemu. One such example is kernel.org toolchain in version 11.3 optimizing at -Os.
Inspecting the sys_brk() call shows the following code:
0040047c <sys_brk>: 40047c: 24020fcd li v0,4045 400480: 27bdffe0 addiu sp,sp,-32 400484: 0000000c syscall 400488: 27bd0020 addiu sp,sp,32 40048c: 10e00001 beqz a3,400494 <sys_brk+0x18> 400490: 00021023 negu v0,v0 400494: 03e00008 jr ra
It is obviously wrong, the "negu" instruction is placed in beqz's delayed slot, and worse, there's no nop nor instruction after the return, so the next function's first instruction (addiu sip,sip,-32) will also be executed as part of the delayed slot that follows the return.
This is caused by the ".set noreorder" directive in the _start block, that applies to the whole program. The compiler emits code without the delayed slots and relies on the compiler to swap instructions when this option is not set. Removing the option would require to change the startup code in a way that wouldn't make it look like the resulting code, which would not be easy to debug. Instead let's just save the default ordering before changing it, and restore it at the end of the _start block. Now the code is correct:
0040047c <sys_brk>: 40047c: 24020fcd li v0,4045 400480: 27bdffe0 addiu sp,sp,-32 400484: 0000000c syscall 400488: 10e00002 beqz a3,400494 <sys_brk+0x18> 40048c: 27bd0020 addiu sp,sp,32 400490: 00021023 negu v0,v0 400494: 03e00008 jr ra 400498: 00000000 nop
Fixes: 66b6f755ad45 ("rcutorture: Import a copy of nolibc") #5.0 Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| 16f5cea7 | 09-Jan-2023 |
Warner Losh <imp@bsdimp.com> |
tools/nolibc: Fix S_ISxxx macros
The mode field has the type encoded as an value in a field, not as a bit mask. Mask the mode with S_IFMT instead of each type to test. Otherwise, false positives are
tools/nolibc: Fix S_ISxxx macros
The mode field has the type encoded as an value in a field, not as a bit mask. Mask the mode with S_IFMT instead of each type to test. Otherwise, false positives are possible: eg S_ISDIR will return true for block devices because S_IFDIR = 0040000 and S_IFBLK = 0060000 since mode is masked with S_IFDIR instead of S_IFMT. These macros now match the similar definitions in tools/include/uapi/linux/stat.h.
Signed-off-by: Warner Losh <imp@bsdimp.com> Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| b3f4f51e | 21-Oct-2022 |
Rasmus Villemoes <linux@rasmusvillemoes.dk> |
tools/nolibc/string: Fix memcmp() implementation
The C standard says that memcmp() must treat the buffers as consisting of "unsigned chars". If char happens to be unsigned, the casts are ok, but the
tools/nolibc/string: Fix memcmp() implementation
The C standard says that memcmp() must treat the buffers as consisting of "unsigned chars". If char happens to be unsigned, the casts are ok, but then obviously the c1 variable can never contain a negative value. And when char is signed, the casts are wrong, and there's still a problem with using an 8-bit quantity to hold the difference, because that can range from -255 to +255.
For example, assuming char is signed, comparing two 1-byte buffers, one containing 0x00 and another 0x80, the current implementation would return -128 for both memcmp(a, b, 1) and memcmp(b, a, 1), whereas one of those should of course return something positive.
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> Fixes: 66b6f755ad45 ("rcutorture: Import a copy of nolibc") Cc: stable@vger.kernel.org # v5.0+ Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| 8b53e83b | 19-Jul-2022 |
Willy Tarreau <w@1wt.eu> |
tools/nolibc: fix build warning in sys_mmap() when my_syscall6 is not defined
We return -ENOSYS when there's no syscall6() operation, but we must cast it to void* to avoid a warning.
Signed-off-by:
tools/nolibc: fix build warning in sys_mmap() when my_syscall6 is not defined
We return -ENOSYS when there's no syscall6() operation, but we must cast it to void* to avoid a warning.
Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| 4f8126f3 | 28-May-2022 |
Willy Tarreau <w@1wt.eu> |
tools/nolibc: add a help target to list supported targets
The "help" target simply presents the list of supported targets and the current set of variables being used to build the sysroot.
Since the
tools/nolibc: add a help target to list supported targets
The "help" target simply presents the list of supported targets and the current set of variables being used to build the sysroot.
Since the help in tools/ suggests to use "install", which is supported by most tools while such a target is not really relevant here, an "install" target was also added, redirecting to "help".
Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| fe20cad4 | 28-May-2022 |
Willy Tarreau <w@1wt.eu> |
tools/nolibc: make the default target build the headers
The help in "make -C tools" enumerates nolibc as a valid target so we must at least make it do something. Let's make it do the equivalent of "
tools/nolibc: make the default target build the headers
The help in "make -C tools" enumerates nolibc as a valid target so we must at least make it do something. Let's make it do the equivalent of "make headers" in that it will prepare a sysroot with the arch's headers, but will not install the kernel's headers. This is the minimum some tools will need when built with a full-blown toolchain anyway.
Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| 6a3ad243 | 28-May-2022 |
Willy Tarreau <w@1wt.eu> |
tools/nolibc: fix the makefile to also work as "make -C tools ..."
As reported by Linus, the nolibc's makefile is currently broken when invoked as per the documented method (make -C tools nolibc_<ta
tools/nolibc: fix the makefile to also work as "make -C tools ..."
As reported by Linus, the nolibc's makefile is currently broken when invoked as per the documented method (make -C tools nolibc_<target>), because it now relies on the ARCH and OUTPUT variables that are not set in this case.
This patch addresses this by sourcing subarch.include, and by presetting OUTPUT to the current directory if not set. This is sufficient to make the commands work both as a standalone target and as a tools/ sub-target.
Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| 4f2c9703 | 19-May-2022 |
Alviro Iskandar Setiawan <alviro.iskandar@gnuweeb.org> |
tools/nolibc/stdio: Add format attribute to enable printf warnings
When we use printf and fprintf functions from the nolibc, we don't get any warning from the compiler if we have the wrong arguments
tools/nolibc/stdio: Add format attribute to enable printf warnings
When we use printf and fprintf functions from the nolibc, we don't get any warning from the compiler if we have the wrong arguments. For example, the following calls will compile silently: ``` printf("%s %s\n", "aaa"); fprintf(stdout, "%s %s\n", "xxx", 1); ``` (Note the wrong arguments).
Those calls are undefined behavior. The compiler can help us warn about the above mistakes by adding a `printf` format attribute to those functions declaration. This patch adds it, and now it yields these warnings for those mistakes: ``` warning: format `%s` expects a matching `char *` argument [-Wformat=] warning: format `%s` expects argument of type `char *`, but argument 4 has type `int` [-Wformat=] ```
[ ammarfaizi2: Simplify the attribute placement. ]
Signed-off-by: Alviro Iskandar Setiawan <alviro.iskandar@gnuweeb.org> Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org> Acked-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| 11dbdaef | 29-Mar-2022 |
Ammar Faizi <ammarfaizi2@gnuweeb.org> |
tools/nolibc/string: Implement `strdup()` and `strndup()`
These functions are currently only available on architectures that have my_syscall6() macro implemented. Since these functions use malloc(),
tools/nolibc/string: Implement `strdup()` and `strndup()`
These functions are currently only available on architectures that have my_syscall6() macro implemented. Since these functions use malloc(), malloc() uses mmap(), mmap() depends on my_syscall6() macro.
On architectures that don't support my_syscall6(), these function will always return NULL with errno set to ENOSYS.
Acked-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| b26823c1 | 29-Mar-2022 |
Ammar Faizi <ammarfaizi2@gnuweeb.org> |
tools/nolibc/string: Implement `strnlen()`
size_t strnlen(const char *str, size_t maxlen);
The strnlen() function returns the number of bytes in the string pointed to by sstr, excluding the termi
tools/nolibc/string: Implement `strnlen()`
size_t strnlen(const char *str, size_t maxlen);
The strnlen() function returns the number of bytes in the string pointed to by sstr, excluding the terminating null byte ('\0'), but at most maxlen. In doing this, strnlen() looks only at the first maxlen characters in the string pointed to by str and never beyond str[maxlen-1].
The first use case of this function is for determining the memory allocation size in the strndup() function.
Link: https://lore.kernel.org/lkml/CAOG64qMpEMh+EkOfjNdAoueC+uQyT2Uv3689_sOr37-JxdJf4g@mail.gmail.com Suggested-by: Alviro Iskandar Setiawan <alviro.iskandar@gnuweeb.org> Acked-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| 0e0ff638 | 29-Mar-2022 |
Ammar Faizi <ammarfaizi2@gnuweeb.org> |
tools/nolibc/stdlib: Implement `malloc()`, `calloc()`, `realloc()` and `free()`
Implement basic dynamic allocator functions. These functions are currently only available on architectures that have n
tools/nolibc/stdlib: Implement `malloc()`, `calloc()`, `realloc()` and `free()`
Implement basic dynamic allocator functions. These functions are currently only available on architectures that have nolibc mmap() syscall implemented. These are not a super-fast memory allocator, but at least they can satisfy basic needs for having heap without libc.
Cc: David Laight <David.Laight@ACULAB.COM> Acked-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| 5a18d07c | 29-Mar-2022 |
Ammar Faizi <ammarfaizi2@gnuweeb.org> |
tools/nolibc/types: Implement `offsetof()` and `container_of()` macro
Implement `offsetof()` and `container_of()` macro. The first use case of these macros is for `malloc()`, `realloc()` and `free()
tools/nolibc/types: Implement `offsetof()` and `container_of()` macro
Implement `offsetof()` and `container_of()` macro. The first use case of these macros is for `malloc()`, `realloc()` and `free()`.
Acked-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| 544fa1a2 | 29-Mar-2022 |
Ammar Faizi <ammarfaizi2@gnuweeb.org> |
tools/nolibc/sys: Implement `mmap()` and `munmap()`
Implement mmap() and munmap(). Currently, they are only available for architecures that have my_syscall6 macro. For architectures that don't have,
tools/nolibc/sys: Implement `mmap()` and `munmap()`
Implement mmap() and munmap(). Currently, they are only available for architecures that have my_syscall6 macro. For architectures that don't have, this function will return -1 with errno set to ENOSYS (Function not implemented).
This has been tested on x86 and i386.
Notes for i386: 1) The common mmap() syscall implementation uses __NR_mmap2 instead of __NR_mmap.
2) The offset must be shifted-right by 12-bit.
Acked-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| f4738ff7 | 29-Mar-2022 |
Ammar Faizi <ammarfaizi2@gnuweeb.org> |
tools/nolibc: i386: Implement syscall with 6 arguments
On i386, the 6th argument of syscall goes in %ebp. However, both Clang and GCC cannot use %ebp in the clobber list and in the "r" constraint wi
tools/nolibc: i386: Implement syscall with 6 arguments
On i386, the 6th argument of syscall goes in %ebp. However, both Clang and GCC cannot use %ebp in the clobber list and in the "r" constraint without using -fomit-frame-pointer. To make it always available for any kind of compilation, the below workaround is implemented.
1) Push the 6-th argument. 2) Push %ebp. 3) Load the 6-th argument from 4(%esp) to %ebp. 4) Do the syscall (int $0x80). 5) Pop %ebp (restore the old value of %ebp). 6) Add %esp by 4 (undo the stack pointer).
Cc: x86@kernel.org Cc: llvm@lists.linux.dev Link: https://lore.kernel.org/lkml/2e335ac54db44f1d8496583d97f9dab0@AcuMS.aculab.com Suggested-by: David Laight <David.Laight@ACULAB.COM> Acked-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|
| 1590c598 | 29-Mar-2022 |
Ammar Faizi <ammarfaizi2@gnuweeb.org> |
tools/nolibc: Remove .global _start from the entry point code
Building with clang yields the following error: ``` <inline asm>:3:1: error: _start changed binding to STB_GLOBAL .global _start ^
tools/nolibc: Remove .global _start from the entry point code
Building with clang yields the following error: ``` <inline asm>:3:1: error: _start changed binding to STB_GLOBAL .global _start ^ 1 error generated. ``` Make sure only specify one between `.global _start` and `.weak _start`. Remove `.global _start`.
Cc: llvm@lists.linux.dev Reviewed-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Ammar Faizi <ammarfaizi2@gnuweeb.org> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
show more ...
|