Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
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.