[PATCH] Fix ld bloat introduced between binutils-2.38 and 2.39
Hans-Peter Nilsson
hp@axis.com
Mon Jan 2 16:08:57 GMT 2023
(Subject is for email list use, see below for a better
commit title.)
Ok to commit? If so, binutils-2.39 and 2.40 branches too?
If not, suggestion of other approaches, no later than
configure-time?
--- 8< ---
Subject: Let --with-elf-maxpagesize=N override target ELF_MAXPAGESIZE
Since commit 9833b7757d24, "PR28824, relro security issues",
ELF_MAXPAGESIZE matters much more, with regards to layout of
the linked file. That commit fixed an actual bug, but also
exposes a problem for targets were that value is too high.
For example, for ARM(32, a.k.a. "Aarch32") specifically
bfd_arch_arm, it's set to 64 KiB, making all Linux(/GNU)
targets pay an extra amount of up to 60 KiB of bloat in
DSO:s and executables. This matters when there are many
such files, and where storage is expensive.
It's *mostly* bloat when using a Linux kernel, as ARM(32) is
a good example of an target where ELF_MAXPAGESIZE is set to
an extreme value for an obscure corner-case. The ARM
(32-bit) kernel has 4 KiB pages, has had that value forever,
and can't be configured to any other value. The use-case is
IIUC "Aarch32" emulation on an "Aarch64" (arm64) kernel, but
not just that, but a setup where the Linux page-size is
configured to something other than the *default* 4 KiB. Not
sure there actually any such systems in use, again with
both Aarch32 compatibility support and a non-4KiB pagesize,
with all the warnings in the kernel config and requiring the
"EXPERT" level set on.
That may sound like an argument for setting the bfd_arch_arm
ELF_MAXPAGESIZE to 4 KiB, but then the obscure corner-case
wouldn't be properly handled. I wouldn't oppose that, but I
prefer not to regress the linker by default in my own patch.
I know about the linker option "-z max-page-size=0x1000",
but that requires finding every linker invocation or
patching gcc -and still finding all stray naked ld calls.
There was for a short while config.relro_use_commonpagesize
in the linker (commit 31b4d3a16f20) but besides the
self-explanatory ld_config_type member, IMHO it's too
obscure to re-introduce.
Instead, I suggest simply making ELF_MAXPAGESIZE generally
overridable by means of a --with option at linker
configuration time. In the patch I make the option
ELF-specific mostly for simplicity (more object-formats
means more places to find and patch, also the original
problem is ELF-specific).
bfd:
Let --with-elf-maxpagesize=N override target ELF_MAXPAGESIZE.
* configure.ac: Define FORCED_ELF_MAXPAGESIZE if
--with-elf-maxpagesize=N is passed.
* elfxx-target.h: Let FORCED_ELF_MAXPAGESIZE] override ELF_MAXPAGESIZE.
* configure, config.in: Regenerate.
---
bfd/config.in | 3 +++
bfd/configure | 22 ++++++++++++++++++++--
bfd/configure.ac | 10 ++++++++++
bfd/elfxx-target.h | 5 +++++
4 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/bfd/configure.ac b/bfd/configure.ac
index 82a3d1f832e7..88eaa52b5a82 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -115,6 +115,16 @@ AC_ARG_WITH(mmap,
*) AC_MSG_ERROR(bad value ${withval} for BFD with-mmap option) ;;
esac],[want_mmap=false])dnl
+ac_default_elf_maxpagesize=unset
+AC_ARG_WITH(elf_maxpagesize,
+ AS_HELP_STRING([--with-elf-maxpagesize=N],
+ [Set ELF_MAXPAGESIZE to N instead of using the target value]),
+[ac_default_elf_maxpagesize=$withval]) dnl
+if test ${ac_default_elf_maxpagesize} != unset; then
+ AC_DEFINE_UNQUOTED(FORCED_ELF_MAXPAGESIZE, ${ac_default_elf_maxpagesize},
+ [Define to a value with which to override the target ELF_MAXPAGESIZE.])
+fi
+
AC_ARG_ENABLE(secureplt,
[ --enable-secureplt Default to creating read-only plt entries],
[case "${enableval}" in
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index 9bcbdfb27dd8..2a32b8a8cb0d 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -374,6 +374,11 @@
#define ELF_OSABI ELFOSABI_NONE
#endif
+#ifdef FORCED_ELF_MAXPAGESIZE
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE FORCED_ELF_MAXPAGESIZE
+#endif
+
#ifndef ELF_MAXPAGESIZE
# error ELF_MAXPAGESIZE is not defined
#define ELF_MAXPAGESIZE 1
--
2.30.2
More information about the Binutils
mailing list