4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
29 * Copyright (c) 2012 by Delphix. All rights reserved.
32 #include <sys/resource.h>
34 #include <sys/types.h>
45 #include <dt_string.h>
46 #include <dt_oformat.h>
49 dt_opt_agg(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
51 dt_aggregate_t *agp = &dtp->dt_aggregate;
54 return (dt_set_errno(dtp, EDT_BADOPTVAL));
56 agp->dtat_flags |= option;
62 dt_opt_amin(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
64 char str[DTRACE_ATTR2STR_MAX];
65 dtrace_attribute_t attr;
67 if (arg == NULL || dtrace_str2attr(arg, &attr) == -1)
68 return (dt_set_errno(dtp, EDT_BADOPTVAL));
70 dt_dprintf("set compiler attribute minimum to %s\n",
71 dtrace_attr2str(attr, str, sizeof (str)));
73 if (dtp->dt_pcb != NULL) {
74 dtp->dt_pcb->pcb_cflags |= DTRACE_C_EATTR;
75 dtp->dt_pcb->pcb_amin = attr;
77 dtp->dt_cflags |= DTRACE_C_EATTR;
87 const char msg[] = "libdtrace DEBUG: [ forcing coredump ]\n";
92 (void) write(STDERR_FILENO, msg, sizeof (msg) - 1);
94 act.sa_handler = SIG_DFL;
97 (void) sigemptyset(&act.sa_mask);
98 (void) sigaction(SIGABRT, &act, NULL);
100 lim.rlim_cur = RLIM_INFINITY;
101 lim.rlim_max = RLIM_INFINITY;
103 (void) setrlimit(RLIMIT_CORE, &lim);
109 dt_opt_core(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
111 static int enabled = 0;
114 return (dt_set_errno(dtp, EDT_BADOPTVAL));
116 if (enabled++ || atexit(dt_coredump) == 0)
119 return (dt_set_errno(dtp, errno));
124 dt_opt_cpp_hdrs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
127 return (dt_set_errno(dtp, EDT_BADOPTVAL));
129 if (dtp->dt_pcb != NULL)
130 return (dt_set_errno(dtp, EDT_BADOPTCTX));
132 if (dt_cpp_add_arg(dtp, "-H") == NULL)
133 return (dt_set_errno(dtp, EDT_NOMEM));
140 dt_opt_cpp_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
145 return (dt_set_errno(dtp, EDT_BADOPTVAL));
147 if (dtp->dt_pcb != NULL)
148 return (dt_set_errno(dtp, EDT_BADOPTCTX));
150 if ((cpp = strdup(arg)) == NULL)
151 return (dt_set_errno(dtp, EDT_NOMEM));
153 dtp->dt_cpp_argv[0] = (char *)strbasename(cpp);
154 free(dtp->dt_cpp_path);
155 dtp->dt_cpp_path = cpp;
161 dt_opt_cpp_opts(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
165 const char *opt = (const char *)option;
168 if (opt == NULL || arg == NULL) {
169 ret = dt_set_errno(dtp, EDT_BADOPTVAL);
173 if (dtp->dt_pcb != NULL) {
174 ret = dt_set_errno(dtp, EDT_BADOPTCTX);
178 len = strlen(opt) + strlen(arg) + 1;
179 if ((buf = dt_alloc(dtp, len)) == NULL) {
180 ret = dt_set_errno(dtp, EDT_NOMEM);
184 (void) strcpy(buf, opt);
185 (void) strcat(buf, arg);
187 if (dt_cpp_add_arg(dtp, buf) == NULL) {
188 ret = dt_set_errno(dtp, EDT_NOMEM);
201 dt_opt_ctypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
206 return (dt_set_errno(dtp, EDT_BADOPTVAL));
208 if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1)
209 return (dt_set_errno(dtp, errno));
211 (void) close(dtp->dt_cdefs_fd);
212 dtp->dt_cdefs_fd = fd;
218 dt_opt_droptags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
220 dtp->dt_droptags = 1;
226 dt_opt_dtypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
231 return (dt_set_errno(dtp, EDT_BADOPTVAL));
233 if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1)
234 return (dt_set_errno(dtp, errno));
236 (void) close(dtp->dt_ddefs_fd);
237 dtp->dt_ddefs_fd = fd;
243 dt_opt_debug(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
246 return (dt_set_errno(dtp, EDT_BADOPTVAL));
254 dt_opt_iregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
258 if (arg == NULL || (n = atoi(arg)) <= 0)
259 return (dt_set_errno(dtp, EDT_BADOPTVAL));
261 dtp->dt_conf.dtc_difintregs = n;
267 dt_opt_lazyload(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
269 dtp->dt_lazyload = 1;
276 dt_opt_ld_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
281 return (dt_set_errno(dtp, EDT_BADOPTVAL));
283 if (dtp->dt_pcb != NULL)
284 return (dt_set_errno(dtp, EDT_BADOPTCTX));
286 if ((ld = strdup(arg)) == NULL)
287 return (dt_set_errno(dtp, EDT_NOMEM));
289 free(dtp->dt_ld_path);
290 dtp->dt_ld_path = ld;
297 dt_opt_objcopy_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
302 return (dt_set_errno(dtp, EDT_BADOPTVAL));
304 if (dtp->dt_pcb != NULL)
305 return (dt_set_errno(dtp, EDT_BADOPTCTX));
307 if ((objcopy = strdup(arg)) == NULL)
308 return (dt_set_errno(dtp, EDT_NOMEM));
310 free(dtp->dt_objcopy_path);
311 dtp->dt_objcopy_path = objcopy;
319 dt_opt_libdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
324 return (dt_set_errno(dtp, EDT_BADOPTVAL));
326 if ((dp = malloc(sizeof (dt_dirpath_t))) == NULL ||
327 (dp->dir_path = strdup(arg)) == NULL) {
329 return (dt_set_errno(dtp, EDT_NOMEM));
332 dt_list_append(&dtp->dt_lib_path, dp);
338 dt_opt_linkmode(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
341 return (dt_set_errno(dtp, EDT_BADOPTVAL));
343 if (strcmp(arg, "kernel") == 0)
344 dtp->dt_linkmode = DT_LINK_KERNEL;
345 else if (strcmp(arg, "primary") == 0)
346 dtp->dt_linkmode = DT_LINK_PRIMARY;
347 else if (strcmp(arg, "dynamic") == 0)
348 dtp->dt_linkmode = DT_LINK_DYNAMIC;
349 else if (strcmp(arg, "static") == 0)
350 dtp->dt_linkmode = DT_LINK_STATIC;
352 return (dt_set_errno(dtp, EDT_BADOPTVAL));
359 dt_opt_linktype(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
362 return (dt_set_errno(dtp, EDT_BADOPTVAL));
364 if (strcasecmp(arg, "elf") == 0)
365 dtp->dt_linktype = DT_LTYP_ELF;
366 else if (strcasecmp(arg, "dof") == 0)
367 dtp->dt_linktype = DT_LTYP_DOF;
369 return (dt_set_errno(dtp, EDT_BADOPTVAL));
376 dt_opt_encoding(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
379 return (dt_set_errno(dtp, EDT_BADOPTVAL));
381 if (strcmp(arg, "ascii") == 0)
382 dtp->dt_encoding = DT_ENCODING_ASCII;
383 else if (strcmp(arg, "utf8") == 0)
384 dtp->dt_encoding = DT_ENCODING_UTF8;
386 return (dt_set_errno(dtp, EDT_BADOPTVAL));
393 dt_opt_evaltime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
396 return (dt_set_errno(dtp, EDT_BADOPTVAL));
398 if (strcmp(arg, "exec") == 0)
399 dtp->dt_prcmode = DT_PROC_STOP_CREATE;
400 else if (strcmp(arg, "preinit") == 0)
401 dtp->dt_prcmode = DT_PROC_STOP_PREINIT;
402 else if (strcmp(arg, "postinit") == 0)
403 dtp->dt_prcmode = DT_PROC_STOP_POSTINIT;
404 else if (strcmp(arg, "main") == 0)
405 dtp->dt_prcmode = DT_PROC_STOP_MAIN;
407 return (dt_set_errno(dtp, EDT_BADOPTVAL));
414 dt_opt_pgmax(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
418 if (arg == NULL || (n = atoi(arg)) < 0)
419 return (dt_set_errno(dtp, EDT_BADOPTVAL));
421 dtp->dt_procs->dph_lrulim = n;
426 dt_opt_setenv(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
433 * We can't effectively set environment variables from #pragma lines
434 * since the processes have already been spawned.
436 if (dtp->dt_pcb != NULL)
437 return (dt_set_errno(dtp, EDT_BADOPTCTX));
440 return (dt_set_errno(dtp, EDT_BADOPTVAL));
442 if (!option && strchr(arg, '=') != NULL)
443 return (dt_set_errno(dtp, EDT_BADOPTVAL));
445 for (nvars = 0, p = dtp->dt_proc_env; *p != NULL; nvars++, p++)
448 for (p = dtp->dt_proc_env; *p != NULL; p++) {
449 var = strchr(*p, '=');
451 var = *p + strlen(*p);
452 if (strncmp(*p, arg, var - *p) == 0) {
454 *p = dtp->dt_proc_env[nvars - 1];
455 dtp->dt_proc_env[nvars - 1] = NULL;
461 if ((var = strdup(arg)) == NULL)
462 return (dt_set_errno(dtp, EDT_NOMEM));
465 if ((p = dt_alloc(dtp, sizeof(char *) * (nvars + 1))) == NULL) {
467 return (dt_set_errno(dtp, EDT_NOMEM));
470 bcopy(dtp->dt_proc_env, p, sizeof(char *) * nvars);
471 dt_free(dtp, dtp->dt_proc_env);
472 dtp->dt_proc_env = p;
474 dtp->dt_proc_env[nvars - 1] = var;
475 dtp->dt_proc_env[nvars] = NULL;
483 dt_opt_stdc(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
486 return (dt_set_errno(dtp, EDT_BADOPTVAL));
488 if (dtp->dt_pcb != NULL)
489 return (dt_set_errno(dtp, EDT_BADOPTCTX));
491 if (strcmp(arg, "a") == 0)
492 dtp->dt_stdcmode = DT_STDC_XA;
493 else if (strcmp(arg, "c") == 0)
494 dtp->dt_stdcmode = DT_STDC_XC;
495 else if (strcmp(arg, "s") == 0)
496 dtp->dt_stdcmode = DT_STDC_XS;
497 else if (strcmp(arg, "t") == 0)
498 dtp->dt_stdcmode = DT_STDC_XT;
500 return (dt_set_errno(dtp, EDT_BADOPTVAL));
507 dt_opt_syslibdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
509 dt_dirpath_t *dp = dt_list_next(&dtp->dt_lib_path);
513 return (dt_set_errno(dtp, EDT_BADOPTVAL));
515 if ((path = strdup(arg)) == NULL)
516 return (dt_set_errno(dtp, EDT_NOMEM));
526 dt_opt_tree(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
530 if (arg == NULL || (m = atoi(arg)) <= 0)
531 return (dt_set_errno(dtp, EDT_BADOPTVAL));
533 dtp->dt_treedump = m;
539 dt_opt_tregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
543 if (arg == NULL || (n = atoi(arg)) <= 0)
544 return (dt_set_errno(dtp, EDT_BADOPTVAL));
546 dtp->dt_conf.dtc_diftupregs = n;
552 dt_opt_xlate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
555 return (dt_set_errno(dtp, EDT_BADOPTVAL));
557 if (strcmp(arg, "dynamic") == 0)
558 dtp->dt_xlatemode = DT_XL_DYNAMIC;
559 else if (strcmp(arg, "static") == 0)
560 dtp->dt_xlatemode = DT_XL_STATIC;
562 return (dt_set_errno(dtp, EDT_BADOPTVAL));
569 dt_opt_cflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
572 return (dt_set_errno(dtp, EDT_BADOPTVAL));
574 if (dtp->dt_pcb != NULL)
575 dtp->dt_pcb->pcb_cflags |= option;
577 dtp->dt_cflags |= option;
583 dt_opt_dflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
586 return (dt_set_errno(dtp, EDT_BADOPTVAL));
588 dtp->dt_dflags |= option;
593 dt_opt_invcflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
596 return (dt_set_errno(dtp, EDT_BADOPTVAL));
598 if (dtp->dt_pcb != NULL)
599 dtp->dt_pcb->pcb_cflags &= ~option;
601 dtp->dt_cflags &= ~option;
608 dt_opt_version(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
613 return (dt_set_errno(dtp, EDT_BADOPTVAL));
615 if (dt_version_str2num(arg, &v) == -1)
616 return (dt_set_errno(dtp, EDT_VERSINVAL));
618 if (!dt_version_defined(v))
619 return (dt_set_errno(dtp, EDT_VERSUNDEF));
621 return (dt_reduce(dtp, v));
625 dt_opt_runtime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
628 dtrace_optval_t val = 0;
636 { "enable", "disable" },
637 { "enabled", "disabled" },
645 if (arg[0] == '\0') {
646 val = DTRACEOPT_UNSET;
650 for (i = 0; couples[i].positive != NULL; i++) {
651 if (strcasecmp(couples[i].positive, arg) == 0) {
656 if (strcasecmp(couples[i].negative, arg) == 0) {
657 val = DTRACEOPT_UNSET;
663 val = strtoull(arg, &end, 0);
665 if (*end != '\0' || errno != 0 || val < 0)
666 return (dt_set_errno(dtp, EDT_BADOPTVAL));
670 dtp->dt_options[option] = val;
675 dt_optval_parse(const char *arg, dtrace_optval_t *rval)
677 dtrace_optval_t mul = 1;
684 switch (arg[len - 1]) {
706 *rval = strtoull(arg, &end, 0) * mul;
708 if ((mul > 1 && end != &arg[len - 1]) || (mul == 1 && *end != '\0') ||
709 *rval < 0 || errno != 0)
716 dt_opt_size(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
718 dtrace_optval_t val = 0;
720 if (arg != NULL && dt_optval_parse(arg, &val) != 0)
721 return (dt_set_errno(dtp, EDT_BADOPTVAL));
723 dtp->dt_options[option] = val;
728 dt_opt_oformat(dtrace_hdl_t *dtp, const char *arg, uintptr_t option __unused)
731 return (dt_set_errno(dtp, EDT_BADOPTVAL));
733 if (xo_set_options(NULL, arg) < 0)
734 return (dt_set_errno(dtp, EDT_BADOPTVAL));
736 return (dtrace_oformat_configure(dtp));
740 dt_opt_rate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
744 dtrace_optval_t mul = 1, val = 0;
750 { "ns", NANOSEC / NANOSEC },
751 { "nsec", NANOSEC / NANOSEC },
752 { "us", NANOSEC / MICROSEC },
753 { "usec", NANOSEC / MICROSEC },
754 { "ms", NANOSEC / MILLISEC },
755 { "msec", NANOSEC / MILLISEC },
756 { "s", NANOSEC / SEC },
757 { "sec", NANOSEC / SEC },
758 { "m", NANOSEC * (hrtime_t)60 },
759 { "min", NANOSEC * (hrtime_t)60 },
760 { "h", NANOSEC * (hrtime_t)60 * (hrtime_t)60 },
761 { "hour", NANOSEC * (hrtime_t)60 * (hrtime_t)60 },
762 { "d", NANOSEC * (hrtime_t)(24 * 60 * 60) },
763 { "day", NANOSEC * (hrtime_t)(24 * 60 * 60) },
770 val = strtoull(arg, &end, 0);
772 for (i = 0; suffix[i].name != NULL; i++) {
773 if (strcasecmp(suffix[i].name, end) == 0) {
779 if (suffix[i].name == NULL && *end != '\0' || val < 0)
780 return (dt_set_errno(dtp, EDT_BADOPTVAL));
784 * The rate has been specified in frequency-per-second.
793 dtp->dt_options[option] = val;
798 * When setting the strsize option, set the option in the dt_options array
799 * using dt_opt_size() as usual, and then update the definition of the CTF
800 * type for the D intrinsic "string" to be an array of the corresponding size.
801 * If any errors occur, reset dt_options[option] to its previous value.
804 dt_opt_strsize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
806 dtrace_optval_t val = dtp->dt_options[option];
807 ctf_file_t *fp = DT_STR_CTFP(dtp);
808 ctf_id_t type = ctf_type_resolve(fp, DT_STR_TYPE(dtp));
811 if (dt_opt_size(dtp, arg, option) != 0)
812 return (-1); /* dt_errno is set for us */
814 if (dtp->dt_options[option] > UINT_MAX) {
815 dtp->dt_options[option] = val;
816 return (dt_set_errno(dtp, EOVERFLOW));
819 if (ctf_array_info(fp, type, &r) == CTF_ERR) {
820 dtp->dt_options[option] = val;
821 dtp->dt_ctferr = ctf_errno(fp);
822 return (dt_set_errno(dtp, EDT_CTF));
825 r.ctr_nelems = (uint_t)dtp->dt_options[option];
827 if (ctf_set_array(fp, type, &r) == CTF_ERR ||
828 ctf_update(fp) == CTF_ERR) {
829 dtp->dt_options[option] = val;
830 dtp->dt_ctferr = ctf_errno(fp);
831 return (dt_set_errno(dtp, EDT_CTF));
837 static const struct {
838 const char *dtbp_name;
840 } _dtrace_bufpolicies[] = {
841 { "ring", DTRACEOPT_BUFPOLICY_RING },
842 { "fill", DTRACEOPT_BUFPOLICY_FILL },
843 { "switch", DTRACEOPT_BUFPOLICY_SWITCH },
849 dt_opt_bufpolicy(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
851 dtrace_optval_t policy = DTRACEOPT_UNSET;
855 return (dt_set_errno(dtp, EDT_BADOPTVAL));
857 for (i = 0; _dtrace_bufpolicies[i].dtbp_name != NULL; i++) {
858 if (strcmp(_dtrace_bufpolicies[i].dtbp_name, arg) == 0) {
859 policy = _dtrace_bufpolicies[i].dtbp_policy;
864 if (policy == DTRACEOPT_UNSET)
865 return (dt_set_errno(dtp, EDT_BADOPTVAL));
867 dtp->dt_options[DTRACEOPT_BUFPOLICY] = policy;
872 static const struct {
873 const char *dtbr_name;
875 } _dtrace_bufresize[] = {
876 { "auto", DTRACEOPT_BUFRESIZE_AUTO },
877 { "manual", DTRACEOPT_BUFRESIZE_MANUAL },
883 dt_opt_bufresize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
885 dtrace_optval_t policy = DTRACEOPT_UNSET;
889 return (dt_set_errno(dtp, EDT_BADOPTVAL));
891 for (i = 0; _dtrace_bufresize[i].dtbr_name != NULL; i++) {
892 if (strcmp(_dtrace_bufresize[i].dtbr_name, arg) == 0) {
893 policy = _dtrace_bufresize[i].dtbr_policy;
898 if (policy == DTRACEOPT_UNSET)
899 return (dt_set_errno(dtp, EDT_BADOPTVAL));
901 dtp->dt_options[DTRACEOPT_BUFRESIZE] = policy;
907 dt_options_load(dtrace_hdl_t *dtp)
915 * To load the option values, we need to ask the kernel to provide its
916 * DOF, which we'll sift through to look for OPTDESC sections.
919 bzero(&hdr, sizeof (dof_hdr_t));
920 hdr.dofh_loadsz = sizeof (dof_hdr_t);
923 if (dt_ioctl(dtp, DTRACEIOC_DOFGET, dof) == -1)
925 if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &dof) == -1)
928 ret = dt_set_errno(dtp, errno);
932 if (hdr.dofh_loadsz < sizeof (dof_hdr_t)) {
933 ret = dt_set_errno(dtp, EINVAL);
937 if ((dof = dt_alloc(dtp, hdr.dofh_loadsz)) == NULL) {
938 ret = dt_set_errno(dtp, EDT_NOMEM);
941 bzero(dof, sizeof (dof_hdr_t));
942 dof->dofh_loadsz = hdr.dofh_loadsz;
944 for (i = 0; i < DTRACEOPT_MAX; i++)
945 dtp->dt_options[i] = DTRACEOPT_UNSET;
948 if (dt_ioctl(dtp, DTRACEIOC_DOFGET, dof) == -1)
950 if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &dof) == -1)
953 ret = dt_set_errno(dtp, errno);
957 for (i = 0; i < dof->dofh_secnum; i++) {
958 sec = (dof_sec_t *)(uintptr_t)((uintptr_t)dof +
959 dof->dofh_secoff + i * dof->dofh_secsize);
961 if (sec->dofs_type != DOF_SECT_OPTDESC)
967 for (offs = 0; offs < sec->dofs_size; offs += sec->dofs_entsize) {
968 dof_optdesc_t *opt = (dof_optdesc_t *)(uintptr_t)
969 ((uintptr_t)dof + sec->dofs_offset + offs);
971 if (opt->dofo_strtab != DOF_SECIDX_NONE)
974 if (opt->dofo_option >= DTRACEOPT_MAX)
977 dtp->dt_options[opt->dofo_option] = opt->dofo_value;
982 if (dof != NULL && dof != &hdr)
987 typedef struct dt_option {
989 int (*o_func)(dtrace_hdl_t *, const char *, uintptr_t);
994 * Compile-time options.
996 static const dt_option_t _dtrace_ctoptions[] = {
997 { "aggpercpu", dt_opt_agg, DTRACE_A_PERCPU },
998 { "amin", dt_opt_amin },
999 { "argref", dt_opt_cflags, DTRACE_C_ARGREF },
1000 { "core", dt_opt_core },
1001 { "cpp", dt_opt_cflags, DTRACE_C_CPP },
1002 { "cpphdrs", dt_opt_cpp_hdrs },
1003 { "cpppath", dt_opt_cpp_path },
1004 { "ctypes", dt_opt_ctypes },
1005 { "defaultargs", dt_opt_cflags, DTRACE_C_DEFARG },
1006 { "dtypes", dt_opt_dtypes },
1007 { "debug", dt_opt_debug },
1008 { "define", dt_opt_cpp_opts, (uintptr_t)"-D" },
1009 { "droptags", dt_opt_droptags },
1010 { "empty", dt_opt_cflags, DTRACE_C_EMPTY },
1011 { "encoding", dt_opt_encoding },
1012 { "errtags", dt_opt_cflags, DTRACE_C_ETAGS },
1013 { "evaltime", dt_opt_evaltime },
1014 { "incdir", dt_opt_cpp_opts, (uintptr_t)"-I" },
1015 { "iregs", dt_opt_iregs },
1016 { "kdefs", dt_opt_invcflags, DTRACE_C_KNODEF },
1017 { "knodefs", dt_opt_cflags, DTRACE_C_KNODEF },
1018 { "late", dt_opt_xlate },
1019 { "lazyload", dt_opt_lazyload },
1020 { "ldpath", dt_opt_ld_path },
1021 { "libdir", dt_opt_libdir },
1022 { "linkmode", dt_opt_linkmode },
1023 { "linktype", dt_opt_linktype },
1024 { "nolibs", dt_opt_cflags, DTRACE_C_NOLIBS },
1026 { "objcopypath", dt_opt_objcopy_path },
1028 { "pgmax", dt_opt_pgmax },
1029 { "pspec", dt_opt_cflags, DTRACE_C_PSPEC },
1030 { "setenv", dt_opt_setenv, 1 },
1031 { "stdc", dt_opt_stdc },
1032 { "strip", dt_opt_dflags, DTRACE_D_STRIP },
1033 { "syslibdir", dt_opt_syslibdir },
1034 { "tree", dt_opt_tree },
1035 { "tregs", dt_opt_tregs },
1036 { "udefs", dt_opt_invcflags, DTRACE_C_UNODEF },
1037 { "undef", dt_opt_cpp_opts, (uintptr_t)"-U" },
1038 { "unodefs", dt_opt_cflags, DTRACE_C_UNODEF },
1039 { "unsetenv", dt_opt_setenv, 0 },
1040 { "verbose", dt_opt_cflags, DTRACE_C_DIFV },
1041 { "version", dt_opt_version },
1042 { "zdefs", dt_opt_cflags, DTRACE_C_ZDEFS },
1049 static const dt_option_t _dtrace_rtoptions[] = {
1050 { "aggsize", dt_opt_size, DTRACEOPT_AGGSIZE },
1051 { "bufsize", dt_opt_size, DTRACEOPT_BUFSIZE },
1052 { "bufpolicy", dt_opt_bufpolicy, DTRACEOPT_BUFPOLICY },
1053 { "bufresize", dt_opt_bufresize, DTRACEOPT_BUFRESIZE },
1054 { "cleanrate", dt_opt_rate, DTRACEOPT_CLEANRATE },
1055 { "cpu", dt_opt_runtime, DTRACEOPT_CPU },
1056 { "destructive", dt_opt_runtime, DTRACEOPT_DESTRUCTIVE },
1057 { "dynvarsize", dt_opt_size, DTRACEOPT_DYNVARSIZE },
1058 { "grabanon", dt_opt_runtime, DTRACEOPT_GRABANON },
1059 { "jstackframes", dt_opt_runtime, DTRACEOPT_JSTACKFRAMES },
1060 { "jstackstrsize", dt_opt_size, DTRACEOPT_JSTACKSTRSIZE },
1061 { "nspec", dt_opt_runtime, DTRACEOPT_NSPEC },
1062 { "oformat", dt_opt_oformat, 0 },
1063 { "specsize", dt_opt_size, DTRACEOPT_SPECSIZE },
1064 { "stackframes", dt_opt_runtime, DTRACEOPT_STACKFRAMES },
1065 { "statusrate", dt_opt_rate, DTRACEOPT_STATUSRATE },
1066 { "strsize", dt_opt_strsize, DTRACEOPT_STRSIZE },
1067 { "ustackframes", dt_opt_runtime, DTRACEOPT_USTACKFRAMES },
1068 { "temporal", dt_opt_runtime, DTRACEOPT_TEMPORAL },
1073 * Dynamic run-time options.
1075 static const dt_option_t _dtrace_drtoptions[] = {
1076 { "agghist", dt_opt_runtime, DTRACEOPT_AGGHIST },
1077 { "aggpack", dt_opt_runtime, DTRACEOPT_AGGPACK },
1078 { "aggrate", dt_opt_rate, DTRACEOPT_AGGRATE },
1079 { "aggsortkey", dt_opt_runtime, DTRACEOPT_AGGSORTKEY },
1080 { "aggsortkeypos", dt_opt_runtime, DTRACEOPT_AGGSORTKEYPOS },
1081 { "aggsortpos", dt_opt_runtime, DTRACEOPT_AGGSORTPOS },
1082 { "aggsortrev", dt_opt_runtime, DTRACEOPT_AGGSORTREV },
1083 { "aggzoom", dt_opt_runtime, DTRACEOPT_AGGZOOM },
1084 { "flowindent", dt_opt_runtime, DTRACEOPT_FLOWINDENT },
1085 { "quiet", dt_opt_runtime, DTRACEOPT_QUIET },
1086 { "rawbytes", dt_opt_runtime, DTRACEOPT_RAWBYTES },
1087 { "stackindent", dt_opt_runtime, DTRACEOPT_STACKINDENT },
1088 { "switchrate", dt_opt_rate, DTRACEOPT_SWITCHRATE },
1093 dtrace_getopt(dtrace_hdl_t *dtp, const char *opt, dtrace_optval_t *val)
1095 const dt_option_t *op;
1098 return (dt_set_errno(dtp, EINVAL));
1101 * We only need to search the run-time options -- it's not legal
1102 * to get the values of compile-time options.
1104 for (op = _dtrace_rtoptions; op->o_name != NULL; op++) {
1105 if (strcmp(op->o_name, opt) == 0) {
1106 *val = dtp->dt_options[op->o_option];
1111 for (op = _dtrace_drtoptions; op->o_name != NULL; op++) {
1112 if (strcmp(op->o_name, opt) == 0) {
1113 *val = dtp->dt_options[op->o_option];
1118 return (dt_set_errno(dtp, EDT_BADOPTNAME));
1122 dtrace_setopt(dtrace_hdl_t *dtp, const char *opt, const char *val)
1124 const dt_option_t *op;
1127 return (dt_set_errno(dtp, EINVAL));
1129 for (op = _dtrace_ctoptions; op->o_name != NULL; op++) {
1130 if (strcmp(op->o_name, opt) == 0)
1131 return (op->o_func(dtp, val, op->o_option));
1134 for (op = _dtrace_drtoptions; op->o_name != NULL; op++) {
1135 if (strcmp(op->o_name, opt) == 0)
1136 return (op->o_func(dtp, val, op->o_option));
1139 for (op = _dtrace_rtoptions; op->o_name != NULL; op++) {
1140 if (strcmp(op->o_name, opt) == 0) {
1142 * Only dynamic run-time options may be set while
1143 * tracing is active.
1146 return (dt_set_errno(dtp, EDT_ACTIVE));
1148 return (op->o_func(dtp, val, op->o_option));
1152 return (dt_set_errno(dtp, EDT_BADOPTNAME));