Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250319161210.GF1827@brightrain.aerifal.cx>
Date: Wed, 19 Mar 2025 12:12:11 -0400
From: Rich Felker <dalias@...c.org>
To: Alba Mendez <me@...a.sh>
Cc: musl@...ts.openwall.com
Subject: Re: Making user libraries Y2038 compatible?

On Tue, Mar 18, 2025 at 11:49:43PM +0100, Alba Mendez wrote:
> Hi,
> 
> First of all, sorry if I'm asking in the wrong list or if this has been
> asked already! User libraries understandably want to stay ABI and API
> compatible with the Y2038 proofness and LFS design, just like libc
> does, meaning:

musl libc does not do the LFS design. Myself and most of the community
generally feel like it was a really bad mistake glibc made.

> - on systems where time_t (and other types) are 32-bit by default,
>   offer an additional "<name>64" symbol in addition to "<name>".
> - also on these systems, "#define <name>64 <name>" in the header if
>   _TIME_BITS (or the relevant app-defined macro for the type) is 64.
> 
> This allows the library to begin providing 64-bit interfaces without
> breaking ABI, and allows it to link with a user application without
> forcing the application to use the same feature test macros as the
> library.

If you really want to do this, *please* don't make the *64() names
public API. Make it so they're automatically remapped if building on a
modern system where time_t is 64-bit or where 64-bit time_t is
available by request, and so the old symbol is just left there for ABI
compatibility with already-linked code using it.

> To do this, I think libraries need at a minimum:
> 
> - a C type that refers to the original default for that platform (i.e.
>   if no app-defined macros were present). glibc offers __ prefixed
>   types for this purpose (__time_t, __off_t, __ino_t...)
> - a preprocessor define to check if the a platform has a 32-bit default
>   (glibc offers __TIMESIZE for this purpose; this decides the size of
>   all affected types, time or size related)
> 
> In the absence of these mechanisms libraries resort to implementation-
> specific and often incorrect[1] heuristics, like testing for
> __BITS_PER_LONG==32 to see if the <name>64 symbol is needed (which is
> incorrect in modern 32-bit platforms that were defined after Y2038
> support was in place, like x32 or RV32).
> 
> Does musl provide, or would consider providing, such a mechanism? Or am
> I approaching this from the wrong angle and libraries shouldn't be
> doing this in the first place?

My leaning would be the latter. That ship really already sailed on
musl a long time ago, unlike on glibc, since 64-bit time_t has been
the only option since we first shipped it, and 32-bit is just there as
ABI-compat with legacy binaries.

If you are making a library that itself wants to do like musl and
provide ABI-compat with existing binaries by using a new remapped
symbol name for the time64 versions of your interfaces, I think the
canonical way to probe is with some kind of test for the symbol
remapping. Maybe something like, if sizeof(long)<sizeof(time_t),
compiling a .c file referencing time() and checking nm(1) for whether
it references a symbol named "time" or something else ("time64").

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.