mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-04 07:31:11 +00:00
rtld: Support DT_RELR relative relocation format
(cherry picked from commit a7d137fcbc
)
This commit is contained in:
parent
5fb00264be
commit
c99fa2c634
|
@ -1255,6 +1255,18 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
|
|||
assert(dynp->d_un.d_val == sizeof(Elf_Rela));
|
||||
break;
|
||||
|
||||
case DT_RELR:
|
||||
obj->relr = (const Elf_Relr *)(obj->relocbase + dynp->d_un.d_ptr);
|
||||
break;
|
||||
|
||||
case DT_RELRSZ:
|
||||
obj->relrsize = dynp->d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_RELRENT:
|
||||
assert(dynp->d_un.d_val == sizeof(Elf_Relr));
|
||||
break;
|
||||
|
||||
case DT_PLTREL:
|
||||
plttype = dynp->d_un.d_val;
|
||||
assert(dynp->d_un.d_val == DT_REL || plttype == DT_RELA);
|
||||
|
@ -3148,6 +3160,29 @@ reloc_textrel_prot(Obj_Entry *obj, bool before)
|
|||
return (0);
|
||||
}
|
||||
|
||||
/* Process RELR relative relocations. */
|
||||
static void
|
||||
reloc_relr(Obj_Entry *obj)
|
||||
{
|
||||
const Elf_Relr *relr, *relrlim;
|
||||
Elf_Addr *where;
|
||||
|
||||
relrlim = (const Elf_Relr *)((const char *)obj->relr + obj->relrsize);
|
||||
for (relr = obj->relr; relr < relrlim; relr++) {
|
||||
Elf_Relr entry = *relr;
|
||||
|
||||
if ((entry & 1) == 0) {
|
||||
where = (Elf_Addr *)(obj->relocbase + entry);
|
||||
*where++ += (Elf_Addr)obj->relocbase;
|
||||
} else {
|
||||
for (long i = 0; (entry >>= 1) != 0; i++)
|
||||
if ((entry & 1) != 0)
|
||||
where[i] += (Elf_Addr)obj->relocbase;
|
||||
where += CHAR_BIT * sizeof(Elf_Relr) - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Relocate single object.
|
||||
* Returns 0 on success, or -1 on failure.
|
||||
|
@ -3174,6 +3209,7 @@ relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj,
|
|||
/* Process the non-PLT non-IFUNC relocations. */
|
||||
if (reloc_non_plt(obj, rtldobj, flags, lockstate))
|
||||
return (-1);
|
||||
reloc_relr(obj);
|
||||
|
||||
/* Re-protected the text segment. */
|
||||
if (obj->textrel && reloc_textrel_prot(obj, false) != 0)
|
||||
|
|
|
@ -174,6 +174,8 @@ typedef struct Struct_Obj_Entry {
|
|||
unsigned long relsize; /* Size in bytes of relocation info */
|
||||
const Elf_Rela *rela; /* Relocation entries with addend */
|
||||
unsigned long relasize; /* Size in bytes of addend relocation info */
|
||||
const Elf_Relr *relr; /* RELR relocation entries */
|
||||
unsigned long relrsize; /* Size in bytes of RELR relocations */
|
||||
const Elf_Rel *pltrel; /* PLT relocation entries */
|
||||
unsigned long pltrelsize; /* Size in bytes of PLT relocation info */
|
||||
const Elf_Rela *pltrela; /* PLT relocation entries with addend */
|
||||
|
|
Loading…
Reference in a new issue