code:
/*-
 * Copyright (c) 2006 nCircle Network Security, Inc.
 * All rights reserved.
 *
 * This software was developed by Robert N. M. Watson for the TrustedBSD
 * Project under contract to nCircle Network Security, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY,
 * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/priv.h 223735 2011-07-03 12:22:02Z bz $
 */

/*
 * Privilege checking interface for BSD kernel.
 */
#ifndef _SYS_PRIV_H_
#define	_SYS_PRIV_H_

/*
 * Privilege list, sorted loosely by kernel subsystem.
 *
 * Think carefully before adding or reusing one of these privileges -- are
 * there existing instances referring to the same privilege?  Third party
 * vendors may request the assignment of privileges to be used in loadable
 * modules.  Particular numeric privilege assignments are part of the
 * loadable kernel module ABI, and should not be changed across minor
 * releases.
 *
 * When adding a new privilege, remember to determine if it's appropriate for
 * use in jail, and update the privilege switch in kern_jail.c as necessary.
 */

/*
 * Track beginning of privilege list.
 */
#define	_PRIV_LOWEST	1

/*
 * The remaining privileges typically correspond to one or a small
 * number of specific privilege checks, and have (relatively) precise
 * meanings.  They are loosely sorted into a set of base system
 * privileges, such as the ability to reboot, and then loosely by
 * subsystem, indicated by a subsystem name.
 */
#define	_PRIV_ROOT		1	/* Removed. */
#define	PRIV_ACCT		2	/* Manage process accounting. */
#define	PRIV_MAXFILES		3	/* Exceed system open files limit. */
#define	PRIV_MAXPROC		4	/* Exceed system processes limit. */
#define	PRIV_KTRACE		5	/* Set/clear KTRFAC_ROOT on ktrace. */
#define	PRIV_SETDUMPER		6	/* Configure dump device. */
#define	PRIV_REBOOT		8	/* Can reboot system. */
#define	PRIV_SWAPON		9	/* Can swapon(). */
#define	PRIV_SWAPOFF		10	/* Can swapoff(). */
#define	PRIV_MSGBUF		11	/* Can read kernel message buffer. */
#define	PRIV_IO			12	/* Can perform low-level I/O. */
#define	PRIV_KEYBOARD		13	/* Reprogram keyboard. */
#define	PRIV_DRIVER		14	/* Low-level driver privilege. */
#define	PRIV_ADJTIME		15	/* Set time adjustment. */
#define	PRIV_NTP_ADJTIME	16	/* Set NTP time adjustment. */
#define	PRIV_CLOCK_SETTIME	17	/* Can call clock_settime. */
#define	PRIV_SETTIMEOFDAY	18	/* Can call settimeofday. */
#define	_PRIV_SETHOSTID		19	/* Removed. */
#define	_PRIV_SETDOMAINNAME	20	/* Removed. */

/*
 * Audit subsystem privileges.
 */
#define	PRIV_AUDIT_CONTROL	40	/* Can configure audit. */
#define	PRIV_AUDIT_FAILSTOP	41	/* Can run during audit fail stop. */
#define	PRIV_AUDIT_GETAUDIT	42	/* Can get proc audit properties. */
#define	PRIV_AUDIT_SETAUDIT	43	/* Can set proc audit properties. */
#define	PRIV_AUDIT_SUBMIT	44	/* Can submit an audit record. */

/*
 * Credential management privileges.
 */
#define	PRIV_CRED_SETUID	50	/* setuid. */
#define	PRIV_CRED_SETEUID	51	/* seteuid to !ruid and !svuid. */
#define	PRIV_CRED_SETGID	52	/* setgid. */
#define	PRIV_CRED_SETEGID	53	/* setgid to !rgid and !svgid. */
#define	PRIV_CRED_SETGROUPS	54	/* Set process additional groups. */
#define	PRIV_CRED_SETREUID	55	/* setreuid. */
#define	PRIV_CRED_SETREGID	56	/* setregid. */
#define	PRIV_CRED_SETRESUID	57	/* setresuid. */
#define	PRIV_CRED_SETRESGID	58	/* setresgid. */
#define	PRIV_SEEOTHERGIDS	59	/* Exempt bsd.seeothergids. */
#define	PRIV_SEEOTHERUIDS	60	/* Exempt bsd.seeotheruids. */

/*
 * Debugging privileges.
 */
#define	PRIV_DEBUG_DIFFCRED	80	/* Exempt debugging other users. */
#define	PRIV_DEBUG_SUGID	81	/* Exempt debugging setuid proc. */
#define	PRIV_DEBUG_UNPRIV	82	/* Exempt unprivileged debug limit. */

/*
 * Dtrace privileges.
 */
#define	PRIV_DTRACE_KERNEL	90	/* Allow use of DTrace on the kernel. */
#define	PRIV_DTRACE_PROC	91	/* Allow attaching DTrace to process. */
#define	PRIV_DTRACE_USER	92	/* Process may submit DTrace events. */

/*
 * Firmware privilegs.
 */
#define	PRIV_FIRMWARE_LOAD	100	/* Can load firmware. */

/*
 * Jail privileges.
 */
#define	PRIV_JAIL_ATTACH	110	/* Attach to a jail. */
#define	PRIV_JAIL_SET		111	/* Set jail parameters. */
#define	PRIV_JAIL_REMOVE	112	/* Remove a jail. */

/*
 * Kernel environment priveleges.
 */
#define	PRIV_KENV_SET		120	/* Set kernel env. variables. */
#define	PRIV_KENV_UNSET		121	/* Unset kernel env. variables. */

/*
 * Loadable kernel module privileges.
 */
#define	PRIV_KLD_LOAD		130	/* Load a kernel module. */
#define	PRIV_KLD_UNLOAD		131	/* Unload a kernel module. */

/*
 * Privileges associated with the MAC Framework and specific MAC policy
 * modules.
 */
#define	PRIV_MAC_PARTITION	140	/* Privilege in mac_partition policy. */
#define	PRIV_MAC_PRIVS		141	/* Privilege in the mac_privs policy. */

/*
 * Process-related privileges.
 */
#define	PRIV_PROC_LIMIT		160	/* Exceed user process limit. */
#define	PRIV_PROC_SETLOGIN	161	/* Can call setlogin. */
#define	PRIV_PROC_SETRLIMIT	162	/* Can raise resources limits. */
#define	PRIV_PROC_SETLOGINCLASS	163	/* Can call setloginclass(2). */

/* System V IPC privileges.
 */
#define	PRIV_IPC_READ		170	/* Can override IPC read perm. */
#define	PRIV_IPC_WRITE		171	/* Can override IPC write perm. */
#define	PRIV_IPC_ADMIN		172	/* Can override IPC owner-only perm. */
#define	PRIV_IPC_MSGSIZE	173	/* Exempt IPC message queue limit. */

/*
 * POSIX message queue privileges.
 */
#define	PRIV_MQ_ADMIN		180	/* Can override msgq owner-only perm. */

/*
 * Performance monitoring counter privileges.
 */
#define	PRIV_PMC_MANAGE		190	/* Can administer PMC. */
#define	PRIV_PMC_SYSTEM		191	/* Can allocate a system-wide PMC. */

/*
 * Scheduling privileges.
 */
#define	PRIV_SCHED_DIFFCRED	200	/* Exempt scheduling other users. */
#define	PRIV_SCHED_SETPRIORITY	201	/* Can set lower nice value for proc. */
#define	PRIV_SCHED_RTPRIO	202	/* Can set real time scheduling. */
#define	PRIV_SCHED_SETPOLICY	203	/* Can set scheduler policy. */
#define	PRIV_SCHED_SET		204	/* Can set thread scheduler. */
#define	PRIV_SCHED_SETPARAM	205	/* Can set thread scheduler params. */
#define	PRIV_SCHED_CPUSET	206	/* Can manipulate cpusets. */
#define	PRIV_SCHED_CPUSET_INTR	207	/* Can adjust IRQ to CPU binding. */

/*
 * POSIX semaphore privileges.
 */
#define	PRIV_SEM_WRITE		220	/* Can override sem write perm. */

/*
 * Signal privileges.
 */
#define	PRIV_SIGNAL_DIFFCRED	230	/* Exempt signalling other users. */
#define	PRIV_SIGNAL_SUGID	231	/* Non-conserv signal setuid proc. */

/*
 * Sysctl privileges.
 */
#define	PRIV_SYSCTL_DEBUG	240	/* Can invoke sysctl.debug. */
#define	PRIV_SYSCTL_WRITE	241	/* Can write sysctls. */
#define	PRIV_SYSCTL_WRITEJAIL	242	/* Can write sysctls, jail permitted. */

/*
 * TTY privileges.
 */
#define	PRIV_TTY_CONSOLE	250	/* Set console to tty. */
#define	PRIV_TTY_DRAINWAIT	251	/* Set tty drain wait time. */
#define	PRIV_TTY_DTRWAIT	252	/* Set DTR wait on tty. */
#define	PRIV_TTY_EXCLUSIVE	253	/* Override tty exclusive flag. */
#define	_PRIV_TTY_PRISON	254	/* Removed. */
#define	PRIV_TTY_STI		255	/* Simulate input on another tty. */
#define	PRIV_TTY_SETA		256	/* Set tty termios structure. */

/*
 * UFS-specific privileges.
 */
#define	PRIV_UFS_EXTATTRCTL	270	/* Can configure EAs on UFS1. */
#define	PRIV_UFS_QUOTAOFF	271	/* quotaoff(). */
#define	PRIV_UFS_QUOTAON	272	/* quotaon(). */
#define	PRIV_UFS_SETUSE		273	/* setuse(). */

/*
 * ZFS-specific privileges.
 */
#define	PRIV_ZFS_POOL_CONFIG	280	/* Can configure ZFS pools. */
#define	PRIV_ZFS_INJECT		281	/* Can inject faults in the ZFS fault
					   injection framework. */
#define	PRIV_ZFS_JAIL		282	/* Can attach/detach ZFS file systems
					   to/from jails. */

/*
 * NFS-specific privileges.
 */
#define	PRIV_NFS_DAEMON		290	/* Can become the NFS daemon. */
#define	PRIV_NFS_LOCKD		291	/* Can become NFS lock daemon. */

/*
 * VFS privileges.
 */
#define	PRIV_VFS_READ		310	/* Override vnode DAC read perm. */
#define	PRIV_VFS_WRITE		311	/* Override vnode DAC write perm. */
#define	PRIV_VFS_ADMIN		312	/* Override vnode DAC admin perm. */
#define	PRIV_VFS_EXEC		313	/* Override vnode DAC exec perm. */
#define	PRIV_VFS_LOOKUP		314	/* Override vnode DAC lookup perm. */
#define	PRIV_VFS_BLOCKRESERVE	315	/* Can use free block reserve. */
#define	PRIV_VFS_CHFLAGS_DEV	316	/* Can chflags() a device node. */
#define	PRIV_VFS_CHOWN		317	/* Can set user; group to non-member. */
#define	PRIV_VFS_CHROOT		318	/* chroot(). */
#define	PRIV_VFS_RETAINSUGID	319	/* Can retain sugid bits on change. */
#define	PRIV_VFS_EXCEEDQUOTA	320	/* Exempt from quota restrictions. */
#define	PRIV_VFS_EXTATTR_SYSTEM	321	/* Operate on system EA namespace. */
#define	PRIV_VFS_FCHROOT	322	/* fchroot(). */
#define	PRIV_VFS_FHOPEN		323	/* Can fhopen(). */
#define	PRIV_VFS_FHSTAT		324	/* Can fhstat(). */
#define	PRIV_VFS_FHSTATFS	325	/* Can fhstatfs(). */
#define	PRIV_VFS_GENERATION	326	/* stat() returns generation number. */
#define	PRIV_VFS_GETFH		327	/* Can retrieve file handles. */
#define	PRIV_VFS_GETQUOTA	328	/* getquota(). */
#define	PRIV_VFS_LINK		329	/* bsd.hardlink_check_uid */
#define	PRIV_VFS_MKNOD_BAD	330	/* Can mknod() to mark bad inodes. */
#define	PRIV_VFS_MKNOD_DEV	331	/* Can mknod() to create dev nodes. */
#define	PRIV_VFS_MKNOD_WHT	332	/* Can mknod() to create whiteout. */
#define	PRIV_VFS_MOUNT		333	/* Can mount(). */
#define	PRIV_VFS_MOUNT_OWNER	334	/* Can manage other users' file systems. */
#define	PRIV_VFS_MOUNT_EXPORTED	335	/* Can set MNT_EXPORTED on mount. */
#define	PRIV_VFS_MOUNT_PERM	336	/* Override dev node perms at mount. */
#define	PRIV_VFS_MOUNT_SUIDDIR	337	/* Can set MNT_SUIDDIR on mount. */
#define	PRIV_VFS_MOUNT_NONUSER	338	/* Can perform a non-user mount. */
#define	PRIV_VFS_SETGID		339	/* Can setgid if not in group. */
#define	PRIV_VFS_SETQUOTA	340	/* setquota(). */
#define	PRIV_VFS_STICKYFILE	341	/* Can set sticky bit on file. */
#define	PRIV_VFS_SYSFLAGS	342	/* Can modify system flags. */
#define	PRIV_VFS_UNMOUNT	343	/* Can unmount(). */
#define	PRIV_VFS_STAT		344	/* Override vnode MAC stat perm. */

