public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/7] Support DT_RELR relative relocation format
@ 2022-02-03 18:09 H.J. Lu
  2022-02-03 18:09 ` [PATCH 1/7] elf: Support DT_RELR relative relocation format [BZ #27924] H.J. Lu
                   ` (7 more replies)
  0 siblings, 8 replies; 20+ messages in thread
From: H.J. Lu @ 2022-02-03 18:09 UTC (permalink / raw)
  To: libc-alpha

PIE and shared objects usually have many relative relocations. In
2017/2018, SHT_RELR/DT_RELR was proposed on
https://groups.google.com/g/generic-abi/c/bX460iggiKg/m/GxjM0L-PBAAJ
("Proposal for a new section type SHT_RELR") and is a pre-standard. RELR
usually takes 3% or smaller space than R_*_RELATIVE relocations. The
virtual memory size of a mostly statically linked PIE is typically 5~10%
smaller.

Binutils 2.38 supports DT_RELR on x86 with the -z report-relative-reloc
option.  When DT_RELR is enabled, ld adds a GLIBC_ABI_DT_RELR symbol
version dependency on libc.so to outputs.  The DT_RELR support is enabled
in ld.so only if the linker supports -z report-relative-reloc option.

DT_RELR is enabled in glibc shared libraries and position independent
executables (PIE) automatically if linker supports -z pack-relative-relocs
nd the architecture defines SUPPORT_DT_RELR in config.h.  At the moment,
only x86 targets define SUPPORT_DT_RELR.

The DT_RELR usage in glibc can be disabled with --disable-default-dt-relr.

Tested with binutils 2.38 on i686, x86-64 and x32.

Fangrui Song (1):
  elf: Support DT_RELR relative relocation format [BZ #27924]

H.J. Lu (6):
  elf: Properly handle zero DT_RELA/DT_REL values
  Add GLIBC_ABI_DT_RELR for DT_RELR support
  x86/configure.ac: Define PI_STATIC_AND_HIDDEN/SUPPORT_STATIC_PIE
  x86: Define SUPPORT_DT_RELR
  Add --disable-default-dt-relr
  NEWS: Mention DT_RELR support

 INSTALL                     |  6 +++
 Makeconfig                  | 19 +++++++++
 Makerules                   |  2 +
 NEWS                        |  5 +++
 config.h.in                 |  6 +++
 configure                   | 84 +++++++++++++++++++++++++++++++++++++
 configure.ac                | 34 +++++++++++++++
 elf/Makefile                | 36 ++++++++++++++--
 elf/Versions                |  7 ++++
 elf/dynamic-link.h          | 40 +++++++++++++++++-
 elf/elf.h                   | 13 +++++-
 elf/get-dynamic-info.h      | 19 +++++++--
 elf/libc-abi-version.exp    |  1 +
 elf/tst-relr-pie.c          |  1 +
 elf/tst-relr.c              | 64 ++++++++++++++++++++++++++++
 manual/install.texi         |  5 +++
 scripts/abilist.awk         |  2 +
 scripts/versions.awk        |  7 +++-
 sysdeps/i386/configure      |  6 ---
 sysdeps/i386/configure.ac   |  7 ----
 sysdeps/x86/configure       |  9 ++++
 sysdeps/x86/configure.ac    | 10 +++++
 sysdeps/x86_64/configure    |  6 ---
 sysdeps/x86_64/configure.ac |  7 ----
 24 files changed, 360 insertions(+), 36 deletions(-)
 create mode 100644 elf/libc-abi-version.exp
 create mode 100644 elf/tst-relr-pie.c
 create mode 100644 elf/tst-relr.c

-- 
2.34.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 1/7] elf: Support DT_RELR relative relocation format [BZ #27924]
  2022-02-03 18:09 [PATCH 0/7] Support DT_RELR relative relocation format H.J. Lu
@ 2022-02-03 18:09 ` H.J. Lu
  2022-02-03 18:09 ` [PATCH 2/7] elf: Properly handle zero DT_RELA/DT_REL values H.J. Lu
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 20+ messages in thread
From: H.J. Lu @ 2022-02-03 18:09 UTC (permalink / raw)
  To: libc-alpha

From: Fangrui Song <maskray@google.com>

PIE and shared objects usually have many relative relocations. In
2017/2018, SHT_RELR/DT_RELR was proposed on
https://groups.google.com/g/generic-abi/c/bX460iggiKg/m/GxjM0L-PBAAJ
("Proposal for a new section type SHT_RELR") and is a pre-standard. RELR
usually takes 3% or smaller space than R_*_RELATIVE relocations. The
virtual memory size of a mostly statically linked PIE is typically 5~10%
smaller.

---

Notes I will not include in the submitted commit:

Available on https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/maskray/relr

"pre-standard": even Solaris folks are happy with the refined generic-abi
proposal. Cary Coutant will apply the change
https://sourceware.org/pipermail/libc-alpha/2021-October/131781.html

This patch is simpler than Chrome OS's glibc patch and makes ELF_DYNAMIC_DO_RELR
available to all ports. I don't think the current glibc implementation
supports ia64 in an ELFCLASS32 container. That said, the style I used is
works with an ELFCLASS32 container for 64-bit machine if ElfW(Addr) is
64-bit.

* Chrome OS folks have carried a local patch since 2018 (latest version:
  https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/refs/heads/main/sys-libs/glibc/files/local/glibc-2.32).
  I.e. this feature has been battle tested.
* Android bionic supports 2018 and switched to DT_RELR==36 in 2020.
* The Linux kernel has supported CONFIG_RELR since 2019-08
  (https://git.kernel.org/linus/5cf896fb6be3effd9aea455b22213e27be8bdb1d).
* A musl patch (by me) exists but is not applied:
  https://www.openwall.com/lists/musl/2019/03/06/3
* rtld-elf from FreeBSD 14 will support DT_RELR.

I believe upstream glibc should support DT_RELR to benefit all Linux
distributions. I filed some feature requests to get their attention:

* Gentoo: https://bugs.gentoo.org/818376
* Arch Linux: https://bugs.archlinux.org/task/72433
* Debian https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=996598
* Fedora https://bugzilla.redhat.com/show_bug.cgi?id=2014699

As of linker support (to the best of my knowledge):

* LLD support DT_RELR.
* https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/refs/heads/main/sys-devel/binutils/files/
  has a gold patch.
* GNU ld feature request https://sourceware.org/bugzilla/show_bug.cgi?id=27923

Changes from the original patch:

1. Check the linker option, -z pack-relative-relocs, which add a
GLIBC_ABI_DT_RELR symbol version dependency on the shared C library if
it provides a GLIBC_2.XX symbol version.
2. Define HAVE_DT_RELR and support DT_RELR only if -z pack-relative-relocs
is available.
3. Change make variale to have-dt-relr.
4. Rename tst-relr-no-pie to tst-relr-pie for --disable-default-pie.
5. Use TEST_VERIFY in tst-relr.c.
6. Add the check-tst-relr-pie.out test to check for linker generated
libc.so version dependency on GLIBC_ABI_DT_RELR.
---
 config.h.in            |  3 ++
 configure              | 46 ++++++++++++++++++++++++++++++
 configure.ac           | 11 ++++++++
 elf/Makefile           | 14 +++++++++
 elf/dynamic-link.h     | 34 ++++++++++++++++++++++
 elf/elf.h              | 13 +++++++--
 elf/get-dynamic-info.h |  3 ++
 elf/tst-relr-pie.c     |  1 +
 elf/tst-relr.c         | 64 ++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 187 insertions(+), 2 deletions(-)
 create mode 100644 elf/tst-relr-pie.c
 create mode 100644 elf/tst-relr.c

diff --git a/config.h.in b/config.h.in
index ff8597413d..edd167d96e 100644
--- a/config.h.in
+++ b/config.h.in
@@ -59,6 +59,9 @@
 /* Define if the linker supports the -z combreloc option.  */
 #undef	HAVE_Z_COMBRELOC
 
+/* Define if the linker supports the -z pack-relative-relocs option.  */
+#undef	HAVE_DT_RELR
+
 /* Define if _rtld_local structure should be forced into .sdata section.  */
 #undef	HAVE_SDATA_SECTION
 
diff --git a/configure b/configure
index 8e5bee775a..a9bdcb4ee5 100755
--- a/configure
+++ b/configure
@@ -6115,6 +6115,52 @@ $as_echo "$libc_linker_feature" >&6; }
 config_vars="$config_vars
 have-depaudit = $libc_cv_depaudit"
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker that supports -z pack-relative-relocs" >&5
+$as_echo_n "checking for linker that supports -z pack-relative-relocs... " >&6; }
+libc_linker_feature=no
+if test x"$gnu_ld" = x"yes"; then
+  cat > conftest.c <<EOF
+int _start (void) { return 42; }
+EOF
+  if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
+		    -Wl,-z,pack-relative-relocs -nostdlib -nostartfiles
+		    -fPIC -shared -o conftest.so conftest.c
+		    1>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+  then
+    if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp -Wl,-z,pack-relative-relocs -nostdlib \
+	-nostartfiles -fPIC -shared -o conftest.so conftest.c 2>&1 \
+	| grep "warning: -z pack-relative-relocs ignored" > /dev/null 2>&1; then
+      true
+    else
+      libc_linker_feature=yes
+    fi
+  fi
+  rm -f conftest*
+fi
+if test $libc_linker_feature = yes; then
+  libc_cv_dt_relr=yes
+else
+  libc_cv_dt_relr=no
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature" >&5
+$as_echo "$libc_linker_feature" >&6; }
+config_vars="$config_vars
+have-dt-relr = $libc_cv_dt_relr"
+if test "$libc_cv_dt_relr" = yes; then
+  have_dt_relr=1
+else
+  have_dt_relr=0
+fi
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DT_RELR $have_dt_relr
+_ACEOF
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker that supports --no-dynamic-linker" >&5
 $as_echo_n "checking for linker that supports --no-dynamic-linker... " >&6; }
 libc_linker_feature=no
