xref: /f-stack/freebsd/sys/sysent.h (revision 22ce4aff)
1a9643ea8Slogwang /*-
2*22ce4affSfengbojiang  * SPDX-License-Identifier: BSD-3-Clause
3*22ce4affSfengbojiang  *
4a9643ea8Slogwang  * Copyright (c) 1982, 1988, 1991 The Regents of the University of California.
5a9643ea8Slogwang  * All rights reserved.
6a9643ea8Slogwang  *
7a9643ea8Slogwang  * Redistribution and use in source and binary forms, with or without
8a9643ea8Slogwang  * modification, are permitted provided that the following conditions
9a9643ea8Slogwang  * are met:
10a9643ea8Slogwang  * 1. Redistributions of source code must retain the above copyright
11a9643ea8Slogwang  *    notice, this list of conditions and the following disclaimer.
12a9643ea8Slogwang  * 2. Redistributions in binary form must reproduce the above copyright
13a9643ea8Slogwang  *    notice, this list of conditions and the following disclaimer in the
14a9643ea8Slogwang  *    documentation and/or other materials provided with the distribution.
15*22ce4affSfengbojiang  * 3. Neither the name of the University nor the names of its contributors
16a9643ea8Slogwang  *    may be used to endorse or promote products derived from this software
17a9643ea8Slogwang  *    without specific prior written permission.
18a9643ea8Slogwang  *
19a9643ea8Slogwang  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20a9643ea8Slogwang  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21a9643ea8Slogwang  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22a9643ea8Slogwang  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23a9643ea8Slogwang  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24a9643ea8Slogwang  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25a9643ea8Slogwang  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26a9643ea8Slogwang  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27a9643ea8Slogwang  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28a9643ea8Slogwang  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29a9643ea8Slogwang  * SUCH DAMAGE.
30a9643ea8Slogwang  *
31a9643ea8Slogwang  * $FreeBSD$
32a9643ea8Slogwang  */
33a9643ea8Slogwang 
34a9643ea8Slogwang #ifndef _SYS_SYSENT_H_
35a9643ea8Slogwang #define	_SYS_SYSENT_H_
36a9643ea8Slogwang 
37a9643ea8Slogwang #include <bsm/audit.h>
38a9643ea8Slogwang 
39a9643ea8Slogwang struct rlimit;
40a9643ea8Slogwang struct sysent;
41a9643ea8Slogwang struct thread;
42a9643ea8Slogwang struct ksiginfo;
43a9643ea8Slogwang struct syscall_args;
44a9643ea8Slogwang 
45a9643ea8Slogwang enum systrace_probe_t {
46a9643ea8Slogwang 	SYSTRACE_ENTRY,
47a9643ea8Slogwang 	SYSTRACE_RETURN,
48a9643ea8Slogwang };
49a9643ea8Slogwang 
50a9643ea8Slogwang typedef	int	sy_call_t(struct thread *, void *);
51a9643ea8Slogwang 
52a9643ea8Slogwang typedef	void	(*systrace_probe_func_t)(struct syscall_args *,
53a9643ea8Slogwang 		    enum systrace_probe_t, int);
54a9643ea8Slogwang typedef	void	(*systrace_args_func_t)(int, void *, uint64_t *, int *);
55a9643ea8Slogwang 
56*22ce4affSfengbojiang #ifdef _KERNEL
57a9643ea8Slogwang extern systrace_probe_func_t	systrace_probe_func;
58*22ce4affSfengbojiang extern bool			systrace_enabled;
59*22ce4affSfengbojiang 
60*22ce4affSfengbojiang #ifdef KDTRACE_HOOKS
61*22ce4affSfengbojiang #define	SYSTRACE_ENABLED()	(systrace_enabled)
62*22ce4affSfengbojiang #else
63*22ce4affSfengbojiang #define SYSTRACE_ENABLED()	(0)
64*22ce4affSfengbojiang #endif
65*22ce4affSfengbojiang #endif /* _KERNEL */
66a9643ea8Slogwang 
67a9643ea8Slogwang struct sysent {			/* system call table */
68a9643ea8Slogwang 	sy_call_t *sy_call;	/* implementing function */
69a9643ea8Slogwang 	systrace_args_func_t sy_systrace_args_func;
70a9643ea8Slogwang 				/* optional argument conversion function. */
71*22ce4affSfengbojiang 	u_int8_t sy_narg;	/* number of arguments */
72*22ce4affSfengbojiang 	u_int8_t sy_flags;	/* General flags for system calls. */
73*22ce4affSfengbojiang 	au_event_t sy_auevent;	/* audit event associated with syscall */
74a9643ea8Slogwang 	u_int32_t sy_entry;	/* DTrace entry ID for systrace. */
75a9643ea8Slogwang 	u_int32_t sy_return;	/* DTrace return ID for systrace. */
76a9643ea8Slogwang 	u_int32_t sy_thrcnt;
77a9643ea8Slogwang };
78a9643ea8Slogwang 
79a9643ea8Slogwang /*
80a9643ea8Slogwang  * A system call is permitted in capability mode.
81a9643ea8Slogwang  */
82a9643ea8Slogwang #define	SYF_CAPENABLED	0x00000001
83a9643ea8Slogwang 
84a9643ea8Slogwang #define	SY_THR_FLAGMASK	0x7
85a9643ea8Slogwang #define	SY_THR_STATIC	0x1
86a9643ea8Slogwang #define	SY_THR_DRAINING	0x2
87a9643ea8Slogwang #define	SY_THR_ABSENT	0x4
88a9643ea8Slogwang #define	SY_THR_INCR	0x8
89a9643ea8Slogwang 
90a9643ea8Slogwang #ifdef KLD_MODULE
91a9643ea8Slogwang #define	SY_THR_STATIC_KLD	0
92a9643ea8Slogwang #else
93a9643ea8Slogwang #define	SY_THR_STATIC_KLD	SY_THR_STATIC
94a9643ea8Slogwang #endif
95a9643ea8Slogwang 
96a9643ea8Slogwang struct image_params;
97*22ce4affSfengbojiang struct proc;
98a9643ea8Slogwang struct __sigset;
99a9643ea8Slogwang struct trapframe;
100a9643ea8Slogwang struct vnode;
101a9643ea8Slogwang 
102a9643ea8Slogwang struct sysentvec {
103a9643ea8Slogwang 	int		sv_size;	/* number of entries */
104a9643ea8Slogwang 	struct sysent	*sv_table;	/* pointer to sysent */
105a9643ea8Slogwang 	int		(*sv_transtrap)(int, int);
106a9643ea8Slogwang 					/* translate trap-to-signal mapping */
107*22ce4affSfengbojiang 	int		(*sv_fixup)(uintptr_t *, struct image_params *);
108a9643ea8Slogwang 					/* stack fixup function */
109a9643ea8Slogwang 	void		(*sv_sendsig)(void (*)(int), struct ksiginfo *, struct __sigset *);
110a9643ea8Slogwang 			    		/* send signal */
111a9643ea8Slogwang 	char 		*sv_sigcode;	/* start of sigtramp code */
112a9643ea8Slogwang 	int 		*sv_szsigcode;	/* size of sigtramp code */
113a9643ea8Slogwang 	char		*sv_name;	/* name of binary type */
114a9643ea8Slogwang 	int		(*sv_coredump)(struct thread *, struct vnode *, off_t, int);
115a9643ea8Slogwang 					/* function to dump core, or NULL */
116a9643ea8Slogwang 	int		(*sv_imgact_try)(struct image_params *);
117*22ce4affSfengbojiang 	void		(*sv_stackgap)(struct image_params *, uintptr_t *);
118*22ce4affSfengbojiang 	int		(*sv_copyout_auxargs)(struct image_params *,
119*22ce4affSfengbojiang 			    uintptr_t);
120a9643ea8Slogwang 	int		sv_minsigstksz;	/* minimum signal stack size */
121a9643ea8Slogwang 	vm_offset_t	sv_minuser;	/* VM_MIN_ADDRESS */
122a9643ea8Slogwang 	vm_offset_t	sv_maxuser;	/* VM_MAXUSER_ADDRESS */
123a9643ea8Slogwang 	vm_offset_t	sv_usrstack;	/* USRSTACK */
124a9643ea8Slogwang 	vm_offset_t	sv_psstrings;	/* PS_STRINGS */
125a9643ea8Slogwang 	int		sv_stackprot;	/* vm protection for stack */
126*22ce4affSfengbojiang 	int		(*sv_copyout_strings)(struct image_params *,
127*22ce4affSfengbojiang 			    uintptr_t *);
128a9643ea8Slogwang 	void		(*sv_setregs)(struct thread *, struct image_params *,
129*22ce4affSfengbojiang 			    uintptr_t);
130a9643ea8Slogwang 	void		(*sv_fixlimit)(struct rlimit *, int);
131a9643ea8Slogwang 	u_long		*sv_maxssiz;
132a9643ea8Slogwang 	u_int		sv_flags;
133a9643ea8Slogwang 	void		(*sv_set_syscall_retval)(struct thread *, int);
134*22ce4affSfengbojiang 	int		(*sv_fetch_syscall_args)(struct thread *);
135a9643ea8Slogwang 	const char	**sv_syscallnames;
136a9643ea8Slogwang 	vm_offset_t	sv_timekeep_base;
137a9643ea8Slogwang 	vm_offset_t	sv_shared_page_base;
138a9643ea8Slogwang 	vm_offset_t	sv_shared_page_len;
139a9643ea8Slogwang 	vm_offset_t	sv_sigcode_base;
140a9643ea8Slogwang 	void		*sv_shared_page_obj;
141a9643ea8Slogwang 	void		(*sv_schedtail)(struct thread *);
142a9643ea8Slogwang 	void		(*sv_thread_detach)(struct thread *);
143a9643ea8Slogwang 	int		(*sv_trap)(struct thread *);
144*22ce4affSfengbojiang 	u_long		*sv_hwcap;	/* Value passed in AT_HWCAP. */
145*22ce4affSfengbojiang 	u_long		*sv_hwcap2;	/* Value passed in AT_HWCAP2. */
146*22ce4affSfengbojiang 	const char	*(*sv_machine_arch)(struct proc *);
147*22ce4affSfengbojiang 	vm_offset_t	sv_fxrng_gen_base;
148*22ce4affSfengbojiang 	void		(*sv_onexec)(struct proc *, struct image_params *);
149*22ce4affSfengbojiang 	void		(*sv_onexit)(struct proc *);
150*22ce4affSfengbojiang 	void		(*sv_ontdexit)(struct thread *td);
151a9643ea8Slogwang };
152a9643ea8Slogwang 
153a9643ea8Slogwang #define	SV_ILP32	0x000100	/* 32-bit executable. */
154a9643ea8Slogwang #define	SV_LP64		0x000200	/* 64-bit executable. */
155a9643ea8Slogwang #define	SV_IA32		0x004000	/* Intel 32-bit executable. */
156a9643ea8Slogwang #define	SV_AOUT		0x008000	/* a.out executable. */
157a9643ea8Slogwang #define	SV_SHP		0x010000	/* Shared page. */
158a9643ea8Slogwang #define	SV_CAPSICUM	0x020000	/* Force cap_enter() on startup. */
159*22ce4affSfengbojiang #define	SV_TIMEKEEP	0x040000	/* Shared page timehands. */
160*22ce4affSfengbojiang #define	SV_ASLR		0x080000	/* ASLR allowed. */
161*22ce4affSfengbojiang #define	SV_RNG_SEED_VER	0x100000	/* random(4) reseed generation. */
162a9643ea8Slogwang 
163a9643ea8Slogwang #define	SV_ABI_MASK	0xff
164a9643ea8Slogwang #define	SV_PROC_FLAG(p, x)	((p)->p_sysent->sv_flags & (x))
165a9643ea8Slogwang #define	SV_PROC_ABI(p)		((p)->p_sysent->sv_flags & SV_ABI_MASK)
166a9643ea8Slogwang #define	SV_CURPROC_FLAG(x)	SV_PROC_FLAG(curproc, x)
167a9643ea8Slogwang #define	SV_CURPROC_ABI()	SV_PROC_ABI(curproc)
168a9643ea8Slogwang /* same as ELFOSABI_XXX, to prevent header pollution */
169a9643ea8Slogwang #define	SV_ABI_LINUX	3
170a9643ea8Slogwang #define	SV_ABI_FREEBSD 	9
171a9643ea8Slogwang #define	SV_ABI_CLOUDABI	17
172a9643ea8Slogwang #define	SV_ABI_UNDEF	255
173a9643ea8Slogwang 
174a9643ea8Slogwang #ifdef _KERNEL
175a9643ea8Slogwang extern struct sysentvec aout_sysvec;
176a9643ea8Slogwang extern struct sysent sysent[];
177a9643ea8Slogwang extern const char *syscallnames[];
178a9643ea8Slogwang 
179a9643ea8Slogwang #define	NO_SYSCALL (-1)
180a9643ea8Slogwang 
181a9643ea8Slogwang struct module;
182a9643ea8Slogwang 
183a9643ea8Slogwang struct syscall_module_data {
184a9643ea8Slogwang 	int	(*chainevh)(struct module *, int, void *); /* next handler */
185a9643ea8Slogwang 	void	*chainarg;		/* arg for next event handler */
186a9643ea8Slogwang 	int	*offset;		/* offset into sysent */
187a9643ea8Slogwang 	struct sysent *new_sysent;	/* new sysent */
188a9643ea8Slogwang 	struct sysent old_sysent;	/* old sysent */
189a9643ea8Slogwang 	int	flags;			/* flags for syscall_register */
190a9643ea8Slogwang };
191a9643ea8Slogwang 
192*22ce4affSfengbojiang /* separate initialization vector so it can be used in a substructure */
193*22ce4affSfengbojiang #define SYSENT_INIT_VALS(_syscallname) {			\
194*22ce4affSfengbojiang 	.sy_narg = (sizeof(struct _syscallname ## _args )	\
195a9643ea8Slogwang 	    / sizeof(register_t)),				\
196*22ce4affSfengbojiang 	.sy_call = (sy_call_t *)&sys_##_syscallname,		\
197*22ce4affSfengbojiang 	.sy_auevent = SYS_AUE_##_syscallname,			\
198*22ce4affSfengbojiang 	.sy_systrace_args_func = NULL,				\
199*22ce4affSfengbojiang 	.sy_entry = 0,						\
200*22ce4affSfengbojiang 	.sy_return = 0,						\
201*22ce4affSfengbojiang 	.sy_flags = 0,						\
202*22ce4affSfengbojiang 	.sy_thrcnt = 0						\
203a9643ea8Slogwang }
204a9643ea8Slogwang 
205*22ce4affSfengbojiang #define	MAKE_SYSENT(syscallname)				\
206*22ce4affSfengbojiang static struct sysent syscallname##_sysent = SYSENT_INIT_VALS(syscallname);
207*22ce4affSfengbojiang 
208a9643ea8Slogwang #define	MAKE_SYSENT_COMPAT(syscallname)				\
209a9643ea8Slogwang static struct sysent syscallname##_sysent = {			\
210a9643ea8Slogwang 	(sizeof(struct syscallname ## _args )			\
211a9643ea8Slogwang 	    / sizeof(register_t)),				\
212a9643ea8Slogwang 	(sy_call_t *)& syscallname,				\
213a9643ea8Slogwang 	SYS_AUE_##syscallname					\
214a9643ea8Slogwang }
215a9643ea8Slogwang 
216a9643ea8Slogwang #define SYSCALL_MODULE(name, offset, new_sysent, evh, arg)	\
217a9643ea8Slogwang static struct syscall_module_data name##_syscall_mod = {	\
218a9643ea8Slogwang 	evh, arg, offset, new_sysent, { 0, NULL, AUE_NULL }	\
219a9643ea8Slogwang };								\
220a9643ea8Slogwang 								\
221a9643ea8Slogwang static moduledata_t name##_mod = {				\
222a9643ea8Slogwang 	"sys/" #name,						\
223a9643ea8Slogwang 	syscall_module_handler,					\
224a9643ea8Slogwang 	&name##_syscall_mod					\
225a9643ea8Slogwang };								\
226a9643ea8Slogwang DECLARE_MODULE(name, name##_mod, SI_SUB_SYSCALLS, SI_ORDER_MIDDLE)
227a9643ea8Slogwang 
228a9643ea8Slogwang #define	SYSCALL_MODULE_HELPER(syscallname)			\
229a9643ea8Slogwang static int syscallname##_syscall = SYS_##syscallname;		\
230a9643ea8Slogwang MAKE_SYSENT(syscallname);					\
231a9643ea8Slogwang SYSCALL_MODULE(syscallname,					\
232a9643ea8Slogwang     & syscallname##_syscall, & syscallname##_sysent,		\
233a9643ea8Slogwang     NULL, NULL)
234a9643ea8Slogwang 
235a9643ea8Slogwang #define	SYSCALL_MODULE_PRESENT(syscallname)				\
236a9643ea8Slogwang 	(sysent[SYS_##syscallname].sy_call != (sy_call_t *)lkmnosys &&	\
237a9643ea8Slogwang 	sysent[SYS_##syscallname].sy_call != (sy_call_t *)lkmressys)
238a9643ea8Slogwang 
239a9643ea8Slogwang /*
240a9643ea8Slogwang  * Syscall registration helpers with resource allocation handling.
241a9643ea8Slogwang  */
242a9643ea8Slogwang struct syscall_helper_data {
243a9643ea8Slogwang 	struct sysent new_sysent;
244a9643ea8Slogwang 	struct sysent old_sysent;
245a9643ea8Slogwang 	int syscall_no;
246a9643ea8Slogwang 	int registered;
247a9643ea8Slogwang };
248*22ce4affSfengbojiang #define SYSCALL_INIT_HELPER_F(syscallname, flags) {		\
249a9643ea8Slogwang     .new_sysent = {						\
250a9643ea8Slogwang 	.sy_narg = (sizeof(struct syscallname ## _args )	\
251a9643ea8Slogwang 	    / sizeof(register_t)),				\
252a9643ea8Slogwang 	.sy_call = (sy_call_t *)& sys_ ## syscallname,		\
253*22ce4affSfengbojiang 	.sy_auevent = SYS_AUE_##syscallname,			\
254*22ce4affSfengbojiang 	.sy_flags = (flags)					\
255a9643ea8Slogwang     },								\
256a9643ea8Slogwang     .syscall_no = SYS_##syscallname				\
257a9643ea8Slogwang }
258*22ce4affSfengbojiang #define SYSCALL_INIT_HELPER_COMPAT_F(syscallname, flags) {	\
259a9643ea8Slogwang     .new_sysent = {						\
260a9643ea8Slogwang 	.sy_narg = (sizeof(struct syscallname ## _args )	\
261a9643ea8Slogwang 	    / sizeof(register_t)),				\
262a9643ea8Slogwang 	.sy_call = (sy_call_t *)& syscallname,			\
263*22ce4affSfengbojiang 	.sy_auevent = SYS_AUE_##syscallname,			\
264*22ce4affSfengbojiang 	.sy_flags = (flags)					\
265a9643ea8Slogwang     },								\
266a9643ea8Slogwang     .syscall_no = SYS_##syscallname				\
267a9643ea8Slogwang }
268*22ce4affSfengbojiang #define SYSCALL_INIT_HELPER(syscallname)			\
269*22ce4affSfengbojiang     SYSCALL_INIT_HELPER_F(syscallname, 0)
270*22ce4affSfengbojiang #define SYSCALL_INIT_HELPER_COMPAT(syscallname)			\
271*22ce4affSfengbojiang     SYSCALL_INIT_HELPER_COMPAT_F(syscallname, 0)
272a9643ea8Slogwang #define SYSCALL_INIT_LAST {					\
273a9643ea8Slogwang     .syscall_no = NO_SYSCALL					\
274a9643ea8Slogwang }
275a9643ea8Slogwang 
276a9643ea8Slogwang int	syscall_module_handler(struct module *mod, int what, void *arg);
277a9643ea8Slogwang int	syscall_helper_register(struct syscall_helper_data *sd, int flags);
278a9643ea8Slogwang int	syscall_helper_unregister(struct syscall_helper_data *sd);
279*22ce4affSfengbojiang /* Implementation, exposed for COMPAT code */
280*22ce4affSfengbojiang int	kern_syscall_register(struct sysent *sysents, int *offset,
281*22ce4affSfengbojiang 	    struct sysent *new_sysent, struct sysent *old_sysent, int flags);
282*22ce4affSfengbojiang int	kern_syscall_deregister(struct sysent *sysents, int offset,
283*22ce4affSfengbojiang 	    const struct sysent *old_sysent);
284*22ce4affSfengbojiang int	kern_syscall_module_handler(struct sysent *sysents,
285*22ce4affSfengbojiang 	    struct module *mod, int what, void *arg);
286*22ce4affSfengbojiang int	kern_syscall_helper_register(struct sysent *sysents,
287*22ce4affSfengbojiang 	    struct syscall_helper_data *sd, int flags);
288*22ce4affSfengbojiang int	kern_syscall_helper_unregister(struct sysent *sysents,
289*22ce4affSfengbojiang 	    struct syscall_helper_data *sd);
290a9643ea8Slogwang 
291a9643ea8Slogwang struct proc;
292a9643ea8Slogwang const char *syscallname(struct proc *p, u_int code);
293a9643ea8Slogwang 
294a9643ea8Slogwang /* Special purpose system call functions. */
295a9643ea8Slogwang struct nosys_args;
296a9643ea8Slogwang 
297a9643ea8Slogwang int	lkmnosys(struct thread *, struct nosys_args *);
298a9643ea8Slogwang int	lkmressys(struct thread *, struct nosys_args *);
299a9643ea8Slogwang 
300a9643ea8Slogwang int	syscall_thread_enter(struct thread *td, struct sysent *se);
301a9643ea8Slogwang void	syscall_thread_exit(struct thread *td, struct sysent *se);
302a9643ea8Slogwang 
303a9643ea8Slogwang int shared_page_alloc(int size, int align);
304a9643ea8Slogwang int shared_page_fill(int size, int align, const void *data);
305a9643ea8Slogwang void shared_page_write(int base, int size, const void *data);
306a9643ea8Slogwang void exec_sysvec_init(void *param);
307*22ce4affSfengbojiang void exec_sysvec_init_secondary(struct sysentvec *sv, struct sysentvec *sv2);
308a9643ea8Slogwang void exec_inittk(void);
309a9643ea8Slogwang 
310a9643ea8Slogwang #define INIT_SYSENTVEC(name, sv)					\
311a9643ea8Slogwang     SYSINIT(name, SI_SUB_EXEC, SI_ORDER_ANY,				\
312a9643ea8Slogwang 	(sysinit_cfunc_t)exec_sysvec_init, sv);
313a9643ea8Slogwang 
314a9643ea8Slogwang #endif /* _KERNEL */
315a9643ea8Slogwang 
316a9643ea8Slogwang #endif /* !_SYS_SYSENT_H_ */
317