/*
 * Virtual memory privileges.
 */
#define	PRIV_VM_MADV_PROTECT	360	/* Can set MADV_PROTECT. */
#define	PRIV_VM_MLOCK		361	/* Can mlock(), mlockall(). */
#define	PRIV_VM_MUNLOCK		362	/* Can munlock(), munlockall(). */
#define	PRIV_VM_SWAP_NOQUOTA	363	/*
					 * Can override the global
					 * swap reservation limits.
					 */
#define	PRIV_VM_SWAP_NORLIMIT	364	/*
					 * Can override the per-uid
					 * swap reservation limits.
					 */

/*
 * Device file system privileges.
 */
#define	PRIV_DEVFS_RULE		370	/* Can manage devfs rules. */
#define	PRIV_DEVFS_SYMLINK	371	/* Can create symlinks in devfs. */

/*
 * Random number generator privileges.
 */
#define	PRIV_RANDOM_RESEED	380	/* Closing /dev/random reseeds. */

/*
 * Network stack privileges.
 */
#define	PRIV_NET_BRIDGE		390	/* Administer bridge. */
#define	PRIV_NET_GRE		391	/* Administer GRE. */
#define	_PRIV_NET_PPP		392	/* Removed. */
#define	_PRIV_NET_SLIP		393	/* Removed. */
#define	PRIV_NET_BPF		394	/* Monitor BPF. */
#define	PRIV_NET_RAW		395	/* Open raw socket. */
#define	PRIV_NET_ROUTE		396	/* Administer routing. */
#define	PRIV_NET_TAP		397	/* Can open tap device. */
#define	PRIV_NET_SETIFMTU	398	/* Set interface MTU. */
#define	PRIV_NET_SETIFFLAGS	399	/* Set interface flags. */
#define	PRIV_NET_SETIFCAP	400	/* Set interface capabilities. */
#define	PRIV_NET_SETIFNAME	401	/* Set interface name. */
#define	PRIV_NET_SETIFMETRIC	402	/* Set interface metrics. */
#define	PRIV_NET_SETIFPHYS	403	/* Set interface physical layer prop. */
#define	PRIV_NET_SETIFMAC	404	/* Set interface MAC label. */
#define	PRIV_NET_ADDMULTI	405	/* Add multicast addr. to ifnet. */
#define	PRIV_NET_DELMULTI	406	/* Delete multicast addr. from ifnet. */
#define	PRIV_NET_HWIOCTL	407	/* Issue hardware ioctl on ifnet. */
#define	PRIV_NET_SETLLADDR	408	/* Set interface link-level address. */
#define	PRIV_NET_ADDIFGROUP	409	/* Add new interface group. */
#define	PRIV_NET_DELIFGROUP	410	/* Delete interface group. */
#define	PRIV_NET_IFCREATE	411	/* Create cloned interface. */
#define	PRIV_NET_IFDESTROY	412	/* Destroy cloned interface. */
#define	PRIV_NET_ADDIFADDR	413	/* Add protocol addr to interface. */
#define	PRIV_NET_DELIFADDR	414	/* Delete protocol addr on interface. */
#define	PRIV_NET_LAGG		415	/* Administer lagg interface. */
#define	PRIV_NET_GIF		416	/* Administer gif interface. */
#define	PRIV_NET_SETIFVNET	417	/* Move interface to vnet. */
#define	PRIV_NET_SETIFDESCR	418	/* Set interface description. */
#define	PRIV_NET_SETIFFIB	419	/* Set interface fib. */

/*
 * 802.11-related privileges.
 */
#define	PRIV_NET80211_GETKEY	440	/* Query 802.11 keys. */
#define	PRIV_NET80211_MANAGE	441	/* Administer 802.11. */

/*
 * AppleTalk privileges.
 */
#define	PRIV_NETATALK_RESERVEDPORT	450	/* Bind low port number. */

/*
 * ATM privileges.
 */
#define	PRIV_NETATM_CFG		460
#define	PRIV_NETATM_ADD		461
#define	PRIV_NETATM_DEL		462
#define	PRIV_NETATM_SET		463

/*
 * Bluetooth privileges.
 */
#define	PRIV_NETBLUETOOTH_RAW	470	/* Open raw bluetooth socket. */

/*
 * Netgraph and netgraph module privileges.
 */
#define	PRIV_NETGRAPH_CONTROL	480	/* Open netgraph control socket. */
#define	PRIV_NETGRAPH_TTY	481	/* Configure tty for netgraph. */

/*
 * IPv4 and IPv6 privileges.
 */
#define	PRIV_NETINET_RESERVEDPORT	490	/* Bind low port number. */
#define	PRIV_NETINET_IPFW	491	/* Administer IPFW firewall. */
#define	PRIV_NETINET_DIVERT	492	/* Open IP divert socket. */
#define	PRIV_NETINET_PF		493	/* Administer pf firewall. */
#define	PRIV_NETINET_DUMMYNET	494	/* Administer DUMMYNET. */
#define	PRIV_NETINET_CARP	495	/* Administer CARP. */
#define	PRIV_NETINET_MROUTE	496	/* Administer multicast routing. */
#define	PRIV_NETINET_RAW	497	/* Open netinet raw socket. */
#define	PRIV_NETINET_GETCRED	498	/* Query netinet pcb credentials. */
#define	PRIV_NETINET_ADDRCTRL6	499	/* Administer IPv6 address scopes. */
#define	PRIV_NETINET_ND6	500	/* Administer IPv6 neighbor disc. */
#define	PRIV_NETINET_SCOPE6	501	/* Administer IPv6 address scopes. */
#define	PRIV_NETINET_ALIFETIME6	502	/* Administer IPv6 address lifetimes. */
#define	PRIV_NETINET_IPSEC	503	/* Administer IPSEC. */
#define	PRIV_NETINET_REUSEPORT	504	/* Allow [rapid] port/address reuse. */
#define	PRIV_NETINET_SETHDROPTS	505	/* Set certain IPv4/6 header options. */
#define	PRIV_NETINET_BINDANY	506	/* Allow bind to any address. */

/*
 * IPX/SPX privileges.
 */
#define	PRIV_NETIPX_RESERVEDPORT	520	/* Bind low port number. */
#define	PRIV_NETIPX_RAW		521	/* Open netipx raw socket. */

/*
 * NCP privileges.
 */
#define	PRIV_NETNCP		530	/* Use another user's connection. */

/*
 * SMB privileges.
 */
#define	PRIV_NETSMB		540	/* Use another user's connection. */

/*
 * VM86 privileges.
 */
#define	PRIV_VM86_INTCALL	550	/* Allow invoking vm86 int handlers. */

/*
 * Set of reserved privilege values, which will be allocated to code as
 * needed, in order to avoid renumbering later privileges due to insertion.
 */
#define	_PRIV_RESERVED0		560
#define	_PRIV_RESERVED1		561
#define	_PRIV_RESERVED2		562
#define	_PRIV_RESERVED3		563
#define	_PRIV_RESERVED4		564
#define	_PRIV_RESERVED5		565
#define	_PRIV_RESERVED6		566
#define	_PRIV_RESERVED7		567
#define	_PRIV_RESERVED8		568
#define	_PRIV_RESERVED9		569
#define	_PRIV_RESERVED10	570
#define	_PRIV_RESERVED11	571
#define	_PRIV_RESERVED12	572
#define	_PRIV_RESERVED13	573
#define	_PRIV_RESERVED14	574
#define	_PRIV_RESERVED15	575

/*
 * Define a set of valid privilege numbers that can be used by loadable
 * modules that don't yet have privilege reservations.  Ideally, these should
 * not be used, since their meaning is opaque to any policies that are aware
 * of specific privileges, such as jail, and as such may be arbitrarily
 * denied.
 */
#define	PRIV_MODULE0		600
#define	PRIV_MODULE1		601
#define	PRIV_MODULE2		602
#define	PRIV_MODULE3		603
#define	PRIV_MODULE4		604
#define	PRIV_MODULE5		605
#define	PRIV_MODULE6		606
#define	PRIV_MODULE7		607
#define	PRIV_MODULE8		608
#define	PRIV_MODULE9		609
#define	PRIV_MODULE10		610
#define	PRIV_MODULE11		611
#define	PRIV_MODULE12		612
#define	PRIV_MODULE13		613
#define	PRIV_MODULE14		614
#define	PRIV_MODULE15		615

/*
 * DDB(4) privileges.
 */
#define	PRIV_DDB_CAPTURE	620	/* Allow reading of DDB capture log. */

/*
 * Arla/nnpfs privileges.
 */
#define	PRIV_NNPFS_DEBUG	630	/* Perforn ARLA_VIOC_NNPFSDEBUG. */

/*
 * cpuctl(4) privileges.
 */
#define PRIV_CPUCTL_WRMSR	640	/* Write model-specific register. */
#define PRIV_CPUCTL_UPDATE	641	/* Update cpu microcode. */

/*
 * Capi4BSD privileges.
 */
#define	PRIV_C4B_RESET_CTLR	650	/* Load firmware, reset controller. */
#define	PRIV_C4B_TRACE		651	/* Unrestricted CAPI message tracing. */

/*
 * OpenAFS privileges.
 */
#define	PRIV_AFS_ADMIN		660	/* Can change AFS client settings. */
#define	PRIV_AFS_DAEMON		661	/* Can become the AFS daemon. */

/*
 * Resource Limits privileges.
 */
#define	PRIV_RCTL_GET_RACCT	670
#define	PRIV_RCTL_GET_RULES	671
#define	PRIV_RCTL_GET_LIMITS	672
#define	PRIV_RCTL_ADD_RULE	673
#define	PRIV_RCTL_REMOVE_RULE	674

/*
 * Track end of privilege list.
 */
#define	_PRIV_HIGHEST		675

/*
 * Validate that a named privilege is known by the privilege system.  Invalid
 * privileges presented to the privilege system by a priv_check interface
 * will result in a panic.  This is only approximate due to sparse allocation
 * of the privilege space.
 */
#define	PRIV_VALID(x)	((x) > _PRIV_LOWEST && (x) < _PRIV_HIGHEST)

#ifdef _KERNEL
/*
 * Privilege check interfaces, modeled after historic suser() interfaces, but
 * with the addition of a specific privilege name.  No flags are currently
 * defined for the API.  Historically, flags specified using the real uid
 * instead of the effective uid, and whether or not the check should be
 * allowed in jail.
 */
struct thread;
struct ucred;
int	priv_check(struct thread *td, int priv);
int	priv_check_cred(struct ucred *cred, int priv, int flags);
#endif

#endif /* !_SYS_PRIV_H_ */


code:
/*-
 * Copyright (c) 1986, 1989, 1991, 1993
 *	The Regents of the University of California.  All rights reserved.
 * (c) UNIX System Laboratories, Inc.
 * All or some portions of this file are derived from material licensed
 * to the University of California by American Telephone and Telegraph
 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
 * the permission of UNIX System Laboratories, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)proc.h	8.15 (Berkeley) 5/19/95
 * $FreeBSD: release/9.0.0/sys/sys/proc.h 227886 2011-11-23 15:16:05Z kib $
 */

#ifndef _SYS_PROC_H_
#define	_SYS_PROC_H_

#include <sys/callout.h>		/* For struct callout. */
#include <sys/event.h>			/* For struct klist. */
#include <sys/condvar.h>
#ifndef _KERNEL
#include <sys/filedesc.h>
#endif
#include <sys/queue.h>
#include <sys/_lock.h>
#include <sys/lock_profile.h>
#include <sys/_mutex.h>
#include <sys/osd.h>
#include <sys/priority.h>
#include <sys/rtprio.h>			/* XXX. */
#include <sys/runq.h>
#include <sys/resource.h>
#include <sys/sigio.h>
#include <sys/signal.h>
#include <sys/signalvar.h>
#include <sys/dynlib.h>
#ifndef _KERNEL
#include <sys/time.h>			/* For structs itimerval, timeval. */
#else
#include <sys/pcpu.h>
#endif
#include <sys/ucontext.h>
#include <sys/ucred.h>
#include <machine/proc.h>		/* Machine-dependent proc substruct. */

/*
 * One structure allocated per session.
 *
 * List of locks
 * (m)		locked by s_mtx mtx
 * (e)		locked by proctree_lock sx
 * (c)		const until freeing
 */
struct session {
	u_int		s_count;	/* Ref cnt; pgrps in session - atomic. */
	struct proc	*s_leader;	/* (m + e) Session leader. */
	struct vnode	*s_ttyvp;	/* (m) Vnode of controlling tty. */
	struct cdev_priv *s_ttydp;	/* (m) Device of controlling tty.  */
	struct tty	*s_ttyp;	/* (e) Controlling tty. */
	pid_t		s_sid;		/* (c) Session ID. */
					/* (m) Setlogin() name: */
	char		s_login[roundup(MAXLOGNAME, sizeof(long))];
	struct mtx	s_mtx;		/* Mutex to protect members. */
};

