public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
* [glibc/maskray/grte-relr] elf: Support DT_RELR relative relocation format
@ 2022-01-12 0:15 Fangrui Song
0 siblings, 0 replies; 3+ messages in thread
From: Fangrui Song @ 2022-01-12 0:15 UTC (permalink / raw)
To: glibc-cvs
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=630e6230397579934a738fd3689ca3c9b458cbda
commit 630e6230397579934a738fd3689ca3c9b458cbda
Author: Fangrui Song <maskray@google.com>
Date: Tue Jan 11 16:10:02 2022 -0800
elf: Support DT_RELR relative relocation format
Upstream patch: https://sourceware.org/pipermail/libc-alpha/2021-October/132029.html
Bikeshedding: https://sourceware.org/pipermail/libc-alpha/2021-November/133009.html
This commit removes configure.ac and test changes to avoid conflict when
the upstream finally gets the feature.
To work around b/208156916, DT_NUM is not bumped. DT_RELR and DT_RELRSZ
take the l_info slots at DT_VERSYM+1 and DT_VERSYM+2.
Diff:
---
elf/Makefile | 7 +++++++
elf/dynamic-link.h | 30 ++++++++++++++++++++++++++++++
elf/elf.h | 15 +++++++++++++--
elf/get-dynamic-info.h | 8 +++++++-
elf/tst-relr-no-pie.c | 1 +
elf/tst-relr.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 103 insertions(+), 3 deletions(-)
diff --git a/elf/Makefile b/elf/Makefile
index 1b9acb5242..167db51039 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -209,6 +209,13 @@ tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog
endif
endif
endif
+ifeq ($(have-relr),)
+tests += tst-relr tst-relr-no-pie
+tests-pie += tst-relr
+tests-no-pie += tst-relr-no-pie
+LDFLAGS-tst-relr += -Wl,--pack-dyn-relocs=relr
+LDFLAGS-tst-relr-no-pie += -Wl,--pack-dyn-relocs=relr -no-pie
+endif
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)tst-leaks1-mem.out \
$(objpfx)tst-leaks1-static-mem.out $(objpfx)noload-mem.out \
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index f576d787e3..18d94faea3 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -253,6 +253,35 @@ elf_machine_lazy_rel (struct link_map *map,
# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc, boot_map) /* Nothing to do. */
# endif
+/* Google-local: b/208156916. To not bump DT_NUM, use DT_VERSYM+1 for DT_RELR
+ * and DT_VERSYM+2 for DT_RELRSZ. */
+# 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[VERSYMIDX (DT_VERSYM + 1)]) \
+ break; \
+ r = (const ElfW(Relr) *)D_PTR((map), l_info[VERSYMIDX (DT_VERSYM + 1)]); \
+ end = (const ElfW(Relr) *)((const char *)r + \
+ (map)->l_info[VERSYMIDX (DT_VERSYM + 2)]->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. */
# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile, skip_ifunc, boot_map) \
@@ -261,6 +290,7 @@ elf_machine_lazy_rel (struct link_map *map,
(consider_profile)); \
ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc, boot_map); \
ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc, boot_map); \
+ ELF_DYNAMIC_DO_RELR ((map)); \
} while (0)
#else /* NESTING */
# if ! ELF_MACHINE_NO_REL
diff --git a/elf/elf.h b/elf/elf.h
index 954f3266f7..35ff17cae2 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -444,8 +444,9 @@ typedef struct
#define SHT_FINI_ARRAY 15 /* Array of destructors */
#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
#define SHT_GROUP 17 /* Section group */
-#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
-#define SHT_NUM 19 /* Number of defined types. */
+#define SHT_SYMTAB_SHNDX 18 /* Extended section indices */
+#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. */
@@ -663,6 +664,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)
@@ -861,6 +867,11 @@ typedef struct
#define DT_ENCODING 32 /* Start of encoded range */
#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_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 */
+/* Google-local: b/208156916. Don't bump DT_NUM. */
#define DT_NUM 34 /* Number used */
#define DT_LOOS 0x6000000d /* Start of OS-specific */
#define DT_HIOS 0x6ffff000 /* End of OS-specific */
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
index f9c5b84d6a..40c40975e4 100644
--- a/elf/get-dynamic-info.h
+++ b/elf/get-dynamic-info.h
@@ -49,7 +49,12 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
while (dyn->d_tag != DT_NULL)
{
- if ((d_tag_utype) dyn->d_tag < DT_NUM)
+ /* Google-local: b/208156916. See ELF_DYNAMIC_DO_RELR. */
+ if (dyn->d_tag == DT_RELR)
+ info[VERSYMIDX (DT_VERSYM + 1)] = dyn;
+ else if (dyn->d_tag == DT_RELRSZ)
+ info[VERSYMIDX (DT_VERSYM + 2)] = dyn;
+ else if ((d_tag_utype) dyn->d_tag < DT_NUM)
info[dyn->d_tag] = dyn;
else if (dyn->d_tag >= DT_LOPROC &&
dyn->d_tag < DT_LOPROC + DT_THISPROCNUM)
@@ -112,6 +117,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
# endif
ADJUST_DYN_INFO (DT_JMPREL);
ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
+ ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM + 1)); /* DT_RELR */
ADJUST_DYN_INFO (DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
+ DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM);
# undef ADJUST_DYN_INFO
diff --git a/elf/tst-relr-no-pie.c b/elf/tst-relr-no-pie.c
new file mode 100644
index 0000000000..7df0cdbfd6
--- /dev/null
+++ b/elf/tst-relr-no-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..22eb8c75a0
--- /dev/null
+++ b/elf/tst-relr.c
@@ -0,0 +1,45 @@
+#include <link.h>
+#include <stdbool.h>
+#include <stdio.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 (!has_relr)
+ {
+ fprintf (stderr, "no DT_RELR\n");
+ return 0;
+ }
+ }
+
+ for (int i = 0; i < sizeof (arr) / sizeof (arr[0]); i++)
+ if (!((arr[i] == 0 && val[i] == 0) ||
+ (arr[i] == &o && val[i] == 1) ||
+ (arr[i] == &x && val[i] == 2)))
+ return 1;
+ return 0;
+}
+
+#include <support/test-driver.c>
^ permalink raw reply [flat|nested] 3+ messages in thread
* [glibc/maskray/grte-relr] elf: Support DT_RELR relative relocation format
@ 2022-01-12 0:19 Fangrui Song
0 siblings, 0 replies; 3+ messages in thread
From: Fangrui Song @ 2022-01-12 0:19 UTC (permalink / raw)
To: glibc-cvs
The branch 'maskray/grte-relr' was updated to point to:
e87abbe055... elf: Support DT_RELR relative relocation format
It previously pointed to:
630e623039... elf: Support DT_RELR relative relocation format
Diff:
!!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST):
-------------------------------------------------------------------
630e623... elf: Support DT_RELR relative relocation format
Summary of changes (added commits):
-----------------------------------
e87abbe... elf: Support DT_RELR relative relocation format
^ permalink raw reply [flat|nested] 3+ messages in thread
* [glibc/maskray/grte-relr] elf: Support DT_RELR relative relocation format
@ 2022-01-12 0:20 Fangrui Song
0 siblings, 0 replies; 3+ messages in thread
From: Fangrui Song @ 2022-01-12 0:20 UTC (permalink / raw)
To: glibc-cvs
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=e87abbe055b853e649a57eaf9bd2941fd86ba385
commit e87abbe055b853e649a57eaf9bd2941fd86ba385
Author: Fangrui Song <maskray@google.com>
Date: Tue Jan 11 16:19:33 2022 -0800
elf: Support DT_RELR relative relocation format
Upstream patch: https://sourceware.org/pipermail/libc-alpha/2021-October/132029.html
Bikeshedding: https://sourceware.org/pipermail/libc-alpha/2021-November/133009.html
This commit removes configure.ac and test changes to avoid conflict when
the upstream finally gets the feature. $(have-relr) is kept for local
testing.
To work around b/208156916, DT_NUM is not bumped. DT_RELR and DT_RELRSZ
take the l_info slots at DT_VERSYM+1 and DT_VERSYM+2.
Diff:
---
elf/Makefile | 7 +++++++
elf/dynamic-link.h | 30 ++++++++++++++++++++++++++++++
elf/elf.h | 15 +++++++++++++--
elf/get-dynamic-info.h | 8 +++++++-
elf/tst-relr-no-pie.c | 1 +
elf/tst-relr.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 103 insertions(+), 3 deletions(-)
diff --git a/elf/Makefile b/elf/Makefile
index 1b9acb5242..6d023d75a0 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -209,6 +209,13 @@ tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog
endif
endif
endif
+ifeq ($(have-relr),yes)
+tests += tst-relr tst-relr-no-pie
+tests-pie += tst-relr
+tests-no-pie += tst-relr-no-pie
+LDFLAGS-tst-relr += -Wl,--pack-dyn-relocs=relr
+LDFLAGS-tst-relr-no-pie += -Wl,--pack-dyn-relocs=relr -no-pie
+endif
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)tst-leaks1-mem.out \
$(objpfx)tst-leaks1-static-mem.out $(objpfx)noload-mem.out \
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index f576d787e3..18d94faea3 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -253,6 +253,35 @@ elf_machine_lazy_rel (struct link_map *map,
# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc, boot_map) /* Nothing to do. */
# endif
+/* Google-local: b/208156916. To not bump DT_NUM, use DT_VERSYM+1 for DT_RELR
+ * and DT_VERSYM+2 for DT_RELRSZ. */
+# 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[VERSYMIDX (DT_VERSYM + 1)]) \
+ break; \
+ r = (const ElfW(Relr) *)D_PTR((map), l_info[VERSYMIDX (DT_VERSYM + 1)]); \
+ end = (const ElfW(Relr) *)((const char *)r + \
+ (map)->l_info[VERSYMIDX (DT_VERSYM + 2)]->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. */
# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile, skip_ifunc, boot_map) \
@@ -261,6 +290,7 @@ elf_machine_lazy_rel (struct link_map *map,
(consider_profile)); \
ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc, boot_map); \
ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc, boot_map); \
+ ELF_DYNAMIC_DO_RELR ((map)); \
} while (0)
#else /* NESTING */
# if ! ELF_MACHINE_NO_REL
diff --git a/elf/elf.h b/elf/elf.h
index 954f3266f7..35ff17cae2 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -444,8 +444,9 @@ typedef struct
#define SHT_FINI_ARRAY 15 /* Array of destructors */
#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
#define SHT_GROUP 17 /* Section group */
-#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
-#define SHT_NUM 19 /* Number of defined types. */
+#define SHT_SYMTAB_SHNDX 18 /* Extended section indices */
+#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. */
@@ -663,6 +664,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)
@@ -861,6 +867,11 @@ typedef struct
#define DT_ENCODING 32 /* Start of encoded range */
#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_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 */
+/* Google-local: b/208156916. Don't bump DT_NUM. */
#define DT_NUM 34 /* Number used */
#define DT_LOOS 0x6000000d /* Start of OS-specific */
#define DT_HIOS 0x6ffff000 /* End of OS-specific */
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
index f9c5b84d6a..3710d41841 100644
--- a/elf/get-dynamic-info.h
+++ b/elf/get-dynamic-info.h
@@ -49,7 +49,12 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
while (dyn->d_tag != DT_NULL)
{
- if ((d_tag_utype) dyn->d_tag < DT_NUM)
+ /* Google-local: b/208156916. See ELF_DYNAMIC_DO_RELR. */
+ if (dyn->d_tag == DT_RELR)
+ info[VERSYMIDX (DT_VERSYM + 1)] = dyn;
+ else if (dyn->d_tag == DT_RELRSZ)
+ info[VERSYMIDX (DT_VERSYM + 2)] = dyn;
+ else if ((d_tag_utype) dyn->d_tag < DT_NUM)
info[dyn->d_tag] = dyn;
else if (dyn->d_tag >= DT_LOPROC &&
dyn->d_tag < DT_LOPROC + DT_THISPROCNUM)
@@ -112,6 +117,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
# endif
ADJUST_DYN_INFO (DT_JMPREL);
ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
+ ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM + 1)); /* DT_RELR */
ADJUST_DYN_INFO (DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
+ DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM);
# undef ADJUST_DYN_INFO
diff --git a/elf/tst-relr-no-pie.c b/elf/tst-relr-no-pie.c
new file mode 100644
index 0000000000..7df0cdbfd6
--- /dev/null
+++ b/elf/tst-relr-no-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..22eb8c75a0
--- /dev/null
+++ b/elf/tst-relr.c
@@ -0,0 +1,45 @@
+#include <link.h>
+#include <stdbool.h>
+#include <stdio.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 (!has_relr)
+ {
+ fprintf (stderr, "no DT_RELR\n");
+ return 0;
+ }
+ }
+
+ for (int i = 0; i < sizeof (arr) / sizeof (arr[0]); i++)
+ if (!((arr[i] == 0 && val[i] == 0) ||
+ (arr[i] == &o && val[i] == 1) ||
+ (arr[i] == &x && val[i] == 2)))
+ return 1;
+ return 0;
+}
+
+#include <support/test-driver.c>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-01-12 0:20 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-12 0:15 [glibc/maskray/grte-relr] elf: Support DT_RELR relative relocation format Fangrui Song
2022-01-12 0:19 Fangrui Song
2022-01-12 0:20 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).