public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
* [glibc/arm/morello/main] aarch64: morello: fix relative relocs
@ 2022-10-12 14:17 Szabolcs Nagy
  0 siblings, 0 replies; only message in thread
From: Szabolcs Nagy @ 2022-10-12 14:17 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=e6a2c4c4bbb922fd326e5085cd1f28d5265ade6d

commit e6a2c4c4bbb922fd326e5085cd1f28d5265ade6d
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date:   Wed Aug 31 16:37:40 2022 +0100

    aarch64: morello: fix relative relocs
    
    use the reloc processing code from cheri-rel.h which already
    supports separate RX and RW capabilities per module.

Diff:
---
 elf/dynamic-link.h                   |  7 +++++-
 sysdeps/aarch64/ldsodefs.h           |  5 ++++
 sysdeps/aarch64/morello/dl-irel.h    | 44 +++++-------------------------------
 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 6102990581..86105714bb 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 ab42b05f6c..b0b23df93c 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 0ff4d40622..e12d29a089 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 ff5169d779..4eaffc2cf6 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;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-10-12 14:17 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-12 14:17 [glibc/arm/morello/main] aarch64: morello: fix relative relocs Szabolcs Nagy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).