/*
 * One structure allocated per process group.
 *
 * List of locks
 * (m)		locked by pg_mtx mtx
 * (e)		locked by proctree_lock sx
 * (c)		const until freeing
 */
struct pgrp {
	LIST_ENTRY(pgrp) pg_hash;	/* (e) Hash chain. */
	LIST_HEAD(, proc) pg_members;	/* (m + e) Pointer to pgrp members. */
	struct session	*pg_session;	/* (c) Pointer to session. */
	struct sigiolst	pg_sigiolst;	/* (m) List of sigio sources. */
	pid_t		pg_id;		/* (c) Process group id. */
	int		pg_jobc;	/* (m) Job control process count. */
	struct mtx	pg_mtx;		/* Mutex to protect members */
};

/*
 * pargs, used to hold a copy of the command line, if it had a sane length.
 */
struct pargs {
	u_int	ar_ref;		/* Reference count. */
	u_int	ar_length;	/* Length. */
	u_char	ar_args[1];	/* Arguments. */
};

/*-
 * Description of a process.
 *
 * This structure contains the information needed to manage a thread of
 * control, known in UN*X as a process; it has references to substructures
 * containing descriptions of things that the process uses, but may share
 * with related processes.  The process structure and the substructures
 * are always addressable except for those marked "(CPU)" below,
 * which might be addressable only on a processor on which the process
 * is running.
 *
 * Below is a key of locks used to protect each member of struct proc.  The
 * lock is indicated by a reference to a specific character in parens in the
 * associated comment.
 *      * - not yet protected
 *      a - only touched by curproc or parent during fork/wait
 *      b - created at fork, never changes
 *		(exception aiods switch vmspaces, but they are also
 *		marked 'P_SYSTEM' so hopefully it will be left alone)
 *      c - locked by proc mtx
 *      d - locked by allproc_lock lock
 *      e - locked by proctree_lock lock
 *      f - session mtx
 *      g - process group mtx
 *      h - callout_lock mtx
 *      i - by curproc or the master session mtx
 *      j - locked by proc slock
 *      k - only accessed by curthread
 *	k*- only accessed by curthread and from an interrupt
 *      l - the attaching proc or attaching proc parent
 *      m - Giant
 *      n - not locked, lazy
 *      o - ktrace lock
 *      q - td_contested lock
 *      r - p_peers lock
 *      t - thread lock
 *      x - created at fork, only changes during single threading in exec
 *      y - created at first aio, doesn't change until exit or exec at which
 *          point we are single-threaded and only curthread changes it
 *      z - zombie threads lock
 *
 * If the locking key specifies two identifiers (for example, p_pptr) then
 * either lock is sufficient for read access, but both locks must be held
 * for write access.
 */
struct cpuset;
struct kaioinfo;
struct kaudit_record;
struct kdtrace_proc;
struct kdtrace_thread;
struct mqueue_notifier;
struct nlminfo;
struct p_sched;
struct proc;
struct procdesc;
struct racct;
struct sleepqueue;
struct td_sched;
struct thread;
struct trapframe;
struct turnstile;

/*
 * XXX: Does this belong in resource.h or resourcevar.h instead?
 * Resource usage extension.  The times in rusage structs in the kernel are
 * never up to date.  The actual times are kept as runtimes and tick counts
 * (with control info in the "previous" times), and are converted when
 * userland asks for rusage info.  Backwards compatibility prevents putting
 * this directly in the user-visible rusage struct.
 *
 * Locking for p_rux: (cj) means (j) for p_rux and (c) for p_crux.
 * Locking for td_rux: (t) for all fields.
 */
struct rusage_ext {
	uint64_t	rux_runtime;    /* (cj) Real time. */
	uint64_t	rux_uticks;     /* (cj) Statclock hits in user mode. */
	uint64_t	rux_sticks;     /* (cj) Statclock hits in sys mode. */
	uint64_t	rux_iticks;     /* (cj) Statclock hits in intr mode. */
	uint64_t	rux_uu;         /* (c) Previous user time in usec. */
	uint64_t	rux_su;         /* (c) Previous sys time in usec. */
	uint64_t	rux_tu;         /* (c) Previous total time in usec. */
};

/*
* Kernel runnable context (thread).
* This is what is put to sleep and reactivated.
* Thread context.  Processes may have multiple threads.
*/
struct thread {
	struct mtx	*volatile td_lock; /* replaces sched lock */
	struct proc	*td_proc;	/* (*) Associated process. */
	TAILQ_ENTRY(thread) td_plist;	/* (*) All threads in this proc. */
	TAILQ_ENTRY(thread) td_runq;	/* (t) Run queue. */
	TAILQ_ENTRY(thread) td_slpq;	/* (t) Sleep queue. */
	TAILQ_ENTRY(thread) td_lockq;	/* (t) Lock queue. */
	LIST_ENTRY(thread) td_hash;	/* (d) Hash chain. */
	struct cpuset	*td_cpuset;	/* (t) CPU affinity mask. */
	struct seltd	*td_sel;	/* Select queue/channel. */
	struct sleepqueue *td_sleepqueue; /* (k) Associated sleep queue. */
	struct turnstile *td_turnstile;	/* (k) Associated turnstile. */
	struct umtx_q   *td_umtxq;	/* (c?) Link for when we're blocked. */
	lwpid_t		td_tid;		/* (b) Thread ID. */
	sigqueue_t	td_sigqueue;	/* (c) Sigs arrived, not delivered. */
#define	td_siglist	td_sigqueue.sq_signals
	u_char		td_lend_user_pri; /* (t) Lend user pri. */

/* Cleared during fork1() */
#define	td_startzero td_flags
	int		td_flags;	/* (t) TDF_* flags. */
	int		td_inhibitors;	/* (t) Why can not run. */
	int		td_pflags;	/* (k) Private thread (TDP_*) flags. */
	int		td_dupfd;	/* (k) Ret value from fdopen. XXX */
	int		td_sqqueue;	/* (t) Sleepqueue queue blocked on. */
	void		*td_wchan;	/* (t) Sleep address. */
	const char	*td_wmesg;	/* (t) Reason for sleep. */
	u_char		td_lastcpu;	/* (t) Last cpu we were on. */
	u_char		td_oncpu;	/* (t) Which cpu we are on. */
	volatile u_char td_owepreempt;  /* (k*) Preempt on last critical_exit */
	u_char		td_tsqueue;	/* (t) Turnstile queue blocked on. */
	short		td_locks;	/* (k) Count of non-spin locks. */
	short		td_rw_rlocks;	/* (k) Count of rwlock read locks. */
	short		td_lk_slocks;	/* (k) Count of lockmgr shared locks. */
	struct turnstile *td_blocked;	/* (t) Lock thread is blocked on. */
	const char	*td_lockname;	/* (t) Name of lock blocked on. */
	LIST_HEAD(, turnstile) td_contested;	/* (q) Contested locks. */
	struct lock_list_entry *td_sleeplocks; /* (k) Held sleep locks. */
	int		td_intr_nesting_level; /* (k) Interrupt recursion. */
	int		td_pinned;	/* (k) Temporary cpu pin count. */
	struct ucred	*td_ucred;	/* (k) Reference to credentials. */
	u_int		td_estcpu;	/* (t) estimated cpu utilization */
	int		td_slptick;	/* (t) Time at sleep. */
	int		td_blktick;	/* (t) Time spent blocked. */
	int		td_swvoltick;	/* (t) Time at last SW_VOL switch. */
	struct rusage	td_ru;		/* (t) rusage information. */
	struct rusage_ext td_rux;	/* (t) Internal rusage information. */
	uint64_t	td_incruntime;	/* (t) Cpu ticks to transfer to proc. */
	uint64_t	td_runtime;	/* (t) How many cpu ticks we've run. */
	u_int 		td_pticks;	/* (t) Statclock hits for profiling */
	u_int		td_sticks;	/* (t) Statclock hits in system mode. */
	u_int		td_iticks;	/* (t) Statclock hits in intr mode. */
	u_int		td_uticks;	/* (t) Statclock hits in user mode. */
	int		td_intrval;	/* (t) Return value for sleepq. */
	sigset_t	td_oldsigmask;	/* (k) Saved mask from pre sigpause. */
	sigset_t	td_sigmask;	/* (c) Current signal mask. */
	volatile u_int	td_generation;	/* (k) For detection of preemption */
	stack_t		td_sigstk;	/* (k) Stack ptr and on-stack flag. */
	int		td_xsig;	/* (c) Signal for ptrace */
	u_long		td_profil_addr;	/* (k) Temporary addr until AST. */
	u_int		td_profil_ticks; /* (k) Temporary ticks until AST. */
	char		td_name[MAXCOMLEN + 17];	/* (*) Thread name. */
	struct file	*td_fpop;	/* (k) file referencing cdev under op */
	int		td_dbgflags;	/* (c) Userland debugger flags */
	struct ksiginfo td_dbgksi;	/* (c) ksi reflected to debugger. */
	int		td_ng_outbound;	/* (k) Thread entered ng from above. */
	struct osd	td_osd;		/* (k) Object specific data. */
	struct vm_map_entry *td_map_def_user; /* (k) Deferred entries. */
	pid_t		td_dbg_forked;	/* (c) Child pid for debugger. */
#define	td_endzero td_rqindex

	char td_unk35C[0x04];

	#if MIRA_PLATFORM >= MIRA_PLATFORM_ORBIS_BSD_355
	char td_unk360[0x18];
	#endif

	#if MIRA_PLATFORM >= MIRA_PLATFORM_ORBIS_BSD_455
	char td_unk378[0x04];
	#endif

/* Copied during fork1() or thread_sched_upcall(). */
#define	td_startcopy td_endzero
	u_short		td_rqindex;	/* (t) Run queue index. */
	u_short		td_base_pri;	/* (t) Thread base kernel priority. */
	u_short		td_priority;	/* (t) Thread active priority. */
	u_short		td_pri_class;	/* (t) Scheduling class. */
	u_short		td_user_pri;	/* (t) User pri from estcpu and nice. */
	u_short		td_base_user_pri; /* (t) Base user pri */
#define	td_endcopy td_pcb

/*
 * Fields that must be manually set in fork1() or thread_sched_upcall()
 * or already have been set in the allocator, constructor, etc.
 */
	struct pcb	*td_pcb;	/* (k) Kernel VA of pcb and kstack. */
	enum {
		TDS_INACTIVE = 0x0,
		TDS_INHIBITED,
		TDS_CAN_RUN,
		TDS_RUNQ,
		TDS_RUNNING
	} td_state;			/* (t) thread state */
	register_t	td_retval[2];	/* (k) Syscall aux returns. */
	struct callout	td_slpcallout;	/* (h) Callout for sleep. */
	struct trapframe *td_frame;	/* (k) */
	struct vm_object *td_kstack_obj;/* (a) Kstack object. */
	vm_offset_t	td_kstack;	/* (a) Kernel VA of kstack. */
	int		td_kstack_pages; /* (a) Size of the kstack. */
	volatile u_int	td_critnest;	/* (k*) Critical section nest level. */
	struct mdthread td_md;		/* (k) Any machine-dependent fields. */
	struct td_sched	*td_sched;	/* (*) Scheduler-specific data. */
	struct kaudit_record	*td_ar;	/* (k) Active audit record, if any. */
	struct lpohead	td_lprof[2];	/* (a) lock profiling objects. */
	struct kdtrace_thread	*td_dtrace; /* (*) DTrace-specific data. */
	int		td_errno;	/* Error returned by last syscall. */
	struct vnet	*td_vnet;	/* (k) Effective vnet. */
	const char	*td_vnet_lpush;	/* (k) Debugging vnet push / pop. */
	struct trapframe *td_intr_frame;/* (k) Frame of the current irq */

	char            td_unk440[0xA8];

	#if MIRA_PLATFORM >= MIRA_PLATFORM_ORBIS_BSD_355
	char            td_unk4E8[0x58];
	#endif

	#if MIRA_PLATFORM >= MIRA_PLATFORM_ORBIS_BSD_455
	char            td_unk540[0x20];
	#endif

	#if MIRA_PLATFORM >= MIRA_PLATFORM_ORBIS_BSD_500
	char td_unk560[0x10];
	#endif

};

struct mtx *thread_lock_block(struct thread *);
void thread_lock_unblock(struct thread *, struct mtx *);
void thread_lock_set(struct thread *, struct mtx *);
#define	THREAD_LOCK_ASSERT(td, type)					\
do {									\
	struct mtx *__m = (td)->td_lock;				\
	if (__m != &blocked_lock)					\
		mtx_assert(__m, (type));				\
} while (0)

#ifdef INVARIANTS
#define	THREAD_LOCKPTR_ASSERT(td, lock)					\
do {									\
	struct mtx *__m = (td)->td_lock;				\
	KASSERT((__m == &blocked_lock || __m == (lock)),		\
	    ("Thread %p lock %p does not match %p", td, __m, (lock)));	\
} while (0)
#else
#define	THREAD_LOCKPTR_ASSERT(td, lock)
#endif

#define	CRITICAL_ASSERT(td)						\
    KASSERT((td)->td_critnest >= 1, ("Not in critical section"));

