[some mailing lists appear to have classified the earlier mail as spam, it was quite long and contained a lot of links. See https://lists.debian.org/debian-arm/2020/03/msg00032.html for the start of the thread if you did not get that]
On Wed, Mar 11, 2020 at 3:37 PM Lukasz Majewski lukma@denx.de wrote:
- stat()/fstat()/lstat(), nanosleep(), wait3()/wait4(), ppoll_chk() are some of the other interfaces that take a time_t based argument and need to grow a time64 version to avoid an ABI
mismatch.
The stat() and friends will use statx internally, which supports 64 bit time from the outset. Unfortunately, it hasn't been yet converted.
As statx was added in 4.1 (IIRC) - after the minimal supported Linux kernel version is bumped to this version (from 3.2 as now) it all will be fixed.
The problem I had with these was not on the kernel API side (I still have CONFIG_COMPAT_32BIT_TIME enabled for now) but on the application side. In particular, the 'struct stat' definition (when __USE_XOPEN2K8 is defined) contains
struct timespec st_atim;
and similar fields that are interpreted using 64-bit time_t in the application including the header, but with 32-bit time_t inside of the ___fxstat64() implementation in glibc. The problem is caused by the mismatched ABI, not by the time_t overflow, in the same way that happens in the nptl library callers and in the other interfaces I mentioned. This is also what seems to cause most of the testcase failures when the tests are built with __TIME_BITS=64.
- The timeval prototype appears to be broken, as it's missing padding on architectures without native alignment of __time64 (e.g. i386) and on all big-endian architectures.
You mean the one "exported" to the system or one, which is internal to glibc (from ./include/time.h)?
I mean in the installed headers, where I get (after preprocessing)
typedef long long __time64_t; typedef long __suseconds_t; struct timeval { __time64_t tv_sec; __suseconds_t tv_usec; };
On i386 and m68k, this leads to a 12 byte structure when the kernel interfaces expect a 16 byte structure. All other 32-bit architectures add four byte padding at the end, so the size is correct, but on big-endian systems, kernel also expects padding *before* tv_usec, in the same way as the timespec definition does. IIRC the best way to handle this is with a 64-bit suseconds_t, e.g. by adding a __suseconds64_t defined the same way as __time64_t.
I have spent more time on this now than I had planned, and don't expect to do further work on it anytime soon, but I hope my summary is useful to others that are going to need this later. I can obviously share my patches and build artifacts if anyone needs them.
Could you upload them to any server? (kernel.org or github)?
I have uploaded the modified debian-glibc and rebootstrap sources to https://git.linaro.org/people/arnd/ now, this should be all that's needed to recreate the build, using these steps:
- build an x86-64 debian glibc-2.31 package (binary plus source) based on the glibc package data - create a pbuilder instance with that available as a source to apt - log into the pbuilder and run the modified bootstrap.sh according to information on the pbuilder web page.
The binary packages I created are not as useful, as they would not work with any build of glibc, neither the version I built, nor any fixed one. I could find a way to send that to you in private, but it's hundreds of megabytes.
Unfortunately I lost the build logs during a crash yesterday.
There are two additional approaches that would likely get a Debian bootstrap further, but that I have not tried as they were previously dismissed:
- Adding a time64 armhf as a separate (incompatible) target in glibc that defines __TIMESIZE==64 and a 64-bit __time_t would avoid most of the remaining ABI issues and put armhf-time64 in the same category as riscv32 and arc, but this idea was so far rejected by
the glibc maintainers.
As fair as I know riscv32 and arc will use generic syscall interface. The arm32 bit doesn't support it - so the code from those two aforementioned ports will not be used.
The differences between the generic syscall interface and the arm version are much smaller than ABI differences between the ABIs for 32-bit __time_t and the __time_t == __time64_t version.
In particular, as such a new port could mandate a minimum kernel of v5.1, it could just use all the time64 syscalls, the split sysvipc and statx as a baseline.
Arnd