Discussion:
PowerPC 64-bit time_t
Justin Hibbits
2016-06-09 17:41:52 UTC
Permalink
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.

Any thoughts?

- Justin
Brooks Davis
2016-06-09 19:31:28 UTC
Permalink
Post by Justin Hibbits
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.

For powerpc, I'd be tempted to just break the ABI and leave a way to switch
it back for people who build products where the ABI change is an issue.

-- Brooks
Nathan Whitehorn
2016-06-09 20:00:09 UTC
Permalink
Post by Brooks Davis
Post by Justin Hibbits
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.
For powerpc, I'd be tempted to just break the ABI and leave a way to switch
it back for people who build products where the ABI change is an issue.
-- Brooks
I would agree with this.
-Nathan
Peter Wemm
2016-06-10 04:57:55 UTC
Permalink
Post by Brooks Davis
Post by Justin Hibbits
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 - ***@wemm.org; ***@FreeBSD.org; ***@yahoo-inc.com; KI6FJV
UTF-8: for when a ' or ... just won\342\200\231t do\342\200\246
Bruce Evans
2016-06-24 10:55:01 UTC
Permalink
Post by Peter Wemm
Post by Brooks Davis
Post by Justin Hibbits
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.
Post by Peter Wemm
Post by Brooks Davis
Post by Justin Hibbits
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.
Post by Peter Wemm
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.
* 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.
Post by Peter Wemm
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.
Post by Peter Wemm
* 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.
Post by Peter Wemm
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.
Post by Peter Wemm
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.
Post by Peter Wemm
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
Poul-Henning Kamp
2016-06-24 11:07:10 UTC
Permalink
--------
Post by Bruce Evans
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'd recommend it, dates one timezones worth before epoch are far too
common in contemporary traffic (particular HTTP).

Why don't we make a i387[1] port where time_t is 64 bit and where we jettison
the museum-ready IBM PC baggage ?


[1] Of course a joke reference to floating point HW being mandatory.
--
Poul-Henning Kamp | UNIX since Zilog Zeus 3.20
***@FreeBSD.ORG | TCP/IP since RFC 956
FreeBSD committer | BSD since 4.3-tahoe
Never attribute to malice what can adequately be explained by incompetence.
Poul-Henning Kamp
2016-06-24 11:10:05 UTC
Permalink
--------
Post by Poul-Henning Kamp
--------
Post by Bruce Evans
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'd recommend it, dates one timezones worth before epoch are far too
common in contemporary traffic (particular HTTP).
It's too warm here: read: I'd recommend *against* it.
Post by Poul-Henning Kamp
Why don't we make a i387[1] port where time_t is 64 bit and where we jettison
the museum-ready IBM PC baggage ?
[1] Of course a joke reference to floating point HW being mandatory.
--
Poul-Henning Kamp | UNIX since Zilog Zeus 3.20
FreeBSD committer | BSD since 4.3-tahoe
Never attribute to malice what can adequately be explained by incompetence.
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
--
Poul-Henning Kamp | UNIX since Zilog Zeus 3.20
***@FreeBSD.ORG | TCP/IP since RFC 956
FreeBSD committer | BSD since 4.3-tahoe
Never attribute to malice what can adequately be explained by incompetence.
John Baldwin
2016-06-24 17:12:13 UTC
Permalink
Post by Poul-Henning Kamp
--------
Post by Bruce Evans
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'd recommend it, dates one timezones worth before epoch are far too
common in contemporary traffic (particular HTTP).
Why don't we make a i387[1] port where time_t is 64 bit and where we jettison
the museum-ready IBM PC baggage ?
The common proposal has been to have a freebsd/i386t64 (or some other name).
Technically speaking FreeBSD/i386 is already FreeBSD/i486dx anyway (we
mandate cmpxchg and an FPU. We might support an external FPU on 486, but
that hasn't been tested in a long, long time).

It has been pointed out that we can actually make this work by adding a new
Elf ABI and that the i386 kernel could support both ABIs by simply choosing
the appropriate sysent. For userland we could have a /usr/libt32 or some
such that is built with the old ABI similar to /usr/lib32 on amd64 and
powerpc64. You could then "stage" this by providing /usr/libt32 for a while
and letting people do a cutover where they set a src.conf knob to switch
the "default" ABI from plain i386 to i386t64 (depending on /usr/libt32 to
run existing binaries during installworld, etc.). We would probably change
the default ABI of the next X.0 release to use the new ABI for i386.

However, someone has to want to do this to put in the work.
--
John Baldwin
Adrian Chadd
2016-06-24 19:31:27 UTC
Permalink
[snip]

We could just call the architecture i486. :-)



-adrian

Doug Rabson
2016-06-09 19:37:44 UTC
Permalink
Well you have to maintain the kernel's syscall ABI, which basically means
adding new syscalls for anything which is affected.
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.
Any thoughts?
- Justin
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
Justin Hibbits
2016-06-09 20:09:40 UTC
Permalink
This would only be needed if syscall ABI compatibility is required,
right? Considering the current support state and userbase of powerpc,
a simple binary option of 32 vs 64 should be sufficient, I believe.
For i386 it's a different story, since it's much more widely used (and
tier1) so backwards compatibility is 100% necessary.

- Justin
Post by Doug Rabson
Well you have to maintain the kernel's syscall ABI, which basically
means adding new syscalls for anything which is affected.
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.
Any thoughts?
- Justin
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-arch
To unsubscribe, send any mail to "freebsd-arch-
Garance A Drosehn
2016-06-09 20:22:50 UTC
Permalink
Post by Justin Hibbits
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.
Any thoughts?
I don't know if it would help to look at the changes done back when
sparc64 went to a 64-bit time_t. I did a lot of that work, but I'll
have to admit I remember almost nothing about the changes.
--
Garance Alistair Drosehn = ***@rpi.edu
Senior Systems Programmer or ***@FreeBSD.org
Rensselaer Polytechnic Institute; Troy, NY; USA
Justin Hibbits
2016-06-09 20:38:34 UTC
Permalink
Post by Garance A Drosehn
Post by Justin Hibbits
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.
Any thoughts?
I don't know if it would help to look at the changes done back when
sparc64 went to a 64-bit time_t. I did a lot of that work, but I'll
have to admit I remember almost nothing about the changes.
--
Rensselaer Polytechnic Institute; Troy, NY; USA
Thanks. The UPDATING.64BIT file you created for the upgrade path for
sparc64 is an excellent source for the headaches involved with source
based upgrades from 32-bit time_t to 64-bit.

- Justin
Continue reading on narkive:
Loading...