Page MenuHomeFreeBSD

lang/ghc: Update for ino64
ClosedPublic

Authored by kib on May 18 2017, 3:11 PM.

Details

Summary

This change adopts the port to ino64 commit, which is explained in
https://lists.freebsd.org/pipermail/freebsd-current/2017-April/065687.html
The src change is nearly ready to commit, and is undergoing a final round
of pre-commit testing. This will likely happen in the next few days,
unless some issue found.

In general, patches for ino64 support will be conditional on FreeBSD
version. It is likely that __FreeBSD_version / kern.osreldate 1200031
will be the value used for the ino64 change, and the port patch may have
a conditional test using that value. Of course, if the final value in
the src commit is different the ports patches will be updated before
commit.

A number of ports require updates after this change is committed to src.
I seek approval of the change to the port in this review, either directly
from the maintainer or portmgr blanket approval of the set of ino64 port
updates. In either case I will commit the ports change shortly after the
src tree commit.

I am also happy if you, as maintainer of the port, wish to handle this
yourself. Please add a comment here with your preference for this port.

Diff Detail

Repository
rP FreeBSD ports repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

The ino64 src change is in review D10439

pgj added a subscriber: pgj.

I think this solution is fine for now, thank you for your work! Note that I have not tested this change myself, but I understand what it does (and the reasons why it does that) and I support it. I believe if all the dependencies build with this version of the compiler, it works just all right.

Once this greater change has settled down and the actual __FreeBSD_version value is set for it, I could just cut a new version for the bootstrap compiler and add it to the port. We have done this many times back in the past -- the reason why you cannot find many different bootstraps in the port currently because we were lucky enough to get away with a single one (in the name of minimalism). But I do not want you to wait for me until I am done with the updated bootstrap.

So, please, go ahead!

This revision is now accepted and ready to land.May 20 2017, 6:49 AM

Thank you for the prompt response.

Yes, re-bootstrap is the ultimate solution, of course. To get new bootstrap somebody needs to either cross-compile or do the tricks like I did there. Effectively, I saved the cross for bootstrap preparation.

Myself, I do not have a bandwidth to learn proper procedures for several compilers (not only ghc) affected by the ino64. Note that ino64 changes are not yet committed into src/, but are expected to land very soon, at which moment the __FreeBSD_version will be confirmed.

I think building a new bootstrap becomes easy with this change. My plan for that would be as follows: move to a FreeBSD version that has the ino64 commit, build the lang/ghc port with the trick featured here, and use it to build GHC from sources. The rest has been documented in our development wiki at GitHub.

I did not expect you to learn anything about the build procedure (since you probably had enough fun with dealing with the kernel and userland aspects) -- instead, I am very grateful that you spent time on investigating the problem and provided us with this temporary workaround.

In D10798#224572, @pgj wrote:

I think building a new bootstrap becomes easy with this change.

Would ghc shipped with the dynamically-linked runtime, the change appeared to be not necessary. It is due to the fact that runtime shipped with the bootstrap compiler, as well as installed by the port, are static, cause problem. There is no mechanism to ensure ABI compatibility for the static libraries, nor it might appear in the future. On the other hand, we do (try to) maintain ABI backward compatbility for dynamic linking.

In other words, the ino64 patch contain a lot of stuff to ensure that dynamically linked binaries worked as before, using the symbol versionining.

All right, I see it more clearly now.

In D10798#224610, @kib wrote:

It is due to the fact that runtime shipped with the bootstrap compiler, as well as installed by the port, are static, cause problem.

Are you sure of that?

I mean, I agree that the bootstrap compiler does not do too much dynamic linking in the run-time system, neither it has the problematic standard libraries, which are base and unix, dynamically linked. That is because I found if I build it with dynamically linked support libraries it significantly increases the size of the bootstrap (doubles or more). With this choice, we will indeed inevitably lose the ability to survive changes in the system ABI. I can live with this, I have never dreamed of anybody being able to offer any backward ABI compatibility for statically linked code.

But I got confused about the second part. The port, by default (via the DYNAMIC port option), should install a version of GHC that deploys and uses a dynamically-linked run-time system together with the dynamic base and unix libraries. However, I accept that if the user does not specifically ask for a dynamic binary, she will just get something that links to the static version of those libraries that might be bad for her. For some time ago, dynamic linking is default for GHC, so it is for all the Haskell ports.

