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;
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;