[PATCH v4 00/18] tools/nolibc: shrink arch support

From: Zhangjin Wu
Date: Sat Jul 15 2023 - 14:18:05 EST


Hi, Willy, Thomas

Thanks very much for your careful review and great suggestions, now, we
get v4 revision of the arch shrink series [1], it mainly include a new
fixup for -O0 under gcc < 11.1.0, the stackprotector support for
_start_c(), new testcases for startup code and two new test targets.

All of the tests passed or skipped (tinyconfig + few options +
qemu-system) for both -Os and -O0:

arch/board | result
------------|------------
arm/versatilepb | 165 test(s): 158 passed, 7 skipped, 0 failed => status: warning.
arm/vexpress-a9 | 165 test(s): 158 passed, 7 skipped, 0 failed => status: warning.
arm/virt | 165 test(s): 158 passed, 7 skipped, 0 failed => status: warning.
aarch64/virt | 165 test(s): 158 passed, 7 skipped, 0 failed => status: warning.
i386/pc | 165 test(s): 158 passed, 7 skipped, 0 failed => status: warning.
x86_64/pc | 165 test(s): 158 passed, 7 skipped, 0 failed => status: warning.
mipsel/malta | 165 test(s): 158 passed, 7 skipped, 0 failed => status: warning.
loongarch64/virt | 165 test(s): 158 passed, 7 skipped, 0 failed => status: warning.
riscv64/virt | 165 test(s): 158 passed, 7 skipped, 0 failed => status: warning.
s390x/s390-ccw-virtio | 165 test(s): 158 passed, 7 skipped, 0 failed => status: warning.

And more, for both -Os and -O0:

$ for r in run-user run-nolibc-test run-libc-test; do make clean > /dev/null; make $r | grep status; done
165 test(s): 157 passed, 8 skipped, 0 failed => status: warning
165 test(s): 157 passed, 8 skipped, 0 failed => status: warning
165 test(s): 153 passed, 12 skipped, 0 failed => status: warning

// for make run-user, the euid0 and 32bit limit related tests are
// skipped
$ make clean && make run-user
$ grep -i skip run.out
17 chroot_root [SKIPPED]
39 link_dir [SKIPPED]
62 limit_intptr_min_32 [SKIPPED]
63 limit_intptr_max_32 [SKIPPED]
64 limit_uintptr_max_32 [SKIPPED]
65 limit_ptrdiff_min_32 [SKIPPED]
66 limit_ptrdiff_max_32 [SKIPPED]
67 limit_size_max_32 [SKIPPED]

// for run-libc-test, the _auxv variables, euid0, 32bits limit and
// stackprotector related tests are skipped
$ make clean && make run-libc-test
$ grep -i skip run.out
9 environ_auxv [SKIPPED]
10 environ_total [SKIPPED]
12 auxv_addr [SKIPPED]
17 chroot_root [SKIPPED]
39 link_dir [SKIPPED]
62 limit_intptr_min_32 [SKIPPED]
63 limit_intptr_max_32 [SKIPPED]
64 limit_uintptr_max_32 [SKIPPED]
65 limit_ptrdiff_min_32 [SKIPPED]
66 limit_ptrdiff_max_32 [SKIPPED]
67 limit_size_max_32 [SKIPPED]
0 -fstackprotector not supported [SKIPPED]

$ make clean >/dev/null; make run-libc-test CC=/labs/linux-lab/src/examples/musl-install/bin/musl-gcc | grep status
165 test(s): 151 passed, 12 skipped, 2 failed => status: failure

// The failures are expected for musl has disabled both sbrk and brk
// but not the sbrk(0); the _auxv variables, euid0, 32bits limit and
// stackprotector related tests are skipped for musl too

$ grep FAIL -ur run.out
9 sbrk = 1 ENOMEM [FAIL]
10 brk = -1 ENOMEM [FAIL]

$ grep "SKIP" -ur run.out
9 environ_auxv [SKIPPED]
10 environ_total [SKIPPED]
12 auxv_addr [SKIPPED]
17 chroot_root [SKIPPED]
39 link_dir [SKIPPED]
62 limit_intptr_min_32 [SKIPPED]
63 limit_intptr_max_32 [SKIPPED]
64 limit_uintptr_max_32 [SKIPPED]
65 limit_ptrdiff_min_32 [SKIPPED]
66 limit_ptrdiff_max_32 [SKIPPED]
67 limit_size_max_32 [SKIPPED]
0 -fstackprotector not supported [SKIPPED]

For stackprotector, gcc 13.1.0 is used to test on x86_64 standalonely:

