diff options
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/imgact_elf.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 699b59a..66659fd 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -633,7 +633,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) Elf_Auxargs *elf_auxargs = NULL; struct vmspace *vmspace; vm_prot_t prot; - u_long text_size = 0, data_size = 0; + u_long text_size = 0, data_size = 0, total_size = 0; u_long text_addr = 0, data_addr = 0; u_long seg_size, seg_addr; u_long addr, entry = 0, proghdr = 0; @@ -734,9 +734,19 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) phdr[i].p_vaddr - seg_addr); /* - * Check whether the entry point is in this segment - * to determine whether to count is as text or data. - * XXX: this needs to be done better! + * Is this .text or .data? We can't use + * VM_PROT_WRITE or VM_PROT_EXEC, it breaks the + * alpha terribly and possibly does other bad + * things so we stick to the old way of figuring + * it out: If the segment contains the program + * entry point, it's a text segment, otherwise it + * is a data segment. + * + * Note that obreak() assumes that data_addr + + * data_size == end of data load area, and the ELF + * file format expects segments to be sorted by + * address. If multiple data segments exist, the + * last one will be used. */ if (hdr->e_entry >= phdr[i].p_vaddr && hdr->e_entry < (phdr[i].p_vaddr + @@ -745,10 +755,10 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) text_addr = seg_addr; entry = (u_long)hdr->e_entry; } else { - data_size += seg_size; - if (data_addr == 0) - data_addr = seg_addr; + data_size = seg_size; + data_addr = seg_addr; } + total_size += seg_size; /* * Check limits. It should be safe to check the @@ -758,7 +768,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) if (data_size > imgp->proc->p_rlimit[RLIMIT_DATA].rlim_cur || text_size > maxtsiz || - data_size + text_size > + total_size > imgp->proc->p_rlimit[RLIMIT_VMEM].rlim_cur) { error = ENOMEM; goto fail; |