From 4d7fbad54fac675dbf9c9a48e7c872cdd9984895 Mon Sep 17 00:00:00 2001 From: Jessica Clarke Date: Tue, 9 Apr 2024 22:09:30 +0100 Subject: [PATCH] rtld-elf: Support upcoming new ABI for R_MORELLO_JUMP_SLOT This will resolve a long-standing quirk, making R_MORELLO_JUMP_SLOT look like a normal R_MORELLO_RELATIVE relocation rather than being unchanged from R_AARCH64_JUMP_SLOT in the ELF object. --- libexec/rtld-elf/aarch64/reloc.c | 37 ++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/libexec/rtld-elf/aarch64/reloc.c b/libexec/rtld-elf/aarch64/reloc.c index 64b67930275d..02679421e996 100644 --- a/libexec/rtld-elf/aarch64/reloc.c +++ b/libexec/rtld-elf/aarch64/reloc.c @@ -349,20 +349,39 @@ reloc_plt(Obj_Entry *obj, int flags, RtldLockState *lockstate) FUNC_PTR_REMOVE_PERMS); #endif for (rela = obj->pltrela; rela < relalim; rela++) { - Elf_Addr *where; + uintptr_t *where; +#ifdef __CHERI_PURE_CAPABILITY__ + Elf_Addr *fragment; +#endif - where = (Elf_Addr *)(obj->relocbase + rela->r_offset); + where = (uintptr_t *)(obj->relocbase + rela->r_offset); +#ifdef __CHERI_PURE_CAPABILITY__ + fragment = (Elf_Addr *)where; +#endif switch(ELF_R_TYPE(rela->r_info)) { #ifdef __CHERI_PURE_CAPABILITY__ case R_MORELLO_JUMP_SLOT: /* - * XXX: This would be far more natural if the linker - * made it an R_MORELLO_RELATIVE-like fragment instead. - * https://git.morello-project.org/morello/llvm-project/-/issues/19 + * Old ABI: + * - Treat as R_AARCH64_JUMP_SLOT + * + * New ABI: + * - Same representation as R_MORELLO_RELATIVE + * + * Determine which this is based on whether there's + * non-zero metadata next to the address. Remove once + * the new ABI is old enough that we can assume it is + * in use. */ - *(uintptr_t *)where = cheri_sealentry(jump_slot_base + - *where); + if (fragment[1] == 0) + *where = cheri_sealentry(jump_slot_base + + fragment[0]); + else + *where = init_cap_from_fragment(fragment, + obj->relocbase, obj->text_rodata_cap, + (Elf_Addr)(uintptr_t)obj->relocbase, + rela->r_addend); break; #else case R_AARCH64_JUMP_SLOT: @@ -374,8 +393,8 @@ reloc_plt(Obj_Entry *obj, int flags, RtldLockState *lockstate) #else case R_AARCH64_TLSDESC: #endif - reloc_tlsdesc(obj, rela, where, SYMLOOK_IN_PLT | flags, - lockstate); + reloc_tlsdesc(obj, rela, (Elf_Addr *)where, + SYMLOOK_IN_PLT | flags, lockstate); break; #ifdef __CHERI_PURE_CAPABILITY__ case R_MORELLO_IRELATIVE: