changeset 49630:986249df86ce

8199403: Require binutils 2.18 or newer Reviewed-by: erikj, tbell
author ihse
date Fri, 09 Mar 2018 19:10:51 +0100
parents 51ad2caecdb6
children a19a6228cdb2
files make/autoconf/flags-ldflags.m4 make/autoconf/toolchain.m4
diffstat 2 files changed, 152 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/make/autoconf/flags-ldflags.m4	Fri Mar 09 19:09:20 2018 +0100
+++ b/make/autoconf/flags-ldflags.m4	Fri Mar 09 19:10:51 2018 +0100
@@ -64,18 +64,6 @@
 [
   # Setup basic LDFLAGS
   if test "x$TOOLCHAIN_TYPE" = xgcc; then
-    # "-z relro" supported in GNU binutils 2.17 and later
-    LINKER_RELRO_FLAG="-Wl,-z,relro"
-    FLAGS_LINKER_CHECK_ARGUMENTS(ARGUMENT: [$LINKER_RELRO_FLAG],
-      IF_TRUE: [HAS_LINKER_RELRO=true],
-      IF_FALSE: [HAS_LINKER_RELRO=false])
-
-    # "-z now" supported in GNU binutils 2.11 and later
-    LINKER_NOW_FLAG="-Wl,-z,now"
-    FLAGS_LINKER_CHECK_ARGUMENTS(ARGUMENT: [$LINKER_NOW_FLAG],
-      IF_TRUE: [HAS_LINKER_NOW=true],
-      IF_FALSE: [HAS_LINKER_NOW=false])
-
     # If this is a --hash-style=gnu system, use --hash-style=both, why?
     # We have previously set HAS_GNU_HASH if this is the case
     if test -n "$HAS_GNU_HASH"; then
@@ -83,20 +71,14 @@
       LIBJSIG_HASHSTYLE_LDFLAGS="-Wl,--hash-style=both"
     fi
 
-    # And since we now know that the linker is gnu, then add -z defs, to forbid
-    # undefined symbols in object files.
+    # Add -z defs, to forbid undefined symbols in object files.
     BASIC_LDFLAGS="$BASIC_LDFLAGS -Wl,-z,defs"
 
-    BASIC_LDFLAGS_JVM_ONLY="-Wl,-z,noexecstack -Wl,-O1"
+    BASIC_LDFLAGS_JVM_ONLY="-Wl,-z,noexecstack -Wl,-O1 -Wl,-z,relro"
 
     BASIC_LDFLAGS_JDK_LIB_ONLY="-Wl,-z,noexecstack"
     LIBJSIG_NOEXECSTACK_LDFLAGS="-Wl,-z,noexecstack"
 
-
-    if test "x$HAS_LINKER_RELRO" = "xtrue"; then
-      BASIC_LDFLAGS_JVM_ONLY="$BASIC_LDFLAGS_JVM_ONLY $LINKER_RELRO_FLAG"
-    fi
-
   elif test "x$TOOLCHAIN_TYPE" = xclang; then
     BASIC_LDFLAGS_JVM_ONLY="-mno-omit-leaf-frame-pointer -mstack-alignment=16 \
         -stdlib=libstdc++ -fPIC"
@@ -133,20 +115,16 @@
   # Setup debug level-dependent LDFLAGS
   if test "x$TOOLCHAIN_TYPE" = xgcc; then
     if test "x$OPENJDK_TARGET_OS" = xlinux; then
-       if test x$DEBUG_LEVEL = xrelease; then
-          DEBUGLEVEL_LDFLAGS_JDK_ONLY="$DEBUGLEVEL_LDFLAGS_JDK_ONLY -Wl,-O1"
-       else
-          # mark relocations read only on (fast/slow) debug builds
-          if test "x$HAS_LINKER_RELRO" = "xtrue"; then
-            DEBUGLEVEL_LDFLAGS_JDK_ONLY="$LINKER_RELRO_FLAG"
-          fi
-       fi
-       if test x$DEBUG_LEVEL = xslowdebug; then
-          if test "x$HAS_LINKER_NOW" = "xtrue"; then
-            # do relocations at load
-            DEBUGLEVEL_LDFLAGS="$LINKER_NOW_FLAG"
-          fi
-       fi
+      if test x$DEBUG_LEVEL = xrelease; then
+        DEBUGLEVEL_LDFLAGS_JDK_ONLY="$DEBUGLEVEL_LDFLAGS_JDK_ONLY -Wl,-O1"
+      else
+        # mark relocations read only on (fast/slow) debug builds
+        DEBUGLEVEL_LDFLAGS_JDK_ONLY="-Wl,-z,relro"
+      fi
+      if test x$DEBUG_LEVEL = xslowdebug; then
+        # do relocations at load
+        DEBUGLEVEL_LDFLAGS="-Wl,-z,now"
+      fi
     fi
 
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
--- a/make/autoconf/toolchain.m4	Fri Mar 09 19:09:20 2018 +0100
+++ b/make/autoconf/toolchain.m4	Fri Mar 09 19:10:51 2018 +0100
@@ -57,6 +57,9 @@
 TOOLCHAIN_MINIMUM_VERSION_solstudio="5.13"
 TOOLCHAIN_MINIMUM_VERSION_xlc=""
 
+# Minimum supported linker versions, empty means unspecified
+TOOLCHAIN_MINIMUM_LD_VERSION_gcc="2.18"
+
 # Prepare the system so that TOOLCHAIN_CHECK_COMPILER_VERSION can be called.
 # Must have CC_VERSION_NUMBER and CXX_VERSION_NUMBER.
 # $1 - optional variable prefix for compiler and version variables (BUILD_)
@@ -114,6 +117,57 @@
   fi
 ])
 
