This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: Fifth draft of the Y2038 design document
Hi Joseph,
On Wed, 22 Feb 2017 16:59:21 +0000, Joseph Myers
<joseph@codesourcery.com> wrote :
> I don't think the description of how APIs are mapped to 64-bit versions is
> right.
>
> You say "New 32-bit symbols would be named after their corresponding
> 32-bit symbol plus "64", e.g. the 64-bit implementation of clock_gettime
> would be named clock_gettime64.". But actually, as per a following point,
> the ABI symbol should be named __clock_gettime64, in the implementation
> namespace. And there shouldn't be a public API called clock_gettime64 at
> all (hopefully), the way to use the 64-bit versions should be
> -D_TIME_BITS=64 (and then calling clock_gettime).
You're correct that the ABI is actually __clock_gettime64, not
clock_gettime64.
Regarding the public API, the problem is that a single GLIBC dynamic
library might need to provide a 32-bit time public API to some
dynamically linked executables and a 64-bit time public API to others.
So the existing (32-bit time) public API symbol 'clock_gettime' has to
remain for 32-bit time callers, and another one needs to be provided
for 64-bit time callers -- that is the one which would be named
'clock_gettime64'.
> You refer to "#define clock_gettime clock_gettime64". But #define is only
> used for remapping in the case of non-__GNUC__ compilers without an
> implementation of __REDIRECT, a case that probably hasn't worked with
> glibc's headers for years. The remapping should be done with __REDIRECT,
> and such #define only if __REDIRECT is not defined.
>
> Similarly there might be an internal __time64_t, but not a public type by
> the time64_t name. And remapping struct tags is only possible with
> #define, which may be problematic, not with typedef, and can't be done at
> all for existing tags because of effects on C++ name mangling; struct
> timespec should probably have tag timespec in any case, with its contents
> differing depending on _TIME_BITS (just like struct stat has contents
> depending on _FILE_OFFSET_BITS).
I think I get it. To sum things up, keeping the clock_gettime example,
user code would #include this:
/* Give user 'time_t', either 32 or 64 bits */
#ifdef __USE_TIME_BITS64
typedef __time64_t time_t;
#else
typedef __time_t time_t;
# endif
/* Give user 'struct timespec', either 32 or 64 bits */
struct timespec {
time_t tv_sec;
long tv_nsec
};
/* Give user 'clock_gettime', either 32 or 64 bits */
#ifdef __USE_TIME_BITS64
extern int __clock_gettime64(clockid_t __clock_id, struct
timespec *__tp);
# if defined(__REDIRECT)
extern int __REDIRECT(clock_gettime,(clockid_t __clock_id,
struct timespec *__tp), __clock_gettime64);
# else
# define clock_gettime __clock_gettime64
# endif
#else /* !__USE_TIME_BITS_64 */
/* the original definition (does not use __REDIRECT) */
extern int clock_gettime (clockid_t __clock_id, struct timespec
*__tp) __THROW;
#endif
(comments here are for clarification only)
I think the above does not define any public time64_t type, defines a
proper 'struct timespec' without using #define, and uses __REDIRECT
(with a fallback to #define if __REDIRECT is not available, as is done
in GLIBC) so that the source code uses the 'common' name but the
object code uses the 64-bit-time variant. Is that how it should be done?
Cordialement,
Albert ARIBAUD
3ADEV