All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/12] tools/nolibc: shrink arch support
@ 2023-07-08 15:25 Zhangjin Wu
  2023-07-08 15:26 ` [PATCH v2 01/12] tools/nolibc: rename arch-<ARCH>.h to <ARCH>/arch.h Zhangjin Wu
                   ` (11 more replies)
  0 siblings, 12 replies; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-08 15:25 UTC (permalink / raw)
  To: w; +Cc: falcon, arnd, linux-kernel, linux-kselftest, thomas

Hi, Willy

This is v2 of the "tools/nolibc: shrink arch support" [1].

This v2 has no core code logic change, but applies some suggestions from
Willy and Thomas, one is using post-whitespaces instead of post-tab,
another is restructuring the arch support directory and files [2].

Like musl, this v2 creates <ARCH> directory for every arch and splits
the old arch-<ARCH>.h to <ARCH>/{crt.h, sys.h} and at the same time,
splits the old arch.h to crt_arch.h and sys_arch.h. at last, only need
to include crt_arch.h in crt.h and sys_arch.h in sys.h respectively, and
no longer need to include arch.h in the other common headers:

    crt.h <-- crt_arch.h <-- <ARCH>/crt.h
    sys.h <-- sys_arch.h <-- <ARCH>/sys.h

It is based on the 20230705-nolibc-series2 branch of nolibc repo [3]. It
should be applied after the v6 __sysret helper series [4] and the v4
min config support series [5].

Here is the test report for all of the supported architectures:

               arch/board | result
              ------------|------------
          arm/vexpress-a9 | 142 test(s) passed, 1 skipped, 0 failed.
                 arm/virt | 142 test(s) passed, 1 skipped, 0 failed.
             aarch64/virt | 142 test(s) passed, 1 skipped, 0 failed.
              ppc/g3beige | not supported
              ppc/ppce500 | not supported
                  i386/pc | 142 test(s) passed, 1 skipped, 0 failed.
                x86_64/pc | 142 test(s) passed, 1 skipped, 0 failed.
             mipsel/malta | 142 test(s) passed, 1 skipped, 0 failed.
         loongarch64/virt | 142 test(s) passed, 1 skipped, 0 failed.
             riscv64/virt | 142 test(s) passed, 1 skipped, 0 failed.
             riscv32/virt | 0 test(s) passed, 0 skipped, 0 failed.
    s390x/s390-ccw-virtio | 142 test(s) passed, 1 skipped, 0 failed.

Changes from v1 --> v2:

* tools/nolibc: rename arch-<ARCH>.h to <ARCH>/arch.h
  tools/nolibc: split arch.h to crt.h and sys.h

    Restruct the arch support directory and files.

    Fix up the errors reported by scripts/checkpatch.pl.

* tools/nolibc: sys.h: remove the old sys_stat support

    Rebase on the new arch support directory and files.

* tools/nolibc: crt.h: add _start_c

    Move #include "compiler.h" in the common crt.h too.

* tools/nolibc: arm/crt.h: shrink _start with _start_c
  tools/nolibc: aarch64/crt.h: shrink _start with _start_c
  tools/nolibc: i386/crt.h: shrink _start with _start_c
  tools/nolibc: x86_64/crt.h: shrink _start with _start_c
  tools/nolibc: mips/crt.h: shrink _start with _start_c
  tools/nolibc: loongarch/crt.h: shrink _start with _start_c
  tools/nolibc: riscv/crt.h: shrink _start with _start_c
  tools/nolibc: s390/crt.h: shrink _start with _start_c

    Rebase on the new arch support directory and files.

    Use post-whitespaces instead of post-tab.    

Best regards,
Zhangjin
---
[1]: https://lore.kernel.org/lkml/cover.1687976753.git.falcon@tinylab.org/
[2]: https://lore.kernel.org/lkml/20230703145500.500460-1-falcon@tinylab.org/
[3]: https://git.kernel.org/pub/scm/linux/kernel/git/wtarreau/nolibc.git
[4]: https://lore.kernel.org/lkml/cover.1688739492.git.falcon@tinylab.org/
[5]: https://lore.kernel.org/lkml/cover.1688750763.git.falcon@tinylab.org/

Zhangjin Wu (12):
  tools/nolibc: rename arch-<ARCH>.h to <ARCH>/arch.h
  tools/nolibc: split arch.h to crt.h and sys.h
  tools/nolibc: sys.h: remove the old sys_stat support
  tools/nolibc: crt.h: add _start_c
  tools/nolibc: arm/crt.h: shrink _start with _start_c
  tools/nolibc: aarch64/crt.h: shrink _start with _start_c
  tools/nolibc: i386/crt.h: shrink _start with _start_c
  tools/nolibc: x86_64/crt.h: shrink _start with _start_c
  tools/nolibc: mips/crt.h: shrink _start with _start_c
  tools/nolibc: loongarch/crt.h: shrink _start with _start_c
  tools/nolibc: riscv/crt.h: shrink _start with _start_c
  tools/nolibc: s390/crt.h: shrink _start with _start_c

 tools/include/nolibc/Makefile                 | 36 ++++---
 tools/include/nolibc/aarch64/crt.h            | 24 +++++
 .../nolibc/{arch-aarch64.h => aarch64/sys.h}  | 68 +------------
 tools/include/nolibc/arch.h                   | 36 -------
 tools/include/nolibc/arm/crt.h                | 25 +++++
 .../include/nolibc/{arch-arm.h => arm/sys.h}  | 96 +------------------
 tools/include/nolibc/crt.h                    | 60 ++++++++++++
 tools/include/nolibc/crt_arch.h               | 32 +++++++
 tools/include/nolibc/i386/crt.h               | 33 +++++++
 .../nolibc/{arch-i386.h => i386/sys.h}        | 77 +--------------
 tools/include/nolibc/loongarch/crt.h          | 30 ++++++
 .../{arch-loongarch.h => loongarch/sys.h}     | 64 +------------
 tools/include/nolibc/mips/crt.h               | 32 +++++++
 .../nolibc/{arch-mips.h => mips/sys.h}        | 87 +----------------
 tools/include/nolibc/nolibc.h                 |  2 +-
 tools/include/nolibc/riscv/crt.h              | 28 ++++++
 .../nolibc/{arch-riscv.h => riscv/sys.h}      | 83 +---------------
 tools/include/nolibc/s390/crt.h               | 21 ++++
 .../nolibc/{arch-s390.h => s390/sys.h}        | 74 +-------------
 tools/include/nolibc/signal.h                 |  1 -
 tools/include/nolibc/stdio.h                  |  1 -
 tools/include/nolibc/stdlib.h                 |  2 +-
 tools/include/nolibc/sys.h                    | 65 +++----------
 tools/include/nolibc/sys_arch.h               | 32 +++++++
 tools/include/nolibc/time.h                   |  1 -
 tools/include/nolibc/types.h                  |  4 +-
 tools/include/nolibc/unistd.h                 |  1 -
 tools/include/nolibc/x86_64/crt.h             | 33 +++++++
 .../nolibc/{arch-x86_64.h => x86_64/sys.h}    | 74 +-------------
 29 files changed, 421 insertions(+), 701 deletions(-)
 create mode 100644 tools/include/nolibc/aarch64/crt.h
 rename tools/include/nolibc/{arch-aarch64.h => aarch64/sys.h} (76%)
 delete mode 100644 tools/include/nolibc/arch.h
 create mode 100644 tools/include/nolibc/arm/crt.h
 rename tools/include/nolibc/{arch-arm.h => arm/sys.h} (74%)
 create mode 100644 tools/include/nolibc/crt.h
 create mode 100644 tools/include/nolibc/crt_arch.h
 create mode 100644 tools/include/nolibc/i386/crt.h
 rename tools/include/nolibc/{arch-i386.h => i386/sys.h} (73%)
 create mode 100644 tools/include/nolibc/loongarch/crt.h
 rename tools/include/nolibc/{arch-loongarch.h => loongarch/sys.h} (73%)
 create mode 100644 tools/include/nolibc/mips/crt.h
 rename tools/include/nolibc/{arch-mips.h => mips/sys.h} (74%)
 create mode 100644 tools/include/nolibc/riscv/crt.h
 rename tools/include/nolibc/{arch-riscv.h => riscv/sys.h} (70%)
 create mode 100644 tools/include/nolibc/s390/crt.h
 rename tools/include/nolibc/{arch-s390.h => s390/sys.h} (68%)
 create mode 100644 tools/include/nolibc/sys_arch.h
 create mode 100644 tools/include/nolibc/x86_64/crt.h
 rename tools/include/nolibc/{arch-x86_64.h => x86_64/sys.h} (76%)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v2 01/12] tools/nolibc: rename arch-<ARCH>.h to <ARCH>/arch.h
  2023-07-08 15:25 [PATCH v2 00/12] tools/nolibc: shrink arch support Zhangjin Wu
@ 2023-07-08 15:26 ` Zhangjin Wu
  2023-07-09  9:56   ` Willy Tarreau
  2023-07-08 15:27 ` [PATCH v2 02/12] tools/nolibc: split arch.h to crt.h and sys.h Zhangjin Wu
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-08 15:26 UTC (permalink / raw)
  To: w; +Cc: falcon, arnd, linux-kernel, linux-kselftest, thomas

Currently, the architecture specific arch.h has two parts, one is the
syscall declarations for sys.h, another is the _start code definition
for startup support.

The coming crt.h will provide the startup support with a new common
_start_c(), it will replace most of the assembly _start code and shrink
the original _start code to be minimal, as a result, _start_c() and the
left minimal _start code will work together to provide the startup
support, therefore, the left _start code will be only required by crt.h.

So, the syscall declarations part of arch.h can be split to sys_arch.h
and the _start code part of arch.h can be split to crt_arch.h and then,
they should only be included in sys.h and crt.h respectively.

At the same time, the architecture specific arch-<ARCH>.h should be
split to <ARCH>/crt.h and <ARCH>/sys.h.

As a preparation, this creates the architecture specific directory and
moves tools/include/nolibc/arch-<ARCH>.h to
tools/include/nolibc/<ARCH>/arch.h.

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/Makefile                    | 10 +++++-----
 .../nolibc/{arch-aarch64.h => aarch64/arch.h}    |  6 +++---
 tools/include/nolibc/arch.h                      | 16 ++++++++--------
 tools/include/nolibc/{arch-arm.h => arm/arch.h}  |  6 +++---
 .../include/nolibc/{arch-i386.h => i386/arch.h}  |  6 +++---
 .../{arch-loongarch.h => loongarch/arch.h}       |  6 +++---
 .../include/nolibc/{arch-mips.h => mips/arch.h}  |  6 +++---
 .../nolibc/{arch-riscv.h => riscv/arch.h}        |  6 +++---
 .../include/nolibc/{arch-s390.h => s390/arch.h}  |  6 +++---
 .../nolibc/{arch-x86_64.h => x86_64/arch.h}      |  6 +++---
 10 files changed, 37 insertions(+), 37 deletions(-)
 rename tools/include/nolibc/{arch-aarch64.h => aarch64/arch.h} (99%)
 rename tools/include/nolibc/{arch-arm.h => arm/arch.h} (99%)
 rename tools/include/nolibc/{arch-i386.h => i386/arch.h} (99%)
 rename tools/include/nolibc/{arch-loongarch.h => loongarch/arch.h} (99%)
 rename tools/include/nolibc/{arch-mips.h => mips/arch.h} (99%)
 rename tools/include/nolibc/{arch-riscv.h => riscv/arch.h} (99%)
 rename tools/include/nolibc/{arch-s390.h => s390/arch.h} (98%)
 rename tools/include/nolibc/{arch-x86_64.h => x86_64/arch.h} (99%)

diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile
index 64d67b080744..ce21ace8210e 100644
--- a/tools/include/nolibc/Makefile
+++ b/tools/include/nolibc/Makefile
@@ -24,7 +24,7 @@ Q=@
 endif
 
 nolibc_arch := $(patsubst arm64,aarch64,$(ARCH))
-arch_file := arch-$(nolibc_arch).h
+arch_file := $(nolibc_arch)/arch.h
 all_files := \
 		compiler.h \
 		ctype.h \
@@ -70,11 +70,11 @@ headers:
 	$(Q)cp $(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;                \
+		  's,^#ifndef _NOLIBC_X86_64_ARCH_H,#if !defined(_NOLIBC_X86_64_ARCH_H) \&\& defined(__x86_64__),' \
+		  x86_64/arch.h;                \
 		sed -e                          \
-		  's,^#ifndef _NOLIBC_ARCH_I386_H,#if !defined(_NOLIBC_ARCH_I386_H) \&\& !defined(__x86_64__),' \
-		  arch-i386.h;                  \
+		  's,^#ifndef _NOLIBC_I386_ARCH_H,#if !defined(_NOLIBC_I386_ARCH_H) \&\& !defined(__x86_64__),' \
+		  i386/arch.h;                  \
 	elif [ -e "$(arch_file)" ]; then        \
 		cat $(arch_file);               \
 	else                                    \
diff --git a/tools/include/nolibc/arch-aarch64.h b/tools/include/nolibc/aarch64/arch.h
similarity index 99%
rename from tools/include/nolibc/arch-aarch64.h
rename to tools/include/nolibc/aarch64/arch.h
index 6227b77a4a09..7d38da13c72b 100644
--- a/tools/include/nolibc/arch-aarch64.h
+++ b/tools/include/nolibc/aarch64/arch.h
@@ -4,8 +4,8 @@
  * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
  */
 
-#ifndef _NOLIBC_ARCH_AARCH64_H
-#define _NOLIBC_ARCH_AARCH64_H
+#ifndef _NOLIBC_AARCH64_ARCH_H
+#define _NOLIBC_AARCH64_ARCH_H
 
 #include "compiler.h"
 
@@ -201,4 +201,4 @@ void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_pr
 	);
 	__builtin_unreachable();
 }
-#endif /* _NOLIBC_ARCH_AARCH64_H */
+#endif /* _NOLIBC_AARCH64_ARCH_H */
diff --git a/tools/include/nolibc/arch.h b/tools/include/nolibc/arch.h
index 82b43935650f..f98616f5b219 100644
--- a/tools/include/nolibc/arch.h
+++ b/tools/include/nolibc/arch.h
@@ -16,21 +16,21 @@
 #define _NOLIBC_ARCH_H
 
 #if defined(__x86_64__)
-#include "arch-x86_64.h"
+#include "x86_64/arch.h"
 #elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
-#include "arch-i386.h"
+#include "i386/arch.h"
 #elif defined(__ARM_EABI__)
-#include "arch-arm.h"
+#include "arm/arch.h"
 #elif defined(__aarch64__)
-#include "arch-aarch64.h"
+#include "aarch64/arch.h"
 #elif defined(__mips__) && defined(_ABIO32)
-#include "arch-mips.h"
+#include "mips/arch.h"
 #elif defined(__riscv)
-#include "arch-riscv.h"
+#include "riscv/arch.h"
 #elif defined(__s390x__)
-#include "arch-s390.h"
+#include "s390/arch.h"
 #elif defined(__loongarch__)
-#include "arch-loongarch.h"
+#include "loongarch/arch.h"
 #endif
 
 #endif /* _NOLIBC_ARCH_H */
diff --git a/tools/include/nolibc/arch-arm.h b/tools/include/nolibc/arm/arch.h
similarity index 99%
rename from tools/include/nolibc/arch-arm.h
rename to tools/include/nolibc/arm/arch.h
index 4d4887a5f04b..473d2c000740 100644
--- a/tools/include/nolibc/arch-arm.h
+++ b/tools/include/nolibc/arm/arch.h
@@ -4,8 +4,8 @@
  * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
  */
 
-#ifndef _NOLIBC_ARCH_ARM_H
-#define _NOLIBC_ARCH_ARM_H
+#ifndef _NOLIBC_ARM_ARCH_H
+#define _NOLIBC_ARM_ARCH_H
 
 #include "compiler.h"
 
@@ -267,4 +267,4 @@ void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_pr
 	__builtin_unreachable();
 }
 
-#endif /* _NOLIBC_ARCH_ARM_H */
+#endif /* _NOLIBC_ARM_ARCH_H */
diff --git a/tools/include/nolibc/arch-i386.h b/tools/include/nolibc/i386/arch.h
similarity index 99%
rename from tools/include/nolibc/arch-i386.h
rename to tools/include/nolibc/i386/arch.h
index 4c6b7c04e2e7..66052742763e 100644
--- a/tools/include/nolibc/arch-i386.h
+++ b/tools/include/nolibc/i386/arch.h
@@ -4,8 +4,8 @@
  * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
  */
 
-#ifndef _NOLIBC_ARCH_I386_H
-#define _NOLIBC_ARCH_I386_H
+#ifndef _NOLIBC_I386_ARCH_H
+#define _NOLIBC_I386_ARCH_H
 
 #include "compiler.h"
 
@@ -221,4 +221,4 @@ void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_pr
 	__builtin_unreachable();
 }
 
-#endif /* _NOLIBC_ARCH_I386_H */
+#endif /* _NOLIBC_I386_ARCH_H */
diff --git a/tools/include/nolibc/arch-loongarch.h b/tools/include/nolibc/loongarch/arch.h
similarity index 99%
rename from tools/include/nolibc/arch-loongarch.h
rename to tools/include/nolibc/loongarch/arch.h
index 8aa7724fe38e..63fee1e8f4d9 100644
--- a/tools/include/nolibc/arch-loongarch.h
+++ b/tools/include/nolibc/loongarch/arch.h
@@ -4,8 +4,8 @@
  * Copyright (C) 2023 Loongson Technology Corporation Limited
  */
 
-#ifndef _NOLIBC_ARCH_LOONGARCH_H
-#define _NOLIBC_ARCH_LOONGARCH_H
+#ifndef _NOLIBC_LOONGARCH_ARCH_H
+#define _NOLIBC_LOONGARCH_ARCH_H
 
 #include "compiler.h"
 
@@ -197,4 +197,4 @@ void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_pr
 	__builtin_unreachable();
 }
 
-#endif /* _NOLIBC_ARCH_LOONGARCH_H */
+#endif /* _NOLIBC_LOONGARCH_ARCH_H */
diff --git a/tools/include/nolibc/arch-mips.h b/tools/include/nolibc/mips/arch.h
similarity index 99%
rename from tools/include/nolibc/arch-mips.h
rename to tools/include/nolibc/mips/arch.h
index a2bfdf57b957..1581b721b714 100644
--- a/tools/include/nolibc/arch-mips.h
+++ b/tools/include/nolibc/mips/arch.h
@@ -4,8 +4,8 @@
  * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
  */
 
-#ifndef _NOLIBC_ARCH_MIPS_H
-#define _NOLIBC_ARCH_MIPS_H
+#ifndef _NOLIBC_MIPS_ARCH_H
+#define _NOLIBC_MIPS_ARCH_H
 
 #include "compiler.h"
 
@@ -250,4 +250,4 @@ void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_pr
 	__builtin_unreachable();
 }
 
-#endif /* _NOLIBC_ARCH_MIPS_H */
+#endif /* _NOLIBC_MIPS_ARCH_H */
diff --git a/tools/include/nolibc/arch-riscv.h b/tools/include/nolibc/riscv/arch.h
similarity index 99%
rename from tools/include/nolibc/arch-riscv.h
rename to tools/include/nolibc/riscv/arch.h
index cd958b2f4b1b..de68759f5959 100644
--- a/tools/include/nolibc/arch-riscv.h
+++ b/tools/include/nolibc/riscv/arch.h
@@ -4,8 +4,8 @@
  * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
  */
 
-#ifndef _NOLIBC_ARCH_RISCV_H
-#define _NOLIBC_ARCH_RISCV_H
+#ifndef _NOLIBC_RISCV_ARCH_H
+#define _NOLIBC_RISCV_ARCH_H
 
 #include "compiler.h"
 
@@ -214,4 +214,4 @@ void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_pr
 	__builtin_unreachable();
 }
 
-#endif /* _NOLIBC_ARCH_RISCV_H */
+#endif /* _NOLIBC_RISCV_ARCH_H */
diff --git a/tools/include/nolibc/arch-s390.h b/tools/include/nolibc/s390/arch.h
similarity index 98%
rename from tools/include/nolibc/arch-s390.h
rename to tools/include/nolibc/s390/arch.h
index a644ecd361c0..a7b512e81234 100644
--- a/tools/include/nolibc/arch-s390.h
+++ b/tools/include/nolibc/s390/arch.h
@@ -3,8 +3,8 @@
  * s390 specific definitions for NOLIBC
  */
 
-#ifndef _NOLIBC_ARCH_S390_H
-#define _NOLIBC_ARCH_S390_H
+#ifndef _NOLIBC_S390_ARCH_H
+#define _NOLIBC_S390_ARCH_H
 #include <asm/signal.h>
 #include <asm/unistd.h>
 
@@ -234,4 +234,4 @@ pid_t sys_fork(void)
 }
 #define sys_fork sys_fork
 
-#endif /* _NOLIBC_ARCH_S390_H */
+#endif /* _NOLIBC_S390_ARCH_H */
diff --git a/tools/include/nolibc/arch-x86_64.h b/tools/include/nolibc/x86_64/arch.h
similarity index 99%
rename from tools/include/nolibc/arch-x86_64.h
rename to tools/include/nolibc/x86_64/arch.h
index e69113742a99..602791c3461a 100644
--- a/tools/include/nolibc/arch-x86_64.h
+++ b/tools/include/nolibc/x86_64/arch.h
@@ -4,8 +4,8 @@
  * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
  */
 
-#ifndef _NOLIBC_ARCH_X86_64_H
-#define _NOLIBC_ARCH_X86_64_H
+#ifndef _NOLIBC_X86_64_ARCH_H
+#define _NOLIBC_X86_64_ARCH_H
 
 #include "compiler.h"
 
@@ -217,4 +217,4 @@ void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_pr
 	__builtin_unreachable();
 }
 
-#endif /* _NOLIBC_ARCH_X86_64_H */
+#endif /* _NOLIBC_X86_64_ARCH_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 02/12] tools/nolibc: split arch.h to crt.h and sys.h
  2023-07-08 15:25 [PATCH v2 00/12] tools/nolibc: shrink arch support Zhangjin Wu
  2023-07-08 15:26 ` [PATCH v2 01/12] tools/nolibc: rename arch-<ARCH>.h to <ARCH>/arch.h Zhangjin Wu
@ 2023-07-08 15:27 ` Zhangjin Wu
  2023-07-08 15:28 ` [PATCH v2 03/12] tools/nolibc: sys.h: remove the old sys_stat support Zhangjin Wu
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-08 15:27 UTC (permalink / raw)
  To: w; +Cc: falcon, arnd, linux-kernel, linux-kselftest, thomas

For each architecture, arch.h has the syscall declarations and the
_start code definition, let's split it to sys.h and crt.h respectively:

- local :   <ARCH>/arch.h -> <ARCH>/{sys.h, crt.h}
- global:          arch.h -> sys_arch.h, crt_arch.h

And then, we can include the architecture specific file to the common
file like this:

- crt.h: #include "crt_arch.h"
- sys.h: #include "sys_arch.h"

At last, the "arch.h" header can be removed from all of the other
headers, instead, we only need to include "sys.h" and "crt.h" on demand.