/*
 * Flags kept in td_flags:
 * To change these you MUST have the scheduler lock.
 */
#define	TDF_BORROWING	0x00000001 /* Thread is borrowing pri from another. */
#define	TDF_INPANIC	0x00000002 /* Caused a panic, let it drive crashdump. */
#define	TDF_INMEM	0x00000004 /* Thread's stack is in memory. */
#define	TDF_SINTR	0x00000008 /* Sleep is interruptible. */
#define	TDF_TIMEOUT	0x00000010 /* Timing out during sleep. */
#define	TDF_IDLETD	0x00000020 /* This is a per-CPU idle thread. */
#define	TDF_CANSWAP	0x00000040 /* Thread can be swapped. */
#define	TDF_SLEEPABORT	0x00000080 /* sleepq_abort was called. */
#define	TDF_KTH_SUSP	0x00000100 /* kthread is suspended */
#define	TDF_UNUSED09	0x00000200 /* --available-- */
#define	TDF_BOUNDARY	0x00000400 /* Thread suspended at user boundary */
#define	TDF_ASTPENDING	0x00000800 /* Thread has some asynchronous events. */
#define	TDF_TIMOFAIL	0x00001000 /* Timeout from sleep after we were awake. */
#define	TDF_SBDRY	0x00002000 /* Stop only on usermode boundary. */
#define	TDF_UPIBLOCKED	0x00004000 /* Thread blocked on user PI mutex. */
#define	TDF_NEEDSUSPCHK	0x00008000 /* Thread may need to suspend. */
#define	TDF_NEEDRESCHED	0x00010000 /* Thread needs to yield. */
#define	TDF_NEEDSIGCHK	0x00020000 /* Thread may need signal delivery. */
#define	TDF_NOLOAD	0x00040000 /* Ignore during load avg calculations. */
#define	TDF_UNUSED19	0x00080000 /* --available-- */
#define	TDF_THRWAKEUP	0x00100000 /* Libthr thread must not suspend itself. */
#define	TDF_UNUSED21	0x00200000 /* --available-- */
#define	TDF_SWAPINREQ	0x00400000 /* Swapin request due to wakeup. */
#define	TDF_UNUSED23	0x00800000 /* --available-- */
#define	TDF_SCHED0	0x01000000 /* Reserved for scheduler private use */
#define	TDF_SCHED1	0x02000000 /* Reserved for scheduler private use */
#define	TDF_SCHED2	0x04000000 /* Reserved for scheduler private use */
#define	TDF_SCHED3	0x08000000 /* Reserved for scheduler private use */
#define	TDF_ALRMPEND	0x10000000 /* Pending SIGVTALRM needs to be posted. */
#define	TDF_PROFPEND	0x20000000 /* Pending SIGPROF needs to be posted. */
#define	TDF_MACPEND	0x40000000 /* AST-based MAC event pending. */

/* Userland debug flags */
#define	TDB_SUSPEND	0x00000001 /* Thread is suspended by debugger */
#define	TDB_XSIG	0x00000002 /* Thread is exchanging signal under trace */
#define	TDB_USERWR	0x00000004 /* Debugger modified memory or registers */
#define	TDB_SCE		0x00000008 /* Thread performs syscall enter */
#define	TDB_SCX		0x00000010 /* Thread performs syscall exit */
#define	TDB_EXEC	0x00000020 /* TDB_SCX from exec(2) family */
#define	TDB_FORK	0x00000040 /* TDB_SCX from fork(2) that created new process */
#define	TDB_STOPATFORK	0x00000080 /* Stop at the return from fork (child only) */

/*
 * "Private" flags kept in td_pflags:
 * These are only written by curthread and thus need no locking.
 */
#define	TDP_OLDMASK	0x00000001 /* Need to restore mask after suspend. */
#define	TDP_INKTR	0x00000002 /* Thread is currently in KTR code. */
#define	TDP_INKTRACE	0x00000004 /* Thread is currently in KTRACE code. */
#define	TDP_BUFNEED	0x00000008 /* Do not recurse into the buf flush */
#define	TDP_COWINPROGRESS 0x00000010 /* Snapshot copy-on-write in progress. */
#define	TDP_ALTSTACK	0x00000020 /* Have alternate signal stack. */
#define	TDP_DEADLKTREAT	0x00000040 /* Lock aquisition - deadlock treatment. */
#define	TDP_NOFAULTING	0x00000080 /* Do not handle page faults. */
#define	TDP_NOSLEEPING	0x00000100 /* Thread is not allowed to sleep on a sq. */
#define	TDP_OWEUPC	0x00000200 /* Call addupc() at next AST. */
#define	TDP_ITHREAD	0x00000400 /* Thread is an interrupt thread. */
#define	TDP_UNUSED800	0x00000800 /* available. */
#define	TDP_SCHED1	0x00001000 /* Reserved for scheduler private use */
#define	TDP_SCHED2	0x00002000 /* Reserved for scheduler private use */
#define	TDP_SCHED3	0x00004000 /* Reserved for scheduler private use */
#define	TDP_SCHED4	0x00008000 /* Reserved for scheduler private use */
#define	TDP_GEOM	0x00010000 /* Settle GEOM before finishing syscall */
#define	TDP_SOFTDEP	0x00020000 /* Stuck processing softdep worklist */
#define	TDP_NORUNNINGBUF 0x00040000 /* Ignore runningbufspace check */
#define	TDP_WAKEUP	0x00080000 /* Don't sleep in umtx cond_wait */
#define	TDP_INBDFLUSH	0x00100000 /* Already in BO_BDFLUSH, do not recurse */
#define	TDP_KTHREAD	0x00200000 /* This is an official kernel thread */
#define	TDP_CALLCHAIN	0x00400000 /* Capture thread's callchain */
#define	TDP_IGNSUSP	0x00800000 /* Permission to ignore the MNTK_SUSPEND* */
#define	TDP_AUDITREC	0x01000000 /* Audit record pending on thread */

/*
 * Reasons that the current thread can not be run yet.
 * More than one may apply.
 */
#define	TDI_SUSPENDED	0x0001	/* On suspension queue. */
#define	TDI_SLEEPING	0x0002	/* Actually asleep! (tricky). */
#define	TDI_SWAPPED	0x0004	/* Stack not in mem.  Bad juju if run. */
#define	TDI_LOCK	0x0008	/* Stopped on a lock. */
#define	TDI_IWAIT	0x0010	/* Awaiting interrupt. */

#define	TD_IS_SLEEPING(td)	((td)->td_inhibitors & TDI_SLEEPING)
#define	TD_ON_SLEEPQ(td)	((td)->td_wchan != NULL)
#define	TD_IS_SUSPENDED(td)	((td)->td_inhibitors & TDI_SUSPENDED)
#define	TD_IS_SWAPPED(td)	((td)->td_inhibitors & TDI_SWAPPED)
#define	TD_ON_LOCK(td)		((td)->td_inhibitors & TDI_LOCK)
#define	TD_AWAITING_INTR(td)	((td)->td_inhibitors & TDI_IWAIT)
#define	TD_IS_RUNNING(td)	((td)->td_state == TDS_RUNNING)
#define	TD_ON_RUNQ(td)		((td)->td_state == TDS_RUNQ)
#define	TD_CAN_RUN(td)		((td)->td_state == TDS_CAN_RUN)
#define	TD_IS_INHIBITED(td)	((td)->td_state == TDS_INHIBITED)
#define	TD_ON_UPILOCK(td)	((td)->td_flags & TDF_UPIBLOCKED)
#define TD_IS_IDLETHREAD(td)	((td)->td_flags & TDF_IDLETD)

#define	TD_SET_INHIB(td, inhib) do {			\
	(td)->td_state = TDS_INHIBITED;			\
	(td)->td_inhibitors |= (inhib);			\
} while (0)

#define	TD_CLR_INHIB(td, inhib) do {			\
	if (((td)->td_inhibitors & (inhib)) &&		\
	    (((td)->td_inhibitors &= ~(inhib)) == 0))	\
		(td)->td_state = TDS_CAN_RUN;		\
} while (0)

#define	TD_SET_SLEEPING(td)	TD_SET_INHIB((td), TDI_SLEEPING)
#define	TD_SET_SWAPPED(td)	TD_SET_INHIB((td), TDI_SWAPPED)
#define	TD_SET_LOCK(td)		TD_SET_INHIB((td), TDI_LOCK)
#define	TD_SET_SUSPENDED(td)	TD_SET_INHIB((td), TDI_SUSPENDED)
#define	TD_SET_IWAIT(td)	TD_SET_INHIB((td), TDI_IWAIT)
#define	TD_SET_EXITING(td)	TD_SET_INHIB((td), TDI_EXITING)

#define	TD_CLR_SLEEPING(td)	TD_CLR_INHIB((td), TDI_SLEEPING)
#define	TD_CLR_SWAPPED(td)	TD_CLR_INHIB((td), TDI_SWAPPED)
#define	TD_CLR_LOCK(td)		TD_CLR_INHIB((td), TDI_LOCK)
#define	TD_CLR_SUSPENDED(td)	TD_CLR_INHIB((td), TDI_SUSPENDED)
#define	TD_CLR_IWAIT(td)	TD_CLR_INHIB((td), TDI_IWAIT)

#define	TD_SET_RUNNING(td)	(td)->td_state = TDS_RUNNING
#define	TD_SET_RUNQ(td)		(td)->td_state = TDS_RUNQ
#define	TD_SET_CAN_RUN(td)	(td)->td_state = TDS_CAN_RUN
 /*
 * Process structure.
 */
struct proc {
	LIST_ENTRY(proc) p_list;	/* (d) List of all processes. */
	TAILQ_HEAD(, thread) p_threads;	/* (c) all threads. */
	struct mtx	p_slock;	/* process spin lock */
	struct ucred	*p_ucred;	/* (c) Process owner's identity. */
	struct filedesc	*p_fd;		/* (b) Open files. */
	struct filedesc_to_leader *p_fdtol; /* (b) Tracking node */
	struct pstats	*p_stats;	/* (b) Accounting/statistics (CPU). */
	struct plimit	*p_limit;	/* (c) Process limits. */
	struct callout	p_limco;	/* (c) Limit callout handle */
	struct sigacts	*p_sigacts;	/* (x) Signal actions, state (CPU). */

	/*
	 * The following don't make too much sense.
	 * See the td_ or ke_ versions of the same flags.
	 */
	int		p_flag;		/* (c) P_* flags. */
	enum {
		PRS_NEW = 0,		/* In creation */
		PRS_NORMAL,		/* threads can be run. */
		PRS_ZOMBIE
	} p_state;			/* (j/c) Process status. */
	pid_t		p_pid;		/* (b) Process identifier. */
	LIST_ENTRY(proc) p_hash;	/* (d) Hash chain. */
	LIST_ENTRY(proc) p_pglist;	/* (g + e) List of processes in pgrp. */
	struct proc	*p_pptr;	/* (c + e) Pointer to parent process. */
	LIST_ENTRY(proc) p_sibling;	/* (e) List of sibling processes. */
	LIST_HEAD(, proc) p_children;	/* (e) Pointer to list of children. */
	struct mtx	p_mtx;		/* (n) Lock for this struct. */
	struct ksiginfo *p_ksi;	/* Locked by parent proc lock */
	sigqueue_t	p_sigqueue;	/* (c) Sigs not delivered to a td. */
#define p_siglist	p_sigqueue.sq_signals

/* The following fields are all zeroed upon creation in fork. */
#define	p_startzero	p_oppid
	pid_t		p_oppid;	/* (c + e) Save ppid in ptrace. XXX */
	int		p_dbg_child;	/* (c + e) # of debugged children in
							ptrace. */
	struct vmspace	*p_vmspace;	/* (b) Address space. */
	u_int		p_swtick;	/* (c) Tick when swapped in or out. */
	struct itimerval p_realtimer;	/* (c) Alarm timer. */
	struct rusage	p_ru;		/* (a) Exit information. */
	struct rusage_ext p_rux;	/* (cj) Internal resource usage. */
	struct rusage_ext p_crux;	/* (c) Internal child resource usage. */
	int		p_profthreads;	/* (c) Num threads in addupc_task. */
	volatile int	p_exitthreads;	/* (j) Number of threads exiting */
	int		p_traceflag;	/* (o) Kernel trace points. */
	struct vnode	*p_tracevp;	/* (c + o) Trace to vnode. */
	struct ucred	*p_tracecred;	/* (o) Credentials to trace with. */
	struct vnode	*p_textvp;	/* (b) Vnode of executable. */
	u_int		p_lock;		/* (c) Proclock (prevent swap) count. */
	struct sigiolst	p_sigiolst;	/* (c) List of sigio sources. */
	int		p_sigparent;	/* (c) Signal to parent on exit. */
	int		p_sig;		/* (n) For core dump/debugger XXX. */
	u_long		p_code;		/* (n) For core dump/debugger XXX. */
	u_int		p_stops;	/* (c) Stop event bitmask. */
	u_int		p_stype;	/* (c) Stop event type. */
	char		p_step;		/* (c) Process is stopped. */
	u_char		p_pfsflags;	/* (c) Procfs flags. */
	struct nlminfo	*p_nlminfo;	/* (?) Only used by/for lockd. */
	struct kaioinfo	*p_aioinfo;	/* (y) ASYNC I/O info. */
	struct thread	*p_singlethread;/* (c + j) If single threading this is it */
	int		p_suspcount;	/* (j) Num threads in suspended mode. */
	struct thread	*p_xthread;	/* (c) Trap thread */
	int		p_boundary_count;/* (j) Num threads at user boundary */
	int		p_pendingcnt;	/* how many signals are pending */
	struct itimers	*p_itimers;	/* (c) POSIX interval timers. */
	struct procdesc	*p_procdesc;	/* (e) Process descriptor, if any. */
/* End area that is zeroed on creation. */
#define	p_endzero	p_magic

