The dynamic section of an executable needs to be written to set the
DT_DEBUG entry for debuggers (unless the target has some other place
to store r_debug). For this reason we make l_ld writable whenever
the dynamic section is writable.
The ld.so l_ld is kept RX, since it does not have DT_DEBUG.
(Note: relocating the dynamic section is not allowed on cheri and
that's the only other reason glibc would write to it.)
}
if (l->l_ld != 0)
- l->l_ld = (ElfW(Dyn) *) ((ElfW(Addr)) l->l_ld + l->l_addr);
+ l->l_ld = (ElfW(Dyn) *) (l->l_ld_readonly
+ ? dl_rx_ptr (l, (elfptr_t) l->l_ld)
+ : dl_rw_ptr (l, (elfptr_t) l->l_ld));
elf_get_dynamic_info (l, false, false);
case PT_DYNAMIC:
/* This tells us where to find the dynamic section,
which tells us everything we need to do. */
- main_map->l_ld = (void *) main_map->l_addr + ph->p_vaddr;
main_map->l_ld_readonly = (ph->p_flags & PF_W) == 0;
+ main_map->l_ld = (void *) (main_map->l_ld_readonly
+ ? dl_rx_ptr (main_map, ph->p_vaddr)
+ : dl_rw_ptr (main_map, ph->p_vaddr));
break;
case PT_INTERP:
/* This "interpreter segment" was used by the program loader to