summaryrefslogtreecommitdiffstats
path: root/sys/kern/imgact_elf.c
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>2002-09-04 04:42:12 +0000
committerdillon <dillon@FreeBSD.org>2002-09-04 04:42:12 +0000
commit469a54660c62e422b1cd51a6ad4f65086007b6bb (patch)
tree747ba528cab8645779f7f47a4b0e33e140dca2d6 /sys/kern/imgact_elf.c
parent8fddee78dba2678e0b3a99d5b964d1f541cb4f55 (diff)
downloadFreeBSD-src-469a54660c62e422b1cd51a6ad4f65086007b6bb.zip
FreeBSD-src-469a54660c62e422b1cd51a6ad4f65086007b6bb.tar.gz
Alright, fix the problems with the elf loader for the Alpha. It turns
out that there is no easy way to discern the difference between a text segment and a data segment through the read-only OR execute attribute in the elf segment header, so revert the algorithm to what it was before. Neither can we account for multiple data load segments in the vmspace structure (at least not without more work), due to assumptions obreak() makes in regards to the data start and data size fields. Retain RLIMIT_VMEM checking by using a local variable to track the total bytes of data being loaded. Reviewed by: peter X-MFC after: ASAP
Diffstat (limited to 'sys/kern/imgact_elf.c')
-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