	char		*p_patchpath;	/* patch file path */
	char		p_unk338[0x8];

	struct dynlib	*p_dynlib;      /* Sony Dynlib info */

	// extra stuff
#if MIRA_PLATFORM >= MIRA_PLATFORM_ORBIS_BSD_650
	char            p_unk348[0x104];
#elif MIRA_PLATFORM >= MIRA_PLATFORM_ORBIS_BSD_600
	char            p_unk348[0x100];
#elif MIRA_PLATFORM >= MIRA_PLATFORM_ORBIS_BSD_550
	char            p_unk348[0x104];
#elif MIRA_PLATFORM >= MIRA_PLATFORM_ORBIS_BSD_500
	char            p_unk348[0x0FC];
#elif MIRA_PLATFORM >= MIRA_PLATFORM_ORBIS_BSD_455
	char            p_unk348[0x0F4];
#elif MIRA_PLATFORM >= MIRA_PLATFORM_ORBIS_BSD_400
	char            p_unk348[0x0A0];
#elif MIRA_PLATFORM >= MIRA_PLATFORM_ORBIS_BSD_355
	char            p_unk348[0x090];
#endif

/* The following fields are all copied upon creation in fork. */
#define	p_startcopy	p_endzero
	u_int		p_magic;	/* (b) Magic number. */
	int		p_osrel;	/* (x) osreldate for the
					       binary (from ELF note, if any) */
	char		p_comm[MAXCOMLEN + 13];	/* (b) Process name. */

	char		p_elfpath[PATH_MAX];        /* full path to elf */

	struct pgrp	*p_pgrp;	/* (c + e) Pointer to process group. */
	struct sysentvec *p_sysent;	/* (b) Syscall dispatch info. */
	struct pargs	*p_args;	/* (c) Process arguments. */
	rlim_t		p_cpulimit;	/* (c) Current CPU limit in seconds. */
	signed char	p_nice;		/* (c) Process "nice" value. */
	int		p_fibnum;	/* in this routing domain XXX MRT */
/* End area that is copied on creation. */
#define	p_endcopy	p_xstat

	int		p_unk7F0;
	int		p_unk7F4;
	int		p_randomized_path_len;		/* sandbox base name length */
	char	p_randomized_path[0x100];	/* sandbox base name */

	u_short		p_xstat;	/* (c) Exit status; also stop sig. */
	struct knlist	p_klist;	/* (c) Knotes attached to this proc. */
	int		p_numthreads;	/* (c) Number of threads. */
	struct mdproc	p_md;		/* Any machine-dependent fields. */
	struct callout	p_itcallout;	/* (h + c) Interval timer callout. */
	u_short		p_acflag;	/* (c) Accounting flags. */
	struct proc	*p_peers;	/* (r) */
	struct proc	*p_leader;	/* (b) */
	void		*p_emuldata;	/* (c) Emulator state data. */
	struct label	*p_label;	/* (*) Proc (not subject) MAC label. */
	struct p_sched	*p_sched;	/* (*) Scheduler-specific data. */
	STAILQ_HEAD(, ktr_request)	p_ktr;	/* (o) KTR event queue. */
	LIST_HEAD(, mqueue_notifier)	p_mqnotifier; /* (c) mqueue notifiers.*/
	struct kdtrace_proc	*p_dtrace; /* (*) DTrace-specific data. */
	struct cv	p_pwait;	/* (*) wait cv for exit/exec. */
	struct cv	p_dbgwait;	/* (*) wait cv for debugger attach
					   after fork. */
	uint64_t	p_prev_runtime;	/* (c) Resource usage accounting. */
	struct racct	*p_racct;	/* (b) Resource accounting. */

	#if MIRA_PLATFORM >= MIRA_PLATFORM_ORBIS_BSD_500
	char            p_unkA08[0xB0];
	#elif MIRA_PLATFORM >= MIRA_PLATFORM_ORBIS_BSD_355
	char            p_unkA08[0xA8];
	#else
	char            p_unkA08[0x98];
	#endif

};

// Saftey measure so we don't fuck anything
#if MIRA_PLATFORM < MIRA_PLATFORM_ORBIS_BSD_672
static_assert(offsetof(struct proc, p_unk338) == 0x338, "unk338 start incorrect");
static_assert(offsetof(struct proc, p_dynlib) == 0x340, "dynlib start incorrect");
#else
static_assert(offsetof(struct proc, p_unk338) == 0x338, "unk338 start incorrect");
static_assert(offsetof(struct proc, p_dynlib) == 0x340, "dynlib start incorrect");
static_assert(offsetof(struct proc, p_magic) == 0x44C, "struct start incorrect");
#endif

#define	p_session	p_pgrp->pg_session
#define	p_pgid		p_pgrp->pg_id

#define	NOCPU	0xff		/* For when we aren't on a CPU. */

#define	PROC_SLOCK(p)	mtx_lock_spin(&(p)->p_slock)
#define	PROC_SUNLOCK(p)	mtx_unlock_spin(&(p)->p_slock)
#define	PROC_SLOCK_ASSERT(p, type)	mtx_assert(&(p)->p_slock, (type))

/* These flags are kept in p_flag. */
#define	P_ADVLOCK	0x00001	/* Process may hold a POSIX advisory lock. */
#define	P_CONTROLT	0x00002	/* Has a controlling terminal. */
#define	P_KTHREAD	0x00004	/* Kernel thread (*). */
#define	P_FOLLOWFORK	0x00008	/* Attach parent debugger to children. */
#define	P_PPWAIT	0x00010	/* Parent is waiting for child to exec/exit. */
#define	P_PROFIL	0x00020	/* Has started profiling. */
#define	P_STOPPROF	0x00040	/* Has thread requesting to stop profiling. */
#define	P_HADTHREADS	0x00080	/* Has had threads (no cleanup shortcuts) */
#define	P_SUGID		0x00100	/* Had set id privileges since last exec. */
#define	P_SYSTEM	0x00200	/* System proc: no sigs, stats or swapping. */
#define	P_SINGLE_EXIT	0x00400	/* Threads suspending should exit, not wait. */
#define	P_TRACED	0x00800	/* Debugged process being traced. */
#define	P_WAITED	0x01000	/* Someone is waiting for us. */
#define	P_WEXIT		0x02000	/* Working on exiting. */
#define	P_EXEC		0x04000	/* Process called exec. */
#define	P_WKILLED	0x08000	/* Killed, go to kernel/user boundary ASAP. */
#define	P_CONTINUED	0x10000	/* Proc has continued from a stopped state. */
#define	P_STOPPED_SIG	0x20000	/* Stopped due to SIGSTOP/SIGTSTP. */
#define	P_STOPPED_TRACE	0x40000	/* Stopped because of tracing. */
#define	P_STOPPED_SINGLE 0x80000 /* Only 1 thread can continue (not to user). */
#define	P_PROTECTED	0x100000 /* Do not kill on memory overcommit. */
#define	P_SIGEVENT	0x200000 /* Process pending signals changed. */
#define	P_SINGLE_BOUNDARY 0x400000 /* Threads should suspend at user boundary. */
#define	P_HWPMC		0x800000 /* Process is using HWPMCs */

#define	P_JAILED	0x1000000 /* Process is in jail. */
#define	P_INEXEC	0x4000000 /* Process is in execve(). */
#define	P_STATCHILD	0x8000000 /* Child process stopped or exited. */
#define	P_INMEM		0x10000000 /* Loaded into memory. */
#define	P_SWAPPINGOUT	0x20000000 /* Process is being swapped out. */
#define	P_SWAPPINGIN	0x40000000 /* Process is being swapped in. */

#define	P_STOPPED	(P_STOPPED_SIG|P_STOPPED_SINGLE|P_STOPPED_TRACE)
#define	P_SHOULDSTOP(p)	((p)->p_flag & P_STOPPED)
#define	P_KILLED(p)	((p)->p_flag & P_WKILLED)

/*
 * These were process status values (p_stat), now they are only used in
 * legacy conversion code.
 */
#define	SIDL	1		/* Process being created by fork. */
#define	SRUN	2		/* Currently runnable. */
#define	SSLEEP	3		/* Sleeping on an address. */
#define	SSTOP	4		/* Process debugging or suspension. */
#define	SZOMB	5		/* Awaiting collection by parent. */
#define	SWAIT	6		/* Waiting for interrupt. */
#define	SLOCK	7		/* Blocked on a lock. */

#define	P_MAGIC		0xbeefface

#ifdef _KERNEL

/* Types and flags for mi_switch(). */
#define	SW_TYPE_MASK		0xff	/* First 8 bits are switch type */
#define	SWT_NONE		0	/* Unspecified switch. */
#define	SWT_PREEMPT		1	/* Switching due to preemption. */
#define	SWT_OWEPREEMPT		2	/* Switching due to opepreempt. */
#define	SWT_TURNSTILE		3	/* Turnstile contention. */
#define	SWT_SLEEPQ		4	/* Sleepq wait. */
#define	SWT_SLEEPQTIMO		5	/* Sleepq timeout wait. */
#define	SWT_RELINQUISH		6	/* yield call. */
#define	SWT_NEEDRESCHED		7	/* NEEDRESCHED was set. */
#define	SWT_IDLE		8	/* Switching from the idle thread. */
#define	SWT_IWAIT		9	/* Waiting for interrupts. */
#define	SWT_SUSPEND		10	/* Thread suspended. */
#define	SWT_REMOTEPREEMPT	11	/* Remote processor preempted. */
#define	SWT_REMOTEWAKEIDLE	12	/* Remote processor preempted idle. */
#define	SWT_COUNT		13	/* Number of switch types. */
/* Flags */
#define	SW_VOL		0x0100		/* Voluntary switch. */
#define	SW_INVOL	0x0200		/* Involuntary switch. */
#define SW_PREEMPT	0x0400		/* The invol switch is a preemption */

/* How values for thread_single(). */
#define	SINGLE_NO_EXIT	0
#define	SINGLE_EXIT	1
#define	SINGLE_BOUNDARY	2

#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_PARGS);
MALLOC_DECLARE(M_PGRP);
MALLOC_DECLARE(M_SESSION);
MALLOC_DECLARE(M_SUBPROC);
#endif

#define	FOREACH_PROC_IN_SYSTEM(p)					\
	LIST_FOREACH((p), allproc, p_list)
#define	FOREACH_THREAD_IN_PROC(p, td)					\
	TAILQ_FOREACH((td), &(p)->p_threads, td_plist)

#define	FIRST_THREAD_IN_PROC(p)	TAILQ_FIRST(&(p)->p_threads)

/*
 * We use process IDs <= PID_MAX; PID_MAX + 1 must also fit in a pid_t,
 * as it is used to represent "no process group".
 */
#define	PID_MAX		99999
#define	NO_PID		100000

#define	SESS_LEADER(p)	((p)->p_session->s_leader == (p))

#define	STOPEVENT(p, e, v) do {						\
	if ((p)->p_stops & (e))	{					\
		PROC_LOCK(p);						\
		stopevent((p), (e), (v));				\
		PROC_UNLOCK(p);						\
	}								\
} while (0)
#define	_STOPEVENT(p, e, v) do {					\
	PROC_LOCK_ASSERT(p, MA_OWNED);					\
	WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, &p->p_mtx.lock_object, \
 	    "checking stopevent %d", (e));				\
	if ((p)->p_stops & (e))						\
		stopevent((p), (e), (v));				\
} while (0)

/* Lock and unlock a process. */
#define	PROC_LOCK(p)	mtx_lock(&(p)->p_mtx)
#define	PROC_TRYLOCK(p)	mtx_trylock(&(p)->p_mtx)
#define	PROC_UNLOCK(p)	mtx_unlock(&(p)->p_mtx)
#define	PROC_LOCKED(p)	(*mtx_owned)(&(p)->p_mtx)
#define	PROC_LOCK_ASSERT(p, type)	mtx_assert(&(p)->p_mtx, (type))

/* Lock and unlock a process group. */
#define	PGRP_LOCK(pg)	mtx_lock(&(pg)->pg_mtx)
#define	PGRP_UNLOCK(pg)	mtx_unlock(&(pg)->pg_mtx)
#define	PGRP_LOCKED(pg)	mtx_owned(&(pg)->pg_mtx)
#define	PGRP_LOCK_ASSERT(pg, type)	mtx_assert(&(pg)->pg_mtx, (type))

