Hi, Willy > Hi Zhangjin, > > On Sun, Jul 16, 2023 at 02:16:36AM +0800, Zhangjin Wu wrote: > > 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: > (...) > > First, good news, it looks OK from the nolibc-test perspective and > by looking at the code, so I merged all this into branch > > 20230715-nolibc-next-1 > Thanks very much. > Second, bad news, my preinit code doesn't build anymore due to missing > definitions for statx. It's built using the default method which involves > just including nolibc.h (and getting linux includes from the default path). > I could simplify it to this one-liner: > > $ printf "int test_stat(const char *p, struct stat *b) { return stat(p,b); }\n" | > gcc -c -o test.o -xc - -nostdlib -include ./sysroot/x86/include/nolibc.h > > In file included from ././sysroot/x86/include/nolibc.h:98:0, > from <command-line>:32: > ././sysroot/x86/include/sys.h:952:78: warning: 'struct statx' declared inside parameter list will not be visible outside of this definition or declaration > int sys_statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf) > ^~~~~ > ././sysroot/x86/include/sys.h:962:74: warning: 'struct statx' declared inside parameter list will not be visible outside of this definition or declaration > int statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf) > ^~~~~ > ././sysroot/x86/include/sys.h: In function 'statx': > ././sysroot/x86/include/sys.h:964:51: warning: passing argument 5 of 'sys_statx' from incompatible pointer type [-Wincompatible-pointer-types] > return __sysret(sys_statx(fd, path, flags, mask, buf)); > ^~~ > ././sysroot/x86/include/sys.h:952:5: note: expected 'struct statx *' but argument is of type 'struct statx *' > int sys_statx(int fd, const char *path, int flags, unsigned int mask, struct statx *buf) > ^~~~~~~~~ > ././sysroot/x86/include/sys.h: In function 'stat': > ././sysroot/x86/include/sys.h:971:15: error: storage size of 'statx' isn't known > struct statx statx; > ^~~~~ > ././sysroot/x86/include/sys.h:974:60: error: 'STATX_BASIC_STATS' undeclared (first use in this function) > ret = __sysret(sys_statx(AT_FDCWD, path, AT_NO_AUTOMOUNT, STATX_BASIC_STATS, &statx)); > ^~~~~~~~~~~~~~~~~ > ././sysroot/x86/include/sys.h:974:60: note: each undeclared identifier is reported only once for each function it appears in > > I finally found that it's due to the lack of -Isysroot/x86/include, so > it used to get linux includes from those provided by glibc and these ones > were missing statx since packaged for an older kernel. > So, your local glibc may be older than 2.28 (The one we mentioned in the commit message who supports statx)? mine 2.31 glibc is ok: $ ldd --version ldd (Ubuntu GLIBC 2.31-0ubuntu9.2) 2.31 Copyright (C) 2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Written by Roland McGrath and Ulrich Drepper. // anyone of the following commands work $ echo -e "int test_stat(const char *p, struct stat *b) { return stat(p,b); }\n" | gcc -c -o test.o -xc - -nostdlib -include sysroot/x86/include/nolibc.h $ echo -e "int test_stat(const char *p, struct stat *b) { return stat(p,b); }\n" | gcc -c -o test.o -xc - -nostdlib -Isysroot/x86/include -include ../../../include/nolibc/nolibc.h $ echo -e "int test_stat(const char *p, struct stat *b) { return stat(p,b); }\n" | gcc -c -o test.o -xc - -nostdlib -include ../../../include/nolibc/nolibc.h For older Linux systems without a newer libc may really require the installation of the linux sysroot (linux/uapi). In Ubuntu 20.04, the "struct statx" is provided by the linux-libc-dev package: $ dpkg -S /usr/include/linux/ linux-libc-dev:amd64: /usr/include/linux $ dpkg -l | grep linux-libc-dev ii linux-libc-dev:amd64 5.4.0-88.99 amd64 Linux Kernel Headers for development ii linux-libc-dev-arm64-cross 5.4.0-59.65cross1 all Linux Kernel Headers for development (for cross-compiling) ii linux-libc-dev-armel-cross 5.4.0-59.65cross1 all Linux Kernel Headers for development (for cross-compiling) ii linux-libc-dev-i386-cross 5.4.0-59.65cross1 all Linux Kernel Headers for development (for cross-compiling) ii linux-libc-dev-riscv64-cross 5.4.0-21.25cross1 all Linux Kernel Headers for development (for cross-compiling) $ grep "struct statx" -ur /usr/include/linux/ /usr/include/linux/stat.h: * Timestamp structure for the timestamps in struct statx. /usr/include/linux/stat.h:struct statx_timestamp { /usr/include/linux/stat.h:struct statx { /usr/include/linux/stat.h: struct statx_timestamp stx_atime; /* Last access time */ /usr/include/linux/stat.h: struct statx_timestamp stx_btime; /* File creation time */ /usr/include/linux/stat.h: struct statx_timestamp stx_ctime; /* Last attribute change time */ /usr/include/linux/stat.h: struct statx_timestamp stx_mtime; /* Last data modification time */ /usr/include/linux/stat.h: * Query request/result mask for statx() and struct statx::stx_mask. /usr/include/linux/stat.h:#define STATX__RESERVED 0x80000000U /* Reserved for future struct statx expansion */ This may be relative to glibc version, it is a dep of libc package: Package: libc6-dev Source: glibc Version: 2.36-9 Architecture: amd64 Maintainer: GNU Libc Maintainers <debian-glibc@xxxxxxxxxxxxxxxx> Installed-Size: 11954 Depends: libc6 (= 2.36-9), libc-dev-bin (= 2.36-9), linux-libc-dev, libcrypt-dev, libnsl-dev, rpcsvc-proto > I knew that sooner or later I'd have to reinstall this machine but I > can't get out of my head that to date I have yet not been convinced by > the absolute necessity of this modification which is progressively adding > more burden :-/ Time will tell... > This may also let us think about the removing of <linux/xxx.h> from our nolibc headers? just like musl does ;-) $ grep "include <linux" -ur ../../../include/nolibc/ ../../../include/nolibc/stdlib.h:#include <linux/auxvec.h> ../../../include/nolibc/sys.h:#include <linux/fs.h> ../../../include/nolibc/sys.h:#include <linux/loop.h> ../../../include/nolibc/sys.h:#include <linux/time.h> ../../../include/nolibc/sys.h:#include <linux/auxvec.h> ../../../include/nolibc/sys.h:#include <linux/fcntl.h> /* for O_* and AT_* */ ../../../include/nolibc/sys.h:#include <linux/stat.h> /* for statx() */ ../../../include/nolibc/sys.h:#include <linux/prctl.h> ../../../include/nolibc/types.h:#include <linux/mman.h> ../../../include/nolibc/types.h:#include <linux/reboot.h> /* for LINUX_REBOOT_* */ ../../../include/nolibc/types.h:#include <linux/stat.h> ../../../include/nolibc/types.h:#include <linux/time.h> If simply put all of them to types.h, it may be too much, a new "sys/" directory with almost the same Linux type files may be required, but as an in-kernel libc, this duplication may be a "big" issue too, so, adding minimal required macros and structs in types.h may be another choice. After removing the duplicated ones, it is not that much: ../../../include/nolibc/stdlib.h:#include <linux/auxvec.h> ../../../include/nolibc/sys.h:#include <linux/fs.h> ../../../include/nolibc/sys.h:#include <linux/loop.h> ../../../include/nolibc/sys.h:#include <linux/time.h> ../../../include/nolibc/sys.h:#include <linux/fcntl.h> /* for O_* and AT_* */ ../../../include/nolibc/sys.h:#include <linux/stat.h> /* for statx() */ ../../../include/nolibc/sys.h:#include <linux/prctl.h> ../../../include/nolibc/types.h:#include <linux/mman.h> ../../../include/nolibc/types.h:#include <linux/reboot.h> /* for LINUX_REBOOT_* */ The required new macros and structs may be around 100-300 lines? but it may help to avoid the installation of sysroot completely and also avoid the cross including the linux-libc-dev package used by glibc? Best regards, Zhangjin > Cheers, > Willy