1 /* $OpenBSD: exec.h,v 1.54 2024/04/02 08:39:16 deraadt 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 * the following structures allow execve() to put together processes 62 * in a more extensible and cleaner way. 63 * 64 * the exec_package struct defines an executable being execve()'d. 65 * it contains the header, the vmspace-building commands, the vnode 66 * information, and the arguments associated with the newly-execve'd 67 * process. 68 * 69 * the exec_vmcmd struct defines a command description to be used 70 * in creating the new process's vmspace. 71 */ 72 73 struct proc; 74 struct exec_package; 75 76 typedef int (*exec_makecmds_fcn)(struct proc *, struct exec_package *); 77 78 struct execsw { 79 u_int es_hdrsz; /* size of header for this format */ 80 exec_makecmds_fcn es_check; /* function to check exec format */ 81 }; 82 83 struct exec_vmcmd { 84 int (*ev_proc)(struct proc *p, struct exec_vmcmd *cmd); 85 /* procedure to run for region of vmspace */ 86 u_long ev_len; /* length of the segment to map */ 87 u_long ev_addr; /* address in the vmspace to place it at */ 88 struct vnode *ev_vp; /* vnode pointer for the file w/the data */ 89 u_long ev_offset; /* offset in the file for the data */ 90 u_int ev_prot; /* protections for segment */ 91 int ev_flags; 92 #define VMCMD_RELATIVE 0x0001 /* ev_addr is relative to base entry */ 93 #define VMCMD_BASE 0x0002 /* marks a base entry */ 94 #define VMCMD_STACK 0x0004 /* create with UVM_FLAG_STACK */ 95 #define VMCMD_IMMUTABLE 0x0010 /* create with UVM_ET_IMMUTABLE */ 96 #define VMCMD_TEXTREL 0x0020 /* terrible binary contains terrible textrel */ 97 }; 98 99 #define EXEC_DEFAULT_VMCMD_SETSIZE 12 /* # of cmds in set to start */ 100 101 /* exec vmspace-creation command set; see below */ 102 struct exec_vmcmd_set { 103 u_int evs_cnt; 104 u_int evs_used; 105 struct exec_vmcmd *evs_cmds; 106 struct exec_vmcmd evs_start[EXEC_DEFAULT_VMCMD_SETSIZE]; 107 }; 108 109 struct elf_args; 110 struct exec_package { 111 char *ep_name; /* file's name */ 112 void *ep_hdr; /* file's exec header */ 113 u_int ep_hdrlen; /* length of ep_hdr */ 114 u_int ep_hdrvalid; /* bytes of ep_hdr that are valid */ 115 struct nameidata *ep_ndp; /* namei data pointer for lookups */ 116 struct exec_vmcmd_set ep_vmcmds; /* vmcmds used to build vmspace */ 117 struct vnode *ep_vp; /* executable's vnode */ 118 struct vattr *ep_vap; /* executable's attributes */ 119 u_long ep_taddr; /* process's text address */ 120 u_long ep_tsize; /* size of process's text */ 121 u_long ep_daddr; /* process's data(+bss) address */ 122 u_long ep_dsize; /* size of process's data(+bss) */ 123 u_long ep_maxsaddr; /* proc's max stack addr ("top") */ 124 u_long ep_minsaddr; /* proc's min stack addr ("bottom") */ 125 u_long ep_ssize; /* size of process's stack */ 126 u_long ep_entry; /* process's entry point */ 127 u_int ep_flags; /* flags; see below. */ 128 char **ep_fa; /* a fake args vector for scripts */ 129 int ep_fd; /* a file descriptor we're holding */ 130 struct elf_args *ep_args; /* ELF info */ 131 void *ep_auxinfo; /* userspace auxinfo address */ 132 char *ep_interp; /* name of interpreter if any */ 133 vaddr_t ep_pinstart, ep_pinend; /* executable region */ 134 u_int *ep_pins; /* array of system call offsets */ 135 int ep_npins; /* entries in array */ 136 }; 137 #define EXEC_INDIR 0x0001 /* script handling already done */ 138 #define EXEC_HASFD 0x0002 /* holding a shell script */ 139 #define EXEC_HASARGL 0x0004 /* has fake args vector */ 140 #define EXEC_SKIPARG 0x0008 /* don't copy user-supplied argv[0] */ 141 #define EXEC_DESTR 0x0010 /* destructive ops performed */ 142 #define EXEC_WXNEEDED 0x0020 /* executable will violate W^X */ 143 #define EXEC_NOBTCFI 0x0040 /* no branch target CFI */ 144 145 #ifdef _KERNEL 146 /* 147 * functions used either by execve() or the various cpu-dependent execve() 148 * hooks. 149 */ 150 void vmcmdset_extend(struct exec_vmcmd_set *); 151 void kill_vmcmds(struct exec_vmcmd_set *evsp); 152 int vmcmd_map_pagedvn(struct proc *, struct exec_vmcmd *); 153 int vmcmd_map_readvn(struct proc *, struct exec_vmcmd *); 154 int vmcmd_map_zero(struct proc *, struct exec_vmcmd *); 155 int vmcmd_mutable(struct proc *, struct exec_vmcmd *); 156 int vmcmd_randomize(struct proc *, struct exec_vmcmd *); 157 int copyargs(struct exec_package *, struct ps_strings *, void *, void *); 158 void setregs(struct proc *, struct exec_package *, u_long, 159 struct ps_strings *); 160 int check_exec(struct proc *, struct exec_package *); 161 int exec_setup_stack(struct proc *, struct exec_package *); 162 int exec_process_vmcmds(struct proc *, struct exec_package *); 163 164 #ifdef DEBUG 165 void new_vmcmd(struct exec_vmcmd_set *evsp, 166 int (*proc)(struct proc *p, struct exec_vmcmd *), 167 u_long len, u_long addr, struct vnode *vp, u_long offset, 168 u_int prot, int flags); 169 #define NEW_VMCMD(evsp,proc,len,addr,vp,offset,prot) \ 170 new_vmcmd(evsp,proc,len,addr,vp,offset,prot, 0); 171 #define NEW_VMCMD2(evsp,proc,len,addr,vp,offset,prot,flags) \ 172 new_vmcmd(evsp,proc,len,addr,vp,offset,prot,flags) 173 #else /* DEBUG */ 174 #define NEW_VMCMD(evsp,proc,len,addr,vp,offset,prot) \ 175 NEW_VMCMD2(evsp,proc,len,addr,vp,offset,prot,0) 176 #define NEW_VMCMD2(evsp,proc,len,addr,vp,offset,prot,flags) do { \ 177 struct exec_vmcmd *__vcp; \ 178 if ((evsp)->evs_used >= (evsp)->evs_cnt) \ 179 vmcmdset_extend(evsp); \ 180 __vcp = &(evsp)->evs_cmds[(evsp)->evs_used++]; \ 181 __vcp->ev_proc = (proc); \ 182 __vcp->ev_len = (len); \ 183 __vcp->ev_addr = (addr); \ 184 if ((__vcp->ev_vp = (vp)) != NULLVP) \ 185 vref(vp); \ 186 __vcp->ev_offset = (offset); \ 187 __vcp->ev_prot = (prot); \ 188 __vcp->ev_flags = (flags); \ 189 } while (0) 190 191 #endif /* DEBUG */ 192 193 /* Initialize an empty vmcmd set */ 194 #define VMCMDSET_INIT(vmc) do { \ 195 (vmc)->evs_cnt = EXEC_DEFAULT_VMCMD_SETSIZE; \ 196 (vmc)->evs_cmds = (vmc)->evs_start; \ 197 (vmc)->evs_used = 0; \ 198 } while (0) 199 200 /* 201 * Exec function switch: 202 * 203 * Note that each makecmds function is responsible for loading the 204 * exec package with the necessary functions for any exec-type-specific 205 * handling. 206 * 207 * Functions for specific exec types should be defined in their own 208 * header file. 209 */ 210 extern const struct execsw execsw[]; 211 extern int nexecs; 212 extern int exec_maxhdrsz; 213 214 /* 215 * If non-zero, stackgap_random specifies the upper limit of the random gap size 216 * added to the fixed stack position. Must be n^2. 217 */ 218 extern int stackgap_random; 219 220 /* Limit on total PT_OPENBSD_RANDOMIZE bytes. */ 221 #define ELF_RANDOMIZE_LIMIT 1024*1024 222 223 #endif /* _KERNEL */ 224 225 #ifndef N_PAGSIZ 226 #define N_PAGSIZ(ex) (__LDPGSZ) 227 #endif 228 229 /* 230 * Legacy a.out structures and defines; start deleting these when 231 * external use no longer exist. 232 */ 233 234 235 /* 236 * Header prepended to each a.out file. 237 * only manipulate the a_midmag field via the 238 * N_SETMAGIC/N_GET{MAGIC,MID,FLAG} macros below. 239 */ 240 struct exec { 241 u_int32_t a_midmag; /* htonl(flags<<26|mid<<16|magic) */ 242 u_int32_t a_text; /* text segment size */ 243 u_int32_t a_data; /* initialized data size */ 244 u_int32_t a_bss; /* uninitialized data size */ 245 u_int32_t a_syms; /* symbol table size */ 246 u_int32_t a_entry; /* entry point */ 247 u_int32_t a_trsize; /* text relocation size */ 248 u_int32_t a_drsize; /* data relocation size */ 249 }; 250 251 /* a_magic */ 252 #define OMAGIC 0407 /* old impure format */ 253 #define NMAGIC 0410 /* read-only text */ 254 #define ZMAGIC 0413 /* demand load format */ 255 #define QMAGIC 0314 /* "compact" demand load format; deprecated */ 256 257 /* 258 * a_mid - keep sorted in numerical order for sanity's sake 259 * ensure that: 0 < mid < 0x3ff 260 */ 261 #define MID_ZERO 0 /* unknown - implementation dependent */ 262 #define MID_SUN010 1 /* sun 68010/68020 binary */ 263 #define MID_SUN020 2 /* sun 68020-only binary */ 264 #define MID_PC386 100 /* 386 PC binary. (so quoth BFD) */ 265 #define MID_ROMPAOS 104 /* old IBM RT */ 266 #define MID_I386 134 /* i386 BSD binary */ 267 #define MID_M68K 135 /* m68k BSD binary with 8K page sizes */ 268 #define MID_M68K4K 136 /* DO NOT USE: m68k BSD binary with 4K page sizes */ 269 #define MID_NS32532 137 /* ns32532 */ 270 #define MID_SPARC 138 /* sparc */ 271 #define MID_PMAX 139 /* pmax */ 272 #define MID_VAX1K 140 /* vax 1k page size */ 273 #define MID_ALPHA 141 /* Alpha BSD binary */ 274 #define MID_MIPS 142 /* big-endian MIPS */ 275 #define MID_ARM6 143 /* ARM6 */ 276 #define MID_SH3 145 /* SH3 */ 277 #define MID_POWERPC 149 /* big-endian PowerPC */ 278 #define MID_VAX 150 /* vax */ 279 #define MID_SPARC64 151 /* LP64 sparc */ 280 #define MID_MIPS2 152 /* MIPS2 */ 281 #define MID_M88K 153 /* m88k BSD binary */ 282 #define MID_HPPA 154 /* hppa */ 283 #define MID_AMD64 157 /* AMD64 */ 284 #define MID_MIPS64 158 /* big-endian MIPS64 */ 285 #define MID_ARM64 159 /* ARM64 */ 286 #define MID_POWERPC64 160 /* big-endian 64-bit PowerPC */ 287 #define MID_RISCV64 161 /* Little-endian 64-bit RISC-V */ 288 #define MID_HP200 200 /* hp200 (68010) BSD binary */ 289 #define MID_HP300 300 /* hp300 (68020+68881) BSD binary */ 290 #define MID_HPUX 0x20C /* hp200/300 HP-UX binary */ 291 #define MID_HPUX800 0x20B /* hp800 HP-UX binary pa1.0 */ 292 #define MID_HPPA11 0x210 /* hp700 HP-UX binary pa1.1 */ 293 #define MID_HPPA20 0x214 /* hp700 HP-UX binary pa2.0 */ 294 295 /* 296 * a_flags 297 */ 298 #define EX_DYNAMIC 0x20 299 #define EX_PIC 0x10 300 #define EX_DPMASK 0x30 301 /* 302 * Interpretation of the (a_flags & EX_DPMASK) bits: 303 * 304 * 00 traditional executable or object file 305 * 01 object file contains PIC code (set by `as -k') 306 * 10 dynamic executable 307 * 11 position independent executable image 308 * (eg. a shared library) 309 * 310 */ 311 312 /* 313 * The a.out structure's a_midmag field is a network-byteorder encoding 314 * of this int 315 * FFFFFFmmmmmmmmmmMMMMMMMMMMMMMMMM 316 * Where `F' is 6 bits of flag like EX_DYNAMIC, 317 * `m' is 10 bits of machine-id like MID_I386, and 318 * `M' is 16 bits worth of magic number, ie. ZMAGIC. 319 * The macros below will set/get the needed fields. 320 */ 321 #define N_GETMAGIC(ex) \ 322 ( (((ex).a_midmag)&0xffff0000) ? (ntohl(((ex).a_midmag))&0xffff) : ((ex).a_midmag)) 323 #define N_GETMAGIC2(ex) \ 324 ( (((ex).a_midmag)&0xffff0000) ? (ntohl(((ex).a_midmag))&0xffff) : \ 325 (((ex).a_midmag) | 0x10000) ) 326 #define N_GETMID(ex) \ 327 ( (((ex).a_midmag)&0xffff0000) ? ((ntohl(((ex).a_midmag))>>16)&0x03ff) : MID_ZERO ) 328 #define N_GETFLAG(ex) \ 329 ( (((ex).a_midmag)&0xffff0000) ? ((ntohl(((ex).a_midmag))>>26)&0x3f) : 0 ) 330 #define N_SETMAGIC(ex,mag,mid,flag) \ 331 ( (ex).a_midmag = htonl( (((flag)&0x3f)<<26) | (((mid)&0x03ff)<<16) | \ 332 (((mag)&0xffff)) ) ) 333 334 #define N_ALIGN(ex,x) \ 335 (N_GETMAGIC(ex) == ZMAGIC || N_GETMAGIC(ex) == QMAGIC ? \ 336 ((x) + __LDPGSZ - 1) & ~(__LDPGSZ - 1) : (x)) 337 338 /* Valid magic number check. */ 339 #define N_BADMAG(ex) \ 340 (N_GETMAGIC(ex) != NMAGIC && N_GETMAGIC(ex) != OMAGIC && \ 341 N_GETMAGIC(ex) != ZMAGIC && N_GETMAGIC(ex) != QMAGIC) 342 343 /* Address of the bottom of the text segment. */ 344 #define N_TXTADDR(ex) (N_GETMAGIC2(ex) == (ZMAGIC|0x10000) ? 0 : __LDPGSZ) 345 346 /* Address of the bottom of the data segment. */ 347 #define N_DATADDR(ex) \ 348 (N_GETMAGIC(ex) == OMAGIC ? N_TXTADDR(ex) + (ex).a_text : \ 349 (N_TXTADDR(ex) + (ex).a_text + __LDPGSZ - 1) & ~(__LDPGSZ - 1)) 350 351 /* Address of the bottom of the bss segment. */ 352 #define N_BSSADDR(ex) \ 353 (N_DATADDR(ex) + (ex).a_data) 354 355 /* Text segment offset. */ 356 #define N_TXTOFF(ex) \ 357 ( N_GETMAGIC2(ex)==ZMAGIC || N_GETMAGIC2(ex)==(QMAGIC|0x10000) ? \ 358 0 : (N_GETMAGIC2(ex)==(ZMAGIC|0x10000) ? __LDPGSZ : \ 359 sizeof(struct exec)) ) 360 361 /* Data segment offset. */ 362 #define N_DATOFF(ex) \ 363 N_ALIGN(ex, N_TXTOFF(ex) + (ex).a_text) 364 365 /* Text relocation table offset. */ 366 #define N_TRELOFF(ex) \ 367 (N_DATOFF(ex) + (ex).a_data) 368 369 /* Data relocation table offset. */ 370 #define N_DRELOFF(ex) \ 371 (N_TRELOFF(ex) + (ex).a_trsize) 372 373 /* Symbol table offset. */ 374 #define N_SYMOFF(ex) \ 375 (N_DRELOFF(ex) + (ex).a_drsize) 376 377 /* String table offset. */ 378 #define N_STROFF(ex) \ 379 (N_SYMOFF(ex) + (ex).a_syms) 380 381 #include <machine/exec.h> 382 383 #endif /* !_SYS_EXEC_H_ */ 384