[commit: ghc] master: driver: skip -Bsymbolic on unregisterised targets (Trac #15338) (8ec4899)

git at git.haskell.org git at git.haskell.org
Mon Jul 16 20:41:16 UTC 2018


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/8ec48990fee9e245bb2fe40dc6f65b61b8612157/ghc

>---------------------------------------------------------------

commit 8ec48990fee9e245bb2fe40dc6f65b61b8612157
Author: Sergei Trofimovich <slyfox at gentoo.org>
Date:   Mon Jul 16 21:38:30 2018 +0100

    driver: skip -Bsymbolic on unregisterised targets (Trac #15338)
    
    Trac #15338 is yet another example where -Bsymbolic breaks
    semantics of a C program: global variable duplication happens
    and unsafePerformIO creates two stdout copies.
    
    When -Bsymbolic is not used both C compiler and linker agree
    on how global variables are handled. In case of sh4 it consists
    on a few assertions:
    
    1. global variable is exported from shared library
    2. code is referred to this variable via GOT-like mechanism to allow
       interposition
    3. global variable is present .bss section on an executable
       (as an R_*_COPY relocation: symbol contents is copied at executable
       startup time)
    4. and symbol in executable interposes symbol in shared library.
    
    This way both code in shared library and code in executable refer
    to a copy of global variable in .bss section of an executable.
    
    Unfortunately -Bsymbolic option breaks assumption [2.] and generates
    direct references to the symbol. This causes mismatch between
    values seen from executable and values seen from shared library code.
    
    This change disables '-Bsymbolic' for unregisterised targets.
    
    Signed-off-by: Sergei Trofimovich <slyfox at gentoo.org>
    
    Test Plan: test 'ghc-pkg --version | cat' to emit data
    
    Reviewers: simonmar, bgamari, jrtc27
    
    Reviewed By: jrtc27
    
    Subscribers: rwbarton, thomie, carter
    
    GHC Trac Issues: #15338
    
    Differential Revision: https://phabricator.haskell.org/D4959


>---------------------------------------------------------------

8ec48990fee9e245bb2fe40dc6f65b61b8612157
 compiler/main/SysTools.hs | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/compiler/main/SysTools.hs b/compiler/main/SysTools.hs
index d987d7d..c3d154f 100644
--- a/compiler/main/SysTools.hs
+++ b/compiler/main/SysTools.hs
@@ -548,9 +548,12 @@ linkDynLib dflags0 o_files dep_packages
             -------------------------------------------------------------------
 
             let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }
+                unregisterised = platformUnregisterised (targetPlatform dflags)
             let bsymbolicFlag = -- we need symbolic linking to resolve
-                                -- non-PIC intra-package-relocations
-                                ["-Wl,-Bsymbolic"]
+                                -- non-PIC intra-package-relocations for
+                                -- performance (where symbolic linking works)
+                                -- See Note [-Bsymbolic assumptions by GHC]
+                                ["-Wl,-Bsymbolic" | not unregisterised]
 
             runLink dflags (
                     map Option verbFlags
@@ -607,3 +610,27 @@ getFrameworkOpts dflags platform
     -- reverse because they're added in reverse order from the cmd line:
     framework_opts = concat [ ["-framework", fw]
                             | fw <- reverse frameworks ]
+
+{-
+Note [-Bsymbolic assumptions by GHC]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+GHC has a few assumptions about interaction of relocations in NCG and linker:
+
+1. -Bsymbolic resolves internal references when the shared library is linked,
+   which is important for performance.
+2. When there is a reference to data in a shared library from the main program,
+   the runtime linker relocates the data object into the main program using an
+   R_*_COPY relocation.
+3. If we used -Bsymbolic, then this results in multiple copies of the data
+   object, because some references have already been resolved to point to the
+   original instance. This is bad!
+
+We work around [3.] for native compiled code by avoiding the generation of
+R_*_COPY relocations.
+
+Unregisterised compiler can't evade R_*_COPY relocations easily thus we disable
+-Bsymbolic linking there.
+
+See related Trac tickets: #4210, #15338
+-}



More information about the ghc-commits mailing list