Check for -z,defs, -z,relro, -fPIC, -fPIE before using them

Those flags are not available on all platforms, and omitting them when
not available will not cause any harm. In particular:

-z,defs disallows undefined symbols in object files. This option is
unsupported if the target binary format enforces the same condition
already. Furthermore it is only a compile time sanity check. When it is
omitted, the same binary is produced.

-z,relro instructs the loader to mark sections read-only after loading
the library, where possible. This is a hardening mechanism. If it is
unavailable, the functionality of the code is not affected in any way.

-fPIC instructs the compiler to produce position independent code. While
this is preferable to relocatable code, relocatable code also works and
may even be faster. Relocatable code might just be loaded into memory
multiple times for different processes.

-fPIE is the same thing as -fPIC for executables rather than shared
libraries.

Signed-off-by: Ulf Hermann <ulf.hermann@qt.io>
diff --git a/ChangeLog b/ChangeLog
index 9253c0a..6214622 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* configure.ac: Check if -fPIC, -fPIE, -Wl,-z,defs,
+	and -Wl,-z,relro are supported by the compiler.
+
 2017-08-02  Mark Wielaard  <mark@klomp.org>
 
 	* configure.ac: Set version to 0.170.
diff --git a/backends/ChangeLog b/backends/ChangeLog
index a66e923..79b50eb 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-27  Ulf Hermann <ulf.hermann@qt.io>
+
+	* Makefile.am: Use dso_LDFLAGS.
+
 2017-07-27  Mark Wielaard  <mark@klomp.org>
 
 	* sparc_reloc.def: GOTDATA_OP_HIX22, GOTDATA_OP_LOX10 and
diff --git a/backends/Makefile.am b/backends/Makefile.am
index 37dc2d2..0fde0cb 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -129,10 +129,10 @@
 	@rm -f $(@:.so=.map)
 	$(AM_V_at)echo 'ELFUTILS_$(PACKAGE_VERSION) { global: $*_init; local: *; };' \
 	  > $(@:.so=.map)
-	$(AM_V_CCLD)$(LINK) -shared -o $(@:.map=.so) \
+	$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $(@:.map=.so) \
 		-Wl,--whole-archive $< $(cpu_$*) -Wl,--no-whole-archive \
 		-Wl,--version-script,$(@:.so=.map),--no-undefined \
-		-Wl,-z,defs,-z,relro -Wl,--as-needed $(libelf) $(libdw) $(libeu)
+		-Wl,--as-needed $(libelf) $(libdw) $(libeu)
 	@$(textrel_check)
 
 libebl_i386.so: $(cpu_i386)
diff --git a/config/ChangeLog b/config/ChangeLog
index 02cf76f..1ed3c4a 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* eu.am: Use fpic_CFLAGS.
+
 2016-08-02  Mark Wielaard  <mark@klomp.org>
 
 	* elfutils.spec.in: Update for 0.170.
diff --git a/config/eu.am b/config/eu.am
index 8fe1e25..796f388 100644
--- a/config/eu.am
+++ b/config/eu.am
@@ -86,14 +86,14 @@
 
 %.os: %.c %.o
 if AMDEP
-	$(AM_V_CC)if $(COMPILE.os) -c -o $@ -fPIC $(DEFS.os) -MT $@ -MD -MP \
+	$(AM_V_CC)if $(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) -MT $@ -MD -MP \
 	  -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \
 	then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \
 	     rm -f "$(DEPDIR)/$*.Tpo"; \
 	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
 	fi
 else
-	$(AM_V_CC)$(COMPILE.os) -c -o $@ -fPIC $(DEFS.os) $<
+	$(AM_V_CC)$(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) $<
 endif
 
 CLEANFILES = *.gcno *.gcda
diff --git a/configure.ac b/configure.ac
index 1f1856d..e6e3b67 100644
--- a/configure.ac
+++ b/configure.ac
@@ -127,13 +127,65 @@
 AS_IF([test "x$ac_cv_c99" != xyes],
       AC_MSG_ERROR([gcc with GNU99 support required]))
 
