sunos_exec.c revision 1.11
11.4Sdsl/* $NetBSD: sunos_exec.c,v 1.11 1996/05/05 12:01:47 briggs Exp $ */ 21.1Sthorpej 31.1Sthorpej/* 41.1Sthorpej * Copyright (c) 1993 Theo de Raadt 51.1Sthorpej * All rights reserved. 61.1Sthorpej * 71.1Sthorpej * Redistribution and use in source and binary forms, with or without 81.1Sthorpej * modification, are permitted provided that the following conditions 91.1Sthorpej * are met: 101.1Sthorpej * 1. Redistributions of source code must retain the above copyright 111.1Sthorpej * notice, this list of conditions and the following disclaimer. 121.1Sthorpej * 2. Redistributions in binary form must reproduce the above copyright 131.1Sthorpej * notice, this list of conditions and the following disclaimer in the 141.1Sthorpej * documentation and/or other materials provided with the distribution. 151.1Sthorpej * 3. The name of the author may not be used to endorse or promote products 161.1Sthorpej * derived from this software without specific prior written permission 171.1Sthorpej * 181.1Sthorpej * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 191.1Sthorpej * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 201.1Sthorpej * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 211.1Sthorpej * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 221.1Sthorpej * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 231.1Sthorpej * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 241.1Sthorpej * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 251.1Sthorpej * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 261.1Sthorpej * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 271.1Sthorpej * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 281.1Sthorpej */ 291.1Sthorpej 301.1Sthorpej#include <sys/param.h> 311.1Sthorpej#include <sys/systm.h> 321.1Sthorpej#include <sys/filedesc.h> 331.1Sthorpej#include <sys/kernel.h> 341.1Sthorpej#include <sys/proc.h> 351.1Sthorpej#include <sys/mount.h> 361.1Sthorpej#include <sys/malloc.h> 371.1Sthorpej#include <sys/namei.h> 381.1Sthorpej#include <sys/signalvar.h> 391.1Sthorpej#include <sys/vnode.h> 401.1Sthorpej#include <sys/file.h> 411.1Sthorpej#include <sys/exec.h> 421.1Sthorpej#include <sys/resourcevar.h> 431.1Sthorpej#include <sys/wait.h> 441.1Sthorpej 451.1Sthorpej#include <sys/mman.h> 461.1Sthorpej#include <vm/vm.h> 471.3Schristos#include <vm/vm_param.h> 481.1Sthorpej#include <vm/vm_map.h> 491.1Sthorpej#include <vm/vm_kern.h> 501.1Sthorpej#include <vm/vm_pager.h> 511.1Sthorpej 521.1Sthorpej#include <machine/cpu.h> 531.3Schristos#include <machine/reg.h> 541.1Sthorpej#include <machine/exec.h> 551.1Sthorpej 561.1Sthorpej#include <compat/sunos/exec.h> 571.1Sthorpej#include <compat/sunos/sunos.h> 581.1Sthorpej#include <compat/sunos/sunos_syscall.h> 591.1Sthorpej 601.1Sthorpej#ifdef sparc 611.1Sthorpej#define sunos_exec_aout_prep_zmagic exec_aout_prep_zmagic 621.1Sthorpej#define sunos_exec_aout_prep_nmagic exec_aout_prep_nmagic 631.1Sthorpej#define sunos_exec_aout_prep_omagic exec_aout_prep_omagic 641.1Sthorpej#endif 651.1Sthorpej 661.1Sthorpejint sunos_exec_aout_makecmds __P((struct proc *, struct exec_package *)); 671.1Sthorpejint sunos_exec_aout_prep_zmagic __P((struct proc *, struct exec_package *)); 681.1Sthorpejint sunos_exec_aout_prep_nmagic __P((struct proc *, struct exec_package *)); 691.1Sthorpejint sunos_exec_aout_prep_omagic __P((struct proc *, struct exec_package *)); 701.1Sthorpej 711.1Sthorpejextern int nsunos_sysent; 721.1Sthorpejextern struct sysent sunos_sysent[]; 731.1Sthorpej#ifdef SYSCALL_DEBUG 741.1Sthorpejextern char *sunos_syscallnames[]; 751.1Sthorpej#endif 761.1Sthorpejextern char sigcode[], esigcode[]; 771.1Sthorpejconst char sunos_emul_path[] = "/emul/sunos"; 781.1Sthorpej 791.1Sthorpejstruct emul emul_sunos = { 801.1Sthorpej "sunos", 811.1Sthorpej NULL, 821.1Sthorpej#ifdef sparc 831.1Sthorpej sendsig, 841.1Sthorpej#else 851.1Sthorpej sunos_sendsig, 861.1Sthorpej#endif 871.1Sthorpej SUNOS_SYS_syscall, 881.1Sthorpej SUNOS_SYS_MAXSYSCALL, 891.1Sthorpej sunos_sysent, 901.1Sthorpej#ifdef SYSCALL_DEBUG 911.1Sthorpej sunos_syscallnames, 921.1Sthorpej#else 931.1Sthorpej NULL, 941.1Sthorpej#endif 951.1Sthorpej 0, 961.1Sthorpej copyargs, 971.1Sthorpej setregs, 981.1Sthorpej sigcode, 991.1Sthorpej esigcode, 1001.1Sthorpej}; 1011.1Sthorpej 1021.1Sthorpejint 1031.1Sthorpejsunos_exec_aout_makecmds(p, epp) 1041.1Sthorpej struct proc *p; 1051.1Sthorpej struct exec_package *epp; 1061.1Sthorpej{ 1071.1Sthorpej struct sunos_exec *sunmag = epp->ep_hdr; 1081.1Sthorpej int error = ENOEXEC; 1091.1Sthorpej 1101.1Sthorpej if(sunmag->a_machtype != SUNOS_M_NATIVE) 1111.1Sthorpej return (ENOEXEC); 1121.1Sthorpej 1131.1Sthorpej switch (sunmag->a_magic) { 1141.1Sthorpej case ZMAGIC: 1151.1Sthorpej error = sunos_exec_aout_prep_zmagic(p, epp); 1161.1Sthorpej break; 1171.1Sthorpej case NMAGIC: 1181.1Sthorpej error = sunos_exec_aout_prep_nmagic(p, epp); 1191.1Sthorpej break; 1201.1Sthorpej case OMAGIC: 1211.1Sthorpej error = sunos_exec_aout_prep_omagic(p, epp); 1221.1Sthorpej break; 1231.1Sthorpej } 1241.1Sthorpej if (error==0) 1251.1Sthorpej epp->ep_emul = &emul_sunos; 1261.1Sthorpej return error; 1271.1Sthorpej} 1281.1Sthorpej 1291.1Sthorpej/* 1301.1Sthorpej * the code below is only needed for sun3 emulation. 1311.1Sthorpej */ 1321.1Sthorpej#ifndef sparc 1331.1Sthorpej 1341.1Sthorpej/* suns keep data seg aligned to SEGSIZ because of sun custom mmu */ 1351.1Sthorpej#define SEGSIZ 0x20000 1361.1Sthorpej#define SUNOS_N_TXTADDR(x,m) __LDPGSZ 1371.1Sthorpej#define SUNOS_N_DATADDR(x,m) (((m)==OMAGIC) ? \ 1381.1Sthorpej (SUNOS_N_TXTADDR(x,m) + (x).a_text) : \ 1391.1Sthorpej (SEGSIZ + ((SUNOS_N_TXTADDR(x,m) + (x).a_text - 1) & ~(SEGSIZ-1)))) 1401.1Sthorpej#define SUNOS_N_BSSADDR(x,m) (SUNOS_N_DATADDR(x,m)+(x).a_data) 1411.1Sthorpej 1421.1Sthorpej#define SUNOS_N_TXTOFF(x,m) ((m)==ZMAGIC ? 0 : sizeof (struct exec)) 1431.1Sthorpej#define SUNOS_N_DATOFF(x,m) (SUNOS_N_TXTOFF(x,m) + (x).a_text) 1441.1Sthorpej 1451.1Sthorpej/* 1461.1Sthorpej * sunos_exec_aout_prep_zmagic(): Prepare a SunOS ZMAGIC binary's exec package 1471.1Sthorpej * 1481.1Sthorpej * First, set of the various offsets/lengths in the exec package. 1491.1Sthorpej * 1501.1Sthorpej * Then, mark the text image busy (so it can be demand paged) or error 1511.1Sthorpej * out if this is not possible. Finally, set up vmcmds for the 1521.1Sthorpej * text, data, bss, and stack segments. 1531.1Sthorpej */ 1541.1Sthorpejint 1551.1Sthorpejsunos_exec_aout_prep_zmagic(p, epp) 1561.1Sthorpej struct proc *p; 1571.1Sthorpej struct exec_package *epp; 1581.1Sthorpej{ 1591.1Sthorpej struct exec *execp = epp->ep_hdr; 1601.1Sthorpej 1611.1Sthorpej epp->ep_taddr = SUNOS_N_TXTADDR(*execp, ZMAGIC); 1621.1Sthorpej epp->ep_tsize = execp->a_text; 1631.1Sthorpej epp->ep_daddr = SUNOS_N_DATADDR(*execp, ZMAGIC); 1641.1Sthorpej epp->ep_dsize = execp->a_data + execp->a_bss; 1651.1Sthorpej epp->ep_entry = execp->a_entry; 1661.1Sthorpej 1671.1Sthorpej /* 1681.1Sthorpej * check if vnode is in open for writing, because we want to 1691.1Sthorpej * demand-page out of it. if it is, don't do it, for various 1701.1Sthorpej * reasons 1711.1Sthorpej */ 1721.1Sthorpej if ((execp->a_text != 0 || execp->a_data != 0) && 1731.1Sthorpej epp->ep_vp->v_writecount != 0) { 1741.1Sthorpej#ifdef DIAGNOSTIC 1751.1Sthorpej if (epp->ep_vp->v_flag & VTEXT) 1761.1Sthorpej panic("exec: a VTEXT vnode has writecount != 0\n"); 1771.1Sthorpej#endif 1781.1Sthorpej return ETXTBSY; 1791.1Sthorpej } 1801.1Sthorpej epp->ep_vp->v_flag |= VTEXT; 1811.1Sthorpej 1821.1Sthorpej /* set up command for text segment */ 1831.1Sthorpej NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->a_text, 1841.1Sthorpej epp->ep_taddr, epp->ep_vp, SUNOS_N_TXTOFF(*execp, ZMAGIC), 1851.1Sthorpej VM_PROT_READ|VM_PROT_EXECUTE); 1861.1Sthorpej 1871.1Sthorpej /* set up command for data segment */ 1881.1Sthorpej NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->a_data, 1891.1Sthorpej epp->ep_daddr, epp->ep_vp, SUNOS_N_DATOFF(*execp, ZMAGIC), 1901.1Sthorpej VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); 1911.1Sthorpej 1921.1Sthorpej /* set up command for bss segment */ 1931.1Sthorpej NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, execp->a_bss, 1941.1Sthorpej epp->ep_daddr + execp->a_data, NULLVP, 0, 1951.1Sthorpej VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); 1961.1Sthorpej 1971.1Sthorpej return exec_aout_setup_stack(p, epp); 1981.1Sthorpej} 1991.1Sthorpej 2001.1Sthorpej/* 2011.1Sthorpej * sunos_exec_aout_prep_nmagic(): Prepare a SunOS NMAGIC binary's exec package 2021.1Sthorpej */ 2031.1Sthorpejint 2041.1Sthorpejsunos_exec_aout_prep_nmagic(p, epp) 2051.4Sdsl struct proc *p; 2061.1Sthorpej struct exec_package *epp; 2071.1Sthorpej{ 2081.4Sdsl struct exec *execp = epp->ep_hdr; 2091.4Sdsl long bsize, baddr; 2101.1Sthorpej 2111.4Sdsl epp->ep_taddr = SUNOS_N_TXTADDR(*execp, NMAGIC); 2121.1Sthorpej epp->ep_tsize = execp->a_text; 2131.1Sthorpej epp->ep_daddr = SUNOS_N_DATADDR(*execp, NMAGIC); 2141.1Sthorpej epp->ep_dsize = execp->a_data + execp->a_bss; 2151.1Sthorpej epp->ep_entry = execp->a_entry; 2161.1Sthorpej 2171.1Sthorpej /* set up command for text segment */ 2181.1Sthorpej NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, execp->a_text, 2191.1Sthorpej epp->ep_taddr, epp->ep_vp, SUNOS_N_TXTOFF(*execp, NMAGIC), 2201.1Sthorpej VM_PROT_READ|VM_PROT_EXECUTE); 2211.4Sdsl 2221.1Sthorpej /* set up command for data segment */ 2231.1Sthorpej NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, execp->a_data, 2241.1Sthorpej epp->ep_daddr, epp->ep_vp, SUNOS_N_DATOFF(*execp, NMAGIC), 2251.1Sthorpej VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); 2261.1Sthorpej 2271.1Sthorpej /* set up command for bss segment */ 2281.1Sthorpej baddr = roundup(epp->ep_daddr + execp->a_data, NBPG); 2291.1Sthorpej bsize = epp->ep_daddr + epp->ep_dsize - baddr; 2301.1Sthorpej if (bsize > 0) 2311.1Sthorpej NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, bsize, baddr, 2321.1Sthorpej NULLVP, 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); 2331.1Sthorpej 2341.4Sdsl return exec_aout_setup_stack(p, epp); 2351.1Sthorpej} 2361.1Sthorpej 2371.1Sthorpej/* 2381.1Sthorpej * sunos_exec_aout_prep_omagic(): Prepare a SunOS OMAGIC binary's exec package 2391.1Sthorpej */ 2401.1Sthorpejint 2411.1Sthorpejsunos_exec_aout_prep_omagic(p, epp) 2421.1Sthorpej struct proc *p; 2431.1Sthorpej struct exec_package *epp; 2441.1Sthorpej{ 2451.1Sthorpej struct exec *execp = epp->ep_hdr; 2461.1Sthorpej long bsize, baddr; 2471.1Sthorpej 2481.1Sthorpej epp->ep_taddr = SUNOS_N_TXTADDR(*execp, OMAGIC); 2491.2Scube epp->ep_tsize = execp->a_text; 2501.2Scube epp->ep_daddr = SUNOS_N_DATADDR(*execp, OMAGIC); 2511.2Scube epp->ep_dsize = execp->a_data + execp->a_bss; 2521.2Scube epp->ep_entry = execp->a_entry; 2531.2Scube 2541.2Scube /* set up command for text and data segments */ 2551.2Scube NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, 2561.2Scube execp->a_text + execp->a_data, epp->ep_taddr, epp->ep_vp, 2571.2Scube SUNOS_N_TXTOFF(*execp, OMAGIC), VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); 2581.1Sthorpej 2591.1Sthorpej /* set up command for bss segment */ 2601.1Sthorpej baddr = roundup(epp->ep_daddr + execp->a_data, NBPG); 2611.1Sthorpej bsize = epp->ep_daddr + epp->ep_dsize - baddr; 2621.1Sthorpej if (bsize > 0) 2631.1Sthorpej NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, bsize, baddr, 2641.1Sthorpej NULLVP, 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); 2651.1Sthorpej 2661.1Sthorpej return exec_aout_setup_stack(p, epp); 2671.1Sthorpej} 2681.1Sthorpej#endif /* !sparc */ 2691.1Sthorpej