Allow -dead_strip linking on platforms with .subsections_via_symbols
authorMoritz Angermann <moritz@lichtzwerge.de>
Wed, 19 Nov 2014 22:38:22 +0000 (16:38 -0600)
committerAustin Seipp <austin@well-typed.com>
Wed, 19 Nov 2014 23:03:06 +0000 (17:03 -0600)
Summary:
This allows to link objects produced with the llvm code generator to be linked with -dead_strip. This applies to at least the iOS cross compiler and OS X compiler.

Signed-off-by: Moritz Angermann <moritz@lichtzwerge.de>
Test Plan: Create a ffi library and link it with -dead_strip. If the resulting binary does not crash, the patch works as advertised.

Reviewers: rwbarton, simonmar, hvr, dterei, mzero, ezyang, austin

Reviewed By: dterei, ezyang, austin

Subscribers: thomie, mzero, simonmar, ezyang, carter

Differential Revision: https://phabricator.haskell.org/D206

13 files changed:
compiler/NOTES [new file with mode: 0644]
compiler/llvmGen/LlvmCodeGen/Ppr.hs
compiler/nativeGen/PPC/Ppr.hs
compiler/nativeGen/SPARC/Ppr.hs
compiler/nativeGen/X86/Ppr.hs
testsuite/tests/llvm/should_run/Makefile [new file with mode: 0644]
testsuite/tests/llvm/should_run/subsections_via_symbols/Makefile [new file with mode: 0644]
testsuite/tests/llvm/should_run/subsections_via_symbols/SubsectionsViaSymbols.hs [new file with mode: 0644]
testsuite/tests/llvm/should_run/subsections_via_symbols/all.T [new file with mode: 0644]
testsuite/tests/llvm/should_run/subsections_via_symbols/subsections_via_symbols-libtool-quiet [new file with mode: 0755]
testsuite/tests/llvm/should_run/subsections_via_symbols/subsections_via_symbols.m [new file with mode: 0644]
testsuite/tests/llvm/should_run/subsections_via_symbols/subsections_via_symbols.stderr [new file with mode: 0644]
testsuite/tests/llvm/should_run/subsections_via_symbols/subsections_via_symbols.stdout [new file with mode: 0644]

diff --git a/compiler/NOTES b/compiler/NOTES
new file mode 100644 (file)
index 0000000..14a1f80
--- /dev/null
@@ -0,0 +1,16 @@
+Note [Subsections Via Symbols]
+
+If we are using the .subsections_via_symbols directive
+(available on recent versions of Darwin),
+we have to make sure that there is some kind of reference
+from the entry code to a label on the _top_ of of the info table,
+so that the linker will not think it is unreferenced and dead-strip
+it. That's why the label is called a DeadStripPreventer (_dsp).
+
+The LLVM code gen already creates `iTableSuf` symbols, where
+the X86 would generate the DeadStripPreventer (_dsp) symbol.
+Therefore all that is left for llvm code gen, is to ensure
+that all the `iTableSuf` symbols are marked as used.
+As of this writing the documentation regarding the
+.subsections_via_symbols and -dead_stip can be found at
+<https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/Assembler/040-Assembler_Directives/asm_directives.html#//apple_ref/doc/uid/TP30000823-TPXREF101>
\ No newline at end of file
index 9c6a719..80e8949 100644 (file)
@@ -114,12 +114,18 @@ pprInfoTable count info_lbl stat
   = do (ldata, ltypes) <- genLlvmData (Text, stat)
 
        dflags <- getDynFlags
+       platform <- getLlvmPlatform
        let setSection (LMGlobal (LMGlobalVar _ ty l _ _ c) d) = do
              lbl <- strCLabel_llvm info_lbl
              let sec = mkLayoutSection count
                  ilabel = lbl `appendFS` fsLit iTableSuf
                  gv = LMGlobalVar ilabel ty l sec (llvmInfAlign dflags) c
-                 v = if l == Internal then [gv] else []
+                 -- See Note [Subsections Via Symbols]
+                 v = if (platformHasSubsectionsViaSymbols platform
+                         && l == ExternallyVisible)
+                        || l == Internal
+                     then [gv]
+                     else []
              funInsert ilabel ty
              return (LMGlobal gv d, v)
            setSection v = return (v,[])
