about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSzabolcs Nagy <szabolcs.nagy@arm.com>2022-04-07 17:04:59 +0100
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2022-10-27 14:46:53 +0100
commiteca0182a2b8f3603434f1385fadbb56cbfc90aab (patch)
tree7de4cf9f89c97ea823cc901d7f615a9f2b481ed9
parent28bd4285ad0f8ce6026583e9cc0a612018d461ba (diff)
downloadglibc-eca0182a2b8f3603434f1385fadbb56cbfc90aab.tar.gz
glibc-eca0182a2b8f3603434f1385fadbb56cbfc90aab.tar.xz
glibc-eca0182a2b8f3603434f1385fadbb56cbfc90aab.zip
cheri: elf: use RX, RW capabilities to derive pointers
Instead of

  map->l_addr + offset

use

  dl_rx_ptr (map, offset)
  dl_rw_ptr (map, offset)

depending on RX or RW permission requirement.
-rw-r--r--elf/dl-find_object.h2
-rw-r--r--elf/dl-load.c9
-rw-r--r--elf/dl-runtime.c2
-rw-r--r--elf/dl-version.c10
-rw-r--r--elf/do-rel.h10
-rw-r--r--elf/rtld.c11
-rw-r--r--sysdeps/generic/ldsodefs.h3
7 files changed, 24 insertions, 23 deletions
diff --git a/elf/dl-find_object.h b/elf/dl-find_object.h
index 3b49877e0e..a4df9a7d67 100644
--- a/elf/dl-find_object.h
+++ b/elf/dl-find_object.h
@@ -105,7 +105,7 @@ _dl_find_object_from_map (struct link_map *l,
     if (ph->p_type == DLFO_EH_SEGMENT_TYPE)
       {
         atomic_store_relaxed (&result->eh_frame,
-                              (void *) (ph->p_vaddr + l->l_addr));
+                              (void *) dl_rx_ptr (l, ph->p_vaddr));
 #if DLFO_STRUCT_HAS_EH_COUNT
         atomic_store_relaxed (&result->eh_count, ph->p_memsz / 8);
 #endif
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 1ad0868dad..7d74214626 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -866,7 +866,7 @@ _dl_init_paths (const char *llp, const char *source,
 void
 _dl_process_pt_gnu_property (struct link_map *l, int fd, const ElfW(Phdr) *ph)
 {
-  const ElfW(Nhdr) *note = (const void *) (ph->p_vaddr + l->l_addr);
+  const ElfW(Nhdr) *note = (const void *) dl_rx_ptr (l, ph->p_vaddr);
   const ElfW(Addr) size = ph->p_memsz;
   const ElfW(Addr) align = ph->p_align;
 
@@ -1314,7 +1314,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
     }
   else
     /* Adjust the PT_PHDR value by the runtime load address.  */
-    l->l_phdr = (ElfW(Phdr) *) ((ElfW(Addr)) l->l_phdr + l->l_addr);
+    l->l_phdr = (ElfW(Phdr) *) dl_rx_ptr (l, (ElfW(Addr)) l->l_phdr);
 
   if (__glibc_unlikely ((stack_flags &~ GL(dl_stack_flags)) & PF_X))
     {
@@ -1369,7 +1369,8 @@ cannot enable executable stack as shared object requires");
 
   /* Adjust the address of the TLS initialization image.  */
   if (l->l_tls_initimage != NULL)
-    l->l_tls_initimage = (char *) l->l_tls_initimage + l->l_addr;
+    l->l_tls_initimage
+      = (void *) dl_rw_ptr (l, (ElfW(Addr)) l->l_tls_initimage);
 
   /* Process program headers again after load segments are mapped in
      case processing requires accessing those segments.  Scan program
@@ -1402,7 +1403,7 @@ cannot enable executable stack as shared object requires");
   /* If this is ET_EXEC, we should have loaded it as lt_executable.  */
   assert (type != ET_EXEC || l->l_type == lt_executable);
 
-  l->l_entry += l->l_addr;
+  l->l_entry = dl_rx_ptr (l, l->l_entry);
 
   if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
     _dl_debug_printf ("\
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index e7c99cbc82..5f6aef3e62 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -55,7 +55,7 @@ _dl_fixup (
 		      + reloc_offset (pltgot, reloc_arg));
   const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
   const ElfW(Sym) *refsym = sym;
-  void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
+  void *const rel_addr = (void *) dl_rw_ptr (l, reloc->r_offset);
   lookup_t result;
   DL_FIXUP_VALUE_TYPE value;
 
diff --git a/elf/dl-version.c b/elf/dl-version.c
index cda0889209..f19c8d1b42 100644
--- a/elf/dl-version.c
+++ b/elf/dl-version.c
@@ -86,7 +86,7 @@ checking for version `%s' in file %s [%lu] required by file %s [%lu]\n",
   def_offset = map->l_info[VERSYMIDX (DT_VERDEF)]->d_un.d_ptr;
   assert (def_offset != 0);
 
-  def = (ElfW(Verdef) *) ((char *) map->l_addr + def_offset);
+  def = (ElfW(Verdef) *) dl_rx_ptr (map, def_offset);
   while (1)
     {
       /* Currently the version number of the definition entry is 1.
@@ -177,7 +177,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
   if (dyn != NULL)
     {
       /* This file requires special versions from its dependencies.  */
-      ElfW(Verneed) *ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
+      ElfW(Verneed) *ent = (ElfW(Verneed) *) dl_rx_ptr (map, dyn->d_un.d_ptr);
 
       /* Currently the version number of the needed entry is 1.
 	 Make sure all we see is this version.  */
@@ -257,7 +257,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
   if (def != NULL)
     {
       ElfW(Verdef) *ent;
-      ent = (ElfW(Verdef) *) (map->l_addr + def->d_un.d_ptr);
+      ent = (ElfW(Verdef) *) dl_rx_ptr (map, def->d_un.d_ptr);
       while (1)
 	{
 	  if ((unsigned int) (ent->vd_ndx & 0x7fff) > ndx_high)
@@ -296,7 +296,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
       if (dyn != NULL)
 	{
 	  ElfW(Verneed) *ent;
-	  ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
+	  ent = (ElfW(Verneed) *) dl_rx_ptr (map, dyn->d_un.d_ptr);
 	  while (1)
 	    {
 	      ElfW(Vernaux) *aux;
@@ -334,7 +334,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
       if (def != NULL)
 	{
 	  ElfW(Verdef) *ent;
-	  ent = (ElfW(Verdef)  *) (map->l_addr + def->d_un.d_ptr);
+	  ent = (ElfW(Verdef)  *) dl_rx_ptr (map, def->d_un.d_ptr);
 	  while (1)
 	    {
 	      ElfW(Verdaux) *aux;
diff --git a/elf/do-rel.h b/elf/do-rel.h
index 27b9b9f427..694b3a6bd7 100644
--- a/elf/do-rel.h
+++ b/elf/do-rel.h
@@ -62,7 +62,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
     {
       ElfW (Half) ndx = version[ELFW (R_SYM) (r->r_info)] & 0x7fff;
       const ElfW (Sym) *sym = &symtab[ELFW (R_SYM) (r->r_info)];
-      void *const r_addr_arg = (void *) (l_addr + r->r_offset);
+      void *const r_addr_arg = (void *) dl_rw_ptr (map, r->r_offset);
       const struct r_found_version *rversion = &map->l_versions[ndx];
 
       elf_machine_rel (map, scope, r, sym, rversion, r_addr_arg, skip_ifunc);
@@ -132,7 +132,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
 	    {
 	      ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
 	      const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)];
-	      void *const r_addr_arg = (void *) (l_addr + r->r_offset);
+	      void *const r_addr_arg = (void *) dl_rw_ptr (map, r->r_offset);
 	      const struct r_found_version *rversion = &map->l_versions[ndx];
 #if defined ELF_MACHINE_IRELATIVE
 	      if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
@@ -169,7 +169,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
 		  elf_machine_rel (map, scope, r2,
 				   &symtab[ELFW(R_SYM) (r2->r_info)],
 				   &map->l_versions[ndx],
-				   (void *) (l_addr + r2->r_offset),
+				   (void *) dl_rw_ptr (map, r2->r_offset),
 				   skip_ifunc);
 		}
 #endif
@@ -179,7 +179,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
 	  for (; r < end; ++r)
 	    {
 	      const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)];
-	      void *const r_addr_arg = (void *) (l_addr + r->r_offset);
+	      void *const r_addr_arg = (void *) dl_rw_ptr (map, r->r_offset);
 # ifdef ELF_MACHINE_IRELATIVE
 	      if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
 		{
@@ -210,7 +210,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
 	    for (; r2 <= end2; ++r2)
 	      if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
 		elf_machine_rel (map, scope, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
-				 NULL, (void *) (l_addr + r2->r_offset),
+				 NULL, (void *) dl_rw_ptr (map, r2->r_offset),
 				 skip_ifunc);
 # endif
 	}
diff --git a/elf/rtld.c b/elf/rtld.c
index 26af99305e..1dac96c94b 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -722,8 +722,7 @@ match_version (const char *string, struct link_map *map)
     /* The file has no symbol versioning.  */
     return 0;
 
-  def = (ElfW(Verdef) *) ((char *) map->l_addr
-			  + map->l_info[VERDEFTAG]->d_un.d_ptr);
+  def = (ElfW(Verdef) *) dl_rx_ptr (map, map->l_info[VERDEFTAG]->d_un.d_ptr);
   while (1)
     {
       ElfW(Verdaux) *aux = (ElfW(Verdaux) *) ((char *) def + def->vd_aux);
@@ -1186,8 +1185,8 @@ rtld_setup_main_map (struct link_map *main_map)
 	   dlopen call or DT_NEEDED entry, for something that wants to link
 	   against the dynamic linker as a shared library, will know that
 	   the shared object is already loaded.  */
-	_dl_rtld_libname.name = ((const char *) main_map->l_addr
-				 + ph->p_vaddr);
+	_dl_rtld_libname.name = (const char *) dl_rx_ptr (main_map,
+							  ph->p_vaddr);
 	/* _dl_rtld_libname.next = NULL;	Already zero.  */
 	GL(dl_rtld_map).l_libname = &_dl_rtld_libname;
 
@@ -1304,7 +1303,7 @@ rtld_setup_main_map (struct link_map *main_map)
      the executable is actually an ET_DYN object.  */
   if (main_map->l_tls_initimage != NULL)
     main_map->l_tls_initimage
-      = (char *) main_map->l_tls_initimage + main_map->l_addr;
+      = (void *) dl_rx_ptr (main_map, (ElfW(Addr)) main_map->l_tls_initimage);
   if (! main_map->l_map_end)
     main_map->l_map_end = ~0;
   if (! main_map->l_text_end)
@@ -2251,7 +2250,7 @@ dl_main (const ElfW(Phdr) *phdr,
 		    continue;
 
 		  strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
-		  ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
+		  ent = (ElfW(Verneed) *) dl_rx_ptr (map, dyn->d_un.d_ptr);
 
 		  if (first)
 		    {
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 4c407e4f24..563b440aab 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -115,7 +115,8 @@ dl_rw_ptr (const struct link_map *l, ElfW(Addr) vaddr)
   most architectures the entry is already relocated - but for some not
   and we need to relocate at access time.  */
 #define D_PTR(map, i) \
-  ((map)->i->d_un.d_ptr + (dl_relocate_ld (map) ? 0 : (map)->l_addr))
+  (dl_relocate_ld (map) ? (map)->i->d_un.d_ptr \
+			: dl_rx_ptr ((map), (map)->i->d_un.d_ptr))
 
 /* Result of the lookup functions and how to retrieve the base address.  */
 typedef struct link_map *lookup_t;