diff --git a/configure.ac b/configure.ac
index 87f67d25ec..36a647cc14 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1367,6 +1367,17 @@ LIBC_LINKER_FEATURE([--depaudit], [-Wl,--depaudit,x],
 		    [libc_cv_depaudit=yes], [libc_cv_depaudit=no])
 LIBC_CONFIG_VAR([have-depaudit], [$libc_cv_depaudit])
 
+LIBC_LINKER_FEATURE([-z pack-relative-relocs],
+		    [-Wl,-z,pack-relative-relocs],
+		    [libc_cv_dt_relr=yes], [libc_cv_dt_relr=no])
+LIBC_CONFIG_VAR([have-dt-relr], [$libc_cv_dt_relr])
+if test "$libc_cv_dt_relr" = yes; then
+  have_dt_relr=1
+else
+  have_dt_relr=0
+fi
+AC_DEFINE_UNQUOTED(HAVE_DT_RELR, $have_dt_relr)
+
 LIBC_LINKER_FEATURE([--no-dynamic-linker],
 		    [-Wl,--no-dynamic-linker],
 		    [libc_cv_no_dynamic_linker=yes],
diff --git a/elf/Makefile b/elf/Makefile
index 5bdf0a383d..d1094f40ce 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -537,6 +537,14 @@ tests-special += \
   # tests-special
 endif
 endif
+ifeq ($(have-dt-relr),yes)
+tests += tst-relr tst-relr-pie
+tests-pie += tst-relr-pie
+tests-special += $(objpfx)check-tst-relr-pie.out
+CFLAGS-tst-relr-pie.c += $(pie-ccflag)
+LDFLAGS-tst-relr += -Wl,-z,pack-relative-relocs
+LDFLAGS-tst-relr-pie += -Wl,-z,pack-relative-relocs
+endif
 endif
 
 ifeq ($(run-built-tests),yes)
@@ -2733,3 +2741,9 @@ $(objpfx)tst-p_align3: $(objpfx)tst-p_alignmod3.so
 $(objpfx)tst-p_align3.out: tst-p_align3.sh $(objpfx)tst-p_align3
 	$(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
 	$(evaluate-test)
+
+$(objpfx)check-tst-relr-pie.out: $(objpfx)tst-relr-pie
+	LC_ALL=C $(OBJDUMP) -p $< \
+		| sed -ne '/required from libc.so/,$$ p' \
+		| grep GLIBC_ABI_DT_RELR > $@; \
+	$(evaluate-test)
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index 25dd7ca4f2..916439a586 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -146,14 +146,48 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 #  define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) /* Nothing to do.  */
 # endif
 
+# define ELF_DYNAMIC_DO_RELR(map)					      \
+  do {									      \
+    ElfW(Addr) l_addr = (map)->l_addr, *where = 0;			      \
+    const ElfW(Relr) *r, *end;						      \
+    if (!(map)->l_info[DT_RELR])					      \
+      break;								      \
+    r = (const ElfW(Relr) *)D_PTR((map), l_info[DT_RELR]);		      \
+    end = (const ElfW(Relr) *)((const char *)r +			      \
+                               (map)->l_info[DT_RELRSZ]->d_un.d_val);	      \
+    for (; r < end; r++)						      \
+      {									      \
+	ElfW(Relr) entry = *r;						      \
+	if ((entry & 1) == 0)						      \
+	  {								      \
+	    where = (ElfW(Addr) *)(l_addr + entry);			      \
+	    *where++ += l_addr;						      \
+	  }								      \
+	else 								      \
+	  {								      \
+	    for (long i = 0; (entry >>= 1) != 0; i++)			      \
+	      if ((entry & 1) != 0)					      \
+		where[i] += l_addr;					      \
+	    where += CHAR_BIT * sizeof(ElfW(Relr)) - 1;			      \
+	  }								      \
+      }									      \
+  } while (0);
+
 /* This can't just be an inline function because GCC is too dumb
    to inline functions containing inlines themselves.  */
+# ifdef RTLD_BOOTSTRAP
+#  define DO_RTLD_BOOTSTRAP 1
+# else
+#  define DO_RTLD_BOOTSTRAP 0
+# endif
 # define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc) \
   do {									      \
     int edr_lazy = elf_machine_runtime_setup ((map), (scope), (lazy),	      \
 					      (consider_profile));	      \
     ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, skip_ifunc);		      \
     ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, skip_ifunc);		      \
+    if (HAVE_DT_RELR && ((map) != &GL(dl_rtld_map) || DO_RTLD_BOOTSTRAP))     \
+      ELF_DYNAMIC_DO_RELR (map);					      \
   } while (0)
 
 #endif
diff --git a/elf/elf.h b/elf/elf.h
index 0735f6b579..0195029188 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -443,7 +443,8 @@ typedef struct
 #define SHT_PREINIT_ARRAY 16		/* Array of pre-constructors */
 #define SHT_GROUP	  17		/* Section group */
 #define SHT_SYMTAB_SHNDX  18		/* Extended section indices */
-#define	SHT_NUM		  19		/* Number of defined types.  */
+#define SHT_RELR	  19            /* RELR relative relocations */
+#define	SHT_NUM		  20		/* Number of defined types.  */
 #define SHT_LOOS	  0x60000000	/* Start OS-specific.  */
 #define SHT_GNU_ATTRIBUTES 0x6ffffff5	/* Object attributes.  */
 #define SHT_GNU_HASH	  0x6ffffff6	/* GNU-style hash table.  */
@@ -662,6 +663,11 @@ typedef struct
   Elf64_Sxword	r_addend;		/* Addend */
 } Elf64_Rela;
 
+/* RELR relocation table entry */
+
+typedef Elf32_Word	Elf32_Relr;
+typedef Elf64_Xword	Elf64_Relr;
+
 /* How to extract and insert information held in the r_info field.  */
 
 #define ELF32_R_SYM(val)		((val) >> 8)
@@ -887,7 +893,10 @@ typedef struct
 #define DT_PREINIT_ARRAY 32		/* Array with addresses of preinit fct*/
 #define DT_PREINIT_ARRAYSZ 33		/* size in bytes of DT_PREINIT_ARRAY */
 #define DT_SYMTAB_SHNDX	34		/* Address of SYMTAB_SHNDX section */
-#define	DT_NUM		35		/* Number used */
+#define DT_RELRSZ	35		/* Total size of RELR relative relocations */
+#define DT_RELR		36		/* Address of RELR relative relocations */
+#define DT_RELRENT	37		/* Size of one RELR relative relocaction */
+#define	DT_NUM		38		/* Number used */
 #define DT_LOOS		0x6000000d	/* Start of OS-specific */
 #define DT_HIOS		0x6ffff000	/* End of OS-specific */
 #define DT_LOPROC	0x70000000	/* Start of processor-specific */
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
index 6c2ccd6db4..6c2a3a12b1 100644
--- a/elf/get-dynamic-info.h
+++ b/elf/get-dynamic-info.h
@@ -89,6 +89,7 @@ elf_get_dynamic_info (struct link_map *l, bool bootstrap,
 # if ! ELF_MACHINE_NO_REL
       ADJUST_DYN_INFO (DT_REL);
 # endif
+      ADJUST_DYN_INFO (DT_RELR);
       ADJUST_DYN_INFO (DT_JMPREL);
       ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
       ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH));
