summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/imgact_elf.c26
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;
OpenPOWER on IntegriCloud