[v4,3/3] ld: Add --enable-memory-seal configure option

Message ID 20241128154511.564500-4-adhemerval.zanella@linaro.org
State New
Headers
Series elf: Add GNU_PROPERTY_MEMORY_SEAL gnu property |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Adhemerval Zanella Netto Nov. 28, 2024, 3:43 p.m. UTC
  Add --enable-memory-seal linker configure option to enable memory
sealing (GNU_PROPERTY_MEMORY_SEAL) by default.

Change-Id: I4ce4ff33657f0f09b1ceb06210b6fcaa501f1799
---
 binutils/testsuite/lib/binutils-common.exp | 22 +++++++++++++
 ld/NEWS                                    |  3 +-
 ld/config.in                               |  3 ++
 ld/configure                               | 38 ++++++++++++++++++----
 ld/configure.ac                            | 17 ++++++++++
 ld/emultempl/elf.em                        |  1 +
 ld/lexsup.c                                |  7 ++++
 ld/testsuite/config/default.exp            |  8 +++++
 ld/testsuite/ld-srec/srec.exp              |  4 +++
 ld/testsuite/lib/ld-lib.exp                |  6 ++++
 10 files changed, 101 insertions(+), 8 deletions(-)
  

Patch

diff --git a/binutils/testsuite/lib/binutils-common.exp b/binutils/testsuite/lib/binutils-common.exp
index 03e8dbb855b..063ba4f20c2 100644
--- a/binutils/testsuite/lib/binutils-common.exp
+++ b/binutils/testsuite/lib/binutils-common.exp
@@ -408,6 +408,25 @@  proc check_relro_support { } {
     return $relro_available_saved
 }
 
