]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
tools/nolibc: merge i386 and x86_64 into a single x86 arch
authorWilly Tarreau <w@1wt.eu>
Wed, 18 Jun 2025 18:30:30 +0000 (20:30 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 22 Jun 2025 07:16:07 +0000 (09:16 +0200)
This remained the only exception to the kernel's architectures
organization and it's always a bit cumbersome to deal with. Let's merge
i386 and x86_64 into x86. This will result in a single arch-x86.h file
by default, and we'll no longer need to merge the two manually during
installation. Requesting either i386 or x86_64 will also result in
installing x86.

Acked-by: Thomas Weißschuh <linux@weissschuh.net>
Signed-off-by: Willy Tarreau <w@1wt.eu>
tools/include/nolibc/Makefile
tools/include/nolibc/arch-i386.h [deleted file]
tools/include/nolibc/arch-x86.h [moved from tools/include/nolibc/arch-x86_64.h with 53% similarity]
tools/include/nolibc/arch.h

index c335ce0bd195c1ec63b9b23c0143307acfd3d3c8..4bace7737b2ade388e138474c10f027a71e21816 100644 (file)
@@ -91,18 +91,12 @@ help:
        @echo "  OUTPUT  = $(OUTPUT)"
        @echo ""
 
-# Note: when ARCH is "x86" we concatenate both x86_64 and i386
 headers:
        $(Q)mkdir -p $(OUTPUT)sysroot
        $(Q)mkdir -p $(OUTPUT)sysroot/include
        $(Q)cp --parents $(all_files) $(OUTPUT)sysroot/include/
-       $(Q)if [ "$(ARCH)" = "x86" ]; then      \
-               sed -e                          \
-                 's,^#ifndef _NOLIBC_ARCH_X86_64_H,#if !defined(_NOLIBC_ARCH_X86_64_H) \&\& defined(__x86_64__),' \
-                 arch-x86_64.h;                \
-               sed -e                          \
-                 's,^#ifndef _NOLIBC_ARCH_I386_H,#if !defined(_NOLIBC_ARCH_I386_H) \&\& !defined(__x86_64__),' \
-                 arch-i386.h;                  \
+       $(Q)if [ "$(ARCH)" = "i386" -o "$(ARCH)" = "x86_64" ]; then \
+               cat arch-x86.h;                 \
        elif [ -e "$(arch_file)" ]; then        \
                cat $(arch_file);               \
        else                                    \
diff --git a/tools/include/nolibc/arch-i386.h b/tools/include/nolibc/arch-i386.h
deleted file mode 100644 (file)
index 7c9b38e..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
-/*
- * i386 specific definitions for NOLIBC
- * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
- */
-
-#ifndef _NOLIBC_ARCH_I386_H
-#define _NOLIBC_ARCH_I386_H
-
-#include "compiler.h"
-#include "crt.h"
-
-/* Syscalls for i386 :
- *   - mostly similar to x86_64
- *   - registers are 32-bit
- *   - syscall number is passed in eax
- *   - arguments are in ebx, ecx, edx, esi, edi, ebp respectively
- *   - all registers are preserved (except eax of course)
- *   - the system call is performed by calling int $0x80
- *   - syscall return comes in eax
- *   - the arguments are cast to long and assigned into the target registers
- *     which are then simply passed as registers to the asm code, so that we
- *     don't have to experience issues with register constraints.
- *   - the syscall number is always specified last in order to allow to force
- *     some registers before (gcc refuses a %-register at the last position).
- *
- * Also, i386 supports the old_select syscall if newselect is not available
- */
-#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_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_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_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;                                                   \
-})
-
-/* startup code */
-/*
- * i386 System V ABI mandates:
- * 1) last pushed argument must be 16-byte aligned.
- * 2) The deepest stack frame should be set to zero
- *
- */
-void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
-{
-       __asm__ volatile (
-               "xor  %ebp, %ebp\n"       /* zero the stack frame                                */
-               "mov  %esp, %eax\n"       /* save stack pointer to %eax, as arg1 of _start_c     */
-               "sub  $12, %esp\n"        /* sub 12 to keep it aligned after the push %eax       */
-               "push %eax\n"             /* push arg1 on stack to support plain stack modes too */
-               "call _start_c\n"         /* transfer to c runtime                               */
-               "hlt\n"                   /* ensure it does not return                           */
-       );
-       __nolibc_entrypoint_epilogue();
-}
-
-#endif /* _NOLIBC_ARCH_I386_H */
similarity index 53%
rename from tools/include/nolibc/arch-x86_64.h
rename to tools/include/nolibc/arch-x86.h
index 67305e24dbefdcd4fd1fc6fd8fdb98d74a34c2d9..d3efc0c3b8adcf2316d188882b04ea1004fce2ae 100644 (file)
 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
 /*
- * x86_64 specific definitions for NOLIBC
- * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
+ * x86 specific definitions for NOLIBC (both 32- and 64-bit)
+ * Copyright (C) 2017-2025 Willy Tarreau <w@1wt.eu>
  */
 