+# Prepare the system so that TOOLCHAIN_CHECK_COMPILER_VERSION can be called.
+# Must have LD_VERSION_NUMBER.
+# $1 - optional variable prefix for compiler and version variables (BUILD_)
+# $2 - optional variable prefix for comparable variable (OPENJDK_BUILD_)
+AC_DEFUN([TOOLCHAIN_PREPARE_FOR_LD_VERSION_COMPARISONS],
+[
+  if [ [[ "[$]$1LD_VERSION_NUMBER" =~ (.*\.){4} ]] ]; then
+    AC_MSG_WARN([Linker version number has more than four parts (W.X.Y.Z): [$]$1LD_VERSION_NUMBER. Comparisons might be wrong.])
+  fi
+
+  if [ [[  "[$]$1LD_VERSION_NUMBER" =~ [0-9]{6} ]] ]; then
+    AC_MSG_WARN([Linker version number has a part larger than 99999: [$]$1LD_VERSION_NUMBER. Comparisons might be wrong.])
+  fi
+
+  $2COMPARABLE_ACTUAL_LD_VERSION=`$AWK -F. '{ printf("%05d%05d%05d%05d\n", [$]1, [$]2, [$]3, [$]4) }' <<< "[$]$1LD_VERSION_NUMBER"`
+])
+
+# Check if the configured linker is of a specific version or
+# newer. TOOLCHAIN_PREPARE_FOR_LD_VERSION_COMPARISONS must have been called before.
+#
+# Arguments:
+#   VERSION:   The version string to check against the found version
+#   IF_AT_LEAST:   block to run if the compiler is at least this version (>=)
+#   IF_OLDER_THAN:   block to run if the compiler is older than this version (<)
+#   PREFIX:   Optional variable prefix for compiler to compare version for (OPENJDK_BUILD_)
+BASIC_DEFUN_NAMED([TOOLCHAIN_CHECK_LINKER_VERSION],
+    [*VERSION PREFIX IF_AT_LEAST IF_OLDER_THAN], [$@],
+[
+  # Need to assign to a variable since m4 is blocked from modifying parts in [].
+  REFERENCE_VERSION=ARG_VERSION
+
+  if [ [[ "$REFERENCE_VERSION" =~ (.*\.){4} ]] ]; then
+    AC_MSG_ERROR([Internal error: Cannot compare to ARG_VERSION, only four parts (W.X.Y.Z) is supported])
+  fi
+
+  if [ [[ "$REFERENCE_VERSION" =~ [0-9]{6} ]] ]; then
+    AC_MSG_ERROR([Internal error: Cannot compare to ARG_VERSION, only parts < 99999 is supported])
+  fi
+
+  # Version comparison method inspired by http://stackoverflow.com/a/24067243
+  COMPARABLE_REFERENCE_VERSION=`$AWK -F. '{ printf("%05d%05d%05d%05d\n", [$]1, [$]2, [$]3, [$]4) }' <<< "$REFERENCE_VERSION"`
+
+  if test [$]ARG_PREFIX[COMPARABLE_ACTUAL_LD_VERSION] -ge $COMPARABLE_REFERENCE_VERSION ; then
+    :
+    ARG_IF_AT_LEAST
+  else
+    :
+    ARG_IF_OLDER_THAN
+  fi
+])
+
 # Setup a number of variables describing how native output files are
 # named on this platform/toolchain.
 AC_DEFUN([TOOLCHAIN_SETUP_FILENAME_PATTERNS],
@@ -241,6 +295,8 @@
   TOOLCHAIN_DESCRIPTION=${!toolchain_var_name}
   toolchain_var_name=TOOLCHAIN_MINIMUM_VERSION_$TOOLCHAIN_TYPE
   TOOLCHAIN_MINIMUM_VERSION=${!toolchain_var_name}
+  toolchain_var_name=TOOLCHAIN_MINIMUM_LD_VERSION_$TOOLCHAIN_TYPE
+  TOOLCHAIN_MINIMUM_LD_VERSION=${!toolchain_var_name}
   toolchain_var_name=TOOLCHAIN_CC_BINARY_$TOOLCHAIN_TYPE
   TOOLCHAIN_CC_BINARY=${!toolchain_var_name}
   toolchain_var_name=TOOLCHAIN_CXX_BINARY_$TOOLCHAIN_TYPE
@@ -524,6 +580,76 @@
   TOOLCHAIN_EXTRACT_COMPILER_VERSION([$1], [$COMPILER_NAME])
 ])
 