@@ -113,6 +114,8 @@ elf_get_dynamic_info (struct link_map *l, bool bootstrap,
   if (info[DT_REL] != NULL)
     assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
 #endif
+  if (info[DT_RELR] != NULL)
+    assert (info[DT_RELRENT]->d_un.d_val == sizeof (ElfW(Relr)));
   if (bootstrap || static_pie_bootstrap)
     {
       assert (info[DT_RUNPATH] == NULL);
diff --git a/elf/tst-relr-pie.c b/elf/tst-relr-pie.c
new file mode 100644
index 0000000000..7df0cdbfd6
--- /dev/null
+++ b/elf/tst-relr-pie.c
@@ -0,0 +1 @@
+#include "tst-relr.c"
diff --git a/elf/tst-relr.c b/elf/tst-relr.c
new file mode 100644
index 0000000000..56addd2ad4
--- /dev/null
+++ b/elf/tst-relr.c
@@ -0,0 +1,64 @@
+/* Basic tests for DT_RELR.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <link.h>
+#include <stdbool.h>
+#include <support/check.h>
+
+static int o, x;
+
+#define ELEMS O O O O O O O O X X X X X X X O O X O O X X X E X E E O X O E
+#define E 0,
+
+#define O &o,
+#define X &x,
+void *arr[] = { ELEMS };
+#undef O
+#undef X
+
+#define O 1,
+#define X 2,
+static char val[] = { ELEMS };
+
+static int
+do_test (void)
+{
+  ElfW(Dyn) *d = _DYNAMIC;
+  if (d)
+    {
+      bool has_relr = false;
+      for (; d->d_tag != DT_NULL; d++)
+	if (d->d_tag == DT_RELR)
+	  has_relr = true;
+
+#if defined __PIE__ || defined __pie__ || defined PIE || defined pie
+      TEST_VERIFY (has_relr);
+#else
+      TEST_VERIFY (!has_relr);
+#endif
+    }
+
+  for (int i = 0; i < sizeof (arr) / sizeof (arr[0]); i++)
+    TEST_VERIFY ((arr[i] == 0 && val[i] == 0)
+		 || (arr[i] == &o && val[i] == 1)
+		 || (arr[i] == &x && val[i] == 2));
+
+  return 0;
+}
+
+#include <support/test-driver.c>
-- 
2.34.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 2/7] elf: Properly handle zero DT_RELA/DT_REL values
  2022-02-03 18:09 [PATCH 0/7] Support DT_RELR relative relocation format H.J. Lu
  2022-02-03 18:09 ` [PATCH 1/7] elf: Support DT_RELR relative relocation format [BZ #27924] H.J. Lu
@ 2022-02-03 18:09 ` H.J. Lu
  2022-02-03 18:09 ` [PATCH 3/7] Add GLIBC_ABI_DT_RELR for DT_RELR support H.J. Lu
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 20+ messages in thread
From: H.J. Lu @ 2022-02-03 18:09 UTC (permalink / raw)
  To: libc-alpha

With DT_RELR, there may be no relocations in DT_RELA/DT_REL and their
entry values are zero.  Don't relocate DT_RELA/DT_REL and update the
combined relocation start address if their entry values are zero.
---
 elf/dynamic-link.h     |  6 +++++-
 elf/get-dynamic-info.h | 18 ++++++++++++++----
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index 916439a586..d6c26d95e4 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -84,7 +84,9 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 	     __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; }  \
       ranges[2] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } };			      \
 									      \
-    if ((map)->l_info[DT_##RELOC])					      \
+    /* With DT_RELR, DT_RELA/DT_REL can have zero value.  */		      \
+    if ((map)->l_info[DT_##RELOC]					      \
+	&& (map)->l_info[DT_##RELOC]->d_un.d_ptr != 0)			      \
       {									      \
 	ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]);		      \
 	ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val;	      \
@@ -98,6 +100,8 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 	ElfW(Addr) start = D_PTR ((map), l_info[DT_JMPREL]);		      \
 	ElfW(Addr) size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val;	      \
 									      \
+	if (ranges[0].start == 0)					      \
+	  ranges[0].start = start;					      \
 	if (ranges[0].start + ranges[0].size == (start + size))		      \
 	  ranges[0].size -= size;					      \
 	if (!(do_lazy)							      \
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
index 6c2a3a12b1..f4b957684b 100644
--- a/elf/get-dynamic-info.h
+++ b/elf/get-dynamic-info.h
@@ -83,16 +83,26 @@ elf_get_dynamic_info (struct link_map *l, bool bootstrap,
       ADJUST_DYN_INFO (DT_PLTGOT);
       ADJUST_DYN_INFO (DT_STRTAB);
       ADJUST_DYN_INFO (DT_SYMTAB);
+      ADJUST_DYN_INFO (DT_RELR);
+      ADJUST_DYN_INFO (DT_JMPREL);
+      ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
+      ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH));
+# undef ADJUST_DYN_INFO
+
+      /* DT_RELA/DT_REL are mandatory.  But they may have zero value if
+	 there is DT_RELR.  Don't relocate them if they are zero.  */
+# define ADJUST_DYN_INFO(tag) \
+      do								      \
+	if (info[tag] != NULL && info[tag]->d_un.d_ptr != 0)		      \
+         info[tag]->d_un.d_ptr += l_addr;				      \
+      while (0)
+
 # if ! ELF_MACHINE_NO_RELA
       ADJUST_DYN_INFO (DT_RELA);
 # endif
 # if ! ELF_MACHINE_NO_REL
       ADJUST_DYN_INFO (DT_REL);
 # endif
-      ADJUST_DYN_INFO (DT_RELR);
-      ADJUST_DYN_INFO (DT_JMPREL);
-      ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
-      ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH));
 # undef ADJUST_DYN_INFO
     }
   if (info[DT_PLTREL] != NULL)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 3/7] Add GLIBC_ABI_DT_RELR for DT_RELR support
  2022-02-03 18:09 [PATCH 0/7] Support DT_RELR relative relocation format H.J. Lu
  2022-02-03 18:09 ` [PATCH 1/7] elf: Support DT_RELR relative relocation format [BZ #27924] H.J. Lu
  2022-02-03 18:09 ` [PATCH 2/7] elf: Properly handle zero DT_RELA/DT_REL values H.J. Lu