+AC_CACHE_CHECK([whether gcc supports -fPIC], ac_cv_fpic, [dnl
+save_CFLAGS="$CFLAGS"
+CFLAGS="$save_CFLAGS -fPIC -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE()], ac_cv_fpic=yes, ac_cv_fpic=no)
+CFLAGS="$save_CFLAGS"
+])
+if test "$ac_cv_fpic" = "yes"; then
+	fpic_CFLAGS="-fPIC"
+else
+	fpic_CFLAGS=""
+fi
+AC_SUBST([fpic_CFLAGS])
+
+AC_CACHE_CHECK([whether gcc supports -fPIE], ac_cv_fpie, [dnl
+save_CFLAGS="$CFLAGS"
+CFLAGS="$save_CFLAGS -fPIE -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE()], ac_cv_fpie=yes, ac_cv_fpie=no)
+CFLAGS="$save_CFLAGS"
+])
+if test "$ac_cv_fpie" = "yes"; then
+	fpie_CFLAGS="-fPIE"
+else
+	fpie_CFLAGS=""
+fi
+AC_SUBST([fpie_CFLAGS])
+
+dso_LDFLAGS="-shared"
+
+ZDEFS_LDFLAGS="-Wl,-z,defs"
+AC_CACHE_CHECK([whether gcc supports $ZDEFS_LDFLAGS], ac_cv_zdefs, [dnl
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$ZDEFS_LDFLAGS $save_LDFLAGS"
+AC_LINK_IFELSE([AC_LANG_PROGRAM()], ac_cv_zdefs=yes, ac_cv_zdefs=no)
+LDFLAGS="$save_LDFLAGS"
+])
+if test "$ac_cv_zdefs" = "yes"; then
+	dso_LDFLAGS="$dso_LDFLAGS $ZDEFS_LDFLAGS"
+fi
+
+ZRELRO_LDFLAGS="-Wl,-z,relro"
+AC_CACHE_CHECK([whether gcc supports $ZRELRO_LDFLAGS], ac_cv_zrelro, [dnl
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$ZRELRO_LDFLAGS $save_LDFLAGS"
+AC_LINK_IFELSE([AC_LANG_PROGRAM()], ac_cv_zrelro=yes, ac_cv_zrelro=no)
+LDFLAGS="$save_LDFLAGS"
+])
+if test "$ac_cv_zrelro" = "yes"; then
+	dso_LDFLAGS="$dso_LDFLAGS $ZRELRO_LDFLAGS"
+fi
+
+AC_SUBST([dso_LDFLAGS])
+
 AC_CACHE_CHECK([for __thread support], ac_cv_tls, [dnl
 # Use the same flags that we use for our DSOs, so the test is representative.
 # Some old compiler/linker/libc combinations fail some ways and not others.
 save_CFLAGS="$CFLAGS"
 save_LDFLAGS="$LDFLAGS"
-CFLAGS="-fPIC $CFLAGS"
-LDFLAGS="-shared -Wl,-z,defs,-z,relro $LDFLAGS"
+CFLAGS="$fpic_CFLAGS $CFLAGS"
+LDFLAGS="$dso_LDFLAGS $LDFLAGS"
 AC_LINK_IFELSE([dnl
 AC_LANG_PROGRAM([[#include <stdlib.h>
 #undef __thread
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 1f16228..67ef279 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Use fpic_CFLAGS.
+
 2017-07-18  Mark Wielaard  <mark@klomp.org>
 
 	* bpf.h: New file.
diff --git a/lib/Makefile.am b/lib/Makefile.am
index ada2030..c30d38b 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -28,7 +28,7 @@
 ## not, see <http://www.gnu.org/licenses/>.
 ##
 include $(top_srcdir)/config/eu.am
-AM_CFLAGS += -fPIC
+AM_CFLAGS += $(fpic_CFLAGS)
 AM_CPPFLAGS += -I$(srcdir)/../libelf
 
 noinst_LIBRARIES = libeu.a
diff --git a/libasm/ChangeLog b/libasm/ChangeLog
index 262d2a9..fffcced 100644
--- a/libasm/ChangeLog
+++ b/libasm/ChangeLog
@@ -1,3 +1,7 @@
+2017-02-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Use dso_LDFLAGS.
+
 2017-02-17  Ulf Hermann  <ulf.hermann@qt.io>
 
 	* Makefile.am: Add libasm_so_DEPS to specify external libraries
diff --git a/libasm/Makefile.am b/libasm/Makefile.am
index 9effa6c..19fef50 100644
--- a/libasm/Makefile.am
+++ b/libasm/Makefile.am
@@ -64,8 +64,8 @@
 libasm_so_LIBS = libasm_pic.a
 libasm_so_SOURCES =
 libasm.so$(EXEEXT): $(srcdir)/libasm.map $(libasm_so_LIBS) $(libasm_so_DEPS)
-	$(AM_V_CCLD)$(LINK) -shared -o $@ \
-		-Wl,--soname,$@.$(VERSION),-z,defs,-z,relro \
+	$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
+		-Wl,--soname,$@.$(VERSION) \
 		-Wl,--version-script,$<,--no-undefined \
 		-Wl,--whole-archive $(libasm_so_LIBS) -Wl,--no-whole-archive \
 		$(libasm_so_LDLIBS)
diff --git a/libcpu/ChangeLog b/libcpu/ChangeLog
index 28b220f..173defe 100644
--- a/libcpu/ChangeLog
+++ b/libcpu/ChangeLog
@@ -1,3 +1,7 @@
+2017-02-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Use fpic_CFLAGS.
+
 2017-07-18  Mark Wielaard  <mark@klomp.org>
 
 	* Makefile.am: Don't check HAVE_LINUX_BPF_H, just define libcpu_bpf.
diff --git a/libcpu/Makefile.am b/libcpu/Makefile.am
index 94de56e..4c8778d 100644
--- a/libcpu/Makefile.am
+++ b/libcpu/Makefile.am
@@ -30,7 +30,7 @@
 include $(top_srcdir)/config/eu.am
 AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
 	    -I$(srcdir)/../libdw -I$(srcdir)/../libasm
-AM_CFLAGS += -fPIC -fdollars-in-identifiers
+AM_CFLAGS += $(fpic_CFLAGS) -fdollars-in-identifiers
 LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS) -P$(<F:lex.l=)
 LEX_OUTPUT_ROOT = lex.$(<F:lex.l=)
 AM_YFLAGS = -p$(<F:parse.y=)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 6533eb5..67d7799 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,7 @@
+2017-02-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Use fpic_CFLAGS and dso_LDFLAGS.
+
 2017-07-26  Mark Wielaard  <mark@klomp.org>
 
 	* dwarf.h: Add DW_MACRO_* and compat defines for DW_MACRO_GNU_*.
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index ff8c291..8ee4680 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -29,7 +29,7 @@
 ##
 include $(top_srcdir)/config/eu.am
 if BUILD_STATIC
-AM_CFLAGS += -fPIC
+AM_CFLAGS += $(fpic_CFLAGS)
 endif
 AM_CPPFLAGS += -I$(srcdir)/../libelf
 VERSION = 1
@@ -110,8 +110,8 @@
 libdw.so$(EXEEXT): $(srcdir)/libdw.map $(libdw_so_LIBS) $(libdw_so_DEPS)
 # The rpath is necessary for libebl because its $ORIGIN use will
 # not fly in a setuid executable that links in libdw.
-	$(AM_V_CCLD)$(LINK) -shared -o $@ \
-		-Wl,--soname,$@.$(VERSION),-z,defs,-z,relro \
+	$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
+		-Wl,--soname,$@.$(VERSION) \
 		-Wl,--enable-new-dtags,-rpath,$(pkglibdir) \
 		-Wl,--version-script,$<,--no-undefined \
 		-Wl,--whole-archive $(libdw_so_LIBS) -Wl,--no-whole-archive \
diff --git a/libebl/ChangeLog b/libebl/ChangeLog
index 334bf22..3b07633 100644
--- a/libebl/ChangeLog
+++ b/libebl/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Use fpic_CFLAGS.
+
 2017-07-19  Gustavo Romero <gromero@linux.vnet.ibm.com>
 
 	* eblcorenotetypename.c: Add ppc64 HTM SPRs note as known type.
diff --git a/libebl/Makefile.am b/libebl/Makefile.am
index 2491df8..737de6b 100644
--- a/libebl/Makefile.am
+++ b/libebl/Makefile.am
@@ -28,7 +28,7 @@
 ## not, see <http://www.gnu.org/licenses/>.
 ##
 include $(top_srcdir)/config/eu.am
-AM_CFLAGS += -fPIC
+AM_CFLAGS += $(fpic_CFLAGS)
 AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libdw -I$(srcdir)/../libasm
 VERSION = 1
 LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 436b888..a073646 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Use fpic_CFLAGS and dso_LDFLAGS.
+
 2017-08-15  Mark Wielaard  <mark@klomp.org>
 
 	* elf.h: Update from glibc. Add new powerpc note descriptors.
diff --git a/libelf/Makefile.am b/libelf/Makefile.am
index 88c1edd..ddaeaa2 100644
--- a/libelf/Makefile.am
+++ b/libelf/Makefile.am
@@ -29,7 +29,7 @@
 ##
 include $(top_srcdir)/config/eu.am
 if BUILD_STATIC
-AM_CFLAGS += -fPIC
+AM_CFLAGS += $(fpic_CFLAGS)
 endif
 GCC_INCLUDE = -I$(shell $(CC) -print-file-name=include)
 VERSION = 1
@@ -104,8 +104,8 @@
 libelf_so_LIBS = libelf_pic.a
 libelf_so_SOURCES =
 libelf.so$(EXEEXT): $(srcdir)/libelf.map $(libelf_so_LIBS) $(libelf_so_DEPS)
-	$(AM_V_CCLD)$(LINK) -shared -o $@ \
-		-Wl,--soname,$@.$(VERSION),-z,defs,-z,relro \
+	$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
+		-Wl,--soname,$@.$(VERSION) \
 		-Wl,--version-script,$<,--no-undefined \
 		-Wl,--whole-archive $(libelf_so_LIBS) -Wl,--no-whole-archive \
 		$(libelf_so_LDLIBS)
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 94f4cf2..19a4c88 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-27  Ulf Hermann <ulf.hermann@qt.io>
+
+	* Makefile.am: Use fpie_CFLAGS and fpic_CFLAGS.
+
 2017-08-08  Dmitry V. Levin <ldv@altlinux.org>
 
 	* run-strip-nothing.sh: Add -s.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3735084..6332a7c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -474,7 +474,7 @@
 varlocs_LDADD = $(libdw) $(libelf) $(argp_LDADD)
 backtrace_LDADD = $(libdw) $(libelf) $(argp_LDADD)
 # backtrace-child-biarch also uses those *_CFLAGS and *_LDLAGS variables:
-backtrace_child_CFLAGS = -fPIE
+backtrace_child_CFLAGS = $(fpie_CFLAGS)
 backtrace_child_LDFLAGS = -pie -pthread
 backtrace_child_biarch_SOURCES = backtrace-child.c
 backtrace_data_LDADD = $(libdw) $(libelf)
@@ -485,7 +485,7 @@
 buildid_LDADD = $(libdw) $(libelf)
 deleted_LDADD = ./deleted-lib.so
 deleted_lib_so_LDFLAGS = -shared -rdynamic
-deleted_lib_so_CFLAGS = -fPIC -fasynchronous-unwind-tables
+deleted_lib_so_CFLAGS = $(fpic_CFLAGS) -fasynchronous-unwind-tables
 aggregate_size_LDADD = $(libdw) $(libelf) $(argp_LDADD)
 peel_type_LDADD = $(libdw) $(libelf) $(argp_LDADD)
 vdsosyms_LDADD = $(libdw) $(libelf)