+# Retrieve the linker version number and store it in LD_VERSION_NUMBER
+# (as a dotted number), and
+# the full version string in LD_VERSION_STRING.
+#
+# $1 = linker to test (LD or BUILD_LD)
+# $2 = human readable name of linker (Linker or BuildLinker)
+AC_DEFUN([TOOLCHAIN_EXTRACT_LD_VERSION],
+[
+  LINKER=[$]$1
+  LINKER_NAME=$2
+
+  if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
+    # cc -Wl,-V output typically looks like
+    #   ld: Software Generation Utilities - Solaris Link Editors: 5.11-1.2329
+
+    # solstudio cc requires us to have an existing file to pass as argument,
+    # but it need not be a syntactically correct C file, so just use
+    # ourself. :)
+    LINKER_VERSION_STRING=`$LD -Wl,-V $TOPDIR/configure 2>&1 | $HEAD -n 1 | $SED -e 's/ld: //'`
+    # Extract version number
+    [ LINKER_VERSION_NUMBER=`$ECHO $LINKER_VERSION_STRING | \
+        $SED -e 's/.* \([0-9][0-9]*\.[0-9][0-9]*\)-\([0-9][0-9]*\.[0-9][0-9]*\)/\1.\2/'` ]
+  elif test  "x$TOOLCHAIN_TYPE" = xxlc; then
+    LINKER_VERSION_STRING="Unknown"
+    LINKER_VERSION_NUMBER="0.0"
+  elif test  "x$TOOLCHAIN_TYPE" = xmicrosoft; then
+    # There is no specific version flag, but all output starts with a version string.
+    # First line typically looks something like:
+    #   Microsoft (R) Incremental Linker Version 12.00.31101.0
+    LINKER_VERSION_STRING=`$LD 2>&1 | $HEAD -n 1 | $TR -d '\r'`
+    # Extract version number
+    [ LINKER_VERSION_NUMBER=`$ECHO $LINKER_VERSION_STRING | \
+        $SED -e 's/.* \([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*/\1/'` ]
+  elif test  "x$TOOLCHAIN_TYPE" = xgcc; then
+    # gcc -Wl,-version output typically looks like
+    #   GNU ld (GNU Binutils for Ubuntu) 2.26.1
+    #   Copyright (C) 2015 Free Software Foundation, Inc.
+    #   This program is free software; [...]
+    LINKER_VERSION_STRING=`$LD -Wl,-version 2>&1 | $HEAD -n 1`
+    # Extract version number
+    [ LINKER_VERSION_NUMBER=`$ECHO $LINKER_VERSION_STRING | \
+        $SED -e 's/.* \([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*/\1/'` ]
+  elif test  "x$TOOLCHAIN_TYPE" = xclang; then
+    # clang -Wl,-v output typically looks like
+    #   @(#)PROGRAM:ld  PROJECT:ld64-305
+    #   configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em (tvOS)
+    #   Library search paths: [...]
+    # or
+    #   GNU ld (GNU Binutils for Ubuntu) 2.26.1
+
+    LINKER_VERSION_STRING=`$LD -Wl,-v 2>&1 | $HEAD -n 1`
+    # Check if we're using the GNU ld
+    $ECHO "$LINKER_VERSION_STRING" | $GREP "GNU" > /dev/null
+    if test $? -eq 0; then
+      # Extract version number
+      [ LINKER_VERSION_NUMBER=`$ECHO $LINKER_VERSION_STRING | \
+          $SED -e 's/.* \([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*/\1/'` ]
+    else
+      # Extract version number
+      [ LINKER_VERSION_NUMBER=`$ECHO $LINKER_VERSION_STRING | \
+          $SED -e 's/.*-\([0-9][0-9]*\)/\1/'` ]
+    fi
+  fi
+
+  $1_VERSION_NUMBER="$LINKER_VERSION_NUMBER"
+  $1_VERSION_STRING="$LINKER_VERSION_STRING"
+
+  AC_MSG_NOTICE([Using $TOOLCHAIN_TYPE $LINKER_NAME version $LINKER_VERSION_NUMBER @<:@$LINKER_VERSION_STRING@:>@])
+])
+
 # Detect the core components of the toolchain, i.e. the compilers (CC and CXX),
 # preprocessor (CPP and CXXCPP), the linker (LD), the assembler (AS) and the
 # archiver (AR). Verify that the compilers are correct according to the
