From 818f27d0b969d08b7e705541e9524ce906fdc709 Mon Sep 17 00:00:00 2001 From: ZombineDev Date: Mon, 27 Nov 2017 13:58:52 +0200 Subject: [PATCH] Fix issue 18014 - dmd test suite fails to link (part 1/2) ... on Linux x86_64 distros where PIC/PIE is enforced. For more details, see: * https://wiki.gentoo.org/wiki/Hardened/Position_Independent_Code_internals * https://fedoraproject.org/wiki/Packaging:Guidelines#PIE * https://wiki.debian.org/Hardening/PIEByDefaultTransition * https://wiki.ubuntu.com/SecurityTeam/PIE * non-PIE linker support removed in Android 5.0: https://source.android.com/security/enhancements/enhancements50 * https://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/ We addressed the issues in the `dmd.conf` generated when dmd is build, the `dmd.conf` files we ship in the release packages, and the makefiles of druntime and phobos, but we haven't (yet) fixed the test suite build system. Because of that, on Linux x86_64 distros where PIC is enforced, the dmd test suite (the d_do_test.d test runner, as well as all test cases that require linking) fails to link and as a result is completely unusable. The first commit of this pull-request does the following: * adds a `PIC` variable to `test/Makefile`, which defaults to `1`, on x86_64 * exports a `PIC_FLAG` environment variable, which is set to `-fPIC` when `PIC` is set to `1` * adds `$(PIC_FLAG)` to `d_do_test.d`'s build command-line * appends `$(PIC_FLAG)` to the `REQUIRED_ARGS` variable, which is expanded in each `*.d` test case command-line The second and final commit adds the `$PIC_FLAG` environment variable to the dmd command-line in the shell-driven test cases, where the object files were linked. This was done by trial and error, by amending each failing test case, until I got the whole test suite to pass on my Ubuntu 17.10 system, minus two unrelated test failures: * `runnable/test_cdvecfill.d` - see https://issues.dlang.org/show_bug.cgi?id=18013 * runnable/test17559.d - stack traces don't work properly on my system, but I have yet to investigate the root cause. See also: * https://github.com/dlang/dmd/pull/7002 * https://github.com/dlang/druntime/pull/1880 * https://github.com/dlang/druntime/pull/1974 * https://github.com/dlang/phobos/pull/5586 * https://github.com/dlang/phobos/pull/5868 --- test/Makefile | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/test/Makefile b/test/Makefile index 7b036a96e3a9..2fb40b596122 100644 --- a/test/Makefile +++ b/test/Makefile @@ -106,6 +106,8 @@ export OBJ=.obj export DSEP=\\ export SEP=$(subst /,\,/) +PIC?=0 + DRUNTIME_PATH=..\..\druntime PHOBOS_PATH=..\..\phobos export DFLAGS=-I$(DRUNTIME_PATH)\import -I$(PHOBOS_PATH) @@ -137,6 +139,21 @@ DMD_MODEL=64 endif export DMD=../generated/$(OS)/$(BUILD)/$(DMD_MODEL)/dmd +# default to PIC on x86_64, use PIC=1/0 to en-/disable PIC. +# Note that shared libraries and C files are always compiled with PIC. +ifeq ($(PIC),) + ifeq ($(MODEL),64) # x86_64 + PIC:=1 + else + PIC:=0 + endif +endif +ifeq ($(PIC),1) + export PIC_FLAG:=-fPIC +else + export PIC_FLAG:= +endif + DRUNTIME_PATH=../../druntime PHOBOS_PATH=../../phobos # link against shared libraries (defaults to true on supported platforms, can be overridden w/ make SHARED=0) @@ -154,6 +171,8 @@ export D_OBJC=1 endif endif +DEBUG_FLAGS=$(PIC_FLAG) -g + export DMD_TEST_COVERAGE= runnable_tests=$(wildcard runnable/*.d) $(wildcard runnable/*.sh) @@ -224,7 +243,9 @@ start_fail_compilation_tests: $(RESULTS_DIR)/.created $(RESULTS_DIR)/d_do_test$( $(RESULTS_DIR)/d_do_test$(EXE): d_do_test.d $(RESULTS_DIR)/.created @echo "Building d_do_test tool" - @echo "OS: $(OS)" - $(QUIET)$(DMD) -conf= $(MODEL_FLAG) -unittest -run d_do_test.d -unittest - $(QUIET)$(DMD) -conf= $(MODEL_FLAG) -od$(RESULTS_DIR) -of$(RESULTS_DIR)$(DSEP)d_do_test$(EXE) d_do_test.d + @echo "OS: '$(OS)'" + @echo "MODEL: '$(MODEL)'" + @echo "PIC: '$(PIC_FLAG)'" + $(DMD) -conf= $(MODEL_FLAG) $(DEBUG_FLAGS) -unittest -run d_do_test.d -unittest + $(DMD) -conf= $(MODEL_FLAG) $(DEBUG_FLAGS) -od$(RESULTS_DIR) -of$(RESULTS_DIR)$(DSEP)d_do_test$(EXE) d_do_test.d