diff options
author | Szabolcs Nagy <szabolcs.nagy@arm.com> | 2022-08-31 16:37:40 +0100 |
---|---|---|
committer | Szabolcs Nagy <szabolcs.nagy@arm.com> | 2022-10-12 14:22:03 +0100 |
commit | e6a2c4c4bbb922fd326e5085cd1f28d5265ade6d (patch) | |
tree | 5decfee722d442decef771901318aba8c6c40daf | |
parent | 87dffcda136a7d1b0c0f81ccf9ac084178181321 (diff) | |
download | glibc-e6a2c4c4bbb922fd326e5085cd1f28d5265ade6d.zip glibc-e6a2c4c4bbb922fd326e5085cd1f28d5265ade6d.tar.gz glibc-e6a2c4c4bbb922fd326e5085cd1f28d5265ade6d.tar.bz2 |
aarch64: morello: fix relative relocs
use the reloc processing code from cheri-rel.h which already
supports separate RX and RW capabilities per module.
-rw-r--r-- | elf/dynamic-link.h | 7 | ||||
-rw-r--r-- | sysdeps/aarch64/ldsodefs.h | 5 | ||||
-rw-r--r-- | sysdeps/aarch64/morello/dl-irel.h | 44 | ||||
-rw-r--r-- | sysdeps/aarch64/morello/dl-machine.h | 26 |
4 files changed, 34 insertions, 48 deletions
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index 6102990..8610571 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -46,9 +46,14 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], const ElfW(Rela) *reloc, const ElfW(Sym) *sym, const struct r_found_version *version, void *const reloc_addr, int skip_ifunc); +# ifdef __CHERI_PURE_CAPABILITY__ static inline void __attribute__((always_inline)) -elf_machine_rela_relative (elfptr_t l_addr, const ElfW(Rela) *reloc, +elf_machine_rela_relative (struct link_map *map, const ElfW(Rela) *reloc); +# else +static inline void __attribute__((always_inline)) +elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, void *const reloc_addr); +# endif # endif # if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL static inline void __attribute__((always_inline)) diff --git a/sysdeps/aarch64/ldsodefs.h b/sysdeps/aarch64/ldsodefs.h index ab42b05..b0b23df 100644 --- a/sysdeps/aarch64/ldsodefs.h +++ b/sysdeps/aarch64/ldsodefs.h @@ -22,6 +22,11 @@ #include <elf.h> #include <cpu-features.h> +#ifdef __CHERI_PURE_CAPABILITY__ +# define DO_ELF_MACHINE_REL_RELATIVE(map, l_addr, relative) \ + elf_machine_rela_relative (map, relative) +#endif + struct La_aarch64_regs; struct La_aarch64_retval; diff --git a/sysdeps/aarch64/morello/dl-irel.h b/sysdeps/aarch64/morello/dl-irel.h index 0ff4d40..e12d29a 100644 --- a/sysdeps/aarch64/morello/dl-irel.h +++ b/sysdeps/aarch64/morello/dl-irel.h @@ -41,42 +41,7 @@ elf_ifunc_invoke (uintptr_t addr) (GLRO(dl_hwcap) | _IFUNC_ARG_HWCAP, &arg); } -#include <cheri_perms.h> - -static inline uintptr_t -__attribute__ ((always_inline)) -morello_relative_value (uintptr_t l_addr, - const ElfW(Rela) *reloc, - void *reloc_addr) -{ - uint64_t *__attribute__((may_alias)) u64_reloc_addr = reloc_addr; - - /* Fragment identified by r_offset has the following information: - | 64-bit: address | 56-bits: length | 8-bits: permissions | */ - unsigned long loc = u64_reloc_addr[0]; - unsigned long len = u64_reloc_addr[1] & ((1UL << 56) - 1); - unsigned long perm = u64_reloc_addr[1] >> 56; - unsigned long perm_mask = 0; - uintptr_t value = __builtin_cheri_bounds_set_exact (l_addr + loc, len); - - value = value + reloc->r_addend; - - /* Set permissions. Permissions field encoded as: - 4 = executable, 2 = read/write, 1 = read-only. - Mask should follow the same encoding as the ELF segment permissions. */ - if (perm == 1) - perm_mask = CAP_PERM_MASK_R; - if (perm == 2) - perm_mask = CAP_PERM_MASK_RW; - if (perm == 4) - perm_mask = CAP_PERM_MASK_RX; - value = __builtin_cheri_perms_and (value, perm_mask); - - /* Seal capabilities, which provide execute permission, with MORELLO_RB. */ - if (perm == 4) - value = __builtin_cheri_seal_entry (value); - return value; -} +#include <cheri-rel.h> static inline void __attribute ((always_inline)) @@ -87,10 +52,13 @@ elf_irela (const ElfW(Rela) *reloc) if (__glibc_likely (r_type == MORELLO_R(IRELATIVE))) { struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; - void *reloc_addr = (void *) main_map->l_addr + reloc->r_offset; + void *reloc_addr = (void *) dl_rw_ptr (main_map, reloc->r_offset); uintptr_t *__attribute__((may_alias)) cap_reloc_addr = reloc_addr; + uint64_t base = main_map->l_addr; + uintptr_t cap_rx = main_map->l_map_start; + uintptr_t cap_rw = main_map->l_rw_start; uintptr_t value - = morello_relative_value (main_map->l_addr, reloc, reloc_addr); + = morello_relative (base, cap_rx, cap_rw, reloc, reloc_addr); *cap_reloc_addr = elf_ifunc_invoke (value); } else diff --git a/sysdeps/aarch64/morello/dl-machine.h b/sysdeps/aarch64/morello/dl-machine.h index ff5169d..4eaffc2 100644 --- a/sysdeps/aarch64/morello/dl-machine.h +++ b/sysdeps/aarch64/morello/dl-machine.h @@ -282,7 +282,8 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info); if (r_type == MORELLO_R(RELATIVE)) - *cap_reloc_addr = morello_relative_value (map->l_addr, reloc, reloc_addr); + *cap_reloc_addr = morello_relative (map->l_addr, map->l_map_start, + map->l_rw_start, reloc, reloc_addr); else if (r_type == AARCH64_R(RELATIVE)) *u64_reloc_addr = map->l_addr + reloc->r_addend; else if (__builtin_expect (r_type == R_AARCH64_NONE, 0)) @@ -347,8 +348,11 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], case MORELLO_R(IRELATIVE): { - uintptr_t value - = morello_relative_value (map->l_addr, reloc, reloc_addr); + uintptr_t value = morello_relative (map->l_addr, + map->l_map_start, + map->l_rw_start, + reloc, + reloc_addr); if (__glibc_likely (!skip_ifunc)) value = elf_ifunc_invoke (value); *cap_reloc_addr = value; @@ -410,15 +414,19 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], static inline void __attribute__ ((always_inline)) -elf_machine_rela_relative (uintptr_t l_addr, - const ElfW(Rela) *reloc, - void *const reloc_addr) +elf_machine_rela_relative (struct link_map *map, const ElfW(Rela) *reloc) { + ElfW(Addr) l_addr = map->l_addr; + uintptr_t cap_rx = map->l_map_start; + uintptr_t cap_rw = map->l_rw_start; + void *const reloc_addr + = (void *) __builtin_cheri_address_set (cap_rw, l_addr + reloc->r_offset); uint64_t *__attribute__((may_alias)) u64_reloc_addr = reloc_addr; uintptr_t *__attribute__((may_alias)) cap_reloc_addr = reloc_addr; const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info); if (r_type == MORELLO_R(RELATIVE)) - *cap_reloc_addr = morello_relative_value (l_addr, reloc, reloc_addr); + *cap_reloc_addr = morello_relative (l_addr, cap_rx, cap_rw, + reloc, reloc_addr); else *u64_reloc_addr = l_addr + reloc->r_addend; } @@ -485,8 +493,8 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], } else if (__glibc_unlikely (r_type == MORELLO_R(IRELATIVE))) { - uintptr_t value - = morello_relative_value (map->l_addr, reloc, reloc_addr); + uintptr_t value = morello_relative (map->l_addr, map->l_map_start, + map->l_rw_start, reloc, reloc_addr); if (__glibc_likely (!skip_ifunc)) value = elf_ifunc_invoke (value); *cap_reloc_addr = value; |