glibc: update support for SHT_RELR patch for 2.35

update of this support is at:
- https://maskray.me/blog/2021-10-31-relative-relocations-and-relr#glibc
- https://sourceware.org/pipermail/libc-alpha/2021-October/132029.html

This commit rebases the current SHT_RELR patch to support glibc 2.35.
Future updates should look at using the updated patch though binutils
updates maybe required.
This commit is contained in:
Rudi Heitbaum 2022-04-10 13:44:10 +00:00
parent b3e6fc48d6
commit cb2b5c4095
2 changed files with 90 additions and 92 deletions

View File

@ -28,7 +28,7 @@ been updated to include the new definitions.
--- a/elf/do-rel.h --- a/elf/do-rel.h
+++ b/elf/do-rel.h +++ b/elf/do-rel.h
@@ -26,6 +26,12 @@ @@ -28,6 +28,12 @@
# define elf_machine_rel_relative elf_machine_rela_relative # define elf_machine_rel_relative elf_machine_rela_relative
#endif #endif
@ -41,7 +41,7 @@ been updated to include the new definitions.
#ifndef DO_ELF_MACHINE_REL_RELATIVE #ifndef DO_ELF_MACHINE_REL_RELATIVE
# define DO_ELF_MACHINE_REL_RELATIVE(map, l_addr, relative) \ # define DO_ELF_MACHINE_REL_RELATIVE(map, l_addr, relative) \
elf_machine_rel_relative (l_addr, relative, \ elf_machine_rel_relative (l_addr, relative, \
@@ -46,12 +52,12 @@ elf_dynamic_do_Rel (struct link_map *map @@ -48,12 +54,12 @@ elf_dynamic_do_Rel (struct link_map *map
const ElfW(Rel) *r = (const void *) reladdr; const ElfW(Rel) *r = (const void *) reladdr;
const ElfW(Rel) *end = (const void *) (reladdr + relsize); const ElfW(Rel) *end = (const void *) (reladdr + relsize);
ElfW(Addr) l_addr = map->l_addr; ElfW(Addr) l_addr = map->l_addr;
@ -56,7 +56,7 @@ been updated to include the new definitions.
/* We never bind lazily during ld.so bootstrap. Unfortunately gcc is /* We never bind lazily during ld.so bootstrap. Unfortunately gcc is
not clever enough to see through all the function calls to realize not clever enough to see through all the function calls to realize
that. */ that. */
@@ -80,8 +86,10 @@ elf_dynamic_do_Rel (struct link_map *map @@ -82,8 +88,10 @@ elf_dynamic_do_Rel (struct link_map *map
else else
#endif #endif
{ {
@ -67,7 +67,7 @@ been updated to include the new definitions.
const ElfW(Rel) *relative = r; const ElfW(Rel) *relative = r;
r += nrelative; r += nrelative;
@@ -108,9 +116,36 @@ elf_dynamic_do_Rel (struct link_map *map @@ -110,9 +118,36 @@ elf_dynamic_do_Rel (struct link_map *map
if (l_addr != 0 || ! map->l_info[VALIDX(DT_GNU_PRELINKED)]) if (l_addr != 0 || ! map->l_info[VALIDX(DT_GNU_PRELINKED)])
# endif # endif
#endif #endif
@ -80,7 +80,7 @@ been updated to include the new definitions.
+ ElfW(Relr) entry = *relative; + ElfW(Relr) entry = *relative;
+ if ((entry&1) == 0) + if ((entry&1) == 0)
+ { + {
+ elf_machine_relr_relative (l_addr, (void *) (l_addr + entry)); + elf_machine_relr_relative (l_addr, scope, (void *) (l_addr + entry));
+ base = entry + sizeof(ElfW(Addr)); + base = entry + sizeof(ElfW(Addr));
+ continue; + continue;
+ } + }
@ -89,7 +89,7 @@ been updated to include the new definitions.
+ { + {
+ entry >>= 1; + entry >>= 1;
+ if ((entry&1) != 0) + if ((entry&1) != 0)
+ elf_machine_relr_relative (l_addr, (void *) (l_addr + offset)); + elf_machine_relr_relative (l_addr, scope, (void *) (l_addr + offset));
+ offset += sizeof(ElfW(Addr)); + offset += sizeof(ElfW(Addr));
+ } + }
+ base += (8*sizeof(ElfW(Addr)) - 1) * sizeof(ElfW(Addr)); + base += (8*sizeof(ElfW(Addr)) - 1) * sizeof(ElfW(Addr));
@ -104,7 +104,7 @@ been updated to include the new definitions.
#ifdef RTLD_BOOTSTRAP #ifdef RTLD_BOOTSTRAP
/* The dynamic linker always uses versioning. */ /* The dynamic linker always uses versioning. */
assert (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL); assert (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL);
@@ -180,6 +215,7 @@ elf_dynamic_do_Rel (struct link_map *map @@ -211,6 +246,7 @@ elf_dynamic_do_Rel (struct link_map *map
# endif # endif
} }
#endif #endif
@ -112,46 +112,46 @@ been updated to include the new definitions.
} }
} }
@@ -189,3 +225,4 @@ elf_dynamic_do_Rel (struct link_map *map @@ -220,3 +256,4 @@ elf_dynamic_do_Rel (struct link_map *map
#undef elf_machine_rel_relative #undef elf_machine_rel_relative
#undef DO_ELF_MACHINE_REL_RELATIVE #undef DO_ELF_MACHINE_REL_RELATIVE
#undef DO_RELA #undef DO_RELA
+#undef DO_RELR +#undef DO_RELR
--- a/elf/dynamic-link.h --- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h +++ b/elf/dynamic-link.h
@@ -76,6 +76,11 @@ auto inline void __attribute__((always_i @@ -50,6 +50,11 @@ static inline void __attribute__((always_i
elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
void *const reloc_addr); void *const reloc_addr);
# endif # endif
+# if ! ELF_MACHINE_NO_RELR +# if ! ELF_MACHINE_NO_RELR
+auto inline void __attribute__((always_inline)) +static inline void __attribute__((always_inline))
+elf_machine_relr_relative (ElfW(Addr) l_addr, +elf_machine_relr_relative (ElfW(Addr) l_addr, struct r_scope_elem *scope[],
+ void *const reloc_addr); + void *const reloc_addr);
+# endif +# endif
# if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL # if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL
auto inline void __attribute__((always_inline)) static inline void __attribute__((always_inline))
elf_machine_lazy_rel (struct link_map *map, elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
@@ -190,6 +195,15 @@ elf_machine_lazy_rel (struct link_map *m @@ -146,6 +151,15 @@ elf_machine_lazy_rel (struct link_map *m
# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) /* Nothing to do. */ # define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) /* Nothing to do. */
# endif # endif
+# if ! ELF_MACHINE_NO_RELR +# if ! ELF_MACHINE_NO_RELR
+# define DO_RELR +# define DO_RELR
+# include "do-rel.h" +# include "do-rel.h"
+# define ELF_DYNAMIC_DO_RELR(map, lazy, skip_ifunc) \ +# define ELF_DYNAMIC_DO_RELR(map, scope, lazy, skip_ifunc) \
+ _ELF_DYNAMIC_DO_RELOC (RELR, Relr, map, lazy, skip_ifunc, 1) + _ELF_DYNAMIC_DO_RELOC (RELR, Relr, map, scope, lazy, skip_ifunc, 1)
+# else +# else
+# define ELF_DYNAMIC_DO_RELR(map, lazy, skip_ifunc) /* Nothing to do. */ +# define ELF_DYNAMIC_DO_RELR(map, scope, lazy, skip_ifunc) /* Nothing to do. */
+# endif +# endif
+ +
/* This can't just be an inline function because GCC is too dumb /* This can't just be an inline function because GCC is too dumb
to inline functions containing inlines themselves. */ to inline functions containing inlines themselves. */
# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile, skip_ifunc) \ # define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc) \
@@ -198,6 +212,7 @@ elf_machine_lazy_rel (struct link_map *m @@ -154,6 +168,7 @@ elf_machine_lazy_rel (struct link_map *m
(consider_profile)); \ (consider_profile)); \
ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc); \ ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, skip_ifunc); \
ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc); \ ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, skip_ifunc); \
+ ELF_DYNAMIC_DO_RELR ((map), edr_lazy, skip_ifunc); \ + ELF_DYNAMIC_DO_RELR ((map), (scope), edr_lazy, skip_ifunc); \
} while (0) } while (0)
#endif #endif
@ -202,7 +202,7 @@ been updated to include the new definitions.
--- a/elf/get-dynamic-info.h --- a/elf/get-dynamic-info.h
+++ b/elf/get-dynamic-info.h +++ b/elf/get-dynamic-info.h
@@ -103,6 +103,9 @@ elf_get_dynamic_info (struct link_map *l @@ -89,6 +89,9 @@ elf_get_dynamic_info (struct link_map *l
# if ! ELF_MACHINE_NO_REL # if ! ELF_MACHINE_NO_REL
ADJUST_DYN_INFO (DT_REL); ADJUST_DYN_INFO (DT_REL);
# endif # endif
@ -212,7 +212,7 @@ been updated to include the new definitions.
ADJUST_DYN_INFO (DT_JMPREL); ADJUST_DYN_INFO (DT_JMPREL);
ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM)); ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH)); ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH));
@@ -129,6 +132,10 @@ elf_get_dynamic_info (struct link_map *l @@ -113,6 +116,10 @@ elf_get_dynamic_info (struct link_map *l
if (info[DT_REL] != NULL) if (info[DT_REL] != NULL)
assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel))); assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
#endif #endif
@ -220,52 +220,36 @@ been updated to include the new definitions.
+ if (info[DT_RELR] != NULL) + if (info[DT_RELR] != NULL)
+ assert (info[DT_RELRENT]->d_un.d_val == sizeof (ElfW(Relr))); + assert (info[DT_RELRENT]->d_un.d_val == sizeof (ElfW(Relr)));
+# endif +# endif
#ifdef RTLD_BOOTSTRAP if (bootstrap || static_pie_bootstrap)
/* Only the bind now flags are allowed. */ {
assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL assert (info[DT_RUNPATH] == NULL);
--- a/sysdeps/aarch64/dl-machine.h --- a/sysdeps/aarch64/dl-machine.h
+++ b/sysdeps/aarch64/dl-machine.h +++ b/sysdeps/aarch64/dl-machine.h
@@ -198,6 +198,7 @@ _dl_start_user: \n\
/* AArch64 uses RELA not REL */
#define ELF_MACHINE_NO_REL 1
#define ELF_MACHINE_NO_RELA 0
+#define ELF_MACHINE_NO_RELR 0
#define DL_PLATFORM_INIT dl_platform_init ()
@@ -384,6 +385,15 @@ elf_machine_rela_relative (ElfW(Addr) l_ @@ -384,6 +385,15 @@ elf_machine_rela_relative (ElfW(Addr) l_
} }
inline void static inline void
+__attribute__ ((always_inline)) +__attribute__ ((always_inline))
+elf_machine_relr_relative (ElfW(Addr) l_addr, +elf_machine_relr_relative (ElfW(Addr) l_addr, struct r_scope_elem *scope[],
+ void *const reloc_addr_arg) + void *const reloc_addr_arg)
+{ +{
+ ElfW(Addr) *const reloc_addr = reloc_addr_arg; + ElfW(Addr) *const reloc_addr = reloc_addr_arg;
+ *reloc_addr += l_addr; + *reloc_addr += l_addr;
+} +}
+ +
+inline void +static inline void
__attribute__ ((always_inline)) __attribute__ ((always_inline))
elf_machine_lazy_rel (struct link_map *map, elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
ElfW(Addr) l_addr, ElfW(Addr) l_addr,
--- a/sysdeps/arm/dl-machine.h --- a/sysdeps/arm/dl-machine.h
+++ b/sysdeps/arm/dl-machine.h +++ b/sysdeps/arm/dl-machine.h
@@ -296,6 +296,7 @@ elf_machine_plt_value (struct link_map *
Prelinked libraries may use Elf32_Rela though. */
#define ELF_MACHINE_NO_RELA defined RTLD_BOOTSTRAP
#define ELF_MACHINE_NO_REL 0
+#define ELF_MACHINE_NO_RELR 0
/* Names of the architecture-specific auditing callback functions. */
#define ARCH_LA_PLTENTER arm_gnu_pltenter
@@ -637,6 +638,15 @@ elf_machine_rel_relative (Elf32_Addr l_a @@ -637,6 +638,15 @@ elf_machine_rel_relative (Elf32_Addr l_a
*reloc_addr += l_addr; *reloc_addr += l_addr;
} }
+auto inline void +static inline void
+__attribute ((always_inline)) +__attribute ((always_inline))
+elf_machine_relr_relative (ElfW(Addr) l_addr, +elf_machine_relr_relative (ElfW(Addr) l_addr, struct r_scope_elem *scope[],
+ void *const reloc_addr_arg) + void *const reloc_addr_arg)
+{ +{
+ ElfW(Addr) *const reloc_addr = reloc_addr_arg; + ElfW(Addr) *const reloc_addr = reloc_addr_arg;
@ -273,57 +257,71 @@ been updated to include the new definitions.
+} +}
+ +
# ifndef RTLD_BOOTSTRAP # ifndef RTLD_BOOTSTRAP
auto inline void static inline void
__attribute__ ((always_inline)) __attribute__ ((always_inline))
--- a/sysdeps/i386/dl-machine.h --- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h
@@ -285,6 +285,7 @@ elf_machine_plt_value (struct link_map * @@ -626,6 +626,15 @@ elf_machine_rel_relative (Elf32_Addr l_a
*reloc_addr += l_addr;
}
+static inline void
+__attribute ((always_inline))
+elf_machine_relr_relative (ElfW(Addr) l_addr, struct r_scope_elem *scope[],
+ void *const reloc_addr_arg)
+{
+ ElfW(Addr) *const reloc_addr = reloc_addr_arg;
+ *reloc_addr += l_addr;
+}
+
# ifndef RTLD_BOOTSTRAP
static inline void
__attribute__ ((always_inline))
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -545,6 +546,15 @@ elf_machine_rela_relative (ElfW(Addr) l_
}
static inline void
+__attribute ((always_inline))
+elf_machine_relr_relative (ElfW(Addr) l_addr, struct r_scope_elem *scope[],
+ void *const reloc_addr_arg)
+{
+ ElfW(Addr) *const reloc_addr = reloc_addr_arg;
+ *reloc_addr += l_addr;
+}
+
+static inline void
__attribute ((always_inline))
elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
--- a/sysdeps/arm/dl-machine-rel.h 2022-02-03 05:27:54.000000000 +0000
+++ b/sysdeps/arm/dl-machine-rel.h 2022-04-11 10:16:03.103743770 +0000
@@ -23,6 +23,7 @@
Prelinked libraries may use Elf32_Rela though. */ Prelinked libraries may use Elf32_Rela though. */
#define ELF_MACHINE_NO_RELA defined RTLD_BOOTSTRAP #define ELF_MACHINE_NO_RELA defined RTLD_BOOTSTRAP
#define ELF_MACHINE_NO_REL 0 #define ELF_MACHINE_NO_REL 0
+#define ELF_MACHINE_NO_RELR 0 +#define ELF_MACHINE_NO_RELR 0
#ifdef RESOLVE_MAP /* ARM never uses Elf32_Rela relocations for the dynamic linker.
Prelinked libraries may use Elf32_Rela though. */
@@ -657,6 +658,15 @@ elf_machine_rel_relative (Elf32_Addr l_a --- a/sysdeps/generic/dl-machine-rel.h 2022-02-03 05:27:54.000000000 +0000
*reloc_addr += l_addr; +++ b/sysdeps/generic/dl-machine-rel.h 2022-04-11 10:28:40.996539086 +0000
} @@ -23,6 +23,7 @@
+auto inline void
+__attribute ((always_inline))
+elf_machine_relr_relative (ElfW(Addr) l_addr,
+ void *const reloc_addr_arg)
+{
+ ElfW(Addr) *const reloc_addr = reloc_addr_arg;
+ *reloc_addr += l_addr;
+}
+
# ifndef RTLD_BOOTSTRAP
auto inline void
__attribute__ ((always_inline))
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -209,6 +209,7 @@ _dl_start_user:\n\
/* The x86-64 never uses Elf64_Rel/Elf32_Rel relocations. */
#define ELF_MACHINE_NO_REL 1 #define ELF_MACHINE_NO_REL 1
/* Defined if the architecture supports Elf{32,64}_Rela relocations. */
#define ELF_MACHINE_NO_RELA 0 #define ELF_MACHINE_NO_RELA 0
+#define ELF_MACHINE_NO_RELR 0 +#define ELF_MACHINE_NO_RELR 0
/* Used to calculate the index of link_map l_reloc_result. */
#define PLTREL ElfW(Rela)
/* We define an initialization function. This is called very early in --- a/sysdeps/i386/dl-machine-rel.h 2022-02-03 05:27:54.000000000 +0000
_dl_sysdep_start. */ +++ b/sysdeps/i386/dl-machine-rel.h 2022-04-11 10:16:17.677066810 +0000
@@ -545,6 +546,15 @@ elf_machine_rela_relative (ElfW(Addr) l_ @@ -23,6 +23,7 @@
} Prelinked libraries may use Elf32_Rela though. */
#define ELF_MACHINE_NO_RELA defined RTLD_BOOTSTRAP
#define ELF_MACHINE_NO_REL 0
+#define ELF_MACHINE_NO_RELR 0
auto inline void /* The i386 never uses Elf32_Rela relocations for the dynamic linker.
+__attribute ((always_inline)) Prelinked libraries may use Elf32_Rela though. */
+elf_machine_relr_relative (ElfW(Addr) l_addr,
+ void *const reloc_addr_arg)
+{
+ ElfW(Addr) *const reloc_addr = reloc_addr_arg;
+ *reloc_addr += l_addr;
+}
+
+auto inline void
__attribute ((always_inline))
elf_machine_lazy_rel (struct link_map *map,
ElfW(Addr) l_addr, const ElfW(Rela) *reloc,

View File

@ -15,7 +15,7 @@ Subject: [PATCH] tls: libwidevinecdm.so: since 4.10.2252.0 has TLS with
@@ -220,6 +220,11 @@ void @@ -220,6 +220,11 @@ void
_dl_determine_tlsoffset (void) _dl_determine_tlsoffset (void)
{ {
size_t max_align = TLS_TCB_ALIGN; size_t max_align = TCB_ALIGNMENT;
+ /* libwidevinecdm.so: since 4.10.2252.0 has TLS with 64-byte alignment. + /* libwidevinecdm.so: since 4.10.2252.0 has TLS with 64-byte alignment.
+ Since TLS is initialized before audit modules are loaded and slotinfo + Since TLS is initialized before audit modules are loaded and slotinfo
+ information is available, this is not taken into account below in + information is available, this is not taken into account below in