From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/14549 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Zack Weinberg Newsgroups: gmane.linux.lib.musl.general,gmane.comp.lib.glibc.alpha Subject: Re: time64 abi choices for glibc and musl Date: Mon, 12 Aug 2019 12:29:55 -0400 Message-ID: References: <20190810175808.GA13205@brightrain.aerifal.cx> Reply-To: musl@lists.openwall.com Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="43995"; mail-complaints-to="usenet@blaine.gmane.org" Cc: GNU C Library , musl@lists.openwall.com To: Rich Felker Original-X-From: musl-return-14565-gllmg-musl=m.gmane.org@lists.openwall.com Mon Aug 12 18:30:26 2019 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.89) (envelope-from ) id 1hxDDG-000BME-Kk for gllmg-musl@m.gmane.org; Mon, 12 Aug 2019 18:30:26 +0200 Original-Received: (qmail 14027 invoked by uid 550); 12 Aug 2019 16:30:23 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 13995 invoked from network); 12 Aug 2019 16:30:22 -0000 X-Gm-Message-State: APjAAAW4b3BLYooID0GXKtV7G+5UynsRUEK02pDaCEoW0HTHEnQjYtAj ZcFu/tf9WaR22YrqRB1h0iyhuHkK0w/TSCmHbVM= X-Google-Smtp-Source: APXvYqws9q5cYLWB851pLA42bdqn5g/3nILXD6m24dlCMzwaFPD+2LcLwHs3moJJDRZ3uyvEWLqrvhxP5MVZ6K4xiPY= X-Received: by 2002:a5d:80c1:: with SMTP id h1mr13566430ior.268.1565627406654; Mon, 12 Aug 2019 09:30:06 -0700 (PDT) In-Reply-To: <20190810175808.GA13205@brightrain.aerifal.cx> X-Gmail-Original-Message-ID: Xref: news.gmane.org gmane.linux.lib.musl.general:14549 gmane.comp.lib.glibc.alpha:96673 Archived-At: On Sat, Aug 10, 2019 at 1:58 PM Rich Felker wrote: > 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] The sysvipc structures, struct rusage, and struct timex are passed directly from and to the kernel, so this ship has already sailed -- I don't see that we have any choice but to match the kernel's layouts of these structures in time64 mode, whether or not that is convenient for the C library or for call compatibility between procedures compiled with _TIME_BITS=32 and _TIME_BITS=64. We do have flex for struct utmp[x], which is entirely controlled by user space, and for struct stat, because the kernel is providing only statx() in the 64-bit-time ABI. Regarding struct stat, I tend to agree with Paul that having both 32- and 64-bit time fields _visible_ at the same time will cause more problems than it solves. What I would suggest is that we add the 64-bit 'struct timespec's at the end, as you suggest, and continue to write (possibly truncated) valid data to the legacy 32-bit 'struct timespec's, but the public header file _immediately_ converts the legacy fields to __reservedN fields. This should work except for when an existing _TIME_BITS=32 binary caller changes the 32-bit fields of a struct stat, passes it to a _TIME_BITS=64 callee, and expects it to notice. Is there any practical way for us to find out whether any such combination actually exists? It also occurs to me that this might mean we can share stat/fstat/lstat for _TIME_BITS=32 and =64. struct utmp[x] describes a format for long-lived files on disk, so not only do we have to keep the time field where it is, we have to make it possible for new programs to read and understand old records. And there is no padding on either side of the ut_tv field, so we would be stuck ... except that it uses struct timeval, and it's silly to track login events to sub-second precision. So I'm going to suggest that we redefine that field as a bare time64_t: #define UT_LINESIZE 32 #define UT_NAMESIZE 32 #define UT_HOSTSIZE 256 struct utmp{,x} { uint16_t ut_type; uint16_t __reserved1; uint32_t ut_pid; char ut_line[UT_LINESIZE]; char ut_id[4]; char ut_user[UT_NAMESIZE]; char ut_host[UT_HOSTSIZE]; struct exit_status { int16_t e_termination; int16_t e_exit; } ut_exit; #if __32_BIT_UT_SESSION int32_t ut_session; #else int64_t ut_session; #endif union { _Alignas(__old_time_t) uint64_t ut_time64; struct { __old_time_t tv_sec; // historic time_t for this ABI, whatever that was int32_t tv_usec; } ut_tv; }; #if __PAD_AFTER_UT_TV int32_t __reserved2; #endif int32_t ut_addr_v6[4]; char __reserved3[20]; }; We could define a new set of ut_type codes to indicate which of ut_tv and ut_time64 is meaningful. Unfortunately no such hack appears to be possible for struct lastlog, and that has the same problem. Anyone have an idea for that one? zw