From owner-freebsd-arch@freebsd.org Fri Jun 24 10:55:12 2016 Return-Path: Delivered-To: freebsd-arch@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 118EEB73429 for ; Fri, 24 Jun 2016 10:55:12 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail104.syd.optusnet.com.au (mail104.syd.optusnet.com.au [211.29.132.246]) by mx1.freebsd.org (Postfix) with ESMTP id A5BA326C5 for ; Fri, 24 Jun 2016 10:55:11 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from c122-106-149-109.carlnfd1.nsw.optusnet.com.au (c122-106-149-109.carlnfd1.nsw.optusnet.com.au [122.106.149.109]) by mail104.syd.optusnet.com.au (Postfix) with ESMTPS id 8F9084281F9; Fri, 24 Jun 2016 20:55:02 +1000 (AEST) Date: Fri, 24 Jun 2016 20:55:01 +1000 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Peter Wemm cc: freebsd-arch@freebsd.org Subject: Re: PowerPC 64-bit time_t In-Reply-To: <575A48D3.3090008@wemm.org> Message-ID: <20160624194454.D1013@besplex.bde.org> References: <3FB65E20-0376-4041-86DE-F8CAB7F37314@freebsd.org> <20160609193128.GB34204@spindle.one-eyed-alien.net> <575A48D3.3090008@wemm.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.1 cv=M8SwUHEs c=1 sm=1 tr=0 a=R/f3m204ZbWUO/0rwPSMPw==:117 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=kj9zAlcOel0A:10 a=fYwcVdWAvfHp3KS-F6MA:9 a=U6V5D88igUOAZD_W:21 a=EH4GcJ3lJI1tdCgS:21 a=CjuIK1q_8ugA:10 X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 24 Jun 2016 10:55:12 -0000 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 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