$ make run-user CROSS_COMPILE=x86_64-linux- | grep status
165 test(s): 157 passed, 8 skipped, 0 failed => status: warning
$ grep stack -ur run.out
0 -fstackprotector [OK]
$ make run-nolibc-test CROSS_COMPILE=x86_64-linux- | grep status
165 test(s): 157 passed, 8 skipped, 0 failed => status: warning
$ grep stack -ur run.out
0 -fstackprotector [OK]

Changes from v3 --> v4:

* tools/nolibc: arch-*.h: add missing space after ','
tools/nolibc: fix up startup failures for -O0 under gcc < 11.1.0

Both of the above changes are for _start, it is able to merge them
if necessary.

The first one is old for format errors reported by
scripts/checkpatch.pl

The second one is for -O0 failure under gcc < 11.1.0, applied the
optimize("-Os", "omit-frame-pointer") suggestion from Thomas.

* tools/nolibc: remove the old sys_stat support

As suggested by Willy, Document carefully about the statx supported
Linux version info.

* tools/nolibc: add new crt.h with _start_c

The code is polished carefully for smaller size and better
readability.

* tools/nolibc: stackprotector.h: add empty __stack_chk_init for !_NOLIBC_STACKPROTECTOR
tools/nolibc: crt.h: initialize stack protector

As suggested by Thomas, init stackprotector in _start_c() too.

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

Removed the stackprotector initialization from _start too, we
already have it in _start_c().

* selftests/nolibc: add EXPECT_PTRGE, EXPECT_PTRGT, EXPECT_PTRLE, EXPECT_PTRLT
selftests/nolibc: add testcases for startup code

Add a new startup test group to cover the testing of argc,
argv/argv0, envp/environ and _auxv.

Some testcases are enhanced, some are newly added from after the
discussion during v3 review.

* selftests/nolibc: allow run nolibc-test locally
selftests/nolibc: allow test -include /path/to/nolibc.h

Two new test targets are added to cover more scenes.

Hope you like this revisoin ;-)

Next patchset is powerpc & powerpc64 support, after that we will send
the v2 of tinyconfig support, at last the left rv32 patches (mainly
64bit time).

Best regards,
Zhangjin
---
[1]: https://lore.kernel.org/lkml/20230715100134.GD24086@xxxxxx/

Zhangjin Wu (18):
tools/nolibc: arch-*.h: add missing space after ','
tools/nolibc: fix up startup failures for -O0 under gcc < 11.1.0
tools/nolibc: remove the old sys_stat support
tools/nolibc: add new crt.h with _start_c
tools/nolibc: stackprotector.h: add empty __stack_chk_init for
!_NOLIBC_STACKPROTECTOR
tools/nolibc: crt.h: initialize stack protector
tools/nolibc: arm: shrink _start with _start_c
tools/nolibc: aarch64: shrink _start with _start_c
tools/nolibc: i386: shrink _start with _start_c
tools/nolibc: x86_64: shrink _start with _start_c
tools/nolibc: mips: shrink _start with _start_c
tools/nolibc: loongarch: shrink _start with _start_c
tools/nolibc: riscv: shrink _start with _start_c
tools/nolibc: s390: shrink _start with _start_c
selftests/nolibc: add EXPECT_PTRGE, EXPECT_PTRGT, EXPECT_PTRLE,
EXPECT_PTRLT
selftests/nolibc: add testcases for startup code
selftests/nolibc: allow run nolibc-test locally
selftests/nolibc: allow test -include /path/to/nolibc.h

tools/include/nolibc/Makefile | 1 +
tools/include/nolibc/arch-aarch64.h | 57 +---------
tools/include/nolibc/arch-arm.h | 83 ++-------------
tools/include/nolibc/arch-i386.h | 62 ++---------
tools/include/nolibc/arch-loongarch.h | 46 +-------
tools/include/nolibc/arch-mips.h | 76 ++-----------
tools/include/nolibc/arch-riscv.h | 69 ++----------
tools/include/nolibc/arch-s390.h | 63 ++---------
tools/include/nolibc/arch-x86_64.h | 58 ++--------
tools/include/nolibc/crt.h | 61 +++++++++++
tools/include/nolibc/stackprotector.h | 2 +
tools/include/nolibc/sys.h | 63 ++---------
tools/include/nolibc/types.h | 4 +-
tools/testing/selftests/nolibc/Makefile | 12 +++
tools/testing/selftests/nolibc/nolibc-test.c | 106 ++++++++++++++++++-
15 files changed, 246 insertions(+), 517 deletions(-)
create mode 100644 tools/include/nolibc/crt.h

--
2.25.1