code:
/*-
 * Copyright (c) 2000,2003 Doug Rabson
 * 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/kobj.h 227712 2011-11-19 12:55:34Z marius $
 */

#ifndef _SYS_KOBJ_H_
#define _SYS_KOBJ_H_

/*
 * Forward declarations
 */
typedef struct kobj		*kobj_t;
typedef struct kobj_class	*kobj_class_t;
typedef struct kobj_method	kobj_method_t;
typedef int			(*kobjop_t)(void);
typedef struct kobj_ops		*kobj_ops_t;
typedef struct kobjop_desc	*kobjop_desc_t;
struct malloc_type;

struct kobj_method {
	kobjop_desc_t	desc;
	kobjop_t	func;
};

/*
 * A class is simply a method table and a sizeof value. When the first
 * instance of the class is created, the method table will be compiled
 * into a form more suited to efficient method dispatch. This compiled
 * method table is always the first field of the object.
 */
#define KOBJ_CLASS_FIELDS						\
	const char	*name;		/* class name */		\
	kobj_method_t	*methods;	/* method table */		\
	size_t		size;		/* object size */		\
	kobj_class_t	*baseclasses;	/* base classes */		\
	u_int		refs;		/* reference count */		\
	kobj_ops_t	ops		/* compiled method table */

struct kobj_class {
	KOBJ_CLASS_FIELDS;
};

/*
 * Implementation of kobj.
 */
#define KOBJ_FIELDS				\
	kobj_ops_t	ops

struct kobj {
	KOBJ_FIELDS;
};

/*
 * The ops table is used as a cache of results from kobj_lookup_method().
 */

#define KOBJ_CACHE_SIZE	256

struct kobj_ops {
	kobj_method_t	*cache[KOBJ_CACHE_SIZE];
	kobj_class_t	cls;
};

struct kobjop_desc {
	unsigned int	id;		/* unique ID */
	kobj_method_t	*deflt;		/* default implementation */
};

/*
 * Shorthand for constructing method tables.
 * The ternary operator is (ab)used to provoke a warning when FUNC
 * has a signature that is not compatible with kobj method signature.
 */
#define KOBJMETHOD(NAME, FUNC) \
	{ &NAME##_desc, (kobjop_t) (1 ? FUNC : (NAME##_t *)NULL) }

/*
 *
 */
#define KOBJMETHOD_END	{ NULL, NULL }

/*
 * Declare a class (which should be defined in another file.
 */
#define DECLARE_CLASS(name) extern struct kobj_class name

/*
 * Define a class with no base classes (api backward-compatible. with
 * FreeBSD-5.1 and earlier).
 */
#define DEFINE_CLASS(name, methods, size)     		\
DEFINE_CLASS_0(name, name ## _class, methods, size)

/*
 * Define a class with no base classes. Use like this:
 *
 * DEFINE_CLASS_0(foo, foo_class, foo_methods, sizeof(foo_softc));
 */
#define DEFINE_CLASS_0(name, classvar, methods, size)	\
							\
struct kobj_class classvar = {				\
	#name, methods, size, NULL			\
}

/*
 * Define a class inheriting a single base class. Use like this:
 *
 * DEFINE_CLASS_1(foo, foo_class, foo_methods, sizeof(foo_softc),
 *			  bar);
 */
#define DEFINE_CLASS_1(name, classvar, methods, size,	\
		       base1)				\
							\
static kobj_class_t name ## _baseclasses[] =		\
	{ &base1, NULL };				\
struct kobj_class classvar = {				\
	#name, methods, size, name ## _baseclasses	\
}

/*
 * Define a class inheriting two base classes. Use like this:
 *
 * DEFINE_CLASS_2(foo, foo_class, foo_methods, sizeof(foo_softc),
 *			  bar, baz);
 */
#define DEFINE_CLASS_2(name, methods, size,		\
	               base1, base2)			\
							\
static kobj_class_t name ## _baseclasses[] =		\
	{ &base1,					\
	  &base2, NULL };				\
struct kobj_class name ## _class = {			\
	#name, methods, size, name ## _baseclasses	\
}

/*
 * Define a class inheriting three base classes. Use like this:
 *
 * DEFINE_CLASS_3(foo, foo_class, foo_methods, sizeof(foo_softc),
 *			  bar, baz, foobar);
 */
#define DEFINE_CLASS_3(name, methods, size,		\
		       base1, base2, base3)		\
							\
static kobj_class_t name ## _baseclasses[] =		\
	{ &base1,					\
	  &base2,					\
	  &base3, NULL };				\
struct kobj_class name ## _class = {			\
	#name, methods, size, name ## _baseclasses	\
}

/*
 * Compile the method table in a class.
 */
void		kobj_class_compile(kobj_class_t cls);

/*
 * Compile the method table, with the caller providing the space for
 * the ops table.(for use before malloc is initialised).
 */
void		kobj_class_compile_static(kobj_class_t cls, kobj_ops_t ops);

/*
 * Free the compiled method table in a class.
 */
void		kobj_class_free(kobj_class_t cls);

/*
 * Allocate memory for and initialise a new object.
 */
kobj_t		kobj_create(kobj_class_t cls,
			    struct malloc_type *mtype,
			    int mflags);

/*
 * Initialise a pre-allocated object.
 */
void		kobj_init(kobj_t obj, kobj_class_t cls);
void		kobj_init_static(kobj_t obj, kobj_class_t cls);

/*
 * Delete an object. If mtype is non-zero, free the memory.
 */
void		kobj_delete(kobj_t obj, struct malloc_type *mtype);

/*
 * Maintain stats on hits/misses in lookup caches.
 */
#ifdef KOBJ_STATS
extern u_int kobj_lookup_hits;
extern u_int kobj_lookup_misses;
#endif

/*
 * Lookup the method in the cache and if it isn't there look it up the
 * slow way.
 */
#ifdef KOBJ_STATS
#define KOBJOPLOOKUP(OPS,OP) do {				\
	kobjop_desc_t _desc = &OP##_##desc;			\
	kobj_method_t **_cep =					\
	    &OPS->cache[_desc->id & (KOBJ_CACHE_SIZE-1)];	\
	kobj_method_t *_ce = *_cep;				\
	kobj_lookup_hits++; /* assume hit */			\
	if (_ce->desc != _desc)					\
		_ce = kobj_lookup_method(OPS->cls,		\
					 _cep, _desc);		\
	_m = _ce->func;						\
} while(0)
#else
#define KOBJOPLOOKUP(OPS,OP) do {				\
	kobjop_desc_t _desc = &OP##_##desc;			\
	kobj_method_t **_cep =					\
	    &OPS->cache[_desc->id & (KOBJ_CACHE_SIZE-1)];	\
	kobj_method_t *_ce = *_cep;				\
	if (_ce->desc != _desc)					\
		_ce = kobj_lookup_method(OPS->cls,		\
					 _cep, _desc);		\
	_m = _ce->func;						\
} while(0)
#endif

kobj_method_t* kobj_lookup_method(kobj_class_t cls,
				  kobj_method_t **cep,
				  kobjop_desc_t desc);

/*
 * Default method implementation. Returns ENXIO.
 */
int kobj_error_method(void);

#endif /* !_SYS_KOBJ_H_ */


code:
/*-
 * Copyright (c) 2002 Alfred Perlstein <alfred@FreeBSD.org>
 * 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/ksem.h 180059 2008-06-27 05:39:04Z jhb $
 */

#ifndef _POSIX4_KSEM_H_
#define	_POSIX4_KSEM_H_

#ifndef _KERNEL
#error "no user-servicable parts inside"
#endif

#include <sys/condvar.h>

struct ksem {
	int		ks_ref;		/* number of references */
	mode_t		ks_mode;	/* protection bits */
	uid_t		ks_uid;		/* creator uid */
	gid_t		ks_gid;		/* creator gid */
	unsigned int	ks_value;	/* current value */
	struct cv	ks_cv;		/* waiters sleep here */
	int		ks_waiters;	/* number of waiters */
	int		ks_flags;

	/*
	 * Values maintained solely to make this a better-behaved file
	 * descriptor for fstat() to run on.
	 *
	 * XXX: dubious
	 */
	struct timespec	ks_atime;
	struct timespec	ks_mtime;
	struct timespec	ks_ctime;
	struct timespec	ks_birthtime;

	struct label	*ks_label;	/* MAC label */
};

#define	KS_ANONYMOUS	0x0001		/* Anonymous (unnamed) semaphore. */
#define	KS_DEAD		0x0002		/* No new waiters allowed. */

#endif /* !_POSIX4_KSEM_H_ */

repo_name: veiledmerc/mira

license: mit


code:
/*-
 * Copyright (c) 2008-2009, Stacey Son <sson@freebsd.org>
 * 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/ksyms.h 192859 2009-05-26 21:39:09Z sson $
 */

#ifndef _SYS_KSYMS_H_
#define _SYS_KSYMS_H_

#include <sys/ioccom.h>

#define KIOCGSIZE	_IOR('l', 1, size_t)
#define KIOCGADDR	_IOR('l', 2, void *)

#endif /* _SYS_KSYMS_H_ */


code:
/*-
 * Copyright (c) 1999 Peter Wemm <peter@FreeBSD.org>
 * 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/kthread.h 210365 2010-07-22 05:42:29Z trasz $
 */

#ifndef _SYS_KTHREAD_H_
#define	_SYS_KTHREAD_H_

#include <sys/cdefs.h>

/*
 * A kernel process descriptor; used to start "internal" daemons.
 *
 * Note: global_procpp may be NULL for no global save area.
 */
struct kproc_desc {
	char		*arg0;			/* arg 0 (for 'ps' listing) */
	void		(*func)(void);	/* "main" for kernel process */
	struct proc	**global_procpp;	/* ptr to proc ptr save area */
};

 /* A kernel thread descriptor; used to start "internal" daemons. */
struct kthread_desc {
	char		*arg0;			/* arg 0 (for 'ps' listing) */
	void		(*func)(void);		/* "main" for kernel thread */
	struct thread	**global_threadpp;	/* ptr to thread ptr save area */
};

int     kproc_create(void (*)(void *), void *, struct proc **,
	    int flags, int pages, const char *, ...) __printflike(6, 7);
void    kproc_exit(int) __dead2;
int	kproc_resume(struct proc *);
void	kproc_shutdown(void *, int);
void	kproc_start(const void *);
int	kproc_suspend(struct proc *, int);
void	kproc_suspend_check(struct proc *);

/* create a thread inthe given process. create the process if needed */
int     kproc_kthread_add(void (*)(void *), void *,
	    struct proc **,
	    struct thread **,
	    int flags, int pages,
	    const char *procname, const char *, ...) __printflike(8, 9);

int     kthread_add(void (*)(void *), void *,
	    struct proc *, struct thread **,
	    int flags, int pages, const char *, ...) __printflike(7, 8);
void    kthread_exit(void) __dead2;
int	kthread_resume(struct thread *);
void	kthread_shutdown(void *, int);
void	kthread_start(const void *);
int	kthread_suspend(struct thread *, int);
void	kthread_suspend_check(void);

#endif /* !_SYS_KTHREAD_H_ */


code:
/*-
 * Copyright (c) 1996 Berkeley Software Design, Inc. 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.
 * 3. Berkeley Software Design Inc's name may not be used to endorse or
 *    promote products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``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 BERKELEY SOFTWARE DESIGN INC 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.
 *
 *	from BSDI $Id: ktr.h,v 1.10.2.7 2000/03/16 21:44:42 cp Exp $
 * $FreeBSD: release/9.0.0/sys/sys/ktr.h 222813 2011-06-07 08:46:13Z attilio $
 */

/*
 *	Wraparound kernel trace buffer support.
 */

#ifndef _SYS_KTR_H_
#define _SYS_KTR_H_

/*
 * Trace classes
 *
 * Two of the trace classes (KTR_DEV and KTR_SUBSYS) are special in that
 * they are really placeholders so that indvidual drivers and subsystems
 * can map their internal tracing to the general class when they wish to
 * have tracing enabled and map it to 0 when they don't.
 */
