Date: Sat, 10 Aug 2019 13:58:08 -0400 From: Rich Felker <dalias@...c.org> To: libc-alpha@...rceware.org Cc: musl@...ts.openwall.com Subject: time64 abi choices for glibc and musl Note: this email is to glibc list and particularly seeking feedback from glibc folks, but CC'd to musl list as well. As far as I can tell, most time64 work/discussion on the glibc side so far has been about implementation mechanisms and symbol-binding ABI aspects, and one aspect that doesn't seem to have been addressed is making good choices about the actual types involved. Some of them have been done: struct timespec (endian-matching padding) struct timeval (64-bit suseconds_t) struct itimerspec, itimerval, utimbuf, timeb (obvious definitions) but I haven't seen a clear proposal with rationale for the choices in defining: struct stat struct msqid_ds, semid_ds, shmid_ds (sysvipc) struct rusage struct timex struct utmp[x] I'd like to avoid ending up with gratuitous differences between musl's and glibc's definitions of these types, which is my direct motivation for asking now, but I'd also like to help ensure glibc makes well-justified choices rather than just overlooking these and getting locked into poorly thought-out ones. For struct stat, I think it's almost necessary to preserve the existing layout and add new time64 members on the end, and to continue filling in the time32 members. This is because of how struct stat is used in callback interfaces -- otherwise, glibc will need a complete duplicate of ftw/nftw for time32 vs time64. As long as the layouts are compatible on the initial overlapped part, it's fine for a time64-aware glibc's time64-aware [n]ftw to callback into a time32 application, passing it pointers to the time64 stat structs. This issue also affects ABI between pairs of libc consumers. It's common to pass struct stat pointers across library boundaries, but the party filling them is almost always the same party allocating them. As long as the overlapping part of both definitions agrees, this simply works. For the sysvipc structs, it was tempting to try to use the padding next to the time32 fields in-place (possibly with endian swapping); this was what Arnd and the kernel folks intended (except on mips where padding was omitted). However it's impossible because alignment is wrong. Almost all of the time_t members are at offsets that are 4 mod 8 on 32-bit archs. So for these musl is adding new time64 members at the end of the structs, and leaving the old time32 ones in place. I think glibc should do the same. I spent a lot of time exploring options here and there just was no other reasonable option. For rusage, timex, and utmp[x], it's less clear to me what should be done. I'd like to align what musl does with glibc at least on rusage. Does anyone from the glibc side have preferences for how it should be done? I'd rather avoid having a huge gratuitously-padded structure like x32 has, possibly keeping the time32 members in-place and just adding new time64 ones at the end, or change the ones at the beginning to time64 so that the time64 version of rusage can be filled just by making the time32 syscall with an appropriate offset (8 or 0 depending on the above choice)then expanding the time members. Either of these options also allows easy implementation of the time32 compat shim just by memcpy. There are probably a few more structs like this I've omitted -- see https://sourceware.org/glibc/wiki/Y2038ProofnessDesig for a near-complete list, but it omitted shmid_ds so it should be checked that nothing else was omitted too. The others are probably not relevant to musl which is why I haven't looked into them much. (Even utmp[x] is mostly irrelevant to us at present since musl's utmp is a stub.) Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.