Explicitly pass -fno-PIC to C compiler on linux
ClosedPublic

Authored by watashi on Oct 31 2018, 6:22 PM.

Details

Summary

Recent gcc on some linux ditributions may have -fPIC on by default

$ uname -a
Linux watashi-arch32 4.18.5-arch1-1.0-ARCH #1 SMP PREEMPT Tue Aug 28 20:45:30 CEST 2018 i686 GNU/Linux
$ gcc --version
gcc (GCC) 7.3.1 20180312
$ touch dummy.c
$ gcc -Q -v dummy.c 2>&1 | grep PIC
options enabled:  -fPIC -fPIE -faggressive-loop-optimizations

This results in following error for i686:

$ TEST=T13366 make test
...
c-iserv.bin: /home/watashi/github/ghc/libraries/ghc-prim/dist-install/build/HSghc-prim-0.5.3.o:
unknown symbol `_GLOBAL_OFFSET_TABLE_'
ghc-stage2: unable to load package `ghc-prim-0.5.3'
...

As our runtime linker doesn't support R_386_GOTPC relocations at all (Trac #15847).
Also while we don't have such problem on x86_64, it's not desired to build PIC objects either.

Test Plan

Diff Detail

Repository
rGHC Glasgow Haskell Compiler
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
watashi created this revision.Oct 31 2018, 6:22 PM

I'm not sure I understand the problem here. Why is there a missing symbol error?

Also I don't know if this fix will be enough. It's common for Haskell packages to include C files, and while those C files are probably compiled using GHC by Cabal, I could imagine that there might be cases where the C files are compiled using bare gcc invocations, and then we wouldn't get the chance to add -fno-PIC.

watashi edited the summary of this revision. (Show Details)Nov 2 2018, 1:20 PM
watashi updated the Trac tickets for this revision.

@simonmar I created tickets with more details:

Trac #15847: We don't support loading non-PIC .o on i386, this is why I noticed this issue
Trac #15848: This is what this diff is trying to address

Why is there a missing symbol error?

PIC code on i386 is much more complex than x86_64, I think the _GLOBAL_OFFSET_TABLE_ symbol is allocated at linking time and is missing in this case.
Even if we have this symbol, we still don't support PIC relocations for i386 and probably need symbol extras or jump islands as we do for x86_64 for handle it.

I could imagine that there might be cases where the C files are compiled using bare gcc invocations, and then we wouldn't get the chance to add -fno-PIC.

Yes, I think in such case, it's the responsibility of the author to make sure they pass correct flags to gcc.
Some combinations may not work.
We can apply similar fix to common Haskell tool chains that we are aware of.

simonmar accepted this revision.Nov 5 2018, 2:16 AM

Trac Trac #15847: We don't support loading non-PIC .o on i386, this is why I noticed this issue

I think you meant "We don't support loading PIC .o on i386", but yes I see. Thanks for the fix!

compiler/main/DynFlags.hs
5514

Add "Trac #15847" here

This revision is now accepted and ready to land.Nov 5 2018, 2:16 AM
watashi marked an inline comment as done.Nov 28 2018, 3:44 PM
watashi updated this revision to Diff 18922.Nov 28 2018, 3:44 PM

add reference to track ticket in the comment

This revision was automatically updated to reflect the committed changes.