BTW, the following errors reported by scripts/checkpatch.pl are fixed:

    ERROR: space required after that ',' (ctx:VxV)
    #1327: FILE: tools/include/nolibc/x86_64/crt.h:17:
    +void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_protector _start(void)

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/Makefile                 | 36 +++++++----
 tools/include/nolibc/aarch64/crt.h            | 37 +++++++++++
 .../include/nolibc/aarch64/{arch.h => sys.h}  | 40 ++----------
 tools/include/nolibc/arch.h                   | 36 -----------
 tools/include/nolibc/arm/crt.h                | 53 +++++++++++++++
 tools/include/nolibc/arm/{arch.h => sys.h}    | 59 ++---------------
 tools/include/nolibc/crt.h                    | 16 +++++
 tools/include/nolibc/crt_arch.h               | 32 ++++++++++
 tools/include/nolibc/i386/crt.h               | 48 ++++++++++++++
 tools/include/nolibc/i386/{arch.h => sys.h}   | 51 ++-------------
 tools/include/nolibc/loongarch/crt.h          | 61 ++++++++++++++++++
 .../nolibc/loongarch/{arch.h => sys.h}        | 64 ++-----------------
 tools/include/nolibc/mips/crt.h               | 56 ++++++++++++++++
 tools/include/nolibc/mips/{arch.h => sys.h}   | 59 ++---------------
 tools/include/nolibc/nolibc.h                 |  2 +-
 tools/include/nolibc/riscv/crt.h              | 57 +++++++++++++++++
 tools/include/nolibc/riscv/{arch.h => sys.h}  | 60 ++---------------
 tools/include/nolibc/s390/crt.h               | 45 +++++++++++++
 tools/include/nolibc/s390/{arch.h => sys.h}   | 49 ++------------
 tools/include/nolibc/signal.h                 |  1 -
 tools/include/nolibc/stdio.h                  |  1 -
 tools/include/nolibc/stdlib.h                 |  2 +-
 tools/include/nolibc/sys.h                    |  2 +-
 tools/include/nolibc/sys_arch.h               | 32 ++++++++++
 tools/include/nolibc/time.h                   |  1 -
 tools/include/nolibc/unistd.h                 |  1 -
 tools/include/nolibc/x86_64/crt.h             | 44 +++++++++++++
 tools/include/nolibc/x86_64/{arch.h => sys.h} | 47 ++------------
 28 files changed, 539 insertions(+), 453 deletions(-)
 create mode 100644 tools/include/nolibc/aarch64/crt.h
 rename tools/include/nolibc/aarch64/{arch.h => sys.h} (82%)
 delete mode 100644 tools/include/nolibc/arch.h
 create mode 100644 tools/include/nolibc/arm/crt.h
 rename tools/include/nolibc/arm/{arch.h => sys.h} (81%)
 create mode 100644 tools/include/nolibc/crt.h
 create mode 100644 tools/include/nolibc/crt_arch.h
 create mode 100644 tools/include/nolibc/i386/crt.h
 rename tools/include/nolibc/i386/{arch.h => sys.h} (79%)
 create mode 100644 tools/include/nolibc/loongarch/crt.h
 rename tools/include/nolibc/loongarch/{arch.h => sys.h} (73%)
 create mode 100644 tools/include/nolibc/mips/crt.h
 rename tools/include/nolibc/mips/{arch.h => sys.h} (79%)
 create mode 100644 tools/include/nolibc/riscv/crt.h
 rename tools/include/nolibc/riscv/{arch.h => sys.h} (78%)
 create mode 100644 tools/include/nolibc/s390/crt.h
 rename tools/include/nolibc/s390/{arch.h => sys.h} (78%)
 create mode 100644 tools/include/nolibc/sys_arch.h
 create mode 100644 tools/include/nolibc/x86_64/crt.h
 rename tools/include/nolibc/x86_64/{arch.h => sys.h} (81%)

diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile
index ce21ace8210e..e23c816598dc 100644
--- a/tools/include/nolibc/Makefile
+++ b/tools/include/nolibc/Makefile
@@ -24,9 +24,13 @@ Q=@
 endif
 
 nolibc_arch := $(patsubst arm64,aarch64,$(ARCH))
-arch_file := $(nolibc_arch)/arch.h
+arch_files := \
+		$(nolibc_arch)/crt.h \
+		$(nolibc_arch)/sys.h
+
 all_files := \
 		compiler.h \
+		crt.h \
 		ctype.h \
 		errno.h \
 		nolibc.h \
@@ -68,19 +72,23 @@ headers:
 	$(Q)mkdir -p $(OUTPUT)sysroot
 	$(Q)mkdir -p $(OUTPUT)sysroot/include
 	$(Q)cp $(all_files) $(OUTPUT)sysroot/include/
-	$(Q)if [ "$(ARCH)" = "x86" ]; then      \
-		sed -e                          \
-		  's,^#ifndef _NOLIBC_X86_64_ARCH_H,#if !defined(_NOLIBC_X86_64_ARCH_H) \&\& defined(__x86_64__),' \
-		  x86_64/arch.h;                \
-		sed -e                          \
-		  's,^#ifndef _NOLIBC_I386_ARCH_H,#if !defined(_NOLIBC_I386_ARCH_H) \&\& !defined(__x86_64__),' \
-		  i386/arch.h;                  \
-	elif [ -e "$(arch_file)" ]; then        \
-		cat $(arch_file);               \
-	else                                    \
-		echo "Fatal: architecture $(ARCH) not yet supported by nolibc." >&2; \
-		exit 1;                         \
-	fi > $(OUTPUT)sysroot/include/arch.h
+	$(Q)for arch_file in $(arch_files); do                                 \
+		base_file=$$(basename $$arch_file);                            \
+		arch_header=$$(echo $$base_file | sed -e 's/\.h$$/_arch.h/g'); \
+		if [ "$(ARCH)" = "x86" ]; then                                 \
+			sed -e                                                 \
+			  's,^#ifndef _NOLIBC_X86_64_\([^_]*\)_H,#if !defined(_NOLIBC_X86_64_\1_H) \&\& defined(__x86_64__),' \
+			  x86_64/$$base_file;                                  \
+			sed -e                                                 \
+			  's,^#ifndef _NOLIBC_I386_\([^_]*\)_H,#if !defined(_NOLIBC_I386_\1_H) \&\& !defined(__x86_64__),' \
+			  i386/$$base_file;                                    \
+		elif [ -e "$$arch_file" ]; then                                \
+			cat $$arch_file;                                       \
+		else                                                           \
+			echo "Fatal: architecture $(ARCH) not yet supported by nolibc." >&2; \
+			exit 1;                                                \
+		fi > $(OUTPUT)sysroot/include/$$arch_header;                   \
+	done
 
 headers_standalone: headers
 	$(Q)$(MAKE) -C $(srctree) headers
