PowerPC 64-bit time_t
Bruce Evans
brde at optusnet.com.au
Fri Jun 24 10:55:12 UTC 2016
On Fri, 10 Jun 2016, Peter Wemm wrote:
> On 6/9/16 3:31 PM, Brooks Davis wrote:
>> On Thu, Jun 09, 2016 at 01:41:52PM -0400, Justin Hibbits wrote:
>>> At the devsummit earlier today I mentioned for FreeBSD 12 wanting 64-
>>> bit time_t across the board. It was pointed out that the only ones
FreeBSD-12 certainly doesn't want the bloat and ABI breakage of 64-bit
time_t. The 32nd bit is not needed before FreeBSD-23 in 2038. The 33rd
bit is not needed before FreeBSD-57 in 2106.
>>> with 32-bit time_t are i386 and powerpc (32-bit). I've made the
>>> changes necessary for at least kernel (world is still building right
>>> now), but it's obviously an ABI and KBI incompatible change.
>>> Addressing KBI is a nonissue, as that's expected to break at major
>>> releases. ABI is another issue. I'm unsure how to properly address
>>> ABI breakage -- bumping libc's .so version, or reversion all symbols
>>> that use something with time_t, or something else. If I can address
>>> it before the code freeze, it could be done for FreeBSD 11, which
>>> leaves about 6 hours from now.
>>
>> For i386, the only practical option is going to be a new TARGET_ARCH and
>> likely ELF machine type.
The only practical option for i386 is to change to unsigned time_t before
2038 and hope that i386 goes away before that runs out in 2106. Changing
to uint32_t time_t mainly requires doing something with times before the
Epoch. These are unsupported in POSIX, but are supposed to work back to
1902 with int32_t in FreeBSD, except 1 second before the Epoch is the
same as the error code (time_t)(-1) so it doesn't work right.
> I investigated this when I did 64 bit time_t on amd64 - the chances of
> getting this to work on i386 are ... problematic.. to say the least.
>
> A short summary of the issues for i386:
>
> * sparc64, amd64 and ia64 were "easy" because there was an actual register to
> implement it. Calling conventions plaster over vast quantities of sins and
> carelessness and make it Just Work by in spite of it. You forget a function
> prototype and it still works. i386 has to do it with "long long" which
> requires discipline. Miss a prototype and it falls flat.
On 64-bit arches, most of the space bloat for 64-bit time_t is unavoidable
because:
- args are expanded to 64 bits
- struct timeval was originally misdesigned as having members tv_sec and
tv_usec of type long. These longs were basically an implementation of
int_least32_t before <stdint.h> existed. tv_usec only needs to go up
to 10**9, so it should have type precisely int_least32_t or possibly
int32_t to give an invariant ABI. POSIX copied this mistake and added
many more when it made the mistake of inventing struct timespec. ts_nsec
stil has type long. This gives the stupid ABI that on 64-bit arches
with 32-bit time_t, struct timespec starts with a 32-bit time_t, then
has 32 bits of padding, then has a 64-bit long with only 32-bits used.
Later, POSIX broke the ABI for struct timeval to match -- it changed
'long tv_sec' to time_t tv_sec.
So using 64-bit time_t costs little on 64-bit arches.
> eg: if you miss the prototype for a function returning time_t the language
> defaults the return value to "int". On ia64, amd64 and sparc64, this is
> actually returned as a 64 bit value (native register) and it actually gets
> the full 64 bit value. For i386, this doesn't happen - you always get
> truncation. You won't find out until it actually matters. This problem will
> keep turning up forever. The top half will be returned in the %edx secondary
> return register and will be ignored.
Forever only afer 2038 :-). And between 2038 and 2106, 32-bit time_t will
still almost work without making it officially unsigned -- discarding the
top half still gives a value that is correct when the sign bit is
interpreted as a value bit, provided it was set using overflow magic as
a value bit.
> * classic 3rd party code used "long" and "time_t" interchangeably. We get
> away with this on ia64, amd64 and sparc64 just fine. This will also lead to
> truncation on i386 with 64 bit time_t when it matters.
>
> * Sloppy prototyping leads to stack misalignment on i386 with "long long".
> Arguments are rounded up to 32 bit alignment, so char/short/int/long
> confusion on i386 for function calling protocol mostly is repaired as a side
> effect. 'long long' doesn't get this treatment for function calls - any
> sloppiness will be punished with arguments being shifted. Unlike the
> truncation above, this is pretty quick to find. You won't have to wait 5-10
> years for them to shake out.
>
> Most of the FreeBSD base tree was fixed for this during the Alpha era (which
> used "int" for time_t on a 64 bit platform because mktime() in libc wasn't 64
> bit safe at all). However, when you go near ports and 3rd party code the
> situation is rather grim. The code out there is terrible.
>
> I maintain that while we got away with it for machines that the calling
> conventions masked the pain for sloppy and legacy programming, this is not
> the case for architectures like i386. The pain will never end.
I agree.
> Do you want to be the one who has to explain why something like openssl isn't
> rejecting expired certificates because openssl happens to confuse long/time_t
> internally somewhere in the X509 validator? (Note: I'm not saying it is
> broken, but I don't have a hard time imagining that it could..).
The question is if changing 32-bit time_t to unsigned is also too painful.
I think it won't make much difference until 2038 when the 32nd bit is
actually used.
> Also, don't forget all the compat_freebsd32 layers. You'll have to realign
> all the arguments because 'long long' is 32 bit aligned, and a 64 bit long
> (aka time_t) is 64 bit aligned.
Also, they need to do something better than truncation to convert 64-bit
time_t to 32-bit time_t. The only reasonable thing to do between 2038
and 2106 is to use uint32_t for the compatibility layers and teach old
applications to expect this.
Then there are the compat_{linux,svr*} layers. All representations and
conversions must be compatible with whatever the emulated OS does.
> I'm sure it could be done for a science project, but I wouldn't want to go
> anywhere near it for something that would be relied upon. This would be a
> project that gives gifts that will keep on giving.
Bruce
More information about the freebsd-arch
mailing list