#define	KTR_GEN		0x00000001		/* General (TR) */
#define	KTR_NET		0x00000002		/* Network */
#define	KTR_DEV		0x00000004		/* Device driver */
#define	KTR_LOCK	0x00000008		/* MP locking */
#define	KTR_SMP		0x00000010		/* MP general */
#define	KTR_SUBSYS	0x00000020		/* Subsystem. */
#define	KTR_PMAP	0x00000040		/* Pmap tracing */
#define	KTR_MALLOC	0x00000080		/* Malloc tracing */
#define	KTR_TRAP	0x00000100		/* Trap processing */
#define	KTR_INTR	0x00000200		/* Interrupt tracing */
#define	KTR_SIG		0x00000400		/* Signal processing */
#define	KTR_SPARE2	0x00000800		/* XXX Used by cxgb */
#define	KTR_PROC	0x00001000		/* Process scheduling */
#define	KTR_SYSC	0x00002000		/* System call */
#define	KTR_INIT	0x00004000		/* System initialization */
#define	KTR_SPARE3	0x00008000		/* XXX Used by cxgb */
#define	KTR_SPARE4	0x00010000		/* XXX Used by cxgb */
#define	KTR_EVH		0x00020000		/* Eventhandler */
#define	KTR_VFS		0x00040000		/* VFS events */
#define	KTR_VOP		0x00080000		/* Auto-generated vop events */
#define	KTR_VM		0x00100000		/* The virtual memory system */
#define	KTR_INET	0x00200000		/* IPv4 stack */
#define	KTR_RUNQ	0x00400000		/* Run queue */
#define	KTR_CONTENTION	0x00800000		/* Lock contention */
#define	KTR_UMA		0x01000000		/* UMA slab allocator */
#define	KTR_CALLOUT	0x02000000		/* Callouts and timeouts */
#define	KTR_GEOM	0x04000000		/* GEOM I/O events */
#define	KTR_BUSDMA	0x08000000		/* busdma(9) events */
#define	KTR_INET6	0x10000000		/* IPv6 stack */
#define	KTR_SCHED	0x20000000		/* Machine parsed sched info. */
#define	KTR_BUF		0x40000000		/* Buffer cache */
#define	KTR_ALL		0x7fffffff

/* Trace classes to compile in */
#ifdef KTR
#ifndef KTR_COMPILE
#define	KTR_COMPILE	(KTR_ALL)
#endif
#else	/* !KTR */
#undef KTR_COMPILE
#define KTR_COMPILE 0
#endif	/* KTR */

/*
 * Version number for ktr_entry struct.  Increment this when you break binary
 * compatibility.
 */
#define	KTR_VERSION	2

#define	KTR_PARMS	6

#ifndef LOCORE

#include <sys/param.h>
#include <sys/_cpuset.h>

struct ktr_entry {
	u_int64_t ktr_timestamp;
	int	ktr_cpu;
	int	ktr_line;
	const	char *ktr_file;
	const	char *ktr_desc;
	struct	thread *ktr_thread;
	u_long	ktr_parms[KTR_PARMS];
};

extern cpuset_t ktr_cpumask;
extern int ktr_mask;
extern int ktr_entries;
extern int ktr_verbose;

extern volatile int ktr_idx;
extern struct ktr_entry ktr_buf[];

#ifdef KTR

void	ktr_tracepoint(u_int mask, const char *file, int line,
	    const char *format, u_long arg1, u_long arg2, u_long arg3,
	    u_long arg4, u_long arg5, u_long arg6);

#define CTR6(m, format, p1, p2, p3, p4, p5, p6) do {			\
	if (KTR_COMPILE & (m))						\
		ktr_tracepoint((m), __FILE__, __LINE__, format,		\
		    (u_long)(p1), (u_long)(p2), (u_long)(p3),		\
		    (u_long)(p4), (u_long)(p5), (u_long)(p6));		\
	} while(0)
#define CTR0(m, format)			CTR6(m, format, 0, 0, 0, 0, 0, 0)
#define CTR1(m, format, p1)		CTR6(m, format, p1, 0, 0, 0, 0, 0)
#define	CTR2(m, format, p1, p2)		CTR6(m, format, p1, p2, 0, 0, 0, 0)
#define	CTR3(m, format, p1, p2, p3)	CTR6(m, format, p1, p2, p3, 0, 0, 0)
#define	CTR4(m, format, p1, p2, p3, p4)	CTR6(m, format, p1, p2, p3, p4, 0, 0)
#define	CTR5(m, format, p1, p2, p3, p4, p5)	CTR6(m, format, p1, p2, p3, p4, p5, 0)
#else	/* KTR */
#define	CTR0(m, d)			(void)0
#define	CTR1(m, d, p1)			(void)0
#define	CTR2(m, d, p1, p2)		(void)0
#define	CTR3(m, d, p1, p2, p3)		(void)0
#define	CTR4(m, d, p1, p2, p3, p4)	(void)0
#define	CTR5(m, d, p1, p2, p3, p4, p5)	(void)0
#define	CTR6(m, d, p1, p2, p3, p4, p5, p6)	(void)0
#endif	/* KTR */

#define	TR0(d)				CTR0(KTR_GEN, d)
#define	TR1(d, p1)			CTR1(KTR_GEN, d, p1)
#define	TR2(d, p1, p2)			CTR2(KTR_GEN, d, p1, p2)
#define	TR3(d, p1, p2, p3)		CTR3(KTR_GEN, d, p1, p2, p3)
#define	TR4(d, p1, p2, p3, p4)		CTR4(KTR_GEN, d, p1, p2, p3, p4)
#define	TR5(d, p1, p2, p3, p4, p5)	CTR5(KTR_GEN, d, p1, p2, p3, p4, p5)
#define	TR6(d, p1, p2, p3, p4, p5, p6)	CTR6(KTR_GEN, d, p1, p2, p3, p4, p5, p6)

/*
 * The event macros implement KTR graphic plotting facilities provided
 * by src/tools/sched/schedgraph.py.  Three generic types of events are
 * supported: states, counters, and points.
 *
 * m is the ktr class for ktr_mask.
 * ident is the string identifier that owns the event (ie: "thread 10001")
 * etype is the type of event to plot (state, counter, point)
 * edat is the event specific data (state name, counter value, point name)
 * up to four attributes may be supplied as a name, value pair of arguments.
 *
 * etype and attribute names must be string constants.  This minimizes the
 * number of ktr slots required by construction the final format strings
 * at compile time.  Both must also include a colon and format specifier
 * (ie. "prio:%d", prio).  It is recommended that string arguments be
 * contained within escaped quotes if they may contain ',' or ':' characters.
 *
 * The special attribute (KTR_ATTR_LINKED, ident) creates a reference to another
 * id on the graph for easy traversal of related graph elements.
 */

#define	KTR_ATTR_LINKED	"linkedto:\"%s\""
#define	KTR_EFMT(egroup, ident, etype)					\
	    "KTRGRAPH group:\"" egroup "\", id:\"%s\", " etype ", attributes: "

#define	KTR_EVENT0(m, egroup, ident, etype, edat)			\
	CTR2(m,	KTR_EFMT(egroup, ident, etype) "none", ident, edat)
#define	KTR_EVENT1(m, egroup, ident, etype, edat, a0, v0)		\
	CTR3(m, KTR_EFMT(egroup, ident, etype) a0, ident, edat, (v0))
#define	KTR_EVENT2(m, egroup, ident, etype, edat, a0, v0, a1, v1)	\
	CTR4(m, KTR_EFMT(egroup, ident, etype) a0 ", " a1,		\
	    ident, edat, (v0), (v1))
#define	KTR_EVENT3(m, egroup, ident, etype, edat, a0, v0, a1, v1, a2, v2)\
	CTR5(m,KTR_EFMT(egroup, ident, etype) a0 ", " a1 ", " a2,	\
	    ident, edat, (v0), (v1), (v2))
#define	KTR_EVENT4(m, egroup, ident, etype, edat,			\
	    a0, v0, a1, v1, a2, v2, a3, v3)				\
	CTR6(m,KTR_EFMT(egroup, ident, etype) a0 ", " a1 ", " a2 ", " a3,\
	     ident, edat, (v0), (v1), (v2), (v3))

/*
 * State functions graph state changes on an ident.
 */
#define KTR_STATE0(m, egroup, ident, state)				\
	KTR_EVENT0(m, egroup, ident, "state:\"%s\"", state)
#define KTR_STATE1(m, egroup, ident, state, a0, v0)			\
	KTR_EVENT1(m, egroup, ident, "state:\"%s\"", state, a0, (v0))
#define KTR_STATE2(m, egroup, ident, state, a0, v0, a1, v1)		\
	KTR_EVENT2(m, egroup, ident, "state:\"%s\"", state, a0, (v0), a1, (v1))
#define KTR_STATE3(m, egroup, ident, state, a0, v0, a1, v1, a2, v2)	\
	KTR_EVENT3(m, egroup, ident, "state:\"%s\"",			\
	    state, a0, (v0), a1, (v1), a2, (v2))
#define KTR_STATE4(m, egroup, ident, state, a0, v0, a1, v1, a2, v2, a3, v3)\
	KTR_EVENT4(m, egroup, ident, "state:\"%s\"",			\
	    state, a0, (v0), a1, (v1), a2, (v2), a3, (v3))

/*
 * Counter functions graph counter values.  The counter id
 * must not be intermixed with a state id.
 */
#define	KTR_COUNTER0(m, egroup, ident, counter)				\
	KTR_EVENT0(m, egroup, ident, "counter:%d", counter)
#define	KTR_COUNTER1(m, egroup, ident, edat, a0, v0)			\
	KTR_EVENT1(m, egroup, ident, "counter:%d", counter, a0, (v0))
#define	KTR_COUNTER2(m, egroup, ident, counter, a0, v0, a1, v1)		\
	KTR_EVENT2(m, egroup, ident, "counter:%d", counter, a0, (v0), a1, (v1))
#define	KTR_COUNTER3(m, egroup, ident, counter, a0, v0, a1, v1, a2, v2)	\
	KTR_EVENT3(m, egroup, ident, "counter:%d",			\
	    counter, a0, (v0), a1, (v1), a2, (v2))
#define	KTR_COUNTER4(m, egroup, ident, counter, a0, v0, a1, v1, a2, v2, a3, v3)\
	KTR_EVENT4(m, egroup, ident, "counter:%d",			\
	    counter, a0, (v0), a1, (v1), a2, (v2), a3, (v3))

/*
 * Point functions plot points of interest on counter or state graphs.
 */
#define	KTR_POINT0(m, egroup, ident, point)				\
	KTR_EVENT0(m, egroup, ident, "point:\"%s\"", point)
#define	KTR_POINT1(m, egroup, ident, point, a0, v0)			\
	KTR_EVENT1(m, egroup, ident, "point:\"%s\"", point, a0, (v0))
#define	KTR_POINT2(m, egroup, ident, point, a0, v0, a1, v1)		\
	KTR_EVENT2(m, egroup, ident, "point:\"%s\"", point, a0, (v0), a1, (v1))
#define	KTR_POINT3(m, egroup, ident, point, a0, v0, a1, v1, a2, v2)	\
	KTR_EVENT3(m, egroup, ident, "point:\"%s\"", point,		\
	    a0, (v0), a1, (v1), a2, (v2))
#define	KTR_POINT4(m, egroup, ident, point, a0, v0, a1, v1, a2, v2, a3, v3)\
	KTR_EVENT4(m, egroup, ident, "point:\"%s\"",			\
	    point, a0, (v0), a1, (v1), a2, (v2), a3, (v3))

/*
 * Trace initialization events, similar to CTR with KTR_INIT, but
 * completely ifdef'ed out if KTR_INIT isn't in KTR_COMPILE (to
 * save string space, the compiler doesn't optimize out strings
 * for the conditional ones above).
 */
#if (KTR_COMPILE & KTR_INIT) != 0
#define	ITR0(d)				CTR0(KTR_INIT, d)
#define	ITR1(d, p1)			CTR1(KTR_INIT, d, p1)
#define	ITR2(d, p1, p2)			CTR2(KTR_INIT, d, p1, p2)
#define	ITR3(d, p1, p2, p3)		CTR3(KTR_INIT, d, p1, p2, p3)
#define	ITR4(d, p1, p2, p3, p4)		CTR4(KTR_INIT, d, p1, p2, p3, p4)
#define	ITR5(d, p1, p2, p3, p4, p5)	CTR5(KTR_INIT, d, p1, p2, p3, p4, p5)
#define	ITR6(d, p1, p2, p3, p4, p5, p6)	CTR6(KTR_INIT, d, p1, p2, p3, p4, p5, p6)
#else
#define	ITR0(d)
#define	ITR1(d, p1)
#define	ITR2(d, p1, p2)
#define	ITR3(d, p1, p2, p3)
#define	ITR4(d, p1, p2, p3, p4)
#define	ITR5(d, p1, p2, p3, p4, p5)
#define	ITR6(d, p1, p2, p3, p4, p5, p6)
#endif

