169587Sgreen/* $OpenBSD: exec.h,v 1.54 2024/04/02 08:39:16 deraadt Exp $ */ 269587Sgreen/* $NetBSD: exec.h,v 1.59 1996/02/09 18:25:09 christos Exp $ */ 369587Sgreen 469587Sgreen/*- 569587Sgreen * Copyright (c) 1994 Christopher G. Demetriou 669587Sgreen * Copyright (c) 1993 Theo de Raadt 769587Sgreen * Copyright (c) 1992, 1993 869587Sgreen * The Regents of the University of California. All rights reserved. 969587Sgreen * (c) UNIX System Laboratories, Inc. 1069587Sgreen * All or some portions of this file are derived from material licensed 1169587Sgreen * to the University of California by American Telephone and Telegraph 1269587Sgreen * Co. or Unix System Laboratories, Inc. and are reproduced herein with 1369587Sgreen * the permission of UNIX System Laboratories, Inc. 1469587Sgreen * 1569587Sgreen * Redistribution and use in source and binary forms, with or without 1669587Sgreen * modification, are permitted provided that the following conditions 1769587Sgreen * are met: 1869587Sgreen * 1. Redistributions of source code must retain the above copyright 1969587Sgreen * notice, this list of conditions and the following disclaimer. 2069587Sgreen * 2. Redistributions in binary form must reproduce the above copyright 2169587Sgreen * notice, this list of conditions and the following disclaimer in the 2269587Sgreen * documentation and/or other materials provided with the distribution. 2369587Sgreen * 3. Neither the name of the University nor the names of its contributors 2469587Sgreen * may be used to endorse or promote products derived from this software 2569587Sgreen * without specific prior written permission. 26137015Sdes * 2769587Sgreen * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2869587Sgreen * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2969587Sgreen * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3069587Sgreen * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3169587Sgreen * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3269587Sgreen * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3369587Sgreen * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3469587Sgreen * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3576259Sgreen * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3669587Sgreen * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3769587Sgreen * SUCH DAMAGE. 3876259Sgreen * 3976259Sgreen * @(#)exec.h 8.3 (Berkeley) 1/21/94 4076259Sgreen */ 4169587Sgreen 4292555Sdes#ifndef _SYS_EXEC_H_ 4369587Sgreen#define _SYS_EXEC_H_ 4469587Sgreen 4569587Sgreen/* 4669587Sgreen * The following structure is found at the top of the user stack of each 4769587Sgreen * user process. The ps program uses it to locate argv and environment 4869587Sgreen * strings. Programs that wish ps to display other information may modify 4969587Sgreen * it; normally ps_argvstr points to argv[0], and ps_nargvstr is the same 5069587Sgreen * as the program's argc. The fields ps_envstr and ps_nenvstr are the 5169587Sgreen * equivalent for the environment. 5269587Sgreen */ 53106121Sdesstruct ps_strings { 5469587Sgreen char **ps_argvstr; /* first of 0 or more argument strings */ 5569587Sgreen int ps_nargvstr; /* the number of argument strings */ 5669587Sgreen char **ps_envstr; /* first of 0 or more environment strings */ 5769587Sgreen int ps_nenvstr; /* the number of environment strings */ 5869587Sgreen}; 5969587Sgreen 6069587Sgreen/* 6169587Sgreen * the following structures allow execve() to put together processes 6269587Sgreen * in a more extensible and cleaner way. 6369587Sgreen * 6469587Sgreen * the exec_package struct defines an executable being execve()'d. 6569587Sgreen * it contains the header, the vmspace-building commands, the vnode 6669587Sgreen * information, and the arguments associated with the newly-execve'd 6769587Sgreen * process. 6869587Sgreen * 6969587Sgreen * the exec_vmcmd struct defines a command description to be used 7069587Sgreen * in creating the new process's vmspace. 7169587Sgreen */ 7276259Sgreen 7376259Sgreenstruct proc; 7469587Sgreenstruct exec_package; 7569587Sgreen 7669587Sgreentypedef int (*exec_makecmds_fcn)(struct proc *, struct exec_package *); 7769587Sgreen 7869587Sgreenstruct execsw { 7969587Sgreen u_int es_hdrsz; /* size of header for this format */ 8069587Sgreen exec_makecmds_fcn es_check; /* function to check exec format */ 8192555Sdes}; 8292555Sdes 8392555Sdesstruct exec_vmcmd { 8492555Sdes int (*ev_proc)(struct proc *p, struct exec_vmcmd *cmd); 8576259Sgreen /* procedure to run for region of vmspace */ 8676259Sgreen u_long ev_len; /* length of the segment to map */ 8769587Sgreen u_long ev_addr; /* address in the vmspace to place it at */ 8876259Sgreen struct vnode *ev_vp; /* vnode pointer for the file w/the data */ 8976259Sgreen u_long ev_offset; /* offset in the file for the data */ 9076259Sgreen u_int ev_prot; /* protections for segment */ 9176259Sgreen int ev_flags; 9276259Sgreen#define VMCMD_RELATIVE 0x0001 /* ev_addr is relative to base entry */ 9376259Sgreen#define VMCMD_BASE 0x0002 /* marks a base entry */ 94128456Sdes#define VMCMD_STACK 0x0004 /* create with UVM_FLAG_STACK */ 95128456Sdes#define VMCMD_IMMUTABLE 0x0010 /* create with UVM_ET_IMMUTABLE */ 96128456Sdes#define VMCMD_TEXTREL 0x0020 /* terrible binary contains terrible textrel */ 9769587Sgreen}; 9876259Sgreen 9976259Sgreen#define EXEC_DEFAULT_VMCMD_SETSIZE 12 /* # of cmds in set to start */ 10092555Sdes 10192555Sdes/* exec vmspace-creation command set; see below */ 10269587Sgreenstruct exec_vmcmd_set { 10376259Sgreen u_int evs_cnt; 10469587Sgreen u_int evs_used; 10569587Sgreen struct exec_vmcmd *evs_cmds; 10669587Sgreen struct exec_vmcmd evs_start[EXEC_DEFAULT_VMCMD_SETSIZE]; 10769587Sgreen}; 10876259Sgreen 10969587Sgreenstruct elf_args; 11069587Sgreenstruct exec_package { 111128456Sdes char *ep_name; /* file's name */ 11269587Sgreen void *ep_hdr; /* file's exec header */ 11369587Sgreen u_int ep_hdrlen; /* length of ep_hdr */ 11469587Sgreen u_int ep_hdrvalid; /* bytes of ep_hdr that are valid */ 11569587Sgreen struct nameidata *ep_ndp; /* namei data pointer for lookups */ 11692555Sdes struct exec_vmcmd_set ep_vmcmds; /* vmcmds used to build vmspace */ 11792555Sdes struct vnode *ep_vp; /* executable's vnode */ 118137015Sdes struct vattr *ep_vap; /* executable's attributes */ 119137015Sdes u_long ep_taddr; /* process's text address */ 120137015Sdes u_long ep_tsize; /* size of process's text */ 12169587Sgreen u_long ep_daddr; /* process's data(+bss) address */ 12269587Sgreen u_long ep_dsize; /* size of process's data(+bss) */ 12369587Sgreen u_long ep_maxsaddr; /* proc's max stack addr ("top") */ 12469587Sgreen u_long ep_minsaddr; /* proc's min stack addr ("bottom") */ 12569587Sgreen u_long ep_ssize; /* size of process's stack */ 12669587Sgreen u_long ep_entry; /* process's entry point */ 12769587Sgreen u_int ep_flags; /* flags; see below. */ 12869587Sgreen char **ep_fa; /* a fake args vector for scripts */ 12992555Sdes int ep_fd; /* a file descriptor we're holding */ 13092555Sdes struct elf_args *ep_args; /* ELF info */ 13169587Sgreen void *ep_auxinfo; /* userspace auxinfo address */ 13276259Sgreen char *ep_interp; /* name of interpreter if any */ 13376259Sgreen vaddr_t ep_pinstart, ep_pinend; /* executable region */ 13476259Sgreen u_int *ep_pins; /* array of system call offsets */ 13576259Sgreen int ep_npins; /* entries in array */ 13676259Sgreen}; 13769587Sgreen#define EXEC_INDIR 0x0001 /* script handling already done */ 13869587Sgreen#define EXEC_HASFD 0x0002 /* holding a shell script */ 13969587Sgreen#define EXEC_HASARGL 0x0004 /* has fake args vector */ 14069587Sgreen#define EXEC_SKIPARG 0x0008 /* don't copy user-supplied argv[0] */ 14169587Sgreen#define EXEC_DESTR 0x0010 /* destructive ops performed */ 14269587Sgreen#define EXEC_WXNEEDED 0x0020 /* executable will violate W^X */ 14392555Sdes#define EXEC_NOBTCFI 0x0040 /* no branch target CFI */ 14469587Sgreen 14569587Sgreen#ifdef _KERNEL 14692555Sdes/* 147124208Sdes * functions used either by execve() or the various cpu-dependent execve() 148137015Sdes * hooks. 14969587Sgreen */ 15069587Sgreenvoid vmcmdset_extend(struct exec_vmcmd_set *); 15169587Sgreenvoid kill_vmcmds(struct exec_vmcmd_set *evsp); 15269587Sgreenint vmcmd_map_pagedvn(struct proc *, struct exec_vmcmd *); 15369587Sgreenint vmcmd_map_readvn(struct proc *, struct exec_vmcmd *); 15469587Sgreenint vmcmd_map_zero(struct proc *, struct exec_vmcmd *); 15569587Sgreenint vmcmd_mutable(struct proc *, struct exec_vmcmd *); 15676259Sgreenint vmcmd_randomize(struct proc *, struct exec_vmcmd *); 15776259Sgreenint copyargs(struct exec_package *, struct ps_strings *, void *, void *); 15876259Sgreenvoid setregs(struct proc *, struct exec_package *, u_long, 15992555Sdes struct ps_strings *); 16092555Sdesint check_exec(struct proc *, struct exec_package *); 16169587Sgreenint exec_setup_stack(struct proc *, struct exec_package *); 16269587Sgreenint exec_process_vmcmds(struct proc *, struct exec_package *); 16369587Sgreen 16469587Sgreen#ifdef DEBUG 16569587Sgreenvoid new_vmcmd(struct exec_vmcmd_set *evsp, 16676259Sgreen int (*proc)(struct proc *p, struct exec_vmcmd *), 16776259Sgreen u_long len, u_long addr, struct vnode *vp, u_long offset, 16876259Sgreen u_int prot, int flags); 16969587Sgreen#define NEW_VMCMD(evsp,proc,len,addr,vp,offset,prot) \ 17069587Sgreen new_vmcmd(evsp,proc,len,addr,vp,offset,prot, 0); 17169587Sgreen#define NEW_VMCMD2(evsp,proc,len,addr,vp,offset,prot,flags) \ 17276259Sgreen new_vmcmd(evsp,proc,len,addr,vp,offset,prot,flags) 173137015Sdes#else /* DEBUG */ 17476259Sgreen#define NEW_VMCMD(evsp,proc,len,addr,vp,offset,prot) \ 17576259Sgreen NEW_VMCMD2(evsp,proc,len,addr,vp,offset,prot,0) 17676259Sgreen#define NEW_VMCMD2(evsp,proc,len,addr,vp,offset,prot,flags) do { \ 17776259Sgreen struct exec_vmcmd *__vcp; \ 17876259Sgreen if ((evsp)->evs_used >= (evsp)->evs_cnt) \ 17976259Sgreen vmcmdset_extend(evsp); \ 18076259Sgreen __vcp = &(evsp)->evs_cmds[(evsp)->evs_used++]; \ 18176259Sgreen __vcp->ev_proc = (proc); \ 18276259Sgreen __vcp->ev_len = (len); \ 183124208Sdes __vcp->ev_addr = (addr); \ 18476259Sgreen if ((__vcp->ev_vp = (vp)) != NULLVP) \ 18576259Sgreen vref(vp); \ 18676259Sgreen __vcp->ev_offset = (offset); \ 18776259Sgreen __vcp->ev_prot = (prot); \ 18876259Sgreen __vcp->ev_flags = (flags); \ 189113908Sdes} while (0) 19076259Sgreen 19176259Sgreen#endif /* DEBUG */ 19276259Sgreen 19376259Sgreen/* Initialize an empty vmcmd set */ 194124208Sdes#define VMCMDSET_INIT(vmc) do { \ 19576259Sgreen (vmc)->evs_cnt = EXEC_DEFAULT_VMCMD_SETSIZE; \ 19676259Sgreen (vmc)->evs_cmds = (vmc)->evs_start; \ 19776259Sgreen (vmc)->evs_used = 0; \ 19876259Sgreen} while (0) 19976259Sgreen 20076259Sgreen/* 201128456Sdes * Exec function switch: 20276259Sgreen * 20376259Sgreen * Note that each makecmds function is responsible for loading the 20476259Sgreen * exec package with the necessary functions for any exec-type-specific 205126274Sdes * handling. 20676259Sgreen * 20776259Sgreen * Functions for specific exec types should be defined in their own 20876259Sgreen * header file. 20976259Sgreen */ 21092555Sdesextern const struct execsw execsw[]; 21192555Sdesextern int nexecs; 21276259Sgreenextern int exec_maxhdrsz; 21376259Sgreen 21476259Sgreen/* 21576259Sgreen * If non-zero, stackgap_random specifies the upper limit of the random gap size 21676259Sgreen * added to the fixed stack position. Must be n^2. 21776259Sgreen */ 218128456Sdesextern int stackgap_random; 21976259Sgreen 22076259Sgreen/* Limit on total PT_OPENBSD_RANDOMIZE bytes. */ 221113908Sdes#define ELF_RANDOMIZE_LIMIT 1024*1024 22276259Sgreen 22376259Sgreen#endif /* _KERNEL */ 22476259Sgreen 22576259Sgreen#ifndef N_PAGSIZ 22676259Sgreen#define N_PAGSIZ(ex) (__LDPGSZ) 22776259Sgreen#endif 22876259Sgreen 22976259Sgreen/* 23076259Sgreen * Legacy a.out structures and defines; start deleting these when 23176259Sgreen * external use no longer exist. 23276259Sgreen */ 23392555Sdes 23492555Sdes 23576259Sgreen/* 23676259Sgreen * Header prepended to each a.out file. 23776259Sgreen * only manipulate the a_midmag field via the 23876259Sgreen * N_SETMAGIC/N_GET{MAGIC,MID,FLAG} macros below. 23976259Sgreen */ 24076259Sgreenstruct exec { 24176259Sgreen u_int32_t a_midmag; /* htonl(flags<<26|mid<<16|magic) */ 24276259Sgreen u_int32_t a_text; /* text segment size */ 24376259Sgreen u_int32_t a_data; /* initialized data size */ 24476259Sgreen u_int32_t a_bss; /* uninitialized data size */ 24576259Sgreen u_int32_t a_syms; /* symbol table size */ 24676259Sgreen u_int32_t a_entry; /* entry point */ 24776259Sgreen u_int32_t a_trsize; /* text relocation size */ 24876259Sgreen u_int32_t a_drsize; /* data relocation size */ 24976259Sgreen}; 25076259Sgreen 25176259Sgreen/* a_magic */ 25276259Sgreen#define OMAGIC 0407 /* old impure format */ 25376259Sgreen#define NMAGIC 0410 /* read-only text */ 25492555Sdes#define ZMAGIC 0413 /* demand load format */ 25592555Sdes#define QMAGIC 0314 /* "compact" demand load format; deprecated */ 25676259Sgreen 25776259Sgreen/* 25876259Sgreen * a_mid - keep sorted in numerical order for sanity's sake 25976259Sgreen * ensure that: 0 < mid < 0x3ff 26076259Sgreen */ 26176259Sgreen#define MID_ZERO 0 /* unknown - implementation dependent */ 26276259Sgreen#define MID_SUN010 1 /* sun 68010/68020 binary */ 26376259Sgreen#define MID_SUN020 2 /* sun 68020-only binary */ 26476259Sgreen#define MID_PC386 100 /* 386 PC binary. (so quoth BFD) */ 26576259Sgreen#define MID_ROMPAOS 104 /* old IBM RT */ 26676259Sgreen#define MID_I386 134 /* i386 BSD binary */ 26776259Sgreen#define MID_M68K 135 /* m68k BSD binary with 8K page sizes */ 26876259Sgreen#define MID_M68K4K 136 /* DO NOT USE: m68k BSD binary with 4K page sizes */ 26976259Sgreen#define MID_NS32532 137 /* ns32532 */ 27076259Sgreen#define MID_SPARC 138 /* sparc */ 27176259Sgreen#define MID_PMAX 139 /* pmax */ 27276259Sgreen#define MID_VAX1K 140 /* vax 1k page size */ 27376259Sgreen#define MID_ALPHA 141 /* Alpha BSD binary */ 27476259Sgreen#define MID_MIPS 142 /* big-endian MIPS */ 27576259Sgreen#define MID_ARM6 143 /* ARM6 */ 276137015Sdes#define MID_SH3 145 /* SH3 */ 277137015Sdes#define MID_POWERPC 149 /* big-endian PowerPC */ 278137015Sdes#define MID_VAX 150 /* vax */ 279137015Sdes#define MID_SPARC64 151 /* LP64 sparc */ 280137015Sdes#define MID_MIPS2 152 /* MIPS2 */ 281137015Sdes#define MID_M88K 153 /* m88k BSD binary */ 282137015Sdes#define MID_HPPA 154 /* hppa */ 283137015Sdes#define MID_AMD64 157 /* AMD64 */ 284137015Sdes#define MID_MIPS64 158 /* big-endian MIPS64 */ 285137015Sdes#define MID_ARM64 159 /* ARM64 */ 286137015Sdes#define MID_POWERPC64 160 /* big-endian 64-bit PowerPC */ 287137015Sdes#define MID_RISCV64 161 /* Little-endian 64-bit RISC-V */ 288137015Sdes#define MID_HP200 200 /* hp200 (68010) BSD binary */ 289137015Sdes#define MID_HP300 300 /* hp300 (68020+68881) BSD binary */ 290137015Sdes#define MID_HPUX 0x20C /* hp200/300 HP-UX binary */ 291137015Sdes#define MID_HPUX800 0x20B /* hp800 HP-UX binary pa1.0 */ 292137015Sdes#define MID_HPPA11 0x210 /* hp700 HP-UX binary pa1.1 */ 293137015Sdes#define MID_HPPA20 0x214 /* hp700 HP-UX binary pa2.0 */ 294137015Sdes 29576259Sgreen/* 29676259Sgreen * a_flags 29776259Sgreen */ 29876259Sgreen#define EX_DYNAMIC 0x20 29976259Sgreen#define EX_PIC 0x10 30076259Sgreen#define EX_DPMASK 0x30 30176259Sgreen/* 30276259Sgreen * Interpretation of the (a_flags & EX_DPMASK) bits: 30376259Sgreen * 30476259Sgreen * 00 traditional executable or object file 305126274Sdes * 01 object file contains PIC code (set by `as -k') 30676259Sgreen * 10 dynamic executable 307126274Sdes * 11 position independent executable image 30876259Sgreen * (eg. a shared library) 30976259Sgreen * 31076259Sgreen */ 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