This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCHv3 00/24] ILP32 support in ARM64


On 02/15/2015 11:03 AM, Rich Felker wrote:
> On Sun, Feb 15, 2015 at 10:41:36AM -0500, Zack Weinberg wrote:
>> On Sat, Feb 14, 2015 at 11:23 PM, Rich Felker <dalias@libc.org> 
>> wrote:
>>> On Sat, Feb 14, 2015 at 02:18:15PM -0500, Zack Weinberg wrote:
>>>> 
>>>> I have to say that I think tv_nsec (and tv_usec) being 
>>>> specified as bare 'long' is a spec bug _in and of itself_. The
>>>>  various *_t types exist precisely to make this sort of problem
>>>>  go away.  As such, I am inclined to think that the _proper_
>>>> fix is to file DRs to that effect, and then invent 'nseconds_t'
>>>> and use it.  Unconditionally - not just for 
>>>> ILP32-on-64-bit-kernel.
>>> 
>>> POSIX does that nonsense, yes. ISO C, not so much. There's 
>>> utterly no reason for the type of tv_nsec to be abstract like 
>>> this,
>> 
>> If you don't consider this very thread to demonstrate adequate 
>> reason for the type of tv_nsec to be abstract, then there's 
>> probably no point me arguing it with you any further, but ...
> 
> Bugs in an implementation are not automatically a reason to change a 
> specification. If you don't understand that there's probably no point
> in arguing with you.

I really do not see this as an implementation bug.  I see this as a
_spec_ bug.  POSIX.1b failed to foresee that putting a bare 'long' field
in a structure passed in and out of the kernel by reference would cause
problems for implementations that want to support LP64 and ILP32 ABIs on
the same kernel.  ISO C picked up the structure definition verbatim
without noticing that there was a problem. (Do you honestly think ISO C
wouldn't have copied over a hypothetical nseconds_t if it had already
been there in POSIX?)

...
> How is this a "sufficiently egregious case"? It's ONE 
> essentially-unused configuration of ONE implementation where 
> implementors failed to read the spec.

If you go back and look at the discussion on l-k, they (specifically,
HJ, H. Peter Anvin, and Linus, if I understand correctly) _did_ read the
spec and they decided it was wrong.

(from yr reply to HJ):
> There will never be more than 1000000000 nanoseconds in a second, and
> LONG_MAX is necessarily larger than 1000000000. Forcing all programs
> that are printing tv_nsec with %ld to change to %jd and cast the
> argument to (intmax_t) is not reasonable.

I sympathize somewhat with this argument, although I expect the
overwhelming majority of programs print tv_nsec by converting it to
_double_ for ease of combination with tv_sec.

However, it can be dealt with by appropriate requirements on the
underlying type:

    nseconds_t

        Used to count fractions of a second in nanoseconds.

        nseconds_t shall be an integer type able to represent values
        in the range [0, 1000000000).  For compatibility with
        historical practice, nseconds_t shall be signed and shall
        have integer conversion rank no larger than that of 'long'.

This effectively requires that the underlying type be either `int` or
`long`, which gives exactly the amount of flexibility that the kernel
needs in order to use the same clock_gettime etc. for both LP64 and ILP32:

    typedef __S32_TYPE __nseconds_t;

    struct timespec {
        __time_t tv_sec;
    #if __BYTE_ORDER == __BIG_ENDIAN
        __S32_TYPE   __unused;
        __nseconds_t tv_nsec;
    #else
        __nseconds_t tv_nsec;
        __S32_TYPE   __unused;
    #endif
    };

And then change the kernel not to read or write the __unused field.
On the affected ABIs, AFAIK it is reliably safe to pass an int to printf
using %ld because the arguments are either in registers that get
automatically extended to 64 bits, or they are in stack slots that are
required to be padded to 64 bits at the high end (whichever end that is).

zw


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]