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
This commit is contained in:
dillon 2002-09-04 04:42:12 +00:00
parent 8fddee78db
commit 469a54660c

View File

@ -633,7 +633,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
Elf_Auxargs *elf_auxargs = NULL; Elf_Auxargs *elf_auxargs = NULL;
struct vmspace *vmspace; struct vmspace *vmspace;
vm_prot_t prot; 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 text_addr = 0, data_addr = 0;
u_long seg_size, seg_addr; u_long seg_size, seg_addr;
u_long addr, entry = 0, proghdr = 0; 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); phdr[i].p_vaddr - seg_addr);
/* /*
* Check whether the entry point is in this segment * Is this .text or .data? We can't use
* to determine whether to count is as text or data. * VM_PROT_WRITE or VM_PROT_EXEC, it breaks the
* XXX: this needs to be done better! * 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 && if (hdr->e_entry >= phdr[i].p_vaddr &&
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; text_addr = seg_addr;
entry = (u_long)hdr->e_entry; entry = (u_long)hdr->e_entry;
} else { } else {
data_size += seg_size; data_size = seg_size;
if (data_addr == 0) data_addr = seg_addr;
data_addr = seg_addr;
} }
total_size += seg_size;
/* /*
* Check limits. It should be safe to check the * Check limits. It should be safe to check the
@ -758,7 +768,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
if (data_size > if (data_size >
imgp->proc->p_rlimit[RLIMIT_DATA].rlim_cur || imgp->proc->p_rlimit[RLIMIT_DATA].rlim_cur ||
text_size > maxtsiz || text_size > maxtsiz ||
data_size + text_size > total_size >
imgp->proc->p_rlimit[RLIMIT_VMEM].rlim_cur) { imgp->proc->p_rlimit[RLIMIT_VMEM].rlim_cur) {
error = ENOMEM; error = ENOMEM;
goto fail; goto fail;