Annotation of sys/compat/hpux/m68k/hpux_exec.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: hpux_exec.c,v 1.2 2005/12/30 19:46:55 miod Exp $ */
! 2: /* $NetBSD: hpux_exec.c,v 1.8 1997/03/16 10:14:44 thorpej Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1995, 1997 Jason R. Thorpe. All rights reserved.
! 6: * Copyright (c) 1993, 1994 Christopher G. Demetriou
! 7: *
! 8: * Redistribution and use in source and binary forms, with or without
! 9: * modification, are permitted provided that the following conditions
! 10: * are met:
! 11: * 1. Redistributions of source code must retain the above copyright
! 12: * notice, this list of conditions and the following disclaimer.
! 13: * 2. Redistributions in binary form must reproduce the above copyright
! 14: * notice, this list of conditions and the following disclaimer in the
! 15: * documentation and/or other materials provided with the distribution.
! 16: * 3. All advertising materials mentioning features or use of this software
! 17: * This product includes software developed by Christopher G. Demetriou.
! 18: * 4. The name of the author may not be used to endorse or promote products
! 19: * derived from this software without specific prior written permission
! 20: *
! 21: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 22: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 23: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 24: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 25: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 26: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 27: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 28: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 29: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 30: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 31: */
! 32:
! 33: /*
! 34: * Glue for exec'ing HP-UX executables and the HP-UX execv() system call.
! 35: * Based on sys/kern/exec_aout.c
! 36: */
! 37:
! 38: #include <sys/param.h>
! 39: #include <sys/systm.h>
! 40: #include <sys/kernel.h>
! 41: #include <sys/proc.h>
! 42: #include <sys/malloc.h>
! 43: #include <sys/mount.h>
! 44: #include <sys/namei.h>
! 45: #include <sys/user.h>
! 46: #include <sys/vnode.h>
! 47: #include <sys/mman.h>
! 48: #include <sys/stat.h>
! 49:
! 50: #include <uvm/uvm_extern.h>
! 51:
! 52: #include <machine/cpu.h>
! 53: #include <machine/reg.h>
! 54:
! 55: #include <sys/syscallargs.h>
! 56:
! 57: #include <compat/hpux/hpux.h>
! 58: #include <compat/hpux/hpux_util.h>
! 59: #include <compat/hpux/m68k/hpux_syscall.h>
! 60: #include <compat/hpux/m68k/hpux_syscallargs.h>
! 61:
! 62: #include <machine/hpux_machdep.h>
! 63:
! 64: const char hpux_emul_path[] = "/emul/hpux";
! 65: extern char sigcode[], esigcode[];
! 66: extern struct sysent hpux_sysent[];
! 67: #ifdef SYSCALL_DEBUG
! 68: extern char *hpux_syscallnames[];
! 69: #endif
! 70: extern int bsdtohpuxerrnomap[];
! 71:
! 72: static int exec_hpux_prep_nmagic(struct proc *, struct exec_package *);
! 73: static int exec_hpux_prep_zmagic(struct proc *, struct exec_package *);
! 74: static int exec_hpux_prep_omagic(struct proc *, struct exec_package *);
! 75:
! 76: struct emul emul_hpux = {
! 77: "hpux",
! 78: bsdtohpuxerrnomap,
! 79: hpux_sendsig,
! 80: HPUX_SYS_syscall,
! 81: HPUX_SYS_MAXSYSCALL,
! 82: hpux_sysent,
! 83: #ifdef SYSCALL_DEBUG
! 84: hpux_syscallnames,
! 85: #else
! 86: NULL,
! 87: #endif
! 88: 0,
! 89: copyargs,
! 90: hpux_setregs,
! 91: NULL,
! 92: sigcode,
! 93: esigcode,
! 94: };
! 95:
! 96: int
! 97: exec_hpux_makecmds(p, epp)
! 98: struct proc *p;
! 99: struct exec_package *epp;
! 100: {
! 101: struct hpux_exec *hpux_ep = epp->ep_hdr;
! 102: short sysid, magic;
! 103: int error = ENOEXEC;
! 104:
! 105: if (epp->ep_hdrvalid < sizeof(struct hpux_exec))
! 106: return (ENOEXEC);
! 107:
! 108: magic = HPUX_MAGIC(hpux_ep);
! 109: sysid = HPUX_SYSID(hpux_ep);
! 110:
! 111: if (sysid != MID_HPUX)
! 112: return (ENOEXEC);
! 113:
! 114: /*
! 115: * HP-UX is a 4k page size system, and executables assume
! 116: * this.
! 117: */
! 118: if (PAGE_SIZE != HPUX_LDPGSZ)
! 119: return (ENOEXEC);
! 120:
! 121: switch (magic) {
! 122: case OMAGIC:
! 123: error = exec_hpux_prep_omagic(p, epp);
! 124: break;
! 125:
! 126: case NMAGIC:
! 127: error = exec_hpux_prep_nmagic(p, epp);
! 128: break;
! 129:
! 130: case ZMAGIC:
! 131: error = exec_hpux_prep_zmagic(p, epp);
! 132: break;
! 133: }
! 134:
! 135: if (error == 0) {
! 136: /* set up our emulation information */
! 137: epp->ep_emul = &emul_hpux;
! 138: } else
! 139: kill_vmcmds(&epp->ep_vmcmds);
! 140:
! 141: return (error);
! 142: }
! 143:
! 144: static int
! 145: exec_hpux_prep_nmagic(p, epp)
! 146: struct proc *p;
! 147: struct exec_package *epp;
! 148: {
! 149: struct hpux_exec *execp = epp->ep_hdr;
! 150: long bsize, baddr;
! 151:
! 152: epp->ep_taddr = 0;
! 153: epp->ep_tsize = execp->ha_text;
! 154: epp->ep_daddr = epp->ep_taddr + roundup(execp->ha_text, HPUX_LDPGSZ);
! 155: epp->ep_dsize = execp->ha_data + execp->ha_bss;
! 156: epp->ep_entry = execp->ha_entry;
! 157:
! 158: /* set up command for text segment */
! 159: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, execp->ha_text,
! 160: epp->ep_taddr, epp->ep_vp, HPUX_TXTOFF(*execp, NMAGIC),
! 161: VM_PROT_READ|VM_PROT_EXECUTE);
! 162:
! 163: /* set up command for data segment */
! 164: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn, execp->ha_data,
! 165: epp->ep_daddr, epp->ep_vp, HPUX_DATAOFF(*execp, NMAGIC),
! 166: VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
! 167:
! 168: /* set up command for bss segment */
! 169: baddr = round_page(epp->ep_daddr + execp->ha_data);
! 170: bsize = epp->ep_daddr + epp->ep_dsize - baddr;
! 171: if (bsize > 0)
! 172: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, bsize, baddr,
! 173: NULLVP, 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
! 174:
! 175: return (exec_setup_stack(p, epp));
! 176: }
! 177:
! 178: static int
! 179: exec_hpux_prep_zmagic(p, epp)
! 180: struct proc *p;
! 181: struct exec_package *epp;
! 182: {
! 183: struct hpux_exec *execp = epp->ep_hdr;
! 184: long bsize, baddr;
! 185: long nontext;
! 186:
! 187: /*
! 188: * Check if vnode is in open for writing, because we want to
! 189: * demand-page out of it. If it is, don't do it, for various
! 190: * reasons.
! 191: */
! 192: if ((execp->ha_text != 0 || execp->ha_data != 0) &&
! 193: epp->ep_vp->v_writecount != 0)
! 194: return (ETXTBSY);
! 195: vn_marktext(epp->ep_vp);
! 196:
! 197: /*
! 198: * HP-UX ZMAGIC executables need to have their segment
! 199: * sizes frobbed.
! 200: */
! 201: nontext = execp->ha_data + execp->ha_bss;
! 202: execp->ha_text = ctob(btoc(execp->ha_text));
! 203: execp->ha_data = ctob(btoc(execp->ha_data));
! 204: execp->ha_bss = nontext - execp->ha_data;
! 205: if (execp->ha_bss < 0)
! 206: execp->ha_bss = 0;
! 207:
! 208: epp->ep_taddr = 0;
! 209: epp->ep_tsize = execp->ha_text;
! 210: epp->ep_daddr = epp->ep_taddr + roundup(execp->ha_text, HPUX_LDPGSZ);
! 211: epp->ep_dsize = execp->ha_data + execp->ha_bss;
! 212: epp->ep_entry = execp->ha_entry;
! 213:
! 214: /* set up command for text segment */
! 215: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->ha_text,
! 216: epp->ep_taddr, epp->ep_vp, HPUX_TXTOFF(*execp, ZMAGIC),
! 217: VM_PROT_READ|VM_PROT_EXECUTE);
! 218:
! 219: /* set up command for data segment */
! 220: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->ha_data,
! 221: epp->ep_daddr, epp->ep_vp, HPUX_DATAOFF(*execp, ZMAGIC),
! 222: VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
! 223:
! 224: /* set up command for bss segment */
! 225: baddr = round_page(epp->ep_daddr + execp->ha_data);
! 226: bsize = epp->ep_daddr + epp->ep_dsize - baddr;
! 227: if (bsize > 0)
! 228: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, bsize, baddr,
! 229: NULLVP, 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
! 230:
! 231: return (exec_setup_stack(p, epp));
! 232: }
! 233:
! 234: /*
! 235: * HP-UX's version of OMAGIC.
! 236: */
! 237: static int
! 238: exec_hpux_prep_omagic(p, epp)
! 239: struct proc *p;
! 240: struct exec_package *epp;
! 241: {
! 242: struct hpux_exec *execp = epp->ep_hdr;
! 243: long dsize, bsize, baddr;
! 244:
! 245: epp->ep_taddr = 0;
! 246: epp->ep_tsize = execp->ha_text;
! 247: epp->ep_daddr = epp->ep_taddr + roundup(execp->ha_text, HPUX_LDPGSZ);
! 248: epp->ep_dsize = execp->ha_data + execp->ha_bss;
! 249: epp->ep_entry = execp->ha_entry;
! 250:
! 251: /* set up command for text and data segments */
! 252: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_readvn,
! 253: execp->ha_text + execp->ha_data, epp->ep_taddr, epp->ep_vp,
! 254: HPUX_TXTOFF(*execp, OMAGIC),
! 255: VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
! 256:
! 257: /* set up command for bss segment */
! 258: baddr = round_page(epp->ep_daddr + execp->ha_data);
! 259: bsize = epp->ep_daddr + epp->ep_dsize - baddr;
! 260: if (bsize > 0)
! 261: NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, bsize, baddr,
! 262: NULLVP, 0, VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
! 263:
! 264: /*
! 265: * Make sure (# of pages) mapped above equals (vm_tsize + vm_dsize);
! 266: * obreak(2) relies on this fact. Both `vm_tsize' and `vm_dsize' are
! 267: * computed (in execve(2)) by rounding *up* `ep_tsize' and `ep_dsize'
! 268: * respectively to page boundaries.
! 269: * Compensate `ep_dsize' for the amount of data covered by the last
! 270: * text page.
! 271: */
! 272: dsize = epp->ep_dsize + execp->ha_text - round_page(execp->ha_text);
! 273: epp->ep_dsize = (dsize > 0) ? dsize : 0;
! 274: return (exec_setup_stack(p, epp));
! 275: }
! 276:
! 277: /*
! 278: * The HP-UX execv(2) system call.
! 279: *
! 280: * Just check the alternate emulation path, and pass it on to the NetBSD
! 281: * execve().
! 282: */
! 283: int
! 284: hpux_sys_execv(p, v, retval)
! 285: struct proc *p;
! 286: void *v;
! 287: register_t *retval;
! 288: {
! 289: struct hpux_sys_execv_args /* {
! 290: syscallarg(char *) path;
! 291: syscallarg(char **) argv;
! 292: } */ *uap = v;
! 293: struct sys_execve_args ap;
! 294: caddr_t sg;
! 295:
! 296: sg = stackgap_init(p->p_emul);
! 297: HPUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
! 298:
! 299: SCARG(&ap, path) = SCARG(uap, path);
! 300: SCARG(&ap, argp) = SCARG(uap, argp);
! 301: SCARG(&ap, envp) = NULL;
! 302:
! 303: return sys_execve(p, &ap, retval);
! 304: }
! 305:
! 306: int
! 307: hpux_sys_execve(p, v, retval)
! 308: struct proc *p;
! 309: void *v;
! 310: register_t *retval;
! 311: {
! 312: struct hpux_sys_execve_args /* {
! 313: syscallarg(char *) path;
! 314: syscallarg(char **) argv;
! 315: syscallarg(char **) envp;
! 316: } */ *uap = v;
! 317: struct sys_execve_args ap;
! 318: caddr_t sg;
! 319:
! 320: sg = stackgap_init(p->p_emul);
! 321: HPUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
! 322:
! 323: SCARG(&ap, path) = SCARG(uap, path);
! 324: SCARG(&ap, argp) = SCARG(uap, argp);
! 325: SCARG(&ap, envp) = SCARG(uap, envp);
! 326:
! 327: return (sys_execve(p, &ap, retval));
! 328: }
CVSweb