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"
30 * Copyright (c) 2012 by Delphix. All rights reserved.
33 #include <sys/resource.h>
35 #include <sys/types.h>
49 #include <dt_string.h>
52 dt_opt_agg(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
54 dt_aggregate_t *agp = &dtp->dt_aggregate;
57 return (dt_set_errno(dtp, EDT_BADOPTVAL));
59 agp->dtat_flags |= option;
65 dt_opt_amin(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
67 char str[DTRACE_ATTR2STR_MAX];
68 dtrace_attribute_t attr;
70 if (arg == NULL || dtrace_str2attr(arg, &attr) == -1)
71 return (dt_set_errno(dtp, EDT_BADOPTVAL));
73 dt_dprintf("set compiler attribute minimum to %s\n",
74 dtrace_attr2str(attr, str, sizeof (str)));
76 if (dtp->dt_pcb != NULL) {
77 dtp->dt_pcb->pcb_cflags |= DTRACE_C_EATTR;
78 dtp->dt_pcb->pcb_amin = attr;
80 dtp->dt_cflags |= DTRACE_C_EATTR;
90 const char msg[] = "libdtrace DEBUG: [ forcing coredump ]\n";
95 (void) write(STDERR_FILENO, msg, sizeof (msg) - 1);
97 act.sa_handler = SIG_DFL;
100 (void) sigemptyset(&act.sa_mask);
101 (void) sigaction(SIGABRT, &act, NULL);
103 lim.rlim_cur = RLIM_INFINITY;
104 lim.rlim_max = RLIM_INFINITY;
106 (void) setrlimit(RLIMIT_CORE, &lim);
112 dt_opt_core(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
114 static int enabled = 0;
117 return (dt_set_errno(dtp, EDT_BADOPTVAL));
119 if (enabled++ || atexit(dt_coredump) == 0)
122 return (dt_set_errno(dtp, errno));
127 dt_opt_cpp_hdrs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
130 return (dt_set_errno(dtp, EDT_BADOPTVAL));
132 if (dtp->dt_pcb != NULL)
133 return (dt_set_errno(dtp, EDT_BADOPTCTX));
135 if (dt_cpp_add_arg(dtp, "-H") == NULL)
136 return (dt_set_errno(dtp, EDT_NOMEM));
143 dt_opt_cpp_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
148 return (dt_set_errno(dtp, EDT_BADOPTVAL));
150 if (dtp->dt_pcb != NULL)
151 return (dt_set_errno(dtp, EDT_BADOPTCTX));
153 if ((cpp = strdup(arg)) == NULL)
154 return (dt_set_errno(dtp, EDT_NOMEM));
156 dtp->dt_cpp_argv[0] = (char *)strbasename(cpp);
157 free(dtp->dt_cpp_path);
158 dtp->dt_cpp_path = cpp;
164 dt_opt_cpp_opts(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
168 const char *opt = (const char *)option;
170 if (opt == NULL || arg == NULL)
171 return (dt_set_errno(dtp, EDT_BADOPTVAL));
173 if (dtp->dt_pcb != NULL)
174 return (dt_set_errno(dtp, EDT_BADOPTCTX));
176 len = strlen(opt) + strlen(arg) + 1;
179 (void) strcpy(buf, opt);
180 (void) strcat(buf, arg);
182 if (dt_cpp_add_arg(dtp, buf) == NULL)
183 return (dt_set_errno(dtp, EDT_NOMEM));
190 dt_opt_ctypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
195 return (dt_set_errno(dtp, EDT_BADOPTVAL));
197 if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1)
198 return (dt_set_errno(dtp, errno));
200 (void) close(dtp->dt_cdefs_fd);
201 dtp->dt_cdefs_fd = fd;
207 dt_opt_droptags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
209 dtp->dt_droptags = 1;
215 dt_opt_dtypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
220 return (dt_set_errno(dtp, EDT_BADOPTVAL));
222 if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1)
223 return (dt_set_errno(dtp, errno));
225 (void) close(dtp->dt_ddefs_fd);
226 dtp->dt_ddefs_fd = fd;
232 dt_opt_debug(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
235 return (dt_set_errno(dtp, EDT_BADOPTVAL));
243 dt_opt_iregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
247 if (arg == NULL || (n = atoi(arg)) <= 0)
248 return (dt_set_errno(dtp, EDT_BADOPTVAL));
250 dtp->dt_conf.dtc_difintregs = n;
256 dt_opt_lazyload(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
258 dtp->dt_lazyload = 1;
265 dt_opt_ld_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
270 return (dt_set_errno(dtp, EDT_BADOPTVAL));
272 if (dtp->dt_pcb != NULL)
273 return (dt_set_errno(dtp, EDT_BADOPTCTX));
275 if ((ld = strdup(arg)) == NULL)
276 return (dt_set_errno(dtp, EDT_NOMEM));
278 free(dtp->dt_ld_path);
279 dtp->dt_ld_path = ld;
286 dt_opt_libdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
291 return (dt_set_errno(dtp, EDT_BADOPTVAL));
293 if ((dp = malloc(sizeof (dt_dirpath_t))) == NULL ||
294 (dp->dir_path = strdup(arg)) == NULL) {
296 return (dt_set_errno(dtp, EDT_NOMEM));
299 dt_list_append(&dtp->dt_lib_path, dp);
305 dt_opt_linkmode(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
308 return (dt_set_errno(dtp, EDT_BADOPTVAL));
310 if (strcmp(arg, "kernel") == 0)
311 dtp->dt_linkmode = DT_LINK_KERNEL;
312 else if (strcmp(arg, "primary") == 0)
313 dtp->dt_linkmode = DT_LINK_PRIMARY;
314 else if (strcmp(arg, "dynamic") == 0)
315 dtp->dt_linkmode = DT_LINK_DYNAMIC;
316 else if (strcmp(arg, "static") == 0)
317 dtp->dt_linkmode = DT_LINK_STATIC;
319 return (dt_set_errno(dtp, EDT_BADOPTVAL));
326 dt_opt_linktype(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
329 return (dt_set_errno(dtp, EDT_BADOPTVAL));
331 if (strcasecmp(arg, "elf") == 0)
332 dtp->dt_linktype = DT_LTYP_ELF;
333 else if (strcasecmp(arg, "dof") == 0)
334 dtp->dt_linktype = DT_LTYP_DOF;
336 return (dt_set_errno(dtp, EDT_BADOPTVAL));
343 dt_opt_evaltime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
346 return (dt_set_errno(dtp, EDT_BADOPTVAL));
348 if (strcmp(arg, "exec") == 0)
349 dtp->dt_prcmode = DT_PROC_STOP_CREATE;
350 else if (strcmp(arg, "preinit") == 0)
351 dtp->dt_prcmode = DT_PROC_STOP_PREINIT;
352 else if (strcmp(arg, "postinit") == 0)
353 dtp->dt_prcmode = DT_PROC_STOP_POSTINIT;
354 else if (strcmp(arg, "main") == 0)
355 dtp->dt_prcmode = DT_PROC_STOP_MAIN;
357 return (dt_set_errno(dtp, EDT_BADOPTVAL));
364 dt_opt_pgmax(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
368 if (arg == NULL || (n = atoi(arg)) < 0)
369 return (dt_set_errno(dtp, EDT_BADOPTVAL));
371 dtp->dt_procs->dph_lrulim = n;
376 dt_opt_setenv(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
383 * We can't effectively set environment variables from #pragma lines
384 * since the processes have already been spawned.
386 if (dtp->dt_pcb != NULL)
387 return (dt_set_errno(dtp, EDT_BADOPTCTX));
390 return (dt_set_errno(dtp, EDT_BADOPTVAL));
392 if (!option && strchr(arg, '=') != NULL)
393 return (dt_set_errno(dtp, EDT_BADOPTVAL));
395 for (i = 1, p = dtp->dt_proc_env; *p != NULL; i++, p++)
398 for (p = dtp->dt_proc_env; *p != NULL; p++) {
399 var = strchr(*p, '=');
401 var = *p + strlen(*p);
402 if (strncmp(*p, arg, var - *p) == 0) {
404 *p = dtp->dt_proc_env[i - 1];
405 dtp->dt_proc_env[i - 1] = NULL;
411 if ((var = strdup(arg)) == NULL)
412 return (dt_set_errno(dtp, EDT_NOMEM));
414 if ((p = dt_alloc(dtp, sizeof (char *) * (i + 1))) == NULL) {
416 return (dt_set_errno(dtp, EDT_NOMEM));
419 bcopy(dtp->dt_proc_env, p, sizeof (char *) * i);
420 dt_free(dtp, dtp->dt_proc_env);
421 dtp->dt_proc_env = p;
423 dtp->dt_proc_env[i - 1] = var;
424 dtp->dt_proc_env[i] = NULL;
432 dt_opt_stdc(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
435 return (dt_set_errno(dtp, EDT_BADOPTVAL));
437 if (dtp->dt_pcb != NULL)
438 return (dt_set_errno(dtp, EDT_BADOPTCTX));
440 if (strcmp(arg, "a") == 0)
441 dtp->dt_stdcmode = DT_STDC_XA;
442 else if (strcmp(arg, "c") == 0)
443 dtp->dt_stdcmode = DT_STDC_XC;
444 else if (strcmp(arg, "s") == 0)
445 dtp->dt_stdcmode = DT_STDC_XS;
446 else if (strcmp(arg, "t") == 0)
447 dtp->dt_stdcmode = DT_STDC_XT;
449 return (dt_set_errno(dtp, EDT_BADOPTVAL));
456 dt_opt_syslibdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
458 dt_dirpath_t *dp = dt_list_next(&dtp->dt_lib_path);
462 return (dt_set_errno(dtp, EDT_BADOPTVAL));
464 if ((path = strdup(arg)) == NULL)
465 return (dt_set_errno(dtp, EDT_NOMEM));
475 dt_opt_tree(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
479 if (arg == NULL || (m = atoi(arg)) <= 0)
480 return (dt_set_errno(dtp, EDT_BADOPTVAL));
482 dtp->dt_treedump = m;
488 dt_opt_tregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
492 if (arg == NULL || (n = atoi(arg)) <= 0)
493 return (dt_set_errno(dtp, EDT_BADOPTVAL));
495 dtp->dt_conf.dtc_diftupregs = n;
501 dt_opt_xlate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
504 return (dt_set_errno(dtp, EDT_BADOPTVAL));
506 if (strcmp(arg, "dynamic") == 0)
507 dtp->dt_xlatemode = DT_XL_DYNAMIC;
508 else if (strcmp(arg, "static") == 0)
509 dtp->dt_xlatemode = DT_XL_STATIC;
511 return (dt_set_errno(dtp, EDT_BADOPTVAL));
518 dt_opt_cflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
521 return (dt_set_errno(dtp, EDT_BADOPTVAL));
523 if (dtp->dt_pcb != NULL)
524 dtp->dt_pcb->pcb_cflags |= option;
526 dtp->dt_cflags |= option;
532 dt_opt_dflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
535 return (dt_set_errno(dtp, EDT_BADOPTVAL));
537 dtp->dt_dflags |= option;
542 dt_opt_invcflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
545 return (dt_set_errno(dtp, EDT_BADOPTVAL));
547 if (dtp->dt_pcb != NULL)
548 dtp->dt_pcb->pcb_cflags &= ~option;
550 dtp->dt_cflags &= ~option;
557 dt_opt_version(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
562 return (dt_set_errno(dtp, EDT_BADOPTVAL));
564 if (dt_version_str2num(arg, &v) == -1)
565 return (dt_set_errno(dtp, EDT_VERSINVAL));
567 if (!dt_version_defined(v))
568 return (dt_set_errno(dtp, EDT_VERSUNDEF));
570 return (dt_reduce(dtp, v));
574 dt_opt_runtime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
577 dtrace_optval_t val = 0;
585 { "enable", "disable" },
586 { "enabled", "disabled" },
594 if (arg[0] == '\0') {
595 val = DTRACEOPT_UNSET;
599 for (i = 0; couples[i].positive != NULL; i++) {
600 if (strcasecmp(couples[i].positive, arg) == 0) {
605 if (strcasecmp(couples[i].negative, arg) == 0) {
606 val = DTRACEOPT_UNSET;
612 val = strtoull(arg, &end, 0);
614 if (*end != '\0' || errno != 0 || val < 0)
615 return (dt_set_errno(dtp, EDT_BADOPTVAL));
619 dtp->dt_options[option] = val;
624 dt_optval_parse(const char *arg, dtrace_optval_t *rval)
626 dtrace_optval_t mul = 1;
633 switch (arg[len - 1]) {
655 *rval = strtoull(arg, &end, 0) * mul;
657 if ((mul > 1 && end != &arg[len - 1]) || (mul == 1 && *end != '\0') ||
658 *rval < 0 || errno != 0)
665 dt_opt_size(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
667 dtrace_optval_t val = 0;
669 if (arg != NULL && dt_optval_parse(arg, &val) != 0)
670 return (dt_set_errno(dtp, EDT_BADOPTVAL));
672 dtp->dt_options[option] = val;
677 dt_opt_rate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
681 dtrace_optval_t mul = 1, val = 0;
687 { "ns", NANOSEC / NANOSEC },
688 { "nsec", NANOSEC / NANOSEC },
689 { "us", NANOSEC / MICROSEC },
690 { "usec", NANOSEC / MICROSEC },
691 { "ms", NANOSEC / MILLISEC },
692 { "msec", NANOSEC / MILLISEC },
693 { "s", NANOSEC / SEC },
694 { "sec", NANOSEC / SEC },
695 { "m", NANOSEC * (hrtime_t)60 },
696 { "min", NANOSEC * (hrtime_t)60 },
697 { "h", NANOSEC * (hrtime_t)60 * (hrtime_t)60 },
698 { "hour", NANOSEC * (hrtime_t)60 * (hrtime_t)60 },
699 { "d", NANOSEC * (hrtime_t)(24 * 60 * 60) },
700 { "day", NANOSEC * (hrtime_t)(24 * 60 * 60) },
707 val = strtoull(arg, &end, 0);
709 for (i = 0; suffix[i].name != NULL; i++) {
710 if (strcasecmp(suffix[i].name, end) == 0) {
716 if (suffix[i].name == NULL && *end != '\0' || val < 0)
717 return (dt_set_errno(dtp, EDT_BADOPTVAL));
721 * The rate has been specified in frequency-per-second.
730 dtp->dt_options[option] = val;
735 * When setting the strsize option, set the option in the dt_options array
736 * using dt_opt_size() as usual, and then update the definition of the CTF
737 * type for the D intrinsic "string" to be an array of the corresponding size.
738 * If any errors occur, reset dt_options[option] to its previous value.
741 dt_opt_strsize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
743 dtrace_optval_t val = dtp->dt_options[option];
744 ctf_file_t *fp = DT_STR_CTFP(dtp);
745 ctf_id_t type = ctf_type_resolve(fp, DT_STR_TYPE(dtp));
748 if (dt_opt_size(dtp, arg, option) != 0)
749 return (-1); /* dt_errno is set for us */
751 if (dtp->dt_options[option] > UINT_MAX) {
752 dtp->dt_options[option] = val;
753 return (dt_set_errno(dtp, EOVERFLOW));
756 if (ctf_array_info(fp, type, &r) == CTF_ERR) {
757 dtp->dt_options[option] = val;
758 dtp->dt_ctferr = ctf_errno(fp);
759 return (dt_set_errno(dtp, EDT_CTF));
762 r.ctr_nelems = (uint_t)dtp->dt_options[option];
764 if (ctf_set_array(fp, type, &r) == CTF_ERR ||
765 ctf_update(fp) == CTF_ERR) {
766 dtp->dt_options[option] = val;
767 dtp->dt_ctferr = ctf_errno(fp);
768 return (dt_set_errno(dtp, EDT_CTF));
774 static const struct {
775 const char *dtbp_name;
777 } _dtrace_bufpolicies[] = {
778 { "ring", DTRACEOPT_BUFPOLICY_RING },
779 { "fill", DTRACEOPT_BUFPOLICY_FILL },
780 { "switch", DTRACEOPT_BUFPOLICY_SWITCH },
786 dt_opt_bufpolicy(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
788 dtrace_optval_t policy = DTRACEOPT_UNSET;
792 return (dt_set_errno(dtp, EDT_BADOPTVAL));
794 for (i = 0; _dtrace_bufpolicies[i].dtbp_name != NULL; i++) {
795 if (strcmp(_dtrace_bufpolicies[i].dtbp_name, arg) == 0) {
796 policy = _dtrace_bufpolicies[i].dtbp_policy;
801 if (policy == DTRACEOPT_UNSET)
802 return (dt_set_errno(dtp, EDT_BADOPTVAL));
804 dtp->dt_options[DTRACEOPT_BUFPOLICY] = policy;
809 static const struct {
810 const char *dtbr_name;
812 } _dtrace_bufresize[] = {
813 { "auto", DTRACEOPT_BUFRESIZE_AUTO },
814 { "manual", DTRACEOPT_BUFRESIZE_MANUAL },
820 dt_opt_bufresize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
822 dtrace_optval_t policy = DTRACEOPT_UNSET;
826 return (dt_set_errno(dtp, EDT_BADOPTVAL));
828 for (i = 0; _dtrace_bufresize[i].dtbr_name != NULL; i++) {
829 if (strcmp(_dtrace_bufresize[i].dtbr_name, arg) == 0) {
830 policy = _dtrace_bufresize[i].dtbr_policy;
835 if (policy == DTRACEOPT_UNSET)
836 return (dt_set_errno(dtp, EDT_BADOPTVAL));
838 dtp->dt_options[DTRACEOPT_BUFRESIZE] = policy;
844 dt_options_load(dtrace_hdl_t *dtp)
852 * To load the option values, we need to ask the kernel to provide its
853 * DOF, which we'll sift through to look for OPTDESC sections.
855 bzero(&hdr, sizeof (dof_hdr_t));
856 hdr.dofh_loadsz = sizeof (dof_hdr_t);
859 if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &hdr) == -1)
862 if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &dof) == -1)
864 return (dt_set_errno(dtp, errno));
866 if (hdr.dofh_loadsz < sizeof (dof_hdr_t))
867 return (dt_set_errno(dtp, EINVAL));
869 dof = alloca(hdr.dofh_loadsz);
870 bzero(dof, sizeof (dof_hdr_t));
871 dof->dofh_loadsz = hdr.dofh_loadsz;
873 for (i = 0; i < DTRACEOPT_MAX; i++)
874 dtp->dt_options[i] = DTRACEOPT_UNSET;
877 if (dt_ioctl(dtp, DTRACEIOC_DOFGET, dof) == -1)
879 if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &dof) == -1)
881 return (dt_set_errno(dtp, errno));
883 for (i = 0; i < dof->dofh_secnum; i++) {
884 sec = (dof_sec_t *)(uintptr_t)((uintptr_t)dof +
885 dof->dofh_secoff + i * dof->dofh_secsize);
887 if (sec->dofs_type != DOF_SECT_OPTDESC)
893 for (offs = 0; offs < sec->dofs_size; offs += sec->dofs_entsize) {
894 dof_optdesc_t *opt = (dof_optdesc_t *)(uintptr_t)
895 ((uintptr_t)dof + sec->dofs_offset + offs);
897 if (opt->dofo_strtab != DOF_SECIDX_NONE)
900 if (opt->dofo_option >= DTRACEOPT_MAX)
903 dtp->dt_options[opt->dofo_option] = opt->dofo_value;
911 dt_opt_preallocate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
913 dtrace_optval_t size;
916 if (arg == NULL || dt_optval_parse(arg, &size) != 0)
917 return (dt_set_errno(dtp, EDT_BADOPTVAL));
922 if ((p = dt_zalloc(dtp, size)) == NULL) {
925 } while ((p = dt_zalloc(dtp, size)) == NULL);
933 typedef struct dt_option {
935 int (*o_func)(dtrace_hdl_t *, const char *, uintptr_t);
940 * Compile-time options.
942 static const dt_option_t _dtrace_ctoptions[] = {
943 { "aggpercpu", dt_opt_agg, DTRACE_A_PERCPU },
944 { "amin", dt_opt_amin },
945 { "argref", dt_opt_cflags, DTRACE_C_ARGREF },
946 { "core", dt_opt_core },
947 { "cpp", dt_opt_cflags, DTRACE_C_CPP },
948 { "cpphdrs", dt_opt_cpp_hdrs },
949 { "cpppath", dt_opt_cpp_path },
950 { "ctypes", dt_opt_ctypes },
951 { "defaultargs", dt_opt_cflags, DTRACE_C_DEFARG },
952 { "dtypes", dt_opt_dtypes },
953 { "debug", dt_opt_debug },
954 { "define", dt_opt_cpp_opts, (uintptr_t)"-D" },
955 { "droptags", dt_opt_droptags },
956 { "empty", dt_opt_cflags, DTRACE_C_EMPTY },
957 { "errtags", dt_opt_cflags, DTRACE_C_ETAGS },
958 { "evaltime", dt_opt_evaltime },
959 { "incdir", dt_opt_cpp_opts, (uintptr_t)"-I" },
960 { "iregs", dt_opt_iregs },
961 { "kdefs", dt_opt_invcflags, DTRACE_C_KNODEF },
962 { "knodefs", dt_opt_cflags, DTRACE_C_KNODEF },
963 { "late", dt_opt_xlate },
964 { "lazyload", dt_opt_lazyload },
965 { "ldpath", dt_opt_ld_path },
966 { "libdir", dt_opt_libdir },
967 { "linkmode", dt_opt_linkmode },
968 { "linktype", dt_opt_linktype },
969 { "nolibs", dt_opt_cflags, DTRACE_C_NOLIBS },
970 { "pgmax", dt_opt_pgmax },
971 { "preallocate", dt_opt_preallocate },
972 { "pspec", dt_opt_cflags, DTRACE_C_PSPEC },
973 { "setenv", dt_opt_setenv, 1 },
974 { "stdc", dt_opt_stdc },
975 { "strip", dt_opt_dflags, DTRACE_D_STRIP },
976 { "syslibdir", dt_opt_syslibdir },
977 { "tree", dt_opt_tree },
978 { "tregs", dt_opt_tregs },
979 { "udefs", dt_opt_invcflags, DTRACE_C_UNODEF },
980 { "undef", dt_opt_cpp_opts, (uintptr_t)"-U" },
981 { "unodefs", dt_opt_cflags, DTRACE_C_UNODEF },
982 { "unsetenv", dt_opt_setenv, 0 },
983 { "verbose", dt_opt_cflags, DTRACE_C_DIFV },
984 { "version", dt_opt_version },
985 { "zdefs", dt_opt_cflags, DTRACE_C_ZDEFS },
992 static const dt_option_t _dtrace_rtoptions[] = {
993 { "aggsize", dt_opt_size, DTRACEOPT_AGGSIZE },
994 { "bufsize", dt_opt_size, DTRACEOPT_BUFSIZE },
995 { "bufpolicy", dt_opt_bufpolicy, DTRACEOPT_BUFPOLICY },
996 { "bufresize", dt_opt_bufresize, DTRACEOPT_BUFRESIZE },
997 { "cleanrate", dt_opt_rate, DTRACEOPT_CLEANRATE },
998 { "cpu", dt_opt_runtime, DTRACEOPT_CPU },
999 { "destructive", dt_opt_runtime, DTRACEOPT_DESTRUCTIVE },
1000 { "dynvarsize", dt_opt_size, DTRACEOPT_DYNVARSIZE },
1001 { "grabanon", dt_opt_runtime, DTRACEOPT_GRABANON },
1002 { "jstackframes", dt_opt_runtime, DTRACEOPT_JSTACKFRAMES },
1003 { "jstackstrsize", dt_opt_size, DTRACEOPT_JSTACKSTRSIZE },
1004 { "nspec", dt_opt_runtime, DTRACEOPT_NSPEC },
1005 { "specsize", dt_opt_size, DTRACEOPT_SPECSIZE },
1006 { "stackframes", dt_opt_runtime, DTRACEOPT_STACKFRAMES },
1007 { "statusrate", dt_opt_rate, DTRACEOPT_STATUSRATE },
1008 { "strsize", dt_opt_strsize, DTRACEOPT_STRSIZE },
1009 { "ustackframes", dt_opt_runtime, DTRACEOPT_USTACKFRAMES },
1010 { "temporal", dt_opt_runtime, DTRACEOPT_TEMPORAL },
1015 * Dynamic run-time options.
1017 static const dt_option_t _dtrace_drtoptions[] = {
1018 { "aggrate", dt_opt_rate, DTRACEOPT_AGGRATE },
1019 { "aggsortkey", dt_opt_runtime, DTRACEOPT_AGGSORTKEY },
1020 { "aggsortkeypos", dt_opt_runtime, DTRACEOPT_AGGSORTKEYPOS },
1021 { "aggsortpos", dt_opt_runtime, DTRACEOPT_AGGSORTPOS },
1022 { "aggsortrev", dt_opt_runtime, DTRACEOPT_AGGSORTREV },
1023 { "flowindent", dt_opt_runtime, DTRACEOPT_FLOWINDENT },
1024 { "quiet", dt_opt_runtime, DTRACEOPT_QUIET },
1025 { "rawbytes", dt_opt_runtime, DTRACEOPT_RAWBYTES },
1026 { "stackindent", dt_opt_runtime, DTRACEOPT_STACKINDENT },
1027 { "switchrate", dt_opt_rate, DTRACEOPT_SWITCHRATE },
1032 dtrace_getopt(dtrace_hdl_t *dtp, const char *opt, dtrace_optval_t *val)
1034 const dt_option_t *op;
1037 return (dt_set_errno(dtp, EINVAL));
1040 * We only need to search the run-time options -- it's not legal
1041 * to get the values of compile-time options.
1043 for (op = _dtrace_rtoptions; op->o_name != NULL; op++) {
1044 if (strcmp(op->o_name, opt) == 0) {
1045 *val = dtp->dt_options[op->o_option];
1050 for (op = _dtrace_drtoptions; op->o_name != NULL; op++) {
1051 if (strcmp(op->o_name, opt) == 0) {
1052 *val = dtp->dt_options[op->o_option];
1057 return (dt_set_errno(dtp, EDT_BADOPTNAME));
1061 dtrace_setopt(dtrace_hdl_t *dtp, const char *opt, const char *val)
1063 const dt_option_t *op;
1066 return (dt_set_errno(dtp, EINVAL));
1068 for (op = _dtrace_ctoptions; op->o_name != NULL; op++) {
1069 if (strcmp(op->o_name, opt) == 0)
1070 return (op->o_func(dtp, val, op->o_option));
1073 for (op = _dtrace_drtoptions; op->o_name != NULL; op++) {
1074 if (strcmp(op->o_name, opt) == 0)
1075 return (op->o_func(dtp, val, op->o_option));
1078 for (op = _dtrace_rtoptions; op->o_name != NULL; op++) {
1079 if (strcmp(op->o_name, opt) == 0) {
1081 * Only dynamic run-time options may be set while
1082 * tracing is active.
1085 return (dt_set_errno(dtp, EDT_ACTIVE));
1087 return (op->o_func(dtp, val, op->o_option));
1091 return (dt_set_errno(dtp, EDT_BADOPTNAME));