diff --git a/tools/include/nolibc/aarch64/crt.h b/tools/include/nolibc/aarch64/crt.h
new file mode 100644
index 000000000000..6c81d81cf31f
--- /dev/null
+++ b/tools/include/nolibc/aarch64/crt.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * AARCH64 specific startup code for NOLIBC
+ * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
+ */
+
+#ifndef _NOLIBC_AARCH64_CRT_H
+#define _NOLIBC_AARCH64_CRT_H
+
+/* startup code */
+void __attribute__((weak, noreturn, optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
+{
+	__asm__ volatile (
+#ifdef _NOLIBC_STACKPROTECTOR
+		"bl __stack_chk_init\n"   /* initialize stack protector                     */
+#endif
+		"ldr x0, [sp]\n"     /* argc (x0) was in the stack                          */
+		"add x1, sp, 8\n"    /* argv (x1) = sp                                      */
+		"lsl x2, x0, 3\n"    /* envp (x2) = 8*argc ...                              */
+		"add x2, x2, 8\n"    /*           + 8 (skip null)                           */
+		"add x2, x2, x1\n"   /*           + argv                                    */
+		"adrp x3, environ\n"          /* x3 = &environ (high bits)                  */
+		"str x2, [x3, #:lo12:environ]\n" /* store envp into environ                 */
+		"mov x4, x2\n"       /* search for auxv (follows NULL after last env)       */
+		"0:\n"
+		"ldr x5, [x4], 8\n"  /* x5 = *x4; x4 += 8                                   */
+		"cbnz x5, 0b\n"      /* and stop at NULL after last env                     */
+		"adrp x3, _auxv\n"   /* x3 = &_auxv (high bits)                             */
+		"str x4, [x3, #:lo12:_auxv]\n" /* store x4 into _auxv                       */
+		"and sp, x1, -16\n"  /* sp must be 16-byte aligned in the callee            */
+		"bl main\n"          /* main() returns the status code, we'll exit with it. */
+		"mov x8, 93\n"       /* NR_exit == 93                                       */
+		"svc #0\n"
+	);
+	__builtin_unreachable();
+}
+#endif /* _NOLIBC_AARCH64_CRT_H */
diff --git a/tools/include/nolibc/aarch64/arch.h b/tools/include/nolibc/aarch64/sys.h
similarity index 82%
rename from tools/include/nolibc/aarch64/arch.h
rename to tools/include/nolibc/aarch64/sys.h
index 7d38da13c72b..b79d6a35ec37 100644
--- a/tools/include/nolibc/aarch64/arch.h
+++ b/tools/include/nolibc/aarch64/sys.h
@@ -1,13 +1,11 @@
 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
 /*
- * AARCH64 specific definitions for NOLIBC
+ * AARCH64 specific syscall declarations for NOLIBC
  * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
  */
 
-#ifndef _NOLIBC_AARCH64_ARCH_H
-#define _NOLIBC_AARCH64_ARCH_H
-
-#include "compiler.h"
+#ifndef _NOLIBC_AARCH64_SYS_H
+#define _NOLIBC_AARCH64_SYS_H
 
 /* The struct returned by the newfstatat() syscall. Differs slightly from the
  * x86_64's stat one by field ordering, so be careful.
@@ -171,34 +169,4 @@ struct sys_stat_struct {
 	_arg1;                                                                \
 })
 
-char **environ __attribute__((weak));
-const unsigned long *_auxv __attribute__((weak));
-
-/* startup code */
-void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
-{
-	__asm__ volatile (
-#ifdef _NOLIBC_STACKPROTECTOR
-		"bl __stack_chk_init\n"   /* initialize stack protector                     */
-#endif
-		"ldr x0, [sp]\n"     /* argc (x0) was in the stack                          */
-		"add x1, sp, 8\n"    /* argv (x1) = sp                                      */
-		"lsl x2, x0, 3\n"    /* envp (x2) = 8*argc ...                              */
-		"add x2, x2, 8\n"    /*           + 8 (skip null)                           */
-		"add x2, x2, x1\n"   /*           + argv                                    */
-		"adrp x3, environ\n"          /* x3 = &environ (high bits)                  */
-		"str x2, [x3, #:lo12:environ]\n" /* store envp into environ                 */
-		"mov x4, x2\n"       /* search for auxv (follows NULL after last env)       */
-		"0:\n"
-		"ldr x5, [x4], 8\n"  /* x5 = *x4; x4 += 8                                   */
-		"cbnz x5, 0b\n"      /* and stop at NULL after last env                     */
-		"adrp x3, _auxv\n"   /* x3 = &_auxv (high bits)                             */
-		"str x4, [x3, #:lo12:_auxv]\n" /* store x4 into _auxv                       */
-		"and sp, x1, -16\n"  /* sp must be 16-byte aligned in the callee            */
-		"bl main\n"          /* main() returns the status code, we'll exit with it. */
-		"mov x8, 93\n"       /* NR_exit == 93                                       */
-		"svc #0\n"
-	);
-	__builtin_unreachable();
-}
-#endif /* _NOLIBC_AARCH64_ARCH_H */
+#endif /* _NOLIBC_AARCH64_SYS_H */
diff --git a/tools/include/nolibc/arch.h b/tools/include/nolibc/arch.h
deleted file mode 100644
index f98616f5b219..000000000000
--- a/tools/include/nolibc/arch.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
-/*
- * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
- */
-
-/* Below comes the architecture-specific code. For each architecture, we have
- * the syscall declarations and the _start code definition. This is the only
- * global part. On all architectures the kernel puts everything in the stack
- * before jumping to _start just above us, without any return address (_start
- * is not a function but an entry point). So at the stack pointer we find argc.
- * Then argv[] begins, and ends at the first NULL. Then we have envp which
- * starts and ends with a NULL as well. So envp=argv+argc+1.
- */
-
-#ifndef _NOLIBC_ARCH_H
-#define _NOLIBC_ARCH_H
-
-#if defined(__x86_64__)
-#include "x86_64/arch.h"
-#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
-#include "i386/arch.h"
-#elif defined(__ARM_EABI__)
-#include "arm/arch.h"
-#elif defined(__aarch64__)
-#include "aarch64/arch.h"
-#elif defined(__mips__) && defined(_ABIO32)
-#include "mips/arch.h"
-#elif defined(__riscv)
-#include "riscv/arch.h"
-#elif defined(__s390x__)
-#include "s390/arch.h"
-#elif defined(__loongarch__)
-#include "loongarch/arch.h"
-#endif
-
-#endif /* _NOLIBC_ARCH_H */
diff --git a/tools/include/nolibc/arm/crt.h b/tools/include/nolibc/arm/crt.h
new file mode 100644
index 000000000000..7b3b9e21e5c4
--- /dev/null
+++ b/tools/include/nolibc/arm/crt.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * ARM specific startup code for NOLIBC
+ * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
+ */
+
+#ifndef _NOLIBC_ARM_CRT_H
+#define _NOLIBC_ARM_CRT_H
+
+/* startup code */
+void __attribute__((weak, noreturn, optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
+{
+	__asm__ volatile (
+#ifdef _NOLIBC_STACKPROTECTOR
+		"bl __stack_chk_init\n"       /* initialize stack protector                          */
+#endif
+		"pop {%r0}\n"                 /* argc was in the stack                               */
+		"mov %r1, %sp\n"              /* argv = sp                                           */
+
+		"add %r2, %r0, $1\n"          /* envp = (argc + 1) ...                               */
+		"lsl %r2, %r2, $2\n"          /*        * 4        ...                               */
+		"add %r2, %r2, %r1\n"         /*        + argv                                       */
+		"ldr %r3, 1f\n"               /* r3 = &environ (see below)                           */
+		"str %r2, [r3]\n"             /* store envp into environ                             */
+
+		"mov r4, r2\n"                /* search for auxv (follows NULL after last env)       */
+		"0:\n"
+		"mov r5, r4\n"                /* r5 = r4                                             */
+		"add r4, r4, #4\n"            /* r4 += 4                                             */
+		"ldr r5,[r5]\n"               /* r5 = *r5 = *(r4-4)                                  */
+		"cmp r5, #0\n"                /* and stop at NULL after last env                     */
+		"bne 0b\n"
+		"ldr %r3, 2f\n"               /* r3 = &_auxv (low bits)                              */
+		"str r4, [r3]\n"              /* store r4 into _auxv                                 */
+
+		"mov %r3, $8\n"               /* AAPCS : sp must be 8-byte aligned in the            */
+		"neg %r3, %r3\n"              /*         callee, and bl doesn't push (lr=pc)         */
+		"and %r3, %r3, %r1\n"         /* so we do sp = r1(=sp) & r3(=-8);                    */
+		"mov %sp, %r3\n"
+
+		"bl main\n"                   /* main() returns the status code, we'll exit with it. */
+		"movs r7, $1\n"               /* NR_exit == 1                                        */
+		"svc $0x00\n"
+		".align 2\n"                  /* below are the pointers to a few variables           */
+		"1:\n"
+		".word environ\n"
+		"2:\n"
+		".word _auxv\n"
+	);
+	__builtin_unreachable();
+}
+
+#endif /* _NOLIBC_ARM_CRT_H */
diff --git a/tools/include/nolibc/arm/arch.h b/tools/include/nolibc/arm/sys.h
similarity index 81%
rename from tools/include/nolibc/arm/arch.h
rename to tools/include/nolibc/arm/sys.h
index 473d2c000740..79173f860948 100644
--- a/tools/include/nolibc/arm/arch.h
+++ b/tools/include/nolibc/arm/sys.h
@@ -1,13 +1,11 @@
 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
 /*
- * ARM specific definitions for NOLIBC
+ * ARM specific syscall declarations for NOLIBC
  * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
  */
 
-#ifndef _NOLIBC_ARM_ARCH_H
-#define _NOLIBC_ARM_ARCH_H
-
-#include "compiler.h"
+#ifndef _NOLIBC_ARM_SYS_H
+#define _NOLIBC_ARM_SYS_H
 
 /* The struct returned by the stat() syscall, 32-bit only, the syscall returns
  * exactly 56 bytes (stops before the unused array). In big endian, the format
@@ -69,7 +67,7 @@ struct sys_stat_struct {
  *
  * Also, ARM supports the old_select syscall if newselect is not available
  */
-#define __ARCH_WANT_SYS_OLD_SELECT
+#define __SYS_WANT_SYS_OLD_SELECT
 
 #if (defined(__THUMBEB__) || defined(__THUMBEL__)) && \
     !defined(NOLIBC_OMIT_FRAME_POINTER)
@@ -220,51 +218,4 @@ struct sys_stat_struct {
 	_arg1;                                                                \
 })
 
-
-char **environ __attribute__((weak));
-const unsigned long *_auxv __attribute__((weak));
-
-/* startup code */
-void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
-{
-	__asm__ volatile (
-#ifdef _NOLIBC_STACKPROTECTOR
-		"bl __stack_chk_init\n"       /* initialize stack protector                          */
-#endif
-		"pop {%r0}\n"                 /* argc was in the stack                               */
-		"mov %r1, %sp\n"              /* argv = sp                                           */
-
-		"add %r2, %r0, $1\n"          /* envp = (argc + 1) ...                               */
-		"lsl %r2, %r2, $2\n"          /*        * 4        ...                               */
-		"add %r2, %r2, %r1\n"         /*        + argv                                       */
-		"ldr %r3, 1f\n"               /* r3 = &environ (see below)                           */
-		"str %r2, [r3]\n"             /* store envp into environ                             */
-
-		"mov r4, r2\n"                /* search for auxv (follows NULL after last env)       */
-		"0:\n"
-		"mov r5, r4\n"                /* r5 = r4                                             */
-		"add r4, r4, #4\n"            /* r4 += 4                                             */
-		"ldr r5,[r5]\n"               /* r5 = *r5 = *(r4-4)                                  */
-		"cmp r5, #0\n"                /* and stop at NULL after last env                     */
-		"bne 0b\n"
-		"ldr %r3, 2f\n"               /* r3 = &_auxv (low bits)                              */
-		"str r4, [r3]\n"              /* store r4 into _auxv                                 */
-
-		"mov %r3, $8\n"               /* AAPCS : sp must be 8-byte aligned in the            */
-		"neg %r3, %r3\n"              /*         callee, and bl doesn't push (lr=pc)         */
-		"and %r3, %r3, %r1\n"         /* so we do sp = r1(=sp) & r3(=-8);                    */
-		"mov %sp, %r3\n"
-
-		"bl main\n"                   /* main() returns the status code, we'll exit with it. */
-		"movs r7, $1\n"               /* NR_exit == 1                                        */
-		"svc $0x00\n"
-		".align 2\n"                  /* below are the pointers to a few variables           */
-		"1:\n"
-		".word environ\n"
-		"2:\n"
-		".word _auxv\n"
-	);
-	__builtin_unreachable();
-}
-
-#endif /* _NOLIBC_ARM_ARCH_H */
+#endif /* _NOLIBC_ARM_SYS_H */
diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
new file mode 100644
index 000000000000..221b7c5346ca
--- /dev/null
+++ b/tools/include/nolibc/crt.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * C Run Time support for NOLIBC
+ * Copyright (C) 2023 Zhangjin Wu <falcon@tinylab.org>
+ */
+
+#ifndef _NOLIBC_CRT_H
+#define _NOLIBC_CRT_H
+
+#include "compiler.h"
+#include "crt_arch.h"
+
+char **environ __attribute__((weak));
+const unsigned long *_auxv __attribute__((weak));
+
+#endif /* _NOLIBC_CRT_H */
diff --git a/tools/include/nolibc/crt_arch.h b/tools/include/nolibc/crt_arch.h
new file mode 100644
index 000000000000..741402557bd0
--- /dev/null
+++ b/tools/include/nolibc/crt_arch.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
+ */
+
+/* Below comes the architecture-specific code. For each architecture, we have
+ * the syscall declarations and the _start code definition. This is the global
+ * part for _start code definition.
+ */
+
+#ifndef _NOLIBC_CRT_ARCH_H
+#define _NOLIBC_CRT_ARCH_H
+
+#if defined(__x86_64__)
+#include "x86_64/crt.h"
+#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
+#include "i386/crt.h"
+#elif defined(__ARM_EABI__)
+#include "arm/crt.h"
+#elif defined(__aarch64__)
+#include "aarch64/crt.h"
+#elif defined(__mips__) && defined(_ABIO32)
+#include "mips/crt.h"
+#elif defined(__riscv)
+#include "riscv/crt.h"
+#elif defined(__s390x__)
+#include "s390/crt.h"
+#elif defined(__loongarch__)
+#include "loongarch/crt.h"
+#endif
+
+#endif /* _NOLIBC_CRT_ARCH_H */
diff --git a/tools/include/nolibc/i386/crt.h b/tools/include/nolibc/i386/crt.h
new file mode 100644
index 000000000000..0b88f7c887ae
--- /dev/null
+++ b/tools/include/nolibc/i386/crt.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * i386 specific startup code for NOLIBC
+ * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
+ */
+
+#ifndef _NOLIBC_I386_CRT_H
+#define _NOLIBC_I386_CRT_H
+
+/* 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, optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
+{
+	__asm__ volatile (
+#ifdef _NOLIBC_STACKPROTECTOR
+		"call __stack_chk_init\n"   /* initialize stack protector                    */
+#endif
+		"pop %eax\n"                /* argc   (first arg, %eax)                      */
+		"mov %esp, %ebx\n"          /* argv[] (second arg, %ebx)                     */
+		"lea 4(%ebx,%eax,4),%ecx\n" /* then a NULL then envp (third arg, %ecx)       */
+		"mov %ecx, environ\n"       /* save environ                                  */
+		"xor %ebp, %ebp\n"          /* zero the stack frame                          */
+		"mov %ecx, %edx\n"          /* search for auxv (follows NULL after last env) */
+		"0:\n"
+		"add $4, %edx\n"            /* search for auxv using edx, it follows the     */
+		"cmp -4(%edx), %ebp\n"      /* ... NULL after last env (ebp is zero here)    */
+		"jnz 0b\n"
+		"mov %edx, _auxv\n"         /* save it into _auxv                            */
+		"and $-16, %esp\n"          /* x86 ABI : esp must be 16-byte aligned before  */
+		"sub $4, %esp\n"            /* the call instruction (args are aligned)       */
+		"push %ecx\n"               /* push all registers on the stack so that we    */
+		"push %ebx\n"               /* support both regparm and plain stack modes    */
+		"push %eax\n"
+		"call main\n"               /* main() returns the status code in %eax        */
+		"mov %eax, %ebx\n"          /* retrieve exit code (32-bit int)               */
+		"movl $1, %eax\n"           /* NR_exit == 1                                  */
+		"int $0x80\n"               /* exit now                                      */
+		"hlt\n"                     /* ensure it does not                            */
+	);
+	__builtin_unreachable();
+}
+
+#endif /* _NOLIBC_I386_CRT_H */
diff --git a/tools/include/nolibc/i386/arch.h b/tools/include/nolibc/i386/sys.h
similarity index 79%
rename from tools/include/nolibc/i386/arch.h
rename to tools/include/nolibc/i386/sys.h
index 66052742763e..c626cf2b145a 100644
--- a/tools/include/nolibc/i386/arch.h
+++ b/tools/include/nolibc/i386/sys.h
@@ -1,13 +1,11 @@
 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
 /*
- * i386 specific definitions for NOLIBC
+ * i386 specific syscall declarations for NOLIBC
  * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
  */
 
-#ifndef _NOLIBC_I386_ARCH_H
-#define _NOLIBC_I386_ARCH_H
-
-#include "compiler.h"
+#ifndef _NOLIBC_I386_SYS_H
+#define _NOLIBC_I386_SYS_H
 
 /* The struct returned by the stat() syscall, 32-bit only, the syscall returns
  * exactly 56 bytes (stops before the unused array).
@@ -180,45 +178,4 @@ struct sys_stat_struct {
 	_eax;							\
 })
 
-char **environ __attribute__((weak));
-const unsigned long *_auxv __attribute__((weak));
-
-/* 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,optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
-{
-	__asm__ volatile (
-#ifdef _NOLIBC_STACKPROTECTOR
-		"call __stack_chk_init\n"   /* initialize stack protector                    */
-#endif
-		"pop %eax\n"                /* argc   (first arg, %eax)                      */
-		"mov %esp, %ebx\n"          /* argv[] (second arg, %ebx)                     */
-		"lea 4(%ebx,%eax,4),%ecx\n" /* then a NULL then envp (third arg, %ecx)       */
-		"mov %ecx, environ\n"       /* save environ                                  */
-		"xor %ebp, %ebp\n"          /* zero the stack frame                          */
-		"mov %ecx, %edx\n"          /* search for auxv (follows NULL after last env) */
-		"0:\n"
-		"add $4, %edx\n"            /* search for auxv using edx, it follows the     */
-		"cmp -4(%edx), %ebp\n"      /* ... NULL after last env (ebp is zero here)    */
-		"jnz 0b\n"
-		"mov %edx, _auxv\n"         /* save it into _auxv                            */
-		"and $-16, %esp\n"          /* x86 ABI : esp must be 16-byte aligned before  */
-		"sub $4, %esp\n"            /* the call instruction (args are aligned)       */
-		"push %ecx\n"               /* push all registers on the stack so that we    */
-		"push %ebx\n"               /* support both regparm and plain stack modes    */
-		"push %eax\n"
-		"call main\n"               /* main() returns the status code in %eax        */
-		"mov %eax, %ebx\n"          /* retrieve exit code (32-bit int)               */
-		"movl $1, %eax\n"           /* NR_exit == 1                                  */
-		"int $0x80\n"               /* exit now                                      */
-		"hlt\n"                     /* ensure it does not                            */
-	);
-	__builtin_unreachable();
-}
-
-#endif /* _NOLIBC_I386_ARCH_H */
+#endif /* _NOLIBC_I386_SYS_H */
diff --git a/tools/include/nolibc/loongarch/crt.h b/tools/include/nolibc/loongarch/crt.h
new file mode 100644
index 000000000000..253d2fccea1e
--- /dev/null
+++ b/tools/include/nolibc/loongarch/crt.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * LoongArch specific startup code for NOLIBC
+ * Copyright (C) 2023 Loongson Technology Corporation Limited
+ */
+
+#ifndef _NOLIBC_LOONGARCH_CRT_H
+#define _NOLIBC_LOONGARCH_CRT_H
+
+#if __loongarch_grlen == 32
+#define LONGLOG      "2"
+#define SZREG        "4"
+#define REG_L        "ld.w"
+#define LONG_S       "st.w"
+#define LONG_ADD     "add.w"
+#define LONG_ADDI    "addi.w"
+#define LONG_SLL     "slli.w"
+#define LONG_BSTRINS "bstrins.w"
+#else /* __loongarch_grlen == 64 */
+#define LONGLOG      "3"
+#define SZREG        "8"
+#define REG_L        "ld.d"
+#define LONG_S       "st.d"
+#define LONG_ADD     "add.d"
+#define LONG_ADDI    "addi.d"
+#define LONG_SLL     "slli.d"
+#define LONG_BSTRINS "bstrins.d"
+#endif
+
+/* startup code */
+void __attribute__((weak, noreturn, optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
+{
+	__asm__ volatile (
+#ifdef _NOLIBC_STACKPROTECTOR
+		"bl __stack_chk_init\n"               /* initialize stack protector                          */
+#endif
+		REG_L        " $a0, $sp, 0\n"         /* argc (a0) was in the stack                          */
+		LONG_ADDI    " $a1, $sp, "SZREG"\n"   /* argv (a1) = sp + SZREG                              */
+		LONG_SLL     " $a2, $a0, "LONGLOG"\n" /* envp (a2) = SZREG*argc ...                          */
+		LONG_ADDI    " $a2, $a2, "SZREG"\n"   /*             + SZREG (skip null)                     */
+		LONG_ADD     " $a2, $a2, $a1\n"       /*             + argv                                  */
+
+		"move          $a3, $a2\n"            /* iterate a3 over envp to find auxv (after NULL)      */
+		"0:\n"                                /* do {                                                */
+		REG_L        " $a4, $a3, 0\n"         /*   a4 = *a3;                                         */
+		LONG_ADDI    " $a3, $a3, "SZREG"\n"   /*   a3 += sizeof(void*);                              */
+		"bne           $a4, $zero, 0b\n"      /* } while (a4);                                       */
+		"la.pcrel      $a4, _auxv\n"          /* a4 = &_auxv                                         */
+		LONG_S       " $a3, $a4, 0\n"         /* store a3 into _auxv                                 */
+
+		"la.pcrel      $a3, environ\n"        /* a3 = &environ                                       */
+		LONG_S       " $a2, $a3, 0\n"         /* store envp(a2) into environ                         */
+		LONG_BSTRINS " $sp, $zero, 3, 0\n"    /* sp must be 16-byte aligned                          */
+		"bl            main\n"                /* main() returns the status code, we'll exit with it. */
+		"li.w          $a7, 93\n"             /* NR_exit == 93                                       */
+		"syscall       0\n"
+	);
+	__builtin_unreachable();
+}
+
+#endif /* _NOLIBC_LOONGARCH_CRT_H */
diff --git a/tools/include/nolibc/loongarch/arch.h b/tools/include/nolibc/loongarch/sys.h
similarity index 73%
rename from tools/include/nolibc/loongarch/arch.h
rename to tools/include/nolibc/loongarch/sys.h
index 63fee1e8f4d9..98d47b5823dc 100644
--- a/tools/include/nolibc/loongarch/arch.h
+++ b/tools/include/nolibc/loongarch/sys.h
@@ -1,13 +1,11 @@
 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
 /*
- * LoongArch specific definitions for NOLIBC
+ * LoongArch specific syscall declarations for NOLIBC
  * Copyright (C) 2023 Loongson Technology Corporation Limited
  */
 
-#ifndef _NOLIBC_LOONGARCH_ARCH_H
-#define _NOLIBC_LOONGARCH_ARCH_H
-
-#include "compiler.h"
+#ifndef _NOLIBC_LOONGARCH_SYS_H
+#define _NOLIBC_LOONGARCH_SYS_H
 
 /* Syscalls for LoongArch :
  *   - stack is 16-byte aligned
@@ -143,58 +141,4 @@
 	_arg1;                                                                \
 })
 
-char **environ __attribute__((weak));
-const unsigned long *_auxv __attribute__((weak));
-
-#if __loongarch_grlen == 32
-#define LONGLOG      "2"
-#define SZREG        "4"
-#define REG_L        "ld.w"
-#define LONG_S       "st.w"
-#define LONG_ADD     "add.w"
-#define LONG_ADDI    "addi.w"
-#define LONG_SLL     "slli.w"
-#define LONG_BSTRINS "bstrins.w"
-#else /* __loongarch_grlen == 64 */
-#define LONGLOG      "3"
-#define SZREG        "8"
-#define REG_L        "ld.d"
-#define LONG_S       "st.d"
-#define LONG_ADD     "add.d"
-#define LONG_ADDI    "addi.d"
-#define LONG_SLL     "slli.d"
-#define LONG_BSTRINS "bstrins.d"
-#endif
-
-/* startup code */
-void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
-{
-	__asm__ volatile (
-#ifdef _NOLIBC_STACKPROTECTOR
-		"bl __stack_chk_init\n"               /* initialize stack protector                          */
-#endif
-		REG_L        " $a0, $sp, 0\n"         /* argc (a0) was in the stack                          */
-		LONG_ADDI    " $a1, $sp, "SZREG"\n"   /* argv (a1) = sp + SZREG                              */
-		LONG_SLL     " $a2, $a0, "LONGLOG"\n" /* envp (a2) = SZREG*argc ...                          */
-		LONG_ADDI    " $a2, $a2, "SZREG"\n"   /*             + SZREG (skip null)                     */
-		LONG_ADD     " $a2, $a2, $a1\n"       /*             + argv                                  */
-
-		"move          $a3, $a2\n"            /* iterate a3 over envp to find auxv (after NULL)      */
-		"0:\n"                                /* do {                                                */
-		REG_L        " $a4, $a3, 0\n"         /*   a4 = *a3;                                         */
-		LONG_ADDI    " $a3, $a3, "SZREG"\n"   /*   a3 += sizeof(void*);                              */
-		"bne           $a4, $zero, 0b\n"      /* } while (a4);                                       */
-		"la.pcrel      $a4, _auxv\n"          /* a4 = &_auxv                                         */
-		LONG_S       " $a3, $a4, 0\n"         /* store a3 into _auxv                                 */
-
-		"la.pcrel      $a3, environ\n"        /* a3 = &environ                                       */
-		LONG_S       " $a2, $a3, 0\n"         /* store envp(a2) into environ                         */
-		LONG_BSTRINS " $sp, $zero, 3, 0\n"    /* sp must be 16-byte aligned                          */
-		"bl            main\n"                /* main() returns the status code, we'll exit with it. */
-		"li.w          $a7, 93\n"             /* NR_exit == 93                                       */
-		"syscall       0\n"
-	);
-	__builtin_unreachable();
-}
-
-#endif /* _NOLIBC_LOONGARCH_ARCH_H */
+#endif /* _NOLIBC_LOONGARCH_SYS_H */
diff --git a/tools/include/nolibc/mips/crt.h b/tools/include/nolibc/mips/crt.h
new file mode 100644
index 000000000000..38df52d8ec16
--- /dev/null
+++ b/tools/include/nolibc/mips/crt.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * MIPS specific startup code for NOLIBC
+ * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
+ */
+
+#ifndef _NOLIBC_MIPS_CRT_H
+#define _NOLIBC_MIPS_CRT_H
+
+/* startup code, note that it's called __start on MIPS */
+void __attribute__((weak, noreturn, optimize("omit-frame-pointer"))) __no_stack_protector __start(void)
+{
+	__asm__ volatile (
+		/*".set nomips16\n"*/
+		".set push\n"
+		".set    noreorder\n"
+		".option pic0\n"
+#ifdef _NOLIBC_STACKPROTECTOR
+		"jal __stack_chk_init\n" /* initialize stack protector                         */
+		"nop\n"                  /* delayed slot                                       */
+#endif
+		/*".ent __start\n"*/
+		/*"__start:\n"*/
+		"lw $a0,($sp)\n"        /* argc was in the stack                               */
+		"addiu  $a1, $sp, 4\n"  /* argv = sp + 4                                       */
+		"sll $a2, $a0, 2\n"     /* a2 = argc * 4                                       */
+		"add   $a2, $a2, $a1\n" /* envp = argv + 4*argc ...                            */
+		"addiu $a2, $a2, 4\n"   /*        ... + 4                                      */
+		"lui $a3, %hi(environ)\n"     /* load environ into a3 (hi)                     */
+		"addiu $a3, %lo(environ)\n"   /* load environ into a3 (lo)                     */
+		"sw $a2,($a3)\n"              /* store envp(a2) into environ                   */
+
+		"move $t0, $a2\n"             /* iterate t0 over envp, look for NULL           */
+		"0:"                          /* do {                                          */
+		"lw $a3, ($t0)\n"             /*   a3=*(t0);                                   */
+		"bne $a3, $0, 0b\n"           /* } while (a3);                                 */
+		"addiu $t0, $t0, 4\n"         /* delayed slot: t0+=4;                          */
+		"lui $a3, %hi(_auxv)\n"       /* load _auxv into a3 (hi)                       */
+		"addiu $a3, %lo(_auxv)\n"     /* load _auxv into a3 (lo)                       */
+		"sw $t0, ($a3)\n"             /* store t0 into _auxv                           */
+
+		"li $t0, -8\n"
+		"and $sp, $sp, $t0\n"   /* sp must be 8-byte aligned                           */
+		"addiu $sp,$sp,-16\n"   /* the callee expects to save a0..a3 there!            */
+		"jal main\n"            /* main() returns the status code, we'll exit with it. */
+		"nop\n"                 /* delayed slot                                        */
+		"move $a0, $v0\n"       /* retrieve 32-bit exit code from v0                   */
+		"li $v0, 4001\n"        /* NR_exit == 4001                                     */
+		"syscall\n"
+		/*".end __start\n"*/
+		".set pop\n"
+	);
+	__builtin_unreachable();
+}
+
+#endif /* _NOLIBC_MIPS_CRT_H */
diff --git a/tools/include/nolibc/mips/arch.h b/tools/include/nolibc/mips/sys.h
similarity index 79%
rename from tools/include/nolibc/mips/arch.h
rename to tools/include/nolibc/mips/sys.h
index 1581b721b714..13dfbf3e6a3d 100644
--- a/tools/include/nolibc/mips/arch.h
+++ b/tools/include/nolibc/mips/sys.h
@@ -1,13 +1,11 @@
 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
 /*
- * MIPS specific definitions for NOLIBC
+ * MIPS specific syscall declarations for NOLIBC
  * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
  */
 
-#ifndef _NOLIBC_MIPS_ARCH_H
-#define _NOLIBC_MIPS_ARCH_H
-
-#include "compiler.h"
+#ifndef _NOLIBC_MIPS_SYS_H
+#define _NOLIBC_MIPS_SYS_H
 
 /* The struct returned by the stat() syscall. 88 bytes are returned by the
  * syscall.
@@ -201,53 +199,4 @@ struct sys_stat_struct {
 	_arg4 ? -_num : _num;                                                 \
 })
 
-char **environ __attribute__((weak));
-const unsigned long *_auxv __attribute__((weak));
-
-/* startup code, note that it's called __start on MIPS */
-void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_protector __start(void)
-{
-	__asm__ volatile (
-		/*".set nomips16\n"*/
-		".set push\n"
-		".set    noreorder\n"
-		".option pic0\n"
-#ifdef _NOLIBC_STACKPROTECTOR
-		"jal __stack_chk_init\n" /* initialize stack protector                         */
-		"nop\n"                  /* delayed slot                                       */
-#endif
-		/*".ent __start\n"*/
-		/*"__start:\n"*/
-		"lw $a0,($sp)\n"        /* argc was in the stack                               */
-		"addiu  $a1, $sp, 4\n"  /* argv = sp + 4                                       */
-		"sll $a2, $a0, 2\n"     /* a2 = argc * 4                                       */
-		"add   $a2, $a2, $a1\n" /* envp = argv + 4*argc ...                            */
-		"addiu $a2, $a2, 4\n"   /*        ... + 4                                      */
-		"lui $a3, %hi(environ)\n"     /* load environ into a3 (hi)                     */
-		"addiu $a3, %lo(environ)\n"   /* load environ into a3 (lo)                     */
-		"sw $a2,($a3)\n"              /* store envp(a2) into environ                   */
-
-		"move $t0, $a2\n"             /* iterate t0 over envp, look for NULL           */
-		"0:"                          /* do {                                          */
-		"lw $a3, ($t0)\n"             /*   a3=*(t0);                                   */
-		"bne $a3, $0, 0b\n"           /* } while (a3);                                 */
-		"addiu $t0, $t0, 4\n"         /* delayed slot: t0+=4;                          */
-		"lui $a3, %hi(_auxv)\n"       /* load _auxv into a3 (hi)                       */
-		"addiu $a3, %lo(_auxv)\n"     /* load _auxv into a3 (lo)                       */
-		"sw $t0, ($a3)\n"             /* store t0 into _auxv                           */
-
-		"li $t0, -8\n"
-		"and $sp, $sp, $t0\n"   /* sp must be 8-byte aligned                           */
-		"addiu $sp,$sp,-16\n"   /* the callee expects to save a0..a3 there!            */
-		"jal main\n"            /* main() returns the status code, we'll exit with it. */
-		"nop\n"                 /* delayed slot                                        */
-		"move $a0, $v0\n"       /* retrieve 32-bit exit code from v0                   */
-		"li $v0, 4001\n"        /* NR_exit == 4001                                     */
-		"syscall\n"
-		/*".end __start\n"*/
-		".set pop\n"
-	);
-	__builtin_unreachable();
-}
-
-#endif /* _NOLIBC_MIPS_ARCH_H */
+#endif /* _NOLIBC_MIPS_SYS_H */
diff --git a/tools/include/nolibc/nolibc.h b/tools/include/nolibc/nolibc.h
index 1f8d821000ac..096a18b71923 100644
--- a/tools/include/nolibc/nolibc.h
+++ b/tools/include/nolibc/nolibc.h
@@ -93,8 +93,8 @@
 #define _NOLIBC_H
 
 #include "std.h"
-#include "arch.h"
 #include "types.h"
+#include "crt.h"
 #include "sys.h"
 #include "ctype.h"
 #include "signal.h"
diff --git a/tools/include/nolibc/riscv/crt.h b/tools/include/nolibc/riscv/crt.h
new file mode 100644
index 000000000000..1f81a2e47a48
--- /dev/null
+++ b/tools/include/nolibc/riscv/crt.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * RISCV (32 and 64) specific startup code for NOLIBC
+ * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
+ */
+
+#ifndef _NOLIBC_RISCV_CRT_H
+#define _NOLIBC_RISCV_CRT_H
+
+#if   __riscv_xlen == 64
+#define PTRLOG "3"
+#define SZREG  "8"
+#define REG_L  "ld"
+#define REG_S  "sd"
+#elif __riscv_xlen == 32
+#define PTRLOG "2"
+#define SZREG  "4"
+#define REG_L  "lw"
+#define REG_S  "sw"
+#endif
+
+/* startup code */
+void __attribute__((weak, noreturn, optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
+{
+	__asm__ volatile (
+		".option push\n"
+		".option norelax\n"
+		"lla   gp, __global_pointer$\n"
+		".option pop\n"
+#ifdef _NOLIBC_STACKPROTECTOR
+		"call __stack_chk_init\n"    /* initialize stack protector                          */
+#endif
+		REG_L" a0, 0(sp)\n"          /* argc (a0) was in the stack                          */
+		"add   a1, sp, "SZREG"\n"    /* argv (a1) = sp                                      */
+		"slli  a2, a0, "PTRLOG"\n"   /* envp (a2) = SZREG*argc ...                          */
+		"add   a2, a2, "SZREG"\n"    /*             + SZREG (skip null)                     */
+		"add   a2,a2,a1\n"           /*             + argv                                  */
+
+		"add   a3, a2, zero\n"       /* iterate a3 over envp to find auxv (after NULL)      */
+		"0:\n"                       /* do {                                                */
+		REG_L" a4, 0(a3)\n"          /*   a4 = *a3;                                         */
+		"add   a3, a3, "SZREG"\n"    /*   a3 += sizeof(void*);                              */
+		"bne   a4, zero, 0b\n"       /* } while (a4);                                       */
+		"lui   a4, %hi(_auxv)\n"     /* a4 = &_auxv (high bits)                             */
+		REG_S" a3, %lo(_auxv)(a4)\n" /* store a3 into _auxv                                 */
+
+		"lui   a3, %hi(environ)\n"   /* a3 = &environ (high bits)                           */
+		REG_S" a2,%lo(environ)(a3)\n"/* store envp(a2) into environ                         */
+		"andi  sp,a1,-16\n"          /* sp must be 16-byte aligned                          */
+		"call  main\n"               /* main() returns the status code, we'll exit with it. */
+		"li a7, 93\n"                /* NR_exit == 93                                       */
+		"ecall\n"
+	);
+	__builtin_unreachable();
+}
+
+#endif /* _NOLIBC_RISCV_CRT_H */
diff --git a/tools/include/nolibc/riscv/arch.h b/tools/include/nolibc/riscv/sys.h
similarity index 78%
rename from tools/include/nolibc/riscv/arch.h
rename to tools/include/nolibc/riscv/sys.h
index de68759f5959..aa15b86c919f 100644
--- a/tools/include/nolibc/riscv/arch.h
+++ b/tools/include/nolibc/riscv/sys.h
@@ -1,13 +1,11 @@
 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
 /*
- * RISCV (32 and 64) specific definitions for NOLIBC
+ * RISCV (32 and 64) specific syscall declarations for NOLIBC
  * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
  */
 
-#ifndef _NOLIBC_RISCV_ARCH_H
-#define _NOLIBC_RISCV_ARCH_H
-
-#include "compiler.h"
+#ifndef _NOLIBC_RISCV_SYS_H
+#define _NOLIBC_RISCV_SYS_H
 
 struct sys_stat_struct {
 	unsigned long	st_dev;		/* Device.  */
@@ -32,18 +30,6 @@ struct sys_stat_struct {
 	unsigned int	__unused5;
 };
 
-#if   __riscv_xlen == 64
-#define PTRLOG "3"
-#define SZREG  "8"
-#define REG_L  "ld"
-#define REG_S  "sd"
-#elif __riscv_xlen == 32
-#define PTRLOG "2"
-#define SZREG  "4"
-#define REG_L  "lw"
-#define REG_S  "sw"
-#endif
-
 /* Syscalls for RISCV :
  *   - stack is 16-byte aligned
  *   - syscall number is passed in a7
@@ -176,42 +162,4 @@ struct sys_stat_struct {
 	_arg1;                                                                \
 })
 
-char **environ __attribute__((weak));
-const unsigned long *_auxv __attribute__((weak));
-
-/* startup code */
-void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
-{
-	__asm__ volatile (
-		".option push\n"
-		".option norelax\n"
-		"lla   gp, __global_pointer$\n"
-		".option pop\n"
-#ifdef _NOLIBC_STACKPROTECTOR
-		"call __stack_chk_init\n"    /* initialize stack protector                          */
-#endif
-		REG_L" a0, 0(sp)\n"          /* argc (a0) was in the stack                          */
-		"add   a1, sp, "SZREG"\n"    /* argv (a1) = sp                                      */
-		"slli  a2, a0, "PTRLOG"\n"   /* envp (a2) = SZREG*argc ...                          */
-		"add   a2, a2, "SZREG"\n"    /*             + SZREG (skip null)                     */
-		"add   a2,a2,a1\n"           /*             + argv                                  */
-
-		"add   a3, a2, zero\n"       /* iterate a3 over envp to find auxv (after NULL)      */
-		"0:\n"                       /* do {                                                */
-		REG_L" a4, 0(a3)\n"          /*   a4 = *a3;                                         */
-		"add   a3, a3, "SZREG"\n"    /*   a3 += sizeof(void*);                              */
-		"bne   a4, zero, 0b\n"       /* } while (a4);                                       */
-		"lui   a4, %hi(_auxv)\n"     /* a4 = &_auxv (high bits)                             */
-		REG_S" a3, %lo(_auxv)(a4)\n" /* store a3 into _auxv                                 */
-
-		"lui   a3, %hi(environ)\n"   /* a3 = &environ (high bits)                           */
-		REG_S" a2,%lo(environ)(a3)\n"/* store envp(a2) into environ                         */
-		"andi  sp,a1,-16\n"          /* sp must be 16-byte aligned                          */
-		"call  main\n"               /* main() returns the status code, we'll exit with it. */
-		"li a7, 93\n"                /* NR_exit == 93                                       */
-		"ecall\n"
-	);
-	__builtin_unreachable();
-}
-
-#endif /* _NOLIBC_RISCV_ARCH_H */
+#endif /* _NOLIBC_RISCV_SYS_H */
diff --git a/tools/include/nolibc/s390/crt.h b/tools/include/nolibc/s390/crt.h
new file mode 100644
index 000000000000..8580f615d525
--- /dev/null
+++ b/tools/include/nolibc/s390/crt.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * s390 specific startup code for NOLIBC
+ */
+
+#ifndef _NOLIBC_S390_CRT_H
+#define _NOLIBC_S390_CRT_H
+
+/* startup code */
+void __attribute__((weak, noreturn, optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
+{
+	__asm__ volatile (
+		"lg	%r2,0(%r15)\n"		/* argument count */
+		"la	%r3,8(%r15)\n"		/* argument pointers */
+
+		"xgr	%r0,%r0\n"		/* r0 will be our NULL value */
+		/* search for envp */
+		"lgr	%r4,%r3\n"		/* start at argv */
+		"0:\n"
+		"clg	%r0,0(%r4)\n"		/* entry zero? */
+		"la	%r4,8(%r4)\n"		/* advance pointer */
+		"jnz	0b\n"			/* no -> test next pointer */
+						/* yes -> r4 now contains start of envp */
+		"larl	%r1,environ\n"
+		"stg	%r4,0(%r1)\n"
+
+		/* search for auxv */
+		"lgr	%r5,%r4\n"		/* start at envp */
+		"1:\n"
+		"clg	%r0,0(%r5)\n"		/* entry zero? */
+		"la	%r5,8(%r5)\n"		/* advance pointer */
+		"jnz	1b\n"			/* no -> test next pointer */
+		"larl	%r1,_auxv\n"		/* yes -> store value in _auxv */
+		"stg	%r5,0(%r1)\n"
+
+		"aghi	%r15,-160\n"		/* allocate new stackframe */
+		"xc	0(8,%r15),0(%r15)\n"	/* clear backchain */
+		"brasl	%r14,main\n"		/* ret value of main is arg to exit */
+		"lghi	%r1,1\n"		/* __NR_exit */
+		"svc	0\n"
+	);
+	__builtin_unreachable();
+}
+
+#endif /* _NOLIBC_S390_CRT_H */
diff --git a/tools/include/nolibc/s390/arch.h b/tools/include/nolibc/s390/sys.h
similarity index 78%
rename from tools/include/nolibc/s390/arch.h
rename to tools/include/nolibc/s390/sys.h
index a7b512e81234..041f4ecb7922 100644
--- a/tools/include/nolibc/s390/arch.h
+++ b/tools/include/nolibc/s390/sys.h
@@ -1,15 +1,13 @@
 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
 /*
- * s390 specific definitions for NOLIBC
+ * s390 specific syscall declarations for NOLIBC
  */
 
-#ifndef _NOLIBC_S390_ARCH_H
-#define _NOLIBC_S390_ARCH_H
+#ifndef _NOLIBC_S390_SYS_H
+#define _NOLIBC_S390_SYS_H
 #include <asm/signal.h>
 #include <asm/unistd.h>
 
-#include "compiler.h"
-
 /* The struct returned by the stat() syscall, equivalent to stat64(). The
  * syscall returns 116 bytes and stops in the middle of __unused.
  */
@@ -162,45 +160,6 @@ struct sys_stat_struct {
 	_arg1;								\
 })
 
-char **environ __attribute__((weak));
-const unsigned long *_auxv __attribute__((weak));
-
-/* startup code */
-void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
-{
-	__asm__ volatile (
-		"lg	%r2,0(%r15)\n"		/* argument count */
-		"la	%r3,8(%r15)\n"		/* argument pointers */
-
-		"xgr	%r0,%r0\n"		/* r0 will be our NULL value */
-		/* search for envp */
-		"lgr	%r4,%r3\n"		/* start at argv */
-		"0:\n"
-		"clg	%r0,0(%r4)\n"		/* entry zero? */
-		"la	%r4,8(%r4)\n"		/* advance pointer */
-		"jnz	0b\n"			/* no -> test next pointer */
-						/* yes -> r4 now contains start of envp */
-		"larl	%r1,environ\n"
-		"stg	%r4,0(%r1)\n"
-
-		/* search for auxv */
-		"lgr	%r5,%r4\n"		/* start at envp */
-		"1:\n"
-		"clg	%r0,0(%r5)\n"		/* entry zero? */
-		"la	%r5,8(%r5)\n"		/* advance pointer */
-		"jnz	1b\n"			/* no -> test next pointer */
-		"larl	%r1,_auxv\n"		/* yes -> store value in _auxv */
-		"stg	%r5,0(%r1)\n"
-
-		"aghi	%r15,-160\n"		/* allocate new stackframe */
-		"xc	0(8,%r15),0(%r15)\n"	/* clear backchain */
-		"brasl	%r14,main\n"		/* ret value of main is arg to exit */
-		"lghi	%r1,1\n"		/* __NR_exit */
-		"svc	0\n"
-	);
-	__builtin_unreachable();
-}
-
 struct s390_mmap_arg_struct {
 	unsigned long addr;
 	unsigned long len;
@@ -234,4 +193,4 @@ pid_t sys_fork(void)
 }
 #define sys_fork sys_fork
 
-#endif /* _NOLIBC_S390_ARCH_H */
+#endif /* _NOLIBC_S390_SYS_H */
diff --git a/tools/include/nolibc/signal.h b/tools/include/nolibc/signal.h
index 137552216e46..687c4c13a1d9 100644
--- a/tools/include/nolibc/signal.h
+++ b/tools/include/nolibc/signal.h
@@ -8,7 +8,6 @@
 #define _NOLIBC_SIGNAL_H
 
 #include "std.h"
-#include "arch.h"
 #include "types.h"
 #include "sys.h"
 
diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h
index 0eef91daf289..ee5b3f3b79e6 100644
--- a/tools/include/nolibc/stdio.h
+++ b/tools/include/nolibc/stdio.h
@@ -10,7 +10,6 @@
 #include <stdarg.h>
 
 #include "std.h"
-#include "arch.h"
 #include "errno.h"
 #include "types.h"
 #include "sys.h"
diff --git a/tools/include/nolibc/stdlib.h b/tools/include/nolibc/stdlib.h
index 902162f80337..2f9b4b3c6d26 100644
--- a/tools/include/nolibc/stdlib.h
+++ b/tools/include/nolibc/stdlib.h
@@ -8,8 +8,8 @@
 #define _NOLIBC_STDLIB_H
 
 #include "std.h"
-#include "arch.h"
 #include "types.h"
+#include "crt.h"
 #include "sys.h"
 #include "string.h"
 #include <linux/auxvec.h>
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index dee56894a811..e84ed57f3a63 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -23,7 +23,7 @@
 #include <linux/stat.h>  /* for statx() */
 #include <linux/prctl.h>
 
-#include "arch.h"
+#include "sys_arch.h"
 #include "errno.h"
 #include "types.h"
 
diff --git a/tools/include/nolibc/sys_arch.h b/tools/include/nolibc/sys_arch.h
new file mode 100644
index 000000000000..b073051c7713
--- /dev/null
+++ b/tools/include/nolibc/sys_arch.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
+ */
+
+/* Below comes the architecture-specific code. For each architecture, we have
+ * the syscall declarations and the _start code definition. This is the global
+ * part for syscall declarations.
+ */
+
+#ifndef _NOLIBC_SYS_ARCH_H
+#define _NOLIBC_SYS_ARCH_H
+
+#if defined(__x86_64__)
+#include "x86_64/sys.h"
+#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
+#include "i386/sys.h"
+#elif defined(__ARM_EABI__)
+#include "arm/sys.h"
+#elif defined(__aarch64__)
+#include "aarch64/sys.h"
+#elif defined(__mips__) && defined(_ABIO32)
+#include "mips/sys.h"
+#elif defined(__riscv)
+#include "riscv/sys.h"
+#elif defined(__s390x__)
+#include "s390/sys.h"
+#elif defined(__loongarch__)
+#include "loongarch/sys.h"
+#endif
+
+#endif /* _NOLIBC_SYS_ARCH_H */
diff --git a/tools/include/nolibc/time.h b/tools/include/nolibc/time.h
index 84655361b9ad..127ac60706b2 100644
--- a/tools/include/nolibc/time.h
+++ b/tools/include/nolibc/time.h
@@ -8,7 +8,6 @@
 #define _NOLIBC_TIME_H
 
 #include "std.h"
-#include "arch.h"
 #include "types.h"
 #include "sys.h"
 
diff --git a/tools/include/nolibc/unistd.h b/tools/include/nolibc/unistd.h
index e38f3660c051..219cc5ea319a 100644
--- a/tools/include/nolibc/unistd.h
+++ b/tools/include/nolibc/unistd.h
@@ -8,7 +8,6 @@
 #define _NOLIBC_UNISTD_H
 
 #include "std.h"
-#include "arch.h"
 #include "types.h"
 #include "sys.h"
 
diff --git a/tools/include/nolibc/x86_64/crt.h b/tools/include/nolibc/x86_64/crt.h
new file mode 100644
index 000000000000..6fede1235efc
--- /dev/null
+++ b/tools/include/nolibc/x86_64/crt.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * x86_64 specific startup code for NOLIBC
+ * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
+ */
+
+#ifndef _NOLIBC_X86_64_CRT_H
+#define _NOLIBC_X86_64_CRT_H
+
+/* startup code */
+/*
+ * x86-64 System V ABI mandates:
+ * 1) %rsp must be 16-byte aligned right before the function call.
+ * 2) The deepest stack frame should be zero (the %rbp).
+ *
+ */
+void __attribute__((weak, noreturn, optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
+{
+	__asm__ volatile (
+#ifdef _NOLIBC_STACKPROTECTOR
+		"call __stack_chk_init\n"   /* initialize stack protector                          */
+#endif
+		"pop %rdi\n"                /* argc   (first arg, %rdi)                            */
+		"mov %rsp, %rsi\n"          /* argv[] (second arg, %rsi)                           */
+		"lea 8(%rsi,%rdi,8),%rdx\n" /* then a NULL then envp (third arg, %rdx)             */
+		"mov %rdx, environ\n"       /* save environ                                        */
+		"xor %ebp, %ebp\n"          /* zero the stack frame                                */
+		"mov %rdx, %rax\n"          /* search for auxv (follows NULL after last env)       */
+		"0:\n"
+		"add $8, %rax\n"            /* search for auxv using rax, it follows the           */
+		"cmp -8(%rax), %rbp\n"      /* ... NULL after last env (rbp is zero here)          */
+		"jnz 0b\n"
+		"mov %rax, _auxv\n"         /* save it into _auxv                                  */
+		"and $-16, %rsp\n"          /* x86 ABI : esp must be 16-byte aligned before call   */
+		"call main\n"               /* main() returns the status code, we'll exit with it. */
+		"mov %eax, %edi\n"          /* retrieve exit code (32 bit)                         */
+		"mov $60, %eax\n"           /* NR_exit == 60                                       */
+		"syscall\n"                 /* really exit                                         */
+		"hlt\n"                     /* ensure it does not return                           */
+	);
+	__builtin_unreachable();
+}
+
+#endif /* _NOLIBC_X86_64_CRT_H */
diff --git a/tools/include/nolibc/x86_64/arch.h b/tools/include/nolibc/x86_64/sys.h
similarity index 81%
rename from tools/include/nolibc/x86_64/arch.h
rename to tools/include/nolibc/x86_64/sys.h
index 602791c3461a..c761c97dccf8 100644
--- a/tools/include/nolibc/x86_64/arch.h
+++ b/tools/include/nolibc/x86_64/sys.h
@@ -1,13 +1,11 @@
 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
 /*
- * x86_64 specific definitions for NOLIBC
+ * x86_64 specific syscall declarations for NOLIBC
  * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
  */
 
-#ifndef _NOLIBC_X86_64_ARCH_H
-#define _NOLIBC_X86_64_ARCH_H
-
-#include "compiler.h"
+#ifndef _NOLIBC_X86_64_SYS_H
+#define _NOLIBC_X86_64_SYS_H
 
 /* The struct returned by the stat() syscall, equivalent to stat64(). The
  * syscall returns 116 bytes and stops in the middle of __unused.
@@ -180,41 +178,4 @@ struct sys_stat_struct {
 	_ret;                                                                 \
 })
 
-char **environ __attribute__((weak));
-const unsigned long *_auxv __attribute__((weak));
-
-/* startup code */
-/*
- * x86-64 System V ABI mandates:
- * 1) %rsp must be 16-byte aligned right before the function call.
- * 2) The deepest stack frame should be zero (the %rbp).
- *
- */
-void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
-{
-	__asm__ volatile (
-#ifdef _NOLIBC_STACKPROTECTOR
-		"call __stack_chk_init\n"   /* initialize stack protector                          */
-#endif
-		"pop %rdi\n"                /* argc   (first arg, %rdi)                            */
-		"mov %rsp, %rsi\n"          /* argv[] (second arg, %rsi)                           */
-		"lea 8(%rsi,%rdi,8),%rdx\n" /* then a NULL then envp (third arg, %rdx)             */
-		"mov %rdx, environ\n"       /* save environ                                        */
-		"xor %ebp, %ebp\n"          /* zero the stack frame                                */
-		"mov %rdx, %rax\n"          /* search for auxv (follows NULL after last env)       */
-		"0:\n"
-		"add $8, %rax\n"            /* search for auxv using rax, it follows the           */
-		"cmp -8(%rax), %rbp\n"      /* ... NULL after last env (rbp is zero here)          */
-		"jnz 0b\n"
-		"mov %rax, _auxv\n"         /* save it into _auxv                                  */
-		"and $-16, %rsp\n"          /* x86 ABI : esp must be 16-byte aligned before call   */
-		"call main\n"               /* main() returns the status code, we'll exit with it. */
-		"mov %eax, %edi\n"          /* retrieve exit code (32 bit)                         */
-		"mov $60, %eax\n"           /* NR_exit == 60                                       */
-		"syscall\n"                 /* really exit                                         */
-		"hlt\n"                     /* ensure it does not return                           */
-	);
-	__builtin_unreachable();
-}
-
-#endif /* _NOLIBC_X86_64_ARCH_H */
+#endif /* _NOLIBC_X86_64_SYS_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 03/12] tools/nolibc: sys.h: remove the old sys_stat support
  2023-07-08 15:25 [PATCH v2 00/12] tools/nolibc: shrink arch support Zhangjin Wu
  2023-07-08 15:26 ` [PATCH v2 01/12] tools/nolibc: rename arch-<ARCH>.h to <ARCH>/arch.h Zhangjin Wu
  2023-07-08 15:27 ` [PATCH v2 02/12] tools/nolibc: split arch.h to crt.h and sys.h Zhangjin Wu
@ 2023-07-08 15:28 ` Zhangjin Wu
  2023-07-08 15:29 ` [PATCH v2 04/12] tools/nolibc: crt.h: add _start_c Zhangjin Wu
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-08 15:28 UTC (permalink / raw)
  To: w; +Cc: falcon, arnd, linux-kernel, linux-kselftest, thomas

__NR_statx has been added from v4.10:

    commit a528d35e8bfc ("statx: Add a system call to make enhanced file info available")

It has been supported by all of the platforms since at least from v4.20
and glibc 2.28.

Let's remove the old arch related and dependent sys_stat support
completely.

This is friendly to the future new architecture porting.

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/aarch64/sys.h | 28 -------------
 tools/include/nolibc/arm/sys.h     | 37 ------------------
 tools/include/nolibc/i386/sys.h    | 26 ------------
 tools/include/nolibc/mips/sys.h    | 28 -------------
 tools/include/nolibc/riscv/sys.h   | 23 -----------
 tools/include/nolibc/s390/sys.h    | 25 ------------
 tools/include/nolibc/sys.h         | 63 ++++++------------------------
 tools/include/nolibc/types.h       |  4 +-
 tools/include/nolibc/x86_64/sys.h  | 27 -------------
 9 files changed, 13 insertions(+), 248 deletions(-)

diff --git a/tools/include/nolibc/aarch64/sys.h b/tools/include/nolibc/aarch64/sys.h
index b79d6a35ec37..43df164b8796 100644
--- a/tools/include/nolibc/aarch64/sys.h
+++ b/tools/include/nolibc/aarch64/sys.h
@@ -7,34 +7,6 @@
 #ifndef _NOLIBC_AARCH64_SYS_H
 #define _NOLIBC_AARCH64_SYS_H
 
-/* The struct returned by the newfstatat() syscall. Differs slightly from the
- * x86_64's stat one by field ordering, so be careful.
- */
-struct sys_stat_struct {
-	unsigned long   st_dev;
-	unsigned long   st_ino;
-	unsigned int    st_mode;
-	unsigned int    st_nlink;
-	unsigned int    st_uid;
-	unsigned int    st_gid;
-
-	unsigned long   st_rdev;
-	unsigned long   __pad1;
-	long            st_size;
-	int             st_blksize;
-	int             __pad2;
-
-	long            st_blocks;
-	long            st_atime;
-	unsigned long   st_atime_nsec;
-	long            st_mtime;
-
-	unsigned long   st_mtime_nsec;
-	long            st_ctime;
-	unsigned long   st_ctime_nsec;
-	unsigned int    __unused[2];
-};
-
 /* Syscalls for AARCH64 :
  *   - registers are 64-bit
  *   - stack is 16-byte aligned
diff --git a/tools/include/nolibc/arm/sys.h b/tools/include/nolibc/arm/sys.h
index 79173f860948..db8846ff3eda 100644
--- a/tools/include/nolibc/arm/sys.h
+++ b/tools/include/nolibc/arm/sys.h
@@ -7,43 +7,6 @@
 #ifndef _NOLIBC_ARM_SYS_H
 #define _NOLIBC_ARM_SYS_H
 
-/* The struct returned by the stat() syscall, 32-bit only, the syscall returns
- * exactly 56 bytes (stops before the unused array). In big endian, the format
- * differs as devices are returned as short only.
- */
-struct sys_stat_struct {
-#if defined(__ARMEB__)
-	unsigned short st_dev;
-	unsigned short __pad1;
-#else
-	unsigned long  st_dev;
-#endif
-	unsigned long  st_ino;
-	unsigned short st_mode;
-	unsigned short st_nlink;
-	unsigned short st_uid;
-	unsigned short st_gid;
-
-#if defined(__ARMEB__)
-	unsigned short st_rdev;
-	unsigned short __pad2;
-#else
-	unsigned long  st_rdev;
-#endif
-	unsigned long  st_size;
-	unsigned long  st_blksize;
-	unsigned long  st_blocks;
-
-	unsigned long  st_atime;
-	unsigned long  st_atime_nsec;
-	unsigned long  st_mtime;
-	unsigned long  st_mtime_nsec;
-
-	unsigned long  st_ctime;
-	unsigned long  st_ctime_nsec;
-	unsigned long  __unused[2];
-};
-
 /* Syscalls for ARM in ARM or Thumb modes :
  *   - registers are 32-bit
  *   - stack is 8-byte aligned
diff --git a/tools/include/nolibc/i386/sys.h b/tools/include/nolibc/i386/sys.h
index c626cf2b145a..d2d0eeccb8fc 100644
--- a/tools/include/nolibc/i386/sys.h
+++ b/tools/include/nolibc/i386/sys.h
@@ -7,32 +7,6 @@
 #ifndef _NOLIBC_I386_SYS_H
 #define _NOLIBC_I386_SYS_H
 
-/* The struct returned by the stat() syscall, 32-bit only, the syscall returns
- * exactly 56 bytes (stops before the unused array).
- */
-struct sys_stat_struct {
-	unsigned long  st_dev;
-	unsigned long  st_ino;
-	unsigned short st_mode;
-	unsigned short st_nlink;
-	unsigned short st_uid;
-	unsigned short st_gid;
-
-	unsigned long  st_rdev;
-	unsigned long  st_size;
-	unsigned long  st_blksize;
-	unsigned long  st_blocks;
-
-	unsigned long  st_atime;
-	unsigned long  st_atime_nsec;
-	unsigned long  st_mtime;
-	unsigned long  st_mtime_nsec;
-
-	unsigned long  st_ctime;
-	unsigned long  st_ctime_nsec;
-	unsigned long  __unused[2];
-};
-
 /* Syscalls for i386 :
  *   - mostly similar to x86_64
  *   - registers are 32-bit
diff --git a/tools/include/nolibc/mips/sys.h b/tools/include/nolibc/mips/sys.h
index 13dfbf3e6a3d..c3c245682e5d 100644
--- a/tools/include/nolibc/mips/sys.h
+++ b/tools/include/nolibc/mips/sys.h
@@ -7,34 +7,6 @@
 #ifndef _NOLIBC_MIPS_SYS_H
 #define _NOLIBC_MIPS_SYS_H
 
-/* The struct returned by the stat() syscall. 88 bytes are returned by the
- * syscall.
- */
-struct sys_stat_struct {
-	unsigned int  st_dev;
-	long          st_pad1[3];
-	unsigned long st_ino;
-	unsigned int  st_mode;
-	unsigned int  st_nlink;
-	unsigned int  st_uid;
-	unsigned int  st_gid;
-	unsigned int  st_rdev;
-	long          st_pad2[2];
-	long          st_size;
-	long          st_pad3;
-
-	long          st_atime;
-	long          st_atime_nsec;
-	long          st_mtime;
-	long          st_mtime_nsec;
-
-	long          st_ctime;
-	long          st_ctime_nsec;
-	long          st_blksize;
-	long          st_blocks;
-	long          st_pad4[14];
-};
-
 /* Syscalls for MIPS ABI O32 :
  *   - WARNING! there's always a delayed slot!
  *   - WARNING again, the syntax is different, registers take a '$' and numbers
diff --git a/tools/include/nolibc/riscv/sys.h b/tools/include/nolibc/riscv/sys.h
index aa15b86c919f..682bf9c0165b 100644
--- a/tools/include/nolibc/riscv/sys.h
+++ b/tools/include/nolibc/riscv/sys.h
@@ -7,29 +7,6 @@
 #ifndef _NOLIBC_RISCV_SYS_H
 #define _NOLIBC_RISCV_SYS_H
 
-struct sys_stat_struct {
-	unsigned long	st_dev;		/* Device.  */
-	unsigned long	st_ino;		/* File serial number.  */
-	unsigned int	st_mode;	/* File mode.  */
-	unsigned int	st_nlink;	/* Link count.  */
-	unsigned int	st_uid;		/* User ID of the file's owner.  */
-	unsigned int	st_gid;		/* Group ID of the file's group. */
-	unsigned long	st_rdev;	/* Device number, if device.  */
-	unsigned long	__pad1;
-	long		st_size;	/* Size of file, in bytes.  */
-	int		st_blksize;	/* Optimal block size for I/O.  */
-	int		__pad2;
-	long		st_blocks;	/* Number 512-byte blocks allocated. */
-	long		st_atime;	/* Time of last access.  */
-	unsigned long	st_atime_nsec;
-	long		st_mtime;	/* Time of last modification.  */
-	unsigned long	st_mtime_nsec;
-	long		st_ctime;	/* Time of last status change.  */
-	unsigned long	st_ctime_nsec;
-	unsigned int	__unused4;
-	unsigned int	__unused5;
-};
-
 /* Syscalls for RISCV :
  *   - stack is 16-byte aligned
  *   - syscall number is passed in a7
diff --git a/tools/include/nolibc/s390/sys.h b/tools/include/nolibc/s390/sys.h
index 041f4ecb7922..4373c4dc1e8a 100644
--- a/tools/include/nolibc/s390/sys.h
+++ b/tools/include/nolibc/s390/sys.h
@@ -8,31 +8,6 @@
 #include <asm/signal.h>
 #include <asm/unistd.h>
 
-/* The struct returned by the stat() syscall, equivalent to stat64(). The
- * syscall returns 116 bytes and stops in the middle of __unused.
- */
-
-struct sys_stat_struct {
-	unsigned long	st_dev;
-	unsigned long	st_ino;
-	unsigned long	st_nlink;
-	unsigned int	st_mode;
-	unsigned int	st_uid;
-	unsigned int	st_gid;
-	unsigned int	__pad1;
-	unsigned long	st_rdev;
-	unsigned long	st_size;
-	unsigned long	st_atime;
-	unsigned long	st_atime_nsec;
-	unsigned long	st_mtime;
-	unsigned long	st_mtime_nsec;
-	unsigned long	st_ctime;
-	unsigned long	st_ctime_nsec;
-	unsigned long	st_blksize;
-	long		st_blocks;
-	unsigned long	__unused[3];
-};
-
 /* Syscalls for s390:
  *   - registers are 64-bit
  *   - syscall number is passed in r1
diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index e84ed57f3a63..8c7fc9f5abd1 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -943,15 +943,19 @@ pid_t setsid(void)
 	return __sysret(sys_setsid());
 }
 
-#if defined(__NR_statx)
 /*
  * int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf);
+ * int stat(const char *path, struct stat *buf);
  */
 
 static __attribute__((unused))
 int sys_statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf)
 {
+#ifdef __NR_statx
 	return my_syscall5(__NR_statx, fd, path, flags, mask, buf);
+#else
+	return -ENOSYS;
+#endif
 }
 
 static __attribute__((unused))
@@ -959,24 +963,18 @@ int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *
 {
 	return __sysret(sys_statx(fd, path, flags, mask, buf));
 }
-#endif
 
-/*
- * int stat(const char *path, struct stat *buf);
- * Warning: the struct stat's layout is arch-dependent.
- */
 
-#if defined(__NR_statx) && !defined(__NR_newfstatat) && !defined(__NR_stat)
-/*
- * Maybe we can just use statx() when available for all architectures?
- */
 static __attribute__((unused))
-int sys_stat(const char *path, struct stat *buf)
+int stat(const char *path, struct stat *buf)
 {
 	struct statx statx;
 	long ret;
 
-	ret = sys_statx(AT_FDCWD, path, AT_NO_AUTOMOUNT, STATX_BASIC_STATS, &statx);
+	ret = __sysret(sys_statx(AT_FDCWD, path, AT_NO_AUTOMOUNT, STATX_BASIC_STATS, &statx));
+	if (ret == -1)
+		return ret;
+
 	buf->st_dev          = ((statx.stx_dev_minor & 0xff)
 			       | (statx.stx_dev_major << 8)
 			       | ((statx.stx_dev_minor & ~0xff) << 12));
@@ -997,47 +995,8 @@ int sys_stat(const char *path, struct stat *buf)
 	buf->st_mtim.tv_nsec = statx.stx_mtime.tv_nsec;
 	buf->st_ctim.tv_sec  = statx.stx_ctime.tv_sec;
 	buf->st_ctim.tv_nsec = statx.stx_ctime.tv_nsec;
-	return ret;
-}
-#else
-static __attribute__((unused))
-int sys_stat(const char *path, struct stat *buf)
-{
-	struct sys_stat_struct stat;
-	long ret;
-
-#ifdef __NR_newfstatat
-	/* only solution for arm64 */
-	ret = my_syscall4(__NR_newfstatat, AT_FDCWD, path, &stat, 0);
-#elif defined(__NR_stat)
-	ret = my_syscall2(__NR_stat, path, &stat);
-#else
-	return -ENOSYS;
-#endif
-	buf->st_dev          = stat.st_dev;
-	buf->st_ino          = stat.st_ino;
-	buf->st_mode         = stat.st_mode;
-	buf->st_nlink        = stat.st_nlink;
-	buf->st_uid          = stat.st_uid;
-	buf->st_gid          = stat.st_gid;
-	buf->st_rdev         = stat.st_rdev;
-	buf->st_size         = stat.st_size;
-	buf->st_blksize      = stat.st_blksize;
-	buf->st_blocks       = stat.st_blocks;
-	buf->st_atim.tv_sec  = stat.st_atime;
-	buf->st_atim.tv_nsec = stat.st_atime_nsec;
-	buf->st_mtim.tv_sec  = stat.st_mtime;
-	buf->st_mtim.tv_nsec = stat.st_mtime_nsec;
-	buf->st_ctim.tv_sec  = stat.st_ctime;
-	buf->st_ctim.tv_nsec = stat.st_ctime_nsec;
-	return ret;
-}
-#endif
 
-static __attribute__((unused))
-int stat(const char *path, struct stat *buf)
-{
-	return __sysret(sys_stat(path, buf));
+	return 0;
 }
 
 
diff --git a/tools/include/nolibc/types.h b/tools/include/nolibc/types.h
index 23963e48d8ee..8cfc4c860fa4 100644
--- a/tools/include/nolibc/types.h
+++ b/tools/include/nolibc/types.h
@@ -15,8 +15,8 @@
 
 
 /* Only the generic macros and types may be defined here. The arch-specific
- * ones such as the O_RDONLY and related macros used by fcntl() and open(), or
- * the layout of sys_stat_struct must not be defined here.
+ * ones such as the O_RDONLY and related macros used by fcntl() and open()
+ * must not be defined here.
  */
 
 /* stat flags (WARNING, octal here). We need to check for an existing
diff --git a/tools/include/nolibc/x86_64/sys.h b/tools/include/nolibc/x86_64/sys.h
index c761c97dccf8..ac3e8811b7d1 100644
--- a/tools/include/nolibc/x86_64/sys.h
+++ b/tools/include/nolibc/x86_64/sys.h
@@ -7,33 +7,6 @@
 #ifndef _NOLIBC_X86_64_SYS_H
 #define _NOLIBC_X86_64_SYS_H
 
-/* The struct returned by the stat() syscall, equivalent to stat64(). The
- * syscall returns 116 bytes and stops in the middle of __unused.
- */
-struct sys_stat_struct {
-	unsigned long st_dev;
-	unsigned long st_ino;
-	unsigned long st_nlink;
-	unsigned int  st_mode;
-	unsigned int  st_uid;
-
-	unsigned int  st_gid;
-	unsigned int  __pad0;
-	unsigned long st_rdev;
-	long          st_size;
-	long          st_blksize;
-
-	long          st_blocks;
-	unsigned long st_atime;
-	unsigned long st_atime_nsec;
-	unsigned long st_mtime;
-
-	unsigned long st_mtime_nsec;
-	unsigned long st_ctime;
-	unsigned long st_ctime_nsec;
-	long          __unused[3];
-};
-
 /* Syscalls for x86_64 :
  *   - registers are 64-bit
  *   - syscall number is passed in rax
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 04/12] tools/nolibc: crt.h: add _start_c
  2023-07-08 15:25 [PATCH v2 00/12] tools/nolibc: shrink arch support Zhangjin Wu
                   ` (2 preceding siblings ...)
  2023-07-08 15:28 ` [PATCH v2 03/12] tools/nolibc: sys.h: remove the old sys_stat support Zhangjin Wu
@ 2023-07-08 15:29 ` Zhangjin Wu
  2023-07-09 18:49   ` Thomas Weißschuh
  2023-07-08 15:31 ` [PATCH v2 05/12] tools/nolibc: arm/crt.h: shrink _start with _start_c Zhangjin Wu
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-08 15:29 UTC (permalink / raw)
  To: w; +Cc: falcon, arnd, linux-kernel, linux-kselftest, thomas

As the environ and _auxv support added for nolibc, the assembly _start
function becomes more and more complex and therefore makes the porting
of nolibc to new architectures harder and harder.

To simplify portability, this c version of _start_c() is added to do
most of the assembly start operations in C, which reduces the complexity
a lot and will eventually simplify the porting of nolibc to the new
architectures.

The new _start_c() only requires a stack pointer argument, it will find
argv, envp and _auxv for us, and then call main(), finally, it exit()
with main's return status. With this new _start_c(), the future new
architectures only require to add very few assembly instructions.

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/crt.h | 44 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
index 221b7c5346ca..b269294e9664 100644
--- a/tools/include/nolibc/crt.h
+++ b/tools/include/nolibc/crt.h
@@ -13,4 +13,48 @@
 char **environ __attribute__((weak));
 const unsigned long *_auxv __attribute__((weak));
 
+int main(int argc, char *argv[], char **envp);
+static void exit(int);
+
+void _start_c(long *sp)
+{
+	int argc, i;
+	char **argv;
+	char **envp;
+
+	/*
+	 * sp  :  argc          <-- argument count, required by main()
+	 * argv:  argv[0]       <-- argument vector, required by main()
+	 *        argv[1]
+	 *        ...
+	 *        argv[argc-1]
+	 *        null
+	 * envp:  envp[0]       <-- environment variables, required by main() and getenv()
+	 *        envp[1]
+	 *        ...
+	 *        null
+	 * _auxv: auxv[0]       <-- auxiliary vector, required by getauxval()
+	 *        auxv[1]
+	 *        ...
+	 *        null
+	 */
+
+	/* assign argc and argv */
+	argc = sp[0];
+	argv = (void *)(sp + 1);
+
+	/* find envp */
+	envp = argv + argc + 1;
+	environ = envp;
+
+	/* find auxv */
+	i = 0;
+	while (envp[i])
+		i++;
+	_auxv = (void *)(envp + i + 1);
+
+	/* go to application */
+	exit(main(argc, argv, envp));
+}
+
 #endif /* _NOLIBC_CRT_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 05/12] tools/nolibc: arm/crt.h: shrink _start with _start_c
  2023-07-08 15:25 [PATCH v2 00/12] tools/nolibc: shrink arch support Zhangjin Wu
                   ` (3 preceding siblings ...)
  2023-07-08 15:29 ` [PATCH v2 04/12] tools/nolibc: crt.h: add _start_c Zhangjin Wu
@ 2023-07-08 15:31 ` Zhangjin Wu
  2023-07-08 15:32 ` [PATCH v2 06/12] tools/nolibc: aarch64/crt.h: " Zhangjin Wu
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-08 15:31 UTC (permalink / raw)
  To: w; +Cc: falcon, arnd, linux-kernel, linux-kselftest, thomas

move most of the _start operations to _start_c().

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/arm/crt.h | 38 +++++-----------------------------
 1 file changed, 5 insertions(+), 33 deletions(-)

diff --git a/tools/include/nolibc/arm/crt.h b/tools/include/nolibc/arm/crt.h
index 7b3b9e21e5c4..75c097027a80 100644
--- a/tools/include/nolibc/arm/crt.h
+++ b/tools/include/nolibc/arm/crt.h
@@ -12,40 +12,12 @@ void __attribute__((weak, noreturn, optimize("omit-frame-pointer"))) __no_stack_
 {
 	__asm__ volatile (
 #ifdef _NOLIBC_STACKPROTECTOR
-		"bl __stack_chk_init\n"       /* initialize stack protector                          */
+		"bl __stack_chk_init\n" /* initialize stack protector                     */
 #endif
-		"pop {%r0}\n"                 /* argc was in the stack                               */
-		"mov %r1, %sp\n"              /* argv = sp                                           */
-
-		"add %r2, %r0, $1\n"          /* envp = (argc + 1) ...                               */
-		"lsl %r2, %r2, $2\n"          /*        * 4        ...                               */
-		"add %r2, %r2, %r1\n"         /*        + argv                                       */
-		"ldr %r3, 1f\n"               /* r3 = &environ (see below)                           */
-		"str %r2, [r3]\n"             /* store envp into environ                             */
-
-		"mov r4, r2\n"                /* search for auxv (follows NULL after last env)       */
-		"0:\n"
-		"mov r5, r4\n"                /* r5 = r4                                             */
-		"add r4, r4, #4\n"            /* r4 += 4                                             */
-		"ldr r5,[r5]\n"               /* r5 = *r5 = *(r4-4)                                  */
-		"cmp r5, #0\n"                /* and stop at NULL after last env                     */
-		"bne 0b\n"
-		"ldr %r3, 2f\n"               /* r3 = &_auxv (low bits)                              */
-		"str r4, [r3]\n"              /* store r4 into _auxv                                 */
-
-		"mov %r3, $8\n"               /* AAPCS : sp must be 8-byte aligned in the            */
-		"neg %r3, %r3\n"              /*         callee, and bl doesn't push (lr=pc)         */
-		"and %r3, %r3, %r1\n"         /* so we do sp = r1(=sp) & r3(=-8);                    */
-		"mov %sp, %r3\n"
-
-		"bl main\n"                   /* main() returns the status code, we'll exit with it. */
-		"movs r7, $1\n"               /* NR_exit == 1                                        */
-		"svc $0x00\n"
-		".align 2\n"                  /* below are the pointers to a few variables           */
-		"1:\n"
-		".word environ\n"
-		"2:\n"
-		".word _auxv\n"
+		"mov %r0, sp\n"         /* save stack pointer to %r0, as arg1 of _start_c */
+		"and ip, %r0, #-8\n"    /* sp must be 8-byte aligned in the callee        */
+		"mov sp, ip\n"
+		"bl  _start_c\n"        /* transfer to c runtime                          */
 	);
 	__builtin_unreachable();
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 06/12] tools/nolibc: aarch64/crt.h: shrink _start with _start_c
  2023-07-08 15:25 [PATCH v2 00/12] tools/nolibc: shrink arch support Zhangjin Wu
                   ` (4 preceding siblings ...)
  2023-07-08 15:31 ` [PATCH v2 05/12] tools/nolibc: arm/crt.h: shrink _start with _start_c Zhangjin Wu
@ 2023-07-08 15:32 ` Zhangjin Wu
  2023-07-08 15:33 ` [PATCH v2 07/12] tools/nolibc: i386/crt.h: " Zhangjin Wu
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-08 15:32 UTC (permalink / raw)
  To: w; +Cc: falcon, arnd, linux-kernel, linux-kselftest, thomas

move most of the _start operations to _start_c().

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/aarch64/crt.h | 23 +++++------------------
 1 file changed, 5 insertions(+), 18 deletions(-)

diff --git a/tools/include/nolibc/aarch64/crt.h b/tools/include/nolibc/aarch64/crt.h
index 6c81d81cf31f..4e04c421ab63 100644
--- a/tools/include/nolibc/aarch64/crt.h
+++ b/tools/include/nolibc/aarch64/crt.h
@@ -12,26 +12,13 @@ void __attribute__((weak, noreturn, optimize("omit-frame-pointer"))) __no_stack_
 {
 	__asm__ volatile (
 #ifdef _NOLIBC_STACKPROTECTOR
-		"bl __stack_chk_init\n"   /* initialize stack protector                     */
+		"bl __stack_chk_init\n" /* initialize stack protector                    */
 #endif
-		"ldr x0, [sp]\n"     /* argc (x0) was in the stack                          */
-		"add x1, sp, 8\n"    /* argv (x1) = sp                                      */
-		"lsl x2, x0, 3\n"    /* envp (x2) = 8*argc ...                              */
-		"add x2, x2, 8\n"    /*           + 8 (skip null)                           */
-		"add x2, x2, x1\n"   /*           + argv                                    */
-		"adrp x3, environ\n"          /* x3 = &environ (high bits)                  */
-		"str x2, [x3, #:lo12:environ]\n" /* store envp into environ                 */
-		"mov x4, x2\n"       /* search for auxv (follows NULL after last env)       */
-		"0:\n"
-		"ldr x5, [x4], 8\n"  /* x5 = *x4; x4 += 8                                   */
-		"cbnz x5, 0b\n"      /* and stop at NULL after last env                     */
-		"adrp x3, _auxv\n"   /* x3 = &_auxv (high bits)                             */
-		"str x4, [x3, #:lo12:_auxv]\n" /* store x4 into _auxv                       */
-		"and sp, x1, -16\n"  /* sp must be 16-byte aligned in the callee            */
-		"bl main\n"          /* main() returns the status code, we'll exit with it. */
-		"mov x8, 93\n"       /* NR_exit == 93                                       */
-		"svc #0\n"
+		"mov x0, sp\n"          /* save stack pointer to x0, as arg1 of _start_c */
+		"and sp, x0, -16\n"     /* sp must be 16-byte aligned in the callee      */
+		"bl  _start_c\n"        /* transfer to c runtime                         */
 	);
 	__builtin_unreachable();
+
 }
 #endif /* _NOLIBC_AARCH64_CRT_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 07/12] tools/nolibc: i386/crt.h: shrink _start with _start_c
  2023-07-08 15:25 [PATCH v2 00/12] tools/nolibc: shrink arch support Zhangjin Wu
                   ` (5 preceding siblings ...)
  2023-07-08 15:32 ` [PATCH v2 06/12] tools/nolibc: aarch64/crt.h: " Zhangjin Wu
@ 2023-07-08 15:33 ` Zhangjin Wu
  2023-07-08 15:34 ` [PATCH v2 08/12] tools/nolibc: x86_64/crt.h: " Zhangjin Wu
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-08 15:33 UTC (permalink / raw)
  To: w; +Cc: falcon, arnd, linux-kernel, linux-kselftest, thomas

move most of the _start operations to _start_c().

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/i386/crt.h | 29 +++++++----------------------
 1 file changed, 7 insertions(+), 22 deletions(-)

diff --git a/tools/include/nolibc/i386/crt.h b/tools/include/nolibc/i386/crt.h
index 0b88f7c887ae..87f31bc253a3 100644
--- a/tools/include/nolibc/i386/crt.h
+++ b/tools/include/nolibc/i386/crt.h
@@ -18,29 +18,14 @@ void __attribute__((weak, noreturn, optimize("omit-frame-pointer"))) __no_stack_
 {
 	__asm__ volatile (
 #ifdef _NOLIBC_STACKPROTECTOR
-		"call __stack_chk_init\n"   /* initialize stack protector                    */
+		"call __stack_chk_init\n" /* initialize stack protector                           */
 #endif
-		"pop %eax\n"                /* argc   (first arg, %eax)                      */
-		"mov %esp, %ebx\n"          /* argv[] (second arg, %ebx)                     */
-		"lea 4(%ebx,%eax,4),%ecx\n" /* then a NULL then envp (third arg, %ecx)       */
-		"mov %ecx, environ\n"       /* save environ                                  */
-		"xor %ebp, %ebp\n"          /* zero the stack frame                          */
-		"mov %ecx, %edx\n"          /* search for auxv (follows NULL after last env) */
-		"0:\n"
-		"add $4, %edx\n"            /* search for auxv using edx, it follows the     */
-		"cmp -4(%edx), %ebp\n"      /* ... NULL after last env (ebp is zero here)    */
-		"jnz 0b\n"
-		"mov %edx, _auxv\n"         /* save it into _auxv                            */
-		"and $-16, %esp\n"          /* x86 ABI : esp must be 16-byte aligned before  */
-		"sub $4, %esp\n"            /* the call instruction (args are aligned)       */
-		"push %ecx\n"               /* push all registers on the stack so that we    */
-		"push %ebx\n"               /* support both regparm and plain stack modes    */
-		"push %eax\n"
-		"call main\n"               /* main() returns the status code in %eax        */
-		"mov %eax, %ebx\n"          /* retrieve exit code (32-bit int)               */
-		"movl $1, %eax\n"           /* NR_exit == 1                                  */
-		"int $0x80\n"               /* exit now                                      */
-		"hlt\n"                     /* ensure it does not                            */
+		"xor  %ebp, %ebp\n"       /* zero the stack frame                                 */
+		"mov  %esp, %eax\n"       /* save stack pointer to %eax, as arg1 of _start_c      */
+		"and  $-16, %esp\n"       /* last pushed argument must be 16-byte aligned         */
+		"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                            */
 	);
 	__builtin_unreachable();
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 08/12] tools/nolibc: x86_64/crt.h: shrink _start with _start_c
  2023-07-08 15:25 [PATCH v2 00/12] tools/nolibc: shrink arch support Zhangjin Wu
                   ` (6 preceding siblings ...)
  2023-07-08 15:33 ` [PATCH v2 07/12] tools/nolibc: i386/crt.h: " Zhangjin Wu
@ 2023-07-08 15:34 ` Zhangjin Wu
  2023-07-08 15:35 ` [PATCH v2 09/12] tools/nolibc: mips/crt.h: " Zhangjin Wu
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-08 15:34 UTC (permalink / raw)
  To: w; +Cc: falcon, arnd, linux-kernel, linux-kselftest, thomas

move most of the _start operations to _start_c().

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/x86_64/crt.h | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)

diff --git a/tools/include/nolibc/x86_64/crt.h b/tools/include/nolibc/x86_64/crt.h
index 6fede1235efc..03899042854e 100644
--- a/tools/include/nolibc/x86_64/crt.h
+++ b/tools/include/nolibc/x86_64/crt.h
@@ -18,27 +18,16 @@ void __attribute__((weak, noreturn, optimize("omit-frame-pointer"))) __no_stack_
 {
 	__asm__ volatile (
 #ifdef _NOLIBC_STACKPROTECTOR
-		"call __stack_chk_init\n"   /* initialize stack protector                          */
+		"call __stack_chk_init\n" /* initialize stack protector                      */
 #endif
-		"pop %rdi\n"                /* argc   (first arg, %rdi)                            */
-		"mov %rsp, %rsi\n"          /* argv[] (second arg, %rsi)                           */
-		"lea 8(%rsi,%rdi,8),%rdx\n" /* then a NULL then envp (third arg, %rdx)             */
-		"mov %rdx, environ\n"       /* save environ                                        */
-		"xor %ebp, %ebp\n"          /* zero the stack frame                                */
-		"mov %rdx, %rax\n"          /* search for auxv (follows NULL after last env)       */
-		"0:\n"
-		"add $8, %rax\n"            /* search for auxv using rax, it follows the           */
-		"cmp -8(%rax), %rbp\n"      /* ... NULL after last env (rbp is zero here)          */
-		"jnz 0b\n"
-		"mov %rax, _auxv\n"         /* save it into _auxv                                  */
-		"and $-16, %rsp\n"          /* x86 ABI : esp must be 16-byte aligned before call   */
-		"call main\n"               /* main() returns the status code, we'll exit with it. */
-		"mov %eax, %edi\n"          /* retrieve exit code (32 bit)                         */
-		"mov $60, %eax\n"           /* NR_exit == 60                                       */
-		"syscall\n"                 /* really exit                                         */
-		"hlt\n"                     /* ensure it does not return                           */
+		"xor  %ebp, %ebp\n"       /* zero the stack frame                            */
+		"mov  %rsp, %rdi\n"       /* save stack pointer to %rdi, as arg1 of _start_c */
+		"and  $-16, %rsp\n"       /* %rsp must be 16-byte aligned before call        */
+		"call _start_c\n"         /* transfer to c runtime                           */
+		"hlt\n"                   /* ensure it does not return                       */
 	);
 	__builtin_unreachable();
+
 }
 
 #endif /* _NOLIBC_X86_64_CRT_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 09/12] tools/nolibc: mips/crt.h: shrink _start with _start_c
  2023-07-08 15:25 [PATCH v2 00/12] tools/nolibc: shrink arch support Zhangjin Wu
                   ` (7 preceding siblings ...)
  2023-07-08 15:34 ` [PATCH v2 08/12] tools/nolibc: x86_64/crt.h: " Zhangjin Wu
@ 2023-07-08 15:35 ` Zhangjin Wu
  2023-07-08 15:36 ` [PATCH v2 10/12] tools/nolibc: loongarch/crt.h: " Zhangjin Wu
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-08 15:35 UTC (permalink / raw)
  To: w; +Cc: falcon, arnd, linux-kernel, linux-kselftest, thomas

move most of the _start operations to _start_c().

Also clean up the instructions in delay slots.

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/mips/crt.h | 42 +++++++--------------------------
 1 file changed, 9 insertions(+), 33 deletions(-)

diff --git a/tools/include/nolibc/mips/crt.h b/tools/include/nolibc/mips/crt.h
index 38df52d8ec16..a49632b64fdd 100644
--- a/tools/include/nolibc/mips/crt.h
+++ b/tools/include/nolibc/mips/crt.h
@@ -11,43 +11,19 @@
 void __attribute__((weak, noreturn, optimize("omit-frame-pointer"))) __no_stack_protector __start(void)
 {
 	__asm__ volatile (
-		/*".set nomips16\n"*/
 		".set push\n"
-		".set    noreorder\n"
+		".set noreorder\n"
 		".option pic0\n"
 #ifdef _NOLIBC_STACKPROTECTOR
-		"jal __stack_chk_init\n" /* initialize stack protector                         */
-		"nop\n"                  /* delayed slot                                       */
+		"jal __stack_chk_init\n" /* initialize stack protector                     */
+		" nop\n"                 /* delayed slot                                   */
 #endif
-		/*".ent __start\n"*/
-		/*"__start:\n"*/
-		"lw $a0,($sp)\n"        /* argc was in the stack                               */
-		"addiu  $a1, $sp, 4\n"  /* argv = sp + 4                                       */
-		"sll $a2, $a0, 2\n"     /* a2 = argc * 4                                       */
-		"add   $a2, $a2, $a1\n" /* envp = argv + 4*argc ...                            */
-		"addiu $a2, $a2, 4\n"   /*        ... + 4                                      */
-		"lui $a3, %hi(environ)\n"     /* load environ into a3 (hi)                     */
-		"addiu $a3, %lo(environ)\n"   /* load environ into a3 (lo)                     */
-		"sw $a2,($a3)\n"              /* store envp(a2) into environ                   */
-
-		"move $t0, $a2\n"             /* iterate t0 over envp, look for NULL           */
-		"0:"                          /* do {                                          */
-		"lw $a3, ($t0)\n"             /*   a3=*(t0);                                   */
-		"bne $a3, $0, 0b\n"           /* } while (a3);                                 */
-		"addiu $t0, $t0, 4\n"         /* delayed slot: t0+=4;                          */
-		"lui $a3, %hi(_auxv)\n"       /* load _auxv into a3 (hi)                       */
-		"addiu $a3, %lo(_auxv)\n"     /* load _auxv into a3 (lo)                       */
-		"sw $t0, ($a3)\n"             /* store t0 into _auxv                           */
-
-		"li $t0, -8\n"
-		"and $sp, $sp, $t0\n"   /* sp must be 8-byte aligned                           */
-		"addiu $sp,$sp,-16\n"   /* the callee expects to save a0..a3 there!            */
-		"jal main\n"            /* main() returns the status code, we'll exit with it. */
-		"nop\n"                 /* delayed slot                                        */
-		"move $a0, $v0\n"       /* retrieve 32-bit exit code from v0                   */
-		"li $v0, 4001\n"        /* NR_exit == 4001                                     */
-		"syscall\n"
-		/*".end __start\n"*/
+		"move  $a0, $sp\n"       /* save stack pointer to $a0, as arg1 of _start_c */
+		"li    $t0, -8\n"
+		"and   $sp, $sp, $t0\n"  /* $sp must be 8-byte aligned                     */
+		"addiu $sp, $sp, -16\n"  /* the callee expects to save a0..a3 there        */
+		"jal   _start_c\n"       /* transfer to c runtime                          */
+		" nop\n"                 /* delayed slot                                   */
 		".set pop\n"
 	);
 	__builtin_unreachable();
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 10/12] tools/nolibc: loongarch/crt.h: shrink _start with _start_c
  2023-07-08 15:25 [PATCH v2 00/12] tools/nolibc: shrink arch support Zhangjin Wu
                   ` (8 preceding siblings ...)
  2023-07-08 15:35 ` [PATCH v2 09/12] tools/nolibc: mips/crt.h: " Zhangjin Wu
@ 2023-07-08 15:36 ` Zhangjin Wu
  2023-07-08 15:37 ` [PATCH v2 11/12] tools/nolibc: riscv/crt.h: " Zhangjin Wu
  2023-07-08 15:38 ` [PATCH v2 12/12] tools/nolibc: s390/crt.h: " Zhangjin Wu
  11 siblings, 0 replies; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-08 15:36 UTC (permalink / raw)
  To: w; +Cc: falcon, arnd, linux-kernel, linux-kselftest, thomas

move most of the _start operations to _start_c().

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/loongarch/crt.h | 39 +++-------------------------
 1 file changed, 4 insertions(+), 35 deletions(-)

diff --git a/tools/include/nolibc/loongarch/crt.h b/tools/include/nolibc/loongarch/crt.h
index 253d2fccea1e..00bfc36b0747 100644
--- a/tools/include/nolibc/loongarch/crt.h
+++ b/tools/include/nolibc/loongarch/crt.h
@@ -8,22 +8,8 @@
 #define _NOLIBC_LOONGARCH_CRT_H
 
 #if __loongarch_grlen == 32
-#define LONGLOG      "2"
-#define SZREG        "4"
-#define REG_L        "ld.w"
-#define LONG_S       "st.w"
-#define LONG_ADD     "add.w"
-#define LONG_ADDI    "addi.w"
-#define LONG_SLL     "slli.w"
 #define LONG_BSTRINS "bstrins.w"
 #else /* __loongarch_grlen == 64 */
-#define LONGLOG      "3"
-#define SZREG        "8"
-#define REG_L        "ld.d"
-#define LONG_S       "st.d"
-#define LONG_ADD     "add.d"
-#define LONG_ADDI    "addi.d"
-#define LONG_SLL     "slli.d"
 #define LONG_BSTRINS "bstrins.d"
 #endif
 
@@ -32,28 +18,11 @@ void __attribute__((weak, noreturn, optimize("omit-frame-pointer"))) __no_stack_
 {
 	__asm__ volatile (
 #ifdef _NOLIBC_STACKPROTECTOR
-		"bl __stack_chk_init\n"               /* initialize stack protector                          */
+		"bl __stack_chk_init\n"            /* initialize stack protector                     */
 #endif
-		REG_L        " $a0, $sp, 0\n"         /* argc (a0) was in the stack                          */
-		LONG_ADDI    " $a1, $sp, "SZREG"\n"   /* argv (a1) = sp + SZREG                              */
-		LONG_SLL     " $a2, $a0, "LONGLOG"\n" /* envp (a2) = SZREG*argc ...                          */
-		LONG_ADDI    " $a2, $a2, "SZREG"\n"   /*             + SZREG (skip null)                     */
-		LONG_ADD     " $a2, $a2, $a1\n"       /*             + argv                                  */
-
-		"move          $a3, $a2\n"            /* iterate a3 over envp to find auxv (after NULL)      */
-		"0:\n"                                /* do {                                                */
-		REG_L        " $a4, $a3, 0\n"         /*   a4 = *a3;                                         */
-		LONG_ADDI    " $a3, $a3, "SZREG"\n"   /*   a3 += sizeof(void*);                              */
-		"bne           $a4, $zero, 0b\n"      /* } while (a4);                                       */
-		"la.pcrel      $a4, _auxv\n"          /* a4 = &_auxv                                         */
-		LONG_S       " $a3, $a4, 0\n"         /* store a3 into _auxv                                 */
-
-		"la.pcrel      $a3, environ\n"        /* a3 = &environ                                       */
-		LONG_S       " $a2, $a3, 0\n"         /* store envp(a2) into environ                         */
-		LONG_BSTRINS " $sp, $zero, 3, 0\n"    /* sp must be 16-byte aligned                          */
-		"bl            main\n"                /* main() returns the status code, we'll exit with it. */
-		"li.w          $a7, 93\n"             /* NR_exit == 93                                       */
-		"syscall       0\n"
+		"move          $a0, $sp\n"         /* save stack pointer to $a0, as arg1 of _start_c */
+		LONG_BSTRINS " $sp, $zero, 3, 0\n" /* $sp must be 16-byte aligned                    */
+		"bl            _start_c\n"         /* transfer to c runtime                          */
 	);
 	__builtin_unreachable();
 }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 11/12] tools/nolibc: riscv/crt.h: shrink _start with _start_c
  2023-07-08 15:25 [PATCH v2 00/12] tools/nolibc: shrink arch support Zhangjin Wu
                   ` (9 preceding siblings ...)
  2023-07-08 15:36 ` [PATCH v2 10/12] tools/nolibc: loongarch/crt.h: " Zhangjin Wu
@ 2023-07-08 15:37 ` Zhangjin Wu
  2023-07-08 15:38 ` [PATCH v2 12/12] tools/nolibc: s390/crt.h: " Zhangjin Wu
  11 siblings, 0 replies; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-08 15:37 UTC (permalink / raw)
  To: w; +Cc: falcon, arnd, linux-kernel, linux-kselftest, thomas

move most of the _start operations to _start_c().

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/riscv/crt.h | 39 ++++----------------------------
 1 file changed, 5 insertions(+), 34 deletions(-)

diff --git a/tools/include/nolibc/riscv/crt.h b/tools/include/nolibc/riscv/crt.h
index 1f81a2e47a48..2b8df4c478d5 100644
--- a/tools/include/nolibc/riscv/crt.h
+++ b/tools/include/nolibc/riscv/crt.h
@@ -7,49 +7,20 @@
 #ifndef _NOLIBC_RISCV_CRT_H
 #define _NOLIBC_RISCV_CRT_H
 
-#if   __riscv_xlen == 64
-#define PTRLOG "3"
-#define SZREG  "8"
-#define REG_L  "ld"
-#define REG_S  "sd"
-#elif __riscv_xlen == 32
-#define PTRLOG "2"
-#define SZREG  "4"
-#define REG_L  "lw"
-#define REG_S  "sw"
-#endif
-
 /* startup code */
 void __attribute__((weak, noreturn, optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
 {
 	__asm__ volatile (
 		".option push\n"
 		".option norelax\n"
-		"lla   gp, __global_pointer$\n"
+		"lla  gp, __global_pointer$\n"
 		".option pop\n"
 #ifdef _NOLIBC_STACKPROTECTOR
-		"call __stack_chk_init\n"    /* initialize stack protector                          */
+		"call __stack_chk_init\n" /* initialize stack protector                    */
 #endif
-		REG_L" a0, 0(sp)\n"          /* argc (a0) was in the stack                          */
-		"add   a1, sp, "SZREG"\n"    /* argv (a1) = sp                                      */
-		"slli  a2, a0, "PTRLOG"\n"   /* envp (a2) = SZREG*argc ...                          */
-		"add   a2, a2, "SZREG"\n"    /*             + SZREG (skip null)                     */
-		"add   a2,a2,a1\n"           /*             + argv                                  */
-
-		"add   a3, a2, zero\n"       /* iterate a3 over envp to find auxv (after NULL)      */
-		"0:\n"                       /* do {                                                */
-		REG_L" a4, 0(a3)\n"          /*   a4 = *a3;                                         */
-		"add   a3, a3, "SZREG"\n"    /*   a3 += sizeof(void*);                              */
-		"bne   a4, zero, 0b\n"       /* } while (a4);                                       */
-		"lui   a4, %hi(_auxv)\n"     /* a4 = &_auxv (high bits)                             */
-		REG_S" a3, %lo(_auxv)(a4)\n" /* store a3 into _auxv                                 */
-
-		"lui   a3, %hi(environ)\n"   /* a3 = &environ (high bits)                           */
-		REG_S" a2,%lo(environ)(a3)\n"/* store envp(a2) into environ                         */
-		"andi  sp,a1,-16\n"          /* sp must be 16-byte aligned                          */
-		"call  main\n"               /* main() returns the status code, we'll exit with it. */
-		"li a7, 93\n"                /* NR_exit == 93                                       */
-		"ecall\n"
+		"mv   a0, sp\n"           /* save stack pointer to a0, as arg1 of _start_c */
+		"andi sp, a0, -16\n"      /* sp must be 16-byte aligned                    */
+		"call _start_c\n"         /* transfer to c runtime                         */
 	);
 	__builtin_unreachable();
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v2 12/12] tools/nolibc: s390/crt.h: shrink _start with _start_c
  2023-07-08 15:25 [PATCH v2 00/12] tools/nolibc: shrink arch support Zhangjin Wu
                   ` (10 preceding siblings ...)
  2023-07-08 15:37 ` [PATCH v2 11/12] tools/nolibc: riscv/crt.h: " Zhangjin Wu
@ 2023-07-08 15:38 ` Zhangjin Wu
  11 siblings, 0 replies; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-08 15:38 UTC (permalink / raw)
  To: w; +Cc: falcon, arnd, linux-kernel, linux-kselftest, thomas

move most of the _start operations to _start_c().

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/include/nolibc/s390/crt.h | 32 ++++----------------------------
 1 file changed, 4 insertions(+), 28 deletions(-)

diff --git a/tools/include/nolibc/s390/crt.h b/tools/include/nolibc/s390/crt.h
index 8580f615d525..e247b8a37475 100644
--- a/tools/include/nolibc/s390/crt.h
+++ b/tools/include/nolibc/s390/crt.h
@@ -10,34 +10,10 @@
 void __attribute__((weak, noreturn, optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
 {
 	__asm__ volatile (
-		"lg	%r2,0(%r15)\n"		/* argument count */
-		"la	%r3,8(%r15)\n"		/* argument pointers */
-
-		"xgr	%r0,%r0\n"		/* r0 will be our NULL value */
-		/* search for envp */
-		"lgr	%r4,%r3\n"		/* start at argv */
-		"0:\n"
-		"clg	%r0,0(%r4)\n"		/* entry zero? */
-		"la	%r4,8(%r4)\n"		/* advance pointer */
-		"jnz	0b\n"			/* no -> test next pointer */
-						/* yes -> r4 now contains start of envp */
-		"larl	%r1,environ\n"
-		"stg	%r4,0(%r1)\n"
-
-		/* search for auxv */
-		"lgr	%r5,%r4\n"		/* start at envp */
-		"1:\n"
-		"clg	%r0,0(%r5)\n"		/* entry zero? */
-		"la	%r5,8(%r5)\n"		/* advance pointer */
-		"jnz	1b\n"			/* no -> test next pointer */
-		"larl	%r1,_auxv\n"		/* yes -> store value in _auxv */
-		"stg	%r5,0(%r1)\n"
-
-		"aghi	%r15,-160\n"		/* allocate new stackframe */
-		"xc	0(8,%r15),0(%r15)\n"	/* clear backchain */
-		"brasl	%r14,main\n"		/* ret value of main is arg to exit */
-		"lghi	%r1,1\n"		/* __NR_exit */
-		"svc	0\n"
+		"lgr	%r2, %r15\n"          /* save stack pointer to %r2, as arg1 of _start_c */
+		"aghi	%r15, -160\n"         /* allocate new stackframe                        */
+		"xc	0(8,%r15), 0(%r15)\n" /* clear backchain                                */
+		"brasl	%r14, _start_c\n"     /* transfer to c runtime                          */
 	);
 	__builtin_unreachable();
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 01/12] tools/nolibc: rename arch-<ARCH>.h to <ARCH>/arch.h
  2023-07-08 15:26 ` [PATCH v2 01/12] tools/nolibc: rename arch-<ARCH>.h to <ARCH>/arch.h Zhangjin Wu
@ 2023-07-09  9:56   ` Willy Tarreau
  2023-07-10  7:23     ` Zhangjin Wu
  0 siblings, 1 reply; 24+ messages in thread
From: Willy Tarreau @ 2023-07-09  9:56 UTC (permalink / raw)
  To: Zhangjin Wu; +Cc: arnd, linux-kernel, linux-kselftest, thomas

On Sat, Jul 08, 2023 at 11:26:42PM +0800, Zhangjin Wu wrote:
> Currently, the architecture specific arch.h has two parts, one is the
> syscall declarations for sys.h, another is the _start code definition
> for startup support.
> 
> The coming crt.h will provide the startup support with a new common
> _start_c(), it will replace most of the assembly _start code and shrink
> the original _start code to be minimal, as a result, _start_c() and the
> left minimal _start code will work together to provide the startup
> support, therefore, the left _start code will be only required by crt.h.
> 
> So, the syscall declarations part of arch.h can be split to sys_arch.h
> and the _start code part of arch.h can be split to crt_arch.h and then,
> they should only be included in sys.h and crt.h respectively.
> 
> At the same time, the architecture specific arch-<ARCH>.h should be
> split to <ARCH>/crt.h and <ARCH>/sys.h.
> 
> As a preparation, this creates the architecture specific directory and
> moves tools/include/nolibc/arch-<ARCH>.h to
> tools/include/nolibc/<ARCH>/arch.h.

I'm sorry but I still don't understand what it *provides*. I'm reading
it as "we *can* do this so let's do it". But what is the specific
purpose of adding this extra directory structure ? It's really unclear
to me and worries me that it'll only result in complicating maintenance
by adding even more files, thus even more "include" lines and cross
dependencies.

Zhangjin, very often in your series, the justification for a change is
missing, instead it's only explaining what is being changed, and I must
confess that it makes it particularly difficult to figure the benefits.
I'm only seeing this as an opportunity for a change ("can be split").
I could have missed something of course, but I can't figure what problem
it is trying to solve.

As a general advice, I tend to remind people that when sending a patch
series, they should consider they're trying to sell it, so they must
emphasize the benefits of accepting the series for the maintainer(s).

You very likely have a good reason for doing this but I can't see it
here so I'm just seeing a change that will possibly add some extra
cost (if at least because file locations change again) and nothing
more. When you try to reorganize things, it's often much more
efficient to try to discuss it before proposing patches, because
reorg patches are generally unreadable and take time for you to
create and for others to review. Instead, just explaining what you
think you can improve is faster for everyone, and others can chime in
and propose alternate approaches (something which is very hard to do
with a patch series).

Thanks!
Willy

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 04/12] tools/nolibc: crt.h: add _start_c
  2023-07-08 15:29 ` [PATCH v2 04/12] tools/nolibc: crt.h: add _start_c Zhangjin Wu
@ 2023-07-09 18:49   ` Thomas Weißschuh
  2023-07-09 21:00     ` Thomas Weißschuh
  2023-07-10  9:26     ` Zhangjin Wu
  0 siblings, 2 replies; 24+ messages in thread
From: Thomas Weißschuh @ 2023-07-09 18:49 UTC (permalink / raw)
  To: Zhangjin Wu; +Cc: w, arnd, linux-kernel, linux-kselftest

On 2023-07-08 23:29:58+0800, Zhangjin Wu wrote:
> As the environ and _auxv support added for nolibc, the assembly _start
> function becomes more and more complex and therefore makes the porting
> of nolibc to new architectures harder and harder.
> 
> To simplify portability, this c version of _start_c() is added to do
> most of the assembly start operations in C, which reduces the complexity
> a lot and will eventually simplify the porting of nolibc to the new
> architectures.
> 
> The new _start_c() only requires a stack pointer argument, it will find
> argv, envp and _auxv for us, and then call main(), finally, it exit()
> with main's return status. With this new _start_c(), the future new
> architectures only require to add very few assembly instructions.

I like it!

A quick test indicates that the initialization of the stackprotectors
could also be moved into the C function.

It also seems like a good opportunity to add some tests for
argv/environment variable passing.

And as general note to the full series I think that splitting the arch
files is not necessary and confusing.

> Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
> ---
>  tools/include/nolibc/crt.h | 44 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
> 
> diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
> index 221b7c5346ca..b269294e9664 100644
> --- a/tools/include/nolibc/crt.h
> +++ b/tools/include/nolibc/crt.h
> @@ -13,4 +13,48 @@
>  char **environ __attribute__((weak));

The old code seems to avoid putting "environ" into the global symbol
namespace. Could this declaration be moved into the function like in
getenv()?

>  const unsigned long *_auxv __attribute__((weak));
>  
> +int main(int argc, char *argv[], char **envp);

This will lead to conflicting declarations if the users use a different
signature. I'm not (yet?) sure how to work around this.

Also how is the case handled where main() returns "void"?
I'm not sure how this is currently handled or if the compiler takes core
of returning 0 in this case.

> +static void exit(int);
> +
> +void _start_c(long *sp)
> +{
> +	int argc, i;
> +	char **argv;
> +	char **envp;
> +
> +	/*
> +	 * sp  :  argc          <-- argument count, required by main()
> +	 * argv:  argv[0]       <-- argument vector, required by main()
> +	 *        argv[1]
> +	 *        ...
> +	 *        argv[argc-1]
> +	 *        null
> +	 * envp:  envp[0]       <-- environment variables, required by main() and getenv()
> +	 *        envp[1]
> +	 *        ...
> +	 *        null
> +	 * _auxv: auxv[0]       <-- auxiliary vector, required by getauxval()
> +	 *        auxv[1]
> +	 *        ...
> +	 *        null
> +	 */
> +
> +	/* assign argc and argv */
> +	argc = sp[0];
> +	argv = (void *)(sp + 1);
> +
> +	/* find envp */
> +	envp = argv + argc + 1;
> +	environ = envp;
> +
> +	/* find auxv */
> +	i = 0;
> +	while (envp[i])
> +		i++;
> +	_auxv = (void *)(envp + i + 1);
> +
> +	/* go to application */
> +	exit(main(argc, argv, envp));
> +}
> +
>  #endif /* _NOLIBC_CRT_H */
> -- 
> 2.25.1
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 04/12] tools/nolibc: crt.h: add _start_c
  2023-07-09 18:49   ` Thomas Weißschuh
@ 2023-07-09 21:00     ` Thomas Weißschuh
  2023-07-10  9:26     ` Zhangjin Wu
  1 sibling, 0 replies; 24+ messages in thread
From: Thomas Weißschuh @ 2023-07-09 21:00 UTC (permalink / raw)
  To: Zhangjin Wu; +Cc: w, arnd, linux-kernel, linux-kselftest

On 2023-07-09 20:49:10+0200, Thomas Weißschuh wrote:
> On 2023-07-08 23:29:58+0800, Zhangjin Wu wrote:

> [..]

> > ---
> >  tools/include/nolibc/crt.h | 44 ++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 44 insertions(+)
> > 
> > diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
> > index 221b7c5346ca..b269294e9664 100644
> > --- a/tools/include/nolibc/crt.h
> > +++ b/tools/include/nolibc/crt.h
> > @@ -13,4 +13,48 @@

> [..]

> >  const unsigned long *_auxv __attribute__((weak));
> >  
> > +int main(int argc, char *argv[], char **envp);
> 
> This will lead to conflicting declarations if the users use a different
> signature. I'm not (yet?) sure how to work around this.
> 
> Also how is the case handled where main() returns "void"?
> I'm not sure how this is currently handled or if the compiler takes core
> of returning 0 in this case.

I looked into this some more.

The diff below allows it to accept different signatures for main().
(Maybe you can improve the naming)

Implicit return values seem to be handled by the compiler automatically.
In C89 mode we get garbage values, in C2X/C23 we get zero.
As per the respective C specs.


diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
index b269294e9664..dba40bc9413f 100644
--- a/tools/include/nolibc/crt.h
+++ b/tools/include/nolibc/crt.h
@@ -13,7 +13,6 @@
 char **environ __attribute__((weak));
 const unsigned long *_auxv __attribute__((weak));
 
-int main(int argc, char *argv[], char **envp);
 static void exit(int);
 
 void _start_c(long *sp)
@@ -21,6 +20,7 @@ void _start_c(long *sp)
 	int argc, i;
 	char **argv;
 	char **envp;
+	int _nolibc_main_alias(int, char**, char**) __asm__("main");
 
 	/*
 	 * sp  :  argc          <-- argument count, required by main()
@@ -54,7 +54,7 @@ void _start_c(long *sp)
 	_auxv = (void *)(envp + i + 1);
 
 	/* go to application */
-	exit(main(argc, argv, envp));
+	exit(_nolibc_main_alias(argc, argv, envp));
 }
 
 #endif /* _NOLIBC_CRT_H */

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 01/12] tools/nolibc: rename arch-<ARCH>.h to <ARCH>/arch.h
  2023-07-09  9:56   ` Willy Tarreau
@ 2023-07-10  7:23     ` Zhangjin Wu
  2023-07-10 15:51       ` Thomas Weißschuh
  0 siblings, 1 reply; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-10  7:23 UTC (permalink / raw)
  To: w; +Cc: arnd, falcon, linux-kernel, linux-kselftest, thomas

Hi, Willy

> 
> On Sat, Jul 08, 2023 at 11:26:42PM +0800, Zhangjin Wu wrote:
> > Currently, the architecture specific arch.h has two parts, one is the
> > syscall declarations for sys.h, another is the _start code definition
> > for startup support.
> > 
> > The coming crt.h will provide the startup support with a new common
> > _start_c(), it will replace most of the assembly _start code and shrink
> > the original _start code to be minimal, as a result, _start_c() and the
> > left minimal _start code will work together to provide the startup
> > support, therefore, the left _start code will be only required by crt.h.
> > 
> > So, the syscall declarations part of arch.h can be split to sys_arch.h
> > and the _start code part of arch.h can be split to crt_arch.h and then,
> > they should only be included in sys.h and crt.h respectively.
> > 
> > At the same time, the architecture specific arch-<ARCH>.h should be
> > split to <ARCH>/crt.h and <ARCH>/sys.h.
> > 
> > As a preparation, this creates the architecture specific directory and
> > moves tools/include/nolibc/arch-<ARCH>.h to
> > tools/include/nolibc/<ARCH>/arch.h.
> 
> I'm sorry but I still don't understand what it *provides*. I'm reading
> it as "we *can* do this so let's do it". But what is the specific
> purpose of adding this extra directory structure ? It's really unclear
> to me and worries me that it'll only result in complicating maintenance
> by adding even more files, thus even more "include" lines and cross
> dependencies.

Willy, I was assuming you had a look at the discussion between Thomas
and me, so, I didn't add the link to our discussion, it is more about
the 'clarity' of code "include" [1].

I have proposed the idea in the discussion but got no response yet, so,
sent this revision for more discussion, obviously, it is better to
discuss more there and get more feedback from Thomas and you.

The v0 included "crt.h" before "arch.h", Thomas suggested me include
"crt.h" in arch_<ARCH>.h, just like the "compiler.h" did. His suggestion
did inspire me to think about how to treat the relationship among crt.h,
sys.h and arch.h.

The idea behind is we have many directions to divide nolibc to different
parts/modules:

- one is arch specific (arch.h) and non-arch specific (the others)

  This method is used by us currently, It is very good to put all of the
  arch specific parts together to simplify (in the files to be
  added/maintained) the porting of a new architecture.

  But to be honest, It also confuse the modularity a little, for
  example, like sys.h, crt.h should be a core function/feature of
  nolibc, arch.h is not so. arch.h only provides the necessary minimal
  assembly "pieces".

  both sys.h and crt.h are not a sub modules of arch.h (although they
  have minimal arch specific code), so, like sys.h, crt.h should be
  included in the top-level headers, not in arch.h, reversely, the
  minimal arch specific should be included in crt.h. To do so and to
  avoid include the non-crt part, the split of arch.h is required, and
  therefore, the <ARCH>/ is created to put the divided <ARCH>/sys.h and
  <ARCH>/crt.h, otherwise, there will be many sys-<ARCH>.h and
  crt-<ARCH>.h in the top-level directory of nolibc.

- another is the parallel functions/features (like crt.h, sys.h, stack protector ...)

  This is used by musl and glibc, before sending this proposal, I have
  taken a look at both of them, musl is simpler and clearer, we apply
  the similar method:

  musl:
      crt/crt1.c
                 #include "crt_arch.h"  /* arch/<ARCH>/crt_arch.h */

                 void _start_c(long *p)
                 {
                        int argc = p[0];
                        char **argv = (void *)(p+1);
                        ...
                 }

      src/internal/syscall.h:
                 ##include "syscall_arch.h" /* arch/<ARCH>/syscall_arch.h */
     
                 ...

  glibc: (it is more complicated than musl)

     csu/libc-start.c, sysdeps/<ARCH>/start.S
     
     sysdeps/unix/sysv/linux/sysdep.h, sysdeps/unix/sysv/linux/<ARCH>/sysdep.h, 


  With this method, the "crt_arch.h + crt.h" together provide the C
  RunTime (startup code, stack protector, environ and _auxv currently)
  function, the "sys_arch.h + sys.h" together provide the syscall
  definitions. The arch specific parts are hidden behind, and only
  require to include the crt_arch.h in crt.h and sys_arch.h in sys.h, no
  need to include the whole arch.h for all.

As a summary, the core obvious reason here is, to this crt.h itself, it
is ok for us to include crt.h in arch.h in code side, but reversely, I
do prefer to include arch.h (and therefore the crt_arch.h) in crt.h,
crt.h is the core function should be exported, arch.h is not, it only
provide some low-level helpers for crt.h. If we treat sys.h as a core
function and crt.h as a arch specific thing, it does confuse a little.
This reorg may also help the similar future functions who require arch
specific support, but of course, it does require to add/maintain more
files for a new architecture, but it also allow to develop/debug at a
smaller fineness.

In current stage, include crt.h in arch.h is not that unacceptable, but
if reorg is a better direction, why not do it currently, because we do
have two functions (crt.h and sys.h) in <ARCH>/, if only one, it is not
urgent ;-)

Is this explanation better than before? welcome to discuss more ;-)

Like musl, if required, another top-level arch/ may be required to put
all of the <ARCH>/ directories together to clean up the top-level nolibc
directory.

> 
> Zhangjin, very often in your series, the justification for a change is
> missing, instead it's only explaining what is being changed, and I must
> confess that it makes it particularly difficult to figure the benefits.
> I'm only seeing this as an opportunity for a change ("can be split").
> I could have missed something of course, but I can't figure what problem
> it is trying to solve.

Willy, thanks very much for pointing out this and so sorry, "commit
message should tell why but not how" is in my mind, but sometimes, it
may be lost especially when the change list are 'huge' (must improve).

In reality, It is a little difficult to just explain it at the right
dimension for this change, so I have wrotten several versions of the
commit message for this change locally (and also for the other changes
too), at last, I choose the one currently used.

As explained in another reply, it is really hard to write a just ok
commit message for every change, sometimes, the justification is
'obvious' to some develoers who have the background information or who
have dicussed together, sometimes, it is not easy to just write
precisely about the core justification, to improve this, here is the
list I plan to do, hope it help the others too:

- discuss more before send new patches, especially for 'new' or 'big'
  change

- reword carefully about every change before sending patches (show
  benefits to let maintainer 'buy' (merge) them)

- send the patches not frequently, keep the mind conscious, not like a
  "flood"

> 
> As a general advice, I tend to remind people that when sending a patch
> series, they should consider they're trying to sell it, so they must
> emphasize the benefits of accepting the series for the maintainer(s).
>

Yeah, why maintainer want to 'buy' (merge) is the right direction.

> You very likely have a good reason for doing this but I can't see it
> here so I'm just seeing a change that will possibly add some extra
> cost (if at least because file locations change again) and nothing
> more. When you try to reorganize things, it's often much more
> efficient to try to discuss it before proposing patches, because
> reorg patches are generally unreadable and take time for you to
> create and for others to review.

Yes, reorg is really hard to do and also hard to review.

> Instead, just explaining what you
> think you can improve is faster for everyone, and others can chime in
> and propose alternate approaches (something which is very hard to do
> with a patch series).
>

Great suggestion, a ping on the discussion [1] would be better than just
reorg it and send the patches. Thanks a lot.

Best regards,
Zhangjin
---
[1]: https://lore.kernel.org/lkml/20230703145500.500460-1-falcon@tinylab.org/

> Thanks!
> Willy

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 04/12] tools/nolibc: crt.h: add _start_c
  2023-07-09 18:49   ` Thomas Weißschuh
  2023-07-09 21:00     ` Thomas Weißschuh
@ 2023-07-10  9:26     ` Zhangjin Wu
  2023-07-10 15:24       ` Thomas Weißschuh
  1 sibling, 1 reply; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-10  9:26 UTC (permalink / raw)
  To: thomas; +Cc: arnd, falcon, linux-kernel, linux-kselftest, w

Hi, Thomas

> 
> On 2023-07-08 23:29:58+0800, Zhangjin Wu wrote:
> > As the environ and _auxv support added for nolibc, the assembly _start
> > function becomes more and more complex and therefore makes the porting
> > of nolibc to new architectures harder and harder.
> > 
> > To simplify portability, this c version of _start_c() is added to do
> > most of the assembly start operations in C, which reduces the complexity
> > a lot and will eventually simplify the porting of nolibc to the new
> > architectures.
> > 
> > The new _start_c() only requires a stack pointer argument, it will find
> > argv, envp and _auxv for us, and then call main(), finally, it exit()
> > with main's return status. With this new _start_c(), the future new
> > architectures only require to add very few assembly instructions.
> 
> I like it!
> 
> A quick test indicates that the initialization of the stackprotectors
> could also be moved into the C function.
>

Cool, do you mean directly call __stack_chk_init() at the beginning of
_start_c()?

> It also seems like a good opportunity to add some tests for
> argv/environment variable passing.

Yes, and even further, we can do more on auxv, just like musl does in
src/env/__libc_start_main.c, not that urgent currently:

    libc.auxv = auxv = (void *)(envp+i+1);
    ...
    __hwcap = aux[AT_HWCAP];
    if (aux[AT_SYSINFO]) __sysinfo = aux[AT_SYSINFO];
    ...
    libc.page_size = aux[AT_PAGESZ];

    if (!pn) pn = (void*)aux[AT_EXECFN];
    if (!pn) pn = "";
    __progname = __progname_full = pn;
    for (i=0; pn[i]; i++) if (pn[i]=='/') __progname = pn+i+1;

    __init_tls(aux);
    __init_ssp((void *)aux[AT_RANDOM]);

    if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID]
            && !aux[AT_SECURE]) return;

    ...
    libc.secure = 1;

> 
> And as general note to the full series I think that splitting the arch
> files is not necessary and confusing.
>

Ok, welcome to discuss more in this thread:

    https://lore.kernel.org/lkml/20230710072340.10798-1-falcon@tinylab.org/

and let's choose a better method as possible as we can, Just replied Willy to
explain more.

> > Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
> > ---
> >  tools/include/nolibc/crt.h | 44 ++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 44 insertions(+)
> > 
> > diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
> > index 221b7c5346ca..b269294e9664 100644
> > --- a/tools/include/nolibc/crt.h
> > +++ b/tools/include/nolibc/crt.h
> > @@ -13,4 +13,48 @@
> >  char **environ __attribute__((weak));
> 
> The old code seems to avoid putting "environ" into the global symbol
> namespace. Could this declaration be moved into the function like in
> getenv()?
>

ok, do you mean just move it to stdlib.h like this? I moved _auxv (used
by getauxv()) to stdlib.h too:

        tools/nolibc: move environ and _auxv from crt.h to stdlib.h
        
        Move the definitions of environ and _auxv from crt.h to stdlib.h, where
        the place who uses those definitions.
        
        - getenv uses environ
        - getauxv uses _auxcv
        
        Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
    
    diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
    index b269294e9664..d2f84cbe73d0 100644
    --- a/tools/include/nolibc/crt.h
    +++ b/tools/include/nolibc/crt.h
    @@ -10,14 +10,13 @@
     #include "compiler.h"
     #include "crt_arch.h"
     
    -char **environ __attribute__((weak));
    -const unsigned long *_auxv __attribute__((weak));
    -
     int main(int argc, char *argv[], char **envp);
     static void exit(int);
     
     void _start_c(long *sp)
     {
    +       extern char **environ;
    +       extern const unsigned long *_auxv;
            int argc, i;
            char **argv;
            char **envp;
    diff --git a/tools/include/nolibc/stdlib.h b/tools/include/nolibc/stdlib.h
    index 2f9b4b3c6d26..5eadadc2d0f5 100644
    --- a/tools/include/nolibc/stdlib.h
    +++ b/tools/include/nolibc/stdlib.h
    @@ -14,6 +14,9 @@
     #include "string.h"
     #include <linux/auxvec.h>
     
    +char **environ __attribute__((weak));
    +const unsigned long *_auxv __attribute__((weak));
    +
     struct nolibc_heap {
            size_t  len;
            char    user_p[] __attribute__((__aligned__));

> >  const unsigned long *_auxv __attribute__((weak));
> >  
> > +int main(int argc, char *argv[], char **envp);
> 
> This will lead to conflicting declarations if the users use a different
> signature. I'm not (yet?) sure how to work around this.
>

Ah yes, I forgot this critical case, people may use something like:

    int main(void)
    int main(int argc, char *argv[])

Just applied the method suggested by you in anothe reply [1]:

    diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
    index d2f84cbe73d0..8fe38ef8c5b2 100644
    --- a/tools/include/nolibc/crt.h
    +++ b/tools/include/nolibc/crt.h
    @@ -10,7 +10,7 @@
     #include "compiler.h"
     #include "crt_arch.h"

    -int main(int argc, char *argv[], char **envp);
    +typedef int (_nolibc_main_fn)(int, char **, char **);
     static void exit(int);

     void _start_c(long *sp)
    @@ -20,6 +20,7 @@ void _start_c(long *sp)
            int argc, i;
            char **argv;
            char **envp;
    +       _nolibc_main_fn _nolibc_main __asm__ ("main");

            /*
             * sp  :  argc          <-- argument count, required by main()
    @@ -53,7 +54,7 @@ void _start_c(long *sp)
            _auxv = (void *)(envp + i + 1);

            /* go to application */
    -       exit(main(argc, argv, envp));
    +       exit(_nolibc_main(argc, argv, envp));
     }
 
     #endif /* _NOLIBC_CRT_H */

It works as expected, thanks very much!

> Also how is the case handled where main() returns "void"?

Do you mean the main() without an explicit "return 0"?

    int main(int argc, char *argv[], char **envp)
    {
        printf("Hello\n");
    }

Tested c89, c99, c2x, c23, gnu11, the same result as yours:

    std       | return value
    ----------|------------
    c89       | 6 /* return value of printf() */
    c99       | 0 /* set by compiler with: xorl    %eax, %eax */
    c2x       | 0
    gnu11     | 0

> I'm not sure how this is currently handled or if the compiler takes care
> of returning 0 in this case.

    void main(void)
    {
        printf("Hello\n");
    }

Tested c89, c99, c2x, c23, gnu11, the same result as yours, the return
value is 6, the return value is the return status of the last called
functon.

Thanks,
Zhangjin
---
[1]: https://lore.kernel.org/lkml/90fdd255-32f4-4caf-90ff-06456b53dac3@t-8ch.de/

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 04/12] tools/nolibc: crt.h: add _start_c
  2023-07-10  9:26     ` Zhangjin Wu
@ 2023-07-10 15:24       ` Thomas Weißschuh
  2023-07-10 16:45         ` Zhangjin Wu
  0 siblings, 1 reply; 24+ messages in thread
From: Thomas Weißschuh @ 2023-07-10 15:24 UTC (permalink / raw)
  To: Zhangjin Wu; +Cc: arnd, linux-kernel, linux-kselftest, w

On 2023-07-10 17:26:43+0800, Zhangjin Wu wrote:
> > On 2023-07-08 23:29:58+0800, Zhangjin Wu wrote:
> > > As the environ and _auxv support added for nolibc, the assembly _start
> > > function becomes more and more complex and therefore makes the porting
> > > of nolibc to new architectures harder and harder.
> > > 
> > > To simplify portability, this c version of _start_c() is added to do
> > > most of the assembly start operations in C, which reduces the complexity
> > > a lot and will eventually simplify the porting of nolibc to the new
> > > architectures.
> > > 
> > > The new _start_c() only requires a stack pointer argument, it will find
> > > argv, envp and _auxv for us, and then call main(), finally, it exit()
> > > with main's return status. With this new _start_c(), the future new
> > > architectures only require to add very few assembly instructions.
> > 
> > I like it!
> > 
> > A quick test indicates that the initialization of the stackprotectors
> > could also be moved into the C function.
> >
> 
> Cool, do you mean directly call __stack_chk_init() at the beginning of
> _start_c()?

Yes, exactly.

> > It also seems like a good opportunity to add some tests for
> > argv/environment variable passing.
> 
> Yes, and even further, we can do more on auxv, just like musl does in
> src/env/__libc_start_main.c, not that urgent currently:

With tests I mean nolibc-test.c to make sure we don't introduce any
regressions.
Only some tiny testcases to validate that argv and environ are picked
up correctly by the startup code on all arches.

> 
>     libc.auxv = auxv = (void *)(envp+i+1);
>     ...
>     __hwcap = aux[AT_HWCAP];
>     if (aux[AT_SYSINFO]) __sysinfo = aux[AT_SYSINFO];
>     ...
>     libc.page_size = aux[AT_PAGESZ];
> 
>     if (!pn) pn = (void*)aux[AT_EXECFN];
>     if (!pn) pn = "";
>     __progname = __progname_full = pn;
>     for (i=0; pn[i]; i++) if (pn[i]=='/') __progname = pn+i+1;
> 
>     __init_tls(aux);
>     __init_ssp((void *)aux[AT_RANDOM]);
> 
>     if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID]
>             && !aux[AT_SECURE]) return;
> 
>     ...
>     libc.secure = 1;
> 
> > 
> > And as general note to the full series I think that splitting the arch
> > files is not necessary and confusing.
> >
> 
> Ok, welcome to discuss more in this thread:
> 
>     https://lore.kernel.org/lkml/20230710072340.10798-1-falcon@tinylab.org/
> 
> and let's choose a better method as possible as we can, Just replied Willy to
> explain more.

Will do.

> > > Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
> > > ---
> > >  tools/include/nolibc/crt.h | 44 ++++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 44 insertions(+)
> > > 
> > > diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
> > > index 221b7c5346ca..b269294e9664 100644
> > > --- a/tools/include/nolibc/crt.h
> > > +++ b/tools/include/nolibc/crt.h
> > > @@ -13,4 +13,48 @@
> > >  char **environ __attribute__((weak));
> > 
> > The old code seems to avoid putting "environ" into the global symbol
> > namespace. Could this declaration be moved into the function like in
> > getenv()?
> >
> 
> ok, do you mean just move it to stdlib.h like this? I moved _auxv (used
> by getauxv()) to stdlib.h too:

Nevermind, I got confused by the in-function declaration of
"extern char **environ" inside "getenv()".
Actually this in-function declaration doesn't do anything and can be
dropped.

> 
>         tools/nolibc: move environ and _auxv from crt.h to stdlib.h
>         
>         Move the definitions of environ and _auxv from crt.h to stdlib.h, where
>         the place who uses those definitions.
>         
>         - getenv uses environ
>         - getauxv uses _auxcv
>         
>         Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
>     
>     diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
>     index b269294e9664..d2f84cbe73d0 100644
>     --- a/tools/include/nolibc/crt.h
>     +++ b/tools/include/nolibc/crt.h
>     @@ -10,14 +10,13 @@
>      #include "compiler.h"
>      #include "crt_arch.h"
>      
>     -char **environ __attribute__((weak));
>     -const unsigned long *_auxv __attribute__((weak));
>     -
>      int main(int argc, char *argv[], char **envp);
>      static void exit(int);
>      
>      void _start_c(long *sp)
>      {
>     +       extern char **environ;
>     +       extern const unsigned long *_auxv;
>             int argc, i;
>             char **argv;
>             char **envp;
>     diff --git a/tools/include/nolibc/stdlib.h b/tools/include/nolibc/stdlib.h
>     index 2f9b4b3c6d26..5eadadc2d0f5 100644
>     --- a/tools/include/nolibc/stdlib.h
>     +++ b/tools/include/nolibc/stdlib.h
>     @@ -14,6 +14,9 @@
>      #include "string.h"
>      #include <linux/auxvec.h>
>      
>     +char **environ __attribute__((weak));
>     +const unsigned long *_auxv __attribute__((weak));
>     +
>      struct nolibc_heap {
>             size_t  len;
>             char    user_p[] __attribute__((__aligned__));
> 
> > >  const unsigned long *_auxv __attribute__((weak));
> > >  
> > > +int main(int argc, char *argv[], char **envp);
> > 
> > This will lead to conflicting declarations if the users use a different
> > signature. I'm not (yet?) sure how to work around this.
> >
> 
> Ah yes, I forgot this critical case, people may use something like:
> 
>     int main(void)
>     int main(int argc, char *argv[])

> [..]

I thought about this general problem and it turns out that there is
nothing that any libc can do to distinguish these special cases.
So it has to be handled in the compiler and we do not have to care.

Thomas

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 01/12] tools/nolibc: rename arch-<ARCH>.h to <ARCH>/arch.h
  2023-07-10  7:23     ` Zhangjin Wu
@ 2023-07-10 15:51       ` Thomas Weißschuh
  2023-07-11  7:41         ` Willy Tarreau
  0 siblings, 1 reply; 24+ messages in thread
From: Thomas Weißschuh @ 2023-07-10 15:51 UTC (permalink / raw)
  To: Zhangjin Wu; +Cc: w, arnd, linux-kernel, linux-kselftest

On 2023-07-10 15:23:40+0800, Zhangjin Wu wrote:
> > On Sat, Jul 08, 2023 at 11:26:42PM +0800, Zhangjin Wu wrote:

> [..]

> > > As a preparation, this creates the architecture specific directory and
> > > moves tools/include/nolibc/arch-<ARCH>.h to
> > > tools/include/nolibc/<ARCH>/arch.h.
> > 
> > I'm sorry but I still don't understand what it *provides*. I'm reading
> > it as "we *can* do this so let's do it". But what is the specific
> > purpose of adding this extra directory structure ? It's really unclear
> > to me and worries me that it'll only result in complicating maintenance
> > by adding even more files, thus even more "include" lines and cross
> > dependencies.
> 
> Willy, I was assuming you had a look at the discussion between Thomas
> and me, so, I didn't add the link to our discussion, it is more about
> the 'clarity' of code "include" [1].
> 
> I have proposed the idea in the discussion but got no response yet, so,
> sent this revision for more discussion, obviously, it is better to
> discuss more there and get more feedback from Thomas and you.

To be honest I got overwhelmed at some point and instead of figuring out
to which series' I already responded and which not I only responded to
those where I had time to do so immediately.

Keeping the amount of in-flight serieses lower would help this.

> The v0 included "crt.h" before "arch.h", Thomas suggested me include
> "crt.h" in arch_<ARCH>.h, just like the "compiler.h" did. His suggestion
> did inspire me to think about how to treat the relationship among crt.h,
> sys.h and arch.h.
> 
> The idea behind is we have many directions to divide nolibc to different
> parts/modules:
> 
> - one is arch specific (arch.h) and non-arch specific (the others)
> 
>   This method is used by us currently, It is very good to put all of the
>   arch specific parts together to simplify (in the files to be
>   added/maintained) the porting of a new architecture.
> 
>   But to be honest, It also confuse the modularity a little, for
>   example, like sys.h, crt.h should be a core function/feature of
>   nolibc, arch.h is not so. arch.h only provides the necessary minimal
>   assembly "pieces".
> 
>   both sys.h and crt.h are not a sub modules of arch.h (although they
>   have minimal arch specific code), so, like sys.h, crt.h should be
>   included in the top-level headers, not in arch.h, reversely, the
>   minimal arch specific should be included in crt.h. To do so and to
>   avoid include the non-crt part, the split of arch.h is required, and
>   therefore, the <ARCH>/ is created to put the divided <ARCH>/sys.h and
>   <ARCH>/crt.h, otherwise, there will be many sys-<ARCH>.h and
>   crt-<ARCH>.h in the top-level directory of nolibc.
> 
> - another is the parallel functions/features (like crt.h, sys.h, stack protector ...)
> 
>   This is used by musl and glibc, before sending this proposal, I have
>   taken a look at both of them, musl is simpler and clearer, we apply
>   the similar method:
> 
>   musl:
>       crt/crt1.c
>                  #include "crt_arch.h"  /* arch/<ARCH>/crt_arch.h */

In musl crt_arch.h seems to be used in different ways. So it makes sense
to split it from syscall_arch.h. In nolibc there is no such distinction.
And everything will end up in a global namespace anyways.

>                  void _start_c(long *p)
>                  {
>                         int argc = p[0];
>                         char **argv = (void *)(p+1);
>                         ...
>                  }
> 
>       src/internal/syscall.h:
>                  ##include "syscall_arch.h" /* arch/<ARCH>/syscall_arch.h */
>      
>                  ...
> 
>   glibc: (it is more complicated than musl)
> 
>      csu/libc-start.c, sysdeps/<ARCH>/start.S
>      
>      sysdeps/unix/sysv/linux/sysdep.h, sysdeps/unix/sysv/linux/<ARCH>/sysdep.h, 
> 
> 
>   With this method, the "crt_arch.h + crt.h" together provide the C
>   RunTime (startup code, stack protector, environ and _auxv currently)
>   function, the "sys_arch.h + sys.h" together provide the syscall
>   definitions. The arch specific parts are hidden behind, and only
>   require to include the crt_arch.h in crt.h and sys_arch.h in sys.h, no
>   need to include the whole arch.h for all.
> 
> As a summary, the core obvious reason here is, to this crt.h itself, it
> is ok for us to include crt.h in arch.h in code side, but reversely, I
> do prefer to include arch.h (and therefore the crt_arch.h) in crt.h,
> crt.h is the core function should be exported, arch.h is not, it only
> provide some low-level helpers for crt.h. If we treat sys.h as a core
> function and crt.h as a arch specific thing, it does confuse a little.
> This reorg may also help the similar future functions who require arch
> specific support, but of course, it does require to add/maintain more
> files for a new architecture, but it also allow to develop/debug at a
> smaller fineness.
> 
> In current stage, include crt.h in arch.h is not that unacceptable, but

Why would it be more unacceptable in the future?

> if reorg is a better direction, why not do it currently, because we do
> have two functions (crt.h and sys.h) in <ARCH>/, if only one, it is not
> urgent ;-)

> Is this explanation better than before? welcome to discuss more ;-)

Personally I'm not convinced :-)

The arch-specific code in nolibc in mainline is currentl ~200 lines per
arch. With this series in general it will be even less.
If at some point there are many more architectures it may make sense to
introduce an arch/ directory then.

> Like musl, if required, another top-level arch/ may be required to put
> all of the <ARCH>/ directories together to clean up the top-level nolibc
> directory.

At the moment in mainline there are 26 files in nolibc.
That does not seem excessive, in fact it looks to be less than most
other kernel directories.

> > Zhangjin, very often in your series, the justification for a change is
> > missing, instead it's only explaining what is being changed, and I must
> > confess that it makes it particularly difficult to figure the benefits.
> > I'm only seeing this as an opportunity for a change ("can be split").
> > I could have missed something of course, but I can't figure what problem
> > it is trying to solve.
> 
> Willy, thanks very much for pointing out this and so sorry, "commit
> message should tell why but not how" is in my mind, but sometimes, it
> may be lost especially when the change list are 'huge' (must improve).
> 
> In reality, It is a little difficult to just explain it at the right
> dimension for this change, so I have wrotten several versions of the
> commit message for this change locally (and also for the other changes
> too), at last, I choose the one currently used.
> 
> As explained in another reply, it is really hard to write a just ok
> commit message for every change, sometimes, the justification is
> 'obvious' to some develoers who have the background information or who
> have dicussed together, sometimes, it is not easy to just write
> precisely about the core justification, to improve this, here is the
> list I plan to do, hope it help the others too:
> 
> - discuss more before send new patches, especially for 'new' or 'big'
>   change

This sounds like the correct thing to do for reorganization patches.
It should be very easy to describe and very annoying to actually do.

> - reword carefully about every change before sending patches (show
>   benefits to let maintainer 'buy' (merge) them)
> 
> - send the patches not frequently, keep the mind conscious, not like a
>   "flood"

> [..]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 04/12] tools/nolibc: crt.h: add _start_c
  2023-07-10 15:24       ` Thomas Weißschuh
@ 2023-07-10 16:45         ` Zhangjin Wu
  0 siblings, 0 replies; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-10 16:45 UTC (permalink / raw)
  To: thomas; +Cc: arnd, falcon, linux-kernel, linux-kselftest, w

Hi, Thomas

> On 2023-07-10 17:26:43+0800, Zhangjin Wu wrote:
> > > On 2023-07-08 23:29:58+0800, Zhangjin Wu wrote:
[...]
> 
> > > It also seems like a good opportunity to add some tests for
> > > argv/environment variable passing.
> > 
> > Yes, and even further, we can do more on auxv, just like musl does in
> > src/env/__libc_start_main.c, not that urgent currently:
> 
> With tests I mean nolibc-test.c to make sure we don't introduce any
> regressions.
> Only some tiny testcases to validate that argv and environ are picked
> up correctly by the startup code on all arches.
>

Thomas, seems we already have some testcases for argv, environ and auxv
currently:

    run_syscall: chmod_argv0 <-- argv[0]
		 chdir_root  <-- chdir(getenv("PWD"))
                 getpagesize <-- getauxval(AT_PAGESZ)
    run_stdlib : getenv_TERM <-- getenv

> > 
[...]
> > >
> > 
> > Ok, welcome to discuss more in this thread:
> > 
> >     https://lore.kernel.org/lkml/20230710072340.10798-1-falcon@tinylab.org/
> > 
> > and let's choose a better method as possible as we can, Just replied Willy to
> > explain more.
> 
> Will do.
> 
> > > > Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
> > > > ---
> > > >  tools/include/nolibc/crt.h | 44 ++++++++++++++++++++++++++++++++++++++
> > > >  1 file changed, 44 insertions(+)
> > > > 
> > > > diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
> > > > index 221b7c5346ca..b269294e9664 100644
> > > > --- a/tools/include/nolibc/crt.h
> > > > +++ b/tools/include/nolibc/crt.h
> > > > @@ -13,4 +13,48 @@
> > > >  char **environ __attribute__((weak));
> > > 
> > > The old code seems to avoid putting "environ" into the global symbol
> > > namespace. Could this declaration be moved into the function like in
> > > getenv()?
> > >
> > 
> > ok, do you mean just move it to stdlib.h like this? I moved _auxv (used
> > by getauxv()) to stdlib.h too:
> 
> Nevermind, I got confused by the in-function declaration of
> "extern char **environ" inside "getenv()".
> Actually this in-function declaration doesn't do anything and can be
> dropped.
>

Yes. for nolibc application is in one-file style, let's remove it.

> > 
[...]
> > > 
> > > This will lead to conflicting declarations if the users use a different
> > > signature. I'm not (yet?) sure how to work around this.
> > >
> > 
> > Ah yes, I forgot this critical case, people may use something like:
> > 
> >     int main(void)
> >     int main(int argc, char *argv[])
> 
> > [..]
> 
> I thought about this general problem and it turns out that there is
> nothing that any libc can do to distinguish these special cases.
> So it has to be handled in the compiler and we do not have to care.

Ok.

Thanks,
Zhangjin

> 
> Thomas

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 01/12] tools/nolibc: rename arch-<ARCH>.h to <ARCH>/arch.h
  2023-07-10 15:51       ` Thomas Weißschuh
@ 2023-07-11  7:41         ` Willy Tarreau
  2023-07-11 16:38           ` Zhangjin Wu
  0 siblings, 1 reply; 24+ messages in thread
From: Willy Tarreau @ 2023-07-11  7:41 UTC (permalink / raw)
  To: Thomas Weißschuh; +Cc: Zhangjin Wu, arnd, linux-kernel, linux-kselftest

Hi Thomas, Zhangjin,

On Mon, Jul 10, 2023 at 05:51:39PM +0200, Thomas Weißschuh wrote:
> On 2023-07-10 15:23:40+0800, Zhangjin Wu wrote:
> > > On Sat, Jul 08, 2023 at 11:26:42PM +0800, Zhangjin Wu wrote:
> 
> > [..]
> 
> > > > As a preparation, this creates the architecture specific directory and
> > > > moves tools/include/nolibc/arch-<ARCH>.h to
> > > > tools/include/nolibc/<ARCH>/arch.h.
> > > 
> > > I'm sorry but I still don't understand what it *provides*. I'm reading
> > > it as "we *can* do this so let's do it". But what is the specific
> > > purpose of adding this extra directory structure ? It's really unclear
> > > to me and worries me that it'll only result in complicating maintenance
> > > by adding even more files, thus even more "include" lines and cross
> > > dependencies.
> > 
> > Willy, I was assuming you had a look at the discussion between Thomas
> > and me, so, I didn't add the link to our discussion, it is more about
> > the 'clarity' of code "include" [1].
> > 
> > I have proposed the idea in the discussion but got no response yet, so,
> > sent this revision for more discussion, obviously, it is better to
> > discuss more there and get more feedback from Thomas and you.
> 
> To be honest I got overwhelmed at some point and instead of figuring out
> to which series' I already responded and which not I only responded to
> those where I had time to do so immediately.
> 
> Keeping the amount of in-flight serieses lower would help this.

+1 on this. First it's difficult for me to assign contiguous time on
the subject so I can't grasp all series at once, and I'm terribly bad
at context-switching, which takes even more time and induces confusion.
Less topics at once, more focused with less reviews of reorganizations
will definitely help.

> > The v0 included "crt.h" before "arch.h", Thomas suggested me include
> > "crt.h" in arch_<ARCH>.h, just like the "compiler.h" did. His suggestion
> > did inspire me to think about how to treat the relationship among crt.h,
> > sys.h and arch.h.
> > 
> > The idea behind is we have many directions to divide nolibc to different
> > parts/modules:

Again above I'm seeing an opportunity but no explanation of why this
is needed. Thomas already mentioned that you're speaking about just
trying to factor out a few tens of lines. I'm not seeing *why* we
need to re-split everything yet again.

> > - one is arch specific (arch.h) and non-arch specific (the others)
> > 
> >   This method is used by us currently, It is very good to put all of the
> >   arch specific parts together to simplify (in the files to be
> >   added/maintained) the porting of a new architecture.
> > 
> >   But to be honest, It also confuse the modularity a little, for
> >   example, like sys.h, crt.h should be a core function/feature of
> >   nolibc, arch.h is not so. arch.h only provides the necessary minimal
> >   assembly "pieces".

But that's precisely the principle: keep arch-specific stuff as minimal
as possible, keep most of the rest generic but easily overloadable if
needed as we know that archs are not all 1:1 equivalent.

> >   both sys.h and crt.h are not a sub modules of arch.h (although they
> >   have minimal arch specific code), so, like sys.h, crt.h should be
> >   included in the top-level headers, not in arch.h,

Why ? Keep in mind that these are only include files, to in the end,
*all* of them are included. The ordering is the only thing that really
matters.

> >   reversely, the
> >   minimal arch specific should be included in crt.h. To do so and to
> >   avoid include the non-crt part, the split of arch.h is required, and
> >   therefore, the <ARCH>/ is created to put the divided <ARCH>/sys.h and
> >   <ARCH>/crt.h, otherwise, there will be many sys-<ARCH>.h and
> >   crt-<ARCH>.h in the top-level directory of nolibc.

Then doesn't it prove that you don't need that crt-<ARCH>.h and that
instead it should just be in arch-<ARCH> like the rest of the same arch ?

> > - another is the parallel functions/features (like crt.h, sys.h, stack protector ...)
> > 
> >   This is used by musl and glibc, before sending this proposal, I have
> >   taken a look at both of them, musl is simpler and clearer, we apply
> >   the similar method:
> > 
> >   musl:
> >       crt/crt1.c
> >                  #include "crt_arch.h"  /* arch/<ARCH>/crt_arch.h */
> 
> In musl crt_arch.h seems to be used in different ways. So it makes sense
> to split it from syscall_arch.h. In nolibc there is no such distinction.
> And everything will end up in a global namespace anyways.

Exactly. Musl is musl and nolibc is nolibc. Musl is a regular libc in that
it provides a .so that is built from many .c files. As such it's desirable
to split along certain edges. nolibc contains no single C file. It's only
meant to be included as-is in the user's C file. This changes a lot of
things, even in terms of splitting. Also keep in mind that musl is a
general-purpose libc, and that some distros are entirely built on it.
nolibc doesn't have such goal nor expectation, the first user was a
preinit code I wrote long ago, and the second one is rcutorture which
contains a while() loop around gettimeofday() IIRC. We must not just
blindly imitate other components' choices because they work, when we're
dealing with different constraints. If ours are acceptable, no need to
complicate everything.

> >   With this method, the "crt_arch.h + crt.h" together provide the C
> >   RunTime (startup code, stack protector, environ and _auxv currently)
> >   function, the "sys_arch.h + sys.h" together provide the syscall
> >   definitions. The arch specific parts are hidden behind, and only
> >   require to include the crt_arch.h in crt.h and sys_arch.h in sys.h, no
> >   need to include the whole arch.h for all.

Everything is included all the time. *everything*. The more files we
create, the more "#ifdef FOO_H" gets evaluated, and the more maintenance
burden it adds.

> > As a summary, the core obvious reason here is, to this crt.h itself, it
> > is ok for us to include crt.h in arch.h in code side, but reversely, I
> > do prefer to include arch.h (and therefore the crt_arch.h) in crt.h,
> > crt.h is the core function should be exported, arch.h is not, it only
> > provide some low-level helpers for crt.h. If we treat sys.h as a core
> > function and crt.h as a arch specific thing, it does confuse a little.
> > This reorg may also help the similar future functions who require arch
> > specific support, but of course, it does require to add/maintain more
> > files for a new architecture, but it also allow to develop/debug at a
> > smaller fineness.
> > 
> > In current stage, include crt.h in arch.h is not that unacceptable, but
> 
> Why would it be more unacceptable in the future?
> 
> > if reorg is a better direction, why not do it currently, because we do
> > have two functions (crt.h and sys.h) in <ARCH>/, if only one, it is not
> > urgent ;-)
> 
> > Is this explanation better than before? welcome to discuss more ;-)
> 
> Personally I'm not convinced :-)

Neither am I.

> The arch-specific code in nolibc in mainline is currentl ~200 lines per
> arch. With this series in general it will be even less.
> If at some point there are many more architectures it may make sense to
> introduce an arch/ directory then.

And even then I'm not convinced because the number of archs will remain
low anyway.

> > Like musl, if required, another top-level arch/ may be required to put
> > all of the <ARCH>/ directories together to clean up the top-level nolibc
> > directory.
> 
> At the moment in mainline there are 26 files in nolibc.
> That does not seem excessive, in fact it looks to be less than most
> other kernel directories.

Indeed :-)  Note that it started with a single one!