-#ifndef _NOLIBC_ARCH_X86_64_H
-#define _NOLIBC_ARCH_X86_64_H
+#ifndef _NOLIBC_ARCH_X86_H
+#define _NOLIBC_ARCH_X86_H
 
 #include "compiler.h"
 #include "crt.h"
 
+#if !defined(__x86_64__)
+
+/* Syscalls for i386 :
+ *   - mostly similar to x86_64
+ *   - registers are 32-bit
+ *   - syscall number is passed in eax
+ *   - arguments are in ebx, ecx, edx, esi, edi, ebp respectively
+ *   - all registers are preserved (except eax of course)
+ *   - the system call is performed by calling int $0x80
+ *   - syscall return comes in eax
+ *   - the arguments are cast to long and assigned into the target registers
+ *     which are then simply passed as registers to the asm code, so that we
+ *     don't have to experience issues with register constraints.
+ *   - the syscall number is always specified last in order to allow to force
+ *     some registers before (gcc refuses a %-register at the last position).
+ *
+ * Also, i386 supports the old_select syscall if newselect is not available
+ */
+#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_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_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_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;                                                   \
+})
+
+/* startup code */
+/*
+ * i386 System V ABI mandates:
+ * 1) last pushed argument must be 16-byte aligned.
+ * 2) The deepest stack frame should be set to zero
+ *
+ */
+void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
+{
+       __asm__ volatile (
+               "xor  %ebp, %ebp\n"       /* zero the stack frame                                */
+               "mov  %esp, %eax\n"       /* save stack pointer to %eax, as arg1 of _start_c     */
+               "sub  $12, %esp\n"        /* sub 12 to keep it aligned after the push %eax       */
+               "push %eax\n"             /* push arg1 on stack to support plain stack modes too */
+               "call _start_c\n"         /* transfer to c runtime                               */
+               "hlt\n"                   /* ensure it does not return                           */
+       );
+       __nolibc_entrypoint_epilogue();
+}
+
+#else /* !defined(__x86_64__) */
+
 /* Syscalls for x86_64 :
  *   - registers are 64-bit
  *   - syscall number is passed in rax
@@ -214,4 +383,5 @@ __asm__ (
        "retq\n"
 );
 
-#endif /* _NOLIBC_ARCH_X86_64_H */
+#endif /* !defined(__x86_64__) */
+#endif /* _NOLIBC_ARCH_X86_H */
index d20b2304aac21bf817f02a085653d5a170546072..4ae57aaf9779610dfb63458416f147116d0a98e6 100644 (file)
 #ifndef _NOLIBC_ARCH_H
 #define _NOLIBC_ARCH_H
 
-#if defined(__x86_64__)
-#include "arch-x86_64.h"
-#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
-#include "arch-i386.h"
+#if defined(__x86_64__) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
+#include "arch-x86.h"
 #elif defined(__ARM_EABI__)
 #include "arch-arm.h"
 #elif defined(__aarch64__)