Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Jun 2016 00:57:55 -0400
From:      Peter Wemm <peter@wemm.org>
To:        freebsd-arch@freebsd.org
Subject:   Re: PowerPC 64-bit time_t
Message-ID:  <575A48D3.3090008@wemm.org>
In-Reply-To: <20160609193128.GB34204@spindle.one-eyed-alien.net>
References:  <3FB65E20-0376-4041-86DE-F8CAB7F37314@freebsd.org> <20160609193128.GB34204@spindle.one-eyed-alien.net>

next in thread | previous in thread | raw e-mail | index | archive | help
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
>> 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.

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.

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.

* 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.

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..).

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.

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.

-- 
Peter Wemm - peter@wemm.org; peter@FreeBSD.org; peter@yahoo-inc.com; KI6FJV
UTF-8: for when a ' or ... just won\342\200\231t do\342\200\246



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?575A48D3.3090008>