#endif /* !LOCORE */

#endif /* !_SYS_KTR_H_ */


code:
/*-
 * Copyright (c) 1988, 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.
 *
 *	@(#)ktrace.h	8.1 (Berkeley) 6/2/93
 * $FreeBSD: release/9.0.0/sys/sys/ktrace.h 219042 2011-02-25 22:05:33Z dchagin $
 */

#ifndef _SYS_KTRACE_H_
#define _SYS_KTRACE_H_

/*
 * operations to ktrace system call  (KTROP(op))
 */
#define KTROP_SET		0	/* set trace points */
#define KTROP_CLEAR		1	/* clear trace points */
#define KTROP_CLEARFILE		2	/* stop all tracing to file */
#define	KTROP(o)		((o)&3)	/* macro to extract operation */
/*
 * flags (ORed in with operation)
 */
#define KTRFLAG_DESCEND		4	/* perform op on all children too */

/*
 * ktrace record header
 */
struct ktr_header {
	int	ktr_len;		/* length of buf */
	short	ktr_type;		/* trace record type */
	pid_t	ktr_pid;		/* process id */
	char	ktr_comm[MAXCOMLEN + 1];/* command name */
	struct	timeval ktr_time;	/* timestamp */
	intptr_t	ktr_tid;	/* was ktr_buffer */
};

/*
 * Test for kernel trace point (MP SAFE).
 *
 * KTRCHECK() just checks that the type is enabled and is only for
 * internal use in the ktrace subsystem.  KTRPOINT() checks against
 * ktrace recursion as well as checking that the type is enabled and
 * is the public interface.
 */
#define	KTRCHECK(td, type)	((td)->td_proc->p_traceflag & (1 << type))
#define KTRPOINT(td, type)						\
	(KTRCHECK((td), (type)) && !((td)->td_pflags & TDP_INKTRACE))
#define	KTRCHECKDRAIN(td)	(!(STAILQ_EMPTY(&(td)->td_proc->p_ktr)))
#define	KTRUSERRET(td) do {						\
	if (KTRCHECKDRAIN(td))						\
		ktruserret(td);						\
} while (0)

/*
 * ktrace record types
 */

/*
 * KTR_SYSCALL - system call record
 */
#define KTR_SYSCALL	1
struct ktr_syscall {
	short	ktr_code;		/* syscall number */
	short	ktr_narg;		/* number of arguments */
	/*
	 * followed by ktr_narg register_t
	 */
	register_t	ktr_args[1];
};

/*
 * KTR_SYSRET - return from system call record
 */
#define KTR_SYSRET	2
struct ktr_sysret {
	short	ktr_code;
	short	ktr_eosys;
	int	ktr_error;
	register_t	ktr_retval;
};

/*
 * KTR_NAMEI - namei record
 */
#define KTR_NAMEI	3
	/* record contains pathname */

/*
 * KTR_GENIO - trace generic process i/o
 */
#define KTR_GENIO	4
struct ktr_genio {
	int	ktr_fd;
	enum	uio_rw ktr_rw;
	/*
	 * followed by data successfully read/written
	 */
};

/*
 * KTR_PSIG - trace processed signal
 */
#define	KTR_PSIG	5
struct ktr_psig {
	int	signo;
	sig_t	action;
	int	code;
	sigset_t mask;
};

/*
 * KTR_CSW - trace context switches
 */
#define KTR_CSW		6
struct ktr_csw {
	int	out;	/* 1 if switch out, 0 if switch in */
	int	user;	/* 1 if usermode (ivcsw), 0 if kernel (vcsw) */
};

/*
 * KTR_USER - data coming from userland
 */
#define KTR_USER_MAXLEN	2048	/* maximum length of passed data */
#define KTR_USER	7

/*
 * KTR_STRUCT - misc. structs
 */
#define KTR_STRUCT	8
	/*
	 * record contains null-terminated struct name followed by
	 * struct contents
	 */
struct sockaddr;
struct stat;
struct sysentvec;

/*
 * KTR_SYSCTL - name of a sysctl MIB
 */
#define	KTR_SYSCTL	9
	/* record contains null-terminated MIB name */

/*
 * KTR_PROCCTOR - trace process creation (multiple ABI support)
 */
#define KTR_PROCCTOR	10
struct ktr_proc_ctor {
	u_int	sv_flags;	/* struct sysentvec sv_flags copy */
};

/*
 * KTR_PROCDTOR - trace process destruction (multiple ABI support)
 */
#define KTR_PROCDTOR	11

/*
 * KTR_DROP - If this bit is set in ktr_type, then at least one event
 * between the previous record and this record was dropped.
 */
#define	KTR_DROP	0x8000

/*
 * kernel trace points (in p_traceflag)
 */
#define KTRFAC_MASK	0x00ffffff
#define KTRFAC_SYSCALL	(1<<KTR_SYSCALL)
#define KTRFAC_SYSRET	(1<<KTR_SYSRET)
#define KTRFAC_NAMEI	(1<<KTR_NAMEI)
#define KTRFAC_GENIO	(1<<KTR_GENIO)
#define	KTRFAC_PSIG	(1<<KTR_PSIG)
#define KTRFAC_CSW	(1<<KTR_CSW)
#define KTRFAC_USER	(1<<KTR_USER)
#define KTRFAC_STRUCT	(1<<KTR_STRUCT)
#define KTRFAC_SYSCTL	(1<<KTR_SYSCTL)
#define KTRFAC_PROCCTOR	(1<<KTR_PROCCTOR)
#define KTRFAC_PROCDTOR	(1<<KTR_PROCDTOR)

/*
 * trace flags (also in p_traceflags)
 */
#define KTRFAC_ROOT	0x80000000	/* root set this trace */
#define KTRFAC_INHERIT	0x40000000	/* pass trace flags to children */
#define	KTRFAC_DROP	0x20000000	/* last event was dropped */

#ifdef	_KERNEL
void	ktrnamei(char *);
void	ktrcsw(int, int);
void	ktrpsig(int, sig_t, sigset_t *, int);
void	ktrgenio(int, enum uio_rw, struct uio *, int);
void	ktrsyscall(int, int narg, register_t args[]);
void	ktrsysctl(int *name, u_int namelen);
void	ktrsysret(int, int, register_t);
void	ktrprocctor(struct proc *);
void	ktrprocexec(struct proc *, struct ucred **, struct vnode **);
void	ktrprocexit(struct thread *);
void	ktrprocfork(struct proc *, struct proc *);
void	ktruserret(struct thread *);
void	ktrstruct(const char *, void *, size_t);
#define ktrsockaddr(s) \
	ktrstruct("sockaddr", (s), ((struct sockaddr *)(s))->sa_len)
#define ktrstat(s) \
	ktrstruct("stat", (s), sizeof(struct stat))

#else

#include <sys/cdefs.h>

__BEGIN_DECLS
int	ktrace(const char *, int, int, pid_t);
int	utrace(const void *, size_t);
__END_DECLS

#endif

#endif


code:
/*-
 * Copyright (c) 1992, 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.
 *
 *	@(#)libkern.h	8.1 (Berkeley) 6/10/93
 * $FreeBSD: release/9.0.0/sys/sys/libkern.h 226229 2011-10-10 19:07:55Z jkim $
 */

#ifndef _SYS_LIBKERN_H_
#define	_SYS_LIBKERN_H_

#include <sys/cdefs.h>
#include <sys/types.h>
#ifdef _KERNEL
#include <sys/systm.h>
#endif

#ifndef	LIBKERN_INLINE
#define	LIBKERN_INLINE  static __inline
#define	LIBKERN_BODY
#endif

/* BCD conversions. */
extern u_char const	bcd2bin_data[];
extern u_char const	bin2bcd_data[];
extern char const	hex2ascii_data[];

#define	bcd2bin(bcd)	(bcd2bin_data[bcd])
#define	bin2bcd(bin)	(bin2bcd_data[bin])
#define	hex2ascii(hex)	(hex2ascii_data[hex])

static __inline int imax(int a, int b) { return (a > b ? a : b); }
static __inline int imin(int a, int b) { return (a < b ? a : b); }
static __inline long lmax(long a, long b) { return (a > b ? a : b); }
static __inline long lmin(long a, long b) { return (a < b ? a : b); }
static __inline u_int max(u_int a, u_int b) { return (a > b ? a : b); }
static __inline u_int min(u_int a, u_int b) { return (a < b ? a : b); }
static __inline quad_t qmax(quad_t a, quad_t b) { return (a > b ? a : b); }
static __inline quad_t qmin(quad_t a, quad_t b) { return (a < b ? a : b); }
static __inline u_long ulmax(u_long a, u_long b) { return (a > b ? a : b); }
static __inline u_long ulmin(u_long a, u_long b) { return (a < b ? a : b); }
static __inline off_t omax(off_t a, off_t b) { return (a > b ? a : b); }
static __inline off_t omin(off_t a, off_t b) { return (a < b ? a : b); }

static __inline int abs(int a) { return (a < 0 ? -a : a); }
static __inline long labs(long a) { return (a < 0 ? -a : a); }
static __inline quad_t qabs(quad_t a) { return (a < 0 ? -a : a); }

/* Prototypes for non-quad routines. */
struct malloc_type;
uint32_t arc4random(void);
void	 arc4rand(void *ptr, u_int len, int reseed);
int	 bcmp(const void *, const void *, size_t);
void	*bsearch(const void *, const void *, size_t,
	    size_t, int (*)(const void *, const void *));
#ifndef	HAVE_INLINE_FFS
int	 ffs(int);
#endif
#ifndef	HAVE_INLINE_FFSL
int	 ffsl(long);
#endif
#ifndef	HAVE_INLINE_FLS
int	 fls(int);
#endif
#ifndef	HAVE_INLINE_FLSL
int	 flsl(long);
#endif
int	 fnmatch(const char *, const char *, int);
void	 gets(char *, size_t, int);
int	 locc(int, char *, u_int);
void	*memchr(const void *s, int c, size_t n);
int	 memcmp(const void *b1, const void *b2, size_t len);
void	 qsort(void *base, size_t nmemb, size_t size,
	    int (*compar)(const void *, const void *));
void	 qsort_r(void *base, size_t nmemb, size_t size, void *thunk,
	    int (*compar)(void *, const void *, const void *));
u_long	 random(void);
char	*index(const char *, int);
char	*rindex(const char *, int);
int	 scanc(u_int, const u_char *, const u_char *, int);
int	 skpc(int, int, char *);
void	 srandom(u_long);
int	 strcasecmp(const char *, const char *);
char	*strcat(char * __restrict, const char * __restrict);
int	 strcmp(const char *, const char *);
char	*strcpy(char * __restrict, const char * __restrict);
size_t	 strcspn(const char * __restrict, const char * __restrict) __pure;
char	*strdup(const char *__restrict, struct malloc_type *);
size_t	 strlcat(char *, const char *, size_t);
size_t	 strlcpy(char *, const char *, size_t);
size_t	 strlen(const char *);
int	 strncasecmp(const char *, const char *, size_t);
int	 strncmp(const char *, const char *, size_t);
char	*strncpy(char * __restrict, const char * __restrict, size_t);
size_t	 strnlen(const char *, size_t);
char	*strsep(char **, const char *delim);
size_t	 strspn(const char *, const char *);
char	*strstr(const char *, const char *);
int	 strvalid(const char *, size_t);

extern uint32_t crc32_tab[];

static __inline uint32_t
crc32_raw(const void *buf, size_t size, uint32_t crc)
{
	const uint8_t *p = (const uint8_t *)buf;

	while (size--)
		crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
	return (crc);
}