index e62a1c4..6851769 100644 (file)
@@ -73,12 +73,7 @@ pprNatCmmDecl proc@(CmmProc top_info lbl _ (ListGraph blocks)) =
          -- elimination, it might be the target of a goto.
             (if platformHasSubsectionsViaSymbols platform
              then
-             -- If we are using the .subsections_via_symbols directive
-             -- (available on recent versions of Darwin),
-             -- we have to make sure that there is some kind of reference
-             -- from the entry code to a label on the _top_ of of the info table,
-             -- so that the linker will not think it is unreferenced and dead-strip
-             -- it. That's why the label is called a DeadStripPreventer (_dsp).
+             -- See Note [Subsections Via Symbols]
                       text "\t.long "
                   <+> ppr info_lbl
                   <+> char '-'
index c734687..e9941b8 100644 (file)
@@ -77,12 +77,7 @@ pprNatCmmDecl proc@(CmmProc top_info lbl _ (ListGraph blocks)) =
          -- elimination, it might be the target of a goto.
             (if platformHasSubsectionsViaSymbols platform
              then
-             -- If we are using the .subsections_via_symbols directive
-             -- (available on recent versions of Darwin),
-             -- we have to make sure that there is some kind of reference
-             -- from the entry code to a label on the _top_ of of the info table,
-             -- so that the linker will not think it is unreferenced and dead-strip
-             -- it. That's why the label is called a DeadStripPreventer (_dsp).
+             -- See Note [Subsections Via Symbols]
                       text "\t.long "
                   <+> ppr info_lbl
                   <+> char '-'
index 2b37117..ddd75c8 100644 (file)
@@ -78,12 +78,7 @@ pprNatCmmDecl proc@(CmmProc top_info lbl _ (ListGraph blocks)) =
          -- elimination, it might be the target of a goto.
             (if platformHasSubsectionsViaSymbols platform
              then
-             -- If we are using the .subsections_via_symbols directive
-             -- (available on recent versions of Darwin),
-             -- we have to make sure that there is some kind of reference
-             -- from the entry code to a label on the _top_ of of the info table,
-             -- so that the linker will not think it is unreferenced and dead-strip
-             -- it. That's why the label is called a DeadStripPreventer (_dsp).
+             -- See Note [Subsections Via Symbols]
                       text "\t.long "
                   <+> ppr info_lbl
                   <+> char '-'
diff --git a/testsuite/tests/llvm/should_run/Makefile b/testsuite/tests/llvm/should_run/Makefile
new file mode 100644 (file)
index 0000000..9101fbd
--- /dev/null
@@ -0,0 +1,3 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
diff --git a/testsuite/tests/llvm/should_run/subsections_via_symbols/Makefile b/testsuite/tests/llvm/should_run/subsections_via_symbols/Makefile
new file mode 100644 (file)
index 0000000..c108a37
--- /dev/null
@@ -0,0 +1,13 @@
+TOP=../../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+# pass -dead_strip to the linker.
+HCFLAGS = -O2 -fllvm
+HCINC = $(TOP)/../includes
+
+.PHONY: subsections_via_symbols_test
+subsections_via_symbols_test:
+       '$(TEST_HC)' -o SubsectionsViaSymbols.o SubsectionsViaSymbols.hs $(HCFLAGS) -staticlib
+       '$(TEST_HC)' -o subsections_via_symbols SubsectionsViaSymbols subsections_via_symbols.m $(HCFLAGS) -optl -dead_strip -no-hs-main
+       ./subsections_via_symbols
diff --git a/testsuite/tests/llvm/should_run/subsections_via_symbols/SubsectionsViaSymbols.hs b/testsuite/tests/llvm/should_run/subsections_via_symbols/SubsectionsViaSymbols.hs
new file mode 100644 (file)
index 0000000..9725717
--- /dev/null
@@ -0,0 +1,5 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+module SymbolsViaSections where
+foreign export ccall test :: Int -> IO ()
+test :: Int -> IO ()
+test i = putStrLn (replicate i '.')
diff --git a/testsuite/tests/llvm/should_run/subsections_via_symbols/all.T b/testsuite/tests/llvm/should_run/subsections_via_symbols/all.T
new file mode 100644 (file)
index 0000000..2ecbaa5
--- /dev/null
@@ -0,0 +1,15 @@
+if config.os == 'darwin':
+  only_darwin = normal
+else:
+  only_darwin = skip
+
+
+# Note [_ffi_call_unix64]
+#
+# Please refer to https://ghc.haskell.org/trac/ghc/ticket/5019
+# for the subsections_via_symbols.stderr
+
+test('subsections_via_symbols',
+     [extra_clean(['SubsectionsViaSymbols.hi', 'SubsectionsViaSymbols.o', 'SymbolsViaSections_stub.h', 'subsections_via_symbols', 'SubsectionsViaSymbols.a', 'SymbolsViaSections.hi', 'SymbolsViaSections.o', 'subsections_via_symbols.o']),
+      only_darwin],
+     run_command, ['$MAKE -s --no-print-directory subsections_via_symbols_test'])
diff --git a/testsuite/tests/llvm/should_run/subsections_via_symbols/subsections_via_symbols-libtool-quiet b/testsuite/tests/llvm/should_run/subsections_via_symbols/subsections_via_symbols-libtool-quiet
new file mode 100755 (executable)
index 0000000..fcc0a8e
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+# Script to suppress annoying warnings from libtool (without suppressing any other interesting output)
+libtool $@ 2>&1 | sed -e "/has no symbols/D" | sed -e "/due to use of basename, truncation and blank padding/D"
\ No newline at end of file
diff --git a/testsuite/tests/llvm/should_run/subsections_via_symbols/subsections_via_symbols.m b/testsuite/tests/llvm/should_run/subsections_via_symbols/subsections_via_symbols.m
new file mode 100644 (file)
index 0000000..9fb2bc6
--- /dev/null
@@ -0,0 +1,11 @@
+#import <Foundation/Foundation.h>
+#import "HsFFI.h"
+#import "SymbolsViaSections_stub.h"
+
+int
+main(int argc, char * argv[]) {
+  hs_init(&argc, &argv);
+  atexit(&hs_exit);
+  test(10);
+  return EXIT_SUCCESS;
+}
diff --git a/testsuite/tests/llvm/should_run/subsections_via_symbols/subsections_via_symbols.stderr b/testsuite/tests/llvm/should_run/subsections_via_symbols/subsections_via_symbols.stderr
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/testsuite/tests/llvm/should_run/subsections_via_symbols/subsections_via_symbols.stdout b/testsuite/tests/llvm/should_run/subsections_via_symbols/subsections_via_symbols.stdout
new file mode 100644 (file)
index 0000000..0daadb5
--- /dev/null
@@ -0,0 +1,2 @@
+Linking subsections_via_symbols ...
+..........