From 02116da56f78945e44ba97aaf2f7774a11ebf518 Mon Sep 17 00:00:00 2001 From: mp Date: Thu, 16 Aug 2001 16:14:26 +0000 Subject: Reduce stack allocation (stack-fast?). elf_load_file() => 352 to 52 bytes exec_elf_imgact() => 1072 to 48 bytes elf_corehdr() => 396 to 8 bytes Reviewed by: julian --- sys/kern/imgact_elf.c | 105 +++++++++++++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 40 deletions(-) (limited to 'sys') diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index ff18d0e..96ef2df 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -326,48 +326,57 @@ elf_load_section(struct proc *p, struct vmspace *vmspace, struct vnode *vp, vm_o static int elf_load_file(struct proc *p, const char *file, u_long *addr, u_long *entry) { + struct { + struct nameidata nd; + struct vattr attr; + struct image_params image_params; + } *tempdata; const Elf_Ehdr *hdr = NULL; const Elf_Phdr *phdr = NULL; - struct nameidata nd; + struct nameidata *nd; struct vmspace *vmspace = p->p_vmspace; - struct vattr attr; - struct image_params image_params, *imgp; + struct vattr *attr; + struct image_params *imgp; vm_prot_t prot; u_long rbase; u_long base_addr = 0; int error, i, numsegs; - imgp = &image_params; + tempdata = malloc(sizeof(*tempdata), M_TEMP, M_WAITOK); + nd = &tempdata->nd; + attr = &tempdata->attr; + imgp = &tempdata->image_params; + /* * Initialize part of the common data */ imgp->proc = p; imgp->uap = NULL; - imgp->attr = &attr; + imgp->attr = attr; imgp->firstpage = NULL; imgp->image_header = (char *)kmem_alloc_wait(exec_map, PAGE_SIZE); if (imgp->image_header == NULL) { - nd.ni_vp = NULL; + nd->ni_vp = NULL; error = ENOMEM; goto fail; } - NDINIT(&nd, LOOKUP, LOCKLEAF|FOLLOW, UIO_SYSSPACE, file, p); + NDINIT(nd, LOOKUP, LOCKLEAF|FOLLOW, UIO_SYSSPACE, file, p); - if ((error = namei(&nd)) != 0) { - nd.ni_vp = NULL; + if ((error = namei(nd)) != 0) { + nd->ni_vp = NULL; goto fail; } - NDFREE(&nd, NDF_ONLY_PNBUF); - imgp->vp = nd.ni_vp; + NDFREE(nd, NDF_ONLY_PNBUF); + imgp->vp = nd->ni_vp; /* * Check permissions, modes, uid, etc on the file, and "open" it. */ error = exec_check_permissions(imgp); if (error) { - VOP_UNLOCK(nd.ni_vp, 0, p); + VOP_UNLOCK(nd->ni_vp, 0, p); goto fail; } @@ -377,8 +386,8 @@ elf_load_file(struct proc *p, const char *file, u_long *addr, u_long *entry) * its VTEXT flag, too. */ if (error == 0) - nd.ni_vp->v_flag |= VTEXT; - VOP_UNLOCK(nd.ni_vp, 0, p); + nd->ni_vp->v_flag |= VTEXT; + VOP_UNLOCK(nd->ni_vp, 0, p); if (error) goto fail; @@ -413,7 +422,7 @@ elf_load_file(struct proc *p, const char *file, u_long *addr, u_long *entry) if (phdr[i].p_flags & PF_R) prot |= VM_PROT_READ; - if ((error = elf_load_section(p, vmspace, nd.ni_vp, + if ((error = elf_load_section(p, vmspace, nd->ni_vp, phdr[i].p_offset, (caddr_t)phdr[i].p_vaddr + rbase, @@ -438,8 +447,10 @@ fail: if (imgp->image_header) kmem_free_wakeup(exec_map, (vm_offset_t)imgp->image_header, PAGE_SIZE); - if (nd.ni_vp) - vrele(nd.ni_vp); + if (nd->ni_vp) + vrele(nd->ni_vp); + + free(tempdata, M_TEMP); return error; } @@ -466,7 +477,7 @@ exec_elf_imgact(struct image_params *imgp) int error, i; const char *interp = NULL; Elf_Brandinfo *brand_info; - char path[MAXPATHLEN]; + char *path; GIANT_REQUIRED; @@ -632,6 +643,7 @@ exec_elf_imgact(struct image_params *imgp) imgp->proc->p_sysent = brand_info->sysvec; if (interp != NULL) { + path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); snprintf(path, sizeof(path), "%s%s", brand_info->emul_path, interp); if ((error = elf_load_file(imgp->proc, path, &addr, @@ -639,9 +651,11 @@ exec_elf_imgact(struct image_params *imgp) if ((error = elf_load_file(imgp->proc, interp, &addr, &imgp->entry_addr)) != 0) { uprintf("ELF interpreter %s not found\n", path); + free(path, M_TEMP); goto fail; } } + free(path, M_TEMP); } /* @@ -898,36 +912,47 @@ elf_corehdr(p, vp, cred, numsegs, hdr, hdrsize) size_t hdrsize; void *hdr; { + struct { + prstatus_t status; + prfpregset_t fpregset; + prpsinfo_t psinfo; + } *tempdata; size_t off; - prstatus_t status; - prfpregset_t fpregset; - prpsinfo_t psinfo; + prstatus_t *status; + prfpregset_t *fpregset; + prpsinfo_t *psinfo; + + tempdata = malloc(sizeof(*tempdata), M_TEMP, M_ZERO); + status = &tempdata->status; + fpregset = &tempdata->fpregset; + psinfo = &tempdata->psinfo; /* Gather the information for the header. */ - bzero(&status, sizeof status); - status.pr_version = PRSTATUS_VERSION; - status.pr_statussz = sizeof(prstatus_t); - status.pr_gregsetsz = sizeof(gregset_t); - status.pr_fpregsetsz = sizeof(fpregset_t); - status.pr_osreldate = osreldate; - status.pr_cursig = p->p_sig; - status.pr_pid = p->p_pid; - fill_regs(p, &status.pr_reg); - - fill_fpregs(p, &fpregset); - - bzero(&psinfo, sizeof psinfo); - psinfo.pr_version = PRPSINFO_VERSION; - psinfo.pr_psinfosz = sizeof(prpsinfo_t); - strncpy(psinfo.pr_fname, p->p_comm, sizeof(psinfo.pr_fname) - 1); - psinfo.pr_fname[sizeof(psinfo.pr_fname) - 1] = '\0'; + status->pr_version = PRSTATUS_VERSION; + status->pr_statussz = sizeof(prstatus_t); + status->pr_gregsetsz = sizeof(gregset_t); + status->pr_fpregsetsz = sizeof(fpregset_t); + status->pr_osreldate = osreldate; + status->pr_cursig = p->p_sig; + status->pr_pid = p->p_pid; + fill_regs(p, &status->pr_reg); + + fill_fpregs(p, fpregset); + + psinfo->pr_version = PRPSINFO_VERSION; + psinfo->pr_psinfosz = sizeof(prpsinfo_t); + strncpy(psinfo->pr_fname, p->p_comm, sizeof(psinfo->pr_fname) - 1); + psinfo->pr_fname[sizeof(psinfo->pr_fname) - 1] = '\0'; + /* XXX - We don't fill in the command line arguments properly yet. */ - strncpy(psinfo.pr_psargs, p->p_comm, PRARGSZ); + strncpy(psinfo->pr_psargs, p->p_comm, PRARGSZ); /* Fill in the header. */ bzero(hdr, hdrsize); off = 0; - elf_puthdr(p, hdr, &off, &status, &fpregset, &psinfo, numsegs); + elf_puthdr(p, hdr, &off, status, fpregset, psinfo, numsegs); + + free(tempdata, M_TEMP); /* Write it to the core file. */ return vn_rdwr(UIO_WRITE, vp, hdr, hdrsize, (off_t)0, -- cgit v1.1