123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- From d32dadd60efb9d3b255351a3b532f8e4c3dd0db1 Mon Sep 17 00:00:00 2001
- From: Fangrui Song <i@maskray.me>
- Date: Tue, 2 Aug 2022 17:24:47 -0400
- Subject: ldso: support DT_RELR relative relocation format
- this resolves DT_RELR relocations in non-ldso, dynamic-linked objects.
- ---
- include/elf.h | 8 ++++++--
- ldso/dynlink.c | 21 ++++++++++++++++++++-
- src/internal/dynlink.h | 2 +-
- 3 files changed, 27 insertions(+), 4 deletions(-)
- diff --git a/include/elf.h b/include/elf.h
- index 86e2f0bb..9e980a29 100644
- --- a/include/elf.h
- +++ b/include/elf.h
- @@ -385,7 +385,8 @@ typedef struct {
- #define SHT_PREINIT_ARRAY 16
- #define SHT_GROUP 17
- #define SHT_SYMTAB_SHNDX 18
- -#define SHT_NUM 19
- +#define SHT_RELR 19
- +#define SHT_NUM 20
- #define SHT_LOOS 0x60000000
- #define SHT_GNU_ATTRIBUTES 0x6ffffff5
- #define SHT_GNU_HASH 0x6ffffff6
- @@ -754,7 +755,10 @@ typedef struct {
- #define DT_PREINIT_ARRAY 32
- #define DT_PREINIT_ARRAYSZ 33
- #define DT_SYMTAB_SHNDX 34
- -#define DT_NUM 35
- +#define DT_RELRSZ 35
- +#define DT_RELR 36
- +#define DT_RELRENT 37
- +#define DT_NUM 38
- #define DT_LOOS 0x6000000d
- #define DT_HIOS 0x6ffff000
- #define DT_LOPROC 0x70000000
- diff --git a/ldso/dynlink.c b/ldso/dynlink.c
- index cc677952..e92f03cb 100644
- --- a/ldso/dynlink.c
- +++ b/ldso/dynlink.c
- @@ -210,7 +210,8 @@ static void decode_vec(size_t *v, size_t *a, size_t cnt)
- size_t i;
- for (i=0; i<cnt; i++) a[i] = 0;
- for (; v[0]; v+=2) if (v[0]-1<cnt-1) {
- - a[0] |= 1UL<<v[0];
- + if (v[0] < 8*sizeof(long))
- + a[0] |= 1UL<<v[0];
- a[v[0]] = v[1];
- }
- }
- @@ -515,6 +516,23 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
- }
- }
-
- +static void do_relr_relocs(struct dso *dso, size_t *relr, size_t relr_size)
- +{
- + unsigned char *base = dso->base;
- + size_t *reloc_addr;
- + for (; relr_size; relr++, relr_size-=sizeof(size_t))
- + if ((relr[0]&1) == 0) {
- + reloc_addr = laddr(dso, relr[0]);
- + *reloc_addr++ += (size_t)base;
- + } else {
- + int i = 0;
- + for (size_t bitmap=relr[0]; (bitmap>>=1); i++)
- + if (bitmap&1)
- + reloc_addr[i] += (size_t)base;
- + reloc_addr += 8*sizeof(size_t)-1;
- + }
- +}
- +
- static void redo_lazy_relocs()
- {
- struct dso *p = lazy_head, *next;
- @@ -1357,6 +1375,7 @@ static void reloc_all(struct dso *p)
- 2+(dyn[DT_PLTREL]==DT_RELA));
- do_relocs(p, laddr(p, dyn[DT_REL]), dyn[DT_RELSZ], 2);
- do_relocs(p, laddr(p, dyn[DT_RELA]), dyn[DT_RELASZ], 3);
- + do_relr_relocs(p, laddr(p, dyn[DT_RELR]), dyn[DT_RELRSZ]);
-
- if (head != &ldso && p->relro_start != p->relro_end) {
- long ret = __syscall(SYS_mprotect, laddr(p, p->relro_start),
- diff --git a/src/internal/dynlink.h b/src/internal/dynlink.h
- index 51c0639f..830354eb 100644
- --- a/src/internal/dynlink.h
- +++ b/src/internal/dynlink.h
- @@ -93,7 +93,7 @@ struct fdpic_dummy_loadmap {
- #endif
-
- #define AUX_CNT 32
- -#define DYN_CNT 32
- +#define DYN_CNT 37
-
- typedef void (*stage2_func)(unsigned char *, size_t *);
-
- --
- cgit v1.2.1
|