xref: /freebsd-src/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c (revision 096a5c6cd28c417456d5ce3598be15e6b656af5c)
16ff6d951SJohn Birrell /*
26ff6d951SJohn Birrell  * CDDL HEADER START
36ff6d951SJohn Birrell  *
46ff6d951SJohn Birrell  * The contents of this file are subject to the terms of the
56ff6d951SJohn Birrell  * Common Development and Distribution License (the "License").
66ff6d951SJohn Birrell  * You may not use this file except in compliance with the License.
76ff6d951SJohn Birrell  *
86ff6d951SJohn Birrell  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96ff6d951SJohn Birrell  * or http://www.opensolaris.org/os/licensing.
106ff6d951SJohn Birrell  * See the License for the specific language governing permissions
116ff6d951SJohn Birrell  * and limitations under the License.
126ff6d951SJohn Birrell  *
136ff6d951SJohn Birrell  * When distributing Covered Code, include this CDDL HEADER in each
146ff6d951SJohn Birrell  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156ff6d951SJohn Birrell  * If applicable, add the following below this CDDL HEADER, with the
166ff6d951SJohn Birrell  * fields enclosed by brackets "[]" replaced with your own identifying
176ff6d951SJohn Birrell  * information: Portions Copyright [yyyy] [name of copyright owner]
186ff6d951SJohn Birrell  *
196ff6d951SJohn Birrell  * CDDL HEADER END
206ff6d951SJohn Birrell  */
216ff6d951SJohn Birrell 
226ff6d951SJohn Birrell /*
231670a1c2SRui Paulo  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
248e648814SRui Paulo  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
25650f66acSMark Johnston  * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
266ff6d951SJohn Birrell  */
276ff6d951SJohn Birrell 
286ff6d951SJohn Birrell #include <sys/types.h>
29bc96366cSSteven Hartland #ifdef illumos
306ff6d951SJohn Birrell #include <sys/modctl.h>
316ff6d951SJohn Birrell #include <sys/systeminfo.h>
324ddb46f6SXin LI #else
334ddb46f6SXin LI #include <sys/param.h>
344ddb46f6SXin LI #include <sys/module.h>
354ddb46f6SXin LI #include <sys/linker.h>
36fb24b944SJohn Birrell #endif
376ff6d951SJohn Birrell #include <sys/resource.h>
386ff6d951SJohn Birrell 
396ff6d951SJohn Birrell #include <libelf.h>
406ff6d951SJohn Birrell #include <strings.h>
41bc96366cSSteven Hartland #ifdef illumos
426ff6d951SJohn Birrell #include <alloca.h>
43fb24b944SJohn Birrell #endif
446ff6d951SJohn Birrell #include <limits.h>
456ff6d951SJohn Birrell #include <unistd.h>
466ff6d951SJohn Birrell #include <stdlib.h>
476ff6d951SJohn Birrell #include <stdio.h>
486ff6d951SJohn Birrell #include <fcntl.h>
496ff6d951SJohn Birrell #include <errno.h>
506ff6d951SJohn Birrell #include <assert.h>
516ff6d951SJohn Birrell 
526ff6d951SJohn Birrell #define	_POSIX_PTHREAD_SEMANTICS
536ff6d951SJohn Birrell #include <dirent.h>
546ff6d951SJohn Birrell #undef	_POSIX_PTHREAD_SEMANTICS
556ff6d951SJohn Birrell 
566ff6d951SJohn Birrell #include <dt_impl.h>
576ff6d951SJohn Birrell #include <dt_program.h>
586ff6d951SJohn Birrell #include <dt_module.h>
596ff6d951SJohn Birrell #include <dt_printf.h>
606ff6d951SJohn Birrell #include <dt_string.h>
616ff6d951SJohn Birrell #include <dt_provider.h>
6293f27766SDomagoj Stolfa #include <dt_oformat.h>
63bc96366cSSteven Hartland #ifndef illumos
64fb24b944SJohn Birrell #include <sys/sysctl.h>
65fb24b944SJohn Birrell #include <string.h>
66fb24b944SJohn Birrell #endif
67fb24b944SJohn Birrell #if defined(__i386__)
68fb24b944SJohn Birrell #include <ieeefp.h>
69fb24b944SJohn Birrell #endif
706ff6d951SJohn Birrell 
716ff6d951SJohn Birrell /*
726ff6d951SJohn Birrell  * Stability and versioning definitions.  These #defines are used in the tables
736ff6d951SJohn Birrell  * of identifiers below to fill in the attribute and version fields associated
746ff6d951SJohn Birrell  * with each identifier.  The DT_ATTR_* macros are a convenience to permit more
756ff6d951SJohn Birrell  * concise declarations of common attributes such as Stable/Stable/Common.  The
766ff6d951SJohn Birrell  * DT_VERS_* macros declare the encoded integer values of all versions used so
776ff6d951SJohn Birrell  * far.  DT_VERS_LATEST must correspond to the latest version value among all
786ff6d951SJohn Birrell  * versions exported by the D compiler.  DT_VERS_STRING must be an ASCII string
796ff6d951SJohn Birrell  * that contains DT_VERS_LATEST within it along with any suffixes (e.g. Beta).
806ff6d951SJohn Birrell  * You must update DT_VERS_LATEST and DT_VERS_STRING when adding a new version,
816ff6d951SJohn Birrell  * and then add the new version to the _dtrace_versions[] array declared below.
826ff6d951SJohn Birrell  * Refer to the Solaris Dynamic Tracing Guide Stability and Versioning chapters
836ff6d951SJohn Birrell  * respectively for an explanation of these DTrace features and their values.
846ff6d951SJohn Birrell  *
856ff6d951SJohn Birrell  * NOTE: Although the DTrace versioning scheme supports the labeling and
866ff6d951SJohn Birrell  *       introduction of incompatible changes (e.g. dropping an interface in a
876ff6d951SJohn Birrell  *       major release), the libdtrace code does not currently support this.
886ff6d951SJohn Birrell  *       All versions are assumed to strictly inherit from one another.  If
896ff6d951SJohn Birrell  *       we ever need to provide divergent interfaces, this will need work.
906ff6d951SJohn Birrell  */
916ff6d951SJohn Birrell #define	DT_ATTR_STABCMN	{ DTRACE_STABILITY_STABLE, \
926ff6d951SJohn Birrell 	DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON }
936ff6d951SJohn Birrell 
946ff6d951SJohn Birrell #define	DT_ATTR_EVOLCMN { DTRACE_STABILITY_EVOLVING, \
956ff6d951SJohn Birrell 	DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON \
966ff6d951SJohn Birrell }
976ff6d951SJohn Birrell 
986ff6d951SJohn Birrell /*
996ff6d951SJohn Birrell  * The version number should be increased for every customer visible release
10009e6105fSMark Johnston  * of DTrace. The major number should be incremented when a fundamental
1016ff6d951SJohn Birrell  * change has been made that would affect all consumers, and would reflect
1026ff6d951SJohn Birrell  * sweeping changes to DTrace or the D language. The minor number should be
1036ff6d951SJohn Birrell  * incremented when a change is introduced that could break scripts that had
1046ff6d951SJohn Birrell  * previously worked; for example, adding a new built-in variable could break
1056ff6d951SJohn Birrell  * a script which was already using that identifier. The micro number should
1066ff6d951SJohn Birrell  * be changed when introducing functionality changes or major bug fixes that
1076ff6d951SJohn Birrell  * do not affect backward compatibility -- this is merely to make capabilities
1086ff6d951SJohn Birrell  * easily determined from the version number. Minor bugs do not require any
1096ff6d951SJohn Birrell  * modification to the version number.
1106ff6d951SJohn Birrell  */
1116ff6d951SJohn Birrell #define	DT_VERS_1_0	DT_VERSION_NUMBER(1, 0, 0)
1126ff6d951SJohn Birrell #define	DT_VERS_1_1	DT_VERSION_NUMBER(1, 1, 0)
1136ff6d951SJohn Birrell #define	DT_VERS_1_2	DT_VERSION_NUMBER(1, 2, 0)
1146ff6d951SJohn Birrell #define	DT_VERS_1_2_1	DT_VERSION_NUMBER(1, 2, 1)
1156ff6d951SJohn Birrell #define	DT_VERS_1_2_2	DT_VERSION_NUMBER(1, 2, 2)
1166ff6d951SJohn Birrell #define	DT_VERS_1_3	DT_VERSION_NUMBER(1, 3, 0)
1176ff6d951SJohn Birrell #define	DT_VERS_1_4	DT_VERSION_NUMBER(1, 4, 0)
1186ff6d951SJohn Birrell #define	DT_VERS_1_4_1	DT_VERSION_NUMBER(1, 4, 1)
1196ff6d951SJohn Birrell #define	DT_VERS_1_5	DT_VERSION_NUMBER(1, 5, 0)
1206ff6d951SJohn Birrell #define	DT_VERS_1_6	DT_VERSION_NUMBER(1, 6, 0)
121fb24b944SJohn Birrell #define	DT_VERS_1_6_1	DT_VERSION_NUMBER(1, 6, 1)
12256b35563SCraig Rodrigues #define	DT_VERS_1_6_2	DT_VERSION_NUMBER(1, 6, 2)
1231670a1c2SRui Paulo #define	DT_VERS_1_6_3	DT_VERSION_NUMBER(1, 6, 3)
124675cf915SPedro F. Giffuni #define	DT_VERS_1_7	DT_VERSION_NUMBER(1, 7, 0)
125f2e66d30SPedro F. Giffuni #define	DT_VERS_1_7_1	DT_VERSION_NUMBER(1, 7, 1)
126730cecb0SPedro F. Giffuni #define	DT_VERS_1_8	DT_VERSION_NUMBER(1, 8, 0)
127730cecb0SPedro F. Giffuni #define	DT_VERS_1_8_1	DT_VERSION_NUMBER(1, 8, 1)
12854727873SPedro F. Giffuni #define	DT_VERS_1_9	DT_VERSION_NUMBER(1, 9, 0)
12909e6105fSMark Johnston #define	DT_VERS_1_9_1	DT_VERSION_NUMBER(1, 9, 1)
1300c2b6019SRui Paulo #define	DT_VERS_1_10	DT_VERSION_NUMBER(1, 10, 0)
131b1f9167fSRui Paulo #define	DT_VERS_1_11	DT_VERSION_NUMBER(1, 11, 0)
1328e648814SRui Paulo #define	DT_VERS_1_12	DT_VERSION_NUMBER(1, 12, 0)
133a43f0be9SRui Paulo #define	DT_VERS_1_12_1	DT_VERSION_NUMBER(1, 12, 1)
134650f66acSMark Johnston #define	DT_VERS_1_13	DT_VERSION_NUMBER(1, 13, 0)
135650f66acSMark Johnston #define	DT_VERS_LATEST	DT_VERS_1_13
136650f66acSMark Johnston #define	DT_VERS_STRING	"Sun D 1.13"
1376ff6d951SJohn Birrell 
1386ff6d951SJohn Birrell const dt_version_t _dtrace_versions[] = {
1396ff6d951SJohn Birrell 	DT_VERS_1_0,	/* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */
1406ff6d951SJohn Birrell 	DT_VERS_1_1,	/* D API 1.1.0 Solaris Express 6/05 */
1416ff6d951SJohn Birrell 	DT_VERS_1_2,	/* D API 1.2.0 Solaris 10 Update 1 */
1426ff6d951SJohn Birrell 	DT_VERS_1_2_1,	/* D API 1.2.1 Solaris Express 4/06 */
1436ff6d951SJohn Birrell 	DT_VERS_1_2_2,	/* D API 1.2.2 Solaris Express 6/06 */
1446ff6d951SJohn Birrell 	DT_VERS_1_3,	/* D API 1.3 Solaris Express 10/06 */
1456ff6d951SJohn Birrell 	DT_VERS_1_4,	/* D API 1.4 Solaris Express 2/07 */
1466ff6d951SJohn Birrell 	DT_VERS_1_4_1,	/* D API 1.4.1 Solaris Express 4/07 */
1476ff6d951SJohn Birrell 	DT_VERS_1_5,	/* D API 1.5 Solaris Express 7/07 */
1486ff6d951SJohn Birrell 	DT_VERS_1_6,	/* D API 1.6 */
149fb24b944SJohn Birrell 	DT_VERS_1_6_1,	/* D API 1.6.1 */
15056b35563SCraig Rodrigues 	DT_VERS_1_6_2,	/* D API 1.6.2 */
1511670a1c2SRui Paulo 	DT_VERS_1_6_3,	/* D API 1.6.3 */
152675cf915SPedro F. Giffuni 	DT_VERS_1_7,	/* D API 1.7 */
153f2e66d30SPedro F. Giffuni 	DT_VERS_1_7_1,	/* D API 1.7.1 */
154730cecb0SPedro F. Giffuni 	DT_VERS_1_8,	/* D API 1.8 */
155730cecb0SPedro F. Giffuni 	DT_VERS_1_8_1,	/* D API 1.8.1 */
15654727873SPedro F. Giffuni 	DT_VERS_1_9,	/* D API 1.9 */
15709e6105fSMark Johnston 	DT_VERS_1_9_1,	/* D API 1.9.1 */
1580c2b6019SRui Paulo 	DT_VERS_1_10,	/* D API 1.10 */
159b1f9167fSRui Paulo 	DT_VERS_1_11,	/* D API 1.11 */
1608e648814SRui Paulo 	DT_VERS_1_12,	/* D API 1.12 */
161a43f0be9SRui Paulo 	DT_VERS_1_12_1,	/* D API 1.12.1 */
162650f66acSMark Johnston 	DT_VERS_1_13,	/* D API 1.13 */
1636ff6d951SJohn Birrell 	0
1646ff6d951SJohn Birrell };
1656ff6d951SJohn Birrell 
1666ff6d951SJohn Birrell /*
167fb24b944SJohn Birrell  * Global variables that are formatted on FreeBSD based on the kernel file name.
168fb24b944SJohn Birrell  */
169bc96366cSSteven Hartland #ifndef illumos
170fb24b944SJohn Birrell static char	curthread_str[MAXPATHLEN];
171fb24b944SJohn Birrell static char	intmtx_str[MAXPATHLEN];
172fb24b944SJohn Birrell static char	threadmtx_str[MAXPATHLEN];
173fb24b944SJohn Birrell static char	rwlock_str[MAXPATHLEN];
174fb24b944SJohn Birrell static char	sxlock_str[MAXPATHLEN];
175fb24b944SJohn Birrell #endif
176fb24b944SJohn Birrell 
177fb24b944SJohn Birrell /*
1786ff6d951SJohn Birrell  * Table of global identifiers.  This is used to populate the global identifier
1796ff6d951SJohn Birrell  * hash when a new dtrace client open occurs.  For more info see dt_ident.h.
1806ff6d951SJohn Birrell  * The global identifiers that represent functions use the dt_idops_func ops
1816ff6d951SJohn Birrell  * and specify the private data pointer as a prototype string which is parsed
1826ff6d951SJohn Birrell  * when the identifier is first encountered.  These prototypes look like ANSI
1836ff6d951SJohn Birrell  * C function prototypes except that the special symbol "@" can be used as a
1846ff6d951SJohn Birrell  * wildcard to represent a single parameter of any type (i.e. any dt_node_t).
1856ff6d951SJohn Birrell  * The standard "..." notation can also be used to represent varargs.  An empty
1866ff6d951SJohn Birrell  * parameter list is taken to mean void (that is, no arguments are permitted).
1876ff6d951SJohn Birrell  * A parameter enclosed in square brackets (e.g. "[int]") denotes an optional
1886ff6d951SJohn Birrell  * argument.
1896ff6d951SJohn Birrell  */
1906ff6d951SJohn Birrell static const dt_ident_t _dtrace_globals[] = {
1916ff6d951SJohn Birrell { "alloca", DT_IDENT_FUNC, 0, DIF_SUBR_ALLOCA, DT_ATTR_STABCMN, DT_VERS_1_0,
1926ff6d951SJohn Birrell 	&dt_idops_func, "void *(size_t)" },
1936ff6d951SJohn Birrell { "arg0", DT_IDENT_SCALAR, 0, DIF_VAR_ARG0, DT_ATTR_STABCMN, DT_VERS_1_0,
1946ff6d951SJohn Birrell 	&dt_idops_type, "int64_t" },
1956ff6d951SJohn Birrell { "arg1", DT_IDENT_SCALAR, 0, DIF_VAR_ARG1, DT_ATTR_STABCMN, DT_VERS_1_0,
1966ff6d951SJohn Birrell 	&dt_idops_type, "int64_t" },
1976ff6d951SJohn Birrell { "arg2", DT_IDENT_SCALAR, 0, DIF_VAR_ARG2, DT_ATTR_STABCMN, DT_VERS_1_0,
1986ff6d951SJohn Birrell 	&dt_idops_type, "int64_t" },
1996ff6d951SJohn Birrell { "arg3", DT_IDENT_SCALAR, 0, DIF_VAR_ARG3, DT_ATTR_STABCMN, DT_VERS_1_0,
2006ff6d951SJohn Birrell 	&dt_idops_type, "int64_t" },
2016ff6d951SJohn Birrell { "arg4", DT_IDENT_SCALAR, 0, DIF_VAR_ARG4, DT_ATTR_STABCMN, DT_VERS_1_0,
2026ff6d951SJohn Birrell 	&dt_idops_type, "int64_t" },
2036ff6d951SJohn Birrell { "arg5", DT_IDENT_SCALAR, 0, DIF_VAR_ARG5, DT_ATTR_STABCMN, DT_VERS_1_0,
2046ff6d951SJohn Birrell 	&dt_idops_type, "int64_t" },
2056ff6d951SJohn Birrell { "arg6", DT_IDENT_SCALAR, 0, DIF_VAR_ARG6, DT_ATTR_STABCMN, DT_VERS_1_0,
2066ff6d951SJohn Birrell 	&dt_idops_type, "int64_t" },
2076ff6d951SJohn Birrell { "arg7", DT_IDENT_SCALAR, 0, DIF_VAR_ARG7, DT_ATTR_STABCMN, DT_VERS_1_0,
2086ff6d951SJohn Birrell 	&dt_idops_type, "int64_t" },
2096ff6d951SJohn Birrell { "arg8", DT_IDENT_SCALAR, 0, DIF_VAR_ARG8, DT_ATTR_STABCMN, DT_VERS_1_0,
2106ff6d951SJohn Birrell 	&dt_idops_type, "int64_t" },
2116ff6d951SJohn Birrell { "arg9", DT_IDENT_SCALAR, 0, DIF_VAR_ARG9, DT_ATTR_STABCMN, DT_VERS_1_0,
2126ff6d951SJohn Birrell 	&dt_idops_type, "int64_t" },
2136ff6d951SJohn Birrell { "args", DT_IDENT_ARRAY, 0, DIF_VAR_ARGS, DT_ATTR_STABCMN, DT_VERS_1_0,
2146ff6d951SJohn Birrell 	&dt_idops_args, NULL },
2156ff6d951SJohn Birrell { "avg", DT_IDENT_AGGFUNC, 0, DTRACEAGG_AVG, DT_ATTR_STABCMN, DT_VERS_1_0,
2166ff6d951SJohn Birrell 	&dt_idops_func, "void(@)" },
2176ff6d951SJohn Birrell { "basename", DT_IDENT_FUNC, 0, DIF_SUBR_BASENAME, DT_ATTR_STABCMN, DT_VERS_1_0,
2186ff6d951SJohn Birrell 	&dt_idops_func, "string(const char *)" },
2196ff6d951SJohn Birrell { "bcopy", DT_IDENT_FUNC, 0, DIF_SUBR_BCOPY, DT_ATTR_STABCMN, DT_VERS_1_0,
2206ff6d951SJohn Birrell 	&dt_idops_func, "void(void *, void *, size_t)" },
2216ff6d951SJohn Birrell { "breakpoint", DT_IDENT_ACTFUNC, 0, DT_ACT_BREAKPOINT,
2226ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0,
2236ff6d951SJohn Birrell 	&dt_idops_func, "void()" },
2246ff6d951SJohn Birrell { "caller", DT_IDENT_SCALAR, 0, DIF_VAR_CALLER, DT_ATTR_STABCMN, DT_VERS_1_0,
2256ff6d951SJohn Birrell 	&dt_idops_type, "uintptr_t" },
2266ff6d951SJohn Birrell { "chill", DT_IDENT_ACTFUNC, 0, DT_ACT_CHILL, DT_ATTR_STABCMN, DT_VERS_1_0,
2276ff6d951SJohn Birrell 	&dt_idops_func, "void(int)" },
2286ff6d951SJohn Birrell { "cleanpath", DT_IDENT_FUNC, 0, DIF_SUBR_CLEANPATH, DT_ATTR_STABCMN,
2296ff6d951SJohn Birrell 	DT_VERS_1_0, &dt_idops_func, "string(const char *)" },
2306ff6d951SJohn Birrell { "clear", DT_IDENT_ACTFUNC, 0, DT_ACT_CLEAR, DT_ATTR_STABCMN, DT_VERS_1_0,
2316ff6d951SJohn Birrell 	&dt_idops_func, "void(...)" },
2326ff6d951SJohn Birrell { "commit", DT_IDENT_ACTFUNC, 0, DT_ACT_COMMIT, DT_ATTR_STABCMN, DT_VERS_1_0,
2336ff6d951SJohn Birrell 	&dt_idops_func, "void(int)" },
2346ff6d951SJohn Birrell { "copyin", DT_IDENT_FUNC, 0, DIF_SUBR_COPYIN, DT_ATTR_STABCMN, DT_VERS_1_0,
2356ff6d951SJohn Birrell 	&dt_idops_func, "void *(uintptr_t, size_t)" },
2366ff6d951SJohn Birrell { "copyinstr", DT_IDENT_FUNC, 0, DIF_SUBR_COPYINSTR,
2376ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0,
2386ff6d951SJohn Birrell 	&dt_idops_func, "string(uintptr_t, [size_t])" },
2396ff6d951SJohn Birrell { "copyinto", DT_IDENT_FUNC, 0, DIF_SUBR_COPYINTO, DT_ATTR_STABCMN,
2406ff6d951SJohn Birrell 	DT_VERS_1_0, &dt_idops_func, "void(uintptr_t, size_t, void *)" },
2416ff6d951SJohn Birrell { "copyout", DT_IDENT_FUNC, 0, DIF_SUBR_COPYOUT, DT_ATTR_STABCMN, DT_VERS_1_0,
2426ff6d951SJohn Birrell 	&dt_idops_func, "void(void *, uintptr_t, size_t)" },
2436ff6d951SJohn Birrell { "copyoutstr", DT_IDENT_FUNC, 0, DIF_SUBR_COPYOUTSTR,
2446ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0,
2456ff6d951SJohn Birrell 	&dt_idops_func, "void(char *, uintptr_t, size_t)" },
2466ff6d951SJohn Birrell { "count", DT_IDENT_AGGFUNC, 0, DTRACEAGG_COUNT, DT_ATTR_STABCMN, DT_VERS_1_0,
2476ff6d951SJohn Birrell 	&dt_idops_func, "void()" },
2486ff6d951SJohn Birrell { "curthread", DT_IDENT_SCALAR, 0, DIF_VAR_CURTHREAD,
2496ff6d951SJohn Birrell 	{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_PRIVATE,
2506ff6d951SJohn Birrell 	DTRACE_CLASS_COMMON }, DT_VERS_1_0,
251bc96366cSSteven Hartland #ifdef illumos
2526ff6d951SJohn Birrell 	&dt_idops_type, "genunix`kthread_t *" },
253fb24b944SJohn Birrell #else
254fb24b944SJohn Birrell 	&dt_idops_type, curthread_str },
255fb24b944SJohn Birrell #endif
2566ff6d951SJohn Birrell { "ddi_pathname", DT_IDENT_FUNC, 0, DIF_SUBR_DDI_PATHNAME,
2576ff6d951SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
2586ff6d951SJohn Birrell 	&dt_idops_func, "string(void *, int64_t)" },
2596ff6d951SJohn Birrell { "denormalize", DT_IDENT_ACTFUNC, 0, DT_ACT_DENORMALIZE, DT_ATTR_STABCMN,
2606ff6d951SJohn Birrell 	DT_VERS_1_0, &dt_idops_func, "void(...)" },
2616ff6d951SJohn Birrell { "dirname", DT_IDENT_FUNC, 0, DIF_SUBR_DIRNAME, DT_ATTR_STABCMN, DT_VERS_1_0,
2626ff6d951SJohn Birrell 	&dt_idops_func, "string(const char *)" },
2636ff6d951SJohn Birrell { "discard", DT_IDENT_ACTFUNC, 0, DT_ACT_DISCARD, DT_ATTR_STABCMN, DT_VERS_1_0,
2646ff6d951SJohn Birrell 	&dt_idops_func, "void(int)" },
2656ff6d951SJohn Birrell { "epid", DT_IDENT_SCALAR, 0, DIF_VAR_EPID, DT_ATTR_STABCMN, DT_VERS_1_0,
2666ff6d951SJohn Birrell 	&dt_idops_type, "uint_t" },
2676ff6d951SJohn Birrell { "errno", DT_IDENT_SCALAR, 0, DIF_VAR_ERRNO, DT_ATTR_STABCMN, DT_VERS_1_0,
2686ff6d951SJohn Birrell 	&dt_idops_type, "int" },
269fb24b944SJohn Birrell { "execargs", DT_IDENT_SCALAR, 0, DIF_VAR_EXECARGS,
270fb24b944SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" },
2716ff6d951SJohn Birrell { "execname", DT_IDENT_SCALAR, 0, DIF_VAR_EXECNAME,
2726ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" },
2736ff6d951SJohn Birrell { "exit", DT_IDENT_ACTFUNC, 0, DT_ACT_EXIT, DT_ATTR_STABCMN, DT_VERS_1_0,
2746ff6d951SJohn Birrell 	&dt_idops_func, "void(int)" },
2756ff6d951SJohn Birrell { "freopen", DT_IDENT_ACTFUNC, 0, DT_ACT_FREOPEN, DT_ATTR_STABCMN,
2766ff6d951SJohn Birrell 	DT_VERS_1_1, &dt_idops_func, "void(@, ...)" },
2776ff6d951SJohn Birrell { "ftruncate", DT_IDENT_ACTFUNC, 0, DT_ACT_FTRUNCATE, DT_ATTR_STABCMN,
2786ff6d951SJohn Birrell 	DT_VERS_1_0, &dt_idops_func, "void()" },
2796ff6d951SJohn Birrell { "func", DT_IDENT_ACTFUNC, 0, DT_ACT_SYM, DT_ATTR_STABCMN,
2806ff6d951SJohn Birrell 	DT_VERS_1_2, &dt_idops_func, "_symaddr(uintptr_t)" },
2816ff6d951SJohn Birrell { "getmajor", DT_IDENT_FUNC, 0, DIF_SUBR_GETMAJOR,
2826ff6d951SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
2836ff6d951SJohn Birrell 	&dt_idops_func, "genunix`major_t(genunix`dev_t)" },
2846ff6d951SJohn Birrell { "getminor", DT_IDENT_FUNC, 0, DIF_SUBR_GETMINOR,
2856ff6d951SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
2866ff6d951SJohn Birrell 	&dt_idops_func, "genunix`minor_t(genunix`dev_t)" },
2876ff6d951SJohn Birrell { "htonl", DT_IDENT_FUNC, 0, DIF_SUBR_HTONL, DT_ATTR_EVOLCMN, DT_VERS_1_3,
2886ff6d951SJohn Birrell 	&dt_idops_func, "uint32_t(uint32_t)" },
2896ff6d951SJohn Birrell { "htonll", DT_IDENT_FUNC, 0, DIF_SUBR_HTONLL, DT_ATTR_EVOLCMN, DT_VERS_1_3,
2906ff6d951SJohn Birrell 	&dt_idops_func, "uint64_t(uint64_t)" },
2916ff6d951SJohn Birrell { "htons", DT_IDENT_FUNC, 0, DIF_SUBR_HTONS, DT_ATTR_EVOLCMN, DT_VERS_1_3,
2926ff6d951SJohn Birrell 	&dt_idops_func, "uint16_t(uint16_t)" },
2930c2b6019SRui Paulo { "getf", DT_IDENT_FUNC, 0, DIF_SUBR_GETF, DT_ATTR_STABCMN, DT_VERS_1_10,
2940c2b6019SRui Paulo 	&dt_idops_func, "file_t *(int)" },
2956ff6d951SJohn Birrell { "gid", DT_IDENT_SCALAR, 0, DIF_VAR_GID, DT_ATTR_STABCMN, DT_VERS_1_0,
2966ff6d951SJohn Birrell 	&dt_idops_type, "gid_t" },
2976ff6d951SJohn Birrell { "id", DT_IDENT_SCALAR, 0, DIF_VAR_ID, DT_ATTR_STABCMN, DT_VERS_1_0,
2986ff6d951SJohn Birrell 	&dt_idops_type, "uint_t" },
2996ff6d951SJohn Birrell { "index", DT_IDENT_FUNC, 0, DIF_SUBR_INDEX, DT_ATTR_STABCMN, DT_VERS_1_1,
3006ff6d951SJohn Birrell 	&dt_idops_func, "int(const char *, const char *, [int])" },
3016ff6d951SJohn Birrell { "inet_ntoa", DT_IDENT_FUNC, 0, DIF_SUBR_INET_NTOA, DT_ATTR_STABCMN,
302bc96366cSSteven Hartland #ifdef illumos
3036ff6d951SJohn Birrell 	DT_VERS_1_5, &dt_idops_func, "string(ipaddr_t *)" },
304fb24b944SJohn Birrell #else
305fb24b944SJohn Birrell 	DT_VERS_1_5, &dt_idops_func, "string(in_addr_t *)" },
306fb24b944SJohn Birrell #endif
3076ff6d951SJohn Birrell { "inet_ntoa6", DT_IDENT_FUNC, 0, DIF_SUBR_INET_NTOA6, DT_ATTR_STABCMN,
308bc96366cSSteven Hartland #ifdef illumos
3096ff6d951SJohn Birrell 	DT_VERS_1_5, &dt_idops_func, "string(in6_addr_t *)" },
310fb24b944SJohn Birrell #else
311fb24b944SJohn Birrell 	DT_VERS_1_5, &dt_idops_func, "string(struct in6_addr *)" },
312fb24b944SJohn Birrell #endif
3136ff6d951SJohn Birrell { "inet_ntop", DT_IDENT_FUNC, 0, DIF_SUBR_INET_NTOP, DT_ATTR_STABCMN,
3146ff6d951SJohn Birrell 	DT_VERS_1_5, &dt_idops_func, "string(int, void *)" },
3156ff6d951SJohn Birrell { "ipl", DT_IDENT_SCALAR, 0, DIF_VAR_IPL, DT_ATTR_STABCMN, DT_VERS_1_0,
3166ff6d951SJohn Birrell 	&dt_idops_type, "uint_t" },
317224e0c2fSMark Johnston #ifdef __FreeBSD__
318224e0c2fSMark Johnston { "jailname", DT_IDENT_SCALAR, 0, DIF_VAR_JAILNAME,
319224e0c2fSMark Johnston 	DT_ATTR_STABCMN, DT_VERS_1_13, &dt_idops_type, "string" },
320224e0c2fSMark Johnston { "jid", DT_IDENT_SCALAR, 0, DIF_VAR_JID, DT_ATTR_STABCMN, DT_VERS_1_13,
321224e0c2fSMark Johnston 	&dt_idops_type, "int" },
322224e0c2fSMark Johnston #endif
323b1f9167fSRui Paulo { "json", DT_IDENT_FUNC, 0, DIF_SUBR_JSON, DT_ATTR_STABCMN, DT_VERS_1_11,
324b1f9167fSRui Paulo 	&dt_idops_func, "string(const char *, const char *)" },
3256ff6d951SJohn Birrell { "jstack", DT_IDENT_ACTFUNC, 0, DT_ACT_JSTACK, DT_ATTR_STABCMN, DT_VERS_1_0,
3266ff6d951SJohn Birrell 	&dt_idops_func, "stack(...)" },
3276ff6d951SJohn Birrell { "lltostr", DT_IDENT_FUNC, 0, DIF_SUBR_LLTOSTR, DT_ATTR_STABCMN, DT_VERS_1_0,
328730cecb0SPedro F. Giffuni 	&dt_idops_func, "string(int64_t, [int])" },
329675cf915SPedro F. Giffuni { "llquantize", DT_IDENT_AGGFUNC, 0, DTRACEAGG_LLQUANTIZE, DT_ATTR_STABCMN,
330675cf915SPedro F. Giffuni 	DT_VERS_1_7, &dt_idops_func,
331675cf915SPedro F. Giffuni 	"void(@, int32_t, int32_t, int32_t, int32_t, ...)" },
3326ff6d951SJohn Birrell { "lquantize", DT_IDENT_AGGFUNC, 0, DTRACEAGG_LQUANTIZE,
3336ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0,
3346ff6d951SJohn Birrell 	&dt_idops_func, "void(@, int32_t, int32_t, ...)" },
3356ff6d951SJohn Birrell { "max", DT_IDENT_AGGFUNC, 0, DTRACEAGG_MAX, DT_ATTR_STABCMN, DT_VERS_1_0,
3366ff6d951SJohn Birrell 	&dt_idops_func, "void(@)" },
337fb24b944SJohn Birrell { "memref", DT_IDENT_FUNC, 0, DIF_SUBR_MEMREF, DT_ATTR_STABCMN, DT_VERS_1_1,
338fb24b944SJohn Birrell 	&dt_idops_func, "uintptr_t *(void *, size_t)" },
339bc96366cSSteven Hartland #ifndef illumos
340e572bc11SMark Johnston { "memstr", DT_IDENT_FUNC, 0, DIF_SUBR_MEMSTR, DT_ATTR_STABCMN, DT_VERS_1_0,
341e572bc11SMark Johnston 	&dt_idops_func, "string(void *, char, size_t)" },
342e572bc11SMark Johnston #endif
3436ff6d951SJohn Birrell { "min", DT_IDENT_AGGFUNC, 0, DTRACEAGG_MIN, DT_ATTR_STABCMN, DT_VERS_1_0,
3446ff6d951SJohn Birrell 	&dt_idops_func, "void(@)" },
3456ff6d951SJohn Birrell { "mod", DT_IDENT_ACTFUNC, 0, DT_ACT_MOD, DT_ATTR_STABCMN,
3466ff6d951SJohn Birrell 	DT_VERS_1_2, &dt_idops_func, "_symaddr(uintptr_t)" },
3470b56e7a8SMark Johnston #ifdef illumos
3486ff6d951SJohn Birrell { "msgdsize", DT_IDENT_FUNC, 0, DIF_SUBR_MSGDSIZE,
3496ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0,
3506ff6d951SJohn Birrell 	&dt_idops_func, "size_t(mblk_t *)" },
3516ff6d951SJohn Birrell { "msgsize", DT_IDENT_FUNC, 0, DIF_SUBR_MSGSIZE,
3526ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0,
3536ff6d951SJohn Birrell 	&dt_idops_func, "size_t(mblk_t *)" },
3546ff6d951SJohn Birrell { "mutex_owned", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_OWNED,
3556ff6d951SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
3566ff6d951SJohn Birrell 	&dt_idops_func, "int(genunix`kmutex_t *)" },
3576ff6d951SJohn Birrell { "mutex_owner", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_OWNER,
3586ff6d951SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
3596ff6d951SJohn Birrell 	&dt_idops_func, "genunix`kthread_t *(genunix`kmutex_t *)" },
3606ff6d951SJohn Birrell { "mutex_type_adaptive", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_TYPE_ADAPTIVE,
3616ff6d951SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
3626ff6d951SJohn Birrell 	&dt_idops_func, "int(genunix`kmutex_t *)" },
3636ff6d951SJohn Birrell { "mutex_type_spin", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_TYPE_SPIN,
3646ff6d951SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
3656ff6d951SJohn Birrell 	&dt_idops_func, "int(genunix`kmutex_t *)" },
366fb24b944SJohn Birrell #else
367fb24b944SJohn Birrell { "mutex_owned", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_OWNED,
368fb24b944SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
369fb24b944SJohn Birrell 	&dt_idops_func, intmtx_str },
370fb24b944SJohn Birrell { "mutex_owner", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_OWNER,
371fb24b944SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
372fb24b944SJohn Birrell 	&dt_idops_func, threadmtx_str },
373fb24b944SJohn Birrell { "mutex_type_adaptive", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_TYPE_ADAPTIVE,
374fb24b944SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
375fb24b944SJohn Birrell 	&dt_idops_func, intmtx_str },
376fb24b944SJohn Birrell { "mutex_type_spin", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_TYPE_SPIN,
377fb24b944SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
378fb24b944SJohn Birrell 	&dt_idops_func, intmtx_str },
379fb24b944SJohn Birrell #endif
3806ff6d951SJohn Birrell { "ntohl", DT_IDENT_FUNC, 0, DIF_SUBR_NTOHL, DT_ATTR_EVOLCMN, DT_VERS_1_3,
3816ff6d951SJohn Birrell 	&dt_idops_func, "uint32_t(uint32_t)" },
3826ff6d951SJohn Birrell { "ntohll", DT_IDENT_FUNC, 0, DIF_SUBR_NTOHLL, DT_ATTR_EVOLCMN, DT_VERS_1_3,
3836ff6d951SJohn Birrell 	&dt_idops_func, "uint64_t(uint64_t)" },
3846ff6d951SJohn Birrell { "ntohs", DT_IDENT_FUNC, 0, DIF_SUBR_NTOHS, DT_ATTR_EVOLCMN, DT_VERS_1_3,
3856ff6d951SJohn Birrell 	&dt_idops_func, "uint16_t(uint16_t)" },
3866ff6d951SJohn Birrell { "normalize", DT_IDENT_ACTFUNC, 0, DT_ACT_NORMALIZE, DT_ATTR_STABCMN,
3876ff6d951SJohn Birrell 	DT_VERS_1_0, &dt_idops_func, "void(...)" },
3886ff6d951SJohn Birrell { "panic", DT_IDENT_ACTFUNC, 0, DT_ACT_PANIC, DT_ATTR_STABCMN, DT_VERS_1_0,
3896ff6d951SJohn Birrell 	&dt_idops_func, "void()" },
3906ff6d951SJohn Birrell { "pid", DT_IDENT_SCALAR, 0, DIF_VAR_PID, DT_ATTR_STABCMN, DT_VERS_1_0,
3916ff6d951SJohn Birrell 	&dt_idops_type, "pid_t" },
3926ff6d951SJohn Birrell { "ppid", DT_IDENT_SCALAR, 0, DIF_VAR_PPID, DT_ATTR_STABCMN, DT_VERS_1_0,
3936ff6d951SJohn Birrell 	&dt_idops_type, "pid_t" },
39454727873SPedro F. Giffuni { "print", DT_IDENT_ACTFUNC, 0, DT_ACT_PRINT, DT_ATTR_STABCMN, DT_VERS_1_9,
39554727873SPedro F. Giffuni 	&dt_idops_func, "void(@)" },
3966ff6d951SJohn Birrell { "printa", DT_IDENT_ACTFUNC, 0, DT_ACT_PRINTA, DT_ATTR_STABCMN, DT_VERS_1_0,
3976ff6d951SJohn Birrell 	&dt_idops_func, "void(@, ...)" },
3986ff6d951SJohn Birrell { "printf", DT_IDENT_ACTFUNC, 0, DT_ACT_PRINTF, DT_ATTR_STABCMN, DT_VERS_1_0,
3996ff6d951SJohn Birrell 	&dt_idops_func, "void(@, ...)" },
400fb24b944SJohn Birrell { "printm", DT_IDENT_ACTFUNC, 0, DT_ACT_PRINTM, DT_ATTR_STABCMN, DT_VERS_1_0,
401fb24b944SJohn Birrell 	&dt_idops_func, "void(size_t, uintptr_t *)" },
4026ff6d951SJohn Birrell { "probefunc", DT_IDENT_SCALAR, 0, DIF_VAR_PROBEFUNC,
4036ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" },
4046ff6d951SJohn Birrell { "probemod", DT_IDENT_SCALAR, 0, DIF_VAR_PROBEMOD,
4056ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" },
4066ff6d951SJohn Birrell { "probename", DT_IDENT_SCALAR, 0, DIF_VAR_PROBENAME,
4076ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" },
4086ff6d951SJohn Birrell { "probeprov", DT_IDENT_SCALAR, 0, DIF_VAR_PROBEPROV,
4096ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" },
4106ff6d951SJohn Birrell { "progenyof", DT_IDENT_FUNC, 0, DIF_SUBR_PROGENYOF,
4116ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0,
4126ff6d951SJohn Birrell 	&dt_idops_func, "int(pid_t)" },
4136ff6d951SJohn Birrell { "quantize", DT_IDENT_AGGFUNC, 0, DTRACEAGG_QUANTIZE,
4146ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0,
4156ff6d951SJohn Birrell 	&dt_idops_func, "void(@, ...)" },
4166ff6d951SJohn Birrell { "raise", DT_IDENT_ACTFUNC, 0, DT_ACT_RAISE, DT_ATTR_STABCMN, DT_VERS_1_0,
4176ff6d951SJohn Birrell 	&dt_idops_func, "void(int)" },
4186ff6d951SJohn Birrell { "rand", DT_IDENT_FUNC, 0, DIF_SUBR_RAND, DT_ATTR_STABCMN, DT_VERS_1_0,
4196ff6d951SJohn Birrell 	&dt_idops_func, "int()" },
420bdd101c4SMark Johnston { "regs", DT_IDENT_ARRAY, 0, DIF_VAR_REGS, DT_ATTR_STABCMN, DT_VERS_1_13,
421bdd101c4SMark Johnston 	&dt_idops_regs, NULL },
4226ff6d951SJohn Birrell { "rindex", DT_IDENT_FUNC, 0, DIF_SUBR_RINDEX, DT_ATTR_STABCMN, DT_VERS_1_1,
4236ff6d951SJohn Birrell 	&dt_idops_func, "int(const char *, const char *, [int])" },
424bc96366cSSteven Hartland #ifdef illumos
4256ff6d951SJohn Birrell { "rw_iswriter", DT_IDENT_FUNC, 0, DIF_SUBR_RW_ISWRITER,
4266ff6d951SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
4276ff6d951SJohn Birrell 	&dt_idops_func, "int(genunix`krwlock_t *)" },
4286ff6d951SJohn Birrell { "rw_read_held", DT_IDENT_FUNC, 0, DIF_SUBR_RW_READ_HELD,
4296ff6d951SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
4306ff6d951SJohn Birrell 	&dt_idops_func, "int(genunix`krwlock_t *)" },
4316ff6d951SJohn Birrell { "rw_write_held", DT_IDENT_FUNC, 0, DIF_SUBR_RW_WRITE_HELD,
4326ff6d951SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
4336ff6d951SJohn Birrell 	&dt_idops_func, "int(genunix`krwlock_t *)" },
434fb24b944SJohn Birrell #else
435fb24b944SJohn Birrell { "rw_iswriter", DT_IDENT_FUNC, 0, DIF_SUBR_RW_ISWRITER,
436fb24b944SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
437fb24b944SJohn Birrell 	&dt_idops_func, rwlock_str },
438fb24b944SJohn Birrell { "rw_read_held", DT_IDENT_FUNC, 0, DIF_SUBR_RW_READ_HELD,
439fb24b944SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
440fb24b944SJohn Birrell 	&dt_idops_func, rwlock_str },
441fb24b944SJohn Birrell { "rw_write_held", DT_IDENT_FUNC, 0, DIF_SUBR_RW_WRITE_HELD,
442fb24b944SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
443fb24b944SJohn Birrell 	&dt_idops_func, rwlock_str },
444fb24b944SJohn Birrell #endif
4456ff6d951SJohn Birrell { "self", DT_IDENT_PTR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0,
4466ff6d951SJohn Birrell 	&dt_idops_type, "void" },
4476ff6d951SJohn Birrell { "setopt", DT_IDENT_ACTFUNC, 0, DT_ACT_SETOPT, DT_ATTR_STABCMN,
4486ff6d951SJohn Birrell 	DT_VERS_1_2, &dt_idops_func, "void(const char *, [const char *])" },
4496ff6d951SJohn Birrell { "speculate", DT_IDENT_ACTFUNC, 0, DT_ACT_SPECULATE,
4506ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0,
4516ff6d951SJohn Birrell 	&dt_idops_func, "void(int)" },
4526ff6d951SJohn Birrell { "speculation", DT_IDENT_FUNC, 0, DIF_SUBR_SPECULATION,
4536ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0,
4546ff6d951SJohn Birrell 	&dt_idops_func, "int()" },
4556ff6d951SJohn Birrell { "stack", DT_IDENT_ACTFUNC, 0, DT_ACT_STACK, DT_ATTR_STABCMN, DT_VERS_1_0,
4566ff6d951SJohn Birrell 	&dt_idops_func, "stack(...)" },
4576ff6d951SJohn Birrell { "stackdepth", DT_IDENT_SCALAR, 0, DIF_VAR_STACKDEPTH,
4586ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0,
4596ff6d951SJohn Birrell 	&dt_idops_type, "uint32_t" },
4606ff6d951SJohn Birrell { "stddev", DT_IDENT_AGGFUNC, 0, DTRACEAGG_STDDEV, DT_ATTR_STABCMN,
4616ff6d951SJohn Birrell 	DT_VERS_1_6, &dt_idops_func, "void(@)" },
4626ff6d951SJohn Birrell { "stop", DT_IDENT_ACTFUNC, 0, DT_ACT_STOP, DT_ATTR_STABCMN, DT_VERS_1_0,
4636ff6d951SJohn Birrell 	&dt_idops_func, "void()" },
4646ff6d951SJohn Birrell { "strchr", DT_IDENT_FUNC, 0, DIF_SUBR_STRCHR, DT_ATTR_STABCMN, DT_VERS_1_1,
4656ff6d951SJohn Birrell 	&dt_idops_func, "string(const char *, char)" },
4666ff6d951SJohn Birrell { "strlen", DT_IDENT_FUNC, 0, DIF_SUBR_STRLEN, DT_ATTR_STABCMN, DT_VERS_1_0,
4676ff6d951SJohn Birrell 	&dt_idops_func, "size_t(const char *)" },
4686ff6d951SJohn Birrell { "strjoin", DT_IDENT_FUNC, 0, DIF_SUBR_STRJOIN, DT_ATTR_STABCMN, DT_VERS_1_0,
4696ff6d951SJohn Birrell 	&dt_idops_func, "string(const char *, const char *)" },
4706ff6d951SJohn Birrell { "strrchr", DT_IDENT_FUNC, 0, DIF_SUBR_STRRCHR, DT_ATTR_STABCMN, DT_VERS_1_1,
4716ff6d951SJohn Birrell 	&dt_idops_func, "string(const char *, char)" },
4726ff6d951SJohn Birrell { "strstr", DT_IDENT_FUNC, 0, DIF_SUBR_STRSTR, DT_ATTR_STABCMN, DT_VERS_1_1,
4736ff6d951SJohn Birrell 	&dt_idops_func, "string(const char *, const char *)" },
4746ff6d951SJohn Birrell { "strtok", DT_IDENT_FUNC, 0, DIF_SUBR_STRTOK, DT_ATTR_STABCMN, DT_VERS_1_1,
4756ff6d951SJohn Birrell 	&dt_idops_func, "string(const char *, const char *)" },
476b1f9167fSRui Paulo { "strtoll", DT_IDENT_FUNC, 0, DIF_SUBR_STRTOLL, DT_ATTR_STABCMN, DT_VERS_1_11,
477b1f9167fSRui Paulo 	&dt_idops_func, "int64_t(const char *, [int])" },
4786ff6d951SJohn Birrell { "substr", DT_IDENT_FUNC, 0, DIF_SUBR_SUBSTR, DT_ATTR_STABCMN, DT_VERS_1_1,
4796ff6d951SJohn Birrell 	&dt_idops_func, "string(const char *, int, [int])" },
4806ff6d951SJohn Birrell { "sum", DT_IDENT_AGGFUNC, 0, DTRACEAGG_SUM, DT_ATTR_STABCMN, DT_VERS_1_0,
4816ff6d951SJohn Birrell 	&dt_idops_func, "void(@)" },
482bc96366cSSteven Hartland #ifndef illumos
483fb24b944SJohn Birrell { "sx_isexclusive", DT_IDENT_FUNC, 0, DIF_SUBR_SX_ISEXCLUSIVE,
484fb24b944SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
485fb24b944SJohn Birrell 	&dt_idops_func, sxlock_str },
486fb24b944SJohn Birrell { "sx_shared_held", DT_IDENT_FUNC, 0, DIF_SUBR_SX_SHARED_HELD,
487fb24b944SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
488fb24b944SJohn Birrell 	&dt_idops_func, sxlock_str },
489fb24b944SJohn Birrell { "sx_exclusive_held", DT_IDENT_FUNC, 0, DIF_SUBR_SX_EXCLUSIVE_HELD,
490fb24b944SJohn Birrell 	DT_ATTR_EVOLCMN, DT_VERS_1_0,
491fb24b944SJohn Birrell 	&dt_idops_func, sxlock_str },
492fb24b944SJohn Birrell #endif
4936ff6d951SJohn Birrell { "sym", DT_IDENT_ACTFUNC, 0, DT_ACT_SYM, DT_ATTR_STABCMN,
4946ff6d951SJohn Birrell 	DT_VERS_1_2, &dt_idops_func, "_symaddr(uintptr_t)" },
4956ff6d951SJohn Birrell { "system", DT_IDENT_ACTFUNC, 0, DT_ACT_SYSTEM, DT_ATTR_STABCMN, DT_VERS_1_0,
4966ff6d951SJohn Birrell 	&dt_idops_func, "void(@, ...)" },
4976ff6d951SJohn Birrell { "this", DT_IDENT_PTR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0,
4986ff6d951SJohn Birrell 	&dt_idops_type, "void" },
4996ff6d951SJohn Birrell { "tid", DT_IDENT_SCALAR, 0, DIF_VAR_TID, DT_ATTR_STABCMN, DT_VERS_1_0,
5006ff6d951SJohn Birrell 	&dt_idops_type, "id_t" },
5016ff6d951SJohn Birrell { "timestamp", DT_IDENT_SCALAR, 0, DIF_VAR_TIMESTAMP,
5026ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0,
5036ff6d951SJohn Birrell 	&dt_idops_type, "uint64_t" },
504730cecb0SPedro F. Giffuni { "tolower", DT_IDENT_FUNC, 0, DIF_SUBR_TOLOWER, DT_ATTR_STABCMN, DT_VERS_1_8,
505730cecb0SPedro F. Giffuni 	&dt_idops_func, "string(const char *)" },
506730cecb0SPedro F. Giffuni { "toupper", DT_IDENT_FUNC, 0, DIF_SUBR_TOUPPER, DT_ATTR_STABCMN, DT_VERS_1_8,
507730cecb0SPedro F. Giffuni 	&dt_idops_func, "string(const char *)" },
5086ff6d951SJohn Birrell { "trace", DT_IDENT_ACTFUNC, 0, DT_ACT_TRACE, DT_ATTR_STABCMN, DT_VERS_1_0,
5096ff6d951SJohn Birrell 	&dt_idops_func, "void(@)" },
5106ff6d951SJohn Birrell { "tracemem", DT_IDENT_ACTFUNC, 0, DT_ACT_TRACEMEM,
5116ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0,
512f2e66d30SPedro F. Giffuni 	&dt_idops_func, "void(@, size_t, ...)" },
5136ff6d951SJohn Birrell { "trunc", DT_IDENT_ACTFUNC, 0, DT_ACT_TRUNC, DT_ATTR_STABCMN,
5146ff6d951SJohn Birrell 	DT_VERS_1_0, &dt_idops_func, "void(...)" },
5156ff6d951SJohn Birrell { "uaddr", DT_IDENT_ACTFUNC, 0, DT_ACT_UADDR, DT_ATTR_STABCMN,
5166ff6d951SJohn Birrell 	DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
5176ff6d951SJohn Birrell { "ucaller", DT_IDENT_SCALAR, 0, DIF_VAR_UCALLER, DT_ATTR_STABCMN,
5186ff6d951SJohn Birrell 	DT_VERS_1_2, &dt_idops_type, "uint64_t" },
5196ff6d951SJohn Birrell { "ufunc", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN,
5206ff6d951SJohn Birrell 	DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
5216ff6d951SJohn Birrell { "uid", DT_IDENT_SCALAR, 0, DIF_VAR_UID, DT_ATTR_STABCMN, DT_VERS_1_0,
5226ff6d951SJohn Birrell 	&dt_idops_type, "uid_t" },
5236ff6d951SJohn Birrell { "umod", DT_IDENT_ACTFUNC, 0, DT_ACT_UMOD, DT_ATTR_STABCMN,
5246ff6d951SJohn Birrell 	DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
5256ff6d951SJohn Birrell { "uregs", DT_IDENT_ARRAY, 0, DIF_VAR_UREGS, DT_ATTR_STABCMN, DT_VERS_1_0,
5266ff6d951SJohn Birrell 	&dt_idops_regs, NULL },
5276ff6d951SJohn Birrell { "ustack", DT_IDENT_ACTFUNC, 0, DT_ACT_USTACK, DT_ATTR_STABCMN, DT_VERS_1_0,
5286ff6d951SJohn Birrell 	&dt_idops_func, "stack(...)" },
5296ff6d951SJohn Birrell { "ustackdepth", DT_IDENT_SCALAR, 0, DIF_VAR_USTACKDEPTH,
5306ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_2,
5316ff6d951SJohn Birrell 	&dt_idops_type, "uint32_t" },
5326ff6d951SJohn Birrell { "usym", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN,
5336ff6d951SJohn Birrell 	DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
5346ff6d951SJohn Birrell { "vtimestamp", DT_IDENT_SCALAR, 0, DIF_VAR_VTIMESTAMP,
5356ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0,
5366ff6d951SJohn Birrell 	&dt_idops_type, "uint64_t" },
5376ff6d951SJohn Birrell { "walltimestamp", DT_IDENT_SCALAR, 0, DIF_VAR_WALLTIMESTAMP,
5386ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0,
5396ff6d951SJohn Birrell 	&dt_idops_type, "int64_t" },
5406ff6d951SJohn Birrell { "zonename", DT_IDENT_SCALAR, 0, DIF_VAR_ZONENAME,
5416ff6d951SJohn Birrell 	DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" },
542c6024848SRyan Stone 
543bc96366cSSteven Hartland #ifndef illumos
544c6024848SRyan Stone { "cpu", DT_IDENT_SCALAR, 0, DIF_VAR_CPU,
545c6024848SRyan Stone 	DT_ATTR_STABCMN, DT_VERS_1_6_3, &dt_idops_type, "int" },
546c6024848SRyan Stone #endif
547c6024848SRyan Stone 
5486ff6d951SJohn Birrell { NULL, 0, 0, 0, { 0, 0, 0 }, 0, NULL, NULL }
5496ff6d951SJohn Birrell };
5506ff6d951SJohn Birrell 
5516ff6d951SJohn Birrell /*
5526ff6d951SJohn Birrell  * Tables of ILP32 intrinsic integer and floating-point type templates to use
5536ff6d951SJohn Birrell  * to populate the dynamic "C" CTF type container.
5546ff6d951SJohn Birrell  */
5556ff6d951SJohn Birrell static const dt_intrinsic_t _dtrace_intrinsics_32[] = {
5566ff6d951SJohn Birrell { "void", { CTF_INT_SIGNED, 0, 0 }, CTF_K_INTEGER },
5576ff6d951SJohn Birrell { "signed", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
5586ff6d951SJohn Birrell { "unsigned", { 0, 0, 32 }, CTF_K_INTEGER },
5596ff6d951SJohn Birrell { "char", { CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
5606ff6d951SJohn Birrell { "short", { CTF_INT_SIGNED, 0, 16 }, CTF_K_INTEGER },
5616ff6d951SJohn Birrell { "int", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
5626ff6d951SJohn Birrell { "long", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
5636ff6d951SJohn Birrell { "long long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
5646ff6d951SJohn Birrell { "signed char", { CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
5656ff6d951SJohn Birrell { "signed short", { CTF_INT_SIGNED, 0, 16 }, CTF_K_INTEGER },
5666ff6d951SJohn Birrell { "signed int", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
5676ff6d951SJohn Birrell { "signed long", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
5686ff6d951SJohn Birrell { "signed long long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
5696ff6d951SJohn Birrell { "unsigned char", { CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
5706ff6d951SJohn Birrell { "unsigned short", { 0, 0, 16 }, CTF_K_INTEGER },
5716ff6d951SJohn Birrell { "unsigned int", { 0, 0, 32 }, CTF_K_INTEGER },
5726ff6d951SJohn Birrell { "unsigned long", { 0, 0, 32 }, CTF_K_INTEGER },
5736ff6d951SJohn Birrell { "unsigned long long", { 0, 0, 64 }, CTF_K_INTEGER },
5746ff6d951SJohn Birrell { "_Bool", { CTF_INT_BOOL, 0, 8 }, CTF_K_INTEGER },
5756ff6d951SJohn Birrell { "float", { CTF_FP_SINGLE, 0, 32 }, CTF_K_FLOAT },
5766ff6d951SJohn Birrell { "double", { CTF_FP_DOUBLE, 0, 64 }, CTF_K_FLOAT },
5776ff6d951SJohn Birrell { "long double", { CTF_FP_LDOUBLE, 0, 128 }, CTF_K_FLOAT },
5786ff6d951SJohn Birrell { "float imaginary", { CTF_FP_IMAGRY, 0, 32 }, CTF_K_FLOAT },
5796ff6d951SJohn Birrell { "double imaginary", { CTF_FP_DIMAGRY, 0, 64 }, CTF_K_FLOAT },
5806ff6d951SJohn Birrell { "long double imaginary", { CTF_FP_LDIMAGRY, 0, 128 }, CTF_K_FLOAT },
5816ff6d951SJohn Birrell { "float complex", { CTF_FP_CPLX, 0, 64 }, CTF_K_FLOAT },
5826ff6d951SJohn Birrell { "double complex", { CTF_FP_DCPLX, 0, 128 }, CTF_K_FLOAT },
5836ff6d951SJohn Birrell { "long double complex", { CTF_FP_LDCPLX, 0, 256 }, CTF_K_FLOAT },
5846ff6d951SJohn Birrell { NULL, { 0, 0, 0 }, 0 }
5856ff6d951SJohn Birrell };
5866ff6d951SJohn Birrell 
5876ff6d951SJohn Birrell /*
5886ff6d951SJohn Birrell  * Tables of LP64 intrinsic integer and floating-point type templates to use
5896ff6d951SJohn Birrell  * to populate the dynamic "C" CTF type container.
5906ff6d951SJohn Birrell  */
5916ff6d951SJohn Birrell static const dt_intrinsic_t _dtrace_intrinsics_64[] = {
5926ff6d951SJohn Birrell { "void", { CTF_INT_SIGNED, 0, 0 }, CTF_K_INTEGER },
5936ff6d951SJohn Birrell { "signed", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
5946ff6d951SJohn Birrell { "unsigned", { 0, 0, 32 }, CTF_K_INTEGER },
5956ff6d951SJohn Birrell { "char", { CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
5966ff6d951SJohn Birrell { "short", { CTF_INT_SIGNED, 0, 16 }, CTF_K_INTEGER },
5976ff6d951SJohn Birrell { "int", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
5986ff6d951SJohn Birrell { "long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
5996ff6d951SJohn Birrell { "long long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
6006ff6d951SJohn Birrell { "signed char", { CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
6016ff6d951SJohn Birrell { "signed short", { CTF_INT_SIGNED, 0, 16 }, CTF_K_INTEGER },
6026ff6d951SJohn Birrell { "signed int", { CTF_INT_SIGNED, 0, 32 }, CTF_K_INTEGER },
6036ff6d951SJohn Birrell { "signed long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
6046ff6d951SJohn Birrell { "signed long long", { CTF_INT_SIGNED, 0, 64 }, CTF_K_INTEGER },
6056ff6d951SJohn Birrell { "unsigned char", { CTF_INT_CHAR, 0, 8 }, CTF_K_INTEGER },
6066ff6d951SJohn Birrell { "unsigned short", { 0, 0, 16 }, CTF_K_INTEGER },
6076ff6d951SJohn Birrell { "unsigned int", { 0, 0, 32 }, CTF_K_INTEGER },
6086ff6d951SJohn Birrell { "unsigned long", { 0, 0, 64 }, CTF_K_INTEGER },
6096ff6d951SJohn Birrell { "unsigned long long", { 0, 0, 64 }, CTF_K_INTEGER },
6106ff6d951SJohn Birrell { "_Bool", { CTF_INT_BOOL, 0, 8 }, CTF_K_INTEGER },
6116ff6d951SJohn Birrell { "float", { CTF_FP_SINGLE, 0, 32 }, CTF_K_FLOAT },
6126ff6d951SJohn Birrell { "double", { CTF_FP_DOUBLE, 0, 64 }, CTF_K_FLOAT },
6136ff6d951SJohn Birrell { "long double", { CTF_FP_LDOUBLE, 0, 128 }, CTF_K_FLOAT },
6146ff6d951SJohn Birrell { "float imaginary", { CTF_FP_IMAGRY, 0, 32 }, CTF_K_FLOAT },
6156ff6d951SJohn Birrell { "double imaginary", { CTF_FP_DIMAGRY, 0, 64 }, CTF_K_FLOAT },
6166ff6d951SJohn Birrell { "long double imaginary", { CTF_FP_LDIMAGRY, 0, 128 }, CTF_K_FLOAT },
6176ff6d951SJohn Birrell { "float complex", { CTF_FP_CPLX, 0, 64 }, CTF_K_FLOAT },
6186ff6d951SJohn Birrell { "double complex", { CTF_FP_DCPLX, 0, 128 }, CTF_K_FLOAT },
6196ff6d951SJohn Birrell { "long double complex", { CTF_FP_LDCPLX, 0, 256 }, CTF_K_FLOAT },
6206ff6d951SJohn Birrell { NULL, { 0, 0, 0 }, 0 }
6216ff6d951SJohn Birrell };
6226ff6d951SJohn Birrell 
6236ff6d951SJohn Birrell /*
6246ff6d951SJohn Birrell  * Tables of ILP32 typedefs to use to populate the dynamic "D" CTF container.
6256ff6d951SJohn Birrell  * These aliases ensure that D definitions can use typical <sys/types.h> names.
6266ff6d951SJohn Birrell  */
6276ff6d951SJohn Birrell static const dt_typedef_t _dtrace_typedefs_32[] = {
6286ff6d951SJohn Birrell { "char", "int8_t" },
6296ff6d951SJohn Birrell { "short", "int16_t" },
6306ff6d951SJohn Birrell { "int", "int32_t" },
6316ff6d951SJohn Birrell { "long long", "int64_t" },
6326ff6d951SJohn Birrell { "int", "intptr_t" },
6336ff6d951SJohn Birrell { "int", "ssize_t" },
6346ff6d951SJohn Birrell { "unsigned char", "uint8_t" },
6356ff6d951SJohn Birrell { "unsigned short", "uint16_t" },
6366ff6d951SJohn Birrell { "unsigned", "uint32_t" },
6376ff6d951SJohn Birrell { "unsigned long long", "uint64_t" },
6386ff6d951SJohn Birrell { "unsigned char", "uchar_t" },
6396ff6d951SJohn Birrell { "unsigned short", "ushort_t" },
6406ff6d951SJohn Birrell { "unsigned", "uint_t" },
6416ff6d951SJohn Birrell { "unsigned long", "ulong_t" },
6426ff6d951SJohn Birrell { "unsigned long long", "u_longlong_t" },
6436ff6d951SJohn Birrell { "int", "ptrdiff_t" },
6446ff6d951SJohn Birrell { "unsigned", "uintptr_t" },
6456ff6d951SJohn Birrell { "unsigned", "size_t" },
6466ff6d951SJohn Birrell { "long", "id_t" },
6476ff6d951SJohn Birrell { "long", "pid_t" },
6486ff6d951SJohn Birrell { NULL, NULL }
6496ff6d951SJohn Birrell };
6506ff6d951SJohn Birrell 
6516ff6d951SJohn Birrell /*
6526ff6d951SJohn Birrell  * Tables of LP64 typedefs to use to populate the dynamic "D" CTF container.
6536ff6d951SJohn Birrell  * These aliases ensure that D definitions can use typical <sys/types.h> names.
6546ff6d951SJohn Birrell  */
6556ff6d951SJohn Birrell static const dt_typedef_t _dtrace_typedefs_64[] = {
6566ff6d951SJohn Birrell { "char", "int8_t" },
6576ff6d951SJohn Birrell { "short", "int16_t" },
6586ff6d951SJohn Birrell { "int", "int32_t" },
6596ff6d951SJohn Birrell { "long", "int64_t" },
6606ff6d951SJohn Birrell { "long", "intptr_t" },
6616ff6d951SJohn Birrell { "long", "ssize_t" },
6626ff6d951SJohn Birrell { "unsigned char", "uint8_t" },
6636ff6d951SJohn Birrell { "unsigned short", "uint16_t" },
6646ff6d951SJohn Birrell { "unsigned", "uint32_t" },
6656ff6d951SJohn Birrell { "unsigned long", "uint64_t" },
6666ff6d951SJohn Birrell { "unsigned char", "uchar_t" },
6676ff6d951SJohn Birrell { "unsigned short", "ushort_t" },
6686ff6d951SJohn Birrell { "unsigned", "uint_t" },
6696ff6d951SJohn Birrell { "unsigned long", "ulong_t" },
6706ff6d951SJohn Birrell { "unsigned long long", "u_longlong_t" },
6716ff6d951SJohn Birrell { "long", "ptrdiff_t" },
6726ff6d951SJohn Birrell { "unsigned long", "uintptr_t" },
6736ff6d951SJohn Birrell { "unsigned long", "size_t" },
6746ff6d951SJohn Birrell { "int", "id_t" },
6756ff6d951SJohn Birrell { "int", "pid_t" },
6766ff6d951SJohn Birrell { NULL, NULL }
6776ff6d951SJohn Birrell };
6786ff6d951SJohn Birrell 
6796ff6d951SJohn Birrell /*
6806ff6d951SJohn Birrell  * Tables of ILP32 integer type templates used to populate the dtp->dt_ints[]
6816ff6d951SJohn Birrell  * cache when a new dtrace client open occurs.  Values are set by dtrace_open().
6826ff6d951SJohn Birrell  */
6836ff6d951SJohn Birrell static const dt_intdesc_t _dtrace_ints_32[] = {
6846ff6d951SJohn Birrell { "int", NULL, CTF_ERR, 0x7fffffffULL },
6856ff6d951SJohn Birrell { "unsigned int", NULL, CTF_ERR, 0xffffffffULL },
6866ff6d951SJohn Birrell { "long", NULL, CTF_ERR, 0x7fffffffULL },
6876ff6d951SJohn Birrell { "unsigned long", NULL, CTF_ERR, 0xffffffffULL },
6886ff6d951SJohn Birrell { "long long", NULL, CTF_ERR, 0x7fffffffffffffffULL },
6896ff6d951SJohn Birrell { "unsigned long long", NULL, CTF_ERR, 0xffffffffffffffffULL }
6906ff6d951SJohn Birrell };
6916ff6d951SJohn Birrell 
6926ff6d951SJohn Birrell /*
6936ff6d951SJohn Birrell  * Tables of LP64 integer type templates used to populate the dtp->dt_ints[]
6946ff6d951SJohn Birrell  * cache when a new dtrace client open occurs.  Values are set by dtrace_open().
6956ff6d951SJohn Birrell  */
6966ff6d951SJohn Birrell static const dt_intdesc_t _dtrace_ints_64[] = {
6976ff6d951SJohn Birrell { "int", NULL, CTF_ERR, 0x7fffffffULL },
6986ff6d951SJohn Birrell { "unsigned int", NULL, CTF_ERR, 0xffffffffULL },
6996ff6d951SJohn Birrell { "long", NULL, CTF_ERR, 0x7fffffffffffffffULL },
7006ff6d951SJohn Birrell { "unsigned long", NULL, CTF_ERR, 0xffffffffffffffffULL },
7016ff6d951SJohn Birrell { "long long", NULL, CTF_ERR, 0x7fffffffffffffffULL },
7026ff6d951SJohn Birrell { "unsigned long long", NULL, CTF_ERR, 0xffffffffffffffffULL }
7036ff6d951SJohn Birrell };
7046ff6d951SJohn Birrell 
7056ff6d951SJohn Birrell /*
7066ff6d951SJohn Birrell  * Table of macro variable templates used to populate the macro identifier hash
7076ff6d951SJohn Birrell  * when a new dtrace client open occurs.  Values are set by dtrace_update().
7086ff6d951SJohn Birrell  */
7096ff6d951SJohn Birrell static const dt_ident_t _dtrace_macros[] = {
7106ff6d951SJohn Birrell { "egid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
7116ff6d951SJohn Birrell { "euid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
7126ff6d951SJohn Birrell { "gid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
7136ff6d951SJohn Birrell { "pid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
7146ff6d951SJohn Birrell { "pgid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
7156ff6d951SJohn Birrell { "ppid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
7166ff6d951SJohn Birrell { "projid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
7176ff6d951SJohn Birrell { "sid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
7186ff6d951SJohn Birrell { "taskid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
7196ff6d951SJohn Birrell { "target", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
7206ff6d951SJohn Birrell { "uid", DT_IDENT_SCALAR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0 },
7216ff6d951SJohn Birrell { NULL, 0, 0, 0, { 0, 0, 0 }, 0 }
7226ff6d951SJohn Birrell };
7236ff6d951SJohn Birrell 
7246ff6d951SJohn Birrell /*
7256ff6d951SJohn Birrell  * Hard-wired definition string to be compiled and cached every time a new
7266ff6d951SJohn Birrell  * DTrace library handle is initialized.  This string should only be used to
7276ff6d951SJohn Birrell  * contain definitions that should be present regardless of DTRACE_O_NOLIBS.
7286ff6d951SJohn Birrell  */
7296ff6d951SJohn Birrell static const char _dtrace_hardwire[] = "\
7306ff6d951SJohn Birrell inline long NULL = 0; \n\
7316ff6d951SJohn Birrell #pragma D binding \"1.0\" NULL\n\
7326ff6d951SJohn Birrell ";
7336ff6d951SJohn Birrell 
7346ff6d951SJohn Birrell /*
7356ff6d951SJohn Birrell  * Default DTrace configuration to use when opening libdtrace DTRACE_O_NODEV.
7366ff6d951SJohn Birrell  * If DTRACE_O_NODEV is not set, we load the configuration from the kernel.
7376ff6d951SJohn Birrell  * The use of CTF_MODEL_NATIVE is more subtle than it might appear: we are
7386ff6d951SJohn Birrell  * relying on the fact that when running dtrace(1M), isaexec will invoke the
7396ff6d951SJohn Birrell  * binary with the same bitness as the kernel, which is what we want by default
7406ff6d951SJohn Birrell  * when generating our DIF.  The user can override the choice using oflags.
7416ff6d951SJohn Birrell  */
7426ff6d951SJohn Birrell static const dtrace_conf_t _dtrace_conf = {
7436ff6d951SJohn Birrell 	DIF_VERSION,		/* dtc_difversion */
7446ff6d951SJohn Birrell 	DIF_DIR_NREGS,		/* dtc_difintregs */
7456ff6d951SJohn Birrell 	DIF_DTR_NREGS,		/* dtc_diftupregs */
7466ff6d951SJohn Birrell 	CTF_MODEL_NATIVE	/* dtc_ctfmodel */
7476ff6d951SJohn Birrell };
7486ff6d951SJohn Birrell 
7496ff6d951SJohn Birrell const dtrace_attribute_t _dtrace_maxattr = {
7506ff6d951SJohn Birrell 	DTRACE_STABILITY_MAX,
7516ff6d951SJohn Birrell 	DTRACE_STABILITY_MAX,
7526ff6d951SJohn Birrell 	DTRACE_CLASS_MAX
7536ff6d951SJohn Birrell };
7546ff6d951SJohn Birrell 
7556ff6d951SJohn Birrell const dtrace_attribute_t _dtrace_defattr = {
7566ff6d951SJohn Birrell 	DTRACE_STABILITY_STABLE,
7576ff6d951SJohn Birrell 	DTRACE_STABILITY_STABLE,
7586ff6d951SJohn Birrell 	DTRACE_CLASS_COMMON
7596ff6d951SJohn Birrell };
7606ff6d951SJohn Birrell 
7616ff6d951SJohn Birrell const dtrace_attribute_t _dtrace_symattr = {
7626ff6d951SJohn Birrell 	DTRACE_STABILITY_PRIVATE,
7636ff6d951SJohn Birrell 	DTRACE_STABILITY_PRIVATE,
7646ff6d951SJohn Birrell 	DTRACE_CLASS_UNKNOWN
7656ff6d951SJohn Birrell };
7666ff6d951SJohn Birrell 
7676ff6d951SJohn Birrell const dtrace_attribute_t _dtrace_typattr = {
7686ff6d951SJohn Birrell 	DTRACE_STABILITY_PRIVATE,
7696ff6d951SJohn Birrell 	DTRACE_STABILITY_PRIVATE,
7706ff6d951SJohn Birrell 	DTRACE_CLASS_UNKNOWN
7716ff6d951SJohn Birrell };
7726ff6d951SJohn Birrell 
7736ff6d951SJohn Birrell const dtrace_attribute_t _dtrace_prvattr = {
7746ff6d951SJohn Birrell 	DTRACE_STABILITY_PRIVATE,
7756ff6d951SJohn Birrell 	DTRACE_STABILITY_PRIVATE,
7766ff6d951SJohn Birrell 	DTRACE_CLASS_UNKNOWN
7776ff6d951SJohn Birrell };
7786ff6d951SJohn Birrell 
7796ff6d951SJohn Birrell const dtrace_pattr_t _dtrace_prvdesc = {
7806ff6d951SJohn Birrell { DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_COMMON },
7816ff6d951SJohn Birrell { DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_COMMON },
7826ff6d951SJohn Birrell { DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_COMMON },
7836ff6d951SJohn Birrell { DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_COMMON },
7846ff6d951SJohn Birrell { DTRACE_STABILITY_UNSTABLE, DTRACE_STABILITY_UNSTABLE, DTRACE_CLASS_COMMON },
7856ff6d951SJohn Birrell };
7866ff6d951SJohn Birrell 
787bc96366cSSteven Hartland #ifdef illumos
7886ff6d951SJohn Birrell const char *_dtrace_defcpp = "/usr/ccs/lib/cpp"; /* default cpp(1) to invoke */
7896ff6d951SJohn Birrell const char *_dtrace_defld = "/usr/ccs/bin/ld";   /* default ld(1) to invoke */
790fb24b944SJohn Birrell #else
791fb24b944SJohn Birrell const char *_dtrace_defcpp = "cpp"; /* default cpp(1) to invoke */
792fb24b944SJohn Birrell const char *_dtrace_defld = "ld";   /* default ld(1) to invoke */
79303a5f9f0SMark Johnston const char *_dtrace_defobjcopy = "objcopy"; /* default objcopy(1) to invoke */
794fb24b944SJohn Birrell #endif
7956ff6d951SJohn Birrell 
7966ff6d951SJohn Birrell const char *_dtrace_libdir = "/usr/lib/dtrace"; /* default library directory */
797bc96366cSSteven Hartland #ifdef illumos
7986ff6d951SJohn Birrell const char *_dtrace_provdir = "/dev/dtrace/provider"; /* provider directory */
799fb24b944SJohn Birrell #else
8000fff3baaSMark Johnston const char *_dtrace_libdir32 = "/usr/lib32/dtrace";
801fb24b944SJohn Birrell const char *_dtrace_provdir = "/dev/dtrace"; /* provider directory */
802fb24b944SJohn Birrell #endif
8036ff6d951SJohn Birrell 
8046ff6d951SJohn Birrell int _dtrace_strbuckets = 211;	/* default number of hash buckets (prime) */
8056ff6d951SJohn Birrell int _dtrace_intbuckets = 256;	/* default number of integer buckets (Pof2) */
8066ff6d951SJohn Birrell uint_t _dtrace_strsize = 256;	/* default size of string intrinsic type */
8076ff6d951SJohn Birrell uint_t _dtrace_stkindent = 14;	/* default whitespace indent for stack/ustack */
8086ff6d951SJohn Birrell uint_t _dtrace_pidbuckets = 64; /* default number of pid hash buckets */
8096ff6d951SJohn Birrell uint_t _dtrace_pidlrulim = 8;	/* default number of pid handles to cache */
8106ff6d951SJohn Birrell size_t _dtrace_bufsize = 512;	/* default dt_buf_create() size */
8116ff6d951SJohn Birrell int _dtrace_argmax = 32;	/* default maximum number of probe arguments */
8126ff6d951SJohn Birrell 
8136ff6d951SJohn Birrell int _dtrace_debug = 0;		/* debug messages enabled (off) */
8146ff6d951SJohn Birrell const char *const _dtrace_version = DT_VERS_STRING; /* API version string */
8156ff6d951SJohn Birrell int _dtrace_rdvers = RD_VERSION; /* rtld_db feature version */
8166ff6d951SJohn Birrell 
8176ff6d951SJohn Birrell typedef struct dt_fdlist {
8186ff6d951SJohn Birrell 	int *df_fds;		/* array of provider driver file descriptors */
8196ff6d951SJohn Birrell 	uint_t df_ents;		/* number of valid elements in df_fds[] */
8206ff6d951SJohn Birrell 	uint_t df_size;		/* size of df_fds[] */
8216ff6d951SJohn Birrell } dt_fdlist_t;
8226ff6d951SJohn Birrell 
823bc96366cSSteven Hartland #ifdef illumos
8246ff6d951SJohn Birrell #pragma init(_dtrace_init)
825fb24b944SJohn Birrell #else
826fb24b944SJohn Birrell void _dtrace_init(void) __attribute__ ((constructor));
827fb24b944SJohn Birrell #endif
8286ff6d951SJohn Birrell void
8296ff6d951SJohn Birrell _dtrace_init(void)
8306ff6d951SJohn Birrell {
8316ff6d951SJohn Birrell 	_dtrace_debug = getenv("DTRACE_DEBUG") != NULL;
8326ff6d951SJohn Birrell 
8336ff6d951SJohn Birrell 	for (; _dtrace_rdvers > 0; _dtrace_rdvers--) {
8346ff6d951SJohn Birrell 		if (rd_init(_dtrace_rdvers) == RD_OK)
8356ff6d951SJohn Birrell 			break;
8366ff6d951SJohn Birrell 	}
837fb24b944SJohn Birrell #if defined(__i386__)
838fb24b944SJohn Birrell 	/* make long doubles 64 bits -sson */
839fb24b944SJohn Birrell 	(void) fpsetprec(FP_PE);
840fb24b944SJohn Birrell #endif
8416ff6d951SJohn Birrell }
8426ff6d951SJohn Birrell 
8436ff6d951SJohn Birrell static dtrace_hdl_t *
8446ff6d951SJohn Birrell set_open_errno(dtrace_hdl_t *dtp, int *errp, int err)
8456ff6d951SJohn Birrell {
8466ff6d951SJohn Birrell 	if (dtp != NULL)
8476ff6d951SJohn Birrell 		dtrace_close(dtp);
8486ff6d951SJohn Birrell 	if (errp != NULL)
8496ff6d951SJohn Birrell 		*errp = err;
8506ff6d951SJohn Birrell 	return (NULL);
8516ff6d951SJohn Birrell }
8526ff6d951SJohn Birrell 
8536ff6d951SJohn Birrell static void
8546ff6d951SJohn Birrell dt_provmod_open(dt_provmod_t **provmod, dt_fdlist_t *dfp)
8556ff6d951SJohn Birrell {
8566ff6d951SJohn Birrell 	dt_provmod_t *prov;
8576ff6d951SJohn Birrell 	char path[PATH_MAX];
858fb24b944SJohn Birrell 	int fd;
859bc96366cSSteven Hartland #ifdef illumos
8606ff6d951SJohn Birrell 	struct dirent *dp, *ep;
8616ff6d951SJohn Birrell 	DIR *dirp;
8626ff6d951SJohn Birrell 
8636ff6d951SJohn Birrell 	if ((dirp = opendir(_dtrace_provdir)) == NULL)
8646ff6d951SJohn Birrell 		return; /* failed to open directory; just skip it */
8656ff6d951SJohn Birrell 
8666ff6d951SJohn Birrell 	ep = alloca(sizeof (struct dirent) + PATH_MAX + 1);
8676ff6d951SJohn Birrell 	bzero(ep, sizeof (struct dirent) + PATH_MAX + 1);
8686ff6d951SJohn Birrell 
8696ff6d951SJohn Birrell 	while (readdir_r(dirp, ep, &dp) == 0 && dp != NULL) {
8706ff6d951SJohn Birrell 		if (dp->d_name[0] == '.')
8716ff6d951SJohn Birrell 			continue; /* skip "." and ".." */
8726ff6d951SJohn Birrell 
8736ff6d951SJohn Birrell 		if (dfp->df_ents == dfp->df_size) {
8746ff6d951SJohn Birrell 			uint_t size = dfp->df_size ? dfp->df_size * 2 : 16;
8756ff6d951SJohn Birrell 			int *fds = realloc(dfp->df_fds, size * sizeof (int));
8766ff6d951SJohn Birrell 
8776ff6d951SJohn Birrell 			if (fds == NULL)
8786ff6d951SJohn Birrell 				break; /* skip the rest of this directory */
8796ff6d951SJohn Birrell 
8806ff6d951SJohn Birrell 			dfp->df_fds = fds;
8816ff6d951SJohn Birrell 			dfp->df_size = size;
8826ff6d951SJohn Birrell 		}
8836ff6d951SJohn Birrell 
8846ff6d951SJohn Birrell 		(void) snprintf(path, sizeof (path), "%s/%s",
8856ff6d951SJohn Birrell 		    _dtrace_provdir, dp->d_name);
8866ff6d951SJohn Birrell 
8876ff6d951SJohn Birrell 		if ((fd = open(path, O_RDONLY)) == -1)
8886ff6d951SJohn Birrell 			continue; /* failed to open driver; just skip it */
8896ff6d951SJohn Birrell 
8906ff6d951SJohn Birrell 		if (((prov = malloc(sizeof (dt_provmod_t))) == NULL) ||
8916ff6d951SJohn Birrell 		    (prov->dp_name = malloc(strlen(dp->d_name) + 1)) == NULL) {
8926ff6d951SJohn Birrell 			free(prov);
8936ff6d951SJohn Birrell 			(void) close(fd);
8946ff6d951SJohn Birrell 			break;
8956ff6d951SJohn Birrell 		}
8966ff6d951SJohn Birrell 
8976ff6d951SJohn Birrell 		(void) strcpy(prov->dp_name, dp->d_name);
8986ff6d951SJohn Birrell 		prov->dp_next = *provmod;
8996ff6d951SJohn Birrell 		*provmod = prov;
9006ff6d951SJohn Birrell 
9016ff6d951SJohn Birrell 		dt_dprintf("opened provider %s\n", dp->d_name);
9026ff6d951SJohn Birrell 		dfp->df_fds[dfp->df_ents++] = fd;
9036ff6d951SJohn Birrell 	}
9046ff6d951SJohn Birrell 
9056ff6d951SJohn Birrell 	(void) closedir(dirp);
906bc96366cSSteven Hartland #else	/* !illumos */
907fb24b944SJohn Birrell 	char	*p;
908fb24b944SJohn Birrell 	char	*p1;
909fb24b944SJohn Birrell 	char	*p_providers = NULL;
910fb24b944SJohn Birrell 	int	error;
911fb24b944SJohn Birrell 	size_t	len = 0;
912fb24b944SJohn Birrell 
913fb24b944SJohn Birrell 	/*
914fb24b944SJohn Birrell 	 * Loop to allocate/reallocate memory for the string of provider
915fb24b944SJohn Birrell 	 * names and retry:
916fb24b944SJohn Birrell 	 */
917fb24b944SJohn Birrell 	while(1) {
918fb24b944SJohn Birrell 		/*
919fb24b944SJohn Birrell 		 * The first time around, get the string length. The next time,
920fb24b944SJohn Birrell 		 * hopefully we've allocated enough memory.
921fb24b944SJohn Birrell 		 */
922fb24b944SJohn Birrell 		error = sysctlbyname("debug.dtrace.providers",p_providers,&len,NULL,0);
923fb24b944SJohn Birrell 		if (len == 0)
924fb24b944SJohn Birrell 			/* No providers? That's strange. Where's dtrace? */
925fb24b944SJohn Birrell 			break;
926fb24b944SJohn Birrell 		else if (error == 0 && p_providers == NULL) {
927fb24b944SJohn Birrell 			/*
928fb24b944SJohn Birrell 			 * Allocate the initial memory which should be enough
929fb24b944SJohn Birrell 			 * unless another provider loads before we have
930fb24b944SJohn Birrell 			 * time to go back and get the string.
931fb24b944SJohn Birrell 			 */
932fb24b944SJohn Birrell 			if ((p_providers = malloc(len)) == NULL)
933fb24b944SJohn Birrell 				/* How do we report errors here? */
934fb24b944SJohn Birrell 				return;
935fb24b944SJohn Birrell 		} else if (error == -1 && errno == ENOMEM) {
936fb24b944SJohn Birrell 			/*
937fb24b944SJohn Birrell 			 * The current buffer isn't large enough, so
938fb24b944SJohn Birrell 			 * reallocate it. We normally won't need to do this
939fb24b944SJohn Birrell 			 * because providers aren't being loaded all the time.
940fb24b944SJohn Birrell 			 */
941d935f34bSMark Johnston 		        if ((p = realloc(p_providers,len)) == NULL) {
942d935f34bSMark Johnston 			        free(p_providers);
943fb24b944SJohn Birrell 				/* How do we report errors here? */
944fb24b944SJohn Birrell 				return;
945d935f34bSMark Johnston 			}
946fb24b944SJohn Birrell 			p_providers = p;
947fb24b944SJohn Birrell 		} else
948fb24b944SJohn Birrell 			break;
949fb24b944SJohn Birrell 	}
950fb24b944SJohn Birrell 
951fb24b944SJohn Birrell 	/* Check if we got a string of provider names: */
952fb24b944SJohn Birrell 	if (error == 0 && len > 0 && p_providers != NULL) {
953fb24b944SJohn Birrell 		p = p_providers;
954fb24b944SJohn Birrell 
955fb24b944SJohn Birrell 		/*
956fb24b944SJohn Birrell 		 * Parse the string containing the space separated
957fb24b944SJohn Birrell 		 * provider names.
958fb24b944SJohn Birrell 		 */
959fb24b944SJohn Birrell 		while ((p1 = strsep(&p," ")) != NULL) {
960fb24b944SJohn Birrell 			if (dfp->df_ents == dfp->df_size) {
961fb24b944SJohn Birrell 				uint_t size = dfp->df_size ? dfp->df_size * 2 : 16;
962fb24b944SJohn Birrell 				int *fds = realloc(dfp->df_fds, size * sizeof (int));
963fb24b944SJohn Birrell 
964fb24b944SJohn Birrell 				if (fds == NULL)
965fb24b944SJohn Birrell 					break;
966fb24b944SJohn Birrell 
967fb24b944SJohn Birrell 				dfp->df_fds = fds;
968fb24b944SJohn Birrell 				dfp->df_size = size;
969fb24b944SJohn Birrell 			}
970fb24b944SJohn Birrell 
971fb24b944SJohn Birrell 			(void) snprintf(path, sizeof (path), "/dev/dtrace/%s", p1);
972fb24b944SJohn Birrell 
973afd2f355SMark Johnston 			if ((fd = open(path, O_RDONLY | O_CLOEXEC)) == -1)
974fb24b944SJohn Birrell 				continue; /* failed to open driver; just skip it */
975fb24b944SJohn Birrell 
976fb24b944SJohn Birrell 			if (((prov = malloc(sizeof (dt_provmod_t))) == NULL) ||
977fb24b944SJohn Birrell 			    (prov->dp_name = malloc(strlen(p1) + 1)) == NULL) {
978fb24b944SJohn Birrell 				free(prov);
979fb24b944SJohn Birrell 				(void) close(fd);
980fb24b944SJohn Birrell 				break;
981fb24b944SJohn Birrell 			}
982fb24b944SJohn Birrell 
983fb24b944SJohn Birrell 			(void) strcpy(prov->dp_name, p1);
984fb24b944SJohn Birrell 			prov->dp_next = *provmod;
985fb24b944SJohn Birrell 			*provmod = prov;
986fb24b944SJohn Birrell 
987fb24b944SJohn Birrell 			dt_dprintf("opened provider %s\n", p1);
988fb24b944SJohn Birrell 			dfp->df_fds[dfp->df_ents++] = fd;
989fb24b944SJohn Birrell 		}
990fb24b944SJohn Birrell 	}
991fb24b944SJohn Birrell 	if (p_providers != NULL)
992fb24b944SJohn Birrell 		free(p_providers);
993bc96366cSSteven Hartland #endif	/* illumos */
9946ff6d951SJohn Birrell }
9956ff6d951SJohn Birrell 
9966ff6d951SJohn Birrell static void
9976ff6d951SJohn Birrell dt_provmod_destroy(dt_provmod_t **provmod)
9986ff6d951SJohn Birrell {
9996ff6d951SJohn Birrell 	dt_provmod_t *next, *current;
10006ff6d951SJohn Birrell 
10016ff6d951SJohn Birrell 	for (current = *provmod; current != NULL; current = next) {
10026ff6d951SJohn Birrell 		next = current->dp_next;
10036ff6d951SJohn Birrell 		free(current->dp_name);
10046ff6d951SJohn Birrell 		free(current);
10056ff6d951SJohn Birrell 	}
10066ff6d951SJohn Birrell 
10076ff6d951SJohn Birrell 	*provmod = NULL;
10086ff6d951SJohn Birrell }
10096ff6d951SJohn Birrell 
1010bc96366cSSteven Hartland #ifdef illumos
10116ff6d951SJohn Birrell static const char *
10126ff6d951SJohn Birrell dt_get_sysinfo(int cmd, char *buf, size_t len)
10136ff6d951SJohn Birrell {
10146ff6d951SJohn Birrell 	ssize_t rv = sysinfo(cmd, buf, len);
10156ff6d951SJohn Birrell 	char *p = buf;
10166ff6d951SJohn Birrell 
10176ff6d951SJohn Birrell 	if (rv < 0 || rv > len)
10186ff6d951SJohn Birrell 		(void) snprintf(buf, len, "%s", "Unknown");
10196ff6d951SJohn Birrell 
10206ff6d951SJohn Birrell 	while ((p = strchr(p, '.')) != NULL)
10216ff6d951SJohn Birrell 		*p++ = '_';
10226ff6d951SJohn Birrell 
10236ff6d951SJohn Birrell 	return (buf);
10246ff6d951SJohn Birrell }
1025fb24b944SJohn Birrell #endif
10266ff6d951SJohn Birrell 
10276ff6d951SJohn Birrell static dtrace_hdl_t *
10286ff6d951SJohn Birrell dt_vopen(int version, int flags, int *errp,
10296ff6d951SJohn Birrell     const dtrace_vector_t *vector, void *arg)
10306ff6d951SJohn Birrell {
10316ff6d951SJohn Birrell 	dtrace_hdl_t *dtp = NULL;
10326ff6d951SJohn Birrell 	int dtfd = -1, ftfd = -1, fterr = 0;
10336ff6d951SJohn Birrell 	dtrace_prog_t *pgp;
10346ff6d951SJohn Birrell 	dt_module_t *dmp;
10356ff6d951SJohn Birrell 	dt_provmod_t *provmod = NULL;
10366ff6d951SJohn Birrell 	int i, err;
10376ff6d951SJohn Birrell 	struct rlimit rl;
10386ff6d951SJohn Birrell 
10396ff6d951SJohn Birrell 	const dt_intrinsic_t *dinp;
10406ff6d951SJohn Birrell 	const dt_typedef_t *dtyp;
10416ff6d951SJohn Birrell 	const dt_ident_t *idp;
10426ff6d951SJohn Birrell 
10436ff6d951SJohn Birrell 	dtrace_typeinfo_t dtt;
10446ff6d951SJohn Birrell 	ctf_funcinfo_t ctc;
10456ff6d951SJohn Birrell 	ctf_arinfo_t ctr;
10466ff6d951SJohn Birrell 
10476ff6d951SJohn Birrell 	dt_fdlist_t df = { NULL, 0, 0 };
10486ff6d951SJohn Birrell 
10496ff6d951SJohn Birrell 	char isadef[32], utsdef[32];
10506ff6d951SJohn Birrell 	char s1[64], s2[64];
10516ff6d951SJohn Birrell 
10526ff6d951SJohn Birrell 	if (version <= 0)
10536ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EINVAL));
10546ff6d951SJohn Birrell 
10556ff6d951SJohn Birrell 	if (version > DTRACE_VERSION)
10566ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_VERSION));
10576ff6d951SJohn Birrell 
10586ff6d951SJohn Birrell 	if (version < DTRACE_VERSION) {
10596ff6d951SJohn Birrell 		/*
10606ff6d951SJohn Birrell 		 * Currently, increasing the library version number is used to
10616ff6d951SJohn Birrell 		 * denote a binary incompatible change.  That is, a consumer
10626ff6d951SJohn Birrell 		 * of the library cannot run on a version of the library with
10636ff6d951SJohn Birrell 		 * a higher DTRACE_VERSION number than the consumer compiled
10646ff6d951SJohn Birrell 		 * against.  Once the library API has been committed to,
10656ff6d951SJohn Birrell 		 * backwards binary compatibility will be required; at that
10666ff6d951SJohn Birrell 		 * time, this check should change to return EDT_OVERSION only
10676ff6d951SJohn Birrell 		 * if the specified version number is less than the version
10686ff6d951SJohn Birrell 		 * number at the time of interface commitment.
10696ff6d951SJohn Birrell 		 */
10706ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_OVERSION));
10716ff6d951SJohn Birrell 	}
10726ff6d951SJohn Birrell 
10736ff6d951SJohn Birrell 	if (flags & ~DTRACE_O_MASK)
10746ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EINVAL));
10756ff6d951SJohn Birrell 
1076*096a5c6cSMark Johnston 	switch (flags & DTRACE_O_MODEL_MASK) {
1077*096a5c6cSMark Johnston 	case 0: /* native model */
1078*096a5c6cSMark Johnston 	case DTRACE_O_ILP32:
1079*096a5c6cSMark Johnston 	case DTRACE_O_LP64:
1080*096a5c6cSMark Johnston 		break;
1081*096a5c6cSMark Johnston 	default:
10826ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EINVAL));
1083*096a5c6cSMark Johnston 	}
10846ff6d951SJohn Birrell 
10856ff6d951SJohn Birrell 	if (vector == NULL && arg != NULL)
10866ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EINVAL));
10876ff6d951SJohn Birrell 
10886ff6d951SJohn Birrell 	if (elf_version(EV_CURRENT) == EV_NONE)
10896ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_ELFVERSION));
10906ff6d951SJohn Birrell 
10916ff6d951SJohn Birrell 	if (vector != NULL || (flags & DTRACE_O_NODEV))
10926ff6d951SJohn Birrell 		goto alloc; /* do not attempt to open dtrace device */
10936ff6d951SJohn Birrell 
10946ff6d951SJohn Birrell 	/*
10956ff6d951SJohn Birrell 	 * Before we get going, crank our limit on file descriptors up to the
10966ff6d951SJohn Birrell 	 * hard limit.  This is to allow for the fact that libproc keeps file
10976ff6d951SJohn Birrell 	 * descriptors to objects open for the lifetime of the proc handle;
10986ff6d951SJohn Birrell 	 * without raising our hard limit, we would have an acceptably small
10996ff6d951SJohn Birrell 	 * bound on the number of processes that we could concurrently
11006ff6d951SJohn Birrell 	 * instrument with the pid provider.
11016ff6d951SJohn Birrell 	 */
11026ff6d951SJohn Birrell 	if (getrlimit(RLIMIT_NOFILE, &rl) == 0) {
11036ff6d951SJohn Birrell 		rl.rlim_cur = rl.rlim_max;
11046ff6d951SJohn Birrell 		(void) setrlimit(RLIMIT_NOFILE, &rl);
11056ff6d951SJohn Birrell 	}
11066ff6d951SJohn Birrell 
11076ff6d951SJohn Birrell 	/*
11086ff6d951SJohn Birrell 	 * Get the device path of each of the providers.  We hold them open
11096ff6d951SJohn Birrell 	 * in the df.df_fds list until we open the DTrace driver itself,
11106ff6d951SJohn Birrell 	 * allowing us to see all of the probes provided on this system.  Once
11116ff6d951SJohn Birrell 	 * we have the DTrace driver open, we can safely close all the providers
11126ff6d951SJohn Birrell 	 * now that they have registered with the framework.
11136ff6d951SJohn Birrell 	 */
11146ff6d951SJohn Birrell 	dt_provmod_open(&provmod, &df);
11156ff6d951SJohn Birrell 
1116afd2f355SMark Johnston 	dtfd = open("/dev/dtrace/dtrace", O_RDWR | O_CLOEXEC);
1117d8f743dcSMark Johnston 	err = dtfd == -1 ? errno : 0; /* save errno from opening dtfd */
1118f6ddb56aSRui Paulo #if defined(__FreeBSD__)
1119f6ddb56aSRui Paulo 	/*
1120f6ddb56aSRui Paulo 	 * Automatically load the 'dtraceall' module if we couldn't open the
1121f6ddb56aSRui Paulo 	 * char device.
1122f6ddb56aSRui Paulo 	 */
1123f6ddb56aSRui Paulo 	if (err == ENOENT && modfind("dtraceall") < 0) {
1124f6ddb56aSRui Paulo 		kldload("dtraceall"); /* ignore the error */
1125da81cc60SAndrew Gallatin #if __SIZEOF_LONG__ == 8
1126da81cc60SAndrew Gallatin 		if (modfind("linux64elf") >= 0)
1127da81cc60SAndrew Gallatin 			kldload("systrace_linux");
1128da81cc60SAndrew Gallatin 		if (modfind("linuxelf") >= 0)
1129da81cc60SAndrew Gallatin 			kldload("systrace_linux32");
1130da81cc60SAndrew Gallatin #else
1131ecdd0b48SKristof Provost 		if (modfind("linuxelf") >= 0)
1132da81cc60SAndrew Gallatin 			kldload("systrace_linux");
1133da81cc60SAndrew Gallatin #endif
1134b934b564SMark Johnston 		dtfd = open("/dev/dtrace/dtrace", O_RDWR | O_CLOEXEC);
1135f6ddb56aSRui Paulo 		err = errno;
1136f6ddb56aSRui Paulo 	}
1137f6ddb56aSRui Paulo #endif
1138bc96366cSSteven Hartland #ifdef illumos
11396ff6d951SJohn Birrell 	ftfd = open("/dev/dtrace/provider/fasttrap", O_RDWR);
1140fb24b944SJohn Birrell #else
1141afd2f355SMark Johnston 	ftfd = open("/dev/dtrace/fasttrap", O_RDWR | O_CLOEXEC);
1142fb24b944SJohn Birrell #endif
11436ff6d951SJohn Birrell 	fterr = ftfd == -1 ? errno : 0; /* save errno from open ftfd */
11446ff6d951SJohn Birrell 
11456ff6d951SJohn Birrell 	while (df.df_ents-- != 0)
11466ff6d951SJohn Birrell 		(void) close(df.df_fds[df.df_ents]);
11476ff6d951SJohn Birrell 
11486ff6d951SJohn Birrell 	free(df.df_fds);
11496ff6d951SJohn Birrell 
11506ff6d951SJohn Birrell 	/*
11516ff6d951SJohn Birrell 	 * If we failed to open the dtrace device, fail dtrace_open().
11526ff6d951SJohn Birrell 	 * We convert some kernel errnos to custom libdtrace errnos to
11536ff6d951SJohn Birrell 	 * improve the resulting message from the usual strerror().
11546ff6d951SJohn Birrell 	 */
11556ff6d951SJohn Birrell 	if (dtfd == -1) {
11566ff6d951SJohn Birrell 		dt_provmod_destroy(&provmod);
11576ff6d951SJohn Birrell 		switch (err) {
11586ff6d951SJohn Birrell 		case ENOENT:
11596ff6d951SJohn Birrell 			err = EDT_NOENT;
11606ff6d951SJohn Birrell 			break;
11616ff6d951SJohn Birrell 		case EBUSY:
11626ff6d951SJohn Birrell 			err = EDT_BUSY;
11636ff6d951SJohn Birrell 			break;
11646ff6d951SJohn Birrell 		case EACCES:
11656ff6d951SJohn Birrell 			err = EDT_ACCESS;
11666ff6d951SJohn Birrell 			break;
11676ff6d951SJohn Birrell 		}
11686ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, err));
11696ff6d951SJohn Birrell 	}
11706ff6d951SJohn Birrell 
11716ff6d951SJohn Birrell alloc:
1172d935f34bSMark Johnston 	if ((dtp = malloc(sizeof (dtrace_hdl_t))) == NULL) {
1173d935f34bSMark Johnston 	        dt_provmod_destroy(&provmod);
11746ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_NOMEM));
1175d935f34bSMark Johnston 	}
11766ff6d951SJohn Birrell 
11776ff6d951SJohn Birrell 	bzero(dtp, sizeof (dtrace_hdl_t));
11786ff6d951SJohn Birrell 	dtp->dt_oflags = flags;
1179bc96366cSSteven Hartland #ifdef illumos
11806ff6d951SJohn Birrell 	dtp->dt_prcmode = DT_PROC_STOP_PREINIT;
11810f2bd1e8SRui Paulo #else
1182f0736f4cSMark Johnston 	dtp->dt_prcmode = DT_PROC_STOP_POSTINIT;
11830f2bd1e8SRui Paulo #endif
11846ff6d951SJohn Birrell 	dtp->dt_linkmode = DT_LINK_KERNEL;
11856ff6d951SJohn Birrell 	dtp->dt_linktype = DT_LTYP_ELF;
11866ff6d951SJohn Birrell 	dtp->dt_xlatemode = DT_XL_STATIC;
11876ff6d951SJohn Birrell 	dtp->dt_stdcmode = DT_STDC_XA;
1188a43f0be9SRui Paulo 	dtp->dt_encoding = DT_ENCODING_UNSET;
11896ff6d951SJohn Birrell 	dtp->dt_version = version;
11906ff6d951SJohn Birrell 	dtp->dt_fd = dtfd;
11916ff6d951SJohn Birrell 	dtp->dt_ftfd = ftfd;
11922179a159SChristos Margiolis 	dtp->dt_kinstfd = -1;
11936ff6d951SJohn Birrell 	dtp->dt_fterr = fterr;
11946ff6d951SJohn Birrell 	dtp->dt_cdefs_fd = -1;
11956ff6d951SJohn Birrell 	dtp->dt_ddefs_fd = -1;
1196bc96366cSSteven Hartland #ifdef illumos
11976ff6d951SJohn Birrell 	dtp->dt_stdout_fd = -1;
1198fb24b944SJohn Birrell #else
1199fb24b944SJohn Birrell 	dtp->dt_freopen_fp = NULL;
1200fb24b944SJohn Birrell #endif
12016ff6d951SJohn Birrell 	dtp->dt_modbuckets = _dtrace_strbuckets;
12026ff6d951SJohn Birrell 	dtp->dt_mods = calloc(dtp->dt_modbuckets, sizeof (dt_module_t *));
12038436cb81SMark Johnston #ifdef __FreeBSD__
12048436cb81SMark Johnston 	dtp->dt_kmods = calloc(dtp->dt_modbuckets, sizeof (dt_module_t *));
12058436cb81SMark Johnston #endif
12066ff6d951SJohn Birrell 	dtp->dt_provbuckets = _dtrace_strbuckets;
12076ff6d951SJohn Birrell 	dtp->dt_provs = calloc(dtp->dt_provbuckets, sizeof (dt_provider_t *));
120804006780SMark Johnston 	dt_proc_init(dtp);
12096ff6d951SJohn Birrell 	dtp->dt_vmax = DT_VERS_LATEST;
12106ff6d951SJohn Birrell 	dtp->dt_cpp_path = strdup(_dtrace_defcpp);
12116ff6d951SJohn Birrell 	dtp->dt_cpp_argv = malloc(sizeof (char *));
12126ff6d951SJohn Birrell 	dtp->dt_cpp_argc = 1;
12136ff6d951SJohn Birrell 	dtp->dt_cpp_args = 1;
12146ff6d951SJohn Birrell 	dtp->dt_ld_path = strdup(_dtrace_defld);
121503a5f9f0SMark Johnston #ifdef __FreeBSD__
121603a5f9f0SMark Johnston 	dtp->dt_objcopy_path = strdup(_dtrace_defobjcopy);
121703a5f9f0SMark Johnston #endif
12186ff6d951SJohn Birrell 	dtp->dt_provmod = provmod;
12196ff6d951SJohn Birrell 	dtp->dt_vector = vector;
12206ff6d951SJohn Birrell 	dtp->dt_varg = arg;
12216ff6d951SJohn Birrell 	dt_dof_init(dtp);
12226ff6d951SJohn Birrell 	(void) uname(&dtp->dt_uts);
12236ff6d951SJohn Birrell 
12246ff6d951SJohn Birrell 	if (dtp->dt_mods == NULL || dtp->dt_provs == NULL ||
122504006780SMark Johnston 	    dtp->dt_procs == NULL || dtp->dt_proc_env == NULL ||
122604006780SMark Johnston 	    dtp->dt_ld_path == NULL || dtp->dt_cpp_path == NULL ||
122703a5f9f0SMark Johnston #ifdef __FreeBSD__
12288436cb81SMark Johnston 	    dtp->dt_kmods == NULL ||
122903a5f9f0SMark Johnston 	    dtp->dt_objcopy_path == NULL ||
123003a5f9f0SMark Johnston #endif
123104006780SMark Johnston 	    dtp->dt_cpp_argv == NULL)
12326ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_NOMEM));
12336ff6d951SJohn Birrell 
12346ff6d951SJohn Birrell 	for (i = 0; i < DTRACEOPT_MAX; i++)
12356ff6d951SJohn Birrell 		dtp->dt_options[i] = DTRACEOPT_UNSET;
12366ff6d951SJohn Birrell 
12376ff6d951SJohn Birrell 	dtp->dt_cpp_argv[0] = (char *)strbasename(dtp->dt_cpp_path);
12386ff6d951SJohn Birrell 
1239bc96366cSSteven Hartland #ifdef illumos
12406ff6d951SJohn Birrell 	(void) snprintf(isadef, sizeof (isadef), "-D__SUNW_D_%u",
12416ff6d951SJohn Birrell 	    (uint_t)(sizeof (void *) * NBBY));
12426ff6d951SJohn Birrell 
12436ff6d951SJohn Birrell 	(void) snprintf(utsdef, sizeof (utsdef), "-D__%s_%s",
12446ff6d951SJohn Birrell 	    dt_get_sysinfo(SI_SYSNAME, s1, sizeof (s1)),
12456ff6d951SJohn Birrell 	    dt_get_sysinfo(SI_RELEASE, s2, sizeof (s2)));
12466ff6d951SJohn Birrell 
12476ff6d951SJohn Birrell 	if (dt_cpp_add_arg(dtp, "-D__sun") == NULL ||
12486ff6d951SJohn Birrell 	    dt_cpp_add_arg(dtp, "-D__unix") == NULL ||
12496ff6d951SJohn Birrell 	    dt_cpp_add_arg(dtp, "-D__SVR4") == NULL ||
12506ff6d951SJohn Birrell 	    dt_cpp_add_arg(dtp, "-D__SUNW_D=1") == NULL ||
12516ff6d951SJohn Birrell 	    dt_cpp_add_arg(dtp, isadef) == NULL ||
12526ff6d951SJohn Birrell 	    dt_cpp_add_arg(dtp, utsdef) == NULL)
12536ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_NOMEM));
1254fb24b944SJohn Birrell #endif
12556ff6d951SJohn Birrell 
12566ff6d951SJohn Birrell 	if (flags & DTRACE_O_NODEV)
12576ff6d951SJohn Birrell 		bcopy(&_dtrace_conf, &dtp->dt_conf, sizeof (_dtrace_conf));
12586ff6d951SJohn Birrell 	else if (dt_ioctl(dtp, DTRACEIOC_CONF, &dtp->dt_conf) != 0)
12596ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, errno));
12606ff6d951SJohn Birrell 
12616ff6d951SJohn Birrell 	if (flags & DTRACE_O_LP64)
12626ff6d951SJohn Birrell 		dtp->dt_conf.dtc_ctfmodel = CTF_MODEL_LP64;
12636ff6d951SJohn Birrell 	else if (flags & DTRACE_O_ILP32)
12646ff6d951SJohn Birrell 		dtp->dt_conf.dtc_ctfmodel = CTF_MODEL_ILP32;
12656ff6d951SJohn Birrell 
12666ff6d951SJohn Birrell #ifdef __sparc
12676ff6d951SJohn Birrell 	/*
12686ff6d951SJohn Birrell 	 * On SPARC systems, __sparc is always defined for <sys/isa_defs.h>
12696ff6d951SJohn Birrell 	 * and __sparcv9 is defined if we are doing a 64-bit compile.
12706ff6d951SJohn Birrell 	 */
12716ff6d951SJohn Birrell 	if (dt_cpp_add_arg(dtp, "-D__sparc") == NULL)
12726ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_NOMEM));
12736ff6d951SJohn Birrell 
12746ff6d951SJohn Birrell 	if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64 &&
12756ff6d951SJohn Birrell 	    dt_cpp_add_arg(dtp, "-D__sparcv9") == NULL)
12766ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_NOMEM));
12776ff6d951SJohn Birrell #endif
12786ff6d951SJohn Birrell 
1279bc96366cSSteven Hartland #ifdef illumos
12806ff6d951SJohn Birrell #ifdef __x86
12816ff6d951SJohn Birrell 	/*
12826ff6d951SJohn Birrell 	 * On x86 systems, __i386 is defined for <sys/isa_defs.h> for 32-bit
12836ff6d951SJohn Birrell 	 * compiles and __amd64 is defined for 64-bit compiles.  Unlike SPARC,
12846ff6d951SJohn Birrell 	 * they are defined exclusive of one another (see PSARC 2004/619).
12856ff6d951SJohn Birrell 	 */
12866ff6d951SJohn Birrell 	if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64) {
12876ff6d951SJohn Birrell 		if (dt_cpp_add_arg(dtp, "-D__amd64") == NULL)
12886ff6d951SJohn Birrell 			return (set_open_errno(dtp, errp, EDT_NOMEM));
12896ff6d951SJohn Birrell 	} else {
12906ff6d951SJohn Birrell 		if (dt_cpp_add_arg(dtp, "-D__i386") == NULL)
12916ff6d951SJohn Birrell 			return (set_open_errno(dtp, errp, EDT_NOMEM));
12926ff6d951SJohn Birrell 	}
12936ff6d951SJohn Birrell #endif
1294fb24b944SJohn Birrell #else
1295fb24b944SJohn Birrell #if defined(__amd64__) || defined(__i386__)
1296fb24b944SJohn Birrell 	if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64) {
1297fb24b944SJohn Birrell 		if (dt_cpp_add_arg(dtp, "-m64") == NULL)
1298fb24b944SJohn Birrell 			return (set_open_errno(dtp, errp, EDT_NOMEM));
1299fb24b944SJohn Birrell 	} else {
1300fb24b944SJohn Birrell 		if (dt_cpp_add_arg(dtp, "-m32") == NULL)
1301fb24b944SJohn Birrell 			return (set_open_errno(dtp, errp, EDT_NOMEM));
1302fb24b944SJohn Birrell 	}
1303fb24b944SJohn Birrell #endif
1304fb24b944SJohn Birrell #endif
13056ff6d951SJohn Birrell 
13066ff6d951SJohn Birrell 	if (dtp->dt_conf.dtc_difversion < DIF_VERSION)
13076ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_DIFVERS));
13086ff6d951SJohn Birrell 
13096ff6d951SJohn Birrell 	if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_ILP32)
13106ff6d951SJohn Birrell 		bcopy(_dtrace_ints_32, dtp->dt_ints, sizeof (_dtrace_ints_32));
13116ff6d951SJohn Birrell 	else
13126ff6d951SJohn Birrell 		bcopy(_dtrace_ints_64, dtp->dt_ints, sizeof (_dtrace_ints_64));
13136ff6d951SJohn Birrell 
1314fb24b944SJohn Birrell 	/*
1315fb24b944SJohn Birrell 	 * On FreeBSD the kernel module name can't be hard-coded. The
1316fb24b944SJohn Birrell 	 * 'kern.bootfile' sysctl value tells us exactly which file is being
1317fb24b944SJohn Birrell 	 * used as the kernel.
1318fb24b944SJohn Birrell 	 */
1319bc96366cSSteven Hartland #ifndef illumos
1320fb24b944SJohn Birrell 	{
1321fb24b944SJohn Birrell 	char bootfile[MAXPATHLEN];
1322fb24b944SJohn Birrell 	char *p;
1323fb24b944SJohn Birrell 	int i;
1324fb24b944SJohn Birrell 	size_t len = sizeof(bootfile);
1325fb24b944SJohn Birrell 
1326fb24b944SJohn Birrell 	/* This call shouldn't fail, but use a default just in case. */
1327fb24b944SJohn Birrell 	if (sysctlbyname("kern.bootfile", bootfile, &len, NULL, 0) != 0)
1328fb24b944SJohn Birrell 		strlcpy(bootfile, "kernel", sizeof(bootfile));
1329fb24b944SJohn Birrell 
1330fb24b944SJohn Birrell 	if ((p = strrchr(bootfile, '/')) != NULL)
1331fb24b944SJohn Birrell 		p++;
1332fb24b944SJohn Birrell 	else
1333fb24b944SJohn Birrell 		p = bootfile;
1334fb24b944SJohn Birrell 
1335fb24b944SJohn Birrell 	/*
1336fb24b944SJohn Birrell 	 * Format the global variables based on the kernel module name.
1337fb24b944SJohn Birrell 	 */
1338fb24b944SJohn Birrell 	snprintf(curthread_str, sizeof(curthread_str), "%s`struct thread *",p);
1339fb24b944SJohn Birrell 	snprintf(intmtx_str, sizeof(intmtx_str), "int(%s`struct mtx *)",p);
1340fb24b944SJohn Birrell 	snprintf(threadmtx_str, sizeof(threadmtx_str), "struct thread *(%s`struct mtx *)",p);
1341fb24b944SJohn Birrell 	snprintf(rwlock_str, sizeof(rwlock_str), "int(%s`struct rwlock *)",p);
1342eb381edaSMark Johnston 	snprintf(sxlock_str, sizeof(sxlock_str), "int(%s`struct sx *)",p);
1343fb24b944SJohn Birrell 	}
1344fb24b944SJohn Birrell #endif
1345fb24b944SJohn Birrell 
13466ff6d951SJohn Birrell 	dtp->dt_macros = dt_idhash_create("macro", NULL, 0, UINT_MAX);
13476ff6d951SJohn Birrell 	dtp->dt_aggs = dt_idhash_create("aggregation", NULL,
13486ff6d951SJohn Birrell 	    DTRACE_AGGVARIDNONE + 1, UINT_MAX);
13496ff6d951SJohn Birrell 
13506ff6d951SJohn Birrell 	dtp->dt_globals = dt_idhash_create("global", _dtrace_globals,
13516ff6d951SJohn Birrell 	    DIF_VAR_OTHER_UBASE, DIF_VAR_OTHER_MAX);
13526ff6d951SJohn Birrell 
13536ff6d951SJohn Birrell 	dtp->dt_tls = dt_idhash_create("thread local", NULL,
13546ff6d951SJohn Birrell 	    DIF_VAR_OTHER_UBASE, DIF_VAR_OTHER_MAX);
13556ff6d951SJohn Birrell 
13566ff6d951SJohn Birrell 	if (dtp->dt_macros == NULL || dtp->dt_aggs == NULL ||
13576ff6d951SJohn Birrell 	    dtp->dt_globals == NULL || dtp->dt_tls == NULL)
13586ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_NOMEM));
13596ff6d951SJohn Birrell 
13606ff6d951SJohn Birrell 	/*
13616ff6d951SJohn Birrell 	 * Populate the dt_macros identifier hash table by hand: we can't use
13626ff6d951SJohn Birrell 	 * the dt_idhash_populate() mechanism because we're not yet compiling
13636ff6d951SJohn Birrell 	 * and dtrace_update() needs to immediately reference these idents.
13646ff6d951SJohn Birrell 	 */
13656ff6d951SJohn Birrell 	for (idp = _dtrace_macros; idp->di_name != NULL; idp++) {
13666ff6d951SJohn Birrell 		if (dt_idhash_insert(dtp->dt_macros, idp->di_name,
13676ff6d951SJohn Birrell 		    idp->di_kind, idp->di_flags, idp->di_id, idp->di_attr,
13686ff6d951SJohn Birrell 		    idp->di_vers, idp->di_ops ? idp->di_ops : &dt_idops_thaw,
13696ff6d951SJohn Birrell 		    idp->di_iarg, 0) == NULL)
13706ff6d951SJohn Birrell 			return (set_open_errno(dtp, errp, EDT_NOMEM));
13716ff6d951SJohn Birrell 	}
13726ff6d951SJohn Birrell 
13736ff6d951SJohn Birrell 	/*
13746ff6d951SJohn Birrell 	 * Update the module list using /system/object and load the values for
13756ff6d951SJohn Birrell 	 * the macro variable definitions according to the current process.
13766ff6d951SJohn Birrell 	 */
13776ff6d951SJohn Birrell 	dtrace_update(dtp);
13786ff6d951SJohn Birrell 
13796ff6d951SJohn Birrell 	/*
13806ff6d951SJohn Birrell 	 * Select the intrinsics and typedefs we want based on the data model.
13816ff6d951SJohn Birrell 	 * The intrinsics are under "C".  The typedefs are added under "D".
13826ff6d951SJohn Birrell 	 */
13836ff6d951SJohn Birrell 	if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_ILP32) {
13846ff6d951SJohn Birrell 		dinp = _dtrace_intrinsics_32;
13856ff6d951SJohn Birrell 		dtyp = _dtrace_typedefs_32;
13866ff6d951SJohn Birrell 	} else {
13876ff6d951SJohn Birrell 		dinp = _dtrace_intrinsics_64;
13886ff6d951SJohn Birrell 		dtyp = _dtrace_typedefs_64;
13896ff6d951SJohn Birrell 	}
13906ff6d951SJohn Birrell 
13916ff6d951SJohn Birrell 	/*
13926ff6d951SJohn Birrell 	 * Create a dynamic CTF container under the "C" scope for intrinsic
13936ff6d951SJohn Birrell 	 * types and types defined in ANSI-C header files that are included.
13946ff6d951SJohn Birrell 	 */
13956ff6d951SJohn Birrell 	if ((dmp = dtp->dt_cdefs = dt_module_create(dtp, "C")) == NULL)
13966ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_NOMEM));
13976ff6d951SJohn Birrell 
13986ff6d951SJohn Birrell 	if ((dmp->dm_ctfp = ctf_create(&dtp->dt_ctferr)) == NULL)
13996ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_CTF));
14006ff6d951SJohn Birrell 
14016ff6d951SJohn Birrell 	dt_dprintf("created CTF container for %s (%p)\n",
14026ff6d951SJohn Birrell 	    dmp->dm_name, (void *)dmp->dm_ctfp);
14036ff6d951SJohn Birrell 
14046ff6d951SJohn Birrell 	(void) ctf_setmodel(dmp->dm_ctfp, dtp->dt_conf.dtc_ctfmodel);
14056ff6d951SJohn Birrell 	ctf_setspecific(dmp->dm_ctfp, dmp);
14066ff6d951SJohn Birrell 
14076ff6d951SJohn Birrell 	dmp->dm_flags = DT_DM_LOADED; /* fake up loaded bit */
14086ff6d951SJohn Birrell 	dmp->dm_modid = -1; /* no module ID */
14096ff6d951SJohn Birrell 
14106ff6d951SJohn Birrell 	/*
14116ff6d951SJohn Birrell 	 * Fill the dynamic "C" CTF container with all of the intrinsic
14126ff6d951SJohn Birrell 	 * integer and floating-point types appropriate for this data model.
14136ff6d951SJohn Birrell 	 */
14146ff6d951SJohn Birrell 	for (; dinp->din_name != NULL; dinp++) {
14156ff6d951SJohn Birrell 		if (dinp->din_kind == CTF_K_INTEGER) {
14166ff6d951SJohn Birrell 			err = ctf_add_integer(dmp->dm_ctfp, CTF_ADD_ROOT,
14176ff6d951SJohn Birrell 			    dinp->din_name, &dinp->din_data);
14186ff6d951SJohn Birrell 		} else {
14196ff6d951SJohn Birrell 			err = ctf_add_float(dmp->dm_ctfp, CTF_ADD_ROOT,
14206ff6d951SJohn Birrell 			    dinp->din_name, &dinp->din_data);
14216ff6d951SJohn Birrell 		}
14226ff6d951SJohn Birrell 
14236ff6d951SJohn Birrell 		if (err == CTF_ERR) {
14246ff6d951SJohn Birrell 			dt_dprintf("failed to add %s to C container: %s\n",
14256ff6d951SJohn Birrell 			    dinp->din_name, ctf_errmsg(
14266ff6d951SJohn Birrell 			    ctf_errno(dmp->dm_ctfp)));
14276ff6d951SJohn Birrell 			return (set_open_errno(dtp, errp, EDT_CTF));
14286ff6d951SJohn Birrell 		}
14296ff6d951SJohn Birrell 	}
14306ff6d951SJohn Birrell 
14316ff6d951SJohn Birrell 	if (ctf_update(dmp->dm_ctfp) != 0) {
14326ff6d951SJohn Birrell 		dt_dprintf("failed to update C container: %s\n",
14336ff6d951SJohn Birrell 		    ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
14346ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_CTF));
14356ff6d951SJohn Birrell 	}
14366ff6d951SJohn Birrell 
14376ff6d951SJohn Birrell 	/*
14386ff6d951SJohn Birrell 	 * Add intrinsic pointer types that are needed to initialize printf
14396ff6d951SJohn Birrell 	 * format dictionary types (see table in dt_printf.c).
14406ff6d951SJohn Birrell 	 */
14416ff6d951SJohn Birrell 	(void) ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT,
14426ff6d951SJohn Birrell 	    ctf_lookup_by_name(dmp->dm_ctfp, "void"));
14436ff6d951SJohn Birrell 
14446ff6d951SJohn Birrell 	(void) ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT,
14456ff6d951SJohn Birrell 	    ctf_lookup_by_name(dmp->dm_ctfp, "char"));
14466ff6d951SJohn Birrell 
14476ff6d951SJohn Birrell 	(void) ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT,
14486ff6d951SJohn Birrell 	    ctf_lookup_by_name(dmp->dm_ctfp, "int"));
14496ff6d951SJohn Birrell 
14506ff6d951SJohn Birrell 	if (ctf_update(dmp->dm_ctfp) != 0) {
14516ff6d951SJohn Birrell 		dt_dprintf("failed to update C container: %s\n",
14526ff6d951SJohn Birrell 		    ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
14536ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_CTF));
14546ff6d951SJohn Birrell 	}
14556ff6d951SJohn Birrell 
14566ff6d951SJohn Birrell 	/*
14576ff6d951SJohn Birrell 	 * Create a dynamic CTF container under the "D" scope for types that
14586ff6d951SJohn Birrell 	 * are defined by the D program itself or on-the-fly by the D compiler.
14596ff6d951SJohn Birrell 	 * The "D" CTF container is a child of the "C" CTF container.
14606ff6d951SJohn Birrell 	 */
14616ff6d951SJohn Birrell 	if ((dmp = dtp->dt_ddefs = dt_module_create(dtp, "D")) == NULL)
14626ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_NOMEM));
14636ff6d951SJohn Birrell 
14646ff6d951SJohn Birrell 	if ((dmp->dm_ctfp = ctf_create(&dtp->dt_ctferr)) == NULL)
14656ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_CTF));
14666ff6d951SJohn Birrell 
14676ff6d951SJohn Birrell 	dt_dprintf("created CTF container for %s (%p)\n",
14686ff6d951SJohn Birrell 	    dmp->dm_name, (void *)dmp->dm_ctfp);
14696ff6d951SJohn Birrell 
14706ff6d951SJohn Birrell 	(void) ctf_setmodel(dmp->dm_ctfp, dtp->dt_conf.dtc_ctfmodel);
14716ff6d951SJohn Birrell 	ctf_setspecific(dmp->dm_ctfp, dmp);
14726ff6d951SJohn Birrell 
14736ff6d951SJohn Birrell 	dmp->dm_flags = DT_DM_LOADED; /* fake up loaded bit */
14746ff6d951SJohn Birrell 	dmp->dm_modid = -1; /* no module ID */
14756ff6d951SJohn Birrell 
14766ff6d951SJohn Birrell 	if (ctf_import(dmp->dm_ctfp, dtp->dt_cdefs->dm_ctfp) == CTF_ERR) {
14776ff6d951SJohn Birrell 		dt_dprintf("failed to import D parent container: %s\n",
14786ff6d951SJohn Birrell 		    ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
14796ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_CTF));
14806ff6d951SJohn Birrell 	}
14816ff6d951SJohn Birrell 
14826ff6d951SJohn Birrell 	/*
14836ff6d951SJohn Birrell 	 * Fill the dynamic "D" CTF container with all of the built-in typedefs
14846ff6d951SJohn Birrell 	 * that we need to use for our D variable and function definitions.
14856ff6d951SJohn Birrell 	 * This ensures that basic inttypes.h names are always available to us.
14866ff6d951SJohn Birrell 	 */
14876ff6d951SJohn Birrell 	for (; dtyp->dty_src != NULL; dtyp++) {
14886ff6d951SJohn Birrell 		if (ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,
14896ff6d951SJohn Birrell 		    dtyp->dty_dst, ctf_lookup_by_name(dmp->dm_ctfp,
14906ff6d951SJohn Birrell 		    dtyp->dty_src)) == CTF_ERR) {
14916ff6d951SJohn Birrell 			dt_dprintf("failed to add typedef %s %s to D "
14921ef441f6SMark Johnston 			    "container: %s\n", dtyp->dty_src, dtyp->dty_dst,
14936ff6d951SJohn Birrell 			    ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
14946ff6d951SJohn Birrell 			return (set_open_errno(dtp, errp, EDT_CTF));
14956ff6d951SJohn Birrell 		}
14966ff6d951SJohn Birrell 	}
14976ff6d951SJohn Birrell 
14986ff6d951SJohn Birrell 	/*
14996ff6d951SJohn Birrell 	 * Insert a CTF ID corresponding to a pointer to a type of kind
15006ff6d951SJohn Birrell 	 * CTF_K_FUNCTION we can use in the compiler for function pointers.
15016ff6d951SJohn Birrell 	 * CTF treats all function pointers as "int (*)()" so we only need one.
15026ff6d951SJohn Birrell 	 */
15036ff6d951SJohn Birrell 	ctc.ctc_return = ctf_lookup_by_name(dmp->dm_ctfp, "int");
15046ff6d951SJohn Birrell 	ctc.ctc_argc = 0;
15056ff6d951SJohn Birrell 	ctc.ctc_flags = 0;
15066ff6d951SJohn Birrell 
15076ff6d951SJohn Birrell 	dtp->dt_type_func = ctf_add_function(dmp->dm_ctfp,
15086ff6d951SJohn Birrell 	    CTF_ADD_ROOT, &ctc, NULL);
15096ff6d951SJohn Birrell 
15106ff6d951SJohn Birrell 	dtp->dt_type_fptr = ctf_add_pointer(dmp->dm_ctfp,
15116ff6d951SJohn Birrell 	    CTF_ADD_ROOT, dtp->dt_type_func);
15126ff6d951SJohn Birrell 
15136ff6d951SJohn Birrell 	/*
15146ff6d951SJohn Birrell 	 * We also insert CTF definitions for the special D intrinsic types
15156ff6d951SJohn Birrell 	 * string and <DYN> into the D container.  The string type is added
15166ff6d951SJohn Birrell 	 * as a typedef of char[n].  The <DYN> type is an alias for void.
15176ff6d951SJohn Birrell 	 * We compare types to these special CTF ids throughout the compiler.
15186ff6d951SJohn Birrell 	 */
15196ff6d951SJohn Birrell 	ctr.ctr_contents = ctf_lookup_by_name(dmp->dm_ctfp, "char");
15206ff6d951SJohn Birrell 	ctr.ctr_index = ctf_lookup_by_name(dmp->dm_ctfp, "long");
15216ff6d951SJohn Birrell 	ctr.ctr_nelems = _dtrace_strsize;
15226ff6d951SJohn Birrell 
15236ff6d951SJohn Birrell 	dtp->dt_type_str = ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,
15246ff6d951SJohn Birrell 	    "string", ctf_add_array(dmp->dm_ctfp, CTF_ADD_ROOT, &ctr));
15256ff6d951SJohn Birrell 
15266ff6d951SJohn Birrell 	dtp->dt_type_dyn = ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,
15276ff6d951SJohn Birrell 	    "<DYN>", ctf_lookup_by_name(dmp->dm_ctfp, "void"));
15286ff6d951SJohn Birrell 
15296ff6d951SJohn Birrell 	dtp->dt_type_stack = ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,
15306ff6d951SJohn Birrell 	    "stack", ctf_lookup_by_name(dmp->dm_ctfp, "void"));
15316ff6d951SJohn Birrell 
15326ff6d951SJohn Birrell 	dtp->dt_type_symaddr = ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,
15336ff6d951SJohn Birrell 	    "_symaddr", ctf_lookup_by_name(dmp->dm_ctfp, "void"));
15346ff6d951SJohn Birrell 
15356ff6d951SJohn Birrell 	dtp->dt_type_usymaddr = ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,
15366ff6d951SJohn Birrell 	    "_usymaddr", ctf_lookup_by_name(dmp->dm_ctfp, "void"));
15376ff6d951SJohn Birrell 
15386ff6d951SJohn Birrell 	if (dtp->dt_type_func == CTF_ERR || dtp->dt_type_fptr == CTF_ERR ||
15396ff6d951SJohn Birrell 	    dtp->dt_type_str == CTF_ERR || dtp->dt_type_dyn == CTF_ERR ||
15406ff6d951SJohn Birrell 	    dtp->dt_type_stack == CTF_ERR || dtp->dt_type_symaddr == CTF_ERR ||
15416ff6d951SJohn Birrell 	    dtp->dt_type_usymaddr == CTF_ERR) {
15426ff6d951SJohn Birrell 		dt_dprintf("failed to add intrinsic to D container: %s\n",
15436ff6d951SJohn Birrell 		    ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
15446ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_CTF));
15456ff6d951SJohn Birrell 	}
15466ff6d951SJohn Birrell 
15476ff6d951SJohn Birrell 	if (ctf_update(dmp->dm_ctfp) != 0) {
15486ff6d951SJohn Birrell 		dt_dprintf("failed update D container: %s\n",
15496ff6d951SJohn Birrell 		    ctf_errmsg(ctf_errno(dmp->dm_ctfp)));
15506ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_CTF));
15516ff6d951SJohn Birrell 	}
15526ff6d951SJohn Birrell 
15536ff6d951SJohn Birrell 	/*
15546ff6d951SJohn Birrell 	 * Initialize the integer description table used to convert integer
15556ff6d951SJohn Birrell 	 * constants to the appropriate types.  Refer to the comments above
15566ff6d951SJohn Birrell 	 * dt_node_int() for a complete description of how this table is used.
15576ff6d951SJohn Birrell 	 */
15586ff6d951SJohn Birrell 	for (i = 0; i < sizeof (dtp->dt_ints) / sizeof (dtp->dt_ints[0]); i++) {
15596ff6d951SJohn Birrell 		if (dtrace_lookup_by_type(dtp, DTRACE_OBJ_EVERY,
15606ff6d951SJohn Birrell 		    dtp->dt_ints[i].did_name, &dtt) != 0) {
15616ff6d951SJohn Birrell 			dt_dprintf("failed to lookup integer type %s: %s\n",
15626ff6d951SJohn Birrell 			    dtp->dt_ints[i].did_name,
15636ff6d951SJohn Birrell 			    dtrace_errmsg(dtp, dtrace_errno(dtp)));
15646ff6d951SJohn Birrell 			return (set_open_errno(dtp, errp, dtp->dt_errno));
15656ff6d951SJohn Birrell 		}
15666ff6d951SJohn Birrell 		dtp->dt_ints[i].did_ctfp = dtt.dtt_ctfp;
15676ff6d951SJohn Birrell 		dtp->dt_ints[i].did_type = dtt.dtt_type;
15686ff6d951SJohn Birrell 	}
15696ff6d951SJohn Birrell 
15706ff6d951SJohn Birrell 	/*
15716ff6d951SJohn Birrell 	 * Now that we've created the "C" and "D" containers, move them to the
15726ff6d951SJohn Birrell 	 * start of the module list so that these types and symbols are found
15736ff6d951SJohn Birrell 	 * first (for stability) when iterating through the module list.
15746ff6d951SJohn Birrell 	 */
15756ff6d951SJohn Birrell 	dt_list_delete(&dtp->dt_modlist, dtp->dt_ddefs);
15766ff6d951SJohn Birrell 	dt_list_prepend(&dtp->dt_modlist, dtp->dt_ddefs);
15776ff6d951SJohn Birrell 
15786ff6d951SJohn Birrell 	dt_list_delete(&dtp->dt_modlist, dtp->dt_cdefs);
15796ff6d951SJohn Birrell 	dt_list_prepend(&dtp->dt_modlist, dtp->dt_cdefs);
15806ff6d951SJohn Birrell 
15816ff6d951SJohn Birrell 	if (dt_pfdict_create(dtp) == -1)
15826ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, dtp->dt_errno));
15836ff6d951SJohn Birrell 
15846ff6d951SJohn Birrell 	/*
15856ff6d951SJohn Birrell 	 * If we are opening libdtrace DTRACE_O_NODEV enable C_ZDEFS by default
15866ff6d951SJohn Birrell 	 * because without /dev/dtrace open, we will not be able to load the
15876ff6d951SJohn Birrell 	 * names and attributes of any providers or probes from the kernel.
15886ff6d951SJohn Birrell 	 */
15896ff6d951SJohn Birrell 	if (flags & DTRACE_O_NODEV)
15906ff6d951SJohn Birrell 		dtp->dt_cflags |= DTRACE_C_ZDEFS;
15916ff6d951SJohn Birrell 
15926ff6d951SJohn Birrell 	/*
15936ff6d951SJohn Birrell 	 * Load hard-wired inlines into the definition cache by calling the
15946ff6d951SJohn Birrell 	 * compiler on the raw definition string defined above.
15956ff6d951SJohn Birrell 	 */
15966ff6d951SJohn Birrell 	if ((pgp = dtrace_program_strcompile(dtp, _dtrace_hardwire,
15976ff6d951SJohn Birrell 	    DTRACE_PROBESPEC_NONE, DTRACE_C_EMPTY, 0, NULL)) == NULL) {
15986ff6d951SJohn Birrell 		dt_dprintf("failed to load hard-wired definitions: %s\n",
15996ff6d951SJohn Birrell 		    dtrace_errmsg(dtp, dtrace_errno(dtp)));
16006ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, EDT_HARDWIRE));
16016ff6d951SJohn Birrell 	}
16026ff6d951SJohn Birrell 
16036ff6d951SJohn Birrell 	dt_program_destroy(dtp, pgp);
16046ff6d951SJohn Birrell 
16056ff6d951SJohn Birrell 	/*
16066ff6d951SJohn Birrell 	 * Set up the default DTrace library path.  Once set, the next call to
16076ff6d951SJohn Birrell 	 * dt_compile() will compile all the libraries.  We intentionally defer
16086ff6d951SJohn Birrell 	 * library processing to improve overhead for clients that don't ever
16096ff6d951SJohn Birrell 	 * compile, and to provide better error reporting (because the full
16106ff6d951SJohn Birrell 	 * reporting of compiler errors requires dtrace_open() to succeed).
16116ff6d951SJohn Birrell 	 */
16120fff3baaSMark Johnston #ifdef __FreeBSD__
16130fff3baaSMark Johnston #ifdef __LP64__
16140fff3baaSMark Johnston 	if ((dtp->dt_oflags & DTRACE_O_ILP32) != 0) {
16150fff3baaSMark Johnston 		if (dtrace_setopt(dtp, "libdir", _dtrace_libdir32) != 0)
16160fff3baaSMark Johnston 			return (set_open_errno(dtp, errp, dtp->dt_errno));
16170fff3baaSMark Johnston 	}
16180fff3baaSMark Johnston #endif
16196ff6d951SJohn Birrell 	if (dtrace_setopt(dtp, "libdir", _dtrace_libdir) != 0)
16206ff6d951SJohn Birrell 		return (set_open_errno(dtp, errp, dtp->dt_errno));
16210fff3baaSMark Johnston #else
16220fff3baaSMark Johnston 	if (dtrace_setopt(dtp, "libdir", _dtrace_libdir) != 0)
16230fff3baaSMark Johnston 		return (set_open_errno(dtp, errp, dtp->dt_errno));
16240fff3baaSMark Johnston #endif
16256ff6d951SJohn Birrell 
16266ff6d951SJohn Birrell 	return (dtp);
16276ff6d951SJohn Birrell }
16286ff6d951SJohn Birrell 
16296ff6d951SJohn Birrell dtrace_hdl_t *
16306ff6d951SJohn Birrell dtrace_open(int version, int flags, int *errp)
16316ff6d951SJohn Birrell {
16326ff6d951SJohn Birrell 	return (dt_vopen(version, flags, errp, NULL, NULL));
16336ff6d951SJohn Birrell }
16346ff6d951SJohn Birrell 
16356ff6d951SJohn Birrell dtrace_hdl_t *
16366ff6d951SJohn Birrell dtrace_vopen(int version, int flags, int *errp,
16376ff6d951SJohn Birrell     const dtrace_vector_t *vector, void *arg)
16386ff6d951SJohn Birrell {
16396ff6d951SJohn Birrell 	return (dt_vopen(version, flags, errp, vector, arg));
16406ff6d951SJohn Birrell }
16416ff6d951SJohn Birrell 
16426ff6d951SJohn Birrell void
16436ff6d951SJohn Birrell dtrace_close(dtrace_hdl_t *dtp)
16446ff6d951SJohn Birrell {
16456ff6d951SJohn Birrell 	dt_ident_t *idp, *ndp;
16466ff6d951SJohn Birrell 	dt_module_t *dmp;
16476ff6d951SJohn Birrell 	dt_provider_t *pvp;
16486ff6d951SJohn Birrell 	dtrace_prog_t *pgp;
16496ff6d951SJohn Birrell 	dt_xlator_t *dxp;
16506ff6d951SJohn Birrell 	dt_dirpath_t *dirp;
16518436cb81SMark Johnston #ifdef __FreeBSD__
16528436cb81SMark Johnston 	dt_kmodule_t *dkm;
16538436cb81SMark Johnston 	uint_t h;
16548436cb81SMark Johnston #endif
16556ff6d951SJohn Birrell 	int i;
16566ff6d951SJohn Birrell 
1657fb24b944SJohn Birrell 	if (dtp->dt_procs != NULL)
165804006780SMark Johnston 		dt_proc_fini(dtp);
1659fb24b944SJohn Birrell 
16606ff6d951SJohn Birrell 	while ((pgp = dt_list_next(&dtp->dt_programs)) != NULL)
16616ff6d951SJohn Birrell 		dt_program_destroy(dtp, pgp);
16626ff6d951SJohn Birrell 
16636ff6d951SJohn Birrell 	while ((dxp = dt_list_next(&dtp->dt_xlators)) != NULL)
16646ff6d951SJohn Birrell 		dt_xlator_destroy(dtp, dxp);
16656ff6d951SJohn Birrell 
16666ff6d951SJohn Birrell 	dt_free(dtp, dtp->dt_xlatormap);
16676ff6d951SJohn Birrell 
16686ff6d951SJohn Birrell 	for (idp = dtp->dt_externs; idp != NULL; idp = ndp) {
16696ff6d951SJohn Birrell 		ndp = idp->di_next;
16706ff6d951SJohn Birrell 		dt_ident_destroy(idp);
16716ff6d951SJohn Birrell 	}
16726ff6d951SJohn Birrell 
16736ff6d951SJohn Birrell 	if (dtp->dt_macros != NULL)
16746ff6d951SJohn Birrell 		dt_idhash_destroy(dtp->dt_macros);
16756ff6d951SJohn Birrell 	if (dtp->dt_aggs != NULL)
16766ff6d951SJohn Birrell 		dt_idhash_destroy(dtp->dt_aggs);
16776ff6d951SJohn Birrell 	if (dtp->dt_globals != NULL)
16786ff6d951SJohn Birrell 		dt_idhash_destroy(dtp->dt_globals);
16796ff6d951SJohn Birrell 	if (dtp->dt_tls != NULL)
16806ff6d951SJohn Birrell 		dt_idhash_destroy(dtp->dt_tls);
16816ff6d951SJohn Birrell 
16828436cb81SMark Johnston #ifdef __FreeBSD__
16838436cb81SMark Johnston 	for (h = 0; h < dtp->dt_modbuckets; h++)
16848436cb81SMark Johnston 		while ((dkm = dtp->dt_kmods[h]) != NULL) {
16858436cb81SMark Johnston 			dtp->dt_kmods[h] = dkm->dkm_next;
16868436cb81SMark Johnston 			free(dkm->dkm_name);
16878436cb81SMark Johnston 			free(dkm);
16888436cb81SMark Johnston 		}
16898436cb81SMark Johnston #endif
16908436cb81SMark Johnston 
16916ff6d951SJohn Birrell 	while ((dmp = dt_list_next(&dtp->dt_modlist)) != NULL)
16926ff6d951SJohn Birrell 		dt_module_destroy(dtp, dmp);
16936ff6d951SJohn Birrell 
16946ff6d951SJohn Birrell 	while ((pvp = dt_list_next(&dtp->dt_provlist)) != NULL)
16956ff6d951SJohn Birrell 		dt_provider_destroy(dtp, pvp);
16966ff6d951SJohn Birrell 
16976ff6d951SJohn Birrell 	if (dtp->dt_fd != -1)
16986ff6d951SJohn Birrell 		(void) close(dtp->dt_fd);
16996ff6d951SJohn Birrell 	if (dtp->dt_ftfd != -1)
17006ff6d951SJohn Birrell 		(void) close(dtp->dt_ftfd);
17012179a159SChristos Margiolis 	if (dtp->dt_kinstfd != -1)
17022179a159SChristos Margiolis 		(void) close(dtp->dt_kinstfd);
17036ff6d951SJohn Birrell 	if (dtp->dt_cdefs_fd != -1)
17046ff6d951SJohn Birrell 		(void) close(dtp->dt_cdefs_fd);
17056ff6d951SJohn Birrell 	if (dtp->dt_ddefs_fd != -1)
17066ff6d951SJohn Birrell 		(void) close(dtp->dt_ddefs_fd);
1707bc96366cSSteven Hartland #ifdef illumos
17086ff6d951SJohn Birrell 	if (dtp->dt_stdout_fd != -1)
17096ff6d951SJohn Birrell 		(void) close(dtp->dt_stdout_fd);
1710fb24b944SJohn Birrell #else
1711fb24b944SJohn Birrell 	if (dtp->dt_freopen_fp != NULL)
1712fb24b944SJohn Birrell 		(void) fclose(dtp->dt_freopen_fp);
1713fb24b944SJohn Birrell #endif
17146ff6d951SJohn Birrell 
17156ff6d951SJohn Birrell 	dt_epid_destroy(dtp);
17166ff6d951SJohn Birrell 	dt_aggid_destroy(dtp);
17176ff6d951SJohn Birrell 	dt_format_destroy(dtp);
171854727873SPedro F. Giffuni 	dt_strdata_destroy(dtp);
17196ff6d951SJohn Birrell 	dt_buffered_destroy(dtp);
17206ff6d951SJohn Birrell 	dt_aggregate_destroy(dtp);
17216ff6d951SJohn Birrell 	dt_pfdict_destroy(dtp);
17226ff6d951SJohn Birrell 	dt_provmod_destroy(&dtp->dt_provmod);
17236ff6d951SJohn Birrell 	dt_dof_fini(dtp);
17246ff6d951SJohn Birrell 
17256ff6d951SJohn Birrell 	for (i = 1; i < dtp->dt_cpp_argc; i++)
17266ff6d951SJohn Birrell 		free(dtp->dt_cpp_argv[i]);
17276ff6d951SJohn Birrell 
17286ff6d951SJohn Birrell 	while ((dirp = dt_list_next(&dtp->dt_lib_path)) != NULL) {
17296ff6d951SJohn Birrell 		dt_list_delete(&dtp->dt_lib_path, dirp);
17306ff6d951SJohn Birrell 		free(dirp->dir_path);
17316ff6d951SJohn Birrell 		free(dirp);
17326ff6d951SJohn Birrell 	}
17336ff6d951SJohn Birrell 
17346ff6d951SJohn Birrell 	free(dtp->dt_cpp_argv);
17356ff6d951SJohn Birrell 	free(dtp->dt_cpp_path);
17366ff6d951SJohn Birrell 	free(dtp->dt_ld_path);
173703a5f9f0SMark Johnston #ifdef __FreeBSD__
173803a5f9f0SMark Johnston 	free(dtp->dt_objcopy_path);
173903a5f9f0SMark Johnston #endif
17406ff6d951SJohn Birrell 
17416ff6d951SJohn Birrell 	free(dtp->dt_mods);
17428436cb81SMark Johnston #ifdef __FreeBSD__
17438436cb81SMark Johnston 	free(dtp->dt_kmods);
17448436cb81SMark Johnston #endif
17456ff6d951SJohn Birrell 	free(dtp->dt_provs);
174693f27766SDomagoj Stolfa 
174793f27766SDomagoj Stolfa 	xo_finish();
17486ff6d951SJohn Birrell 	free(dtp);
17496ff6d951SJohn Birrell }
17506ff6d951SJohn Birrell 
17516ff6d951SJohn Birrell int
17526ff6d951SJohn Birrell dtrace_provider_modules(dtrace_hdl_t *dtp, const char **mods, int nmods)
17536ff6d951SJohn Birrell {
17546ff6d951SJohn Birrell 	dt_provmod_t *prov;
17556ff6d951SJohn Birrell 	int i = 0;
17566ff6d951SJohn Birrell 
17576ff6d951SJohn Birrell 	for (prov = dtp->dt_provmod; prov != NULL; prov = prov->dp_next, i++) {
17586ff6d951SJohn Birrell 		if (i < nmods)
17596ff6d951SJohn Birrell 			mods[i] = prov->dp_name;
17606ff6d951SJohn Birrell 	}
17616ff6d951SJohn Birrell 
17626ff6d951SJohn Birrell 	return (i);
17636ff6d951SJohn Birrell }
17646ff6d951SJohn Birrell 
17656ff6d951SJohn Birrell int
17666ff6d951SJohn Birrell dtrace_ctlfd(dtrace_hdl_t *dtp)
17676ff6d951SJohn Birrell {
17686ff6d951SJohn Birrell 	return (dtp->dt_fd);
17696ff6d951SJohn Birrell }
1770