static __inline uint32_t
crc32(const void *buf, size_t size)
{
	uint32_t crc;

	crc = crc32_raw(buf, size, ~0U);
	return (crc ^ ~0U);
}

uint32_t
calculate_crc32c(uint32_t crc32c, const unsigned char *buffer,
        unsigned int length);

//LIBKERN_INLINE void *memset(void *, int, size_t);
//#ifdef LIBKERN_BODY
//LIBKERN_INLINE void *
//memset(void *b, int c, size_t len)
//{
//	char *bb;
//
//	if (c == 0)
//		bzero(b, len);
//	else
//		for (bb = (char *)b; len--; )
//			*bb++ = c;
//	return (b);
//}
//#endif

static __inline char *
strchr(const char *p, int ch)
{
	return (index(p, ch));
}

static __inline char *
strrchr(const char *p, int ch)
{
	return (rindex(p, ch));
}

/* fnmatch() return values. */
#define	FNM_NOMATCH	1	/* Match failed. */

/* fnmatch() flags. */
#define	FNM_NOESCAPE	0x01	/* Disable backslash escaping. */
#define	FNM_PATHNAME	0x02	/* Slash must be matched by slash. */
#define	FNM_PERIOD	0x04	/* Period must be matched by period. */
#define	FNM_LEADING_DIR	0x08	/* Ignore /<tail> after Imatch. */
#define	FNM_CASEFOLD	0x10	/* Case insensitive search. */
#define	FNM_IGNORECASE	FNM_CASEFOLD
#define	FNM_FILE_NAME	FNM_PATHNAME

/* Visibility of characters in gets() */
#define	GETS_NOECHO	0	/* Disable echoing of characters. */
#define	GETS_ECHO	1	/* Enable echoing of characters. */
#define	GETS_ECHOPASS	2	/* Print a * for every character. */

#endif /* !_SYS_LIBKERN_H_ */


code:
/*-
 * Copyright (c) 1988, 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.
 *
 * $FreeBSD: release/9.0.0/sys/sys/limits.h 219271 2011-03-04 19:28:27Z jilles $
 */

#ifndef _SYS_LIMITS_H_
#define	_SYS_LIMITS_H_

#include <sys/cdefs.h>
#include <machine/_limits.h>

#define	CHAR_BIT	__CHAR_BIT	/* number of bits in a char */

#define	SCHAR_MAX	__SCHAR_MAX	/* max value for a signed char */
#define	SCHAR_MIN	__SCHAR_MIN	/* min value for a signed char */

#define	UCHAR_MAX	__UCHAR_MAX	/* max value for an unsigned char */

#ifdef __CHAR_UNSIGNED__
#define	CHAR_MAX	UCHAR_MAX	/* max value for a char */
#define	CHAR_MIN	0		/* min value for a char */
#else
#define	CHAR_MAX	SCHAR_MAX
#define	CHAR_MIN	SCHAR_MIN
#endif

#define	USHRT_MAX	__USHRT_MAX	/* max value for an unsigned short */
#define	SHRT_MAX	__SHRT_MAX	/* max value for a short */
#define	SHRT_MIN	__SHRT_MIN	/* min value for a short */

#define	UINT_MAX	__UINT_MAX	/* max value for an unsigned int */
#define	INT_MAX		__INT_MAX	/* max value for an int */
#define	INT_MIN		__INT_MIN	/* min value for an int */

#define	ULONG_MAX	__ULONG_MAX	/* max for an unsigned long */
#define	LONG_MAX	__LONG_MAX	/* max for a long */
#define	LONG_MIN	__LONG_MIN	/* min for a long */

#ifdef __LONG_LONG_SUPPORTED
#define	ULLONG_MAX	__ULLONG_MAX	/* max for an unsigned long long */
#define	LLONG_MAX	__LLONG_MAX	/* max for a long long */
#define	LLONG_MIN	__LLONG_MIN	/* min for a long long */
#endif

#if __POSIX_VISIBLE || __XSI_VISIBLE
#define	SSIZE_MAX	__SSIZE_MAX	/* max value for an ssize_t */
#endif

#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE
#define	SIZE_T_MAX	__SIZE_T_MAX	/* max value for a size_t */

#define	OFF_MAX		__OFF_MAX	/* max value for an off_t */
#define	OFF_MIN		__OFF_MIN	/* min value for an off_t */
#endif

#if __BSD_VISIBLE
#define	GID_MAX		UINT_MAX	/* max value for a gid_t */
#define	UID_MAX		UINT_MAX	/* max value for a uid_t */

#define	UQUAD_MAX	(__UQUAD_MAX)	/* max value for a uquad_t */
#define	QUAD_MAX	(__QUAD_MAX)	/* max value for a quad_t */
#define	QUAD_MIN	(__QUAD_MIN)	/* min value for a quad_t */
#endif

#if __XSI_VISIBLE || __POSIX_VISIBLE >= 200809
#define	LONG_BIT	__LONG_BIT
#define	WORD_BIT	__WORD_BIT
#endif

#if __POSIX_VISIBLE
#define	MQ_PRIO_MAX	64
#endif

#endif /* !_SYS_LIMITS_H_ */


code:
/*-
 * Copyright (c) 1993 Paul Kranenburg
 * 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.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Paul Kranenburg.
 * 4. 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 ``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 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/link_aout.h 139825 2005-01-07 02:29:27Z imp $
 */

/*
 * RRS section definitions.
 *
 * The layout of some data structures defined in this header file is
 * such that we can provide compatibility with the SunOS 4.x shared
 * library scheme.
 */

#ifndef _SYS_LINK_AOUT_H_
#define _SYS_LINK_AOUT_H_

struct dl_info;

/*
 * A `Shared Object Descriptor' describes a shared object that is needed
 * to complete the link edit process of the object containing it.
 * A list of such objects (chained through `sod_next') is pointed at
 * by `sdt_sods' in the section_dispatch_table structure.
 */

struct sod {	/* Shared Object Descriptor */
	long	sod_name;		/* name (relative to load address) */
	u_int	sod_library  : 1,	/* Searched for by library rules */
		sod_reserved : 31;
	short	sod_major;		/* major version number */
	short	sod_minor;		/* minor version number */
	long	sod_next;		/* next sod */
};

/*
 * `Shared Object Map's are used by the run-time link editor (ld.so) to
 * keep track of all shared objects loaded into a process' address space.
 * These structures are only used at run-time and do not occur within
 * the text or data segment of an executable or shared library.
 */
struct so_map {		/* Shared Object Map */
	caddr_t		som_addr;	/* Address at which object mapped */
	char 		*som_path;	/* Path to mmap'ed file */
	struct so_map	*som_next;	/* Next map in chain */
	struct sod	*som_sod;	/* Sod responsible for this map */
	caddr_t		som_sodbase;	/* Base address of this sod */
	u_int		som_write : 1;	/* Text is currently writable */
	struct _dynamic	*som_dynamic;	/* _dynamic structure */
	caddr_t		som_spd;	/* Private data */
};

/*
 * Symbol description with size. This is simply an `nlist' with
 * one field (nz_size) added.
 * Used to convey size information on items in the data segment
 * of shared objects. An array of these live in the shared object's
 * text segment and is addressed by the `sdt_nzlist' field.
 */
struct nzlist {
	struct nlist	nlist;
	u_long		nz_size;
};

#define nz_un		nlist.n_un
#define nz_strx		nlist.n_un.n_strx
#define nz_name		nlist.n_un.n_name
#define nz_type		nlist.n_type
#define nz_value	nlist.n_value
#define nz_desc		nlist.n_desc
#define nz_other	nlist.n_other

/*
 * The `section_dispatch_table' structure contains offsets to various data
 * structures needed to do run-time relocation.
 */
struct section_dispatch_table {
	struct so_map *sdt_loaded;	/* List of loaded objects */
	long	sdt_sods;		/* List of shared objects descriptors */
	long	sdt_paths;		/* Library search paths */
	long	sdt_got;		/* Global offset table */
	long	sdt_plt;		/* Procedure linkage table */
	long	sdt_rel;		/* Relocation table */
	long	sdt_hash;		/* Symbol hash table */
	long	sdt_nzlist;		/* Symbol table itself */
	long	sdt_filler2;		/* Unused (was: stab_hash) */
	long	sdt_buckets;		/* Number of hash buckets */
	long	sdt_strings;		/* Symbol strings */
	long	sdt_str_sz;		/* Size of symbol strings */
	long	sdt_text_sz;		/* Size of text area */
	long	sdt_plt_sz;		/* Size of procedure linkage table */
};

/*
 * RRS symbol hash table, addressed by `sdt_hash' in section_dispatch_table.
 * Used to quickly lookup symbols of the shared object by hashing
 * on the symbol's name. `rh_symbolnum' is the index of the symbol
 * in the shared object's symbol list (`sdt_nzlist'), `rh_next' is
 * the next symbol in the hash bucket (in case of collisions).
 */
struct rrs_hash {
	int	rh_symbolnum;		/* Symbol number */
	int	rh_next;		/* Next hash entry */
};

/*
 * `rt_symbols' is used to keep track of run-time allocated commons
 * and data items copied from shared objects.
 */
struct rt_symbol {
	struct nzlist		*rt_sp;		/* The symbol */
	struct rt_symbol	*rt_next;	/* Next in linear list */
	struct rt_symbol	*rt_link;	/* Next in bucket */
	caddr_t			rt_srcaddr;	/* Address of "master" copy */
	struct so_map		*rt_smp;	/* Originating map */
};

/*
 * Debugger interface structure.
 */
struct so_debug {
	int	dd_version;		/* Version # of interface */
	int	dd_in_debugger;		/* Set when run by debugger */
	int	dd_sym_loaded;		/* Run-time linking brought more
					   symbols into scope */
	char   	 *dd_bpt_addr;		/* Address of rtld-generated bpt */
	int	dd_bpt_shadow;		/* Original contents of bpt */
	struct rt_symbol *dd_cc;	/* Allocated commons/copied data */
};

/*
 * Version returned to crt0 from ld.so
 */
#define LDSO_VERSION_NONE	0	/* FreeBSD2.0, 2.0.5 */
#define LDSO_VERSION_HAS_DLEXIT	1	/* includes dlexit in ld_entry */
#define LDSO_VERSION_HAS_DLSYM3	2	/* includes 3-argument dlsym */
#define LDSO_VERSION_HAS_DLADDR	3	/* includes dladdr in ld_entry */

/*
 * Entry points into ld.so - user interface to the run-time linker.
 * Entries are valid for the given version numbers returned by ld.so
 * to crt0.
 */
struct ld_entry {
	void	*(*dlopen)(const char *, int);	/* NONE */
	int	(*dlclose)(void *);		/* NONE */
	void	*(*dlsym)(void *, const char *);	/* NONE */
	const char *(*dlerror)(void);		/* NONE */
	void	(*dlexit)(void);			/* HAS_DLEXIT */
	void	*(*dlsym3)(void *, const char *, void *); /* HAS_DLSYM3 */
	int	 (*dladdr)(const void *, struct dl_info *); /* HAS_DLADDR */
};

/*
 * This is the structure pointed at by the __DYNAMIC symbol if an
 * executable requires the attention of the run-time link editor.
 * __DYNAMIC is given the value zero if no run-time linking needs to
 * be done (it is always present in shared objects).
 * The union `d_un' provides for different versions of the dynamic
 * linking mechanism (switched on by `d_version'). The last version
 * used by Sun is 3. We leave some room here and go to version number
 * 8 for NetBSD, the main difference lying in the support for the
 * `nz_list' type of symbols.
 */

struct _dynamic {
	int		d_version;	/* version # of this interface */
	struct so_debug	*d_debug;
	union {
		struct section_dispatch_table *d_sdt;
	} d_un;
	struct ld_entry *d_entry;	/* XXX */
};

#define LD_VERSION_SUN		(3)
#define LD_VERSION_BSD		(8)
#define LD_VERSION_NZLIST_P(v)	((v) >= 8)