In D10798#224614, @pgj wrote:
In D10798#224610, @kib wrote:

It is due to the fact that runtime shipped with the bootstrap compiler, as well as installed by the port, are static, cause problem.

Are you sure of that?

Absolutely.

I mean, I agree that the bootstrap compiler does not do too much dynamic linking in the run-time system, neither it has the problematic standard libraries, which are base and unix, dynamically linked. That is because I found if I build it with dynamically linked support libraries it significantly increases the size of the bootstrap (doubles or more). With this choice, we will indeed inevitably lose the ability to survive changes in the system ABI. I can live with this, I have never dreamed of anybody being able to offer any backward ABI compatibility for statically linked code.

No, it is exactly other way around. We (src developers) work hard to ensure that all user binaries and shared libraries that worked before, work on the new systems.

What we cannot guarantee is that static libraries can still be used. E.g., ino64 changes the layout of struct stat. To handle the libc functions which utilize the changed definition, e.g fstat(2), we provide fstat@FBSD_1.0 (compat version) and fstat@FBSD_1.5 (new version). If old code used fstat@FBSD_1.0, it gets the old layout in result and just work. Thing is, versioning only works for _finally linked_ objects, i.e. binaries and shared libraries. For .o and .a objects, versioning information is not yet accessible, it is added by the static linked AKA ld(1).

But I got confused about the second part. The port, by default (via the DYNAMIC port option), should install a version of GHC that deploys and uses a dynamically-linked run-time system together with the dynamic base and unix libraries. However, I accept that if the user does not specifically ask for a dynamic binary, she will just get something that links to the static version of those libraries that might be bad for her. For some time ago, dynamic linking is default for GHC, so it is for all the Haskell ports.

Static final binaries are fine, because we do provide compatibility syscalls as well. I.e. old ghc binary will run and output the compiled objects. What does not work is the binary which is result of statically linking of the compiled objects + old _static_ runtime and new libc. Old static runtime references just 'fstat' symbol, which is resolved to fstat@FBSD_1.5, and old runtime code gets new layout on result from the fstat call. Then the binary compiled by old compiler package on the new system fails at runtime, due to the memory corruption.

The solution is either make a hack to forcibly redirect naked symbols to their compat shims, as I did in the patch, or ship dynamic runtime, which references compat symbols due to embedding symbol version into the dynamic library which references the symbol.

Okay, but I still do not understand something: is there a problem, and if yes, what is the problem with the way rebuilding the bootstrap compiler as I drafted above?

I think I understand what you are saying, but I do not get why this would cause any problems. I assumed that if you add those static compat shims to the current version of the bootstrap compiler libraries (like you are doing in the patch), then one is able to build a fully working version of GHC. To me, this seems to be sufficient to rebuild the bootstrap compiler from the sources that could be then used to replace the existing bootstrap for systems that are newer than a given __FreeBSD_version (post-ino64). Obviously, the old version of the bootstrap would be kept used for the older ones (pre-ino64), since the new version would not work there. You can see an example of that in some older version of the port's Makefile.

In D10798#224628, @pgj wrote:

Okay, but I still do not understand something: is there a problem, and if yes, what is the problem with the way rebuilding the bootstrap compiler as I drafted above?

I think I understand what you are saying, but I do not get why this would cause any problems. I assumed that if you add those static compat shims to the current version of the bootstrap compiler libraries (like you are doing in the patch), then one is able to build a fully working version of GHC. To me, this seems to be sufficient to rebuild the bootstrap compiler from the sources that could be then used to replace the existing bootstrap for systems that are newer than a given __FreeBSD_version (post-ino64). Obviously, the old version of the bootstrap would be kept used for the older ones (pre-ino64), since the new version would not work there. You can see an example of that in some older version of the port's Makefile.

This is fine.

But if you today shipped bootstrap that uses dynamic runtime for compiled binaries, then re-creating the bootstrap for >= ino64 base would be not necessary. Similarly, older compiler installed by users would work on newer systems, if the compilers created binaries with dynamically linked runtimes. I.e., (much) less hassle for everybody.

Yes, along our discussion here, I got motivated to experiment with building a dynamically-linked version of the bootstrap that does not use any statically linked libraries. I am not sure if the GHC build system can handle this, though. But once the ino64 changes are there, I will give it a try. Until then, I am fine with your workaround.

This revision was automatically updated to reflect the committed changes.