#define	PGRP_LOCK_PGSIGNAL(pg) do {					\
	if ((pg) != NULL)						\
		PGRP_LOCK(pg);						\
} while (0)
#define	PGRP_UNLOCK_PGSIGNAL(pg) do {					\
	if ((pg) != NULL)						\
		PGRP_UNLOCK(pg);					\
} while (0)

/* Lock and unlock a session. */
#define	SESS_LOCK(s)	mtx_lock(&(s)->s_mtx)
#define	SESS_UNLOCK(s)	mtx_unlock(&(s)->s_mtx)
#define	SESS_LOCKED(s)	mtx_owned(&(s)->s_mtx)
#define	SESS_LOCK_ASSERT(s, type)	mtx_assert(&(s)->s_mtx, (type))

/* Hold process U-area in memory, normally for ptrace/procfs work. */
#define	PHOLD(p) do {							\
	PROC_LOCK(p);							\
	_PHOLD(p);							\
	PROC_UNLOCK(p);							\
} while (0)
#define	_PHOLD(p) do {							\
	PROC_LOCK_ASSERT((p), MA_OWNED);				\
	KASSERT(!((p)->p_flag & P_WEXIT) || (p) == curproc,		\
	    ("PHOLD of exiting process"));				\
	(p)->p_lock++;							\
	if (((p)->p_flag & P_INMEM) == 0)				\
		faultin((p));						\
} while (0)
#define PROC_ASSERT_HELD(p) do {					\
	KASSERT((p)->p_lock > 0, ("process not held"));			\
} while (0)

#define	PRELE(p) do {							\
	PROC_LOCK((p));							\
	_PRELE((p));							\
	PROC_UNLOCK((p));						\
} while (0)
#define	_PRELE(p) do {							\
	PROC_LOCK_ASSERT((p), MA_OWNED);				\
	(--(p)->p_lock);						\
	if (((p)->p_flag & P_WEXIT) && (p)->p_lock == 0)		\
		wakeup(&(p)->p_lock);					\
} while (0)
#define PROC_ASSERT_NOT_HELD(p) do {					\
	KASSERT((p)->p_lock == 0, ("process held"));			\
} while (0)

/* Check whether a thread is safe to be swapped out. */
#define	thread_safetoswapout(td)	((td)->td_flags & TDF_CANSWAP)

/* Control whether or not it is safe for curthread to sleep. */
#define	THREAD_NO_SLEEPING() do {					\
	KASSERT(!(curthread->td_pflags & TDP_NOSLEEPING),		\
	    ("nested no sleeping"));					\
	curthread->td_pflags |= TDP_NOSLEEPING;				\
} while (0)

#define	THREAD_SLEEPING_OK() do {					\
	KASSERT((curthread->td_pflags & TDP_NOSLEEPING),		\
	    ("nested sleeping ok"));					\
	curthread->td_pflags &= ~TDP_NOSLEEPING;			\
} while (0)

#define	PIDHASH(pid)	(&pidhashtbl[(pid) & pidhash])
extern LIST_HEAD(pidhashhead, proc) *pidhashtbl;
extern u_long pidhash;
#define	TIDHASH(tid)	(&tidhashtbl[(tid) & tidhash])
extern LIST_HEAD(tidhashhead, thread) *tidhashtbl;
extern u_long tidhash;
extern struct rwlock tidhash_lock;

#define	PGRPHASH(pgid)	(&pgrphashtbl[(pgid) & pgrphash])
extern LIST_HEAD(pgrphashhead, pgrp) *pgrphashtbl;
extern u_long pgrphash;

extern struct sx allproc_lock;
extern struct sx proctree_lock;
extern struct mtx ppeers_lock;
extern struct proc proc0;		/* Process slot for swapper. */
extern struct thread thread0;		/* Primary thread in proc0. */
extern struct vmspace vmspace0;		/* VM space for proc0. */
extern int hogticks;			/* Limit on kernel cpu hogs. */
extern int lastpid;
extern int nprocs, maxproc;		/* Current and max number of procs. */
extern int maxprocperuid;		/* Max procs per uid. */
extern u_long ps_arg_cache_limit;

LIST_HEAD(proclist, proc);
TAILQ_HEAD(procqueue, proc);
TAILQ_HEAD(threadqueue, thread);
extern struct proclist allproc;		/* List of all processes. */
extern struct proclist zombproc;	/* List of zombie processes. */
extern struct proc *initproc, *pageproc; /* Process slots for init, pager. */

extern struct uma_zone *proc_zone;

struct	proc *pfind(pid_t);		/* Find process by id. */
struct	pgrp *pgfind(pid_t);		/* Find process group by id. */
struct	proc *zpfind(pid_t);		/* Find zombie process by id. */

void	ast(struct trapframe *framep);
struct	thread *choosethread(void);
int	cr_cansignal(struct ucred *cred, struct proc *proc, int signum);
int	enterpgrp(struct proc *p, pid_t pgid, struct pgrp *pgrp,
	    struct session *sess);
int	enterthispgrp(struct proc *p, struct pgrp *pgrp);
void	faultin(struct proc *p);
void	fixjobc(struct proc *p, struct pgrp *pgrp, int entering);
int	fork1(struct thread *, int, int, struct proc **, int *, int);
void	fork_exit(void (*)(void *, struct trapframe *), void *,
	    struct trapframe *);
void	fork_return(struct thread *, struct trapframe *);
int	inferior(struct proc *p);
void	kern_yield(int);
void 	kick_proc0(void);
int	leavepgrp(struct proc *p);
int	maybe_preempt(struct thread *td);
void	maybe_yield(void);
void	mi_switch(int flags, struct thread *newtd);
int	p_candebug(struct thread *td, struct proc *p);
int	p_cansee(struct thread *td, struct proc *p);
int	p_cansched(struct thread *td, struct proc *p);
int	p_cansignal(struct thread *td, struct proc *p, int signum);
int	p_canwait(struct thread *td, struct proc *p);
struct	pargs *pargs_alloc(int len);
void	pargs_drop(struct pargs *pa);
void	pargs_hold(struct pargs *pa);
void	procinit(void);
void	proc_linkup0(struct proc *p, struct thread *td);
void	proc_linkup(struct proc *p, struct thread *td);
void	proc_reap(struct thread *td, struct proc *p, int *status, int options,
	    struct rusage *rusage);
void	proc_reparent(struct proc *child, struct proc *newparent);
struct	pstats *pstats_alloc(void);
void	pstats_fork(struct pstats *src, struct pstats *dst);
void	pstats_free(struct pstats *ps);
int	securelevel_ge(struct ucred *cr, int level);
int	securelevel_gt(struct ucred *cr, int level);
void	sess_hold(struct session *);
void	sess_release(struct session *);
int	setrunnable(struct thread *);
void	setsugid(struct proc *p);
int	should_yield(void);
int	sigonstack(size_t sp);
void	sleepinit(void);
void	stopevent(struct proc *, u_int, u_int);
struct	thread *tdfind(lwpid_t, pid_t);
void	threadinit(void);
void	tidhash_add(struct thread *);
void	tidhash_remove(struct thread *);
void	cpu_idle(int);
int	cpu_idle_wakeup(int);
extern	void (*cpu_idle_hook)(void);	/* Hook to machdep CPU idler. */
void	cpu_switch(struct thread *, struct thread *, struct mtx *);
void	cpu_throw(struct thread *, struct thread *) __dead2;
void	unsleep(struct thread *);
void	userret(struct thread *, struct trapframe *);

void	cpu_exit(struct thread *);
void	exit1(struct thread *, int) __dead2;
struct syscall_args;
int	cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa);
void	cpu_fork(struct thread *, struct proc *, struct thread *, int);
void	cpu_set_fork_handler(struct thread *, void (*)(void *), void *);
void	cpu_set_syscall_retval(struct thread *, int);
void	cpu_set_upcall(struct thread *td, struct thread *td0);
void	cpu_set_upcall_kse(struct thread *, void (*)(void *), void *,
	    stack_t *);
int	cpu_set_user_tls(struct thread *, void *tls_base);
void	cpu_thread_alloc(struct thread *);
void	cpu_thread_clean(struct thread *);
void	cpu_thread_exit(struct thread *);
void	cpu_thread_free(struct thread *);
void	cpu_thread_swapin(struct thread *);
void	cpu_thread_swapout(struct thread *);
struct	thread *thread_alloc(int pages);
int	thread_alloc_stack(struct thread *, int pages);
void	thread_exit(void) __dead2;
void	thread_free(struct thread *td);
void	thread_link(struct thread *td, struct proc *p);
void	thread_reap(void);
int	thread_single(int how);
void	thread_single_end(void);
void	thread_stash(struct thread *td);
void	thread_stopped(struct proc *p);
void	childproc_stopped(struct proc *child, int reason);
void	childproc_continued(struct proc *child);
void	childproc_exited(struct proc *child);
int	thread_suspend_check(int how);
void	thread_suspend_switch(struct thread *);
void	thread_suspend_one(struct thread *td);
void	thread_unlink(struct thread *td);
void	thread_unsuspend(struct proc *p);
int	thread_unsuspend_one(struct thread *td);
void	thread_unthread(struct thread *td);
void	thread_wait(struct proc *p);
struct thread	*thread_find(struct proc *p, lwpid_t tid);

static __inline int
curthread_pflags_set(int flags)
{
	struct thread *td;
	int save;

	td = curthread;
	save = ~flags | (td->td_pflags & flags);
	td->td_pflags |= flags;
	return (save);
}

static __inline void
curthread_pflags_restore(int save)
{

	curthread->td_pflags &= save;
}

#endif	/* _KERNEL */

#endif	/* !_SYS_PROC_H_ */

repo_name: veiledmerc/mira

license: mit


code:
/*-
 * Copyright (c) 2009 Robert N. M. Watson
 * All rights reserved.
 *
 * This software was developed at the University of Cambridge Computer
 * Laboratory with support from a grant from Google, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/procdesc.h 224987 2011-08-18 22:51:30Z jonathan $
 */

#ifndef _SYS_PROCDESC_H_
#define	_SYS_PROCDESC_H_

#ifdef _KERNEL
#include <sys/selinfo.h>	/* struct selinfo */
#include <sys/_lock.h>
#include <sys/_mutex.h>

/*-
 * struct procdesc describes a process descriptor, and essentially consists
 * of two pointers -- one to the file descriptor, and one to the process.
 * When both become NULL, the process descriptor will be freed.  An important
 * invariant is that there is only ever one process descriptor for a process,
 * so a single file pointer will suffice.
 *
 * Locking key:
 * (c) - Constant after initial setup.
 * (p) - Protected by the process descriptor mutex.
 * (r) - Atomic eference count.
 * (s) - Protected by selinfo.
 * (t) - Protected by the proctree_lock
 */
struct proc;
struct sigio;
struct procdesc {
	/*
	 * Basic process descriptor state: the process, a cache of its pid to
	 * satisfy queries after the process exits, and process descriptor
	 * refcount.
	 */
	struct proc	*pd_proc;		/* (t) Process. */
	pid_t		 pd_pid;		/* (c) Cached pid. */
	u_int		 pd_refcount;		/* (r) Reference count. */

	/*
	 * In-flight data and notification of events.
	 */
	int		 pd_flags;		/* (p) PD_ flags. */
	struct selinfo	 pd_selinfo;		/* (p) Event notification. */
	struct mtx	 pd_lock;		/* Protect data + events. */
};

/*
 * Locking macros for the procdesc itself.
 */
#define	PROCDESC_LOCK_DESTROY(pd)	mtx_destroy(&(pd)->pd_lock)
#define	PROCDESC_LOCK_INIT(pd)	mtx_init(&(pd)->pd_lock, "procdesc", NULL, \
				    MTX_DEF)
#define	PROCDESC_LOCK(pd)	mtx_lock(&(pd)->pd_lock)
#define	PROCDESC_UNLOCK(pd)	mtx_unlock(&(pd)->pd_lock)

/*
 * Flags for the pd_flags field.
 */
#define	PDF_CLOSED	0x00000001	/* Descriptor has closed. */
#define	PDF_SELECTED	0x00000002	/* Issue selwakeup(). */
#define	PDF_EXITED	0x00000004	/* Process exited. */
#define	PDF_DAEMON	0x00000008	/* Don't exit when procdesc closes. */

/*
 * In-kernel interfaces to process descriptors.
 */
int	 procdesc_exit(struct proc *);
int	 procdesc_find(struct thread *, int fd, cap_rights_t, struct proc **);
int	 kern_pdgetpid(struct thread *, int fd, cap_rights_t, pid_t *pidp);
void	 procdesc_new(struct proc *, int);
void	 procdesc_finit(struct procdesc *, struct file *);
pid_t	 procdesc_pid(struct file *);
void	 procdesc_reap(struct proc *);

#else /* !_KERNEL */

/*
 * Process descriptor system calls.
 */
struct rusage;
int	 pdfork(int *, int);
int	 pdkill(int, int);
int	 pdgetpid(int, pid_t *);

#endif /* _KERNEL */

/*
 * Flags which can be passed to pdfork(2).
 */
#define	PD_DAEMON	0x00000001	/* Don't exit when procdesc closes. */