@ 2022-02-03 18:09 ` H.J. Lu
  2022-02-04 19:53   ` Joseph Myers
  2022-02-03 18:09 ` [PATCH 4/7] x86/configure.ac: Define PI_STATIC_AND_HIDDEN/SUPPORT_STATIC_PIE H.J. Lu
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 20+ messages in thread
From: H.J. Lu @ 2022-02-03 18:09 UTC (permalink / raw)
  To: libc-alpha

The EI_ABIVERSION field of the ELF header in executables and shared
libraries can be bumped to indicate the minimum ABI requirement on the
dynamic linker.  However, EI_ABIVERSION in executables isn't checked by
the Linux kernel ELF loader nor the existing dynamic linker.  Executables
will crash mysteriously if the dynamic linker doesn't support the ABI
features required by the EI_ABIVERSION field.  The dynamic linker should
be changed to check EI_ABIVERSION in executables.

Add a glibc version, GLIBC_ABI_DT_RELR, to indicate DT_RELR support so
that the existing dynamic linkers will issue an error on executables
with GLIBC_ABI_DT_RELR depdendency.

Support __placeholder_only_for_empty_version_map as the placeholder symbol
used only for empty version map to generate GLIBC_ABI_DT_RELR without any
symbols.
---
 elf/Makefile             | 18 ++++++++++++++++--
 elf/Versions             |  7 +++++++
 elf/libc-abi-version.exp |  1 +
 scripts/abilist.awk      |  2 ++
 scripts/versions.awk     |  7 ++++++-
 5 files changed, 32 insertions(+), 3 deletions(-)
 create mode 100644 elf/libc-abi-version.exp

diff --git a/elf/Makefile b/elf/Makefile
index d1094f40ce..c697e7b7ee 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -48,6 +48,10 @@ routines = \
   rtld_static_init \
   # routines
 
+ifeq ($(have-dt-relr),yes)
+check-abi-version-libc = $(objpfx)check-abi-version-libc.out
+endif
+
 # The core dynamic linking functions are in libc for the static and
 # profiled libraries.
 dl-routines = \
@@ -1106,8 +1110,8 @@ $(eval $(call include_dsosort_tests,dso-sort-tests-1.def))
 $(eval $(call include_dsosort_tests,dso-sort-tests-2.def))
 endif
 
-check-abi: $(objpfx)check-abi-ld.out
-tests-special += $(objpfx)check-abi-ld.out
+check-abi: $(objpfx)check-abi-ld.out $(check-abi-version-libc)
+tests-special += $(objpfx)check-abi-ld.out $(check-abi-version-libc)
 update-abi: update-abi-ld
 update-all-abi: update-all-abi-ld
 
@@ -2747,3 +2751,13 @@ $(objpfx)check-tst-relr-pie.out: $(objpfx)tst-relr-pie
 		| sed -ne '/required from libc.so/,$$ p' \
 		| grep GLIBC_ABI_DT_RELR > $@; \
 	$(evaluate-test)
+
+$(objpfx)check-abi-version-libc.out: libc-abi-version.exp \
+  $(objpfx)libc.symlist-abi-version
+	cmp $^ > $@; \
+	$(evaluate-test)
+
+$(objpfx)libc.symlist-abi-version: $(common-objpfx)libc.so
+	LC_ALL=C $(NM) -D $< | grep " GLIBC_ABI_" \
+		| sed "s/^0\+/00000000/" > $@T
+	mv -f $@T $@
diff --git a/elf/Versions b/elf/Versions
index 8bed855d8c..a84927c95f 100644
--- a/elf/Versions
+++ b/elf/Versions
@@ -23,6 +23,13 @@ libc {
   GLIBC_2.35 {
     _dl_find_object;
   }
+%if HAVE_DT_RELR
+  GLIBC_ABI_DT_RELR {
+    # This symbol is used only for empty version map and will be removed
+    # by scripts/versions.awk.
+    __placeholder_only_for_empty_version_map;
+  }
+%endif
   GLIBC_PRIVATE {
     # functions used in other libraries
     __libc_early_init;
diff --git a/elf/libc-abi-version.exp b/elf/libc-abi-version.exp
new file mode 100644
index 0000000000..455088dc6b
--- /dev/null
+++ b/elf/libc-abi-version.exp
@@ -0,0 +1 @@
+00000000 A GLIBC_ABI_DT_RELR
diff --git a/scripts/abilist.awk b/scripts/abilist.awk
index 24a34ccbed..6cc7af6ac8 100644
--- a/scripts/abilist.awk
+++ b/scripts/abilist.awk
@@ -55,6 +55,8 @@ $2 == "g" || $2 == "w" && (NF == 7 || NF == 8) {
   # caused STV_HIDDEN symbols to appear in .dynsym, though that is useless.
   if (NF > 7 && $7 == ".hidden") next;
 
+  if (version ~ /^GLIBC_ABI_/ && !include_abi_version) next;
+
   if (version == "GLIBC_PRIVATE" && !include_private) next;
 
   desc = "";
diff --git a/scripts/versions.awk b/scripts/versions.awk
index 357ad1355e..d70b07bd1a 100644
--- a/scripts/versions.awk
+++ b/scripts/versions.awk
@@ -185,8 +185,13 @@ END {
 	closeversion(oldver, veryoldver);
 	veryoldver = oldver;
       }
-      printf("%s {\n  global:\n", $2) > outfile;
       oldver = $2;
+      # Skip the placeholder symbol used only for empty version map.
+      if ($3 == "__placeholder_only_for_empty_version_map;") {
+	printf("%s {\n", $2) > outfile;
+	continue;
+      }
+      printf("%s {\n  global:\n", $2) > outfile;
     }
     printf("   ") > outfile;
     for (n = 3; n <= NF; ++n) {
-- 
2.34.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 4/7] x86/configure.ac: Define PI_STATIC_AND_HIDDEN/SUPPORT_STATIC_PIE
  2022-02-03 18:09 [PATCH 0/7] Support DT_RELR relative relocation format H.J. Lu
                   ` (2 preceding siblings ...)
  2022-02-03 18:09 ` [PATCH 3/7] Add GLIBC_ABI_DT_RELR for DT_RELR support H.J. Lu
@ 2022-02-03 18:09 ` H.J. Lu
  2022-02-03 18:09 ` [PATCH 5/7] x86: Define SUPPORT_DT_RELR H.J. Lu
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 20+ messages in thread
From: H.J. Lu @ 2022-02-03 18:09 UTC (permalink / raw)
  To: libc-alpha

Move PI_STATIC_AND_HIDDEN and SUPPORT_STATIC_PIE to
sysdeps/x86/configure.ac.
---
 sysdeps/i386/configure      | 6 ------
 sysdeps/i386/configure.ac   | 7 -------
 sysdeps/x86/configure       | 6 ++++++
 sysdeps/x86/configure.ac    | 7 +++++++
 sysdeps/x86_64/configure    | 6 ------
 sysdeps/x86_64/configure.ac | 7 -------
 6 files changed, 13 insertions(+), 26 deletions(-)

diff --git a/sysdeps/i386/configure b/sysdeps/i386/configure
index ed46d53314..af50c5bfab 100644
--- a/sysdeps/i386/configure
+++ b/sysdeps/i386/configure
@@ -83,13 +83,7 @@ $as_echo "$libc_cv_ld_static_pie" >&6; }
   fi
 fi
 
-$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
-
-
 if test x"$multi_arch" != xno; then
   $as_echo "#define NO_HIDDEN_EXTERN_FUNC_IN_PIE 1" >>confdefs.h
 
 fi
-
-$as_echo "#define SUPPORT_STATIC_PIE 1" >>confdefs.h
-
diff --git a/sysdeps/i386/configure.ac b/sysdeps/i386/configure.ac
index a6a0672835..234ef2454a 100644
--- a/sysdeps/i386/configure.ac
+++ b/sysdeps/i386/configure.ac
@@ -53,15 +53,8 @@ rm -f conftest*])
   fi
 fi
 
-dnl It is always possible to access static and hidden symbols in an
-dnl position independent way.
-AC_DEFINE(PI_STATIC_AND_HIDDEN)
-
 dnl When multi-arch is enabled, all external functions must be called
 dnl via PIC PLT in PIE, which requires setting up EBX register.
 if test x"$multi_arch" != xno; then
   AC_DEFINE(NO_HIDDEN_EXTERN_FUNC_IN_PIE)
 fi
-
-dnl Static PIE is supported.
-AC_DEFINE(SUPPORT_STATIC_PIE)
diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure
index 7bdbfdc6dc..46d436fddf 100644
--- a/sysdeps/x86/configure
+++ b/sysdeps/x86/configure
@@ -189,3 +189,9 @@ $as_echo "$libc_cv_have_x86_movbe" >&6; }
 fi
 config_vars="$config_vars
 enable-x86-isa-level = $libc_cv_include_x86_isa_level"
+
+$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
+
+
+$as_echo "#define SUPPORT_STATIC_PIE 1" >>confdefs.h
+
diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac
index 10d5c2e0e5..918b636891 100644
--- a/sysdeps/x86/configure.ac
+++ b/sysdeps/x86/configure.ac
@@ -127,3 +127,10 @@ if test $libc_cv_include_x86_isa_level = yes; then
   fi
 fi
 LIBC_CONFIG_VAR([enable-x86-isa-level], [$libc_cv_include_x86_isa_level])
+
+dnl It is always possible to access static and hidden symbols in an
+dnl position independent way.
+AC_DEFINE(PI_STATIC_AND_HIDDEN)
+
+dnl Static PIE is supported.
+AC_DEFINE(SUPPORT_STATIC_PIE)
diff --git a/sysdeps/x86_64/configure b/sysdeps/x86_64/configure
index d4dd0aa7df..44b6055e55 100755
--- a/sysdeps/x86_64/configure
+++ b/sysdeps/x86_64/configure
@@ -27,11 +27,5 @@ if test x"$build_mathvec" = xnotset; then
   build_mathvec=yes
 fi
 
-$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
-
-
-$as_echo "#define SUPPORT_STATIC_PIE 1" >>confdefs.h
-
-
 test -n "$critic_missing" && as_fn_error $? "
 *** $critic_missing" "$LINENO" 5
diff --git a/sysdeps/x86_64/configure.ac b/sysdeps/x86_64/configure.ac
index c4c748c1d0..1215dcb1e4 100644
--- a/sysdeps/x86_64/configure.ac
+++ b/sysdeps/x86_64/configure.ac
@@ -14,12 +14,5 @@ if test x"$build_mathvec" = xnotset; then
   build_mathvec=yes
 fi
 
-dnl It is always possible to access static and hidden symbols in an
-dnl position independent way.
-AC_DEFINE(PI_STATIC_AND_HIDDEN)
-
-dnl Static PIE is supported.
-AC_DEFINE(SUPPORT_STATIC_PIE)
-
 test -n "$critic_missing" && AC_MSG_ERROR([
 *** $critic_missing])
-- 
2.34.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 5/7] x86: Define SUPPORT_DT_RELR
  2022-02-03 18:09 [PATCH 0/7] Support DT_RELR relative relocation format H.J. Lu
                   ` (3 preceding siblings ...)
  2022-02-03 18:09 ` [PATCH 4/7] x86/configure.ac: Define PI_STATIC_AND_HIDDEN/SUPPORT_STATIC_PIE H.J. Lu
@ 2022-02-03 18:09 ` H.J. Lu
  2022-02-03 18:09 ` [PATCH 6/7] Add --disable-default-dt-relr H.J. Lu
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 20+ messages in thread
From: H.J. Lu @ 2022-02-03 18:09 UTC (permalink / raw)
  To: libc-alpha

Define SUPPORT_DT_RELR to indicate that DT_RELR is supported on x86.
---
 config.h.in              | 3 +++
 sysdeps/x86/configure    | 3 +++
 sysdeps/x86/configure.ac | 3 +++
 3 files changed, 9 insertions(+)

diff --git a/config.h.in b/config.h.in
index edd167d96e..fbf8138fce 100644
--- a/config.h.in
+++ b/config.h.in
@@ -280,6 +280,9 @@
 /* Define if static PIE is enabled.  */
 #define ENABLE_STATIC_PIE 0
 
+/* Define if DT_RELR is supported.  */
+#undef SUPPORT_DT_RELR
+
 /* The default value of x86 CET control.  */
 #define DEFAULT_DL_X86_CET_CONTROL cet_elf_property
 
diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure
index 46d436fddf..bf4b041f48 100644
--- a/sysdeps/x86/configure
+++ b/sysdeps/x86/configure
@@ -195,3 +195,6 @@ $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
 
 $as_echo "#define SUPPORT_STATIC_PIE 1" >>confdefs.h
 
+
+$as_echo "#define SUPPORT_DT_RELR 1" >>confdefs.h
+
diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac
index 918b636891..e737fd156a 100644
--- a/sysdeps/x86/configure.ac
+++ b/sysdeps/x86/configure.ac
@@ -134,3 +134,6 @@ AC_DEFINE(PI_STATIC_AND_HIDDEN)
 
 dnl Static PIE is supported.
 AC_DEFINE(SUPPORT_STATIC_PIE)
+
+dnl DT_RELR is supported.
+AC_DEFINE(SUPPORT_DT_RELR)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 6/7] Add --disable-default-dt-relr
  2022-02-03 18:09 [PATCH 0/7] Support DT_RELR relative relocation format H.J. Lu
                   ` (4 preceding siblings ...)
  2022-02-03 18:09 ` [PATCH 5/7] x86: Define SUPPORT_DT_RELR H.J. Lu
@ 2022-02-03 18:09 ` H.J. Lu
  2022-02-03 18:09 ` [PATCH 7/7] NEWS: Mention DT_RELR support H.J. Lu
  2022-02-04 20:00 ` [PATCH 0/7] Support DT_RELR relative relocation format Joseph Myers
  7 siblings, 0 replies; 20+ messages in thread
From: H.J. Lu @ 2022-02-03 18:09 UTC (permalink / raw)
  To: libc-alpha

Enable DT_RELR in glibc shared libraries and position independent
executables (PIE) automatically if linker supports -z pack-relative-relocs
and the architecture defines SUPPORT_DT_RELR in config.h.  At the moment,
only x86 targets define SUPPORT_DT_RELR.

Also add a new configuration option, --disable-default-dt-relr, to
avoid DT_RELR usage in glibc shared libraries and PIEs.
---
 INSTALL             |  6 ++++++
 Makeconfig          | 19 +++++++++++++++++++
 Makerules           |  2 ++
 configure           | 38 ++++++++++++++++++++++++++++++++++++++
 configure.ac        | 23 +++++++++++++++++++++++
 elf/Makefile        |  4 +++-
 manual/install.texi |  5 +++++
 7 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/INSTALL b/INSTALL
