sunos_exec.c revision 1.1
1/* 2 * Copyright (c) 1993 Theo de Raadt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software withough specific prior written permission 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 * $Id: sunos_exec.c,v 1.1 1993/11/28 18:03:19 deraadt Exp $ 28 */ 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/filedesc.h> 33#include <sys/kernel.h> 34#include <sys/proc.h> 35#include <sys/mount.h> 36#include <sys/malloc.h> 37#include <sys/namei.h> 38#include <sys/vnode.h> 39#include <sys/file.h> 40#include <sys/exec.h> 41#include <sys/resourcevar.h> 42#include <sys/wait.h> 43 44#include <sys/mman.h> 45#include <vm/vm.h> 46#include <vm/vm_param.h> 47#include <vm/vm_map.h> 48#include <vm/vm_kern.h> 49#include <vm/vm_pager.h> 50 51#include <machine/cpu.h> 52#include <machine/reg.h> 53#include <machine/exec.h> 54 55#include <compat/sunos/exec.h> 56 57#ifdef sparc 58#define sun_exec_aout_prep_zmagic exec_aout_prep_zmagic 59#define sun_exec_aout_prep_nmagic exec_aout_prep_nmagic 60#define sun_exec_aout_prep_omagic exec_aout_prep_omagic 61#endif 62 63int 64sun_exec_aout_makecmds(p, epp) 65 struct proc *p; 66 struct exec_package *epp; 67{ 68 struct sun_exec *sunmag; 69 70 sunmag = (struct sun_exec *)epp->ep_execp; 71 if(sunmag->a_machtype != SUN_M_NATIVE) 72 return (ENOEXEC); 73 74 epp->ep_emul = EMUL_SUNOS; 75 switch (sunmag->a_magic) { 76 case ZMAGIC: 77 return sun_exec_aout_prep_zmagic(p, epp); 78 case NMAGIC: 79 return sun_exec_aout_prep_nmagic(p, epp); 80 case OMAGIC: 81 return sun_exec_aout_prep_omagic(p, epp); 82 default: 83 break; 84 } 85 return (ENOEXEC); 86} 87 88/* 89 * the code below is only needed for sun3 emulation. 90 */ 91#ifndef sparc 92 93/* suns keep data seg aligned to SEGSIZ because of sun custom mmu */ 94#define SEGSIZ 0x20000 95#define N_TXTADDR(x,m) __LDPGSZ 96#define N_DATADDR(x,m) (((m)==OMAGIC) ? (N_TXTADDR(x,m) + (x).a_text) \ 97 : (SEGSIZ + ((N_TXTADDR(x,m) + (x).a_text - 1) \ 98 & ~(SEGSIZ-1)))) 99#define N_BSSADDR(x,m) (N_DATADDR(x,m)+(x).a_data) 100 101#define N_TXTOFF(x,m) ((m)==ZMAGIC ? 0 : sizeof (struct exec)) 102#define N_DATOFF(x,m) (N_TXTOFF(x,m) + (x).a_text) 103 104/* 105 * sun_exec_aout_prep_zmagic(): Prepare a SunOS ZMAGIC binary's exec package 106 * 107 * First, set of the various offsets/lengths in the exec package. 108 * 109 * Then, mark the text image busy (so it can be demand paged) or error 110 * out if this is not possible. Finally, set up vmcmds for the 111 * text, data, bss, and stack segments. 112 */ 113int 114sun_exec_aout_prep_zmagic(p, epp) 115 struct proc *p; 116 struct exec_package *epp; 117{ 118 struct exec *execp = epp->ep_execp; 119 struct exec_vmcmd *ccmdp; 120 121 epp->ep_taddr = N_TXTADDR(*execp, ZMAGIC); 122 epp->ep_tsize = execp->a_text; 123 epp->ep_daddr = N_DATADDR(*execp, ZMAGIC); 124 epp->ep_dsize = execp->a_data + execp->a_bss; 125 epp->ep_entry = execp->a_entry; 126 127 /* 128 * check if vnode is in open for writing, because we want to 129 * demand-page out of it. if it is, don't do it, for various 130 * reasons 131 */ 132 if ((execp->a_text != 0 || execp->a_data != 0) && 133 (epp->ep_vp->v_flag & VTEXT) == 0 && epp->ep_vp->v_writecount != 0) { 134#ifdef DIAGNOSTIC 135 if (epp->ep_vp->v_flag & VTEXT) 136 panic("exec: a VTEXT vnode has writecount != 0\n"); 137#endif 138 epp->ep_vcp = NULL; 139 return ETXTBSY; 140 } 141 epp->ep_vp->v_flag |= VTEXT; 142 143 /* set up command for text segment */ 144 epp->ep_vcp = new_vmcmd(vmcmd_map_pagedvn, 145 execp->a_text, 146 epp->ep_taddr, 147 epp->ep_vp, 148 N_TXTOFF(*execp, ZMAGIC), 149 VM_PROT_READ | VM_PROT_EXECUTE); 150 ccmdp = epp->ep_vcp; 151 152 /* set up command for data segment */ 153 ccmdp->ev_next = new_vmcmd(vmcmd_map_pagedvn, 154 execp->a_data, 155 epp->ep_daddr, 156 epp->ep_vp, 157 N_DATOFF(*execp, ZMAGIC), 158 VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE); 159 ccmdp = ccmdp->ev_next; 160 161 /* set up command for bss segment */ 162 ccmdp->ev_next = new_vmcmd(vmcmd_map_zero, 163 execp->a_bss, 164 epp->ep_daddr + execp->a_data, 165 0, 166 0, 167 VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE); 168 ccmdp = ccmdp->ev_next; 169 170 return exec_aout_setup_stack(p, epp, ccmdp); 171} 172 173/* 174 * sun_exec_aout_prep_nmagic(): Prepare a SunOS NMAGIC binary's exec package 175 */ 176int 177sun_exec_aout_prep_nmagic(p, epp) 178 struct proc *p; 179 struct exec_package *epp; 180{ 181 struct exec *execp = epp->ep_execp; 182 struct exec_vmcmd *ccmdp; 183 long bsize, baddr; 184 185 epp->ep_taddr = N_TXTADDR(*execp, NMAGIC); 186 epp->ep_tsize = execp->a_text; 187 epp->ep_daddr = N_DATADDR(*execp, NMAGIC); 188 epp->ep_dsize = execp->a_data + execp->a_bss; 189 epp->ep_entry = execp->a_entry; 190 191 /* set up command for text segment */ 192 epp->ep_vcp = new_vmcmd(vmcmd_map_readvn, 193 execp->a_text, 194 epp->ep_taddr, 195 epp->ep_vp, 196 N_TXTOFF(*execp, NMAGIC), 197 VM_PROT_READ | VM_PROT_EXECUTE); 198 ccmdp = epp->ep_vcp; 199 200 /* set up command for data segment */ 201 ccmdp->ev_next = new_vmcmd(vmcmd_map_readvn, 202 execp->a_data, 203 epp->ep_daddr, 204 epp->ep_vp, 205 N_DATOFF(*execp, NMAGIC), 206 VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE); 207 ccmdp = ccmdp->ev_next; 208 209 /* set up command for bss segment */ 210 baddr = roundup(epp->ep_daddr + execp->a_data, NBPG); 211 bsize = epp->ep_daddr + epp->ep_dsize - baddr; 212 if (bsize > 0) { 213 ccmdp->ev_next = new_vmcmd(vmcmd_map_zero, bsize, baddr, 214 0, 0, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE); 215 ccmdp = ccmdp->ev_next; 216 } 217 218 return exec_aout_setup_stack(p, epp, ccmdp); 219} 220 221/* 222 * sun_exec_aout_prep_omagic(): Prepare a SunOS OMAGIC binary's exec package 223 */ 224int 225sun_exec_aout_prep_omagic(p, epp) 226 struct proc *p; 227 struct exec_package *epp; 228{ 229 struct exec *execp = epp->ep_execp; 230 struct exec_vmcmd *ccmdp; 231 long bsize, baddr; 232 233 epp->ep_taddr = N_TXTADDR(*execp, OMAGIC); 234 epp->ep_tsize = execp->a_text; 235 epp->ep_daddr = N_DATADDR(*execp, OMAGIC); 236 epp->ep_dsize = execp->a_data + execp->a_bss; 237 epp->ep_entry = execp->a_entry; 238 239 /* set up command for text and data segments */ 240 epp->ep_vcp = new_vmcmd(vmcmd_map_readvn, 241 execp->a_text + execp->a_data, 242 epp->ep_taddr, 243 epp->ep_vp, 244 N_TXTOFF(*execp, OMAGIC), 245 VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE); 246 ccmdp = epp->ep_vcp; 247 248 /* set up command for bss segment */ 249 baddr = roundup(epp->ep_daddr + execp->a_data, __LDPGSZ); 250 bsize = epp->ep_daddr + epp->ep_dsize - baddr; 251 if (bsize > 0) { 252 ccmdp->ev_next = new_vmcmd(vmcmd_map_zero, bsize, baddr, 253 0, 0, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE); 254 ccmdp = ccmdp->ev_next; 255 } 256 257 return exec_aout_setup_stack(p, epp, ccmdp); 258} 259#endif /* !sparc */ 260