#define LD_GOT(x)	((x)->d_un.d_sdt->sdt_got)
#define LD_PLT(x)	((x)->d_un.d_sdt->sdt_plt)
#define LD_REL(x)	((x)->d_un.d_sdt->sdt_rel)
#define LD_SYMBOL(x)	((x)->d_un.d_sdt->sdt_nzlist)
#define LD_HASH(x)	((x)->d_un.d_sdt->sdt_hash)
#define LD_STRINGS(x)	((x)->d_un.d_sdt->sdt_strings)
#define LD_NEED(x)	((x)->d_un.d_sdt->sdt_sods)
#define LD_BUCKETS(x)	((x)->d_un.d_sdt->sdt_buckets)
#define LD_PATHS(x)	((x)->d_un.d_sdt->sdt_paths)

#define LD_GOTSZ(x)	((x)->d_un.d_sdt->sdt_plt - (x)->d_un.d_sdt->sdt_got)
#define LD_RELSZ(x)	((x)->d_un.d_sdt->sdt_hash - (x)->d_un.d_sdt->sdt_rel)
#define LD_HASHSZ(x)	((x)->d_un.d_sdt->sdt_nzlist - (x)->d_un.d_sdt->sdt_hash)
#define LD_STABSZ(x)	((x)->d_un.d_sdt->sdt_strings - (x)->d_un.d_sdt->sdt_nzlist)
#define LD_PLTSZ(x)	((x)->d_un.d_sdt->sdt_plt_sz)
#define LD_STRSZ(x)	((x)->d_un.d_sdt->sdt_str_sz)
#define LD_TEXTSZ(x)	((x)->d_un.d_sdt->sdt_text_sz)

/*
 * Interface to ld.so
 */
struct crt_ldso {
	int		crt_ba;		/* Base address of ld.so */
	int		crt_dzfd;	/* "/dev/zero" file descriptor (SunOS) */
	int		crt_ldfd;	/* ld.so file descriptor */
	struct _dynamic	*crt_dp;	/* Main's __DYNAMIC */
	char		**crt_ep;	/* environment strings */
	caddr_t		crt_bp;		/* Breakpoint if run from debugger */
	char		*crt_prog;	/* Program name (v3) */
	char		*crt_ldso;	/* Link editor name (v4) */
	struct ld_entry	*crt_ldentry;	/* dl*() access (v4) */
	char		**crt_argv;	/* argument strings (v5) */
};

/*
 * Version passed from crt0 to ld.so (1st argument to _rtld()).
 */
#define CRT_VERSION_SUN		1
#define CRT_VERSION_BSD_2	2
#define CRT_VERSION_BSD_3	3
#define CRT_VERSION_BSD_4	4
#define CRT_VERSION_BSD_5	5

/*
 * Maximum number of recognized shared object version numbers.
 */
#define MAXDEWEY	8

/*
 * Header of the hints file.
 */
struct hints_header {
	long		hh_magic;
#define HH_MAGIC	011421044151
	long		hh_version;	/* Interface version number */
#define LD_HINTS_VERSION_1	1
#define LD_HINTS_VERSION_2	2
	long		hh_hashtab;	/* Location of hash table */
	long		hh_nbucket;	/* Number of buckets in hashtab */
	long		hh_strtab;	/* Location of strings */
	long		hh_strtab_sz;	/* Size of strings */
	long		hh_ehints;	/* End of hints (max offset in file) */
	long		hh_dirlist;	/* Colon-separated list of srch dirs */
};

#define HH_BADMAG(hdr)	((hdr).hh_magic != HH_MAGIC)

/*
 * Hash table element in hints file.
 */
struct hints_bucket {
	/* namex and pathx are indices into the string table */
	int		hi_namex;		/* Library name */
	int		hi_pathx;		/* Full path */
	int		hi_dewey[MAXDEWEY];	/* The versions */
	int		hi_ndewey;		/* Number of version numbers */
#define hi_major hi_dewey[0]
#define hi_minor hi_dewey[1]
	int		hi_next;		/* Next in this bucket */
};

#define _PATH_LD_HINTS		"/var/run/ld.so.hints"

#endif /* _SYS_LINK_AOUT_H_ */


code:
/*-
 * Copyright (c) 1993 Paul Kranenburg
 * 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.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Paul Kranenburg.
 * 4. 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 ``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 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/link_elf.h 217153 2011-01-08 17:11:49Z kib $
 */

/*
 * RRS section definitions.
 *
 * The layout of some data structures defined in this header file is
 * such that we can provide compatibility with the SunOS 4.x shared
 * library scheme.
 */

#ifndef _SYS_LINK_ELF_H_
#define	_SYS_LINK_ELF_H_

#include <sys/elf.h>

/*
 * Flags that describe the origin of the entries in Dl_serinfo.
 * SunOS has these in <sys/link.h>, we follow the suit.
 */
#define	LA_SER_ORIG	0x01	/* original (needed) name */
#define	LA_SER_LIBPATH	0x02	/* LD_LIBRARY_PATH entry prepended */
#define	LA_SER_RUNPATH	0x04	/* runpath entry prepended */
#define	LA_SER_CONFIG	0x08	/* configuration entry prepended */
#define	LA_SER_DEFAULT	0x40	/* default path prepended */
#define	LA_SER_SECURE	0x80	/* default (secure) path prepended */

typedef struct link_map {
	caddr_t		l_addr;			/* Base Address of library */
#ifdef __mips__
	caddr_t		l_offs;			/* Load Offset of library */
#endif
	const char	*l_name;		/* Absolute Path to Library */
	const void	*l_ld;			/* Pointer to .dynamic in memory */
	struct link_map	*l_next, *l_prev;	/* linked list of of mapped libs */
} Link_map;

struct r_debug {
	int		r_version;		/* not used */
	struct link_map *r_map;			/* list of loaded images */
	void		(*r_brk)(struct r_debug *, struct link_map *);
						/* pointer to break point */
	enum {
		RT_CONSISTENT,			/* things are stable */
		RT_ADD,				/* adding a shared library */
		RT_DELETE			/* removing a shared library */
	}		r_state;
};

struct dl_phdr_info
{
	Elf_Addr dlpi_addr;			/* module relocation base */
	const char *dlpi_name;			/* module name */
	const Elf_Phdr *dlpi_phdr;		/* pointer to module's phdr */
	Elf_Half dlpi_phnum;			/* number of entries in phdr */
	unsigned long long int dlpi_adds;	/* total # of loads */
	unsigned long long int dlpi_subs;	/* total # of unloads */
	size_t dlpi_tls_modid;
	void *dlpi_tls_data;
};

__BEGIN_DECLS

typedef int (*__dl_iterate_hdr_callback)(struct dl_phdr_info *, size_t, void *);
extern int dl_iterate_phdr(__dl_iterate_hdr_callback, void *);
int _rtld_addr_phdr(const void *, struct dl_phdr_info *);
int _rtld_get_stack_prot(void);

__END_DECLS

#endif /* _SYS_LINK_ELF_H_ */


code:
/*-
 * Copyright (c) 1997-2000 Doug Rabson
 * 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/linker.h 218494 2011-02-09 19:08:21Z marcel $
 */

#ifndef _SYS_LINKER_H_
#define _SYS_LINKER_H_

#ifdef _KERNEL

#include <machine/elf.h>
#include <sys/kobj.h>

#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_LINKER);
#endif

struct mod_depend;

/*
 * Object representing a file which has been loaded by the linker.
 */
typedef struct linker_file* linker_file_t;
typedef TAILQ_HEAD(, linker_file) linker_file_list_t;

typedef caddr_t linker_sym_t;		/* opaque symbol */
typedef c_caddr_t c_linker_sym_t;	/* const opaque symbol */
typedef int (*linker_function_name_callback_t)(const char *, void *);

/*
 * expanded out linker_sym_t
 */
typedef struct linker_symval {
    const char*		name;
    caddr_t		value;
    size_t		size;
} linker_symval_t;

typedef int (*linker_function_nameval_callback_t)(linker_file_t, int, linker_symval_t *, void *);

struct common_symbol {
    STAILQ_ENTRY(common_symbol) link;
    char*		name;
    caddr_t		address;
};

struct linker_file {
    KOBJ_FIELDS;
    int			refs;		/* reference count */
    int			userrefs;	/* kldload(2) count */
    int			flags;
#define LINKER_FILE_LINKED	0x1	/* file has been fully linked */
    TAILQ_ENTRY(linker_file) link;	/* list of all loaded files */
    char*		filename;	/* file which was loaded */
    char*		pathname;	/* file name with full path */
    int			id;		/* unique id */
    caddr_t		address;	/* load address */
    size_t		size;		/* size of file */
    int			ndeps;		/* number of dependencies */
    linker_file_t*	deps;		/* list of dependencies */
    STAILQ_HEAD(, common_symbol) common; /* list of common symbols */
    TAILQ_HEAD(, module) modules;	/* modules in this file */
    TAILQ_ENTRY(linker_file) loaded;	/* preload dependency support */
    int			loadcnt;	/* load counter value */

    /*
     * Function Boundary Tracing (FBT) or Statically Defined Tracing (SDT)
     * fields.
     */
    int			nenabled;	/* number of enabled probes. */
    int			fbt_nentries;	/* number of fbt entries created. */
    void		*sdt_probes;
    int			sdt_nentries;
    size_t		sdt_nprobes;
    size_t		sdt_size;
};

/*
 * Object implementing a class of file (a.out, elf, etc.)
 */
typedef struct linker_class *linker_class_t;
typedef TAILQ_HEAD(, linker_class) linker_class_list_t;

struct linker_class {
    KOBJ_CLASS_FIELDS;
    TAILQ_ENTRY(linker_class) link;	/* list of all file classes */
};

/*
 * Function type used when iterating over the list of linker files.
 */
typedef int linker_predicate_t(linker_file_t, void *);

/*
 * The "file" for the kernel.
 */
extern linker_file_t	linker_kernel_file;

/*
 * Obtain a reference to a module, loading it if required.
 */
int linker_reference_module(const char* _modname, struct mod_depend *_verinfo,
			    linker_file_t* _result);

/*
 * Release a reference to a module, unloading it if there are no more
 * references.  Note that one should either provide a module name and
 * optional version info or a linker file, but not both.
 */
int linker_release_module(const char *_modname, struct mod_depend *_verinfo,
			  linker_file_t _file);

/*
 * Iterate over all of the currently loaded linker files calling the
 * predicate function while the function returns 0.  Returns the value
 * returned by the last predicate function.
 */
int linker_file_foreach(linker_predicate_t *_predicate, void *_context);

/*
 * Lookup a symbol in a file.  If deps is TRUE, look in dependencies
 * if not found in file.
 */
caddr_t linker_file_lookup_symbol(linker_file_t _file, const char* _name,
				  int _deps);

/*
 * Lookup a linker set in a file.  Return pointers to the first entry,
 * last + 1, and count of entries.  Use: for (p = start; p < stop; p++) {}
 * void *start is really: "struct yoursetmember ***start;"
 */
int linker_file_lookup_set(linker_file_t _file, const char *_name,
			   void *_start, void *_stop, int *_count);

/*
 * List all functions in a file.
 */
int linker_file_function_listall(linker_file_t,
				 linker_function_nameval_callback_t, void *);

/*
 * Functions soley for use by the linker class handlers.
 */
int linker_add_class(linker_class_t _cls);
int linker_file_unload(linker_file_t _file, int flags);
int linker_load_dependencies(linker_file_t _lf);
linker_file_t linker_make_file(const char* _filename, linker_class_t _cls);

/*
 * DDB Helpers, tuned specifically for ddb/db_kld.c
 */
int linker_ddb_lookup(const char *_symstr, c_linker_sym_t *_sym);
int linker_ddb_search_symbol(caddr_t _value, c_linker_sym_t *_sym,
			     long *_diffp);
int linker_ddb_symbol_values(c_linker_sym_t _sym, linker_symval_t *_symval);
int linker_ddb_search_symbol_name(caddr_t value, char *buf, u_int buflen,
				  long *offset);

/*
 * stack(9) helper for situations where kernel locking is required.
 */
int linker_search_symbol_name(caddr_t value, char *buf, u_int buflen,
    long *offset);

/* HWPMC helper */
void *linker_hwpmc_list_objects(void);

#endif	/* _KERNEL */

/*
 * Module information subtypes
 */
#define MODINFO_END		0x0000		/* End of list */
#define MODINFO_NAME		0x0001		/* Name of module (string) */
#define MODINFO_TYPE		0x0002		/* Type of module (string) */
#define MODINFO_ADDR		0x0003		/* Loaded address */
#define MODINFO_SIZE		0x0004		/* Size of module */
#define MODINFO_EMPTY		0x0005		/* Has been deleted */
#define MODINFO_ARGS		0x0006		/* Parameters string */
#define MODINFO_METADATA	0x8000		/* Module-specfic */

