[PATCH v5 3/3] ld: Add --enable-memory-seal configure option

H.J. Lu hjl.tools@gmail.com
Thu Jan 2 21:49:13 GMT 2025


On Fri, Jan 3, 2025 at 3:20 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
> 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(-)
>
> diff --git a/binutils/testsuite/lib/binutils-common.exp b/binutils/testsuite/lib/binutils-common.exp
> index daf12eb0fbb..72664d84bcc 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 5d5fec4aed3..4aa5408d88f 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 004fa31d877..228f2ee4089 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 9a14eae749e..d8fb034697b 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 9cf1a9a033b..5399aa45b72 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 95ff4f19e7a..f93fb30ab07 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 49ca7454d86..bec59130425 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 6182d3e066a..c4653d4946b 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
> --
> 2.43.0
>

As the GNU property owner, it looks OK to me.  Please apply if
there are no objections from other binutils maintainers after a few
days.

Thanks.

-- 
H.J.


More information about the Binutils mailing list