diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c index 02f786318ac2..101156ac3e63 100644 --- a/libexec/rtld-elf/map_object.c +++ b/libexec/rtld-elf/map_object.c @@ -93,6 +93,7 @@ map_object(int fd, const char *path, const struct stat *sb) Elf_Addr note_end; char *note_map; size_t note_map_len; + Elf_Addr text_end; hdr = get_elf_header(fd, path, sb); if (hdr == NULL) @@ -116,6 +117,7 @@ map_object(int fd, const char *path, const struct stat *sb) note_map = NULL; segs = alloca(sizeof(segs[0]) * hdr->e_phnum); stack_flags = RTLD_DEFAULT_STACK_PF_EXEC | PF_R | PF_W; + text_end = 0; while (phdr < phlimit) { switch (phdr->p_type) { @@ -130,6 +132,10 @@ map_object(int fd, const char *path, const struct stat *sb) path, nsegs); goto error; } + if ((segs[nsegs]->p_flags & PF_X) == PF_X) { + text_end = MAX(text_end, + round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz)); + } break; case PT_PHDR: @@ -280,8 +286,7 @@ map_object(int fd, const char *path, const struct stat *sb) } obj->mapbase = mapbase; obj->mapsize = mapsize; - obj->textsize = round_page(segs[0]->p_vaddr + segs[0]->p_memsz) - - base_vaddr; + obj->textsize = text_end - base_vaddr; obj->vaddrbase = base_vaddr; obj->relocbase = mapbase - base_vaddr; obj->dynamic = (const Elf_Dyn *) (obj->relocbase + phdyn->p_vaddr); diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 83d5e28e287b..ba4a238e1d06 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -1390,13 +1390,15 @@ digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path) if (nsegs == 0) { /* First load segment */ obj->vaddrbase = trunc_page(ph->p_vaddr); obj->mapbase = obj->vaddrbase + obj->relocbase; - obj->textsize = round_page(ph->p_vaddr + ph->p_memsz) - - obj->vaddrbase; } else { /* Last load segment */ obj->mapsize = round_page(ph->p_vaddr + ph->p_memsz) - obj->vaddrbase; } nsegs++; + if ((ph->p_flags & PF_X) == PF_X) { + obj->textsize = MAX(obj->textsize, + round_page(ph->p_vaddr + ph->p_memsz) - obj->vaddrbase); + } break; case PT_DYNAMIC: