1 1.19 maxv /* $NetBSD: sunos_exec_aout.c,v 1.19 2015/10/18 16:59:19 maxv Exp $ */ 2 1.1 jdolecek 3 1.1 jdolecek /* 4 1.1 jdolecek * Copyright (c) 1993 Theo de Raadt 5 1.1 jdolecek * All rights reserved. 6 1.1 jdolecek * 7 1.1 jdolecek * Redistribution and use in source and binary forms, with or without 8 1.1 jdolecek * modification, are permitted provided that the following conditions 9 1.1 jdolecek * are met: 10 1.1 jdolecek * 1. Redistributions of source code must retain the above copyright 11 1.1 jdolecek * notice, this list of conditions and the following disclaimer. 12 1.1 jdolecek * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 jdolecek * notice, this list of conditions and the following disclaimer in the 14 1.1 jdolecek * documentation and/or other materials provided with the distribution. 15 1.1 jdolecek * 3. The name of the author may not be used to endorse or promote products 16 1.1 jdolecek * derived from this software without specific prior written permission 17 1.1 jdolecek * 18 1.1 jdolecek * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 1.1 jdolecek * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 1.1 jdolecek * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 1.1 jdolecek * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 1.1 jdolecek * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 1.1 jdolecek * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 1.1 jdolecek * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 1.1 jdolecek * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 1.1 jdolecek * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 1.1 jdolecek * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 1.1 jdolecek */ 29 1.3 lukem 30 1.3 lukem #include <sys/cdefs.h> 31 1.19 maxv __KERNEL_RCSID(0, "$NetBSD: sunos_exec_aout.c,v 1.19 2015/10/18 16:59:19 maxv Exp $"); 32 1.1 jdolecek 33 1.1 jdolecek #include <sys/param.h> 34 1.1 jdolecek #include <sys/systm.h> 35 1.1 jdolecek #include <sys/filedesc.h> 36 1.1 jdolecek #include <sys/kernel.h> 37 1.1 jdolecek #include <sys/proc.h> 38 1.1 jdolecek #include <sys/mount.h> 39 1.1 jdolecek #include <sys/malloc.h> 40 1.1 jdolecek #include <sys/namei.h> 41 1.1 jdolecek #include <sys/signalvar.h> 42 1.1 jdolecek #include <sys/vnode.h> 43 1.1 jdolecek #include <sys/file.h> 44 1.1 jdolecek #include <sys/exec.h> 45 1.18 matt #include <sys/exec_aout.h> 46 1.1 jdolecek #include <sys/resourcevar.h> 47 1.1 jdolecek #include <sys/wait.h> 48 1.1 jdolecek 49 1.1 jdolecek #include <sys/mman.h> 50 1.1 jdolecek 51 1.15 ad #include <sys/cpu.h> 52 1.1 jdolecek #include <machine/reg.h> 53 1.1 jdolecek 54 1.1 jdolecek #include <compat/sunos/sunos.h> 55 1.1 jdolecek #include <compat/sunos/sunos_exec.h> 56 1.1 jdolecek #include <compat/sunos/sunos_syscall.h> 57 1.1 jdolecek 58 1.1 jdolecek #ifdef __sparc__ 59 1.1 jdolecek #define sunos_exec_aout_prep_zmagic exec_aout_prep_zmagic 60 1.1 jdolecek #define sunos_exec_aout_prep_nmagic exec_aout_prep_nmagic 61 1.1 jdolecek #define sunos_exec_aout_prep_omagic exec_aout_prep_omagic 62 1.1 jdolecek #endif 63 1.1 jdolecek 64 1.16 dsl int sunos_exec_aout_prep_zmagic(struct lwp *, struct exec_package *); 65 1.16 dsl int sunos_exec_aout_prep_nmagic(struct lwp *, struct exec_package *); 66 1.16 dsl int sunos_exec_aout_prep_omagic(struct lwp *, struct exec_package *); 67 1.1 jdolecek 68 1.1 jdolecek int 69 1.17 dsl exec_sunos_aout_makecmds(struct lwp *l, struct exec_package *epp) 70 1.1 jdolecek { 71 1.1 jdolecek struct sunos_exec *sunmag = epp->ep_hdr; 72 1.1 jdolecek int error = ENOEXEC; 73 1.1 jdolecek 74 1.19 maxv if (epp->ep_hdrvalid < sizeof(struct sunos_exec)) 75 1.19 maxv return ENOEXEC; 76 1.4 fredette if (!SUNOS_M_NATIVE(sunmag->a_machtype)) 77 1.1 jdolecek return (ENOEXEC); 78 1.1 jdolecek 79 1.1 jdolecek switch (sunmag->a_magic) { 80 1.1 jdolecek case ZMAGIC: 81 1.14 christos error = sunos_exec_aout_prep_zmagic(l, epp); 82 1.1 jdolecek break; 83 1.1 jdolecek case NMAGIC: 84 1.14 christos error = sunos_exec_aout_prep_nmagic(l, epp); 85 1.1 jdolecek break; 86 1.1 jdolecek case OMAGIC: 87 1.14 christos error = sunos_exec_aout_prep_omagic(l, epp); 88 1.1 jdolecek break; 89 1.1 jdolecek } 90 1.1 jdolecek return error; 91 1.1 jdolecek } 92 1.1 jdolecek 93 1.1 jdolecek /* 94 1.4 fredette * the code below is only needed for sun2/sun3 emulation. 95 1.1 jdolecek */ 96 1.1 jdolecek #ifndef __sparc__ 97 1.1 jdolecek 98 1.1 jdolecek /* suns keep data seg aligned to SEGSIZ because of sun custom mmu */ 99 1.1 jdolecek #define SEGSIZ 0x20000 100 1.4 fredette #define SUNOS_N_TXTADDR(x,m) 0x2000 101 1.1 jdolecek #define SUNOS_N_DATADDR(x,m) (((m)==OMAGIC) ? \ 102 1.1 jdolecek (SUNOS_N_TXTADDR(x,m) + (x).a_text) : \ 103 1.1 jdolecek (SEGSIZ + ((SUNOS_N_TXTADDR(x,m) + (x).a_text - 1) & ~(SEGSIZ-1)))) 104 1.1 jdolecek #define SUNOS_N_BSSADDR(x,m) (SUNOS_N_DATADDR(x,m)+(x).a_data) 105 1.1 jdolecek 106 1.1 jdolecek #define SUNOS_N_TXTOFF(x,m) ((m)==ZMAGIC ? 0 : sizeof (struct exec)) 107 1.1 jdolecek #define SUNOS_N_DATOFF(x,m) (SUNOS_N_TXTOFF(x,m) + (x).a_text) 108 1.1 jdolecek 109 1.1 jdolecek /* 110 1.1 jdolecek * sunos_exec_aout_prep_zmagic(): Prepare a SunOS ZMAGIC binary's exec package 111 1.1 jdolecek * 112 1.1 jdolecek * First, set of the various offsets/lengths in the exec package. 113 1.1 jdolecek * 114 1.1 jdolecek * Then, mark the text image busy (so it can be demand paged) or error 115 1.1 jdolecek * out if this is not possible. Finally, set up vmcmds for the 116 1.1 jdolecek * text, data, bss, and stack segments. 117 1.1 jdolecek */ 118 1.1 jdolecek int 119 1.17 dsl sunos_exec_aout_prep_zmagic(struct lwp *l, struct exec_package *epp) 120 1.1 jdolecek { 121 1.1 jdolecek struct exec *execp = epp->ep_hdr; 122 1.6 chs int error; 123 1.1 jdolecek 124 1.1 jdolecek epp->ep_taddr = SUNOS_N_TXTADDR(*execp, ZMAGIC); 125 1.1 jdolecek epp->ep_tsize = execp->a_text; 126 1.1 jdolecek epp->ep_daddr = SUNOS_N_DATADDR(*execp, ZMAGIC); 127 1.1 jdolecek epp->ep_dsize = execp->a_data + execp->a_bss; 128 1.1 jdolecek epp->ep_entry = execp->a_entry; 129 1.1 jdolecek 130 1.6 chs error = vn_marktext(epp->ep_vp); 131 1.6 chs if (error) 132 1.6 chs return (error); 133 1.1 jdolecek 134 1.1 jdolecek /* set up command for text segment */ 135 1.1 jdolecek NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->a_text, 136 1.13 perry epp->ep_taddr, epp->ep_vp, SUNOS_N_TXTOFF(*execp, ZMAGIC), 137 1.1 jdolecek VM_PROT_READ|VM_PROT_EXECUTE); 138 1.1 jdolecek 139 1.1 jdolecek /* set up command for data segment */ 140 1.1 jdolecek NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->a_data, 141 1.1 jdolecek epp->ep_daddr, epp->ep_vp, SUNOS_N_DATOFF(*execp, ZMAGIC), 142 1.1 jdolecek VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); 143 1.1 jdolecek 144 1.1 jdolecek /* set up command for bss segment */ 145 1.12 christos if (execp->a_bss) 146 1.12 christos NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, execp->a_bss, 147 1.12 christos epp->ep_daddr + execp->a_data, NULLVP, 0, 148 1.12 christos VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); 149 1.1 jdolecek 150 1.14 christos return (*epp->ep_esch->es_setup_stack)(l, epp); 151 1.1 jdolecek } 152 1.1 jdolecek 153 1.1 jdolecek /* 154 1.1 jdolecek * sunos_exec_aout_prep_nmagic(): Prepare a SunOS NMAGIC binary's exec package 155 1.1 jdolecek */ 156 1.1 jdolecek int 157 1.17 dsl sunos_exec_aout_prep_nmagic(struct lwp *l, struct exec_package *epp) 158 1.1 jdolecek { 159 1.1 jdolecek struct exec *execp = epp->ep_hdr; 160 1.1 jdolecek long bsize, baddr; 161 1.1 jdolecek 162 1.1 jdolecek epp->ep_taddr = SUNOS_N_TXTADDR(*execp, NMAGIC); 163 1.1 jdolecek epp->ep_tsize = execp->a_text; 164 1.1 jdolecek epp->ep_daddr = SUNOS_N_DATADDR(*execp, NMAGIC); 165 1.1 jdolecek epp->ep_dsize = execp->a_data + execp->a_bss; 166 1.1 jdolecek epp->ep_entry = execp->a_entry; 167 1.1 jdolecek 168 1.1 jdolecek /* set up command for text segment */ 169 1.1 jdolecek NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, execp->a_text, 170 1.1 jdolecek epp->ep_taddr, epp->ep_vp, SUNOS_N_TXTOFF(*execp, NMAGIC), 171 1.1 jdolecek VM_PROT_READ|VM_PROT_EXECUTE); 172 1.1 jdolecek 173 1.1 jdolecek /* set up command for data segment */ 174 1.1 jdolecek NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, execp->a_data, 175 1.1 jdolecek epp->ep_daddr, epp->ep_vp, SUNOS_N_DATOFF(*execp, NMAGIC), 176 1.1 jdolecek VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); 177 1.1 jdolecek 178 1.1 jdolecek /* set up command for bss segment */ 179 1.7 thorpej baddr = roundup(epp->ep_daddr + execp->a_data, PAGE_SIZE); 180 1.1 jdolecek bsize = epp->ep_daddr + epp->ep_dsize - baddr; 181 1.1 jdolecek if (bsize > 0) 182 1.1 jdolecek NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, bsize, baddr, 183 1.1 jdolecek NULLVP, 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); 184 1.1 jdolecek 185 1.14 christos return (*epp->ep_esch->es_setup_stack)(l, epp); 186 1.1 jdolecek } 187 1.1 jdolecek 188 1.1 jdolecek /* 189 1.1 jdolecek * sunos_exec_aout_prep_omagic(): Prepare a SunOS OMAGIC binary's exec package 190 1.1 jdolecek */ 191 1.1 jdolecek int 192 1.17 dsl sunos_exec_aout_prep_omagic(struct lwp *l, struct exec_package *epp) 193 1.1 jdolecek { 194 1.1 jdolecek struct exec *execp = epp->ep_hdr; 195 1.1 jdolecek long bsize, baddr; 196 1.1 jdolecek 197 1.1 jdolecek epp->ep_taddr = SUNOS_N_TXTADDR(*execp, OMAGIC); 198 1.1 jdolecek epp->ep_tsize = execp->a_text; 199 1.1 jdolecek epp->ep_daddr = SUNOS_N_DATADDR(*execp, OMAGIC); 200 1.1 jdolecek epp->ep_dsize = execp->a_data + execp->a_bss; 201 1.1 jdolecek epp->ep_entry = execp->a_entry; 202 1.1 jdolecek 203 1.1 jdolecek /* set up command for text and data segments */ 204 1.1 jdolecek NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, 205 1.1 jdolecek execp->a_text + execp->a_data, epp->ep_taddr, epp->ep_vp, 206 1.1 jdolecek SUNOS_N_TXTOFF(*execp, OMAGIC), VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); 207 1.1 jdolecek 208 1.1 jdolecek /* set up command for bss segment */ 209 1.7 thorpej baddr = roundup(epp->ep_daddr + execp->a_data, PAGE_SIZE); 210 1.1 jdolecek bsize = epp->ep_daddr + epp->ep_dsize - baddr; 211 1.1 jdolecek if (bsize > 0) 212 1.1 jdolecek NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, bsize, baddr, 213 1.1 jdolecek NULLVP, 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); 214 1.1 jdolecek 215 1.14 christos return (*epp->ep_esch->es_setup_stack)(l, epp); 216 1.1 jdolecek } 217 1.1 jdolecek #endif /* !sparc */ 218