xref: /openbsd/sys/sys/exec.h (revision 30d20579)
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