> > As explained in another reply, it is really hard to write a just ok
> > commit message for every change, sometimes, the justification is
> > 'obvious' to some develoers who have the background information or who
> > have dicussed together, sometimes,

Sometimes yes, but most of the series come with propositions to improve
something. The commits making the major changes (and the cover letter)
should justify why this is a desirable change, what it implies not to
have it and what it may imply to have it, what possible alternatives
were considered and dropped sometimes (e.g. when hesitating between two
approaches), etc.

Thanks,
Willy

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 01/12] tools/nolibc: rename arch-<ARCH>.h to <ARCH>/arch.h
  2023-07-11  7:41         ` Willy Tarreau
@ 2023-07-11 16:38           ` Zhangjin Wu
  2023-07-11 19:28             ` Willy Tarreau
  0 siblings, 1 reply; 24+ messages in thread
From: Zhangjin Wu @ 2023-07-11 16:38 UTC (permalink / raw)
  To: w; +Cc: arnd, falcon, linux-kernel, linux-kselftest, thomas

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 10661 bytes --]

Hi, Willy

> Hi Thomas, Zhangjin,
> 
> On Mon, Jul 10, 2023 at 05:51:39PM +0200, Thomas Weißschuh wrote:
> > On 2023-07-10 15:23:40+0800, Zhangjin Wu wrote:
> > > > On Sat, Jul 08, 2023 at 11:26:42PM +0800, Zhangjin Wu wrote:
> > 
> > > [..]
> > 
> > > > > As a preparation, this creates the architecture specific directory and
> > > > > moves tools/include/nolibc/arch-<ARCH>.h to
> > > > > tools/include/nolibc/<ARCH>/arch.h.
> > > > 
> > > > I'm sorry but I still don't understand what it *provides*. I'm reading
> > > > it as "we *can* do this so let's do it". But what is the specific
> > > > purpose of adding this extra directory structure ? It's really unclear
> > > > to me and worries me that it'll only result in complicating maintenance
> > > > by adding even more files, thus even more "include" lines and cross
> > > > dependencies.
> > > 
> > > Willy, I was assuming you had a look at the discussion between Thomas
> > > and me, so, I didn't add the link to our discussion, it is more about
> > > the 'clarity' of code "include" [1].
> > > 
> > > I have proposed the idea in the discussion but got no response yet, so,
> > > sent this revision for more discussion, obviously, it is better to
> > > discuss more there and get more feedback from Thomas and you.
> > 
> > To be honest I got overwhelmed at some point and instead of figuring out
> > to which series' I already responded and which not I only responded to
> > those where I had time to do so immediately.
> > 
> > Keeping the amount of in-flight serieses lower would help this.
> 
> +1 on this. First it's difficult for me to assign contiguous time on
> the subject so I can't grasp all series at once, and I'm terribly bad
> at context-switching, which takes even more time and induces confusion.
> Less topics at once, more focused with less reviews of reorganizations
> will definitely help.

me too, let's go back to the original rv32 support asap ;-)

> 
> > > The v0 included "crt.h" before "arch.h", Thomas suggested me include
> > > "crt.h" in arch_<ARCH>.h, just like the "compiler.h" did. His suggestion
> > > did inspire me to think about how to treat the relationship among crt.h,
> > > sys.h and arch.h.
> > > 
> > > The idea behind is we have many directions to divide nolibc to different
> > > parts/modules:
> 
> Again above I'm seeing an opportunity but no explanation of why this
> is needed. Thomas already mentioned that you're speaking about just
> trying to factor out a few tens of lines. I'm not seeing *why* we
> need to re-split everything yet again.
>
> > > - one is arch specific (arch.h) and non-arch specific (the others)
> > > 
> > >   This method is used by us currently, It is very good to put all of the
> > >   arch specific parts together to simplify (in the files to be
> > >   added/maintained) the porting of a new architecture.
> > > 
> > >   But to be honest, It also confuse the modularity a little, for
> > >   example, like sys.h, crt.h should be a core function/feature of
> > >   nolibc, arch.h is not so. arch.h only provides the necessary minimal
> > >   assembly "pieces".
> 
> But that's precisely the principle: keep arch-specific stuff as minimal
> as possible, keep most of the rest generic but easily overloadable if
> needed as we know that archs are not all 1:1 equivalent.
>

This patchset applies the same principle but mixes some other
requirements ;-)

Agree with "archs are not all 1:1 equivalent".

> > >   both sys.h and crt.h are not a sub modules of arch.h (although they
> > >   have minimal arch specific code), so, like sys.h, crt.h should be
> > >   included in the top-level headers, not in arch.h,
> 
> Why ? Keep in mind that these are only include files, to in the end,
> *all* of them are included. The ordering is the only thing that really
> matters.
>

Yeah, I know this. The only thing confused me is the relationship among
crt.h, sys.h and arch.h, the include position should better reflects
their relationship, currently, we have mixed two "divide" methods
together, one is arch and non-arch, another is the parallel
functions/features.

so, the only left question is where should we include crt.h in? Firstly,
I put it like sys.h (In my mind, it should be), If you two both agree to
put it in arch-<ARCH.h>, I will renew this series with it, this is
definitely a lighter way than the reorg method, I don't persist ;-)

> > >   reversely, the
> > >   minimal arch specific should be included in crt.h. To do so and to
> > >   avoid include the non-crt part, the split of arch.h is required, and
> > >   therefore, the <ARCH>/ is created to put the divided <ARCH>/sys.h and
> > >   <ARCH>/crt.h, otherwise, there will be many sys-<ARCH>.h and
> > >   crt-<ARCH>.h in the top-level directory of nolibc.
> 
> Then doesn't it prove that you don't need that crt-<ARCH>.h and that
> instead it should just be in arch-<ARCH> like the rest of the same arch ?
> 
> > > - another is the parallel functions/features (like crt.h, sys.h, stack protector ...)
> > > 
> > >   This is used by musl and glibc, before sending this proposal, I have
> > >   taken a look at both of them, musl is simpler and clearer, we apply
> > >   the similar method:
> > > 
> > >   musl:
> > >       crt/crt1.c
> > >                  #include "crt_arch.h"  /* arch/<ARCH>/crt_arch.h */
> > 
> > In musl crt_arch.h seems to be used in different ways. So it makes sense
> > to split it from syscall_arch.h. In nolibc there is no such distinction.
> > And everything will end up in a global namespace anyways.
> 
> Exactly. Musl is musl and nolibc is nolibc. Musl is a regular libc in that
> it provides a .so that is built from many .c files. As such it's desirable
> to split along certain edges. nolibc contains no single C file. It's only
> meant to be included as-is in the user's C file. This changes a lot of
> things, even in terms of splitting. Also keep in mind that musl is a
> general-purpose libc, and that some distros are entirely built on it.
> nolibc doesn't have such goal nor expectation, the first user was a
> preinit code I wrote long ago, and the second one is rcutorture which
> contains a while() loop around gettimeofday() IIRC. We must not just
> blindly imitate other components' choices because they work, when we're
> dealing with different constraints. If ours are acceptable, no need to
> complicate everything.
>

Willy, I know the difference between musl and nolibc, the musl code
referenced here is only used to clear my confusion about "the
relationship among crt.h, sys.h and arch.h" I mentiond above.

BTW, I do think nolibc have more using scenes, I like it very much and
have used it in my own "Linux Lab" open source project [1] to let it
work as the minimal rootfs to speed up kernel features learning and
development, I do like the 'kernel-only deployments' feature behind
nolibc [2], although there is something like "Unikernel Linux" [3], but
that differs from a normal Linux system and is more complicated ;-)

I'm even imaging using it with a pure-header shell and a pure-header gui
to let them further work together as a tiny rtos ;-)

[1]: https://github.com/tinyclub/linux-lab
[2]: https://lwn.net/Articles/920158/
[3]: https://github.com/unikernelLinux/ukl

> > >   With this method, the "crt_arch.h + crt.h" together provide the C
> > >   RunTime (startup code, stack protector, environ and _auxv currently)
> > >   function, the "sys_arch.h + sys.h" together provide the syscall
> > >   definitions. The arch specific parts are hidden behind, and only
> > >   require to include the crt_arch.h in crt.h and sys_arch.h in sys.h, no
> > >   need to include the whole arch.h for all.
> 
> Everything is included all the time. *everything*. The more files we
> create, the more "#ifdef FOO_H" gets evaluated, and the more maintenance
> burden it adds.
>

Agree with less "#ifdef"s.

> > > As a summary, the core obvious reason here is, to this crt.h itself, it
> > > is ok for us to include crt.h in arch.h in code side, but reversely, I
> > > do prefer to include arch.h (and therefore the crt_arch.h) in crt.h,
> > > crt.h is the core function should be exported, arch.h is not, it only
> > > provide some low-level helpers for crt.h. If we treat sys.h as a core
> > > function and crt.h as a arch specific thing, it does confuse a little.
> > > This reorg may also help the similar future functions who require arch
> > > specific support, but of course, it does require to add/maintain more
> > > files for a new architecture, but it also allow to develop/debug at a
> > > smaller fineness.
> > > 
> > > In current stage, include crt.h in arch.h is not that unacceptable, but
> > 
> > Why would it be more unacceptable in the future?
> > 
> > > if reorg is a better direction, why not do it currently, because we do
> > > have two functions (crt.h and sys.h) in <ARCH>/, if only one, it is not
> > > urgent ;-)
> > 
> > > Is this explanation better than before? welcome to discuss more ;-)
> > 
> > Personally I'm not convinced :-)
> 
> Neither am I.
> 
> > The arch-specific code in nolibc in mainline is currentl ~200 lines per
> > arch. With this series in general it will be even less.
> > If at some point there are many more architectures it may make sense to
> > introduce an arch/ directory then.
> 
> And even then I'm not convinced because the number of archs will remain
> low anyway.
>

We have 8 now, the maximum may be 'ls -d arch/*/ | wc -l', it is 22
currently ;-)

> > > Like musl, if required, another top-level arch/ may be required to put
> > > all of the <ARCH>/ directories together to clean up the top-level nolibc
> > > directory.
> > 
> > At the moment in mainline there are 26 files in nolibc.
> > That does not seem excessive, in fact it looks to be less than most
> > other kernel directories.
> 
> Indeed :-)  Note that it started with a single one!

Yeah, I learned the history, but I do think we will have more, as the
requirements become more and more ;-)

> 
> > > As explained in another reply, it is really hard to write a just ok
> > > commit message for every change, sometimes, the justification is
> > > 'obvious' to some develoers who have the background information or who
> > > have dicussed together, sometimes,
> 
> Sometimes yes, but most of the series come with propositions to improve
> something. The commits making the major changes (and the cover letter)
> should justify why this is a desirable change, what it implies not to
> have it and what it may imply to have it, what possible alternatives
> were considered and dropped sometimes (e.g. when hesitating between two
> approaches), etc.

Ok. 

Thanks,
Zhangjin

> 
> Thanks,
> Willy

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 01/12] tools/nolibc: rename arch-<ARCH>.h to <ARCH>/arch.h
  2023-07-11 16:38           ` Zhangjin Wu
