[PATCH 2/3] msqid: Provide internal copy of struct __msqid64_ds
Lukasz Majewski
lukma@denx.de
Thu Nov 12 15:27:17 GMT 2020
Hi Adhemerval,
> On 11/11/2020 20:57, Lukasz Majewski wrote:
> > Hi Adhemerval,
> >
> >> On 09/11/2020 21:02, Lukasz Majewski wrote:
> >>> Hi Joseph, Adhemerval,
> >>>
> >>>> On Mon, 9 Nov 2020, Lukasz Majewski wrote:
> >>>>
> >>>>>> If in a particular case defining the struct tag as a macro is
> >>>>>> unsafe,
> >>>>>
> >>>>> Could you explain why having construct as:
> >>>>>
> >>>>> #define timespec __timespec64 in
> >>>>> ./time/bits/types/struct_timespec.c is unsafe (after having the
> >>>>> file ./time/bits/types/struct___timespec64.c exported)?
> >>>>
> >>>> I think "#define stat __stat64_time64" is unsafe, since people
> >>>> may do "#undef stat" to get a function rather than a macro (and
> >>>> thereby suppress the macro expansion for the struct tag as well).
> >>>>
> >>>> I'm less sure there would be any problems with "#define timespec
> >>>> __timespec64". The POSIX namespace rules are clearer on e.g.
> >>>> what's reserved with file scope, than on what's reserved as a
> >>>> macro name that the user mustn't undefine.
> >>>>
> >>>
> >>> Please correct me if I'm wrong, but the scheme shall be
> >>> consistent. Which approach shall be taken then?
> >>
> >> As Joseph has put, some header name space allows the use of use
> >> identifiers prefix by the implementation. However, there are
> >> restriction as well of what the implementation is allowed to do,
> >> check the 'Name Space' part at the POSIX definition [1].
> >
> > Thanks for sharing the link. Now I do understand a bit more.
> >
> >>
> >> For instance, for the sys/msg.h interface we can export the
> >> 'struct msqid64_ds' type since 'msg' is a reserve prefix. And I
> >> think that doing
> >>
> >> #if __TIMESIZE == 32 && defined __USE_TIME_BITS64
> >> # define msqid_ds __msqid64_ds
> >> #endif
> >>
> >> For 'sys/msg.h' should be safe as well.
> >
> > According to the link [1] - the "msg" prefix is reserved in the
> > 'sys/msg.h', but we do #define msqid_ds - the msq prefix is not
> > reserved...
> >
> > Is this correct?
>
> Indeed, I overlooked this case. It seems we will need to go on the
> same route I laid out for 'struct timespec' for the SysV interface
> as well. It would require to change some arch-specific files I was
> expecting to have to touch, but it seems there is no better option.
You may also consider reusing following patches:
https://github.com/lmajewski/y2038_glibc/commit/e7acba0ea587afab875f62eb132608ba6a679af5
https://github.com/lmajewski/y2038_glibc/commit/4c42b58c539af778dc17476187fa8330db37d7d2
https://github.com/lmajewski/y2038_glibc/commit/0ade361931988d6918888019d233335c82acc087
>
> >
> >>
> >> However, doing:
> >>
> >> #if __TIMESIZE == 32 && defined __USE_TIME_BITS64
> >> # define timespec __timespec64
> >> #endif
> >>
> >> It is not allowed since 'timespec' does not fall on the reserved
> >> namespace of 'time.h' header.
> >
> > Definately - the timespec is not reserved in the time.h name space.
> >
> >> As indicated by Joseph, if in a
> >> particular case defining the struct tag as a macro is unsafe (as
> >> for timespec), we would need to redefine the struct member itself
> >> depending of the _TIME_BITS.
> >>
> >> It means that for timespec, we will need to do something as:
> >>
> >> 1. On 'time/bits/types/struct_timespec.h' define 'struct
> >> timespec' as:
> >>
> >> struct timespec
> >> {
> >> #if __TIMESIZE == 32 && defined __USE_TIME_BITS64
> >> __tim64_t tv_sec; /* Seconds. */
> >> #else
> >> __time_t tv_sec;
> >> #endif
> >> #if __WORDSIZE == 64 \
> >> || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) \
> >> || __TIMESIZE == 32
> >> __syscall_slong_t tv_nsec; /* Nanoseconds. */
> >> #else
> >> # if __BYTE_ORDER == __BIG_ENDIAN
> >> int: 32; /* Padding. */
> >> long int tv_nsec; /* Nanoseconds. */
> >> # else
> >> long int tv_nsec; /* Nanoseconds. */
> >> int: 32; /* Padding. */
> >> # endif
> >> #endif
> >> };
> >>
> >
> > I do follow this approach - such implementation is in [2].
>
> Yeah, I though we would be able to simplify the boilerplate required,
> but it seems we are constrained by the POSIX namespace names.
Ok.
>
> >
> >>
> >> 2. And for the interfaces that uses it, on time/time.h:
> >>
> >> [...]
> >> #ifdef __USE_POSIX199309
> >> [...]
> >> #if __TIMESIZE == 64 || !defined __USE_TIME_BITS64
> >> extern int nanosleep (const struct timespec *__requested_time,
> >> struct timespec *__remaining);
> >> #else
> >> # ifdef __REDIRECT_NTH
> >> extern int __REDIRECT_NTH (nanosleep (const struct timespec
> >> *__requested_time, struct timespec *__remaining),
> >> __nanosleep64);
> >> # else
> >> /* This might not be safe, but I don't see a better way to do it
> >> without __REDIRECT_NTH support. */
> >> # define nanosleep __nanosleep64
> >> # endif
> >>
> >
> > This is also done in the code from [2]. However, there is no need to
> > have
> > #if __TIMESIZE == 64 || !defined __USE_TIME_BITS64
> > as we override it when __USE_TIME_BITS64 is defined
> >
> >>
> >> 3. It would be good to add a internal tests to check if the
> >> export ABI for timespec does in fact match the internal
> >> definition. A test that does something:
> >>
> >> #define _TIME_SIZE 64
> >>
> >> _Static_assert (sizeof (struct timespec)
> >> == sizeof (struct __timespec64),
> >> ...);
> >>
> >> _Static_assert (sizeof ((struct timespec){0}.tv_sec)
> >> == sizeof ((struct __timespec64){0}.tv_nsec),
> >> ...);
> >> _Static_assert (offsetof (struct timespec, tv_sec)
> >> == offsetof (struct __timespec64, tv_sec),
> >> ...);
> >> _Static_assert (sizeof ((struct timespec){0}.tv_nsec)
> >> == sizeof ((struct __timespec64){0}.tv_nsec),
> >> ...);
> >> _Static_assert (offsetof (struct timespec, tv_nsec)
> >> == offsetof (struct __timespec64, tv_nsec),
> >> ...);
> >>
> >
> > This would be welcome, I will add such simple check when I add
> > __USE_TIME_BITS64 support (i.e. Y2038 support).
> >
> >> I don't think it needs test for the internal fields (unless
> >> the implementation does use it in some way, which I don't think it
> >> is the case).
> >>
> >
> > Ok.
> >
> >>
> >> 4. For timespec we should change all symbols that uses it,
> >> including compound types.
> >
> > Yes - this is also done in patch [2]. For example struct itimerspec
> > is adjusted as well.
> >
> >>
> >>
> >> 5. We need to make sure glibc does not build or define _TIME_SIZE
> >> internally (we already have issues if user tries to enable the LFS
> >> support, so it should be ok as-is with default values).
> >
> > Do you think about _TIME_BITS=64 when the code is compiled
> > (-D_TIME_BITS=64)?
> > When -D_TIME_BITS=64 is passed during compilation of user program,
> > the __USE_TIME_BITS64 is set to 1 in exported headers, so aliasing
> > for Y2038 is enabled.
>
> I meant building glibc itself, not user programs using glibc provided
> headers. It is to ensure that internally 'struct timespec' (or any
> affected struct by 64-bit time) will have 32-bit ABI layout for ABIs
> that supports it since glibc itself includes installed headers.
>
Could you elaborate on this?
I do guess that _TIME_BITS when added to glibc (i.e. when it will be
recognized by "exported" headers) will enable 64 bit time support on
archs with __WORDSIZE=32 (e.g. ARM 32 bit).
Then, after some time, we will add #define _TIME_BITS 64 at e.g.
features.h (exported) on eligible ports, which would mean that by
default support for 64 bit time is enabled on them.
Am I correct?
> >
> > I'm not sure about the role of _TIME_SIZE. I only recall the
> > __TIMESIZE which is set depending on __WORDSIZE (or explicitly to
> > 64 on e.g. RISC-V).
>
> My understanding is _TIME_SIZE will be the compiler flag used by the
> programs to define which time ABI they want to use.
Yes, this is also my understanding.
>
> >
> >>
> >>
> >> I think I have outlined what is required, but I might have
> >> overlooked something.
> >
> > So to sum up:
> >
> > - When prefix is reserved in POSIX namespaces [1] it may be allowed
> > to export __foo64 struct and make the aliasing in the corresponding
> > exported header.
> >
> > - Otherwise, we need an internal glibc copy of the struct (i.e.
> > struct __timespec64) and also corresponding exported struct (i.e.
> > struct timespec) needs to be adjusted when __USE_TIME_BITS64 is
> > defined.
> >
> > The second case seems to be pervasive and is already utilized in my
> > WIP patch [2].
>
> I think to simplify we should for [2] as you initially suggested. I
> though we could mimic LFS support, but for y2038 support it seems that
> we will need to re-define the types without using different names for
> the affected types.
Ok.
>
> >
> >>
> >>
> >> [1]
> >> https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html
> >>
> >
> >
> > Links:
> >
> > [2] -
> > https://github.com/lmajewski/y2038_glibc/commit/b5d9a0881ccc0a06e520c495ce7409f8e077fb20#diff-8297a1191cc06a8a7af6fc6ac33af4bef2d7d72efd901d1634d910b56631e0c7R13
> >
>
Best regards,
Lukasz Majewski
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <https://sourceware.org/pipermail/libc-alpha/attachments/20201112/e681d4a1/attachment.sig>
More information about the Libc-alpha
mailing list