summaryrefslogtreecommitdiff
path: root/tools/include/nolibc
AgeCommit message (Collapse)AuthorFilesLines
2021-12-01tools/nolibc: Implement gettid()Mark Brown1-0/+18
Allow test programs to determine their thread ID. Signed-off-by: Mark Brown <broonie@kernel.org> Cc: Willy Tarreau <w@1wt.eu> Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2021-12-01tools/nolibc: x86-64: Use `mov $60,%eax` instead of `mov $60,%rax`Ammar Faizi1-1/+1
Note that mov to 32-bit register will zero extend to 64-bit register. Thus `mov $60,%eax` has the same effect with `mov $60,%rax`. Use the shorter opcode to achieve the same thing. ``` b8 3c 00 00 00 mov $60,%eax (5 bytes) [1] 48 c7 c0 3c 00 00 00 mov $60,%rax (7 bytes) [2] ``` Currently, we use [2]. Change it to [1] for shorter code. Signed-off-by: Ammar Faizi <ammar.faizi@students.amikom.ac.id> Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2021-12-01tools/nolibc: x86: Remove `r8`, `r9` and `r10` from the clobber listAmmar Faizi1-14/+19
Linux x86-64 syscall only clobbers rax, rcx and r11 (and "memory"). - rax for the return value. - rcx to save the return address. - r11 to save the rflags. Other registers are preserved. Having r8, r9 and r10 in the syscall clobber list is harmless, but this results in a missed-optimization. As the syscall doesn't clobber r8-r10, GCC should be allowed to reuse their value after the syscall returns to userspace. But since they are in the clobber list, GCC will always miss this opportunity. Remove them from the x86-64 syscall clobber list to help GCC generate better code and fix the comment. See also the x86-64 ABI, section A.2 AMD64 Linux Kernel Conventions, A.2.1 Calling Conventions [1]. Extra note: Some people may think it does not really give a benefit to remove r8, r9 and r10 from the syscall clobber list because the impression of syscall is a C function call, and function call always clobbers those 3. However, that is not the case for nolibc.h, because we have a potential to inline the "syscall" instruction (which its opcode is "0f 05") to the user functions. All syscalls in the nolibc.h are written as a static function with inline ASM and are likely always inline if we use optimization flag, so this is a profit not to have r8, r9 and r10 in the clobber list. Here is the example where this matters. Consider the following C code: ``` #include "tools/include/nolibc/nolibc.h" #define read_abc(a, b, c) __asm__ volatile("nop"::"r"(a),"r"(b),"r"(c)) int main(void) { int a = 0xaa; int b = 0xbb; int c = 0xcc; read_abc(a, b, c); write(1, "test\n", 5); read_abc(a, b, c); return 0; } ``` Compile with: gcc -Os test.c -o test -nostdlib With r8, r9, r10 in the clobber list, GCC generates this: 0000000000001000 <main>: 1000: f3 0f 1e fa endbr64 1004: 41 54 push %r12 1006: 41 bc cc 00 00 00 mov $0xcc,%r12d 100c: 55 push %rbp 100d: bd bb 00 00 00 mov $0xbb,%ebp 1012: 53 push %rbx 1013: bb aa 00 00 00 mov $0xaa,%ebx 1018: 90 nop 1019: b8 01 00 00 00 mov $0x1,%eax 101e: bf 01 00 00 00 mov $0x1,%edi 1023: ba 05 00 00 00 mov $0x5,%edx 1028: 48 8d 35 d1 0f 00 00 lea 0xfd1(%rip),%rsi 102f: 0f 05 syscall 1031: 90 nop 1032: 31 c0 xor %eax,%eax 1034: 5b pop %rbx 1035: 5d pop %rbp 1036: 41 5c pop %r12 1038: c3 ret GCC thinks that syscall will clobber r8, r9, r10. So it spills 0xaa, 0xbb and 0xcc to callee saved registers (r12, rbp and rbx). This is clearly extra memory access and extra stack size for preserving them. But syscall does not actually clobber them, so this is a missed optimization. Now without r8, r9, r10 in the clobber list, GCC generates better code: 0000000000001000 <main>: 1000: f3 0f 1e fa endbr64 1004: 41 b8 aa 00 00 00 mov $0xaa,%r8d 100a: 41 b9 bb 00 00 00 mov $0xbb,%r9d 1010: 41 ba cc 00 00 00 mov $0xcc,%r10d 1016: 90 nop 1017: b8 01 00 00 00 mov $0x1,%eax 101c: bf 01 00 00 00 mov $0x1,%edi 1021: ba 05 00 00 00 mov $0x5,%edx 1026: 48 8d 35 d3 0f 00 00 lea 0xfd3(%rip),%rsi 102d: 0f 05 syscall 102f: 90 nop 1030: 31 c0 xor %eax,%eax 1032: c3 ret Cc: Andy Lutomirski <luto@kernel.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: x86@kernel.org Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: David Laight <David.Laight@ACULAB.COM> Acked-by: Andy Lutomirski <luto@kernel.org> Signed-off-by: Ammar Faizi <ammar.faizi@students.amikom.ac.id> Link: https://gitlab.com/x86-psABIs/x86-64-ABI/-/wikis/x86-64-psABI [1] Link: https://lore.kernel.org/lkml/20211011040344.437264-1-ammar.faizi@students.amikom.ac.id/ Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2021-12-01tools/nolibc: fix incorrect truncation of exit codeWilly Tarreau1-8/+5
Ammar Faizi reported that our exit code handling is wrong. We truncate it to the lowest 8 bits but the syscall itself is expected to take a regular 32-bit signed integer, not an unsigned char. It's the kernel that later truncates it to the lowest 8 bits. The difference is visible in strace, where the program below used to show exit(255) instead of exit(-1): int main(void) { return -1; } This patch applies the fix to all archs. x86_64, i386, arm64, armv7 and mips were all tested and confirmed to work fine now. Risc-v was not tested but the change is trivial and exactly the same as for other archs. Reported-by: Ammar Faizi <ammar.faizi@students.amikom.ac.id> Cc: stable@vger.kernel.org Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2021-12-01tools/nolibc: i386: fix initial stack alignmentWilly Tarreau1-1/+9
After re-checking in the spec and comparing stack offsets with glibc, The last pushed argument must be 16-byte aligned (i.e. aligned before the call) so that in the callee esp+4 is multiple of 16, so the principle is the 32-bit equivalent to what Ammar fixed for x86_64. It's possible that 32-bit code using SSE2 or MMX could have been affected. In addition the frame pointer ought to be zero at the deepest level. Link: https://gitlab.com/x86-psABIs/i386-ABI/-/wikis/Intel386-psABI Cc: Ammar Faizi <ammar.faizi@students.amikom.ac.id> Cc: stable@vger.kernel.org Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2021-12-01tools/nolibc: x86-64: Fix startup code bugAmmar Faizi1-2/+8
Before this patch, the `_start` function looks like this: ``` 0000000000001170 <_start>: 1170: pop %rdi 1171: mov %rsp,%rsi 1174: lea 0x8(%rsi,%rdi,8),%rdx 1179: and $0xfffffffffffffff0,%rsp 117d: sub $0x8,%rsp 1181: call 1000 <main> 1186: movzbq %al,%rdi 118a: mov $0x3c,%rax 1191: syscall 1193: hlt 1194: data16 cs nopw 0x0(%rax,%rax,1) 119f: nop ``` Note the "and" to %rsp with $-16, it makes the %rsp be 16-byte aligned, but then there is a "sub" with $0x8 which makes the %rsp no longer 16-byte aligned, then it calls main. That's the bug! What actually the x86-64 System V ABI mandates is that right before the "call", the %rsp must be 16-byte aligned, not after the "call". So the "sub" with $0x8 here breaks the alignment. Remove it. An example where this rule matters is when the callee needs to align its stack at 16-byte for aligned move instruction, like `movdqa` and `movaps`. If the callee can't align its stack properly, it will result in segmentation fault. x86-64 System V ABI also mandates the deepest stack frame should be zero. Just to be safe, let's zero the %rbp on startup as the content of %rbp may be unspecified when the program starts. Now it looks like this: ``` 0000000000001170 <_start>: 1170: pop %rdi 1171: mov %rsp,%rsi 1174: lea 0x8(%rsi,%rdi,8),%rdx 1179: xor %ebp,%ebp # zero the %rbp 117b: and $0xfffffffffffffff0,%rsp # align the %rsp 117f: call 1000 <main> 1184: movzbq %al,%rdi 1188: mov $0x3c,%rax 118f: syscall 1191: hlt 1192: data16 cs nopw 0x0(%rax,%rax,1) 119d: nopl (%rax) ``` Cc: Bedirhan KURT <windowz414@gnuweeb.org> Cc: Louvian Lyndal <louvianlyndal@gmail.com> Reported-by: Peter Cordes <peter@cordes.ca> Signed-off-by: Ammar Faizi <ammar.faizi@students.amikom.ac.id> [wt: I did this on purpose due to a misunderstanding of the spec, other archs will thus have to be rechecked, particularly i386] Cc: stable@vger.kernel.org Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2021-07-20tools/nolibc: Implement msleep()Mark Brown1-0/+13
Allow users to implement shorter delays than a full second by implementing msleep(). Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2021-07-20tools: include: nolibc: Fix a typo occured to occurred in the file nolibc.hBhaskar Chowdhury1-1/+1
s/occured/occurred/ Signed-off-by: Bhaskar Chowdhury <unixbhaskar@gmail.com> Acked-by: Randy Dunlap <rdunlap@infradead.org> Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2021-01-21tools/nolibc: Fix position of -lgcc in the documented exampleWilly Tarreau1-1/+1
The documentation header in the nolibc.h file provides an example command line, but it places the -lgcc argument before the source files, which can fail with libgcc.a (e.g. on ARM when uidiv is needed). This commit therefore moves the -lgcc to the end of the command line, hopefully before this example leaks into makefiles. This is a port of nolibc's upstream commit b5e282089223 to the Linux kernel. Fixes: 66b6f755ad45 ("rcutorture: Import a copy of nolibc") Tested-by: Valentin Schneider <valentin.schneider@arm.com> Tested-by: Mark Rutland <mark.rutland@arm.com> [arm64] Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2021-01-21tools/nolibc: Emit detailed error for missing alternate syscall number ↵Willy Tarreau1-13/+39
definitions Some syscalls can be implemented from different __NR_* variants. For example, sys_dup2() can be implemented based on __NR_dup3 or __NR_dup2. In this case it is useful to mention both alternatives in error messages when neither are detected. This information will help the user search for the right one (e.g __NR_dup3) instead of just the fallback (__NR_dup2) which might not exist on the platform. This is a port of nolibc's upstream commit a21080d2ba41 to the Linux kernel. Suggested-by: Mark Rutland <mark.rutland@arm.com> Link: https://lore.kernel.org/lkml/20210120145447.GC77728@C02TD0UTHF1T.local/ Tested-by: Valentin Schneider <valentin.schneider@arm.com> Tested-by: Mark Rutland <mark.rutland@arm.com> [arm64] Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2021-01-21tools/nolibc: Remove incorrect definitions of __ARCH_WANT_*Willy Tarreau1-8/+0
The __ARCH_WANT_* definitions were added in order to support aarch64 when it was missing some syscall definitions (including __NR_dup2, __NR_fork, and __NR_getpgrp), but these __ARCH_WANT_* definitions were actually wrong because these syscalls do not exist on this platform. Defining these resulted in exposing invalid definitions, resulting in failures on aarch64. The missing syscalls were since implemented based on the newer ones (__NR_dup3, __NR_clone, __NR_getpgid) so these incorrect __ARCH_WANT_* definitions are no longer needed. Thanks to Mark Rutland for spotting this incorrect analysis and explaining why it was wrong. This is a port of nolibc's upstream commit 00b1b0d9b2a4 to the Linux kernel. Reported-by: Mark Rutland <mark.rutland@arm.com> Link: https://lore.kernel.org/lkml/20210119153147.GA5083@paulmck-ThinkPad-P72 Tested-by: Valentin Schneider <valentin.schneider@arm.com> Tested-by: Mark Rutland <mark.rutland@arm.com> [arm64] Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2021-01-21tools/nolibc: Get timeval, timespec and timezone from linux/time.hWilly Tarreau1-18/+1
The definitions of timeval(), timespec() and timezone() conflict with linux/time.h when building, so this commit takes them directly from linux/time.h. This is a port of nolibc's upstream commit dc45f5426b0c to the Linux kernel. Fixes: 66b6f755ad45 ("rcutorture: Import a copy of nolibc") Tested-by: Valentin Schneider <valentin.schneider@arm.com> Tested-by: Mark Rutland <mark.rutland@arm.com> [arm64] Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2021-01-21tools/nolibc: Implement poll() based on ppoll()Willy Tarreau1-0/+10
Some architectures like arm64 do not implement poll() and have to use ppoll() instead. This commit therefore makes poll() use ppoll() when available. This is a port of nolibc's upstream commit 800f75c13ede to the Linux kernel. Fixes: 66b6f755ad45 ("rcutorture: Import a copy of nolibc") Tested-by: Valentin Schneider <valentin.schneider@arm.com> Tested-by: Mark Rutland <mark.rutland@arm.com> [arm64] Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2021-01-21tools/nolibc: Implement fork() based on clone()Willy Tarreau1-0/+10
Some archs such as arm64 do not have fork() and have to use clone() instead. This commit therefore makes fork() use clone() when available. This requires including signal.h to get the definition of SIGCHLD. This is a port of nolibc's upstream commit d2dc42fd6149 to the Linux kernel. Fixes: 66b6f755ad45 ("rcutorture: Import a copy of nolibc") Tested-by: Valentin Schneider <valentin.schneider@arm.com> Tested-by: Mark Rutland <mark.rutland@arm.com> [arm64] Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2021-01-21tools/nolibc: Make getpgrp() fall back to getpgid(0)Willy Tarreau1-1/+19
The getpgrp() syscall is not implemented on arm64, so this commit instead uses getpgid(0) when getpgrp() is not available. This is a port of nolibc's upstream commit 2379f25073f9 to the Linux kernel. Fixes: 66b6f755ad45 ("rcutorture: Import a copy of nolibc") Tested-by: Valentin Schneider <valentin.schneider@arm.com> Tested-by: Mark Rutland <mark.rutland@arm.com> [arm64] Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2021-01-21tools/nolibc: Make dup2() rely on dup3() when availableWilly Tarreau1-0/+26
A recent boot failure on 5.4-rc3 on arm64 revealed that sys_dup2() is not available and that only sys_dup3() is implemented. This commit detects this and falls back to sys_dup3() when available. This is a port of nolibc's upstream commit fd5272ec2c66 to the Linux kernel. Tested-by: Valentin Schneider <valentin.schneider@arm.com> Tested-by: Mark Rutland <mark.rutland@arm.com> [arm64] Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2021-01-21tools/nolibc: Add the definition for dup()Willy Tarreau1-0/+12
This commit adds the dup() function, which was omitted when sys_dup() was defined. This is a port of nolibc's upstream commit 47cc42a79c92 to the Linux kernel. Fixes: 66b6f755ad45 ("rcutorture: Import a copy of nolibc") Tested-by: Valentin Schneider <valentin.schneider@arm.com> Tested-by: Mark Rutland <mark.rutland@arm.com> [arm64] Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2020-11-07tools/nolibc: Fix a spelling error in a commentBhaskar Chowdhury1-1/+1
Fix a spelling in the comment line. s/memry/memory/p This is on linux-next. Signed-off-by: Bhaskar Chowdhury <unixbhaskar@gmail.com> Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2020-11-07rcutorture/nolibc: Fix a typo in header fileSamuel Hernandez1-1/+1
This fixes a typo. Before this, the AT_FDCWD macro would be defined regardless of whether or not it's been defined before. Signed-off-by: Samuel Hernandez <sam.hernandez.amador@gmail.com> Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
2019-05-08tool headers nolibc: add RISCV supportPranith Kumar1-0/+194
This adds support for the RISCV architecture (32 and 64 bit) to the nolibc header file. Signed-off-by: Pranith Kumar <bobby.prani@gmail.com> [willy: minimal rewording of the commit message] Signed-off-by: Willy Tarreau <w@1wt.eu>
2019-01-26tools headers: Move the nolibc header from rcutorture to tools/include/nolibc/Willy Tarreau1-0/+2263
As suggested by Ingo, this header file might benefit other tools than just rcutorture. For now it's quite limited, but is easy to extend, so exposing it into tools/include/nolibc/ will make it much easier to adopt by other tools. The mkinitrd.sh script in rcutorture was updated to use this new location. Cc: Ingo Molnar <mingo@kernel.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Paul E. McKenney <paulmck@linux.ibm.com>