#define MODINFOMD_AOUTEXEC	0x0001		/* a.out exec header */
#define MODINFOMD_ELFHDR	0x0002		/* ELF header */
#define MODINFOMD_SSYM		0x0003		/* start of symbols */
#define MODINFOMD_ESYM		0x0004		/* end of symbols */
#define MODINFOMD_DYNAMIC	0x0005		/* _DYNAMIC pointer */
/* These values are MD on these two platforms */
#if !defined(__sparc64__) && !defined(__powerpc__)
#define MODINFOMD_ENVP		0x0006		/* envp[] */
#define MODINFOMD_HOWTO		0x0007		/* boothowto */
#define MODINFOMD_KERNEND	0x0008		/* kernend */
#endif
#define MODINFOMD_SHDR		0x0009		/* section header table */
#define MODINFOMD_NOCOPY	0x8000		/* don't copy this metadata to the kernel */

#define MODINFOMD_DEPLIST	(0x4001 | MODINFOMD_NOCOPY)	/* depends on */

#ifdef _KERNEL
#define MD_FETCH(mdp, info, type) ({ \
	type *__p; \
	__p = (type *)preload_search_info((mdp), MODINFO_METADATA | (info)); \
	__p ? *__p : 0; \
})
#endif

#define	LINKER_HINTS_VERSION	1		/* linker.hints file version */

#ifdef _KERNEL

/*
 * Module lookup
 */
extern vm_offset_t	preload_addr_relocate;
extern caddr_t		preload_metadata;

extern void *		preload_fetch_addr(caddr_t _mod);
extern size_t		preload_fetch_size(caddr_t _mod);
extern caddr_t		preload_search_by_name(const char *_name);
extern caddr_t		preload_search_by_type(const char *_type);
extern caddr_t		preload_search_next_name(caddr_t _base);
extern caddr_t		preload_search_info(caddr_t _mod, int _inf);
extern void		preload_delete_name(const char *_name);
extern void		preload_bootstrap_relocate(vm_offset_t _offset);

#ifdef KLD_DEBUG

extern int kld_debug;
#define KLD_DEBUG_FILE	1	/* file load/unload */
#define KLD_DEBUG_SYM	2	/* symbol lookup */

#define KLD_DPF(cat, args)					\
	do {							\
		if (kld_debug & KLD_DEBUG_##cat) printf args;	\
	} while (0)

#else

#define KLD_DPF(cat, args)

#endif

typedef Elf_Addr elf_lookup_fn(linker_file_t, Elf_Size, int);

/* Support functions */
int	elf_reloc(linker_file_t _lf, Elf_Addr base, const void *_rel, int _type, elf_lookup_fn _lu);
int	elf_reloc_local(linker_file_t _lf, Elf_Addr base, const void *_rel, int _type, elf_lookup_fn _lu);
Elf_Addr elf_relocaddr(linker_file_t _lf, Elf_Addr addr);
const Elf_Sym *elf_get_sym(linker_file_t _lf, Elf_Size _symidx);
const char *elf_get_symname(linker_file_t _lf, Elf_Size _symidx);

typedef struct linker_ctf {
	const uint8_t 	*ctftab;	/* Decompressed CTF data. */
	int 		ctfcnt;		/* Number of CTF data bytes. */
	const Elf_Sym	*symtab;	/* Ptr to the symbol table. */
	int		nsym;		/* Number of symbols. */
	const char	*strtab;	/* Ptr to the string table. */
	int 		strcnt;		/* Number of string bytes. */
	uint32_t	**ctfoffp;	/* Ptr to array of obj/fnc offsets. */
	uint32_t	**typoffp;	/* Ptr to array of type offsets. */
	long		*typlenp;	/* Ptr to number of type data entries. */
} linker_ctf_t;

int	linker_ctf_get(linker_file_t, linker_ctf_t *);

int elf_cpu_load_file(linker_file_t);
int elf_cpu_unload_file(linker_file_t);

/* values for type */
#define ELF_RELOC_REL	1
#define ELF_RELOC_RELA	2

/*
 * This is version 1 of the KLD file status structure. It is identified
 * by its _size_ in the version field.
 */
struct kld_file_stat_1 {
    int		version;	/* set to sizeof(struct kld_file_stat_1) */
    char        name[MAXPATHLEN];
    int		refs;
    int		id;
    caddr_t	address;	/* load address */
    size_t	size;		/* size in bytes */
};
#endif /* _KERNEL */

struct kld_file_stat {
    int		version;	/* set to sizeof(struct kld_file_stat) */
    char        name[MAXPATHLEN];
    int		refs;
    int		id;
    caddr_t	address;	/* load address */
    size_t	size;		/* size in bytes */
    char        pathname[MAXPATHLEN];
};

struct kld_sym_lookup {
    int		version;	/* set to sizeof(struct kld_sym_lookup) */
    char	*symname;	/* Symbol name we are looking up */
    u_long	symvalue;
    size_t	symsize;
};
#define KLDSYM_LOOKUP	1

/*
 * Flags for kldunloadf() and linker_file_unload()
 */
#define LINKER_UNLOAD_NORMAL	0
#define LINKER_UNLOAD_FORCE	1

#ifndef _KERNEL

#include <sys/cdefs.h>

__BEGIN_DECLS
int	kldload(const char* _file);
int	kldunload(int _fileid);
int	kldunloadf(int _fileid, int flags);
int	kldfind(const char* _file);
int	kldnext(int _fileid);
int	kldstat(int _fileid, struct kld_file_stat* _stat);
int	kldfirstmod(int _fileid);
int	kldsym(int _fileid, int _cmd, void *_data);
__END_DECLS

#endif

#endif /* !_SYS_LINKER_H_ */


code:
/*-
 * Copyright (c) 1999 John D. Polstra
 * Copyright (c) 1999,2001 Peter Wemm <peter@FreeBSD.org>
 * 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/linker_set.h 215701 2010-11-22 19:32:54Z dim $
 */

#ifndef _SYS_LINKER_SET_H_
#define _SYS_LINKER_SET_H_

#ifndef _SYS_CDEFS_H_
#error this file needs sys/cdefs.h as a prerequisite
#endif

/*
 * The following macros are used to declare global sets of objects, which
 * are collected by the linker into a `linker_set' as defined below.
 * For ELF, this is done by constructing a separate segment for each set.
 */

/*
 * Private macros, not to be used outside this header file.
 */
#ifdef __GNUCLIKE___SECTION
#define __MAKE_SET(set, sym)						\
	__GLOBL(__CONCAT(__start_set_,set));				\
	__GLOBL(__CONCAT(__stop_set_,set));				\
	static void const * const __set_##set##_sym_##sym 		\
	__section("set_" #set) __used = &sym
#else /* !__GNUCLIKE___SECTION */
#ifndef lint
#error this file needs to be ported to your compiler
#endif /* lint */
#define __MAKE_SET(set, sym)	extern void const * const (__set_##set##_sym_##sym)
#endif /* __GNUCLIKE___SECTION */

/*
 * Public macros.
 */
#define TEXT_SET(set, sym)	__MAKE_SET(set, sym)
#define DATA_SET(set, sym)	__MAKE_SET(set, sym)
#define BSS_SET(set, sym)	__MAKE_SET(set, sym)
#define ABS_SET(set, sym)	__MAKE_SET(set, sym)
#define SET_ENTRY(set, sym)	__MAKE_SET(set, sym)

/*
 * Initialize before referring to a given linker set.
 */
#define SET_DECLARE(set, ptype)						\
	extern ptype *__CONCAT(__start_set_,set);			\
	extern ptype *__CONCAT(__stop_set_,set)

#define SET_BEGIN(set)							\
	(&__CONCAT(__start_set_,set))
#define SET_LIMIT(set)							\
	(&__CONCAT(__stop_set_,set))

/*
 * Iterate over all the elements of a set.
 *
 * Sets always contain addresses of things, and "pvar" points to words
 * containing those addresses.  Thus is must be declared as "type **pvar",
 * and the address of each set item is obtained inside the loop by "*pvar".
 */
#define SET_FOREACH(pvar, set)						\
	for (pvar = SET_BEGIN(set); pvar < SET_LIMIT(set); pvar++)

#define SET_ITEM(set, i)						\
	((SET_BEGIN(set))[i])

/*
 * Provide a count of the items in a set.
 */
#define SET_COUNT(set)							\
	(SET_LIMIT(set) - SET_BEGIN(set))

#endif	/* _SYS_LINKER_SET_H_ */


code:
/*-
 * Copyright (c) 1997 Berkeley Software Design, Inc. 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.
 * 3. Berkeley Software Design Inc's name may not be used to endorse or
 *    promote products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``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 BERKELEY SOFTWARE DESIGN INC 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.
 *
 *	from BSDI Id: mutex.h,v 2.7.2.35 2000/04/27 03:10:26 cp
 * $FreeBSD: release/9.0.0/sys/sys/lock.h 212408 2010-09-10 06:26:28Z obrien $
 */

#ifndef _SYS_LOCK_H_
#define _SYS_LOCK_H_

#include <sys/queue.h>
#include <sys/_lock.h>

struct lock_list_entry;
struct thread;

/*
 * Lock classes.  Each lock has a class which describes characteristics
 * common to all types of locks of a given class.
 *
 * Spin locks in general must always protect against preemption, as it is
 * an error to perform any type of context switch while holding a spin lock.
 * Also, for an individual lock to be recursable, its class must allow
 * recursion and the lock itself must explicitly allow recursion.
 *
 * The 'lc_ddb_show' function pointer is used to dump class-specific
 * data for the 'show lock' DDB command.  The 'lc_lock' and
 * 'lc_unlock' function pointers are used in sleep(9) and cv_wait(9)
 * to lock and unlock locks while blocking on a sleep queue.  The
 * return value of 'lc_unlock' will be passed to 'lc_lock' on resume
 * to allow communication of state between the two routines.
 */

struct lock_class {
	const	char *lc_name;
	u_int	lc_flags;
	void	(*lc_assert)(struct lock_object *lock, int what);
	void	(*lc_ddb_show)(struct lock_object *lock);
	void	(*lc_lock)(struct lock_object *lock, int how);
	int	(*lc_owner)(struct lock_object *lock, struct thread **owner);
	int	(*lc_unlock)(struct lock_object *lock);
};

#define	LC_SLEEPLOCK	0x00000001	/* Sleep lock. */
#define	LC_SPINLOCK	0x00000002	/* Spin lock. */
#define	LC_SLEEPABLE	0x00000004	/* Sleeping allowed with this lock. */
#define	LC_RECURSABLE	0x00000008	/* Locks of this type may recurse. */
#define	LC_UPGRADABLE	0x00000010	/* Upgrades and downgrades permitted. */

#define	LO_CLASSFLAGS	0x0000ffff	/* Class specific flags. */
#define	LO_INITIALIZED	0x00010000	/* Lock has been initialized. */
#define	LO_WITNESS	0x00020000	/* Should witness monitor this lock. */
#define	LO_QUIET	0x00040000	/* Don't log locking operations. */
#define	LO_RECURSABLE	0x00080000	/* Lock may recurse. */
#define	LO_SLEEPABLE	0x00100000	/* Lock may be held while sleeping. */
#define	LO_UPGRADABLE	0x00200000	/* Lock may be upgraded/downgraded. */
#define	LO_DUPOK	0x00400000	/* Don't check for duplicate acquires */
#define	LO_CLASSMASK	0x0f000000	/* Class index bitmask. */
#define LO_NOPROFILE    0x10000000      /* Don't profile this lock */

/*
 * Lock classes are statically assigned an index into the gobal lock_classes
 * array.  Debugging code looks up the lock class for a given lock object
 * by indexing the array.
 */
#define	LO_CLASSSHIFT		24
#define	LO_CLASSINDEX(lock)	((((lock)->lo_flags) & LO_CLASSMASK) >> LO_CLASSSHIFT)
#define	LOCK_CLASS(lock)	(lock_classes[LO_CLASSINDEX((lock))])
#define	LOCK_CLASS_MAX		(LO_CLASSMASK >> LO_CLASSSHIFT)

/*
 * Option flags passed to lock operations that witness also needs to know
 * about or that are generic across all locks.
 */
#define	LOP_NEWORDER	0x00000001	/* Define a new lock order. */
#define	LOP_QUIET	0x00000002	/* Don't log locking operations. */
#define	LOP_TRYLOCK	0x00000004	/* Don't check lock order. */
#define	LOP_EXCLUSIVE	0x00000008	/* Exclusive lock. */
#define	LOP_DUPOK	0x00000010	/* Don't check for duplicate acquires */

/* Flags passed to witness_assert. */
#define	LA_MASKASSERT	0x000000ff	/* Mask for witness defined asserts. */
#define	LA_UNLOCKED	0x00000000	/* Lock is unlocked. */
#define	LA_LOCKED	0x00000001	/* Lock is at least share locked. */
#define	LA_SLOCKED	0x00000002	/* Lock is exactly share locked. */
#define	LA_XLOCKED	0x00000004	/* Lock is exclusively locked. */
#define	LA_RECURSED	0x00000008	/* Lock is recursed. */
#define	LA_NOTRECURSED	0x00000010	/* Lock is not recursed. */

#ifdef _KERNEL
/*
 * If any of WITNESS, INVARIANTS, or KTR_LOCK KTR tracing has been enabled,
 * then turn on LOCK_DEBUG.  When this option is on, extra debugging
 * facilities such as tracking the file and line number of lock operations
 * are enabled.  Also, mutex locking operations are not inlined to avoid
 * bloat from all the extra debugging code.  We also have to turn on all the
 * calling conventions for this debugging code in modules so that modules can
 * work with both debug and non-debug kernels.
 */
#if defined(KLD_MODULE) || defined(WITNESS) || defined(INVARIANTS) || defined(INVARIANT_SUPPORT) || defined(KTR) || defined(LOCK_PROFILING)
#define	LOCK_DEBUG	1
#else
#define	LOCK_DEBUG	0
#endif

/*
 * In the LOCK_DEBUG case, use the filename and line numbers for debugging
 * operations.  Otherwise, use default values to avoid the unneeded bloat.
 */
#if LOCK_DEBUG > 0
#define	LOCK_FILE	__FILE__
#define	LOCK_LINE	__LINE__
#else
#define	LOCK_FILE	NULL
#define	LOCK_LINE	0
#endif

/*
 * Macros for KTR_LOCK tracing.
 *
 * opname  - name of this operation (LOCK/UNLOCK/SLOCK, etc.)
 * lo      - struct lock_object * for this lock
 * flags   - flags passed to the lock operation
 * recurse - this locks recursion level (or 0 if class is not recursable)
 * result  - result of a try lock operation
 * file    - file name
 * line    - line number
 */
#define	LOCK_LOG_TEST(lo, flags)					\
	(((flags) & LOP_QUIET) == 0 && ((lo)->lo_flags & LO_QUIET) == 0)

#define	LOCK_LOG_LOCK(opname, lo, flags, recurse, file, line) do {	\
	if (LOCK_LOG_TEST((lo), (flags)))				\
		CTR6(KTR_LOCK, opname " (%s) %s %p r = %d at %s:%d",	\
		    LOCK_CLASS(lo)->lc_name, (lo)->lo_name,		\
		    (lo), (u_int)(recurse), (file), (line));		\
} while (0)

#define	LOCK_LOG_TRY(opname, lo, flags, result, file, line) do {	\
	if (LOCK_LOG_TEST((lo), (flags)))				\
		CTR6(KTR_LOCK, "TRY_" opname " (%s) %s %p result=%d at %s:%d",\
		    LOCK_CLASS(lo)->lc_name, (lo)->lo_name,		\
		    (lo), (u_int)(result), (file), (line));		\
} while (0)

