[commit: ghc] master: Revert "Make LLVM output robust to -dead_strip on mach-o platforms" (1c76dd8)

git at git.haskell.org git at git.haskell.org
Thu Jun 8 19:36:17 UTC 2017


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

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/1c76dd85462c77b73c8efdefb6c959b41702ff3f/ghc

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

commit 1c76dd85462c77b73c8efdefb6c959b41702ff3f
Author: Ben Gamari <ben at smart-cactus.org>
Date:   Wed Jun 7 09:02:18 2017 -0400

    Revert "Make LLVM output robust to -dead_strip on mach-o platforms"
    
    This reverts commit 667abf17dced8b4a4cd2dc6a291a6f244ffa031f.


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

1c76dd85462c77b73c8efdefb6c959b41702ff3f
 compiler/llvmGen/LlvmCodeGen/Ppr.hs | 73 +------------------------------------
 compiler/llvmGen/LlvmMangler.hs     | 11 +++++-
 2 files changed, 12 insertions(+), 72 deletions(-)

diff --git a/compiler/llvmGen/LlvmCodeGen/Ppr.hs b/compiler/llvmGen/LlvmCodeGen/Ppr.hs
index 16c5518..8614084 100644
--- a/compiler/llvmGen/LlvmCodeGen/Ppr.hs
+++ b/compiler/llvmGen/LlvmCodeGen/Ppr.hs
@@ -21,8 +21,6 @@ import FastString
 import Outputable
 import Unique
 
-import DynFlags (targetPlatform)
-
 -- ----------------------------------------------------------------------------
 -- * Top level
 --
@@ -151,75 +149,8 @@ pprLlvmCmmDecl (CmmProc mb_info entry_lbl live (ListGraph blks))
            alias = LMGlobal funVar
                             (Just $ LMBitc (LMStaticPointer defVar)
                                            (LMPointer $ LMInt 8))
-       -- our beloved dead_strip preventer.
-       -- the idea here is to inject
-       --
-       -- module asm "_symbol$dsp = _symbol-24" -- assuming prefix
-       --                                          of <{i64, i64, i64}>
-       -- module asm ".no_dead_strip _symbol$dsp"
-       --
-       -- and thereby generating a second symbol
-       -- at the start of the info table, which is dead strip prevented.
-       --
-       -- ideally, llvm should generate these for us, but as
-       -- things stand, this is the least hacky solution to
-       -- prevent dead_stripping of the prefix data, while
-       -- retaining dead stripping in general.
-       --
-       -- The general layout of the above code results in the following:
-       --
-       --   .------------. <- @<name>$def$dsp
-       --   | Info Table |
-       --   |------------| <- @<name>, @<name>$def
-       --   | Fn Body    |
-       --   '------------'
-       --
-       -- Why this @<name> and @<name>$def?  As the textual llvm ir
-       -- generator is only handed typeless labels, it often does not
-       -- know the type of the label (e.g. function to call), until
-       -- the actual call happens.  However, llvm requires symbol
-       -- lookups to be typed.  Therefore we create the actual function
-       -- as @<name>$def, and alias a bitcast to i8* as @<name>.
-       --   Any subsequent lookup can lookup @<name> as i8* and
-       -- bitcast it to the required type once we want to call it.
-       --
-       -- Why .no_dead_strip? Doesn't this prevent the linker from
-       -- -dead_strip'ing anything? Yes, it does. And we'll have to
-       -- live with this wart until a better solution is found that
-       -- ensures that all symbols that are used directly or
-       -- indirectly are marked used.
-       --
-       -- This is all rather annoying. ghc 8.2 uses the infamous
-       -- Mangler to drop the .subsections_via_symbols directive
-       -- from the assembly.  LLVM ingeniously emits said directive
-       -- unconditionally for mach-o files.  To lift the need for
-       -- extra mangler step, we explicitly mark every symbol
-       -- .no_dead_strip.
-       --
-       -- We are making a few assumptions here:
-       -- - the symbols end up being name _<symbol> in the final
-       --   assembly file.
-       --
-       dsp <- case mb_info of
-         Nothing -> pure empty
-         Just (Statics _ statics)
-           | platformHasSubsectionsViaSymbols (targetPlatform dflags) -> do
-               infoStatics <- mapM genData statics
-               -- remember, the prefix_size is in bits!
-               let prefix_size = sum (map (llvmWidthInBits dflags . getStatType)
-                                          infoStatics)
-                   dspName = defName `appendFS` fsLit "$dsp"
-                   defSymbol = text "_" <> ftext defName
-                   dspSymbol = text "_" <> ftext dspName
-                   moduleAsm s = text "module asm" <+> doubleQuotes s
-               return $ text "; insert dead_strip preventer"
-                      $+$ moduleAsm (dspSymbol <+> text "=" <+> defSymbol
-                                     <> text "-" <> int (prefix_size `div` 8))
-                      $+$ moduleAsm (text ".no_dead_strip" <+> dspSymbol)
-                      $+$ text "; end dead_strip preventer"
-           | otherwise -> pure empty
-
-       return (ppLlvmGlobal alias $+$ ppLlvmFunction fun' $+$ dsp, [])
+
+       return (ppLlvmGlobal alias $+$ ppLlvmFunction fun', [])
 
 
 -- | The section we are putting info tables and their entry code into, should
diff --git a/compiler/llvmGen/LlvmMangler.hs b/compiler/llvmGen/LlvmMangler.hs
index acf344f..eed13ba 100644
--- a/compiler/llvmGen/LlvmMangler.hs
+++ b/compiler/llvmGen/LlvmMangler.hs
@@ -47,11 +47,20 @@ type Rewrite = DynFlags -> B.ByteString -> Maybe B.ByteString
 -- | Rewrite a line of assembly source with the given rewrites,
 -- taking the first rewrite that applies.
 rewriteLine :: DynFlags -> [Rewrite] -> B.ByteString -> B.ByteString
-rewriteLine dflags rewrites l =
+rewriteLine dflags rewrites l
+  -- We disable .subsections_via_symbols on darwin and ios, as the llvm code
+  -- gen uses prefix data for the info table.  This however does not prevent
+  -- llvm from generating .subsections_via_symbols, which in turn with
+  -- -dead_strip, strips the info tables, and therefore breaks ghc.
+  | isSubsectionsViaSymbols l =
+    (B.pack "## no .subsection_via_symbols for ghc. We need our info tables!")
+  | otherwise =
     case firstJust $ map (\rewrite -> rewrite dflags rest) rewrites of
       Nothing        -> l
       Just rewritten -> B.concat $ [symbol, B.pack "\t", rewritten]
   where
+    isSubsectionsViaSymbols = B.isPrefixOf (B.pack ".subsections_via_symbols")
+
     (symbol, rest) = splitLine l
 
     firstJust :: [Maybe a] -> Maybe a



More information about the ghc-commits mailing list