ldso: support DT_RELR relative relocation format

this resolves DT_RELR relocations in non-ldso, dynamic-linked objects.
This commit is contained in:
Fangrui Song 2022-08-02 17:24:47 -04:00 committed by Rich Felker
parent 2404d9d643
commit d32dadd60e
3 changed files with 27 additions and 4 deletions

View File

@ -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

View File

@ -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),

View File

@ -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 *);