summaryrefslogtreecommitdiff
path: root/testsuite
diff options
context:
space:
mode:
authorSylvain HENRY <hsyl20@gmail.com>2015-11-11 12:31:31 +0100
committerBen Gamari <ben@smart-cactus.org>2015-11-11 12:31:42 +0100
commit109d7ce85aadbd9fb7a322a0a83548e5d4e83926 (patch)
treebd367f2d0c1559f1a811322989c116d09576094f /testsuite
parentf0f9365fd7fe1a4c06926f390a6183449c3c6332 (diff)
downloadhaskell-109d7ce85aadbd9fb7a322a0a83548e5d4e83926.tar.gz
Systools: read ELF section without calling readelf
This patch tackles two issues: 1) GHC stores a "link info" string into a ELF section. Initially a section with type "note" was used but GHC didn't follow the ELF specification which specifies a record-based format for these sections. With D1375 we switched to a "progbits" section type for which there isn't any format constraint. This is an issue for D1242 which use GCC's --gc-sections which collects "unused" sections, such as our section containing link info... In this patch, we fall back to a section with type "note" but we respect the specified format. 2) Reading back the ELF section was done by parsing the result of a call to "readelf". Calling readelf is problematic because the program may not be available or it may be renamed on some platforms (see D1326). Moreover we have no garanty that its output layout will stay the same in future releases of readelf. Finally we would need to fix the parsing to support "note" sections because of 1. Instead, this patch proposes to use Data.Binary.Get to directly read the "link info" note into its section. ELF has a specification, hence it should work on every conforming platform. This patch "reverts" D1375, hence it supersedes D1432. It makes D1326 not necessary anymore. Test Plan: - recomp011 should pass (test that relinking is avoided when both "link info" match) - we should add a test for ELF objects with more than 0xff00 sections => added test "recomp015" - we should check that GAS generates 32-bit words with .int on every supported platform using ELF (or find a place where this is documented). harbomaster and I (@hsyl20) only tested on x86-64. On platforms where it is not true, it should make recomp011 fail. => tested to work on Linux/amd64, Solaris/i386 and OpenBSD/amd64 Reviewers: olsner, ony, thomie, kgardas, austin, bgamari Reviewed By: thomie, bgamari Subscribers: kgardas, rwbarton, thomie Differential Revision: https://phabricator.haskell.org/D1381 GHC Trac Issues: #10974, #11022
Diffstat (limited to 'testsuite')
-rw-r--r--testsuite/tests/driver/recomp015/Generate.hs7
-rw-r--r--testsuite/tests/driver/recomp015/Makefile39
-rw-r--r--testsuite/tests/driver/recomp015/all.T7
-rw-r--r--testsuite/tests/driver/recomp015/recomp015.stderr0
-rw-r--r--testsuite/tests/driver/recomp015/recomp015.stdout6
5 files changed, 59 insertions, 0 deletions
diff --git a/testsuite/tests/driver/recomp015/Generate.hs b/testsuite/tests/driver/recomp015/Generate.hs
new file mode 100644
index 0000000000..059c763dd6
--- /dev/null
+++ b/testsuite/tests/driver/recomp015/Generate.hs
@@ -0,0 +1,7 @@
+import Control.Monad (forM_)
+
+main :: IO ()
+main = forM_ [0..0xffff] $ \i -> do
+ putStrLn $ ".section s" ++ show i ++ ",\"\",@progbits"
+ putStrLn $ ".asciz \"Section " ++ show i ++ "\""
+ putStrLn ""
diff --git a/testsuite/tests/driver/recomp015/Makefile b/testsuite/tests/driver/recomp015/Makefile
new file mode 100644
index 0000000000..9f7ebc0b7f
--- /dev/null
+++ b/testsuite/tests/driver/recomp015/Makefile
@@ -0,0 +1,39 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+# -fforce-recomp makes lots of driver tests trivially pass, so we
+# filter it out from $(TEST_HC_OPTS).
+TEST_HC_OPTS_NO_RECOMP = $(filter-out -fforce-recomp,$(TEST_HC_OPTS))
+
+# Recompilation tests
+
+clean:
+ rm -f *.o *.hi
+ rm -f ManySections.s Main.hs
+ rm -f Main$(exeext)
+ rm -f Generate$(exeext)
+
+recomp015: clean
+ # Generate a file with more than 0xff00 sections to force different ELF
+ # fields to be used (ELF header fields are limited to 16-bit).
+ #
+ # You can confirm that fields of section 0 entry are used to store the
+ # number of section (size field of section 0) and the index of the .shstrtab
+ # section (link field of section 0) with:
+ # readelf -t ManySections.o | less
+ # and/or
+ # readelf -t Main | less
+ #
+ # This test checks that GHC can read these fields correctly and avoids
+ # recompilation (just like recomp011 which does the same thing for a smaller
+ # number of sections)
+ '$(TEST_HC)' $(TEST_HC_OPTS_NO_RECOMP) Generate.hs
+ ./Generate > ManySections.s
+ echo 'main = putStrLn "Running main..."' > Main.hs
+ '$(TEST_HC)' $(TEST_HC_OPTS_NO_RECOMP) -c ManySections.s
+ '$(TEST_HC)' $(TEST_HC_OPTS_NO_RECOMP) --make -O Main.hs ManySections.o
+ ./Main
+ sleep 1
+ '$(TEST_HC)' $(TEST_HC_OPTS_NO_RECOMP) --make -O Main.hs ManySections.o
+ ./Main
diff --git a/testsuite/tests/driver/recomp015/all.T b/testsuite/tests/driver/recomp015/all.T
new file mode 100644
index 0000000000..ff86cafa38
--- /dev/null
+++ b/testsuite/tests/driver/recomp015/all.T
@@ -0,0 +1,7 @@
+# Test for the ELF parser: more than 0xff00 sections (use different ELF fields)
+
+test('recomp015',
+ [ clean_cmd('$MAKE -s clean') ],
+ run_command,
+ ['$MAKE -s --no-print-directory recomp015'])
+
diff --git a/testsuite/tests/driver/recomp015/recomp015.stderr b/testsuite/tests/driver/recomp015/recomp015.stderr
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testsuite/tests/driver/recomp015/recomp015.stderr
diff --git a/testsuite/tests/driver/recomp015/recomp015.stdout b/testsuite/tests/driver/recomp015/recomp015.stdout
new file mode 100644
index 0000000000..a7dbad203a
--- /dev/null
+++ b/testsuite/tests/driver/recomp015/recomp015.stdout
@@ -0,0 +1,6 @@
+[1 of 1] Compiling Main ( Generate.hs, Generate.o )
+Linking Generate ...
+[1 of 1] Compiling Main ( Main.hs, Main.o )
+Linking Main ...
+Running main...
+Running main...