@ 2023-07-11 19:28             ` Willy Tarreau
  0 siblings, 0 replies; 24+ messages in thread
From: Willy Tarreau @ 2023-07-11 19:28 UTC (permalink / raw)
  To: Zhangjin Wu; +Cc: arnd, linux-kernel, linux-kselftest, thomas

Hi Zhangjin,

On Wed, Jul 12, 2023 at 12:38:30AM +0800, Zhangjin Wu wrote:
> > > >   both sys.h and crt.h are not a sub modules of arch.h (although they
> > > >   have minimal arch specific code), so, like sys.h, crt.h should be
> > > >   included in the top-level headers, not in arch.h,
> > 
> > Why ? Keep in mind that these are only include files, to in the end,
> > *all* of them are included. The ordering is the only thing that really
> > matters.
> >
> 
> Yeah, I know this. The only thing confused me is the relationship among
> crt.h, sys.h and arch.h, the include position should better reflects
> their relationship, currently, we have mixed two "divide" methods
> together, one is arch and non-arch, another is the parallel
> functions/features.
> 
> so, the only left question is where should we include crt.h in? Firstly,
> I put it like sys.h (In my mind, it should be), If you two both agree to
> put it in arch-<ARCH.h>, I will renew this series with it, this is
> definitely a lighter way than the reorg method, I don't persist ;-)

Then let's start this way. And if later we find a better organization
*and* a good reason to change it, we can do it. Please also keep in mind
that constantly renaming/moving inflicts extra pain to the stable team
when backporting fixes if any. That's another reason for not moving code
around often.

> > > In musl crt_arch.h seems to be used in different ways. So it makes sense
> > > to split it from syscall_arch.h. In nolibc there is no such distinction.
> > > And everything will end up in a global namespace anyways.
> > 
> > Exactly. Musl is musl and nolibc is nolibc. Musl is a regular libc in that
> > it provides a .so that is built from many .c files. As such it's desirable
> > to split along certain edges. nolibc contains no single C file. It's only
> > meant to be included as-is in the user's C file. This changes a lot of
> > things, even in terms of splitting. Also keep in mind that musl is a
> > general-purpose libc, and that some distros are entirely built on it.
> > nolibc doesn't have such goal nor expectation, the first user was a
> > preinit code I wrote long ago, and the second one is rcutorture which
> > contains a while() loop around gettimeofday() IIRC. We must not just
> > blindly imitate other components' choices because they work, when we're
> > dealing with different constraints. If ours are acceptable, no need to
> > complicate everything.
> >
> 
> Willy, I know the difference between musl and nolibc, the musl code
> referenced here is only used to clear my confusion about "the
> relationship among crt.h, sys.h and arch.h" I mentiond above.

OK, but even so, our includes are "private" and do not necessarily need
to be organized like other projects. That doesn't mean that good ideas
from other ones should not help us decide, of course, I just mean that
it's normal to see differences.

> BTW, I do think nolibc have more using scenes, I like it very much and
> have used it in my own "Linux Lab" open source project [1] to let it
> work as the minimal rootfs to speed up kernel features learning and
> development, I do like the 'kernel-only deployments' feature behind
> nolibc [2], although there is something like "Unikernel Linux" [3], but
> that differs from a normal Linux system and is more complicated ;-)
> 
> I'm even imaging using it with a pure-header shell and a pure-header gui
> to let them further work together as a tiny rtos ;-)

I'm not denying the possibilities for other use cases. I still have
somewhere a small 1MB kernel image+rootfs that is sufficient to SSH into
remotely or download and flash a firmware image over tftp/http/serial,
so I see pretty well how this can be useful, and suspect this could
eventually happen again. But doing incremental changes that don't seem
to go in a particular direction is not much helpful and complicates
participation from everyone.

However of course, if someone comes and say "I'd like to use it in this
or that environment but for this I need all that", it's easier to follow
and try to steer in a direction that adapts smoothly to all users' needs.
Another point, please also remember that we moved it into the kernel to
help those who need to adjust their tests easily contribute the missing
calls (like you did for a number of things). But I tend to think that as
long as it's in the kernel, the activity should remain related to the
kernel usage. If you have bigger plans for a much larger project, the
kernel's process will slow you down and you'll experience some rejection
for breaking certain principles, so in this case such work would better
be done outside (after re-updating the original repo that I left rot for
a while).

> > > The arch-specific code in nolibc in mainline is currentl ~200 lines per
> > > arch. With this series in general it will be even less.
> > > If at some point there are many more architectures it may make sense to
> > > introduce an arch/ directory then.
> > 
> > And even then I'm not convinced because the number of archs will remain
> > low anyway.
> >
> 
> We have 8 now, the maximum may be 'ls -d arch/*/ | wc -l', it is 22
> currently ;-)

Yes but I'm not convinced that all of them will be ported there, for
various reasons ranging from lack of interest or lack of use cases, to
lack of maintainer time.

> > > > Like musl, if required, another top-level arch/ may be required to put
> > > > all of the <ARCH>/ directories together to clean up the top-level nolibc
> > > > directory.
> > > 
> > > At the moment in mainline there are 26 files in nolibc.
> > > That does not seem excessive, in fact it looks to be less than most
> > > other kernel directories.
> > 
> > Indeed :-)  Note that it started with a single one!
> 
> Yeah, I learned the history, but I do think we will have more, as the
> requirements become more and more ;-)

Sure, but it grew fast thanks to being easy to understand and locate
stuff. This should be seen as a feature I guess.

Cheers,
Willy

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2023-07-11 19:28 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-08 15:25 [PATCH v2 00/12] tools/nolibc: shrink arch support Zhangjin Wu
2023-07-08 15:26 ` [PATCH v2 01/12] tools/nolibc: rename arch-<ARCH>.h to <ARCH>/arch.h Zhangjin Wu
2023-07-09  9:56   ` Willy Tarreau
2023-07-10  7:23     ` Zhangjin Wu
2023-07-10 15:51       ` Thomas Weißschuh
2023-07-11  7:41         ` Willy Tarreau
2023-07-11 16:38           ` Zhangjin Wu
2023-07-11 19:28             ` Willy Tarreau
2023-07-08 15:27 ` [PATCH v2 02/12] tools/nolibc: split arch.h to crt.h and sys.h Zhangjin Wu
2023-07-08 15:28 ` [PATCH v2 03/12] tools/nolibc: sys.h: remove the old sys_stat support Zhangjin Wu
2023-07-08 15:29 ` [PATCH v2 04/12] tools/nolibc: crt.h: add _start_c Zhangjin Wu
2023-07-09 18:49   ` Thomas Weißschuh
2023-07-09 21:00     ` Thomas Weißschuh
2023-07-10  9:26     ` Zhangjin Wu
2023-07-10 15:24       ` Thomas Weißschuh
2023-07-10 16:45         ` Zhangjin Wu
2023-07-08 15:31 ` [PATCH v2 05/12] tools/nolibc: arm/crt.h: shrink _start with _start_c Zhangjin Wu
2023-07-08 15:32 ` [PATCH v2 06/12] tools/nolibc: aarch64/crt.h: " Zhangjin Wu
2023-07-08 15:33 ` [PATCH v2 07/12] tools/nolibc: i386/crt.h: " Zhangjin Wu
2023-07-08 15:34 ` [PATCH v2 08/12] tools/nolibc: x86_64/crt.h: " Zhangjin Wu
2023-07-08 15:35 ` [PATCH v2 09/12] tools/nolibc: mips/crt.h: " Zhangjin Wu
2023-07-08 15:36 ` [PATCH v2 10/12] tools/nolibc: loongarch/crt.h: " Zhangjin Wu
2023-07-08 15:37 ` [PATCH v2 11/12] tools/nolibc: riscv/crt.h: " Zhangjin Wu
2023-07-08 15:38 ` [PATCH v2 12/12] tools/nolibc: s390/crt.h: " Zhangjin Wu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.