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:
parent
8fddee78db
commit
469a54660c
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user