#define	LOCK_LOG_INIT(lo, flags) do {					\
	if (LOCK_LOG_TEST((lo), (flags)))				\
		CTR4(KTR_LOCK, "%s: %p (%s) %s", __func__, (lo),	\
 		    LOCK_CLASS(lo)->lc_name, (lo)->lo_name);		\
} while (0)

#define	LOCK_LOG_DESTROY(lo, flags)	LOCK_LOG_INIT(lo, flags)

#define	lock_initalized(lo)	((lo)->lo_flags & LO_INITIALIZED)

/*
 * Helpful macros for quickly coming up with assertions with informative
 * panic messages.
 */
#define MPASS(ex)		MPASS4(ex, #ex, __FILE__, __LINE__)
#define MPASS2(ex, what)	MPASS4(ex, what, __FILE__, __LINE__)
#define MPASS3(ex, file, line)	MPASS4(ex, #ex, file, line)
#define MPASS4(ex, what, file, line)					\
	KASSERT((ex), ("Assertion %s failed at %s:%d", what, file, line))

extern struct lock_class lock_class_mtx_sleep;
extern struct lock_class lock_class_mtx_spin;
extern struct lock_class lock_class_sx;
extern struct lock_class lock_class_rw;
extern struct lock_class lock_class_rm;
extern struct lock_class lock_class_lockmgr;

extern struct lock_class *lock_classes[];

void	lock_init(struct lock_object *, struct lock_class *,
	    const char *, const char *, int);
void	lock_destroy(struct lock_object *);
void	spinlock_enter(void);
void	spinlock_exit(void);
void	witness_init(struct lock_object *, const char *);
void	witness_destroy(struct lock_object *);
int	witness_defineorder(struct lock_object *, struct lock_object *);
void	witness_checkorder(struct lock_object *, int, const char *, int,
	    struct lock_object *);
void	witness_lock(struct lock_object *, int, const char *, int);
void	witness_upgrade(struct lock_object *, int, const char *, int);
void	witness_downgrade(struct lock_object *, int, const char *, int);
void	witness_unlock(struct lock_object *, int, const char *, int);
void	witness_save(struct lock_object *, const char **, int *);
void	witness_restore(struct lock_object *, const char *, int);
int	witness_list_locks(struct lock_list_entry **,
	    int (*)(const char *, ...));
int	witness_warn(int, struct lock_object *, const char *, ...);
void	witness_assert(struct lock_object *, int, const char *, int);
void	witness_display_spinlock(struct lock_object *, struct thread *,
	    int (*)(const char *, ...));
int	witness_line(struct lock_object *);
void	witness_norelease(struct lock_object *);
void	witness_releaseok(struct lock_object *);
const char *witness_file(struct lock_object *);
void	witness_thread_exit(struct thread *);

#ifdef	WITNESS

/* Flags for witness_warn(). */
#define	WARN_GIANTOK	0x01	/* Giant is exempt from this check. */
#define	WARN_PANIC	0x02	/* Panic if check fails. */
#define	WARN_SLEEPOK	0x04	/* Sleepable locks are exempt from check. */

#define	WITNESS_INIT(lock, type)					\
	witness_init((lock), (type))

#define WITNESS_DESTROY(lock)						\
	witness_destroy(lock)

#define	WITNESS_CHECKORDER(lock, flags, file, line, interlock)		\
	witness_checkorder((lock), (flags), (file), (line), (interlock))

#define	WITNESS_DEFINEORDER(lock1, lock2)				\
	witness_defineorder((struct lock_object *)(lock1),		\
	    (struct lock_object *)(lock2))

#define	WITNESS_LOCK(lock, flags, file, line)				\
	witness_lock((lock), (flags), (file), (line))

#define	WITNESS_UPGRADE(lock, flags, file, line)			\
	witness_upgrade((lock), (flags), (file), (line))

#define	WITNESS_DOWNGRADE(lock, flags, file, line)			\
	witness_downgrade((lock), (flags), (file), (line))

#define	WITNESS_UNLOCK(lock, flags, file, line)				\
	witness_unlock((lock), (flags), (file), (line))