#endif /* !_SYS_PROCDESC_H_ */


code:
/*-
 * Copyright (c) 1998 John D. Polstra.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/procfs.h 215679 2010-11-22 14:42:13Z attilio $
 */

#ifndef _SYS_PROCFS_H_
#define _SYS_PROCFS_H_

#include <sys/param.h>
#include <machine/reg.h>

typedef struct reg gregset_t;
typedef struct fpreg fpregset_t;

/*
 * These structures define an interface between core files and the debugger.
 * Never change or delete any elements.  If you add elements, add them to
 * the end of the structure, and increment the value of its version field.
 * This will help to ensure that today's core dump will still be usable
 * with next year's debugger.
 *
 * A lot more things should be added to these structures.  At present,
 * they contain the absolute bare minimum required to allow GDB to work
 * with ELF core dumps.
 */

/*
 * The parenthsized numbers like (1) indicate the minimum version number
 * for which each element exists in the structure.
 */

#define PRSTATUS_VERSION	1	/* Current version of prstatus_t */

typedef struct prstatus {
    int		pr_version;	/* Version number of struct (1) */
    size_t	pr_statussz;	/* sizeof(prstatus_t) (1) */
    size_t	pr_gregsetsz;	/* sizeof(gregset_t) (1) */
    size_t	pr_fpregsetsz;	/* sizeof(fpregset_t) (1) */
    int		pr_osreldate;	/* Kernel version (1) */
    int		pr_cursig;	/* Current signal (1) */
    pid_t	pr_pid;		/* Process ID (1) */
    gregset_t	pr_reg;		/* General purpose registers (1) */
} prstatus_t;

typedef gregset_t prgregset_t[1];
typedef fpregset_t prfpregset_t;

#define PRFNAMESZ	16	/* Maximum command length saved */
#define PRARGSZ		80	/* Maximum argument bytes saved */

#define PRPSINFO_VERSION	1	/* Current version of prpsinfo_t */

typedef struct prpsinfo {
    int		pr_version;	/* Version number of struct (1) */
    size_t	pr_psinfosz;	/* sizeof(prpsinfo_t) (1) */
    char	pr_fname[PRFNAMESZ+1];	/* Command name, null terminated (1) */
    char	pr_psargs[PRARGSZ+1];	/* Arguments, null terminated (1) */
} prpsinfo_t;

#define THRMISC_VERSION		1	/* Current version of thrmisc_t */

typedef struct thrmisc {
    char	pr_tname[MAXCOMLEN+1];	/* Thread name, null terminated (1) */
    u_int	_pad;			/* Convenience pad, 0-filled (1) */
} thrmisc_t;

typedef uint64_t psaddr_t;	/* An address in the target process. */

#endif /* _SYS_PROCFS_H_ */


code:
/*-
 * Copyright (c) 1982, 1986, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)protosw.h	8.1 (Berkeley) 6/2/93
 * $FreeBSD: release/9.0.0/sys/sys/protosw.h 193731 2009-06-08 17:15:40Z zec $
 */

#ifndef _SYS_PROTOSW_H_
#define _SYS_PROTOSW_H_

/* Forward declare these structures referenced from prototypes below. */
struct mbuf;
struct thread;
struct sockaddr;
struct socket;
struct sockopt;

/*#ifdef _KERNEL*/
/*
 * Protocol switch table.
 *
 * Each protocol has a handle initializing one of these structures,
 * which is used for protocol-protocol and system-protocol communication.
 *
 * A protocol is called through the pr_init entry before any other.
 * Thereafter it is called every 200ms through the pr_fasttimo entry and
 * every 500ms through the pr_slowtimo for timer based actions.
 * The system will call the pr_drain entry if it is low on space and
 * this should throw away any non-critical data.
 *
 * Protocols pass data between themselves as chains of mbufs using
 * the pr_input and pr_output hooks.  Pr_input passes data up (towards
 * the users) and pr_output passes it down (towards the interfaces); control
 * information passes up and down on pr_ctlinput and pr_ctloutput.
 * The protocol is responsible for the space occupied by any the
 * arguments to these entries and must dispose it.
 *
 * In retrospect, it would be a lot nicer to use an interface
 * similar to the vnode VOP interface.
 */
/* USE THESE FOR YOUR PROTOTYPES ! */
typedef void	pr_input_t (struct mbuf *, int);
typedef int	pr_input6_t (struct mbuf **, int*, int);  /* XXX FIX THIS */
typedef int	pr_output_t (struct mbuf *, struct socket *);
typedef void	pr_ctlinput_t (int, struct sockaddr *, void *);
typedef int	pr_ctloutput_t (struct socket *, struct sockopt *);
typedef	void	pr_init_t (void);
typedef	void	pr_destroy_t (void);
typedef	void	pr_fasttimo_t (void);
typedef	void	pr_slowtimo_t (void);
typedef	void	pr_drain_t (void);

struct protosw {
	short	pr_type;		/* socket type used for */
	struct	domain *pr_domain;	/* domain protocol a member of */
	short	pr_protocol;		/* protocol number */
	short	pr_flags;		/* see below */
/* protocol-protocol hooks */
	pr_input_t *pr_input;		/* input to protocol (from below) */
	pr_output_t *pr_output;		/* output to protocol (from above) */
	pr_ctlinput_t *pr_ctlinput;	/* control input (from below) */
	pr_ctloutput_t *pr_ctloutput;	/* control output (from above) */
/* utility hooks */
	pr_init_t *pr_init;
	pr_destroy_t *pr_destroy;
	pr_fasttimo_t *pr_fasttimo;	/* fast timeout (200ms) */
	pr_slowtimo_t *pr_slowtimo;	/* slow timeout (500ms) */
	pr_drain_t *pr_drain;		/* flush any excess space possible */

	struct	pr_usrreqs *pr_usrreqs;	/* user-protocol hook */
};
/*#endif*/

#define	PR_SLOWHZ	2		/* 2 slow timeouts per second */
#define	PR_FASTHZ	5		/* 5 fast timeouts per second */

/*
 * This number should be defined again within each protocol family to avoid
 * confusion.
 */
#define	PROTO_SPACER	32767		/* spacer for loadable protocols */

/*
 * Values for pr_flags.
 * PR_ADDR requires PR_ATOMIC;
 * PR_ADDR and PR_CONNREQUIRED are mutually exclusive.
 * PR_IMPLOPCL means that the protocol allows sendto without prior connect,
 *	and the protocol understands the MSG_EOF flag.  The first property is
 *	is only relevant if PR_CONNREQUIRED is set (otherwise sendto is allowed
 *	anyhow).
 */
#define	PR_ATOMIC	0x01		/* exchange atomic messages only */
#define	PR_ADDR		0x02		/* addresses given with messages */
#define	PR_CONNREQUIRED	0x04		/* connection required by protocol */
#define	PR_WANTRCVD	0x08		/* want PRU_RCVD calls */
#define	PR_RIGHTS	0x10		/* passes capabilities */
#define PR_IMPLOPCL	0x20		/* implied open/close */
#define	PR_LASTHDR	0x40		/* enforce ipsec policy; last header */

/*
 * In earlier BSD network stacks, a single pr_usrreq() function pointer was
 * invoked with an operation number indicating what operation was desired.
 * We now provide individual function pointers which protocols can implement,
 * which offers a number of benefits (such as type checking for arguments).
 * These older constants are still present in order to support TCP debugging.
 */
#define	PRU_ATTACH		0	/* attach protocol to up */
#define	PRU_DETACH		1	/* detach protocol from up */
#define	PRU_BIND		2	/* bind socket to address */
#define	PRU_LISTEN		3	/* listen for connection */
#define	PRU_CONNECT		4	/* establish connection to peer */
#define	PRU_ACCEPT		5	/* accept connection from peer */
#define	PRU_DISCONNECT		6	/* disconnect from peer */
#define	PRU_SHUTDOWN		7	/* won't send any more data */
#define	PRU_RCVD		8	/* have taken data; more room now */
#define	PRU_SEND		9	/* send this data */
#define	PRU_ABORT		10	/* abort (fast DISCONNECT, DETATCH) */
#define	PRU_CONTROL		11	/* control operations on protocol */
#define	PRU_SENSE		12	/* return status into m */
#define	PRU_RCVOOB		13	/* retrieve out of band data */
#define	PRU_SENDOOB		14	/* send out of band data */
#define	PRU_SOCKADDR		15	/* fetch socket's address */
#define	PRU_PEERADDR		16	/* fetch peer's address */
#define	PRU_CONNECT2		17	/* connect two sockets */
/* begin for protocols internal use */
#define	PRU_FASTTIMO		18	/* 200ms timeout */
#define	PRU_SLOWTIMO		19	/* 500ms timeout */
#define	PRU_PROTORCV		20	/* receive from below */
#define	PRU_PROTOSEND		21	/* send to below */
/* end for protocol's internal use */
#define PRU_SEND_EOF		22	/* send and close */
#define	PRU_SOSETLABEL		23	/* MAC label change */
#define	PRU_CLOSE		24	/* socket close */
#define	PRU_FLUSH		25	/* flush the socket */
#define	PRU_NREQ		25

#ifdef PRUREQUESTS
const char *prurequests[] = {
	"ATTACH",	"DETACH",	"BIND",		"LISTEN",
	"CONNECT",	"ACCEPT",	"DISCONNECT",	"SHUTDOWN",
	"RCVD",		"SEND",		"ABORT",	"CONTROL",
	"SENSE",	"RCVOOB",	"SENDOOB",	"SOCKADDR",
	"PEERADDR",	"CONNECT2",	"FASTTIMO",	"SLOWTIMO",
	"PROTORCV",	"PROTOSEND",	"SEND_EOF",	"SOSETLABEL",
	"CLOSE",	"FLUSH",
};
#endif

#ifdef	_KERNEL			/* users shouldn't see this decl */

struct ifnet;
struct stat;
struct ucred;
struct uio;

/*
 * If the ordering here looks odd, that's because it's alphabetical.  These
 * should eventually be merged back into struct protosw.
 *
 * Some fields initialized to defaults if they are NULL.
 * See uipc_domain.c:net_init_domain()
 */
struct pr_usrreqs {
	void	(*pru_abort)(struct socket *so);
	int	(*pru_accept)(struct socket *so, struct sockaddr **nam);
	int	(*pru_attach)(struct socket *so, int proto, struct thread *td);
	int	(*pru_bind)(struct socket *so, struct sockaddr *nam,
		    struct thread *td);
	int	(*pru_connect)(struct socket *so, struct sockaddr *nam,
		    struct thread *td);
	int	(*pru_connect2)(struct socket *so1, struct socket *so2);
	int	(*pru_control)(struct socket *so, u_long cmd, caddr_t data,
		    struct ifnet *ifp, struct thread *td);
	void	(*pru_detach)(struct socket *so);
	int	(*pru_disconnect)(struct socket *so);
	int	(*pru_listen)(struct socket *so, int backlog,
		    struct thread *td);
	int	(*pru_peeraddr)(struct socket *so, struct sockaddr **nam);
	int	(*pru_rcvd)(struct socket *so, int flags);
	int	(*pru_rcvoob)(struct socket *so, struct mbuf *m, int flags);
	int	(*pru_send)(struct socket *so, int flags, struct mbuf *m,
		    struct sockaddr *addr, struct mbuf *control,
		    struct thread *td);
#define	PRUS_OOB	0x1
#define	PRUS_EOF	0x2
#define	PRUS_MORETOCOME	0x4
	int	(*pru_sense)(struct socket *so, struct stat *sb);
        int	(*pru_shutdown)(struct socket *so);
	int	(*pru_flush)(struct socket *so, int direction);
	int	(*pru_sockaddr)(struct socket *so, struct sockaddr **nam);
	int	(*pru_sosend)(struct socket *so, struct sockaddr *addr,
		    struct uio *uio, struct mbuf *top, struct mbuf *control,
		    int flags, struct thread *td);
	int	(*pru_soreceive)(struct socket *so, struct sockaddr **paddr,
		    struct uio *uio, struct mbuf **mp0, struct mbuf **controlp,
		    int *flagsp);
	int	(*pru_sopoll)(struct socket *so, int events,
		    struct ucred *cred, struct thread *td);
	void	(*pru_sosetlabel)(struct socket *so);
	void	(*pru_close)(struct socket *so);
};

/*
 * All nonvoid pru_*() functions below return EOPNOTSUPP.
 */
int	pru_accept_notsupp(struct socket *so, struct sockaddr **nam);
int	pru_attach_notsupp(struct socket *so, int proto, struct thread *td);
int	pru_bind_notsupp(struct socket *so, struct sockaddr *nam,
	    struct thread *td);
int	pru_connect_notsupp(struct socket *so, struct sockaddr *nam,
	    struct thread *td);
int	pru_connect2_notsupp(struct socket *so1, struct socket *so2);
int	pru_control_notsupp(struct socket *so, u_long cmd, caddr_t data,
	    struct ifnet *ifp, struct thread *td);
