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 */
53struct 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
73struct proc;
74struct exec_package;
75
76typedef int (*exec_makecmds_fcn)(struct proc *, struct exec_package *);
77
78struct 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
83struct 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 */
102struct 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
109struct elf_args;
110struct 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 */
150void	vmcmdset_extend(struct exec_vmcmd_set *);
151void	kill_vmcmds(struct exec_vmcmd_set *evsp);
152int	vmcmd_map_pagedvn(struct proc *, struct exec_vmcmd *);
153int	vmcmd_map_readvn(struct proc *, struct exec_vmcmd *);
154int	vmcmd_map_zero(struct proc *, struct exec_vmcmd *);
155int	vmcmd_mutable(struct proc *, struct exec_vmcmd *);
156int	vmcmd_randomize(struct proc *, struct exec_vmcmd *);
157int	copyargs(struct exec_package *, struct ps_strings *, void *, void *);
158void	setregs(struct proc *, struct exec_package *, u_long,
159	    struct ps_strings *);
160int	check_exec(struct proc *, struct exec_package *);
161int	exec_setup_stack(struct proc *, struct exec_package *);
162int	exec_process_vmcmds(struct proc *, struct exec_package *);
163
164#ifdef DEBUG
165void	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 */
210extern const struct	execsw execsw[];
211extern int	nexecs;
212extern 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 */
218extern 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 */
240struct 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