1cfefd687SGarrett Wollman /* 2cfefd687SGarrett Wollman * Copyright (c) 1993, David Greenman 3cfefd687SGarrett Wollman * All rights reserved. 4cfefd687SGarrett Wollman * 5cfefd687SGarrett Wollman * Redistribution and use in source and binary forms, with or without 6cfefd687SGarrett Wollman * modification, are permitted provided that the following conditions 7cfefd687SGarrett Wollman * are met: 8cfefd687SGarrett Wollman * 1. Redistributions of source code must retain the above copyright 9cfefd687SGarrett Wollman * notice, this list of conditions and the following disclaimer. 10cfefd687SGarrett Wollman * 2. Redistributions in binary form must reproduce the above copyright 11cfefd687SGarrett Wollman * notice, this list of conditions and the following disclaimer in the 12cfefd687SGarrett Wollman * documentation and/or other materials provided with the distribution. 13cfefd687SGarrett Wollman * 3. All advertising materials mentioning features or use of this software 14cfefd687SGarrett Wollman * must display the following acknowledgement: 15cfefd687SGarrett Wollman * This product includes software developed by David Greenman 16cfefd687SGarrett Wollman * 4. The name of the developer may be used to endorse or promote products 17cfefd687SGarrett Wollman * derived from this software without specific prior written permission. 18cfefd687SGarrett Wollman * 19cfefd687SGarrett Wollman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20cfefd687SGarrett Wollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21cfefd687SGarrett Wollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22cfefd687SGarrett Wollman * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23cfefd687SGarrett Wollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24cfefd687SGarrett Wollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25cfefd687SGarrett Wollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26cfefd687SGarrett Wollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27cfefd687SGarrett Wollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28cfefd687SGarrett Wollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29cfefd687SGarrett Wollman * SUCH DAMAGE. 30cfefd687SGarrett Wollman * 31bb56ec4aSPoul-Henning Kamp * $Id: imgact_aout.c,v 1.8 1994/09/24 21:36:50 davidg Exp $ 32cfefd687SGarrett Wollman */ 33cfefd687SGarrett Wollman 3426f9a767SRodney W. Grimes #include <sys/param.h> 3526f9a767SRodney W. Grimes #include <sys/systm.h> 3626f9a767SRodney W. Grimes #include <sys/resourcevar.h> 3726f9a767SRodney W. Grimes #include <sys/exec.h> 3826f9a767SRodney W. Grimes #include <sys/mman.h> 3926f9a767SRodney W. Grimes #include <sys/imgact.h> 40bc6d7444SDavid Greenman #include <sys/imgact_aout.h> 4126f9a767SRodney W. Grimes #include <sys/kernel.h> 42f3f0ca60SSøren Schmidt #include <sys/sysent.h> 43cfefd687SGarrett Wollman 4426f9a767SRodney W. Grimes #include <vm/vm.h> 45cfefd687SGarrett Wollman 46cfefd687SGarrett Wollman int 47cfefd687SGarrett Wollman exec_aout_imgact(iparams) 48cfefd687SGarrett Wollman struct image_params *iparams; 49cfefd687SGarrett Wollman { 50cfefd687SGarrett Wollman struct exec *a_out = (struct exec *) iparams->image_header; 51cfefd687SGarrett Wollman struct vmspace *vmspace = iparams->proc->p_vmspace; 52cfefd687SGarrett Wollman unsigned long vmaddr, virtual_offset, file_offset; 53cfefd687SGarrett Wollman unsigned long bss_size; 54bb56ec4aSPoul-Henning Kamp int error; 55f3f0ca60SSøren Schmidt extern struct sysentvec aout_sysvec; 56cfefd687SGarrett Wollman 57cfefd687SGarrett Wollman /* 58cfefd687SGarrett Wollman * Set file/virtual offset based on a.out variant. 59cfefd687SGarrett Wollman * We do two cases: host byte order and network byte order 60cfefd687SGarrett Wollman * (for NetBSD compatibility) 61cfefd687SGarrett Wollman */ 62cfefd687SGarrett Wollman switch ((int)(a_out->a_magic & 0xffff)) { 63cfefd687SGarrett Wollman case ZMAGIC: 64cfefd687SGarrett Wollman virtual_offset = 0; 65cfefd687SGarrett Wollman if (a_out->a_text) { 66cfefd687SGarrett Wollman file_offset = NBPG; 67cfefd687SGarrett Wollman } else { 68cfefd687SGarrett Wollman /* Bill's "screwball mode" */ 69cfefd687SGarrett Wollman file_offset = 0; 70cfefd687SGarrett Wollman } 71cfefd687SGarrett Wollman break; 72cfefd687SGarrett Wollman case QMAGIC: 73cfefd687SGarrett Wollman virtual_offset = NBPG; 74cfefd687SGarrett Wollman file_offset = 0; 75cfefd687SGarrett Wollman break; 76cfefd687SGarrett Wollman default: 77cfefd687SGarrett Wollman /* NetBSD compatibility */ 78cfefd687SGarrett Wollman switch ((int)(ntohl(a_out->a_magic) & 0xffff)) { 79cfefd687SGarrett Wollman case ZMAGIC: 80cfefd687SGarrett Wollman case QMAGIC: 81cfefd687SGarrett Wollman virtual_offset = NBPG; 82cfefd687SGarrett Wollman file_offset = 0; 83cfefd687SGarrett Wollman break; 84cfefd687SGarrett Wollman default: 85cfefd687SGarrett Wollman return (-1); 86cfefd687SGarrett Wollman } 87cfefd687SGarrett Wollman } 88cfefd687SGarrett Wollman 89cfefd687SGarrett Wollman bss_size = roundup(a_out->a_bss, NBPG); 90cfefd687SGarrett Wollman 91cfefd687SGarrett Wollman /* 92cfefd687SGarrett Wollman * Check various fields in header for validity/bounds. 93cfefd687SGarrett Wollman */ 94cfefd687SGarrett Wollman if (/* entry point must lay with text region */ 95cfefd687SGarrett Wollman a_out->a_entry < virtual_offset || 96cfefd687SGarrett Wollman a_out->a_entry >= virtual_offset + a_out->a_text || 97cfefd687SGarrett Wollman 98cfefd687SGarrett Wollman /* text and data size must each be page rounded */ 99cfefd687SGarrett Wollman a_out->a_text % NBPG || 100cfefd687SGarrett Wollman a_out->a_data % NBPG) 101cfefd687SGarrett Wollman return (-1); 102cfefd687SGarrett Wollman 103cfefd687SGarrett Wollman /* text + data can't exceed file size */ 104cfefd687SGarrett Wollman if (a_out->a_data + a_out->a_text > iparams->attr->va_size) 105cfefd687SGarrett Wollman return (EFAULT); 106cfefd687SGarrett Wollman 107cfefd687SGarrett Wollman /* 108cfefd687SGarrett Wollman * text/data/bss must not exceed limits 109cfefd687SGarrett Wollman */ 110cfefd687SGarrett Wollman if (/* text can't exceed maximum text size */ 111cfefd687SGarrett Wollman a_out->a_text > MAXTSIZ || 112cfefd687SGarrett Wollman 113cfefd687SGarrett Wollman /* data + bss can't exceed maximum data size */ 114cfefd687SGarrett Wollman a_out->a_data + bss_size > MAXDSIZ || 115cfefd687SGarrett Wollman 116cfefd687SGarrett Wollman /* data + bss can't exceed rlimit */ 117cfefd687SGarrett Wollman a_out->a_data + bss_size > 118cfefd687SGarrett Wollman iparams->proc->p_rlimit[RLIMIT_DATA].rlim_cur) 119cfefd687SGarrett Wollman return (ENOMEM); 120cfefd687SGarrett Wollman 121cfefd687SGarrett Wollman /* copy in arguments and/or environment from old process */ 122cfefd687SGarrett Wollman error = exec_extract_strings(iparams); 123cfefd687SGarrett Wollman if (error) 124cfefd687SGarrett Wollman return (error); 125cfefd687SGarrett Wollman 126cfefd687SGarrett Wollman /* 127cfefd687SGarrett Wollman * Destroy old process VM and create a new one (with a new stack) 128cfefd687SGarrett Wollman */ 129cfefd687SGarrett Wollman exec_new_vmspace(iparams); 130cfefd687SGarrett Wollman 131cfefd687SGarrett Wollman /* 132cfefd687SGarrett Wollman * Map text read/execute 133cfefd687SGarrett Wollman */ 134cfefd687SGarrett Wollman vmaddr = virtual_offset; 135cfefd687SGarrett Wollman error = 136cfefd687SGarrett Wollman vm_mmap(&vmspace->vm_map, /* map */ 137cfefd687SGarrett Wollman &vmaddr, /* address */ 138cfefd687SGarrett Wollman a_out->a_text, /* size */ 139cfefd687SGarrett Wollman VM_PROT_READ | VM_PROT_EXECUTE, /* protection */ 1408de7809aSDavid Greenman VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_WRITE, /* max protection */ 14126f9a767SRodney W. Grimes MAP_PRIVATE | MAP_FIXED, /* flags */ 14226f9a767SRodney W. Grimes (caddr_t)iparams->vnodep, /* vnode */ 143cfefd687SGarrett Wollman file_offset); /* offset */ 144cfefd687SGarrett Wollman if (error) 145cfefd687SGarrett Wollman return (error); 146cfefd687SGarrett Wollman 147cfefd687SGarrett Wollman /* 148cfefd687SGarrett Wollman * Map data read/write (if text is 0, assume text is in data area 149cfefd687SGarrett Wollman * [Bill's screwball mode]) 150cfefd687SGarrett Wollman */ 151cfefd687SGarrett Wollman vmaddr = virtual_offset + a_out->a_text; 152cfefd687SGarrett Wollman error = 153cfefd687SGarrett Wollman vm_mmap(&vmspace->vm_map, 154cfefd687SGarrett Wollman &vmaddr, 155cfefd687SGarrett Wollman a_out->a_data, 156cfefd687SGarrett Wollman VM_PROT_READ | VM_PROT_WRITE | (a_out->a_text ? 0 : VM_PROT_EXECUTE), 15726f9a767SRodney W. Grimes VM_PROT_ALL, MAP_PRIVATE | MAP_FIXED, 15826f9a767SRodney W. Grimes (caddr_t) iparams->vnodep, 159cfefd687SGarrett Wollman file_offset + a_out->a_text); 160cfefd687SGarrett Wollman if (error) 161cfefd687SGarrett Wollman return (error); 162cfefd687SGarrett Wollman 163cfefd687SGarrett Wollman /* 164cfefd687SGarrett Wollman * Allocate demand-zeroed area for uninitialized data 165cfefd687SGarrett Wollman * "bss" = 'block started by symbol' - named after the IBM 7090 166cfefd687SGarrett Wollman * instruction of the same name. 167cfefd687SGarrett Wollman */ 168cfefd687SGarrett Wollman vmaddr = virtual_offset + a_out->a_text + a_out->a_data; 169cfefd687SGarrett Wollman error = vm_allocate(&vmspace->vm_map, &vmaddr, bss_size, FALSE); 170cfefd687SGarrett Wollman if (error) 171cfefd687SGarrett Wollman return (error); 172cfefd687SGarrett Wollman 173cfefd687SGarrett Wollman /* Fill in process VM information */ 174cfefd687SGarrett Wollman vmspace->vm_tsize = a_out->a_text >> PAGE_SHIFT; 175cfefd687SGarrett Wollman vmspace->vm_dsize = (a_out->a_data + bss_size) >> PAGE_SHIFT; 176cfefd687SGarrett Wollman vmspace->vm_taddr = (caddr_t) virtual_offset; 177cfefd687SGarrett Wollman vmspace->vm_daddr = (caddr_t) virtual_offset + a_out->a_text; 178cfefd687SGarrett Wollman 179cfefd687SGarrett Wollman /* Fill in image_params */ 180cfefd687SGarrett Wollman iparams->interpreted = 0; 181cfefd687SGarrett Wollman iparams->entry_addr = a_out->a_entry; 182cfefd687SGarrett Wollman 183f3f0ca60SSøren Schmidt iparams->proc->p_sysent = &aout_sysvec; 184cfefd687SGarrett Wollman return (0); 185cfefd687SGarrett Wollman } 18692d91f76SGarrett Wollman 18792d91f76SGarrett Wollman /* 18892d91f76SGarrett Wollman * Tell kern_execve.c about it, with a little help from the linker. 18992d91f76SGarrett Wollman * Since `const' objects end up in the text segment, TEXT_SET is the 19092d91f76SGarrett Wollman * correct directive to use. 19192d91f76SGarrett Wollman */ 192f23b4c91SGarrett Wollman static const struct execsw aout_execsw = { exec_aout_imgact, "a.out" }; 19392d91f76SGarrett Wollman TEXT_SET(execsw_set, aout_execsw); 19492d91f76SGarrett Wollman 195