int	pru_disconnect_notsupp(struct socket *so);
int	pru_listen_notsupp(struct socket *so, int backlog, struct thread *td);
int	pru_peeraddr_notsupp(struct socket *so, struct sockaddr **nam);
int	pru_rcvd_notsupp(struct socket *so, int flags);
int	pru_rcvoob_notsupp(struct socket *so, struct mbuf *m, int flags);
int	pru_send_notsupp(struct socket *so, int flags, struct mbuf *m,
	    struct sockaddr *addr, struct mbuf *control, struct thread *td);
int	pru_sense_null(struct socket *so, struct stat *sb);
int	pru_shutdown_notsupp(struct socket *so);
int	pru_sockaddr_notsupp(struct socket *so, struct sockaddr **nam);
int	pru_sosend_notsupp(struct socket *so, struct sockaddr *addr,
	    struct uio *uio, struct mbuf *top, struct mbuf *control, int flags,
	    struct thread *td);
int	pru_soreceive_notsupp(struct socket *so, struct sockaddr **paddr,
	    struct uio *uio, struct mbuf **mp0, struct mbuf **controlp,
	    int *flagsp);
int	pru_sopoll_notsupp(struct socket *so, int events, struct ucred *cred,
	    struct thread *td);

#endif /* _KERNEL */

/*
 * The arguments to the ctlinput routine are
 *	(*protosw[].pr_ctlinput)(cmd, sa, arg);
 * where cmd is one of the commands below, sa is a pointer to a sockaddr,
 * and arg is a `void *' argument used within a protocol family.
 */
#define	PRC_IFDOWN		0	/* interface transition */
#define	PRC_ROUTEDEAD		1	/* select new route if possible ??? */
#define	PRC_IFUP		2 	/* interface has come back up */
#define	PRC_QUENCH2		3	/* DEC congestion bit says slow down */
#define	PRC_QUENCH		4	/* some one said to slow down */
#define	PRC_MSGSIZE		5	/* message size forced drop */
#define	PRC_HOSTDEAD		6	/* host appears to be down */
#define	PRC_HOSTUNREACH		7	/* deprecated (use PRC_UNREACH_HOST) */
#define	PRC_UNREACH_NET		8	/* no route to network */
#define	PRC_UNREACH_HOST	9	/* no route to host */
#define	PRC_UNREACH_PROTOCOL	10	/* dst says bad protocol */
#define	PRC_UNREACH_PORT	11	/* bad port # */
/* was	PRC_UNREACH_NEEDFRAG	12	   (use PRC_MSGSIZE) */
#define	PRC_UNREACH_SRCFAIL	13	/* source route failed */
#define	PRC_REDIRECT_NET	14	/* net routing redirect */
#define	PRC_REDIRECT_HOST	15	/* host routing redirect */
#define	PRC_REDIRECT_TOSNET	16	/* redirect for type of service & net */
#define	PRC_REDIRECT_TOSHOST	17	/* redirect for tos & host */
#define	PRC_TIMXCEED_INTRANS	18	/* packet lifetime expired in transit */
#define	PRC_TIMXCEED_REASS	19	/* lifetime expired on reass q */
#define	PRC_PARAMPROB		20	/* header incorrect */
#define	PRC_UNREACH_ADMIN_PROHIB	21	/* packet administrativly prohibited */

#define	PRC_NCMDS		22

#define	PRC_IS_REDIRECT(cmd)	\
	((cmd) >= PRC_REDIRECT_NET && (cmd) <= PRC_REDIRECT_TOSHOST)

#ifdef PRCREQUESTS
char	*prcrequests[] = {
	"IFDOWN", "ROUTEDEAD", "IFUP", "DEC-BIT-QUENCH2",
	"QUENCH", "MSGSIZE", "HOSTDEAD", "#7",
	"NET-UNREACH", "HOST-UNREACH", "PROTO-UNREACH", "PORT-UNREACH",
	"#12", "SRCFAIL-UNREACH", "NET-REDIRECT", "HOST-REDIRECT",
	"TOSNET-REDIRECT", "TOSHOST-REDIRECT", "TX-INTRANS", "TX-REASS",
	"PARAMPROB", "ADMIN-UNREACH"
};
#endif

/*
 * The arguments to ctloutput are:
 *	(*protosw[].pr_ctloutput)(req, so, level, optname, optval, p);
 * req is one of the actions listed below, so is a (struct socket *),
 * level is an indication of which protocol layer the option is intended.
 * optname is a protocol dependent socket option request,
 * optval is a pointer to a mbuf-chain pointer, for value-return results.
 * The protocol is responsible for disposal of the mbuf chain *optval
 * if supplied,
 * the caller is responsible for any space held by *optval, when returned.
 * A non-zero return from ctloutput gives an
 * UNIX error number which should be passed to higher level software.
 */
#define	PRCO_GETOPT	0
#define	PRCO_SETOPT	1

#define	PRCO_NCMDS	2

#ifdef PRCOREQUESTS
char	*prcorequests[] = {
	"GETOPT", "SETOPT",
};
#endif

#ifdef _KERNEL
void	pfctlinput(int, struct sockaddr *);
void	pfctlinput2(int, struct sockaddr *, void *);
struct protosw *pffindproto(int family, int protocol, int type);
struct protosw *pffindtype(int family, int type);
int	pf_proto_register(int family, struct protosw *npr);
int	pf_proto_unregister(int family, int protocol, int type);
#endif

#endif


code:
/*-
 * Copyright (c) 1999 Kenneth D. Merry.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification, immediately at the beginning of the file.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/sys/ptio.h 50477 1999-08-28 01:08:13Z peter $
 */

#ifndef _SYS_PTIO_H_
#define	_SYS_PTIO_H_

#include <sys/ioccom.h>

#define	PTIOCGETTIMEOUT	_IOR('T', 1, int)
#define	PTIOCSETTIMEOUT	_IOW('T', 2, int)

#endif /* !_SYS_PTIO_H_ */


code:
/*-
 * Copyright (c) 1984, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)ptrace.h	8.2 (Berkeley) 1/4/94
 * $FreeBSD: release/9.0.0/sys/sys/ptrace.h 217819 2011-01-25 10:59:21Z kib $
 */

#ifndef	_SYS_PTRACE_H_
#define	_SYS_PTRACE_H_

#include <sys/signal.h>
#include <sys/param.h>
#include <machine/reg.h>

#define	PT_TRACE_ME	0	/* child declares it's being traced */
#define	PT_READ_I	1	/* read word in child's I space */
#define	PT_READ_D	2	/* read word in child's D space */
/* was	PT_READ_U	3	 * read word in child's user structure */
#define	PT_WRITE_I	4	/* write word in child's I space */
#define	PT_WRITE_D	5	/* write word in child's D space */
/* was	PT_WRITE_U	6	 * write word in child's user structure */
#define	PT_CONTINUE	7	/* continue the child */
#define	PT_KILL		8	/* kill the child process */
#define	PT_STEP		9	/* single step the child */

#define	PT_ATTACH	10	/* trace some running process */
#define	PT_DETACH	11	/* stop tracing a process */
#define PT_IO		12	/* do I/O to/from stopped process. */
#define	PT_LWPINFO	13	/* Info about the LWP that stopped. */
#define PT_GETNUMLWPS	14	/* get total number of threads */
#define PT_GETLWPLIST	15	/* get thread list */
#define PT_CLEARSTEP	16	/* turn off single step */
#define PT_SETSTEP	17	/* turn on single step */
#define PT_SUSPEND	18	/* suspend a thread */
#define PT_RESUME	19	/* resume a thread */

#define	PT_TO_SCE	20
#define	PT_TO_SCX	21
#define	PT_SYSCALL	22

#define	PT_FOLLOW_FORK	23

#define PT_GETREGS      33	/* get general-purpose registers */
#define PT_SETREGS      34	/* set general-purpose registers */
#define PT_GETFPREGS    35	/* get floating-point registers */
#define PT_SETFPREGS    36	/* set floating-point registers */
#define PT_GETDBREGS    37	/* get debugging registers */
#define PT_SETDBREGS    38	/* set debugging registers */

#define	PT_VM_TIMESTAMP	40	/* Get VM version (timestamp) */
#define	PT_VM_ENTRY	41	/* Get VM map (entry) */

#define PT_FIRSTMACH    64	/* for machine-specific requests */
#include <machine/ptrace.h>	/* machine-specific requests, if any */

struct ptrace_io_desc {
	int	piod_op;	/* I/O operation */
	void	*piod_offs;	/* child offset */
	void	*piod_addr;	/* parent offset */
	size_t	piod_len;	/* request length */
};

/*
 * Operations in piod_op.
 */
#define PIOD_READ_D	1	/* Read from D space */
#define PIOD_WRITE_D	2	/* Write to D space */
#define PIOD_READ_I	3	/* Read from I space */
#define PIOD_WRITE_I	4	/* Write to I space */

/* Argument structure for PT_LWPINFO. */
struct ptrace_lwpinfo {
	lwpid_t	pl_lwpid;	/* LWP described. */
	int	pl_event;	/* Event that stopped the LWP. */
#define	PL_EVENT_NONE	0
#define	PL_EVENT_SIGNAL	1
	int	pl_flags;	/* LWP flags. */
#define	PL_FLAG_SA	0x01	/* M:N thread */
#define	PL_FLAG_BOUND	0x02	/* M:N bound thread */
#define	PL_FLAG_SCE	0x04	/* syscall enter point */
#define	PL_FLAG_SCX	0x08	/* syscall leave point */
#define	PL_FLAG_EXEC	0x10	/* exec(2) succeeded */
#define	PL_FLAG_SI	0x20	/* siginfo is valid */
#define	PL_FLAG_FORKED	0x40	/* new child */
	sigset_t	pl_sigmask;	/* LWP signal mask */
	sigset_t	pl_siglist;	/* LWP pending signal */
	struct __siginfo pl_siginfo;	/* siginfo for signal */
	char		pl_tdname[MAXCOMLEN + 1]; /* LWP name */
	int		pl_child_pid;	/* New child pid */
};

/* Argument structure for PT_VM_ENTRY. */
struct ptrace_vm_entry {
	int		pve_entry;	/* Entry number used for iteration. */
	int		pve_timestamp;	/* Generation number of VM map. */
	u_long		pve_start;	/* Start VA of range. */
	u_long		pve_end;	/* End VA of range (incl). */
	u_long		pve_offset;	/* Offset in backing object. */
	u_int		pve_prot;	/* Protection of memory range. */
	u_int		pve_pathlen;	/* Size of path. */
	long		pve_fileid;	/* File ID. */
	uint32_t	pve_fsid;	/* File system ID. */
	char		*pve_path;	/* Path name of object. */
};

#ifdef _KERNEL

#define	PTRACESTOP_SC(p, td, flag)				\
	if ((p)->p_flag & P_TRACED && (p)->p_stops & (flag)) {	\
		PROC_LOCK(p);					\
		ptracestop((td), SIGTRAP);			\
		PROC_UNLOCK(p);					\
	}
/*
 * The flags below are used for ptrace(2) tracing and have no relation
 * to procfs.  They are stored in struct proc's p_stops member.
 */
#define	S_PT_SCE	0x000010000
#define	S_PT_SCX	0x000020000

int	ptrace_set_pc(struct thread *_td, unsigned long _addr);
int	ptrace_single_step(struct thread *_td);
int	ptrace_clear_single_step(struct thread *_td);

#ifdef __HAVE_PTRACE_MACHDEP
int	cpu_ptrace(struct thread *_td, int _req, void *_addr, int _data);
#endif

/*
 * These are prototypes for functions that implement some of the
 * debugging functionality exported by procfs / linprocfs and by the
 * ptrace(2) syscall.  They used to be part of procfs, but they don't
 * really belong there.
 */
struct reg;
struct fpreg;
struct dbreg;
struct uio;
int	proc_read_regs(struct thread *_td, struct reg *_reg);
int	proc_write_regs(struct thread *_td, struct reg *_reg);
int	proc_read_fpregs(struct thread *_td, struct fpreg *_fpreg);
int	proc_write_fpregs(struct thread *_td, struct fpreg *_fpreg);
int	proc_read_dbregs(struct thread *_td, struct dbreg *_dbreg);
int	proc_write_dbregs(struct thread *_td, struct dbreg *_dbreg);
int	proc_sstep(struct thread *_td);
int	proc_rwmem(struct proc *_p, struct uio *_uio);
#ifdef COMPAT_FREEBSD32
struct reg32;
struct fpreg32;
struct dbreg32;
int	proc_read_regs32(struct thread *_td, struct reg32 *_reg32);
int	proc_write_regs32(struct thread *_td, struct reg32 *_reg32);
int	proc_read_fpregs32(struct thread *_td, struct fpreg32 *_fpreg32);
int	proc_write_fpregs32(struct thread *_td, struct fpreg32 *_fpreg32);
int	proc_read_dbregs32(struct thread *_td, struct dbreg32 *_dbreg32);
int	proc_write_dbregs32(struct thread *_td, struct dbreg32 *_dbreg32);
#endif
#else /* !_KERNEL */

#include <sys/cdefs.h>

__BEGIN_DECLS
int	ptrace(int _request, pid_t _pid, caddr_t _addr, int _data);
__END_DECLS

#endif /* !_KERNEL */

#endif	/* !_SYS_PTRACE_H_ */