#define	WITNESS_CHECK(flags, lock, fmt, ...)				\
	witness_warn((flags), (lock), (fmt), ## __VA_ARGS__)

#define	WITNESS_WARN(flags, lock, fmt, ...)				\
	witness_warn((flags), (lock), (fmt), ## __VA_ARGS__)

#define	WITNESS_SAVE_DECL(n)						\
	const char * __CONCAT(n, __wf);					\
	int __CONCAT(n, __wl)

#define	WITNESS_SAVE(lock, n) 						\
	witness_save((lock), &__CONCAT(n, __wf), &__CONCAT(n, __wl))

#define	WITNESS_RESTORE(lock, n) 					\
	witness_restore((lock), __CONCAT(n, __wf), __CONCAT(n, __wl))

#define	WITNESS_NORELEASE(lock)						\
	witness_norelease(&(lock)->lock_object)

#define	WITNESS_RELEASEOK(lock)						\
	witness_releaseok(&(lock)->lock_object)

#define	WITNESS_FILE(lock) 						\
	witness_file(lock)

#define	WITNESS_LINE(lock) 						\
	witness_line(lock)

#else	/* WITNESS */
#define	WITNESS_INIT(lock, type)				(void)0
#define	WITNESS_DESTROY(lock)					(void)0
#define	WITNESS_DEFINEORDER(lock1, lock2)	0
#define	WITNESS_CHECKORDER(lock, flags, file, line, interlock)	(void)0
#define	WITNESS_LOCK(lock, flags, file, line)			(void)0
#define	WITNESS_UPGRADE(lock, flags, file, line)		(void)0
#define	WITNESS_DOWNGRADE(lock, flags, file, line)		(void)0
#define	WITNESS_UNLOCK(lock, flags, file, line)			(void)0
#define	WITNESS_CHECK(flags, lock, fmt, ...)	0
#define	WITNESS_WARN(flags, lock, fmt, ...)			(void)0
#define	WITNESS_SAVE_DECL(n)					(void)0
#define	WITNESS_SAVE(lock, n)					(void)0
#define	WITNESS_RESTORE(lock, n)				(void)0
#define	WITNESS_NORELEASE(lock)					(void)0
#define	WITNESS_RELEASEOK(lock)					(void)0
#define	WITNESS_FILE(lock) ("?")
#define	WITNESS_LINE(lock) (0)
#endif	/* WITNESS */

/*
 * Helper macros to allow developers to add explicit lock order checks
 * wherever they please without having to actually grab a lock to do so.
 */
#define	witness_check(l)						\
	WITNESS_CHECKORDER(&(l)->lock_object, LOP_EXCLUSIVE, LOCK_FILE,	\
	    LOCK_LINE, NULL)

#define	witness_check_shared(l)						\
	WITNESS_CHECKORDER(&(l)->lock_object, 0, LOCK_FILE, LOCK_LINE, NULL)

#endif	/* _KERNEL */
#endif	/* _SYS_LOCK_H_ */


code:
/*-
 * Copyright (c) 2006 Kip Macy kmacy@FreeBSD.org
 * Copyright (c) 2006 Kris Kennaway kris@FreeBSD.org
 * Copyright (c) 2006 Dag-Erling Smorgrav des@des.no
 *
 * 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 AUTHORS ``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 SHAL THE AUTHORS 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/lock_profile.h 194578 2009-06-21 09:01:12Z rdivacky $
 */

#ifndef _SYS_LOCK_PROFILE_H_
#define _SYS_LOCK_PROFILE_H_

struct lock_profile_object;
LIST_HEAD(lpohead, lock_profile_object);

#ifdef _KERNEL
#ifdef LOCK_PROFILING
#include <machine/cpufunc.h>
#include <sys/lock.h>

#ifndef USE_CPU_NANOSECONDS
u_int64_t nanoseconds(void);
#endif

extern volatile int lock_prof_enable;

void lock_profile_obtain_lock_success(struct lock_object *lo, int contested,
    uint64_t waittime, const char *file, int line);
void lock_profile_release_lock(struct lock_object *lo);
void lock_profile_thread_exit(struct thread *td);

static inline void
lock_profile_obtain_lock_failed(struct lock_object *lo, int *contested,
    uint64_t *waittime)
{
	if (!lock_prof_enable || (lo->lo_flags & LO_NOPROFILE) || *contested)
		return;
	*waittime = nanoseconds();
	*contested = 1;
}

#else /* !LOCK_PROFILING */

#define	lock_profile_release_lock(lo)					(void)0
#define lock_profile_obtain_lock_failed(lo, contested, waittime)	(void)0
#define lock_profile_obtain_lock_success(lo, contested, waittime, file, line)	(void)0
#define	lock_profile_thread_exit(td)					(void)0

#endif  /* !LOCK_PROFILING */

#endif /* _KERNEL */

#endif /* _SYS_LOCK_PROFILE_H_ */


code:
/*-
 * Copyright (c) 1991, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Scooter Morris at Genentech 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.
 *
 *	@(#)lockf.h	8.1 (Berkeley) 6/11/93
 * $FreeBSD: release/9.0.0/sys/sys/lockf.h 192685 2009-05-24 12:39:38Z kib $
 */

#ifndef _SYS_LOCKF_H_
#define	_SYS_LOCKF_H_

#include <sys/queue.h>
#include <sys/_lock.h>
#include <sys/_sx.h>

struct flock;
struct vop_advlock_args;
struct vop_advlockasync_args;

/*
 * The lockf_entry structure is a kernel structure which contains the
 * information associated with a byte range lock.  The lockf_entry
 * structures are linked into the inode structure. Locks are sorted by
 * the starting byte of the lock for efficiency.
 *
 * Active and pending locks on a vnode are organised into a
 * graph. Each pending lock has an out-going edge to each active lock
 * that blocks it.
 *
 * Locks:
 * (i)		locked by the vnode interlock
 * (s)		locked by state->ls_lock
 * (S)		locked by lf_lock_states_lock
 * (c)		const until freeing
 */
struct lockf_edge {
	LIST_ENTRY(lockf_edge) le_outlink; /* (s) link from's out-edge list */
	LIST_ENTRY(lockf_edge) le_inlink; /* (s) link to's in-edge list */
	struct lockf_entry *le_from;	/* (c) out-going from here */
	struct lockf_entry *le_to;	/* (s) in-coming to here */
};
LIST_HEAD(lockf_edge_list, lockf_edge);

struct lockf_entry {
	short	lf_flags;	    /* (c) Semantics: F_POSIX, F_FLOCK, F_WAIT */
	short	lf_type;	    /* (s) Lock type: F_RDLCK, F_WRLCK */
	off_t	lf_start;	    /* (s) Byte # of the start of the lock */
	off_t	lf_end;		    /* (s) Byte # of the end of the lock (OFF_MAX=EOF) */
	struct	lock_owner *lf_owner; /* (c) Owner of the lock */
	struct	vnode *lf_vnode;    /* (c) File being locked (only valid for active lock) */
	struct	inode *lf_inode;    /* (c) Back pointer to the inode */
	struct	task *lf_async_task;/* (c) Async lock callback */
	LIST_ENTRY(lockf_entry) lf_link;  /* (s) Linkage for lock lists */
	struct lockf_edge_list lf_outedges; /* (s) list of out-edges */
	struct lockf_edge_list lf_inedges; /* (s) list of out-edges */
	int	lf_refs;	    /* (s) ref count */
};
LIST_HEAD(lockf_entry_list, lockf_entry);

/*
 * Extra lf_flags bits used by the implementation
 */
#define	F_INTR		0x8000	/* lock was interrupted by lf_purgelocks */

/*
 * Filesystem private node structures should include space for a
 * pointer to a struct lockf_state. This pointer is used by the lock
 * manager to track the locking state for a file.
 *
 * The ls_active list contains the set of active locks on the file. It
 * is strictly ordered by the lock's lf_start value. Each active lock
 * will have in-coming edges to any pending lock which it blocks.
 *
 * Lock requests which are blocked by some other active lock are
 * listed in ls_pending with newer requests first in the list. Lock
 * requests in this list will have out-going edges to each active lock
 * that blocks then. They will also have out-going edges to each
 * pending lock that is older in the queue - this helps to ensure
 * fairness when several processes are contenting to lock the same
 * record.

 * The value of ls_threads is the number of threads currently using
 * the state structure (typically either setting/clearing locks or
 * sleeping waiting to do so). This is used to defer freeing the
 * structure while some thread is still using it.
 */
struct lockf {
	LIST_ENTRY(lockf) ls_link;	/* (S) all active lockf states */
	struct	sx	ls_lock;
	struct	lockf_entry_list ls_active; /* (s) Active locks */
	struct	lockf_entry_list ls_pending; /* (s) Pending locks */
	int		ls_threads;	/* (i) Thread count */
};
LIST_HEAD(lockf_list, lockf);

typedef int lf_iterator(struct vnode *, struct flock *, void *);

int	 lf_advlock(struct vop_advlock_args *, struct lockf **, u_quad_t);
int	 lf_advlockasync(struct vop_advlockasync_args *, struct lockf **, u_quad_t);
void	 lf_purgelocks(struct vnode *vp, struct lockf **statep);
int	 lf_iteratelocks_sysid(int sysid, lf_iterator *, void *);
int	 lf_iteratelocks_vnode(struct vnode *vp, lf_iterator *, void *);
int	 lf_countlocks(int sysid);
void	 lf_clearremotesys(int sysid);

#endif /* !_SYS_LOCKF_H_ */


code:
/*-
 * Copyright (c) 2008 Attilio Rao <attilio@FreeBSD.org>
 * 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(s), this list of conditions and the following disclaimer as
 *    the first lines of this file unmodified other than the possible
 *    addition of one or more copyright notices.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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/lockmgr.h 211531 2010-08-20 19:46:50Z jhb $
 */

#ifndef	_SYS_LOCKMGR_H_
#define	_SYS_LOCKMGR_H_

#include <sys/_lock.h>
#include <sys/_lockmgr.h>
#include <sys/_mutex.h>
#include <sys/_rwlock.h>

#define	LK_SHARE			0x01
#define	LK_SHARED_WAITERS		0x02
#define	LK_EXCLUSIVE_WAITERS		0x04
#define	LK_EXCLUSIVE_SPINNERS		0x08
#define	LK_ALL_WAITERS							\
	(LK_SHARED_WAITERS | LK_EXCLUSIVE_WAITERS)
#define	LK_FLAGMASK							\
	(LK_SHARE | LK_ALL_WAITERS | LK_EXCLUSIVE_SPINNERS)

#define	LK_HOLDER(x)			((x) & ~LK_FLAGMASK)
#define	LK_SHARERS_SHIFT		4
#define	LK_SHARERS(x)			(LK_HOLDER(x) >> LK_SHARERS_SHIFT)
#define	LK_SHARERS_LOCK(x)		((x) << LK_SHARERS_SHIFT | LK_SHARE)
#define	LK_ONE_SHARER			(1 << LK_SHARERS_SHIFT)
#define	LK_UNLOCKED			LK_SHARERS_LOCK(0)
#define	LK_KERNPROC			((uintptr_t)(-1) & ~LK_FLAGMASK)

#ifdef _KERNEL

#if !defined(LOCK_FILE) || !defined(LOCK_LINE)
#error	"LOCK_FILE and LOCK_LINE not defined, include <sys/lock.h> before"
#endif

struct thread;
#define	lk_recurse	lock_object.lo_data

/*
 * Function prototipes.  Routines that start with an underscore are not part
 * of the public interface and might be wrappered with a macro.
 */
int	 __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
	    const char *wmesg, int prio, int timo, const char *file, int line);
#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
void	 _lockmgr_assert(struct lock *lk, int what, const char *file, int line);
#endif
void	 _lockmgr_disown(struct lock *lk, const char *file, int line);

void	 lockallowrecurse(struct lock *lk);
void	 lockallowshare(struct lock *lk);
void	 lockdestroy(struct lock *lk);
void	 lockdisablerecurse(struct lock *lk);
void	 lockinit(struct lock *lk, int prio, const char *wmesg, int timo,
	    int flags);
#ifdef DDB
int	 lockmgr_chain(struct thread *td, struct thread **ownerp);
#endif
void	 lockmgr_printinfo(struct lock *lk);
int	 lockstatus(struct lock *lk);

/*
 * As far as the ilk can be a static NULL pointer these functions need a
 * strict prototype in order to safely use the lock_object member.
 */
static __inline int
_lockmgr_args(struct lock *lk, u_int flags, struct mtx *ilk, const char *wmesg,
    int prio, int timo, const char *file, int line)
{

	return (__lockmgr_args(lk, flags, (ilk != NULL) ? &ilk->lock_object :
	    NULL, wmesg, prio, timo, file, line));
}

static __inline int
_lockmgr_args_rw(struct lock *lk, u_int flags, struct rwlock *ilk,
    const char *wmesg, int prio, int timo, const char *file, int line)
{

	return (__lockmgr_args(lk, flags, (ilk != NULL) ? &ilk->lock_object :
	    NULL, wmesg, prio, timo, file, line));
}

/*
 * Define aliases in order to complete lockmgr KPI.
 */
#define	lockmgr(lk, flags, ilk)						\
	_lockmgr_args((lk), (flags), (ilk), LK_WMESG_DEFAULT,		\
	    LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, LOCK_FILE, LOCK_LINE)
#define	lockmgr_args(lk, flags, ilk, wmesg, prio, timo)			\
	_lockmgr_args((lk), (flags), (ilk), (wmesg), (prio), (timo),	\
	    LOCK_FILE, LOCK_LINE)
#define	lockmgr_args_rw(lk, flags, ilk, wmesg, prio, timo)		\
	_lockmgr_args_rw((lk), (flags), (ilk), (wmesg), (prio), (timo),	\
	    LOCK_FILE, LOCK_LINE)
#define	lockmgr_disown(lk)						\
	_lockmgr_disown((lk), LOCK_FILE, LOCK_LINE)
#define	lockmgr_recursed(lk)						\
	((lk)->lk_recurse != 0)
#define	lockmgr_rw(lk, flags, ilk)					\
	_lockmgr_args_rw((lk), (flags), (ilk), LK_WMESG_DEFAULT,	\
	    LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, LOCK_FILE, LOCK_LINE)
#define	lockmgr_waiters(lk)						\
	((lk)->lk_lock & LK_ALL_WAITERS)
#ifdef INVARIANTS
#define	lockmgr_assert(lk, what)					\
	_lockmgr_assert((lk), (what), LOCK_FILE, LOCK_LINE)
#else
#define	lockmgr_assert(lk, what)
#endif

/*
 * Flags for lockinit().
 */
#define	LK_INIT_MASK	0x0000FF
#define	LK_CANRECURSE	0x000001
#define	LK_NODUP	0x000002
#define	LK_NOPROFILE	0x000004
#define	LK_NOSHARE	0x000008
#define	LK_NOWITNESS	0x000010
#define	LK_QUIET	0x000020
#define	LK_ADAPTIVE	0x000040

/*
 * Additional attributes to be used in lockmgr().
 */
#define	LK_EATTR_MASK	0x00FF00
#define	LK_INTERLOCK	0x000100
#define	LK_NOWAIT	0x000200
#define	LK_RETRY	0x000400
#define	LK_SLEEPFAIL	0x000800
#define	LK_TIMELOCK	0x001000

/*
 * Operations for lockmgr().
 */
#define	LK_TYPE_MASK	0xFF0000
#define	LK_DOWNGRADE	0x010000
#define	LK_DRAIN	0x020000
#define	LK_EXCLOTHER	0x040000
#define	LK_EXCLUSIVE	0x080000
#define	LK_RELEASE	0x100000
#define	LK_SHARED	0x200000
#define	LK_UPGRADE	0x400000

#define	LK_TOTAL_MASK	(LK_INIT_MASK | LK_EATTR_MASK | LK_TYPE_MASK)

/*
 * Default values for lockmgr_args().
 */
#define	LK_WMESG_DEFAULT	(NULL)
#define	LK_PRIO_DEFAULT		(0)
#define	LK_TIMO_DEFAULT		(0)

/*
 * Assertion flags.
 */
#if defined(INVARIANTS) || defined(INVARIANT_SUPPORT)
#define	KA_LOCKED	LA_LOCKED
#define	KA_SLOCKED	LA_SLOCKED
#define	KA_XLOCKED	LA_XLOCKED
#define	KA_UNLOCKED	LA_UNLOCKED
#define	KA_RECURSED	LA_RECURSED
#define	KA_NOTRECURSED	LA_NOTRECURSED
#endif

#endif /* _KERNEL */

#endif /* !_SYS_LOCKMGR_H_ */