index 63c022d6b9..4a6506f11f 100644
--- a/INSTALL
+++ b/INSTALL
@@ -133,6 +133,12 @@ if 'CFLAGS' is specified it must enable optimization.  For example:
      used with the GCC option, -static-pie, which is available with GCC
      8 or above, to create static PIE.
 
+'--disable-default-dt-relr'
+     Don't enable DT_RELR in glibc shared libraries and position
+     independent executables (PIE). By default, DT_RELR is enabled in
+     glibc shared libraries and position independent executables on
+     targets that support it.
+
 '--enable-cet'
 '--enable-cet=permissive'
      Enable Intel Control-flow Enforcement Technology (CET) support.
diff --git a/Makeconfig b/Makeconfig
index 47db08d6ae..70c0acc065 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -358,6 +358,23 @@ else
 real-static-start-installed-name = $(static-start-installed-name)
 endif
 
+# Linker option to enable and disable DT-RELR.
+ifeq ($(have-dt-relr),yes)
+dt-relr-ldflag = -Wl,-z,pack-relative-relocs
+no-dt-relr-ldflag = -Wl,-z,nopack-relative-relocs
+else
+dt-relr-ldflag =
+no-dt-relr-ldflag =
+endif
+
+# Default linker option for DT-RELR.
+ifeq (yes,$(build-dt-relr-default))
+default-rt-relr-ldflag = $(dt-relr-ldflag)
+else
+default-rt-relr-ldflag = $(no-dt-relr-ldflag)
+endif
+LDFLAGS-rtld += $(default-rt-relr-ldflag)
+
 ifeq (yesyes,$(build-shared)$(have-z-combreloc))
 combreloc-LDFLAGS = -Wl,-z,combreloc
 LDFLAGS.so += $(combreloc-LDFLAGS)
@@ -419,6 +436,7 @@ link-extra-libs-tests = $(libsupport)
 # Command for linking PIE programs with the C library.
 ifndef +link-pie
 +link-pie-before-inputs = $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \
+	     $(if $($(@F)-no-dt-relr),$(no-dt-relr-ldflag),$(default-rt-relr-ldflag)) \
 	     -Wl,-O1 -nostdlib -nostartfiles \
 	     $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
 	     $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \
@@ -451,6 +469,7 @@ endif
 ifndef +link-static
 +link-static-before-inputs = -nostdlib -nostartfiles -static \
 	      $(if $($(@F)-no-pie),$(no-pie-ldflag),$(static-pie-ldflag)) \
+	      $(if $($(@F)-no-dt-relr),$(no-dt-relr-ldflag),$(default-rt-relr-ldflag)) \
 	      $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F))  \
 	      $(firstword $(CRT-$(@F)) $(csu-objpfx)$(real-static-start-installed-name)) \
 	      $(+preinit) $(+prectorT)
diff --git a/Makerules b/Makerules
index 5de2cec6be..260c7b7253 100644
--- a/Makerules
+++ b/Makerules
@@ -536,6 +536,7 @@ lib%.so: lib%_pic.a $(+preinit) $(+postinit) $(link-libc-deps)
 define build-shlib-helper
 $(LINK.o) -shared -static-libgcc -Wl,-O1 $(sysdep-LDFLAGS) \
 	  $(if $($(@F)-no-z-defs)$(no-z-defs),,-Wl,-z,defs) $(rtld-LDFLAGS) \
+	  $(if $($(@F)-no-dt-relr),$(no-dt-relr-ldflag),$(default-rt-relr-ldflag)) \
 	  $(extra-B-$(@F:lib%.so=%).so) -B$(csu-objpfx) \
 	  $(extra-B-$(@F:lib%.so=%).so) $(load-map-file) \
 	  -Wl,-soname=lib$(libprefix)$(@F:lib%.so=%).so$($(@F)-version) \
@@ -595,6 +596,7 @@ endef
 define build-module-helper
 $(LINK.o) -shared -static-libgcc $(sysdep-LDFLAGS) $(rtld-LDFLAGS) \
 	  $(if $($(@F)-no-z-defs)$(no-z-defs),,-Wl,-z,defs) \
+	  $(if $($(@F)-no-dt-relr),$(no-dt-relr-ldflag),$(default-rt-relr-ldflag)) \
 	  -B$(csu-objpfx) $(load-map-file) \
 	  $(LDFLAGS.so) $(LDFLAGS-$(@F:%.so=%).so) \
 	  $(link-test-modules-rpath-link) \
diff --git a/configure b/configure
index a9bdcb4ee5..e2d09ae84a 100755
--- a/configure
+++ b/configure
@@ -768,6 +768,7 @@ enable_sanity_checks
 enable_shared
 enable_profile
 enable_default_pie
+enable_default_dt_relr
 enable_timezone_tools
 enable_hardcoded_path_in_tests
 enable_hidden_plt
@@ -1425,6 +1426,7 @@ Optional Features:
   --enable-profile        build profiled library [default=no]
   --disable-default-pie   Do not build glibc programs and the testsuite as PIE
                           [default=no]
+  --disable-dt-relr       Do not enable DT_RELR in glibc[default=no]
   --disable-timezone-tools
                           do not install timezone tools [default=install]
   --enable-hardcoded-path-in-tests
@@ -3441,6 +3443,13 @@ else
   default_pie=yes
 fi
 
+# Check whether --enable-default-dt-relr was given.
+if test "${enable_default_dt_relr+set}" = set; then :
+  enableval=$enable_default_dt_relr; default_dt_relr=$enableval
+else
+  default_dt_relr=yes
+fi
+
 # Check whether --enable-timezone-tools was given.
 if test "${enable_timezone_tools+set}" = set; then :
   enableval=$enable_timezone_tools; enable_timezone_tools=$enableval
@@ -7140,6 +7149,35 @@ fi
 config_vars="$config_vars
 enable-static-pie = $libc_cv_static_pie"
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can enable DT_RELR" >&5
+$as_echo_n "checking if we can enable DT_RELR... " >&6; }
+libc_cv_dt_relr_supported=$libc_cv_dt_relr
+if test "x$libc_cv_dt_relr_supported" != xno; then
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef SUPPORT_DT_RELR
+# error DT_RELR is not supported
+#endif
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  libc_cv_dt_relr_supported=yes
+else
+  libc_cv_dt_relr_supported=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_dt_relr_supported" >&5
+$as_echo "$libc_cv_dt_relr_supported" >&6; }
+
+# Disable build-dt-relr-default if target does not support it or glibc is
+# configured with --disable-default-dt-relr.
+build_dt_relr_default=$default_dt_relr
+if test "x$build_dt_relr_default" != xno; then
+  build_dt_relr_default=$libc_cv_dt_relr_supported
+fi
+config_vars="$config_vars
+build-dt-relr-default = $build_dt_relr_default"
+
 # Set the `multidir' variable by grabbing the variable from the compiler.
 # We do it once and save the result in a generated makefile.
 libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
diff --git a/configure.ac b/configure.ac
index 36a647cc14..e572e99c41 100644
--- a/configure.ac
+++ b/configure.ac
@@ -197,6 +197,11 @@ AC_ARG_ENABLE([default-pie],
 			     [Do not build glibc programs and the testsuite as PIE @<:@default=no@:>@]),
 	      [default_pie=$enableval],
 	      [default_pie=yes])
+AC_ARG_ENABLE([default-dt-relr],
+	      AS_HELP_STRING([--disable-dt-relr],
+			     [Do not enable DT_RELR in glibc@<:@default=no@:>@]),
+	      [default_dt_relr=$enableval],
+	      [default_dt_relr=yes])
 AC_ARG_ENABLE([timezone-tools],
 	      AS_HELP_STRING([--disable-timezone-tools],
 			     [do not install timezone tools @<:@default=install@:>@]),
@@ -1915,6 +1920,24 @@ if test "$libc_cv_static_pie" = "yes"; then
 fi
 LIBC_CONFIG_VAR([enable-static-pie], [$libc_cv_static_pie])
 
+AC_MSG_CHECKING(if we can enable DT_RELR)
+libc_cv_dt_relr_supported=$libc_cv_dt_relr
+if test "x$libc_cv_dt_relr_supported" != xno; then
+  AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#ifndef SUPPORT_DT_RELR
+# error DT_RELR is not supported
+#endif]])], [libc_cv_dt_relr_supported=yes],
+	    [libc_cv_dt_relr_supported=no])
+fi
+AC_MSG_RESULT($libc_cv_dt_relr_supported)
+
+# Disable build-dt-relr-default if target does not support it or glibc is
+# configured with --disable-default-dt-relr.
+build_dt_relr_default=$default_dt_relr
+if test "x$build_dt_relr_default" != xno; then
+  build_dt_relr_default=$libc_cv_dt_relr_supported
+fi
+LIBC_CONFIG_VAR([build-dt-relr-default], [$build_dt_relr_default])
+
 # Set the `multidir' variable by grabbing the variable from the compiler.
 # We do it once and save the result in a generated makefile.
 libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
diff --git a/elf/Makefile b/elf/Makefile
index c697e7b7ee..9f807cd650 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -1570,6 +1570,7 @@ $(objpfx)nodlopen2.out: $(objpfx)nodlopenmod2.so
 
 $(objpfx)filtmod1.so: $(objpfx)filtmod1.os $(objpfx)filtmod2.so
 	$(LINK.o) -shared -o $@ -B$(csu-objpfx) $(LDFLAGS.so) \
+		  $(default-rt-relr-ldflag) \
 		  -L$(subst :, -L,$(rpath-link)) \
 		  -Wl,-rpath-link=$(rpath-link) \
 		  $< -Wl,-F,$(objpfx)filtmod2.so
