This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: RFC: x86: Enable -z separate-code by default
On Mon, Feb 19, 2018 at 8:39 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Mon, Feb 19, 2018 at 7:53 AM, Michael Matz <matz@suse.de> wrote:
>> Hi,
>>
>> On Mon, 19 Feb 2018, H.J. Lu wrote:
>>
>>> This patch enables -z separate-code by default for x86. To reduce
>>> x86-64 binary size, set ELF_MAXPAGESIZE to 4KB.
>>
>> Meh :-( Have you done any performance measurements on, say, SPECcpu?
>
> We will.
We compared SPEC CPU 2017 performance before and after this change on
Skylake server. There are no any significant performance changes.
Everything is mostly below +/-1%.
>>> Should I add an ld configure option, --enable-separate-code, instead?
>>
>> Yes, definitely. For old distros at least I definitely want to retain old
>> behaviour by default and a configure switch would make that easier.
>
> Will do.
>
Here is the patch to add --enable-separate-code to ld configure and
enable it by default for Linux/x86. But the default maximum page size
is changed to 4KB for x86-64.
Any comments?
--
H.J.
From c4ac3a6bb23240ae17d6f33228dd517fabeb3729 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 14 Feb 2018 04:09:05 -0800
Subject: [PATCH] ld: Add --enable-separate-code
This patch adds --enable-separate-code to ld configure and enables it
by default for Linux/x86. This avoids mixing code pages with data to
improve cache performance as well as security.
To reduce x86-64 executable and shared object sizes, the maximum page
size is reduced from 2MB to 4KB. Note: -z max-page-size= can be used
to set the maximum page size.
We compared SPEC CPU 2017 performance before and after this change on
Skylake server. There are no any significant performance changes.
Everything is mostly below +/-1%.
bfd/
* elf64-x86-64.c (ELF_MAXPAGESIZE): Set to 0x1000.
ld/
* NEWS: Mention --enable-separate-code.
* configure.ac: Add --enable-separate-code.
(DEFAULT_LD_Z_SEPARATE_CODE): New AC_DEFINE_UNQUOTED.
* configure.tgt: Default ac_default_ld_z_separate_code to 1 for
Linux/x86 targets.
* config.in: Regenerated.
* configure: Likewise.
* emultempl/elf32.em (gld${EMULATION_NAME}_before_parse): Set
link_info.separate_code DEFAULT_LD_Z_SEPARATE_CODE.
---
bfd/elf64-x86-64.c | 4 ++--
ld/NEWS | 5 +++++
ld/config.in | 4 ++++
ld/configure | 26 ++++++++++++++++++++++++--
ld/configure.ac | 17 +++++++++++++++++
ld/configure.tgt | 9 +++++++++
ld/emultempl/elf32.em | 1 +
7 files changed, 62 insertions(+), 4 deletions(-)
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index d66d9ba5fc..c79e503107 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -4936,7 +4936,7 @@ elf_x86_64_special_sections[]=
#define ELF_ARCH bfd_arch_i386
#define ELF_TARGET_ID X86_64_ELF_DATA
#define ELF_MACHINE_CODE EM_X86_64
-#define ELF_MAXPAGESIZE 0x200000
+#define ELF_MAXPAGESIZE 0x1000
#define ELF_MINPAGESIZE 0x1000
#define ELF_COMMONPAGESIZE 0x1000
@@ -5329,7 +5329,7 @@ elf64_l1om_elf_object_p (bfd *abfd)
#undef ELF_MAXPAGESIZE
#undef ELF_MINPAGESIZE
#undef ELF_COMMONPAGESIZE
-#define ELF_MAXPAGESIZE 0x200000
+#define ELF_MAXPAGESIZE 0x1000
#define ELF_MINPAGESIZE 0x1000
#define ELF_COMMONPAGESIZE 0x1000
#undef elf_backend_plt_alignment
diff --git a/ld/NEWS b/ld/NEWS
index eafcaf33cb..75f8100f87 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,10 @@
-*- text -*-
+* Add a configure option --enable-separate-code to decide whether
+ -z separate-code should be enabled in ELF linker by default. Default
+ to yes for Linux/x86 targets. Note that -z separate-code can increase
+ disk and memory size.
+
Changes in 2.30:
* Add -z separate-code to generate separate code PT_LOAD segment.
diff --git a/ld/config.in b/ld/config.in
index a846743da6..b227a53984 100644
--- a/ld/config.in
+++ b/ld/config.in
@@ -19,6 +19,10 @@
/* Define to 1 if you want to enable -z relro in ELF linker by default. */
#undef DEFAULT_LD_Z_RELRO
+/* Define to 1 if you want to enable -z separate-code in ELF linker by
+ default. */
+#undef DEFAULT_LD_Z_SEPARATE_CODE
+
/* Define to 1 if you want to set DT_RUNPATH instead of DT_RPATH by default.
*/
#undef DEFAULT_NEW_DTAGS
diff --git a/ld/configure b/ld/configure
index 0cc6e8a50f..241ac8f90e 100755
--- a/ld/configure
+++ b/ld/configure
@@ -790,6 +790,7 @@ enable_got
enable_compressed_debug_sections
enable_new_dtags
enable_relro
+enable_separate_code
enable_default_hash_style
enable_werror
enable_build_warnings
@@ -1451,6 +1452,7 @@ Optional Features:
compress debug sections by default]
--enable-new-dtags set DT_RUNPATH instead of DT_RPATH by default]
--enable-relro enable -z relro in ELF linker by default
+ --enable-separate-code enable -z separate-code in ELF linker by default
--enable-default-hash-style={sysv,gnu,both}
use this default hash style
--enable-werror treat compile warnings as errors
@@ -11725,7 +11727,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11728 "configure"
+#line 11730 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11831,7 +11833,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11834 "configure"
+#line 11836 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -15567,6 +15569,17 @@ if test "${enable_relro+set}" = set; then :
esac
fi
+# Decide if -z separate-code should be enabled in ELF linker by default.
+ac_default_ld_z_separate_code=unset
+# Check whether --enable-separate-code was given.
+if test "${enable_separate_code+set}" = set; then :
+ enableval=$enable_separate_code; case "${enableval}" in
+ yes) ac_default_ld_z_separate_code=1 ;;
+ no) ac_default_ld_z_separate_code=0 ;;
+esac
+fi
+
+
# Decide which "--hash-style" to use by default
# Provide a configure time option to override our default.
# Check whether --enable-default-hash-style was given.
@@ -17258,6 +17271,15 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
+if test "${ac_default_ld_z_separate_code}" = unset; then
+ ac_default_ld_z_separate_code=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_LD_Z_SEPARATE_CODE $ac_default_ld_z_separate_code
+_ACEOF
+
+
cat >>confdefs.h <<_ACEOF
#define DEFAULT_EMIT_SYSV_HASH $ac_default_emit_sysv_hash
diff --git a/ld/configure.ac b/ld/configure.ac
index bada1b50b0..5554873485 100644
--- a/ld/configure.ac
+++ b/ld/configure.ac
@@ -177,6 +177,16 @@ AC_ARG_ENABLE(relro,
no) ac_default_ld_z_relro=0 ;;
esac])dnl
+# Decide if -z separate-code should be enabled in ELF linker by default.
+ac_default_ld_z_separate_code=unset
+AC_ARG_ENABLE(separate-code,
+ AS_HELP_STRING([--enable-separate-code],
+ [enable -z separate-code in ELF linker by default]),
+[case "${enableval}" in
+ yes) ac_default_ld_z_separate_code=1 ;;
+ no) ac_default_ld_z_separate_code=0 ;;
+esac])
+
# Decide which "--hash-style" to use by default
# Provide a configure time option to override our default.
AC_ARG_ENABLE([default-hash-style],
@@ -434,6 +444,13 @@ AC_DEFINE_UNQUOTED(DEFAULT_LD_Z_RELRO,
$ac_default_ld_z_relro,
[Define to 1 if you want to enable -z relro in ELF linker by default.])
+if test "${ac_default_ld_z_separate_code}" = unset; then
+ ac_default_ld_z_separate_code=0
+fi
+AC_DEFINE_UNQUOTED(DEFAULT_LD_Z_SEPARATE_CODE,
+ $ac_default_ld_z_separate_code,
+ [Define to 1 if you want to enable -z separate-code in ELF linker by default.])
+
AC_DEFINE_UNQUOTED([DEFAULT_EMIT_SYSV_HASH],
[$ac_default_emit_sysv_hash],
[Define to 1 if you want to emit sysv hash in the ELF linker by default.])
diff --git a/ld/configure.tgt b/ld/configure.tgt
index 6183a85b3d..7897448e64 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -968,3 +968,12 @@ frv-*-* | hppa*-*-* | ia64-*-* | mips*-*-*)
fi
;;
esac
+
+# Enable -z separate-code by default for Linux/x86.
+case "${target}" in
+i[3-7]86-*-linux-* | x86_64-*-linux-*)
+ if test ${ac_default_ld_z_separate_code} = unset; then
+ ac_default_ld_z_separate_code=1
+ fi
+ ;;
+esac
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index eb90743cee..e21b3e3300 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -106,6 +106,7 @@ gld${EMULATION_NAME}_before_parse (void)
`if test -n "$CALL_NOP_BYTE" ; then echo link_info.call_nop_byte = $CALL_NOP_BYTE; fi`;
link_info.check_relocs_after_open_input = TRUE;
link_info.relro = DEFAULT_LD_Z_RELRO;
+ link_info.separate_code = DEFAULT_LD_Z_SEPARATE_CODE;
}
EOF
--
2.14.3