+proc check_memory_seal_support { } {
+    global memory_seal_available_saved
+    global ld
+
+    if {![info exists memory_seal_available_saved]} {
+	remote_file host delete nomemory_seal
+	set ld_output [remote_exec host $ld "-z nomemory-seal"]
+	if { [string first "not supported" $ld_output] >= 0
+	     || [string first "unrecognized option" $ld_output] >= 0
+	     || [string first "-z nomemory-seal ignored" $ld_output] >= 0
+	     || [string first "cannot find nomemory-seal" $ld_output] >= 0 } {
+	    set memory_seal_available_saved 0
+	} else {
+	    set memory_seal_available_saved 1
+	}
+    }
+    return $memory_seal_available_saved
+}
+
 # Check for support of the .noinit section, used for data that is not
 # initialized at load, or during the application's initialization sequence.
 proc supports_noinit_section {} {
@@ -1401,6 +1420,9 @@  proc run_dump_test { name {extra_options {}} } {
 	    if [check_relro_support] {
 		set ld_extra_opt "-z norelro"
 	    }
+	    if [check_memory_seal_support] {
+		append ld_extra_opt " -z nomemory-seal"
+	    }
 
 	    # Add -L$srcdir/$subdir so that the linker command can use
 	    # linker scripts in the source directory.
diff --git a/ld/NEWS b/ld/NEWS
index babcf8753e8..a129ad634e6 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -34,7 +34,8 @@  Changes in 2.43:
 * Add -plugin-save-temps to store plugin intermediate files permanently.
 
 * Add -z memory-seal/-z nomemory-seal options to ELF linker to mark the
-  object to memory sealed.
+  object to memory sealed.   Also added --enable-memory-seal configure option
+  to enable the memory sealing by default.
 
 Changes in 2.42:
 
diff --git a/ld/config.in b/ld/config.in
index 633105a43ad..ed838463856 100644
--- a/ld/config.in
+++ b/ld/config.in
@@ -60,6 +60,9 @@ 
    default. */
 #undef DEFAULT_LD_Z_SEPARATE_CODE
 
+/* Define to 1 if you want to enable -z memory-seal in ELF linker by default.  */
+#undef DEFAULT_LD_Z_MEMORY_SEAL
+
 /* 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 0b4197d1c4f..f34141bb238 100755
--- a/ld/configure
+++ b/ld/configure
@@ -854,6 +854,7 @@  enable_textrel_check
 enable_separate_code
 enable_rosegment
 enable_mark_plt
+enable_memory_seal
 enable_warn_execstack
 enable_error_execstack
 enable_warn_rwx_segments
@@ -1551,6 +1552,7 @@  Optional Features:
   --enable-separate-code  enable -z separate-code in ELF linker by default
   --enable-rosegment      enable --rosegment in the ELF linker by default
   --enable-mark-plt       enable -z mark-plt in ELF x86-64 linker by default
+  --enable-memory-seal    enable -z memory-seal in ELF linker by default
   --enable-warn-execstack enable warnings when creating an executable stack
   --enable-error-execstack
                           turn executable stack warnings into errors
@@ -11686,7 +11688,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11689 "configure"
+#line 11691 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11792,7 +11794,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11795 "configure"
+#line 11797 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -15251,7 +15253,7 @@  else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -15297,7 +15299,7 @@  else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -15321,7 +15323,7 @@  rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -15366,7 +15368,7 @@  else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -15390,7 +15392,7 @@  rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -15709,6 +15711,17 @@  esac
 fi
 
 
+# Decide if -z memory-seal should be enabled in ELF linker by default.
+ac_default_ld_z_memory_seal=unset
+# Check whether --enable-memory-seal was given.
+if test "${enable_memory_seal+set}" = set; then :
+  enableval=$enable_memory_seal; case "${enableval}" in
+  yes) ac_default_ld_z_memory_seal=1 ;;
+  no) ac_default_ld_z_memory_seal=0 ;;
+esac
+fi
+
+
 
 # By default warn when an executable stack is created due to object files
 # requesting such, not when the user specifies -z execstack.
@@ -18965,6 +18978,8 @@  main ()
     if (*(data + i) != *(data3 + i))
       return 14;
   close (fd);
+  free (data);
+  free (data3);
   return 0;
 }
 _ACEOF
@@ -19444,6 +19459,15 @@  cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+if test "${ac_default_ld_z_memory_seal}" = unset; then
+  ac_default_ld_z_memory_seal=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_LD_Z_MEMORY_SEAL $ac_default_ld_z_memory_seal
+_ACEOF
+
+
 
 
 cat >>confdefs.h <<_ACEOF
diff --git a/ld/configure.ac b/ld/configure.ac
index 3ac2b46ee03..2166f75b487 100644
--- a/ld/configure.ac
+++ b/ld/configure.ac
@@ -232,6 +232,16 @@  AC_ARG_ENABLE(mark-plt,
   no) ac_default_ld_z_mark_plt=0 ;;
 esac])
 
+# Decide if -z memory-seal should be enabled in ELF linker by default.
+ac_default_ld_z_memory_seal=unset
+AC_ARG_ENABLE(memory-seal,
+	      AS_HELP_STRING([--enable-memory-seal],
+	      [enable -z memory-seal in ELF linker by default]),
+[case "${enableval}" in
+  yes) ac_default_ld_z_memory_seal=1 ;;
+  no) ac_default_ld_z_memory_seal=0 ;;
+esac])
+
 
 # By default warn when an executable stack is created due to object files
 # requesting such, not when the user specifies -z execstack.
@@ -617,6 +627,13 @@  AC_DEFINE_UNQUOTED(DEFAULT_LD_Z_MARK_PLT,
   $ac_default_ld_z_mark_plt,
   [Define to 1 if you want to enable -z mark-plt in ELF x86-64 linker by default.])
 
+if test "${ac_default_ld_z_memory_seal}" = unset; then
+  ac_default_ld_z_memory_seal=0
+fi
+AC_DEFINE_UNQUOTED(DEFAULT_LD_Z_MEMORY_SEAL,
+  $ac_default_ld_z_memory_seal,
+  [Define to 1 if you want to enable -z memory_seal in ELF linker by default.])
+
 
 AC_DEFINE_UNQUOTED(DEFAULT_LD_WARN_EXECSTACK,
   $ac_default_ld_warn_execstack,
diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em
index b2d281f96c7..7d7af8c8068 100644
--- a/ld/emultempl/elf.em
+++ b/ld/emultempl/elf.em
@@ -99,6 +99,7 @@  fragment <<EOF
   link_info.default_execstack = DEFAULT_LD_EXECSTACK;
   link_info.error_execstack = DEFAULT_LD_ERROR_EXECSTACK;
   link_info.warn_is_error_for_rwx_segments = DEFAULT_LD_ERROR_RWX_SEGMENTS;
+  link_info.memory_seal = DEFAULT_LD_Z_MEMORY_SEAL;
 }
 
 EOF
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 2bc7c953798..e21ebc233b0 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -2265,10 +2265,17 @@  elf_shlib_list_options (FILE *file)
       fprintf (file, _("\
   -z textoff                  Don't treat DT_TEXTREL in output as error\n"));
     }
+#if DEFAULT_LD_Z_MEMORY_SEAL
+  fprintf (file, _("\
+  -z memory-seal              Mark object be memory sealed (default)\n"));
+  fprintf (file, _("\
+  -z nomemory-seal            Don't mark oject to be memory sealed\n"));
+#else
   fprintf (file, _("\
   -z memory-seal              Mark object be memory sealed\n"));
   fprintf (file, _("\
   -z nomemory-seal            Don't mark oject to be memory sealed (default)\n"));
+#endif
 }
 
 static void
diff --git a/ld/testsuite/config/default.exp b/ld/testsuite/config/default.exp
index 9ffcc58779f..666f6660c0d 100644
--- a/ld/testsuite/config/default.exp
+++ b/ld/testsuite/config/default.exp
@@ -382,6 +382,14 @@  if { ![info exists NO_DT_RELR_CC_LDFLAGS] } then {
     }
 }
 
+if { ![info exists NO_MEMORY_SEAL_LDFLAGS] } then {
+    if { [check_memory_seal_support] } then {
+	set NO_MEMORY_SEAL_LDFLAGS "-z nomemory-seal"
+    } else {
+	set NO_MEMORY_SEAL_LDFLAGS {}
+    }
+}
+
 # Set LD_CLASS to "64bit" for a 64-bit *host* linker.
 if { ![info exists LD_CLASS] } then {
     set REAL_LD [findfile $base_dir/.libs/ld-new .libs/ld-new $LD [transform ld]]
diff --git a/ld/testsuite/ld-srec/srec.exp b/ld/testsuite/ld-srec/srec.exp
index bf440a2fa39..cbb58e719ed 100644
--- a/ld/testsuite/ld-srec/srec.exp
+++ b/ld/testsuite/ld-srec/srec.exp
@@ -226,12 +226,15 @@  proc run_srec_test { test objs } {
     global objcopy
     global sizeof_headers
     global host_triplet
+    global extra_flags
 
     # Tell the ELF linker to not do anything clever with .eh_frame,
     # not to put anything in small data, and define various symbols.
     set flags "--traditional-format -G 0 -e 0 "
     append flags [ld_link_defsyms]
 
+    append flags " $extra_flags"
+
     # If the linker script uses SIZEOF_HEADERS, use a -Ttext argument
     # to force both the normal link and the S-record link to be put in
     # the same place.  We don't always use -Ttext because it interacts
@@ -345,6 +348,7 @@  set test2 "S-records with constructors"
 # See whether the default linker script uses SIZEOF_HEADERS.
 set exec_output [run_host_cmd "$ld" "--verbose"]
 set sizeof_headers [string match "*SIZEOF_HEADERS*" $exec_output]
+set extra_flags " $NO_MEMORY_SEAL_LDFLAGS"
 
 # First test linking a C program.  We don't require any libraries.  We
 # link it normally, and objcopy to the S-record format, and then link
diff --git a/ld/testsuite/lib/ld-lib.exp b/ld/testsuite/lib/ld-lib.exp
index 4c434257725..7a1ce68cb6d 100644
--- a/ld/testsuite/lib/ld-lib.exp
+++ b/ld/testsuite/lib/ld-lib.exp
@@ -460,6 +460,9 @@  proc run_ld_link_tests { ldtests args } {
     if [check_relro_support] {
 	append ld_extra_opt " -z norelro"
     }
+    if [check_memory_seal_support] {
+	append ld_extra_opt " -z nomemory-seal"
+    }
 
     foreach testitem $ldtests {
 	set testname [lindex $testitem 0]
@@ -977,6 +980,9 @@  proc run_cc_link_tests { ldtests } {
 		set failed 1
 	    }
 	} else {
+	    if [check_memory_seal_support] {
+		append ldflags " -z nomemory-seal"
+	    }
 	    if { [string match "" $STATIC_LDFLAGS] \
 		 && [regexp -- ".* \[-\]+static .*" " $board_cflags $board_ldflags $ldflags $objfiles "] } {
 		untested $testname