@@ -2376,7 +2377,7 @@ $(objpfx)tst-big-note: $(objpfx)tst-big-note-lib.so
 # artificial, large note in tst-big-note-lib.o and invalidate the
 # test.
 $(objpfx)tst-big-note-lib.so: $(objpfx)tst-big-note-lib.o
-	$(LINK.o) -shared -o $@ $(LDFLAGS.so) $<
+	$(LINK.o) -shared -o $@ $(LDFLAGS.so) $(default-rt-relr-ldflag) $<
 
 $(objpfx)tst-unwind-ctor: $(objpfx)tst-unwind-ctor-lib.so
 
@@ -2682,6 +2683,7 @@ $(objpfx)tst-ro-dynamic: $(objpfx)tst-ro-dynamic-mod.so
 $(objpfx)tst-ro-dynamic-mod.so: $(objpfx)tst-ro-dynamic-mod.os \
   tst-ro-dynamic-mod.map
 	$(LINK.o) -nostdlib -nostartfiles -shared -o $@ \
+		$(default-rt-relr-ldflag) \
 		-Wl,--script=tst-ro-dynamic-mod.map \
 		$(objpfx)tst-ro-dynamic-mod.os
 
diff --git a/manual/install.texi b/manual/install.texi
index 29c52f2927..04ea996561 100644
--- a/manual/install.texi
+++ b/manual/install.texi
@@ -161,6 +161,11 @@ and architecture support it, static executables are built as static PIE and the
 resulting glibc can be used with the GCC option, -static-pie, which is
 available with GCC 8 or above, to create static PIE.
 
+@item --disable-default-dt-relr
+Don't enable DT_RELR in glibc shared libraries and position independent
+executables (PIE).  By default, DT_RELR is enabled in glibc shared
+libraries and position independent executables on targets that support it.
+
 @item --enable-cet
 @itemx --enable-cet=permissive
 Enable Intel Control-flow Enforcement Technology (CET) support.  When
-- 
2.34.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 7/7] NEWS: Mention DT_RELR support
  2022-02-03 18:09 [PATCH 0/7] Support DT_RELR relative relocation format H.J. Lu
                   ` (5 preceding siblings ...)
  2022-02-03 18:09 ` [PATCH 6/7] Add --disable-default-dt-relr H.J. Lu
@ 2022-02-03 18:09 ` H.J. Lu
  2022-02-04 20:00 ` [PATCH 0/7] Support DT_RELR relative relocation format Joseph Myers
  7 siblings, 0 replies; 20+ messages in thread
From: H.J. Lu @ 2022-02-03 18:09 UTC (permalink / raw)
  To: libc-alpha

---
 NEWS | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/NEWS b/NEWS
index 7b8febcb72..31ace26ca3 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,11 @@ See the end for copying conditions.
 
 Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
 using `glibc' in the "product" field.
+\f
+Major new features:
+
+* Support DT_RELR relative relocation format.
+
 \f
 Version 2.36
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/7] Add GLIBC_ABI_DT_RELR for DT_RELR support
  2022-02-03 18:09 ` [PATCH 3/7] Add GLIBC_ABI_DT_RELR for DT_RELR support H.J. Lu
@ 2022-02-04 19:53   ` Joseph Myers
  2022-02-04 20:04     ` H.J. Lu
  0 siblings, 1 reply; 20+ messages in thread
From: Joseph Myers @ 2022-02-04 19:53 UTC (permalink / raw)
  To: H.J. Lu; +Cc: libc-alpha

On Thu, 3 Feb 2022, H.J. Lu via Libc-alpha wrote:

> +%if HAVE_DT_RELR
> +  GLIBC_ABI_DT_RELR {
> +    # This symbol is used only for empty version map and will be removed
> +    # by scripts/versions.awk.
> +    __placeholder_only_for_empty_version_map;
> +  }

My understanding is that HAVE_DT_RELR describes a property of the linker 
used to build glibc, not a property of what features glibc itself 
supports.

The symbol versions provided by glibc, and whether glibc supports binaries 
using RELR relocations, should be independent of whether the linker 
version used to build glibc supports such relocations.  A given glibc 
version should either always support RELR relocations (for a given glibc 
ABI) or never support them (for that ABI), independent of linker features, 
and likewise the symbol versions provided by glibc should be independent 
of linker features.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/7] Support DT_RELR relative relocation format
  2022-02-03 18:09 [PATCH 0/7] Support DT_RELR relative relocation format H.J. Lu
                   ` (6 preceding siblings ...)
  2022-02-03 18:09 ` [PATCH 7/7] NEWS: Mention DT_RELR support H.J. Lu
@ 2022-02-04 20:00 ` Joseph Myers
  2022-02-04 20:08   ` H.J. Lu
  2022-02-04 20:32   ` Fangrui Song
  7 siblings, 2 replies; 20+ messages in thread
From: Joseph Myers @ 2022-02-04 20:00 UTC (permalink / raw)
  To: H.J. Lu; +Cc: libc-alpha

On Thu, 3 Feb 2022, H.J. Lu via Libc-alpha wrote:

> DT_RELR is enabled in glibc shared libraries and position independent
> executables (PIE) automatically if linker supports -z pack-relative-relocs
> nd the architecture defines SUPPORT_DT_RELR in config.h.  At the moment,
> only x86 targets define SUPPORT_DT_RELR.

The patch 1 description says "This patch is simpler than Chrome OS's glibc 
patch and makes ELF_DYNAMIC_DO_RELR available to all ports.".

What exactly would other architectures need to add in glibc to provide 
RELR support, since I don't see any actual architecture-specific code in 
this patch series outside of configure scripts?  Please provide text you 
would propose to add to https://sourceware.org/glibc/wiki/PortStatus that 
gives an architecture maintainer all the information needed to add such 
support for their architecture.  If in fact no architecture-specific code 
should be needed, please remove the SUPPORT_DT_RELR handling and just 
allow glibc to support the feature for all architectures (while using RELR 
in glibc itself for architectures where the linker support is present, as 
detected by a configure test on the linker rather than hardcoding 
information about which architectures have that linker support at a given 
time).

The default should be to support a feature for all architectures.  A patch 
series supporting a feature for only some architectures needs a positive 
reason for excluding other architectures (for example, that each 
architecture needs architecture-specific code, for which you provide 
suitable documentation to add to PortStatus to help architecture 
maintainers in writing such code).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/7] Add GLIBC_ABI_DT_RELR for DT_RELR support
  2022-02-04 19:53   ` Joseph Myers
@ 2022-02-04 20:04     ` H.J. Lu
  2022-02-04 20:10       ` Joseph Myers
  0 siblings, 1 reply; 20+ messages in thread
From: H.J. Lu @ 2022-02-04 20:04 UTC (permalink / raw)
  To: Joseph Myers; +Cc: GNU C Library

On Fri, Feb 4, 2022 at 11:53 AM Joseph Myers <joseph@codesourcery.com> wrote:
>
> On Thu, 3 Feb 2022, H.J. Lu via Libc-alpha wrote:
>
> > +%if HAVE_DT_RELR
> > +  GLIBC_ABI_DT_RELR {
> > +    # This symbol is used only for empty version map and will be removed
> > +    # by scripts/versions.awk.
> > +    __placeholder_only_for_empty_version_map;
> > +  }
>
> My understanding is that HAVE_DT_RELR describes a property of the linker
> used to build glibc, not a property of what features glibc itself
> supports.
>
> The symbol versions provided by glibc, and whether glibc supports binaries
> using RELR relocations, should be independent of whether the linker
> version used to build glibc supports such relocations.  A given glibc
> version should either always support RELR relocations (for a given glibc
> ABI) or never support them (for that ABI), independent of linker features,
> and likewise the symbol versions provided by glibc should be independent
> of linker features.
>

In my cover letter, I said

Binutils 2.38 supports DT_RELR on x86 with the -z report-relative-reloc
option.  When DT_RELR is enabled, ld adds a GLIBC_ABI_DT_RELR symbol
version dependency on libc.so to outputs.  The DT_RELR support is enabled
in ld.so only if the linker supports -z report-relative-reloc option.

and the first patch has

 # define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc) \
   do {       \
     int edr_lazy = elf_machine_runtime_setup ((map), (scope), (lazy),       \
        (consider_profile));       \
     ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, skip_ifunc);       \
     ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, skip_ifunc);
      \
+    if (HAVE_DT_RELR && ((map) != &GL(dl_rtld_map) || DO_RTLD_BOOTSTRAP))     \
+      ELF_DYNAMIC_DO_RELR (map);       \
   } while (0)

If HAVE_DT_RELR is 0, DT_RELR is disabled.

-- 
H.J.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/7] Support DT_RELR relative relocation format
  2022-02-04 20:00 ` [PATCH 0/7] Support DT_RELR relative relocation format Joseph Myers
@ 2022-02-04 20:08   ` H.J. Lu
  2022-02-04 20:12     ` Joseph Myers
  2022-02-04 20:32   ` Fangrui Song
  1 sibling, 1 reply; 20+ messages in thread
From: H.J. Lu @ 2022-02-04 20:08 UTC (permalink / raw)
  To: Joseph Myers; +Cc: GNU C Library

On Fri, Feb 4, 2022 at 12:00 PM Joseph Myers <joseph@codesourcery.com> wrote:
>
> On Thu, 3 Feb 2022, H.J. Lu via Libc-alpha wrote:
>
> > DT_RELR is enabled in glibc shared libraries and position independent
> > executables (PIE) automatically if linker supports -z pack-relative-relocs
> > nd the architecture defines SUPPORT_DT_RELR in config.h.  At the moment,
> > only x86 targets define SUPPORT_DT_RELR.
>
> The patch 1 description says "This patch is simpler than Chrome OS's glibc
> patch and makes ELF_DYNAMIC_DO_RELR available to all ports.".
>
> What exactly would other architectures need to add in glibc to provide
> RELR support, since I don't see any actual architecture-specific code in

