Annotation of sys/kern/exec_ecoff.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: exec_ecoff.c,v 1.10 2005/11/12 04:31:24 jsg Exp $ */
! 2: /* $NetBSD: exec_ecoff.c,v 1.8 1996/05/19 20:36:06 jonathan Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1994 Adam Glass
! 6: * Copyright (c) 1993, 1994, 1996 Christopher G. Demetriou
! 7: * All rights reserved.
! 8: *
! 9: * Redistribution and use in source and binary forms, with or without
! 10: * modification, are permitted provided that the following conditions
! 11: * are met:
! 12: * 1. Redistributions of source code must retain the above copyright
! 13: * notice, this list of conditions and the following disclaimer.
! 14: * 2. Redistributions in binary form must reproduce the above copyright
! 15: * notice, this list of conditions and the following disclaimer in the
! 16: * documentation and/or other materials provided with the distribution.
! 17: * 3. All advertising materials mentioning features or use of this software
! 18: * must display the following acknowledgement:
! 19: * This product includes software developed by Christopher G. Demetriou.
! 20: * 4. The name of the author may not be used to endorse or promote products
! 21: * derived from this software without specific prior written permission
! 22: *
! 23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 25: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 26: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 27: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 28: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 29: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 30: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 31: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 32: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 33: */
! 34:
! 35: #include <sys/param.h>
! 36: #include <sys/systm.h>
! 37: #include <sys/proc.h>
! 38: #include <sys/malloc.h>
! 39: #include <sys/vnode.h>
! 40: #include <sys/exec.h>
! 41: #include <sys/resourcevar.h>
! 42: #include <uvm/uvm_extern.h>
! 43:
! 44: #if defined(_KERN_DO_ECOFF)
! 45:
! 46: #include <sys/exec_ecoff.h>
! 47:
! 48: /*
! 49: * exec_ecoff_makecmds(): Check if it's an ecoff-format executable.
! 50: *
! 51: * Given a proc pointer and an exec package pointer, see if the referent
! 52: * of the epp is in ecoff format. Check 'standard' magic numbers for
! 53: * this architecture. If that fails, return failure.
! 54: *
! 55: * This function is responsible for creating a set of vmcmds which can be
! 56: * used to build the process's vm space and inserting them into the exec
! 57: * package.
! 58: */
! 59: int
! 60: exec_ecoff_makecmds(struct proc *p, struct exec_package *epp)
! 61: {
! 62: int error;
! 63: struct ecoff_exechdr *execp = epp->ep_hdr;
! 64:
! 65: if (epp->ep_hdrvalid < ECOFF_HDR_SIZE)
! 66: return ENOEXEC;
! 67:
! 68: if (ECOFF_BADMAG(execp))
! 69: return ENOEXEC;
! 70:
! 71: switch (execp->a.magic) {
! 72: case ECOFF_OMAGIC:
! 73: error = exec_ecoff_prep_omagic(p, epp);
! 74: break;
! 75: case ECOFF_NMAGIC:
! 76: error = exec_ecoff_prep_nmagic(p, epp);
! 77: break;
! 78: case ECOFF_ZMAGIC:
! 79: error = exec_ecoff_prep_zmagic(p, epp);
! 80: break;
! 81: default:
! 82: return ENOEXEC;
! 83: }
! 84:
! 85: if (error == 0)
! 86: error = cpu_exec_ecoff_hook(p, epp);
! 87:
! 88: if (error)
! 89: kill_vmcmds(&epp->ep_vmcmds);
! 90:
! 91: return error;
! 92: }
! 93:
! 94: /*
! 95: * exec_ecoff_prep_omagic(): Prepare a ECOFF OMAGIC binary's exec package
! 96: */
! 97: int
! 98: exec_ecoff_prep_omagic(struct proc *p, struct exec_package *epp)
! 99: {
! 100: struct ecoff_exechdr *execp = epp->ep_hdr;
! 101: struct ecoff_aouthdr *eap = &execp->a;
! 102:
! 103: epp->ep_taddr = ECOFF_SEGMENT_ALIGN(execp, eap->text_start);
! 104: epp->ep_tsize = eap->tsize;
! 105: epp->ep_daddr = ECOFF_SEGMENT_ALIGN(execp, eap->data_start);
! 106: epp->ep_dsize = eap->dsize + eap->bsize;
! 107: epp->ep_entry = eap->entry;
! 108:
! 109: /* set up command for text and data segments */
! 110: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn,
! 111: eap->tsize + eap->dsize, epp->ep_taddr, epp->ep_vp,
! 112: ECOFF_TXTOFF(execp),
! 113: VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
! 114:
! 115: /* set up command for bss segment */
! 116: if (eap->bsize > 0)
! 117: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, eap->bsize,
! 118: ECOFF_SEGMENT_ALIGN(execp, eap->bss_start), NULLVP, 0,
! 119: VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
! 120:
! 121: return exec_setup_stack(p, epp);
! 122: }
! 123:
! 124: /*
! 125: * exec_ecoff_prep_nmagic(): Prepare a 'native' NMAGIC ECOFF binary's exec
! 126: * package.
! 127: */
! 128: int
! 129: exec_ecoff_prep_nmagic(struct proc *p, struct exec_package *epp)
! 130: {
! 131: struct ecoff_exechdr *execp = epp->ep_hdr;
! 132: struct ecoff_aouthdr *eap = &execp->a;
! 133:
! 134: epp->ep_taddr = ECOFF_SEGMENT_ALIGN(execp, eap->text_start);
! 135: epp->ep_tsize = eap->tsize;
! 136: epp->ep_daddr = ECOFF_ROUND(eap->data_start, ECOFF_LDPGSZ);
! 137: epp->ep_dsize = eap->dsize + eap->bsize;
! 138: epp->ep_entry = eap->entry;
! 139:
! 140: /* set up command for text segment */
! 141: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, epp->ep_tsize,
! 142: epp->ep_taddr, epp->ep_vp, ECOFF_TXTOFF(execp),
! 143: VM_PROT_READ|VM_PROT_EXECUTE);
! 144:
! 145: /* set up command for data segment */
! 146: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, epp->ep_dsize,
! 147: epp->ep_daddr, epp->ep_vp, ECOFF_DATOFF(execp),
! 148: VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
! 149:
! 150: /* set up command for bss segment */
! 151: if (eap->bsize > 0)
! 152: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, eap->bsize,
! 153: ECOFF_SEGMENT_ALIGN(execp, eap->bss_start), NULLVP, 0,
! 154: VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
! 155:
! 156: return exec_setup_stack(p, epp);
! 157: }
! 158:
! 159: /*
! 160: * exec_ecoff_prep_zmagic(): Prepare a ECOFF ZMAGIC binary's exec package
! 161: *
! 162: * First, set the various offsets/lengths in the exec package.
! 163: *
! 164: * Then, mark the text image busy (so it can be demand paged) or error
! 165: * out if this is not possible. Finally, set up vmcmds for the
! 166: * text, data, bss, and stack segments.
! 167: */
! 168: int
! 169: exec_ecoff_prep_zmagic(struct proc *p, struct exec_package *epp)
! 170: {
! 171: struct ecoff_exechdr *execp = epp->ep_hdr;
! 172: struct ecoff_aouthdr *eap = &execp->a;
! 173:
! 174: epp->ep_taddr = ECOFF_SEGMENT_ALIGN(execp, eap->text_start);
! 175: epp->ep_tsize = eap->tsize;
! 176: epp->ep_daddr = ECOFF_SEGMENT_ALIGN(execp, eap->data_start);
! 177: epp->ep_dsize = eap->dsize + eap->bsize;
! 178: epp->ep_entry = eap->entry;
! 179:
! 180: /*
! 181: * check if vnode is in open for writing, because we want to
! 182: * demand-page out of it. if it is, don't do it, for various
! 183: * reasons
! 184: */
! 185: if ((eap->tsize != 0 || eap->dsize != 0) &&
! 186: epp->ep_vp->v_writecount != 0) {
! 187: #ifdef DIAGNOSTIC
! 188: if (epp->ep_vp->v_flag & VTEXT)
! 189: panic("exec: a VTEXT vnode has writecount != 0");
! 190: #endif
! 191: return ETXTBSY;
! 192: }
! 193: vn_marktext(epp->ep_vp);
! 194:
! 195: /* set up command for text segment */
! 196: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, eap->tsize,
! 197: epp->ep_taddr, epp->ep_vp, ECOFF_TXTOFF(execp),
! 198: VM_PROT_READ|VM_PROT_EXECUTE);
! 199:
! 200: /* set up command for data segment */
! 201: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, eap->dsize,
! 202: epp->ep_daddr, epp->ep_vp, ECOFF_DATOFF(execp),
! 203: VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
! 204:
! 205: /* set up command for bss segment */
! 206: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, eap->bsize,
! 207: ECOFF_SEGMENT_ALIGN(execp, eap->bss_start), NULLVP, 0,
! 208: VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
! 209:
! 210: return exec_setup_stack(p, epp);
! 211: }
! 212:
! 213: #endif /* _KERN_DO_ECOFF */
CVSweb