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.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <sys/resource.h>
31 #include <sys/types.h>
45 #include <dt_string.h>
48 dt_opt_agg(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
50 dt_aggregate_t *agp = &dtp->dt_aggregate;
53 return (dt_set_errno(dtp, EDT_BADOPTVAL));
55 agp->dtat_flags |= option;
61 dt_opt_amin(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
63 char str[DTRACE_ATTR2STR_MAX];
64 dtrace_attribute_t attr;
66 if (arg == NULL || dtrace_str2attr(arg, &attr) == -1)
67 return (dt_set_errno(dtp, EDT_BADOPTVAL));
69 dt_dprintf("set compiler attribute minimum to %s\n",
70 dtrace_attr2str(attr, str, sizeof (str)));
72 if (dtp->dt_pcb != NULL) {
73 dtp->dt_pcb->pcb_cflags |= DTRACE_C_EATTR;
74 dtp->dt_pcb->pcb_amin = attr;
76 dtp->dt_cflags |= DTRACE_C_EATTR;
86 const char msg[] = "libdtrace DEBUG: [ forcing coredump ]\n";
91 (void) write(STDERR_FILENO, msg, sizeof (msg) - 1);
93 act.sa_handler = SIG_DFL;
96 (void) sigemptyset(&act.sa_mask);
97 (void) sigaction(SIGABRT, &act, NULL);
99 lim.rlim_cur = RLIM_INFINITY;
100 lim.rlim_max = RLIM_INFINITY;
102 (void) setrlimit(RLIMIT_CORE, &lim);
108 dt_opt_core(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
110 static int enabled = 0;
113 return (dt_set_errno(dtp, EDT_BADOPTVAL));
115 if (enabled++ || atexit(dt_coredump) == 0)
118 return (dt_set_errno(dtp, errno));
123 dt_opt_cpp_hdrs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
126 return (dt_set_errno(dtp, EDT_BADOPTVAL));
128 if (dtp->dt_pcb != NULL)
129 return (dt_set_errno(dtp, EDT_BADOPTCTX));
131 if (dt_cpp_add_arg(dtp, "-H") == NULL)
132 return (dt_set_errno(dtp, EDT_NOMEM));
139 dt_opt_cpp_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
144 return (dt_set_errno(dtp, EDT_BADOPTVAL));
146 if (dtp->dt_pcb != NULL)
147 return (dt_set_errno(dtp, EDT_BADOPTCTX));
149 if ((cpp = strdup(arg)) == NULL)
150 return (dt_set_errno(dtp, EDT_NOMEM));
152 dtp->dt_cpp_argv[0] = (char *)strbasename(cpp);
153 free(dtp->dt_cpp_path);
154 dtp->dt_cpp_path = cpp;
160 dt_opt_cpp_opts(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
164 const char *opt = (const char *)option;
166 if (opt == NULL || arg == NULL)
167 return (dt_set_errno(dtp, EDT_BADOPTVAL));
169 if (dtp->dt_pcb != NULL)
170 return (dt_set_errno(dtp, EDT_BADOPTCTX));
172 len = strlen(opt) + strlen(arg) + 1;
175 (void) strcpy(buf, opt);
176 (void) strcat(buf, arg);
178 if (dt_cpp_add_arg(dtp, buf) == NULL)
179 return (dt_set_errno(dtp, EDT_NOMEM));
186 dt_opt_ctypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
191 return (dt_set_errno(dtp, EDT_BADOPTVAL));
193 if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1)
194 return (dt_set_errno(dtp, errno));
196 (void) close(dtp->dt_cdefs_fd);
197 dtp->dt_cdefs_fd = fd;
203 dt_opt_droptags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
205 dtp->dt_droptags = 1;
211 dt_opt_dtypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
216 return (dt_set_errno(dtp, EDT_BADOPTVAL));
218 if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1)
219 return (dt_set_errno(dtp, errno));
221 (void) close(dtp->dt_ddefs_fd);
222 dtp->dt_ddefs_fd = fd;
228 dt_opt_debug(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
231 return (dt_set_errno(dtp, EDT_BADOPTVAL));
239 dt_opt_iregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
243 if (arg == NULL || (n = atoi(arg)) <= 0)
244 return (dt_set_errno(dtp, EDT_BADOPTVAL));
246 dtp->dt_conf.dtc_difintregs = n;
252 dt_opt_lazyload(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
254 dtp->dt_lazyload = 1;
261 dt_opt_ld_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
266 return (dt_set_errno(dtp, EDT_BADOPTVAL));
268 if (dtp->dt_pcb != NULL)
269 return (dt_set_errno(dtp, EDT_BADOPTCTX));
271 if ((ld = strdup(arg)) == NULL)
272 return (dt_set_errno(dtp, EDT_NOMEM));
274 free(dtp->dt_ld_path);
275 dtp->dt_ld_path = ld;
282 dt_opt_libdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
287 return (dt_set_errno(dtp, EDT_BADOPTVAL));
289 if ((dp = malloc(sizeof (dt_dirpath_t))) == NULL ||
290 (dp->dir_path = strdup(arg)) == NULL) {
292 return (dt_set_errno(dtp, EDT_NOMEM));
295 dt_list_append(&dtp->dt_lib_path, dp);
301 dt_opt_linkmode(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
304 return (dt_set_errno(dtp, EDT_BADOPTVAL));
306 if (strcmp(arg, "kernel") == 0)
307 dtp->dt_linkmode = DT_LINK_KERNEL;
308 else if (strcmp(arg, "primary") == 0)
309 dtp->dt_linkmode = DT_LINK_PRIMARY;
310 else if (strcmp(arg, "dynamic") == 0)
311 dtp->dt_linkmode = DT_LINK_DYNAMIC;
312 else if (strcmp(arg, "static") == 0)
313 dtp->dt_linkmode = DT_LINK_STATIC;
315 return (dt_set_errno(dtp, EDT_BADOPTVAL));
322 dt_opt_linktype(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
325 return (dt_set_errno(dtp, EDT_BADOPTVAL));
327 if (strcasecmp(arg, "elf") == 0)
328 dtp->dt_linktype = DT_LTYP_ELF;
329 else if (strcasecmp(arg, "dof") == 0)
330 dtp->dt_linktype = DT_LTYP_DOF;
332 return (dt_set_errno(dtp, EDT_BADOPTVAL));
339 dt_opt_evaltime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
342 return (dt_set_errno(dtp, EDT_BADOPTVAL));
344 if (strcmp(arg, "exec") == 0)
345 dtp->dt_prcmode = DT_PROC_STOP_CREATE;
346 else if (strcmp(arg, "preinit") == 0)
347 dtp->dt_prcmode = DT_PROC_STOP_PREINIT;
348 else if (strcmp(arg, "postinit") == 0)
349 dtp->dt_prcmode = DT_PROC_STOP_POSTINIT;
350 else if (strcmp(arg, "main") == 0)
351 dtp->dt_prcmode = DT_PROC_STOP_MAIN;
353 return (dt_set_errno(dtp, EDT_BADOPTVAL));
360 dt_opt_pgmax(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
364 if (arg == NULL || (n = atoi(arg)) < 0)
365 return (dt_set_errno(dtp, EDT_BADOPTVAL));
367 dtp->dt_procs->dph_lrulim = n;
373 dt_opt_stdc(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
376 return (dt_set_errno(dtp, EDT_BADOPTVAL));
378 if (dtp->dt_pcb != NULL)
379 return (dt_set_errno(dtp, EDT_BADOPTCTX));
381 if (strcmp(arg, "a") == 0)
382 dtp->dt_stdcmode = DT_STDC_XA;
383 else if (strcmp(arg, "c") == 0)
384 dtp->dt_stdcmode = DT_STDC_XC;
385 else if (strcmp(arg, "s") == 0)
386 dtp->dt_stdcmode = DT_STDC_XS;
387 else if (strcmp(arg, "t") == 0)
388 dtp->dt_stdcmode = DT_STDC_XT;
390 return (dt_set_errno(dtp, EDT_BADOPTVAL));
397 dt_opt_syslibdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
399 dt_dirpath_t *dp = dt_list_next(&dtp->dt_lib_path);
403 return (dt_set_errno(dtp, EDT_BADOPTVAL));
405 if ((path = strdup(arg)) == NULL)
406 return (dt_set_errno(dtp, EDT_NOMEM));
417 dt_opt_tree(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
421 if (arg == NULL || (m = atoi(arg)) <= 0)
422 return (dt_set_errno(dtp, EDT_BADOPTVAL));
424 dtp->dt_treedump = m;
430 dt_opt_tregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
434 if (arg == NULL || (n = atoi(arg)) <= 0)
435 return (dt_set_errno(dtp, EDT_BADOPTVAL));
437 dtp->dt_conf.dtc_diftupregs = n;
443 dt_opt_xlate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
446 return (dt_set_errno(dtp, EDT_BADOPTVAL));
448 if (strcmp(arg, "dynamic") == 0)
449 dtp->dt_xlatemode = DT_XL_DYNAMIC;
450 else if (strcmp(arg, "static") == 0)
451 dtp->dt_xlatemode = DT_XL_STATIC;
453 return (dt_set_errno(dtp, EDT_BADOPTVAL));
460 dt_opt_cflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
463 return (dt_set_errno(dtp, EDT_BADOPTVAL));
465 if (dtp->dt_pcb != NULL)
466 dtp->dt_pcb->pcb_cflags |= option;
468 dtp->dt_cflags |= option;
474 dt_opt_dflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
477 return (dt_set_errno(dtp, EDT_BADOPTVAL));
479 dtp->dt_dflags |= option;
484 dt_opt_invcflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
487 return (dt_set_errno(dtp, EDT_BADOPTVAL));
489 if (dtp->dt_pcb != NULL)
490 dtp->dt_pcb->pcb_cflags &= ~option;
492 dtp->dt_cflags &= ~option;
499 dt_opt_version(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
504 return (dt_set_errno(dtp, EDT_BADOPTVAL));
506 if (dt_version_str2num(arg, &v) == -1)
507 return (dt_set_errno(dtp, EDT_VERSINVAL));
509 if (!dt_version_defined(v))
510 return (dt_set_errno(dtp, EDT_VERSUNDEF));
512 return (dt_reduce(dtp, v));
516 dt_opt_runtime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
519 dtrace_optval_t val = 0;
527 { "enable", "disable" },
528 { "enabled", "disabled" },
536 if (arg[0] == '\0') {
537 val = DTRACEOPT_UNSET;
541 for (i = 0; couples[i].positive != NULL; i++) {
542 if (strcasecmp(couples[i].positive, arg) == 0) {
547 if (strcasecmp(couples[i].negative, arg) == 0) {
548 val = DTRACEOPT_UNSET;
554 val = strtoull(arg, &end, 0);
556 if (*end != '\0' || errno != 0 || val < 0)
557 return (dt_set_errno(dtp, EDT_BADOPTVAL));
561 dtp->dt_options[option] = val;
566 dt_optval_parse(const char *arg, dtrace_optval_t *rval)
568 dtrace_optval_t mul = 1;
575 switch (arg[len - 1]) {
597 *rval = strtoull(arg, &end, 0) * mul;
599 if ((mul > 1 && end != &arg[len - 1]) || (mul == 1 && *end != '\0') ||
600 *rval < 0 || errno != 0)
607 dt_opt_size(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
609 dtrace_optval_t val = 0;
611 if (arg != NULL && dt_optval_parse(arg, &val) != 0)
612 return (dt_set_errno(dtp, EDT_BADOPTVAL));
614 dtp->dt_options[option] = val;
619 dt_opt_rate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
623 dtrace_optval_t mul = 1, val = 0;
629 { "ns", NANOSEC / NANOSEC },
630 { "nsec", NANOSEC / NANOSEC },
631 { "us", NANOSEC / MICROSEC },
632 { "usec", NANOSEC / MICROSEC },
633 { "ms", NANOSEC / MILLISEC },
634 { "msec", NANOSEC / MILLISEC },
635 { "s", NANOSEC / SEC },
636 { "sec", NANOSEC / SEC },
637 { "m", NANOSEC * (hrtime_t)60 },
638 { "min", NANOSEC * (hrtime_t)60 },
639 { "h", NANOSEC * (hrtime_t)60 * (hrtime_t)60 },
640 { "hour", NANOSEC * (hrtime_t)60 * (hrtime_t)60 },
641 { "d", NANOSEC * (hrtime_t)(24 * 60 * 60) },
642 { "day", NANOSEC * (hrtime_t)(24 * 60 * 60) },
649 val = strtoull(arg, &end, 0);
651 for (i = 0; suffix[i].name != NULL; i++) {
652 if (strcasecmp(suffix[i].name, end) == 0) {
658 if (suffix[i].name == NULL && *end != '\0' || val < 0)
659 return (dt_set_errno(dtp, EDT_BADOPTVAL));
663 * The rate has been specified in frequency-per-second.
672 dtp->dt_options[option] = val;
677 * When setting the strsize option, set the option in the dt_options array
678 * using dt_opt_size() as usual, and then update the definition of the CTF
679 * type for the D intrinsic "string" to be an array of the corresponding size.
680 * If any errors occur, reset dt_options[option] to its previous value.
683 dt_opt_strsize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
685 dtrace_optval_t val = dtp->dt_options[option];
686 ctf_file_t *fp = DT_STR_CTFP(dtp);
687 ctf_id_t type = ctf_type_resolve(fp, DT_STR_TYPE(dtp));
690 if (dt_opt_size(dtp, arg, option) != 0)
691 return (-1); /* dt_errno is set for us */
693 if (dtp->dt_options[option] > UINT_MAX) {
694 dtp->dt_options[option] = val;
695 return (dt_set_errno(dtp, EOVERFLOW));
698 if (ctf_array_info(fp, type, &r) == CTF_ERR) {
699 dtp->dt_options[option] = val;
700 dtp->dt_ctferr = ctf_errno(fp);
701 return (dt_set_errno(dtp, EDT_CTF));
704 r.ctr_nelems = (uint_t)dtp->dt_options[option];
706 if (ctf_set_array(fp, type, &r) == CTF_ERR ||
707 ctf_update(fp) == CTF_ERR) {
708 dtp->dt_options[option] = val;
709 dtp->dt_ctferr = ctf_errno(fp);
710 return (dt_set_errno(dtp, EDT_CTF));
716 static const struct {
717 const char *dtbp_name;
719 } _dtrace_bufpolicies[] = {
720 { "ring", DTRACEOPT_BUFPOLICY_RING },
721 { "fill", DTRACEOPT_BUFPOLICY_FILL },
722 { "switch", DTRACEOPT_BUFPOLICY_SWITCH },
728 dt_opt_bufpolicy(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
730 dtrace_optval_t policy = DTRACEOPT_UNSET;
734 return (dt_set_errno(dtp, EDT_BADOPTVAL));
736 for (i = 0; _dtrace_bufpolicies[i].dtbp_name != NULL; i++) {
737 if (strcmp(_dtrace_bufpolicies[i].dtbp_name, arg) == 0) {
738 policy = _dtrace_bufpolicies[i].dtbp_policy;
743 if (policy == DTRACEOPT_UNSET)
744 return (dt_set_errno(dtp, EDT_BADOPTVAL));
746 dtp->dt_options[DTRACEOPT_BUFPOLICY] = policy;
751 static const struct {
752 const char *dtbr_name;
754 } _dtrace_bufresize[] = {
755 { "auto", DTRACEOPT_BUFRESIZE_AUTO },
756 { "manual", DTRACEOPT_BUFRESIZE_MANUAL },
762 dt_opt_bufresize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
764 dtrace_optval_t policy = DTRACEOPT_UNSET;
768 return (dt_set_errno(dtp, EDT_BADOPTVAL));
770 for (i = 0; _dtrace_bufresize[i].dtbr_name != NULL; i++) {
771 if (strcmp(_dtrace_bufresize[i].dtbr_name, arg) == 0) {
772 policy = _dtrace_bufresize[i].dtbr_policy;
777 if (policy == DTRACEOPT_UNSET)
778 return (dt_set_errno(dtp, EDT_BADOPTVAL));
780 dtp->dt_options[DTRACEOPT_BUFRESIZE] = policy;
786 dt_options_load(dtrace_hdl_t *dtp)
794 * To load the option values, we need to ask the kernel to provide its
795 * DOF, which we'll sift through to look for OPTDESC sections.
797 bzero(&hdr, sizeof (dof_hdr_t));
798 hdr.dofh_loadsz = sizeof (dof_hdr_t);
801 if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &hdr) == -1)
804 if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &dof) == -1)
806 return (dt_set_errno(dtp, errno));
808 if (hdr.dofh_loadsz < sizeof (dof_hdr_t))
809 return (dt_set_errno(dtp, EINVAL));
811 dof = alloca(hdr.dofh_loadsz);
812 bzero(dof, sizeof (dof_hdr_t));
813 dof->dofh_loadsz = hdr.dofh_loadsz;
815 for (i = 0; i < DTRACEOPT_MAX; i++)
816 dtp->dt_options[i] = DTRACEOPT_UNSET;
819 if (dt_ioctl(dtp, DTRACEIOC_DOFGET, dof) == -1)
821 if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &dof) == -1)
823 return (dt_set_errno(dtp, errno));
825 for (i = 0; i < dof->dofh_secnum; i++) {
826 sec = (dof_sec_t *)(uintptr_t)((uintptr_t)dof +
827 dof->dofh_secoff + i * dof->dofh_secsize);
829 if (sec->dofs_type != DOF_SECT_OPTDESC)
835 for (offs = 0; offs < sec->dofs_size; offs += sec->dofs_entsize) {
836 dof_optdesc_t *opt = (dof_optdesc_t *)(uintptr_t)
837 ((uintptr_t)dof + sec->dofs_offset + offs);
839 if (opt->dofo_strtab != DOF_SECIDX_NONE)
842 if (opt->dofo_option >= DTRACEOPT_MAX)
845 dtp->dt_options[opt->dofo_option] = opt->dofo_value;
853 dt_opt_preallocate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
855 dtrace_optval_t size;
858 if (arg == NULL || dt_optval_parse(arg, &size) != 0)
859 return (dt_set_errno(dtp, EDT_BADOPTVAL));
864 if ((p = dt_zalloc(dtp, size)) == NULL) {
867 } while ((p = dt_zalloc(dtp, size)) == NULL);
875 typedef struct dt_option {
877 int (*o_func)(dtrace_hdl_t *, const char *, uintptr_t);
882 * Compile-time options.
884 static const dt_option_t _dtrace_ctoptions[] = {
885 { "aggpercpu", dt_opt_agg, DTRACE_A_PERCPU },
886 { "amin", dt_opt_amin },
887 { "argref", dt_opt_cflags, DTRACE_C_ARGREF },
888 { "core", dt_opt_core },
889 { "cpp", dt_opt_cflags, DTRACE_C_CPP },
890 { "cpphdrs", dt_opt_cpp_hdrs },
891 { "cpppath", dt_opt_cpp_path },
892 { "ctypes", dt_opt_ctypes },
893 { "defaultargs", dt_opt_cflags, DTRACE_C_DEFARG },
894 { "dtypes", dt_opt_dtypes },
895 { "debug", dt_opt_debug },
896 { "define", dt_opt_cpp_opts, (uintptr_t)"-D" },
897 { "droptags", dt_opt_droptags },
898 { "empty", dt_opt_cflags, DTRACE_C_EMPTY },
899 { "errtags", dt_opt_cflags, DTRACE_C_ETAGS },
900 { "evaltime", dt_opt_evaltime },
901 { "incdir", dt_opt_cpp_opts, (uintptr_t)"-I" },
902 { "iregs", dt_opt_iregs },
903 { "kdefs", dt_opt_invcflags, DTRACE_C_KNODEF },
904 { "knodefs", dt_opt_cflags, DTRACE_C_KNODEF },
905 { "late", dt_opt_xlate },
906 { "lazyload", dt_opt_lazyload },
907 { "ldpath", dt_opt_ld_path },
908 { "libdir", dt_opt_libdir },
909 { "linkmode", dt_opt_linkmode },
910 { "linktype", dt_opt_linktype },
911 { "nolibs", dt_opt_cflags, DTRACE_C_NOLIBS },
912 { "pgmax", dt_opt_pgmax },
913 { "preallocate", dt_opt_preallocate },
914 { "pspec", dt_opt_cflags, DTRACE_C_PSPEC },
915 { "stdc", dt_opt_stdc },
916 { "strip", dt_opt_dflags, DTRACE_D_STRIP },
917 { "syslibdir", dt_opt_syslibdir },
918 { "tree", dt_opt_tree },
919 { "tregs", dt_opt_tregs },
920 { "udefs", dt_opt_invcflags, DTRACE_C_UNODEF },
921 { "undef", dt_opt_cpp_opts, (uintptr_t)"-U" },
922 { "unodefs", dt_opt_cflags, DTRACE_C_UNODEF },
923 { "verbose", dt_opt_cflags, DTRACE_C_DIFV },
924 { "version", dt_opt_version },
925 { "zdefs", dt_opt_cflags, DTRACE_C_ZDEFS },
932 static const dt_option_t _dtrace_rtoptions[] = {
933 { "aggsize", dt_opt_size, DTRACEOPT_AGGSIZE },
934 { "bufsize", dt_opt_size, DTRACEOPT_BUFSIZE },
935 { "bufpolicy", dt_opt_bufpolicy, DTRACEOPT_BUFPOLICY },
936 { "bufresize", dt_opt_bufresize, DTRACEOPT_BUFRESIZE },
937 { "cleanrate", dt_opt_rate, DTRACEOPT_CLEANRATE },
938 { "cpu", dt_opt_runtime, DTRACEOPT_CPU },
939 { "destructive", dt_opt_runtime, DTRACEOPT_DESTRUCTIVE },
940 { "dynvarsize", dt_opt_size, DTRACEOPT_DYNVARSIZE },
941 { "grabanon", dt_opt_runtime, DTRACEOPT_GRABANON },
942 { "jstackframes", dt_opt_runtime, DTRACEOPT_JSTACKFRAMES },
943 { "jstackstrsize", dt_opt_size, DTRACEOPT_JSTACKSTRSIZE },
944 { "nspec", dt_opt_runtime, DTRACEOPT_NSPEC },
945 { "specsize", dt_opt_size, DTRACEOPT_SPECSIZE },
946 { "stackframes", dt_opt_runtime, DTRACEOPT_STACKFRAMES },
947 { "statusrate", dt_opt_rate, DTRACEOPT_STATUSRATE },
948 { "strsize", dt_opt_strsize, DTRACEOPT_STRSIZE },
949 { "ustackframes", dt_opt_runtime, DTRACEOPT_USTACKFRAMES },
954 * Dynamic run-time options.
956 static const dt_option_t _dtrace_drtoptions[] = {
957 { "aggrate", dt_opt_rate, DTRACEOPT_AGGRATE },
958 { "aggsortkey", dt_opt_runtime, DTRACEOPT_AGGSORTKEY },
959 { "aggsortkeypos", dt_opt_runtime, DTRACEOPT_AGGSORTKEYPOS },
960 { "aggsortpos", dt_opt_runtime, DTRACEOPT_AGGSORTPOS },
961 { "aggsortrev", dt_opt_runtime, DTRACEOPT_AGGSORTREV },
962 { "flowindent", dt_opt_runtime, DTRACEOPT_FLOWINDENT },
963 { "quiet", dt_opt_runtime, DTRACEOPT_QUIET },
964 { "rawbytes", dt_opt_runtime, DTRACEOPT_RAWBYTES },
965 { "stackindent", dt_opt_runtime, DTRACEOPT_STACKINDENT },
966 { "switchrate", dt_opt_rate, DTRACEOPT_SWITCHRATE },
971 dtrace_getopt(dtrace_hdl_t *dtp, const char *opt, dtrace_optval_t *val)
973 const dt_option_t *op;
976 return (dt_set_errno(dtp, EINVAL));
979 * We only need to search the run-time options -- it's not legal
980 * to get the values of compile-time options.
982 for (op = _dtrace_rtoptions; op->o_name != NULL; op++) {
983 if (strcmp(op->o_name, opt) == 0) {
984 *val = dtp->dt_options[op->o_option];
989 for (op = _dtrace_drtoptions; op->o_name != NULL; op++) {
990 if (strcmp(op->o_name, opt) == 0) {
991 *val = dtp->dt_options[op->o_option];
996 return (dt_set_errno(dtp, EDT_BADOPTNAME));
1000 dtrace_setopt(dtrace_hdl_t *dtp, const char *opt, const char *val)
1002 const dt_option_t *op;
1005 return (dt_set_errno(dtp, EINVAL));
1007 for (op = _dtrace_ctoptions; op->o_name != NULL; op++) {
1008 if (strcmp(op->o_name, opt) == 0)
1009 return (op->o_func(dtp, val, op->o_option));
1012 for (op = _dtrace_drtoptions; op->o_name != NULL; op++) {
1013 if (strcmp(op->o_name, opt) == 0)
1014 return (op->o_func(dtp, val, op->o_option));
1017 for (op = _dtrace_rtoptions; op->o_name != NULL; op++) {
1018 if (strcmp(op->o_name, opt) == 0) {
1020 * Only dynamic run-time options may be set while
1021 * tracing is active.
1024 return (dt_set_errno(dtp, EDT_ACTIVE));
1026 return (op->o_func(dtp, val, op->o_option));
1030 return (dt_set_errno(dtp, EDT_BADOPTNAME));