DT_RELR is enabled only if linker supports -z report-relative-reloc option
which adds GLIBC_ABI_DT_RELR dependency in the linker output to
prevent random crashes with the older glibc binaries.

> this patch series outside of configure scripts?  Please provide text you
> would propose to add to https://sourceware.org/glibc/wiki/PortStatus that
> gives an architecture maintainer all the information needed to add such
> support for their architecture.  If in fact no architecture-specific code
> should be needed, please remove the SUPPORT_DT_RELR handling and just
> allow glibc to support the feature for all architectures (while using RELR
> in glibc itself for architectures where the linker support is present, as
> detected by a configure test on the linker rather than hardcoding
> information about which architectures have that linker support at a given
> time).
>
> The default should be to support a feature for all architectures.  A patch
> series supporting a feature for only some architectures needs a positive
> reason for excluding other architectures (for example, that each
> architecture needs architecture-specific code, for which you provide
> suitable documentation to add to PortStatus to help architecture
> maintainers in writing such code).
>
> --
> Joseph S. Myers
> joseph@codesourcery.com



-- 
H.J.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/7] Add GLIBC_ABI_DT_RELR for DT_RELR support
  2022-02-04 20:04     ` H.J. Lu
@ 2022-02-04 20:10       ` Joseph Myers
  2022-02-04 20:40         ` H.J. Lu
  0 siblings, 1 reply; 20+ messages in thread
From: Joseph Myers @ 2022-02-04 20:10 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GNU C Library

On Fri, 4 Feb 2022, H.J. Lu via Libc-alpha wrote:

> In my cover letter, I said
> 
> Binutils 2.38 supports DT_RELR on x86 with the -z report-relative-reloc
> option.  When DT_RELR is enabled, ld adds a GLIBC_ABI_DT_RELR symbol
> version dependency on libc.so to outputs.  The DT_RELR support is enabled
> in ld.so only if the linker supports -z report-relative-reloc option.
> 
> and the first patch has
> 
>  # define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc) \
>    do {       \
>      int edr_lazy = elf_machine_runtime_setup ((map), (scope), (lazy),       \
>         (consider_profile));       \
>      ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, skip_ifunc);       \
>      ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, skip_ifunc);
>       \
> +    if (HAVE_DT_RELR && ((map) != &GL(dl_rtld_map) || DO_RTLD_BOOTSTRAP))     \
> +      ELF_DYNAMIC_DO_RELR (map);       \
>    } while (0)
> 
> If HAVE_DT_RELR is 0, DT_RELR is disabled.

It's important that glibc 2.36 supports the same executables and shared 
libraries on a given platform, independent of the binutils version used to 
build glibc.  If any build of glibc 2.36 for some platform supports RELR 
relocations, all builds of it for that platform must support such 
relocations.

That means that configure tests for linker support can *only* affect 
whether glibc is built to *use* such relocations itself - not whether it 
supports loading executables and shared libraries that use them.

(You could also increase the minimum linker version for building glibc for 
a given platform, but the RELR support is too recent for it to be a good 
idea to make the minimum version new enough to include RELR support.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/7] Support DT_RELR relative relocation format
  2022-02-04 20:08   ` H.J. Lu
@ 2022-02-04 20:12     ` Joseph Myers
  0 siblings, 0 replies; 20+ messages in thread
From: Joseph Myers @ 2022-02-04 20:12 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GNU C Library

On Fri, 4 Feb 2022, H.J. Lu via Libc-alpha wrote:

> On Fri, Feb 4, 2022 at 12:00 PM Joseph Myers <joseph@codesourcery.com> wrote:
> >
> > On Thu, 3 Feb 2022, H.J. Lu via Libc-alpha wrote:
> >
> > > DT_RELR is enabled in glibc shared libraries and position independent
> > > executables (PIE) automatically if linker supports -z pack-relative-relocs
> > > nd the architecture defines SUPPORT_DT_RELR in config.h.  At the moment,
> > > only x86 targets define SUPPORT_DT_RELR.
> >
> > The patch 1 description says "This patch is simpler than Chrome OS's glibc
> > patch and makes ELF_DYNAMIC_DO_RELR available to all ports.".
> >
> > What exactly would other architectures need to add in glibc to provide
> > RELR support, since I don't see any actual architecture-specific code in
> 
> DT_RELR is enabled only if linker supports -z report-relative-reloc option
> which adds GLIBC_ABI_DT_RELR dependency in the linker output to
> prevent random crashes with the older glibc binaries.

What do you mean by "is enabled"?

Building glibc itself to use such relocations can properly depend on 
linker support.

The set of binaries (executables and shared libraries) glibc can load must 
not depend on linker support.

Those are two different questions.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/7] Support DT_RELR relative relocation format
  2022-02-04 20:00 ` [PATCH 0/7] Support DT_RELR relative relocation format Joseph Myers
  2022-02-04 20:08   ` H.J. Lu
@ 2022-02-04 20:32   ` Fangrui Song
  1 sibling, 0 replies; 20+ messages in thread
From: Fangrui Song @ 2022-02-04 20:32 UTC (permalink / raw)
  To: Joseph Myers; +Cc: H.J. Lu, libc-alpha

On 2022-02-04, Joseph Myers wrote:
>On Thu, 3 Feb 2022, H.J. Lu via Libc-alpha wrote:
>
>> DT_RELR is enabled in glibc shared libraries and position independent
>> executables (PIE) automatically if linker supports -z pack-relative-relocs
>> nd the architecture defines SUPPORT_DT_RELR in config.h.  At the moment,
>> only x86 targets define SUPPORT_DT_RELR.
>
>The patch 1 description says "This patch is simpler than Chrome OS's glibc
>patch and makes ELF_DYNAMIC_DO_RELR available to all ports.".
>
>What exactly would other architectures need to add in glibc to provide
>RELR support, since I don't see any actual architecture-specific code in
>this patch series outside of configure scripts?  Please provide text you
>would propose to add to https://sourceware.org/glibc/wiki/PortStatus that
>gives an architecture maintainer all the information needed to add such
>support for their architecture.  If in fact no architecture-specific code
>should be needed, please remove the SUPPORT_DT_RELR handling and just
>allow glibc to support the feature for all architectures (while using RELR
>in glibc itself for architectures where the linker support is present, as
>detected by a configure test on the linker rather than hardcoding
>information about which architectures have that linker support at a given
>time).
>
>The default should be to support a feature for all architectures.  A patch
>series supporting a feature for only some architectures needs a positive
>reason for excluding other architectures (for example, that each
>architecture needs architecture-specific code, for which you provide
>suitable documentation to add to PortStatus to help architecture
>maintainers in writing such code).

The patch series mix two things.

"elf: Support DT_RELR relative relocation format [BZ #27924]" allows
user programs to use DT_RELR. This is the main benefit.

AIUI the other patches are to allow x86-64 libc.so.6 to be built with
DT_RELR. This is more for dogfooding purposes and helps binutils port
maintainers confirm their ld.bfd support handles some uncommon cases
(glibc shared objects).

The second part needs a https://sourceware.org/glibc/wiki/PortStatus
entry.

---

(Personally I'd prefer separate patches.
But with some frustration on
https://sourceware.org/pipermail/libc-alpha/2021-November/133009.html
I don't care in what form glibc will get DT_RELR support...
and I really appreciate that H.J contributed the ld.bfd support and
drives this glibc effort.
)

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/7] Add GLIBC_ABI_DT_RELR for DT_RELR support
  2022-02-04 20:10       ` Joseph Myers
@ 2022-02-04 20:40         ` H.J. Lu
  2022-02-04 21:01           ` Joseph Myers
  0 siblings, 1 reply; 20+ messages in thread
From: H.J. Lu @ 2022-02-04 20:40 UTC (permalink / raw)
  To: Joseph Myers; +Cc: GNU C Library

On Fri, Feb 4, 2022 at 12:11 PM Joseph Myers <joseph@codesourcery.com> wrote:
>
> On Fri, 4 Feb 2022, H.J. Lu via Libc-alpha wrote:
>
> > In my cover letter, I said
> >
> > Binutils 2.38 supports DT_RELR on x86 with the -z report-relative-reloc
> > option.  When DT_RELR is enabled, ld adds a GLIBC_ABI_DT_RELR symbol
> > version dependency on libc.so to outputs.  The DT_RELR support is enabled
> > in ld.so only if the linker supports -z report-relative-reloc option.
> >
> > and the first patch has
> >
> >  # define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc) \
> >    do {       \
> >      int edr_lazy = elf_machine_runtime_setup ((map), (scope), (lazy),       \
> >         (consider_profile));       \
> >      ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, skip_ifunc);       \
> >      ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, skip_ifunc);
> >       \
> > +    if (HAVE_DT_RELR && ((map) != &GL(dl_rtld_map) || DO_RTLD_BOOTSTRAP))     \
> > +      ELF_DYNAMIC_DO_RELR (map);       \
> >    } while (0)
> >
> > If HAVE_DT_RELR is 0, DT_RELR is disabled.
>
> It's important that glibc 2.36 supports the same executables and shared
> libraries on a given platform, independent of the binutils version used to
> build glibc.  If any build of glibc 2.36 for some platform supports RELR
> relocations, all builds of it for that platform must support such
> relocations.
>
> That means that configure tests for linker support can *only* affect
> whether glibc is built to *use* such relocations itself - not whether it
> supports loading executables and shared libraries that use them.
>
> (You could also increase the minimum linker version for building glibc for
> a given platform, but the RELR support is too recent for it to be a good
> idea to make the minimum version new enough to include RELR support.)

Good point.  How about "enable DT_RELR only if SUPPORT_DT_RELR is
defined?  Currently, only x86 defines SUPPORT_DT_RELR.

-- 
H.J.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/7] Add GLIBC_ABI_DT_RELR for DT_RELR support
  2022-02-04 20:40         ` H.J. Lu
