1 /* $OpenBSD: exec.h,v 1.24 2007/05/26 00:36:03 krw Exp $ */ 2 /* $NetBSD: exec.h,v 1.59 1996/02/09 18:25:09 christos Exp $ */ 3 4 /*- 5 * Copyright (c) 1994 Christopher G. Demetriou 6 * Copyright (c) 1993 Theo de Raadt 7 * Copyright (c) 1992, 1993 8 * The Regents of the University of California. All rights reserved. 9 * (c) UNIX System Laboratories, Inc. 10 * All or some portions of this file are derived from material licensed 11 * to the University of California by American Telephone and Telegraph 12 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 13 * the permission of UNIX System Laboratories, Inc. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 18 * 1. Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in the 22 * documentation and/or other materials provided with the distribution. 23 * 3. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)exec.h 8.3 (Berkeley) 1/21/94 40 */ 41 42 #ifndef _SYS_EXEC_H_ 43 #define _SYS_EXEC_H_ 44 45 /* 46 * The following structure is found at the top of the user stack of each 47 * user process. The ps program uses it to locate argv and environment 48 * strings. Programs that wish ps to display other information may modify 49 * it; normally ps_argvstr points to argv[0], and ps_nargvstr is the same 50 * as the program's argc. The fields ps_envstr and ps_nenvstr are the 51 * equivalent for the environment. 52 */ 53 struct ps_strings { 54 char **ps_argvstr; /* first of 0 or more argument strings */ 55 int ps_nargvstr; /* the number of argument strings */ 56 char **ps_envstr; /* first of 0 or more environment strings */ 57 int ps_nenvstr; /* the number of environment strings */ 58 }; 59 60 /* 61 * Address of ps_strings structure (in user space). 62 */ 63 #ifdef MACHINE_STACK_GROWS_UP 64 #define PS_STRINGS ((struct ps_strings *)(USRSTACK)) 65 #else 66 #define PS_STRINGS \ 67 ((struct ps_strings *)(USRSTACK - sizeof(struct ps_strings))) 68 #endif 69 70 /* 71 * Below the PS_STRINGS and sigtramp, we may require a gap on the stack 72 * (used to copyin/copyout various emulation data structures). 73 */ 74 #define STACKGAPLEN (2*1024) /* plenty enough for now */ 75 76 #ifdef MACHINE_STACK_GROWS_UP 77 #define STACKGAPBASE_UNALIGNED \ 78 ((caddr_t)PS_STRINGS + sizeof(struct ps_strings)) 79 #else 80 #define STACKGAPBASE_UNALIGNED \ 81 ((caddr_t)PS_STRINGS - STACKGAPLEN) 82 #endif 83 #define STACKGAPBASE \ 84 ((caddr_t)ALIGN(STACKGAPBASE_UNALIGNED)) 85 86 /* 87 * the following structures allow execve() to put together processes 88 * in a more extensible and cleaner way. 89 * 90 * the exec_package struct defines an executable being execve()'d. 91 * it contains the header, the vmspace-building commands, the vnode 92 * information, and the arguments associated with the newly-execve'd 93 * process. 94 * 95 * the exec_vmcmd struct defines a command description to be used 96 * in creating the new process's vmspace. 97 */ 98 99 struct proc; 100 struct exec_package; 101 102 typedef int (*exec_makecmds_fcn)(struct proc *, struct exec_package *); 103 104 struct execsw { 105 u_int es_hdrsz; /* size of header for this format */ 106 exec_makecmds_fcn es_check; /* function to check exec format */ 107 struct emul *es_emul; /* emulation */ 108 }; 109 110 struct exec_vmcmd { 111 int (*ev_proc)(struct proc *p, struct exec_vmcmd *cmd); 112 /* procedure to run for region of vmspace */ 113 u_long ev_len; /* length of the segment to map */ 114 u_long ev_addr; /* address in the vmspace to place it at */ 115 struct vnode *ev_vp; /* vnode pointer for the file w/the data */ 116 u_long ev_offset; /* offset in the file for the data */ 117 u_int ev_prot; /* protections for segment */ 118 int ev_flags; 119 #define VMCMD_RELATIVE 0x0001 /* ev_addr is relative to base entry */ 120 #define VMCMD_BASE 0x0002 /* marks a base entry */ 121 }; 122 123 #define EXEC_DEFAULT_VMCMD_SETSIZE 8 /* # of cmds in set to start */ 124 125 /* exec vmspace-creation command set; see below */ 126 struct exec_vmcmd_set { 127 u_int evs_cnt; 128 u_int evs_used; 129 struct exec_vmcmd *evs_cmds; 130 struct exec_vmcmd evs_start[EXEC_DEFAULT_VMCMD_SETSIZE]; 131 }; 132 133 struct exec_package { 134 char *ep_name; /* file's name */ 135 void *ep_hdr; /* file's exec header */ 136 u_int ep_hdrlen; /* length of ep_hdr */ 137 u_int ep_hdrvalid; /* bytes of ep_hdr that are valid */ 138 struct nameidata *ep_ndp; /* namei data pointer for lookups */ 139 struct exec_vmcmd_set ep_vmcmds; /* vmcmds used to build vmspace */ 140 struct vnode *ep_vp; /* executable's vnode */ 141 struct vattr *ep_vap; /* executable's attributes */ 142 u_long ep_taddr; /* process's text address */ 143 u_long ep_tsize; /* size of process's text */ 144 u_long ep_daddr; /* process's data(+bss) address */ 145 u_long ep_dsize; /* size of process's data(+bss) */ 146 u_long ep_maxsaddr; /* proc's max stack addr ("top") */ 147 u_long ep_minsaddr; /* proc's min stack addr ("bottom") */ 148 u_long ep_ssize; /* size of process's stack */ 149 u_long ep_entry; /* process's entry point */ 150 u_int ep_flags; /* flags; see below. */ 151 char **ep_fa; /* a fake args vector for scripts */ 152 int ep_fd; /* a file descriptor we're holding */ 153 struct emul *ep_emul; /* os emulation */ 154 void *ep_emul_arg; /* emulation argument */ 155 void *ep_emul_argp; /* emulation argument pointer */ 156 char *ep_interp; /* name of interpreter if any */ 157 u_long ep_interp_pos; /* interpreter load position */ 158 }; 159 #define EXEC_INDIR 0x0001 /* script handling already done */ 160 #define EXEC_HASFD 0x0002 /* holding a shell script */ 161 #define EXEC_HASARGL 0x0004 /* has fake args vector */ 162 #define EXEC_SKIPARG 0x0008 /* don't copy user-supplied argv[0] */ 163 #define EXEC_DESTR 0x0010 /* destructive ops performed */ 164 165 #ifdef _KERNEL 166 /* 167 * functions used either by execve() or the various cpu-dependent execve() 168 * hooks. 169 */ 170 int exec_makecmds(struct proc *, struct exec_package *); 171 int exec_runcmds(struct proc *, struct exec_package *); 172 void vmcmdset_extend(struct exec_vmcmd_set *); 173 void kill_vmcmds(struct exec_vmcmd_set *evsp); 174 int vmcmd_map_pagedvn(struct proc *, struct exec_vmcmd *); 175 int vmcmd_map_readvn(struct proc *, struct exec_vmcmd *); 176 int vmcmd_map_zero(struct proc *, struct exec_vmcmd *); 177 void *copyargs(struct exec_package *, 178 struct ps_strings *, 179 void *, void *); 180 void setregs(struct proc *, struct exec_package *, 181 u_long, register_t *); 182 int check_exec(struct proc *, struct exec_package *); 183 int exec_setup_stack(struct proc *, struct exec_package *); 184 int exec_process_vmcmds(struct proc *, struct exec_package *); 185 186 #ifdef DEBUG 187 void new_vmcmd(struct exec_vmcmd_set *evsp, 188 int (*proc)(struct proc *p, struct exec_vmcmd *), 189 u_long len, u_long addr, struct vnode *vp, u_long offset, 190 u_int prot, int flags); 191 #define NEW_VMCMD(evsp,proc,len,addr,vp,offset,prot) \ 192 new_vmcmd(evsp,proc,len,addr,vp,offset,prot, 0); 193 #define NEW_VMCMD2(evsp,proc,len,addr,vp,offset,prot,flags) \ 194 new_vmcmd(evsp,proc,len,addr,vp,offset,prot,flags) 195 #else /* DEBUG */ 196 #define NEW_VMCMD(evsp,proc,len,addr,vp,offset,prot) \ 197 NEW_VMCMD2(evsp,proc,len,addr,vp,offset,prot,0) 198 #define NEW_VMCMD2(evsp,proc,len,addr,vp,offset,prot,flags) do { \ 199 struct exec_vmcmd *vcp; \ 200 if ((evsp)->evs_used >= (evsp)->evs_cnt) \ 201 vmcmdset_extend(evsp); \ 202 vcp = &(evsp)->evs_cmds[(evsp)->evs_used++]; \ 203 vcp->ev_proc = (proc); \ 204 vcp->ev_len = (len); \ 205 vcp->ev_addr = (addr); \ 206 if ((vcp->ev_vp = (vp)) != NULLVP) \ 207 VREF(vp); \ 208 vcp->ev_offset = (offset); \ 209 vcp->ev_prot = (prot); \ 210 vcp->ev_flags = (flags); \ 211 } while (0) 212 213 #endif /* DEBUG */ 214 215 /* Initialize an empty vmcmd set */ 216 #define VMCMDSET_INIT(vmc) do { \ 217 (vmc)->evs_cnt = EXEC_DEFAULT_VMCMD_SETSIZE; \ 218 (vmc)->evs_cmds = (vmc)->evs_start; \ 219 (vmc)->evs_used = 0; \ 220 } while (0) 221 222 /* 223 * Exec function switch: 224 * 225 * Note that each makecmds function is responsible for loading the 226 * exec package with the necessary functions for any exec-type-specific 227 * handling. 228 * 229 * Functions for specific exec types should be defined in their own 230 * header file. 231 */ 232 extern struct execsw execsw[]; 233 extern int nexecs; 234 extern int exec_maxhdrsz; 235 236 #endif /* _KERNEL */ 237 238 #include <sys/exec_aout.h> 239 #include <machine/exec.h> 240 241 #endif /* !_SYS_EXEC_H_ */