diff options
author | Szabolcs Nagy <szabolcs.nagy@arm.com> | 2022-08-08 13:03:57 +0100 |
---|---|---|
committer | Szabolcs Nagy <szabolcs.nagy@arm.com> | 2022-10-12 14:22:03 +0100 |
commit | 9c11d64d6d6fcd5ef2fc1acb623744ab6f7099b5 (patch) | |
tree | c89f20d3d4df06305a343e5fc165e5f0ebd44780 | |
parent | b35504abf039438ce90a406b6261e78e0558ad5a (diff) | |
download | glibc-9c11d64d6d6fcd5ef2fc1acb623744ab6f7099b5.tar.gz glibc-9c11d64d6d6fcd5ef2fc1acb623744ab6f7099b5.tar.xz glibc-9c11d64d6d6fcd5ef2fc1acb623744ab6f7099b5.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-- | csu/libc-start.c | 4 | ||||
-rw-r--r-- | csu/libc-tls.c | 2 | ||||
-rw-r--r-- | elf/dl-close.c | 6 | ||||
-rw-r--r-- | elf/dl-find_object.h | 2 | ||||
-rw-r--r-- | elf/dl-fini.c | 7 | ||||
-rw-r--r-- | elf/dl-init.c | 7 | ||||
-rw-r--r-- | elf/dl-load.c | 9 | ||||
-rw-r--r-- | elf/dl-reloc.c | 3 | ||||
-rw-r--r-- | elf/dl-runtime.c | 2 | ||||
-rw-r--r-- | elf/dl-version.c | 10 | ||||
-rw-r--r-- | elf/do-rel.h | 10 | ||||
-rw-r--r-- | elf/rtld.c | 11 | ||||
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 3 |
13 files changed, 37 insertions, 39 deletions
diff --git a/csu/libc-start.c b/csu/libc-start.c index 2acefceb1a..d71fbec3fe 100644 --- a/csu/libc-start.c +++ b/csu/libc-start.c @@ -132,7 +132,7 @@ call_init (int argc, char **argv, char **env) the same file. */ if (ELF_INITFINI && l->l_info[DT_INIT] != NULL) - DL_CALL_DT_INIT(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr, + DL_CALL_DT_INIT(l, dl_rx_ptr (l, l->l_info[DT_INIT]->d_un.d_ptr), argc, argv, env); ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY]; @@ -140,7 +140,7 @@ call_init (int argc, char **argv, char **env) { unsigned int jm = l->l_info[DT_INIT_ARRAYSZ]->d_un.d_val / sizeof (elfptr_t); - elfptr_t *addrs = (void *) (init_array->d_un.d_ptr + l->l_addr); + elfptr_t *addrs = (void *) dl_rx_ptr (l, init_array->d_un.d_ptr); for (unsigned int j = 0; j < jm; ++j) ((dl_init_t) addrs[j]) (argc, argv, env); } diff --git a/csu/libc-tls.c b/csu/libc-tls.c index b3d146472d..0701ec5acb 100644 --- a/csu/libc-tls.c +++ b/csu/libc-tls.c @@ -125,7 +125,7 @@ __libc_setup_tls (void) /* Remember the values we need. */ memsz = phdr->p_memsz; filesz = phdr->p_filesz; - initimage = phdr->p_vaddr + (void *) main_map->l_addr; + initimage = (void *) dl_rx_ptr (main_map, phdr->p_vaddr); align = phdr->p_align; if (phdr->p_align > max_align) max_align = phdr->p_align; diff --git a/elf/dl-close.c b/elf/dl-close.c index a20cf8cc36..5a45062f09 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -120,8 +120,7 @@ call_destructors (void *closure) if (map->l_info[DT_FINI_ARRAY] != NULL) { elfptr_t *array = - (elfptr_t *) (map->l_addr - + map->l_info[DT_FINI_ARRAY]->d_un.d_ptr); + (elfptr_t *) dl_rx_ptr (map, map->l_info[DT_FINI_ARRAY]->d_un.d_ptr); unsigned int sz = (map->l_info[DT_FINI_ARRAYSZ]->d_un.d_val / sizeof (elfptr_t)); @@ -131,8 +130,7 @@ call_destructors (void *closure) /* Next try the old-style destructor. */ if (map->l_info[DT_FINI] != NULL) - DL_CALL_DT_FINI (map, ((void *) map->l_addr - + map->l_info[DT_FINI]->d_un.d_ptr)); + DL_CALL_DT_FINI (map, dl_rx_ptr (map, map->l_info[DT_FINI]->d_un.d_ptr)); } void 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-fini.c b/elf/dl-fini.c index 040bda28b2..18135b2191 100644 --- a/elf/dl-fini.c +++ b/elf/dl-fini.c @@ -133,9 +133,8 @@ _dl_fini (void) /* First see whether an array is given. */ if (l->l_info[DT_FINI_ARRAY] != NULL) { - elfptr_t *array = - (elfptr_t *) (l->l_addr - + l->l_info[DT_FINI_ARRAY]->d_un.d_ptr); + ElfW(Addr) v = l->l_info[DT_FINI_ARRAY]->d_un.d_ptr; + elfptr_t *array = (elfptr_t *) dl_rx_ptr (l, v); unsigned int i = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val / sizeof (elfptr_t)); while (i-- > 0) @@ -145,7 +144,7 @@ _dl_fini (void) /* Next try the old-style destructor. */ if (ELF_INITFINI && l->l_info[DT_FINI] != NULL) DL_CALL_DT_FINI - (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr); + (l, dl_rx_ptr (l, l->l_info[DT_FINI]->d_un.d_ptr)); } #ifdef SHARED diff --git a/elf/dl-init.c b/elf/dl-init.c index 4c8aaae7e0..7fb2af6a3f 100644 --- a/elf/dl-init.c +++ b/elf/dl-init.c @@ -53,7 +53,8 @@ call_init (struct link_map *l, int argc, char **argv, char **env) - the others in the DT_INIT_ARRAY. */ if (ELF_INITFINI && l->l_info[DT_INIT] != NULL) - DL_CALL_DT_INIT(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr, argc, argv, env); + DL_CALL_DT_INIT(l, dl_rx_ptr (l, l->l_info[DT_INIT]->d_un.d_ptr), + argc, argv, env); /* Next see whether there is an array with initialization functions. */ ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY]; @@ -65,7 +66,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env) jm = l->l_info[DT_INIT_ARRAYSZ]->d_un.d_val / sizeof (elfptr_t); - addrs = (elfptr_t *) (init_array->d_un.d_ptr + l->l_addr); + addrs = (elfptr_t *) dl_rx_ptr (l, init_array->d_un.d_ptr); for (j = 0; j < jm; ++j) ((dl_init_t) addrs[j]) (argc, argv, env); } @@ -97,7 +98,7 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env) _dl_debug_printf ("\ncalling preinit: %s\n\n", DSO_FILENAME (main_map->l_name)); - addrs = (elfptr_t *) (preinit_array->d_un.d_ptr + main_map->l_addr); + addrs = (elfptr_t *) dl_rx_ptr (main_map, preinit_array->d_un.d_ptr); for (cnt = 0; cnt < i; ++cnt) ((dl_init_t) addrs[cnt]) (argc, argv, env); } diff --git a/elf/dl-load.c b/elf/dl-load.c index 192ad4f7c9..b25ddaec05 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; @@ -1316,7 +1316,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)) { @@ -1371,7 +1371,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 = (ElfW(Addr)) l->l_tls_initimage + (char *) 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 @@ -1404,7 +1405,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-reloc.c b/elf/dl-reloc.c index abc72472ba..d0d9a51716 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -353,8 +353,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], void _dl_protect_relro (struct link_map *l) { - elfptr_t start = ALIGN_DOWN((l->l_addr - + l->l_relro_addr), + elfptr_t start = ALIGN_DOWN(dl_rx_ptr (l, l->l_relro_addr), GLRO(dl_pagesize)); elfptr_t end = ALIGN_DOWN((l->l_addr + l->l_relro_addr 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 0c028ca8b3..0a2eddf737 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 fcb8b9e888..82e40e8201 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -723,8 +723,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); @@ -1193,8 +1192,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; @@ -1311,7 +1310,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 - = (ElfW(Addr)) main_map->l_tls_initimage + (char *) 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) @@ -2252,7 +2251,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 0cc9d7e89c..8c930e9493 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; |