@ 2022-02-04 21:01           ` Joseph Myers
  2022-02-04 21:08             ` H.J. Lu
  0 siblings, 1 reply; 20+ messages in thread
From: Joseph Myers @ 2022-02-04 21:01 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GNU C Library

On Fri, 4 Feb 2022, H.J. Lu via Libc-alpha wrote:

> Good point.  How about "enable DT_RELR only if SUPPORT_DT_RELR is
> defined?  Currently, only x86 defines SUPPORT_DT_RELR.

My preference would be:

1. Support user executables and shared libraries with RELR relocations 
across all platforms, unconditionally.

2. Build glibc to use RELR relocations in its own executables and shared 
libraries based on an architecture-independent configure test for whether 
linker support is present.

And avoid any architecture-specific conditional relating to RELR support 
in glibc completely.

*If* it turns out to be hard to have a fully reliable 
architecture-independent configure test for linker support, and the 
architecture-independent test reports linker support to be present (in an 
actual binutils release, not just the development mainline) for an 
architecture where that support is in fact buggy and incomplete, then we 
might consider adding an architecture-specific test on that architecture 
to disable building glibc to use RELR relocations with the buggy linker 
version.  That is, architecture-specific tests would only be to disable 
building glibc to use RELR relocations, not to enable it, and only when 
the bugs in linker support on that architecture can't readily be detected 
by an architecture-independent test.  The default for all existing and 
future architectures would be to follow the results of the 
architecture-independent configure test.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/7] Add GLIBC_ABI_DT_RELR for DT_RELR support
  2022-02-04 21:01           ` Joseph Myers
@ 2022-02-04 21:08             ` H.J. Lu
  2022-02-04 23:58               ` Joseph Myers
  0 siblings, 1 reply; 20+ messages in thread
From: H.J. Lu @ 2022-02-04 21:08 UTC (permalink / raw)
  To: Joseph Myers; +Cc: GNU C Library

On Fri, Feb 4, 2022 at 1:01 PM Joseph Myers <joseph@codesourcery.com> wrote:
>
> On Fri, 4 Feb 2022, H.J. Lu via Libc-alpha wrote:
>
> > Good point.  How about "enable DT_RELR only if SUPPORT_DT_RELR is
> > defined?  Currently, only x86 defines SUPPORT_DT_RELR.
>
> My preference would be:
>
> 1. Support user executables and shared libraries with RELR relocations
> across all platforms, unconditionally.

RELR is kind of like static PIE.  Not all architectures support it.
RELR should be enabled only if there is a linker which supports
-z pack-relative-relocs.  That is the main reason why RELR is
enabled in glibc 2.35.

> 2. Build glibc to use RELR relocations in its own executables and shared
> libraries based on an architecture-independent configure test for whether
> linker support is present.

This is implemented in

commit 486531c29b0fa48287b29ea20e805bee1ec19a67
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sat Jan 22 05:44:45 2022 -0800

    Add --disable-default-dt-relr

which is similar to --disable-default-pie.

> And avoid any architecture-specific conditional relating to RELR support
> in glibc completely.
>
> *If* it turns out to be hard to have a fully reliable
> architecture-independent configure test for linker support, and the
> architecture-independent test reports linker support to be present (in an
> actual binutils release, not just the development mainline) for an
> architecture where that support is in fact buggy and incomplete, then we
> might consider adding an architecture-specific test on that architecture
> to disable building glibc to use RELR relocations with the buggy linker
> version.  That is, architecture-specific tests would only be to disable
> building glibc to use RELR relocations, not to enable it, and only when
> the bugs in linker support on that architecture can't readily be detected
> by an architecture-independent test.  The default for all existing and
> future architectures would be to follow the results of the
> architecture-independent configure test.


-- 
H.J.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/7] Add GLIBC_ABI_DT_RELR for DT_RELR support
  2022-02-04 21:08             ` H.J. Lu
@ 2022-02-04 23:58               ` Joseph Myers
  2022-02-05 17:24                 ` H.J. Lu
  0 siblings, 1 reply; 20+ messages in thread
From: Joseph Myers @ 2022-02-04 23:58 UTC (permalink / raw)
  To: H.J. Lu; +Cc: GNU C Library

On Fri, 4 Feb 2022, H.J. Lu via Libc-alpha wrote:

> On Fri, Feb 4, 2022 at 1:01 PM Joseph Myers <joseph@codesourcery.com> wrote:
> >
> > On Fri, 4 Feb 2022, H.J. Lu via Libc-alpha wrote:
> >
> > > Good point.  How about "enable DT_RELR only if SUPPORT_DT_RELR is
> > > defined?  Currently, only x86 defines SUPPORT_DT_RELR.
> >
> > My preference would be:
> >
> > 1. Support user executables and shared libraries with RELR relocations
> > across all platforms, unconditionally.
> 
> RELR is kind of like static PIE.  Not all architectures support it.

My understanding is that analogy only applies to the static linker, not to 
glibc itself - that the static linker needs architecture-specific code, 
but glibc doesn't (as evidenced by the lack of any architecture-specific 
non-configure changes in this patch series).

> RELR should be enabled only if there is a linker which supports
> -z pack-relative-relocs.

(a) That should only apply to "enabled" in the sense of "glibc itself uses 
RELR relocations", not "glibc supports loading executables and shared 
libraries with such relocations".

(b) The configure test for that should be architecture-independent, with 
no architecture-specific configure changes needed at all.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 3/7] Add GLIBC_ABI_DT_RELR for DT_RELR support
  2022-02-04 23:58               ` Joseph Myers
@ 2022-02-05 17:24                 ` H.J. Lu
  0 siblings, 0 replies; 20+ messages in thread
From: H.J. Lu @ 2022-02-05 17:24 UTC (permalink / raw)
  To: Joseph Myers; +Cc: GNU C Library

On Fri, Feb 4, 2022 at 3:58 PM Joseph Myers <joseph@codesourcery.com> wrote:
>
> On Fri, 4 Feb 2022, H.J. Lu via Libc-alpha wrote:
>
> > On Fri, Feb 4, 2022 at 1:01 PM Joseph Myers <joseph@codesourcery.com> wrote:
> > >
> > > On Fri, 4 Feb 2022, H.J. Lu via Libc-alpha wrote:
> > >
> > > > Good point.  How about "enable DT_RELR only if SUPPORT_DT_RELR is
> > > > defined?  Currently, only x86 defines SUPPORT_DT_RELR.
> > >
> > > My preference would be:
> > >
> > > 1. Support user executables and shared libraries with RELR relocations
> > > across all platforms, unconditionally.
> >
> > RELR is kind of like static PIE.  Not all architectures support it.
>
> My understanding is that analogy only applies to the static linker, not to
> glibc itself - that the static linker needs architecture-specific code,
> but glibc doesn't (as evidenced by the lack of any architecture-specific
> non-configure changes in this patch series).
>
> > RELR should be enabled only if there is a linker which supports
> > -z pack-relative-relocs.
>
> (a) That should only apply to "enabled" in the sense of "glibc itself uses
> RELR relocations", not "glibc supports loading executables and shared
> libraries with such relocations".
>
> (b) The configure test for that should be architecture-independent, with
> no architecture-specific configure changes needed at all.
>

Fixed in the v2 patch.

-- 
H.J.

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2022-02-05 17:25 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-03 18:09 [PATCH 0/7] Support DT_RELR relative relocation format H.J. Lu
2022-02-03 18:09 ` [PATCH 1/7] elf: Support DT_RELR relative relocation format [BZ #27924] H.J. Lu
2022-02-03 18:09 ` [PATCH 2/7] elf: Properly handle zero DT_RELA/DT_REL values H.J. Lu
2022-02-03 18:09 ` [PATCH 3/7] Add GLIBC_ABI_DT_RELR for DT_RELR support H.J. Lu
2022-02-04 19:53   ` Joseph Myers
2022-02-04 20:04     ` H.J. Lu
2022-02-04 20:10       ` Joseph Myers
2022-02-04 20:40         ` H.J. Lu
2022-02-04 21:01           ` Joseph Myers
2022-02-04 21:08             ` H.J. Lu
2022-02-04 23:58               ` Joseph Myers
2022-02-05 17:24                 ` H.J. Lu
2022-02-03 18:09 ` [PATCH 4/7] x86/configure.ac: Define PI_STATIC_AND_HIDDEN/SUPPORT_STATIC_PIE H.J. Lu
2022-02-03 18:09 ` [PATCH 5/7] x86: Define SUPPORT_DT_RELR H.J. Lu
2022-02-03 18:09 ` [PATCH 6/7] Add --disable-default-dt-relr H.J. Lu
2022-02-03 18:09 ` [PATCH 7/7] NEWS: Mention DT_RELR support H.J. Lu
2022-02-04 20:00 ` [PATCH 0/7] Support DT_RELR relative relocation format Joseph Myers
2022-02-04 20:08   ` H.J. Lu
2022-02-04 20:12     ` Joseph Myers
2022-02-04 20:32   ` Fangrui Song

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).