12255Ssos/*-
22255Ssos * Copyright (c) 1982, 1988, 1991 The Regents of the University of California.
32255Ssos * All rights reserved.
42255Ssos *
52255Ssos * Redistribution and use in source and binary forms, with or without
62255Ssos * modification, are permitted provided that the following conditions
72255Ssos * are met:
82255Ssos * 1. Redistributions of source code must retain the above copyright
92255Ssos *    notice, this list of conditions and the following disclaimer.
102255Ssos * 2. Redistributions in binary form must reproduce the above copyright
112255Ssos *    notice, this list of conditions and the following disclaimer in the
122255Ssos *    documentation and/or other materials provided with the distribution.
132255Ssos * 4. Neither the name of the University nor the names of its contributors
142255Ssos *    may be used to endorse or promote products derived from this software
152255Ssos *    without specific prior written permission.
162255Ssos *
172255Ssos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
182255Ssos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
192255Ssos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
202255Ssos * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
212255Ssos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
222255Ssos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
232255Ssos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
242255Ssos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
252255Ssos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
262255Ssos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
272255Ssos * SUCH DAMAGE.
282255Ssos *
2950477Speter * $FreeBSD$
302255Ssos */
312255Ssos
322255Ssos#ifndef _SYS_SYSENT_H_
3314917Sbde#define	_SYS_SYSENT_H_
342255Ssos
35146782Srwatson#include <bsm/audit.h>
36146782Srwatson
37169565Sjhbstruct rlimit;
38160941Sjbstruct sysent;
3983366Sjulianstruct thread;
40151316Sdavidxustruct ksiginfo;
4133054Sbde
4292719Salfredtypedef	int	sy_call_t(struct thread *, void *);
4310905Sbde
44160941Sjb/* Used by the machine dependent syscall() code. */
45211608Srpaulotypedef	void (*systrace_probe_func_t)(u_int32_t, int, struct sysent *, void *,
46211608Srpaulo    int);
47160941Sjb
48160941Sjb/*
49160941Sjb * Used by loaded syscalls to convert arguments to a DTrace array
50160941Sjb * of 64-bit arguments.
51160941Sjb */
52184698Srodrigctypedef	void (*systrace_args_func_t)(int, void *, u_int64_t *, int *);
53160941Sjb
54160941Sjbextern systrace_probe_func_t	systrace_probe_func;
55160941Sjb
56183159Sjhbstruct sysent {			/* system call table */
572255Ssos	int	sy_narg;	/* number of arguments */
5810905Sbde	sy_call_t *sy_call;	/* implementing function */
59146782Srwatson	au_event_t sy_auevent;	/* audit event associated with syscall */
60160941Sjb	systrace_args_func_t sy_systrace_args_func;
61160941Sjb				/* optional argument conversion function. */
62183159Sjhb	u_int32_t sy_entry;	/* DTrace entry ID for systrace. */
63183159Sjhb	u_int32_t sy_return;	/* DTrace return ID for systrace. */
64193234Srwatson	u_int32_t sy_flags;	/* General flags for system calls. */
65209579Skib	u_int32_t sy_thrcnt;
662255Ssos};
6758717Sdillon
68219131Srwatson/*
69219131Srwatson * A system call is permitted in capability mode.
70219131Srwatson */
71219131Srwatson#define	SYF_CAPENABLED	0x00000001
72219131Srwatson
73209579Skib#define	SY_THR_FLAGMASK	0x7
74209579Skib#define	SY_THR_STATIC	0x1
75209579Skib#define	SY_THR_DRAINING	0x2
76209579Skib#define	SY_THR_ABSENT	0x4
77209579Skib#define	SY_THR_INCR	0x8
78209579Skib
7910905Sbdestruct image_params;
8055152Sbdestruct __sigset;
81208453Skibstruct syscall_args;
8214331Speterstruct trapframe;
8350791Smarcelstruct vnode;
8410905Sbde
852255Ssosstruct sysentvec {
862255Ssos	int		sv_size;	/* number of entries */
872255Ssos	struct sysent	*sv_table;	/* pointer to sysent */
8814917Sbde	u_int		sv_mask;	/* optional mask to index */
893472Ssos	int		sv_sigsize;	/* size of signal translation table */
903472Ssos	int		*sv_sigtbl;	/* signal translation table */
9115036Ssmpatel	int		sv_errsize;	/* size of errno translation table */
923472Ssos	int 		*sv_errtbl;	/* errno translation table */
9392719Salfred	int		(*sv_transtrap)(int, int);
9435496Seivind					/* translate trap-to-signal mapping */
9592719Salfred	int		(*sv_fixup)(register_t **, struct image_params *);
9610905Sbde					/* stack fixup function */
97151316Sdavidxu	void		(*sv_sendsig)(void (*)(int), struct ksiginfo *, struct __sigset *);
98151316Sdavidxu			    		/* send signal */
9914331Speter	char 		*sv_sigcode;	/* start of sigtramp code */
10014331Speter	int 		*sv_szsigcode;	/* size of sigtramp code */
10193008Sbde	void		(*sv_prepsyscall)(struct trapframe *, int *, u_int *,
10293008Sbde			    caddr_t *);
10316474Sdyson	char		*sv_name;	/* name of binary type */
104204552Salfred	int		(*sv_coredump)(struct thread *, struct vnode *, off_t, int);
10539154Sjdp					/* function to dump core, or NULL */
10692719Salfred	int		(*sv_imgact_try)(struct image_params *);
10768520Smarcel	int		sv_minsigstksz;	/* minimum signal stack size */
108102808Sjake	int		sv_pagesize;	/* pagesize */
109102808Sjake	vm_offset_t	sv_minuser;	/* VM_MIN_ADDRESS */
110102808Sjake	vm_offset_t	sv_maxuser;	/* VM_MAXUSER_ADDRESS */
111102808Sjake	vm_offset_t	sv_usrstack;	/* USRSTACK */
112102808Sjake	vm_offset_t	sv_psstrings;	/* PS_STRINGS */
113102808Sjake	int		sv_stackprot;	/* vm protection for stack */
114100384Speter	register_t	*(*sv_copyout_strings)(struct image_params *);
115205642Snwhitehorn	void		(*sv_setregs)(struct thread *, struct image_params *,
116205642Snwhitehorn			    u_long);
117169565Sjhb	void		(*sv_fixlimit)(struct rlimit *, int);
118171410Sjhb	u_long		*sv_maxssiz;
119185169Skib	u_int		sv_flags;
120208453Skib	void		(*sv_set_syscall_retval)(struct thread *, int);
121208453Skib	int		(*sv_fetch_syscall_args)(struct thread *, struct
122208453Skib			    syscall_args *);
123208453Skib	const char	**sv_syscallnames;
124217151Skib	vm_offset_t	sv_shared_page_base;
125217151Skib	vm_offset_t	sv_shared_page_len;
126217151Skib	vm_offset_t	sv_sigcode_base;
127237433Skib	vm_offset_t	sv_timekeep_base;
128237433Skib	int		sv_timekeep_off;
129237433Skib	int		sv_timekeep_curr;
130237433Skib	uint32_t	sv_timekeep_gen;
131217151Skib	void		*sv_shared_page_obj;
132219405Sdchagin	void		(*sv_schedtail)(struct thread *);
133293490Sdchagin	void		(*sv_thread_detach)(struct thread *);
134294136Sdchagin	int		(*sv_trap)(struct thread *);
1352255Ssos};
1362255Ssos
137185169Skib#define	SV_ILP32	0x000100
138185169Skib#define	SV_LP64		0x000200
139185169Skib#define	SV_IA32		0x004000
140185169Skib#define	SV_AOUT		0x008000
141217151Skib#define	SV_SHP		0x010000
142185169Skib
143185169Skib#define	SV_ABI_MASK	0xff
144301428Sdchagin#define	SV_ABI_ERRNO(p, e)	((p)->p_sysent->sv_errsize <= 0 ? e :	\
145301428Sdchagin	((e) >= (p)->p_sysent->sv_errsize ? -1 : (p)->p_sysent->sv_errtbl[e]))
146217896Sdchagin#define	SV_PROC_FLAG(p, x)	((p)->p_sysent->sv_flags & (x))
147217896Sdchagin#define	SV_PROC_ABI(p)		((p)->p_sysent->sv_flags & SV_ABI_MASK)
148217896Sdchagin#define	SV_CURPROC_FLAG(x)	SV_PROC_FLAG(curproc, x)
149217896Sdchagin#define	SV_CURPROC_ABI()	SV_PROC_ABI(curproc)
150185169Skib/* same as ELFOSABI_XXX, to prevent header pollution */
151185169Skib#define	SV_ABI_LINUX	3
152185169Skib#define	SV_ABI_FREEBSD 	9
153185169Skib#define	SV_ABI_UNDEF	255
154185169Skib
15555205Speter#ifdef _KERNEL
1567090Sbdeextern struct sysentvec aout_sysvec;
1572255Ssosextern struct sysent sysent[];
158208453Skibextern const char *syscallnames[];
1592255Ssos
160226388Skib#if defined(__amd64__) || defined(__ia64__)
161226388Skibextern int i386_read_exec;
162226388Skib#endif
163226388Skib
164183159Sjhb#define	NO_SYSCALL (-1)
16542433Sdfr
16642433Sdfrstruct module;
16742433Sdfr
16842433Sdfrstruct syscall_module_data {
169183159Sjhb	int	(*chainevh)(struct module *, int, void *); /* next handler */
170183159Sjhb	void	*chainarg;		/* arg for next event handler */
171183159Sjhb	int	*offset;		/* offset into sysent */
172183159Sjhb	struct sysent *new_sysent;	/* new sysent */
173183159Sjhb	struct sysent old_sysent;	/* old sysent */
17442433Sdfr};
17542433Sdfr
176303395Sjulian/* separate initialization vector so it can be used in a substructure */
177303395Sjulian#define SYSENT_INIT_VALS(_syscallname) {			\
178303395Sjulian	.sy_narg = (sizeof(struct _syscallname ## _args )	\
179183159Sjhb	    / sizeof(register_t)),				\
180303395Sjulian	.sy_call = (sy_call_t *)&sys_##_syscallname,		\
181303395Sjulian	.sy_auevent = SYS_AUE_##_syscallname,			\
182303395Sjulian	.sy_systrace_args_func = NULL,				\
183303395Sjulian	.sy_entry = 0,						\
184303395Sjulian	.sy_return = 0,						\
185303395Sjulian	.sy_flags = 0,						\
186303395Sjulian	.sy_thrcnt = 0						\
187303395Sjulian}
188225617Skmacy
189303395Sjulian#define	MAKE_SYSENT(syscallname)				\
190303395Sjulianstatic struct sysent syscallname##_sysent = SYSENT_INIT_VALS(syscallname);
191303395Sjulian
192225617Skmacy#define	MAKE_SYSENT_COMPAT(syscallname)				\
193225617Skmacystatic struct sysent syscallname##_sysent = {			\
194225617Skmacy	(sizeof(struct syscallname ## _args )			\
195225617Skmacy	    / sizeof(register_t)),				\
196209587Skib	(sy_call_t *)& syscallname,				\
197209587Skib	SYS_AUE_##syscallname					\
198168268Sjhb}
199183159Sjhb
200183159Sjhb#define SYSCALL_MODULE(name, offset, new_sysent, evh, arg)	\
201183159Sjhbstatic struct syscall_module_data name##_syscall_mod = {	\
202183159Sjhb	evh, arg, offset, new_sysent, { 0, NULL, AUE_NULL }	\
203183159Sjhb};								\
204183159Sjhb								\
205183159Sjhbstatic moduledata_t name##_mod = {				\
206205320Skib	"sys/" #name,						\
207183159Sjhb	syscall_module_handler,					\
208183159Sjhb	&name##_syscall_mod					\
209183159Sjhb};								\
210160882SjhbDECLARE_MODULE(name, name##_mod, SI_SUB_SYSCALLS, SI_ORDER_MIDDLE)
21142433Sdfr
212183159Sjhb#define	SYSCALL_MODULE_HELPER(syscallname)			\
213183159Sjhbstatic int syscallname##_syscall = SYS_##syscallname;		\
214183159SjhbMAKE_SYSENT(syscallname);					\
215183159SjhbSYSCALL_MODULE(syscallname,					\
216183159Sjhb    & syscallname##_syscall, & syscallname##_sysent,		\
217183159Sjhb    NULL, NULL)
21869449Salfred
219183159Sjhb#define	SYSCALL_MODULE_PRESENT(syscallname)				\
220183159Sjhb	(sysent[SYS_##syscallname].sy_call != (sy_call_t *)lkmnosys &&	\
221183159Sjhb	sysent[SYS_##syscallname].sy_call != (sy_call_t *)lkmressys)
222165402Sjkim
223205321Skib/*
224205321Skib * Syscall registration helpers with resource allocation handling.
225205321Skib */
226205321Skibstruct syscall_helper_data {
227205321Skib	struct sysent new_sysent;
228205321Skib	struct sysent old_sysent;
229205321Skib	int syscall_no;
230205321Skib	int registered;
231205321Skib};
232205321Skib#define SYSCALL_INIT_HELPER(syscallname) {			\
233205321Skib    .new_sysent = {						\
234205321Skib	.sy_narg = (sizeof(struct syscallname ## _args )	\
235205321Skib	    / sizeof(register_t)),				\
236225617Skmacy	.sy_call = (sy_call_t *)& sys_ ## syscallname,		\
237225617Skmacy	.sy_auevent = SYS_AUE_##syscallname			\
238225617Skmacy    },								\
239225617Skmacy    .syscall_no = SYS_##syscallname				\
240225617Skmacy}
241225617Skmacy#define SYSCALL_INIT_HELPER_COMPAT(syscallname) {		\
242225617Skmacy    .new_sysent = {						\
243225617Skmacy	.sy_narg = (sizeof(struct syscallname ## _args )	\
244225617Skmacy	    / sizeof(register_t)),				\
245205321Skib	.sy_call = (sy_call_t *)& syscallname,			\
246205321Skib	.sy_auevent = SYS_AUE_##syscallname			\
247205321Skib    },								\
248205321Skib    .syscall_no = SYS_##syscallname				\
249205321Skib}
250205321Skib#define SYSCALL_INIT_LAST {					\
251205321Skib    .syscall_no = NO_SYSCALL					\
252205321Skib}
253205321Skib
254183159Sjhbint	syscall_register(int *offset, struct sysent *new_sysent,
25593008Sbde	    struct sysent *old_sysent);
256183159Sjhbint	syscall_deregister(int *offset, struct sysent *old_sysent);
257183159Sjhbint	syscall_module_handler(struct module *mod, int what, void *arg);
258205321Skibint	syscall_helper_register(struct syscall_helper_data *sd);
259205321Skibint	syscall_helper_unregister(struct syscall_helper_data *sd);
26042433Sdfr
261208566Skibstruct proc;
262208566Skibconst char *syscallname(struct proc *p, u_int code);
263208566Skib
264183361Sjhb/* Special purpose system call functions. */
265183361Sjhbstruct nosys_args;
266183361Sjhb
267183361Sjhbint	lkmnosys(struct thread *, struct nosys_args *);
268183361Sjhbint	lkmressys(struct thread *, struct nosys_args *);
269183361Sjhb
270209579Skibint	syscall_thread_enter(struct thread *td, struct sysent *se);
271209579Skibvoid	syscall_thread_exit(struct thread *td, struct sysent *se);
272209579Skib
273237431Skibint shared_page_alloc(int size, int align);
274237431Skibint shared_page_fill(int size, int align, const void *data);
275237431Skibvoid shared_page_write(int base, int size, const void *data);
276217151Skibvoid exec_sysvec_init(void *param);
277217151Skib
278217151Skib#define INIT_SYSENTVEC(name, sv)					\
279217151Skib    SYSINIT(name, SI_SUB_EXEC, SI_ORDER_ANY,				\
280217151Skib	(sysinit_cfunc_t)exec_sysvec_init, sv);
281217151Skib
28255205Speter#endif /* _KERNEL */
28342433Sdfr
28414917Sbde#endif /* !_SYS_SYSENT_H_ */
285