@@ -591,6 +717,17 @@
   # FIXME: it should be CXXLD, according to standard (cf CXXCPP)
   AC_SUBST(LDCXX)
 
+  TOOLCHAIN_EXTRACT_LD_VERSION([LD], [linker])
+  TOOLCHAIN_PREPARE_FOR_LD_VERSION_COMPARISONS
+
+  if test "x$TOOLCHAIN_MINIMUM_LD_VERSION" != x; then
+    TOOLCHAIN_CHECK_LINKER_VERSION(VERSION: $TOOLCHAIN_MINIMUM_LD_VERSION,
+        IF_OLDER_THAN: [
+          AC_MSG_WARN([You are using a linker older than $TOOLCHAIN_MINIMUM_LD_VERSION. This is not a supported configuration.])
+        ]
+    )
+  fi
+
   #
   # Setup the assembler (AS)
   #
@@ -818,6 +955,8 @@
     TOOLCHAIN_EXTRACT_COMPILER_VERSION(BUILD_CC, [BuildC])
     TOOLCHAIN_EXTRACT_COMPILER_VERSION(BUILD_CXX, [BuildC++])
     TOOLCHAIN_PREPARE_FOR_VERSION_COMPARISONS([BUILD_], [OPENJDK_BUILD_])
+    TOOLCHAIN_EXTRACT_LD_VERSION(BUILD_LD, [build linker])
+    TOOLCHAIN_PREPARE_FOR_LD_VERSION_COMPARISONS([BUILD_], [OPENJDK_BUILD_])
   else
     # If we are not cross compiling, use the normal target compilers for
     # building the build platform executables.
@@ -832,6 +971,7 @@
     BUILD_AR="$AR"
 
     TOOLCHAIN_PREPARE_FOR_VERSION_COMPARISONS([], [OPENJDK_BUILD_])
+    TOOLCHAIN_PREPARE_FOR_LD_VERSION_COMPARISONS([BUILD_], [OPENJDK_BUILD_])
   fi
 
   AC_SUBST(BUILD_CC)