Created
February 17, 2022 12:17
-
-
Save dobo90/74dfddcc8faea2222b251b8ec125749f to your computer and use it in GitHub Desktop.
glibc 2.35 widevine patches for arm (relr and firends)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 33a9869e2e7fe993f57d23559317b7f558ae2331 Mon Sep 17 00:00:00 2001 | |
From: Rahul Chaudhry <rahulchaudhry@chromium.org> | |
Date: Thu, 15 Mar 2018 14:30:17 -0700 | |
Subject: [PATCH 1/2] sys-libs/glibc: add support for SHT_RELR sections. | |
This patch adds experimental support for SHT_RELR sections, proposed | |
here: https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg | |
SHT_RELR sections are supported for arm, aarch64, and x86_64 targets. | |
To enable them, pass '--experimental-use-relr' flag to gold. | |
Definitions for the new ELF section type and dynamic array tags, as well | |
as the encoding used in the new section are all under discussion and are | |
subject to change. We plan to send the patch upstream after the gABI has | |
been updated to include the new definitions. | |
[Adrian: forward-ported to glibc 2.32] | |
[dobo: forward-ported to glibc 2.35] | |
--- | |
elf/do-rel.h | 41 +++++++++++++++++++++++++++++++++-- | |
elf/dynamic-link.h | 15 +++++++++++++ | |
elf/elf.h | 15 +++++++++++-- | |
elf/get-dynamic-info.h | 7 ++++++ | |
sysdeps/aarch64/dl-machine.h | 9 ++++++++ | |
sysdeps/arm/dl-machine-rel.h | 1 + | |
sysdeps/arm/dl-machine.h | 9 ++++++++ | |
sysdeps/i386/dl-machine-rel.h | 1 + | |
sysdeps/i386/dl-machine.h | 9 ++++++++ | |
sysdeps/x86_64/dl-machine.h | 9 ++++++++ | |
10 files changed, 112 insertions(+), 4 deletions(-) | |
diff --git a/elf/do-rel.h b/elf/do-rel.h | |
index 60d5dce8f2..c1477be9b0 100644 | |
--- a/elf/do-rel.h | |
+++ b/elf/do-rel.h | |
@@ -28,6 +28,12 @@ | |
# define elf_machine_rel_relative elf_machine_rela_relative | |
#endif | |
+#ifdef DO_RELR | |
+# define elf_dynamic_do_Rel elf_dynamic_do_Relr | |
+# define Rel Relr | |
+# define elf_machine_rel_relative elf_machine_relr_relative | |
+#endif | |
+ | |
#ifndef DO_ELF_MACHINE_REL_RELATIVE | |
# define DO_ELF_MACHINE_REL_RELATIVE(map, l_addr, relative) \ | |
elf_machine_rel_relative (l_addr, relative, \ | |
@@ -48,12 +54,12 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], | |
const ElfW(Rel) *r = (const void *) reladdr; | |
const ElfW(Rel) *end = (const void *) (reladdr + relsize); | |
ElfW(Addr) l_addr = map->l_addr; | |
-# if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP | |
+# if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP && !defined DO_RELR | |
const ElfW(Rel) *r2 = NULL; | |
const ElfW(Rel) *end2 = NULL; | |
# endif | |
-#if (!defined DO_RELA || !defined ELF_MACHINE_PLT_REL) && !defined RTLD_BOOTSTRAP | |
+#if (!defined DO_RELA || !defined ELF_MACHINE_PLT_REL) && !defined RTLD_BOOTSTRAP && !defined DO_RELR | |
/* We never bind lazily during ld.so bootstrap. Unfortunately gcc is | |
not clever enough to see through all the function calls to realize | |
that. */ | |
@@ -82,8 +88,10 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], | |
else | |
#endif | |
{ | |
+# if !defined DO_RELR | |
const ElfW(Sym) *const symtab = | |
(const void *) D_PTR (map, l_info[DT_SYMTAB]); | |
+# endif | |
const ElfW(Rel) *relative = r; | |
r += nrelative; | |
@@ -110,9 +118,36 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], | |
if (l_addr != 0 || ! map->l_info[VALIDX(DT_GNU_PRELINKED)]) | |
# endif | |
#endif | |
+ | |
+#ifdef DO_RELR | |
+ { | |
+ ElfW(Addr) base = 0; | |
+ for (; relative < end; ++relative) | |
+ { | |
+ ElfW(Relr) entry = *relative; | |
+ if ((entry&1) == 0) | |
+ { | |
+ elf_machine_relr_relative (l_addr, (void *) (l_addr + entry)); | |
+ base = entry + sizeof(ElfW(Addr)); | |
+ continue; | |
+ } | |
+ ElfW(Addr) offset = base; | |
+ while (entry != 0) | |
+ { | |
+ entry >>= 1; | |
+ if ((entry&1) != 0) | |
+ elf_machine_relr_relative (l_addr, (void *) (l_addr + offset)); | |
+ offset += sizeof(ElfW(Addr)); | |
+ } | |
+ base += (8*sizeof(ElfW(Addr)) - 1) * sizeof(ElfW(Addr)); | |
+ } | |
+ } | |
+#else | |
for (; relative < r; ++relative) | |
DO_ELF_MACHINE_REL_RELATIVE (map, l_addr, relative); | |
+#endif | |
+#if !defined DO_RELR | |
#ifdef RTLD_BOOTSTRAP | |
/* The dynamic linker always uses versioning. */ | |
assert (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL); | |
@@ -210,6 +245,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], | |
skip_ifunc); | |
# endif | |
} | |
+#endif | |
#endif | |
} | |
} | |
@@ -220,3 +256,4 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], | |
#undef elf_machine_rel_relative | |
#undef DO_ELF_MACHINE_REL_RELATIVE | |
#undef DO_RELA | |
+#undef DO_RELR | |
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h | |
index 25dd7ca4f2..6acacc851f 100644 | |
--- a/elf/dynamic-link.h | |
+++ b/elf/dynamic-link.h | |
@@ -50,6 +50,11 @@ static inline void __attribute__((always_inline)) | |
elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, | |
void *const reloc_addr); | |
# endif | |
+# if ! ELF_MACHINE_NO_RELR | |
+static inline void __attribute__((always_inline)) | |
+elf_machine_relr_relative (ElfW(Addr) l_addr, | |
+ void *const reloc_addr); | |
+# endif | |
# if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL | |
static inline void __attribute__((always_inline)) | |
elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], | |
@@ -146,6 +151,15 @@ 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 | |
+# if ! ELF_MACHINE_NO_RELR | |
+# define DO_RELR | |
+# include "do-rel.h" | |
+# define ELF_DYNAMIC_DO_RELR(map, scope, lazy, skip_ifunc) \ | |
+ _ELF_DYNAMIC_DO_RELOC (RELR, Relr, map, scope, lazy, skip_ifunc, 1) | |
+# else | |
+# define ELF_DYNAMIC_DO_RELR(map, scope, lazy, skip_ifunc) /* Nothing to do. */ | |
+# endif | |
+ | |
/* This can't just be an inline function because GCC is too dumb | |
to inline functions containing inlines themselves. */ | |
# define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc) \ | |
@@ -154,6 +168,7 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], | |
(consider_profile)); \ | |
ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, skip_ifunc); \ | |
ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, skip_ifunc); \ | |
+ ELF_DYNAMIC_DO_RELR ((map), (scope), edr_lazy, skip_ifunc); \ | |
} while (0) | |
#endif | |
diff --git a/elf/elf.h b/elf/elf.h | |
index 0735f6b579..d42ff0025c 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 /* Relative relocation, only offsets */ | |
+#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,12 @@ typedef struct | |
Elf64_Sxword r_addend; /* Addend */ | |
} Elf64_Rela; | |
+/* Relocation table entry for relative (in section of type SHT_RELR). */ | |
+ | |
+typedef Elf32_Word Elf32_Relr; /* offset/bitmap for relative relocations */ | |
+ | |
+typedef Elf64_Xword Elf64_Relr; /* offset/bitmap for relative relocations */ | |
+ | |
/* How to extract and insert information held in the r_info field. */ | |
#define ELF32_R_SYM(val) ((val) >> 8) | |
@@ -887,7 +894,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 | |
+#define DT_RELR 36 | |
+#define DT_RELRENT 37 | |
+#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 */ | |
@@ -939,6 +949,7 @@ typedef struct | |
GNU extension. */ | |
#define DT_VERSYM 0x6ffffff0 | |
+#define DT_RELRCOUNT 0x6ffffff8 | |
#define DT_RELACOUNT 0x6ffffff9 | |
#define DT_RELCOUNT 0x6ffffffa | |
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h | |
index 6c2ccd6db4..92552a8204 100644 | |
--- a/elf/get-dynamic-info.h | |
+++ b/elf/get-dynamic-info.h | |
@@ -89,6 +89,9 @@ elf_get_dynamic_info (struct link_map *l, bool bootstrap, | |
# if ! ELF_MACHINE_NO_REL | |
ADJUST_DYN_INFO (DT_REL); | |
# endif | |
+# if ! ELF_MACHINE_NO_RELR | |
+ ADJUST_DYN_INFO (DT_RELR); | |
+#endif | |
ADJUST_DYN_INFO (DT_JMPREL); | |
ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM)); | |
ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH)); | |
@@ -113,6 +116,10 @@ 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 ! ELF_MACHINE_NO_RELR | |
+ if (info[DT_RELR] != NULL) | |
+ assert (info[DT_RELRENT]->d_un.d_val == sizeof (ElfW(Relr))); | |
+# endif | |
if (bootstrap || static_pie_bootstrap) | |
{ | |
assert (info[DT_RUNPATH] == NULL); | |
diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h | |
index b40050a981..c11499b5f6 100644 | |
--- a/sysdeps/aarch64/dl-machine.h | |
+++ b/sysdeps/aarch64/dl-machine.h | |
@@ -378,6 +378,15 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, | |
*reloc_addr = l_addr + reloc->r_addend; | |
} | |
+static 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; | |
+} | |
+ | |
static inline void | |
__attribute__ ((always_inline)) | |
elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], | |
diff --git a/sysdeps/arm/dl-machine-rel.h b/sysdeps/arm/dl-machine-rel.h | |
index 999967931b..88fe8cae79 100644 | |
--- a/sysdeps/arm/dl-machine-rel.h | |
+++ b/sysdeps/arm/dl-machine-rel.h | |
@@ -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 | |
/* ARM never uses Elf32_Rela relocations for the dynamic linker. | |
Prelinked libraries may use Elf32_Rela though. */ | |
diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h | |
index 68dcb96d9d..a13ba25cbb 100644 | |
--- a/sysdeps/arm/dl-machine.h | |
+++ b/sysdeps/arm/dl-machine.h | |
@@ -608,6 +608,15 @@ elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc, | |
*reloc_addr += l_addr; | |
} | |
+static 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 | |
static inline void | |
__attribute__ ((always_inline)) | |
diff --git a/sysdeps/i386/dl-machine-rel.h b/sysdeps/i386/dl-machine-rel.h | |
index b98273aead..29f850773e 100644 | |
--- a/sysdeps/i386/dl-machine-rel.h | |
+++ b/sysdeps/i386/dl-machine-rel.h | |
@@ -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 | |
/* The i386 never uses Elf32_Rela relocations for the dynamic linker. | |
Prelinked libraries may use Elf32_Rela though. */ | |
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h | |
index 6182b45ed3..3fcd8a4c46 100644 | |
--- a/sysdeps/i386/dl-machine.h | |
+++ b/sysdeps/i386/dl-machine.h | |
@@ -626,6 +626,15 @@ elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc, | |
*reloc_addr += l_addr; | |
} | |
+static 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 | |
static inline void | |
__attribute__ ((always_inline)) | |
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h | |
index 155ca36bd5..ef9c81c075 100644 | |
--- a/sysdeps/x86_64/dl-machine.h | |
+++ b/sysdeps/x86_64/dl-machine.h | |
@@ -536,6 +536,15 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, | |
} | |
} | |
+static 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; | |
+} | |
+ | |
static inline void | |
__attribute ((always_inline)) | |
elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], | |
-- | |
2.34.1 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From fc5f14ff84b8e3381b3a732ae1ea9861d6911baf Mon Sep 17 00:00:00 2001 | |
From: Portisch <hugo.portisch@yahoo.de> | |
Date: Sat, 5 Jun 2021 19:41:25 +0200 | |
Subject: [PATCH 2/2] tls: libwidevinecdm.so: since 4.10.2252.0 has TLS with | |
64-byte alignment Change the max_align to 64U instead 16 to make it possible | |
to use dlopen again. Tests by changing TLS_TCB_ALIGN directly showed up some | |
random crashes. Reverence: https://lkml.org/lkml/2020/7/3/754 | |
--- | |
elf/dl-tls.c | 5 +++++ | |
1 file changed, 5 insertions(+) | |
diff --git a/elf/dl-tls.c b/elf/dl-tls.c | |
index 093cdddb7e..7314c2f9b2 100644 | |
--- a/elf/dl-tls.c | |
+++ b/elf/dl-tls.c | |
@@ -220,6 +220,11 @@ void | |
_dl_determine_tlsoffset (void) | |
{ | |
size_t max_align = TCB_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 | |
+ information is available, this is not taken into account below in | |
+ the audit case. */ | |
+ max_align = MAX (max_align, 64U); | |
size_t freetop = 0; | |
size_t freebottom = 0; | |
-- | |
2.34.1 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment