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>
46 #include <dt_string.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
;
167 if (opt
== NULL
|| arg
== NULL
)
168 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
170 if (dtp
->dt_pcb
!= NULL
)
171 return (dt_set_errno(dtp
, EDT_BADOPTCTX
));
173 len
= strlen(opt
) + strlen(arg
) + 1;
176 (void) strcpy(buf
, opt
);
177 (void) strcat(buf
, arg
);
179 if (dt_cpp_add_arg(dtp
, buf
) == NULL
)
180 return (dt_set_errno(dtp
, EDT_NOMEM
));
187 dt_opt_ctypes(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
192 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
194 if ((fd
= open64(arg
, O_CREAT
| O_WRONLY
, 0666)) == -1)
195 return (dt_set_errno(dtp
, errno
));
197 (void) close(dtp
->dt_cdefs_fd
);
198 dtp
->dt_cdefs_fd
= fd
;
204 dt_opt_droptags(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
206 dtp
->dt_droptags
= 1;
212 dt_opt_dtypes(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
217 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
219 if ((fd
= open64(arg
, O_CREAT
| O_WRONLY
, 0666)) == -1)
220 return (dt_set_errno(dtp
, errno
));
222 (void) close(dtp
->dt_ddefs_fd
);
223 dtp
->dt_ddefs_fd
= fd
;
229 dt_opt_debug(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
232 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
240 dt_opt_iregs(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
244 if (arg
== NULL
|| (n
= atoi(arg
)) <= 0)
245 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
247 dtp
->dt_conf
.dtc_difintregs
= n
;
253 dt_opt_lazyload(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
255 dtp
->dt_lazyload
= 1;
262 dt_opt_ld_path(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
267 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
269 if (dtp
->dt_pcb
!= NULL
)
270 return (dt_set_errno(dtp
, EDT_BADOPTCTX
));
272 if ((ld
= strdup(arg
)) == NULL
)
273 return (dt_set_errno(dtp
, EDT_NOMEM
));
275 free(dtp
->dt_ld_path
);
276 dtp
->dt_ld_path
= ld
;
283 dt_opt_libdir(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
288 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
290 if ((dp
= malloc(sizeof (dt_dirpath_t
))) == NULL
||
291 (dp
->dir_path
= strdup(arg
)) == NULL
) {
293 return (dt_set_errno(dtp
, EDT_NOMEM
));
296 dt_list_append(&dtp
->dt_lib_path
, dp
);
302 dt_opt_linkmode(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
305 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
307 if (strcmp(arg
, "kernel") == 0)
308 dtp
->dt_linkmode
= DT_LINK_KERNEL
;
309 else if (strcmp(arg
, "primary") == 0)
310 dtp
->dt_linkmode
= DT_LINK_PRIMARY
;
311 else if (strcmp(arg
, "dynamic") == 0)
312 dtp
->dt_linkmode
= DT_LINK_DYNAMIC
;
313 else if (strcmp(arg
, "static") == 0)
314 dtp
->dt_linkmode
= DT_LINK_STATIC
;
316 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
323 dt_opt_linktype(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
326 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
328 if (strcasecmp(arg
, "elf") == 0)
329 dtp
->dt_linktype
= DT_LTYP_ELF
;
330 else if (strcasecmp(arg
, "dof") == 0)
331 dtp
->dt_linktype
= DT_LTYP_DOF
;
333 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
340 dt_opt_encoding(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
343 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
345 if (strcmp(arg
, "ascii") == 0)
346 dtp
->dt_encoding
= DT_ENCODING_ASCII
;
347 else if (strcmp(arg
, "utf8") == 0)
348 dtp
->dt_encoding
= DT_ENCODING_UTF8
;
350 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
357 dt_opt_evaltime(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
360 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
362 if (strcmp(arg
, "exec") == 0)
363 dtp
->dt_prcmode
= DT_PROC_STOP_CREATE
;
364 else if (strcmp(arg
, "preinit") == 0)
365 dtp
->dt_prcmode
= DT_PROC_STOP_PREINIT
;
366 else if (strcmp(arg
, "postinit") == 0)
367 dtp
->dt_prcmode
= DT_PROC_STOP_POSTINIT
;
368 else if (strcmp(arg
, "main") == 0)
369 dtp
->dt_prcmode
= DT_PROC_STOP_MAIN
;
371 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
378 dt_opt_pgmax(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
382 if (arg
== NULL
|| (n
= atoi(arg
)) < 0)
383 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
385 dtp
->dt_procs
->dph_lrulim
= n
;
390 dt_opt_setenv(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
397 * We can't effectively set environment variables from #pragma lines
398 * since the processes have already been spawned.
400 if (dtp
->dt_pcb
!= NULL
)
401 return (dt_set_errno(dtp
, EDT_BADOPTCTX
));
404 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
406 if (!option
&& strchr(arg
, '=') != NULL
)
407 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
409 for (i
= 1, p
= dtp
->dt_proc_env
; *p
!= NULL
; i
++, p
++)
412 for (p
= dtp
->dt_proc_env
; *p
!= NULL
; p
++) {
413 var
= strchr(*p
, '=');
415 var
= *p
+ strlen(*p
);
416 if (strncmp(*p
, arg
, var
- *p
) == 0) {
418 *p
= dtp
->dt_proc_env
[i
- 1];
419 dtp
->dt_proc_env
[i
- 1] = NULL
;
425 if ((var
= strdup(arg
)) == NULL
)
426 return (dt_set_errno(dtp
, EDT_NOMEM
));
428 if ((p
= dt_alloc(dtp
, sizeof (char *) * (i
+ 1))) == NULL
) {
430 return (dt_set_errno(dtp
, EDT_NOMEM
));
433 bcopy(dtp
->dt_proc_env
, p
, sizeof (char *) * i
);
434 dt_free(dtp
, dtp
->dt_proc_env
);
435 dtp
->dt_proc_env
= p
;
437 dtp
->dt_proc_env
[i
- 1] = var
;
438 dtp
->dt_proc_env
[i
] = NULL
;
446 dt_opt_stdc(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
449 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
451 if (dtp
->dt_pcb
!= NULL
)
452 return (dt_set_errno(dtp
, EDT_BADOPTCTX
));
454 if (strcmp(arg
, "a") == 0)
455 dtp
->dt_stdcmode
= DT_STDC_XA
;
456 else if (strcmp(arg
, "c") == 0)
457 dtp
->dt_stdcmode
= DT_STDC_XC
;
458 else if (strcmp(arg
, "s") == 0)
459 dtp
->dt_stdcmode
= DT_STDC_XS
;
460 else if (strcmp(arg
, "t") == 0)
461 dtp
->dt_stdcmode
= DT_STDC_XT
;
463 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
470 dt_opt_syslibdir(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
472 dt_dirpath_t
*dp
= dt_list_next(&dtp
->dt_lib_path
);
476 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
478 if ((path
= strdup(arg
)) == NULL
)
479 return (dt_set_errno(dtp
, EDT_NOMEM
));
489 dt_opt_tree(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
493 if (arg
== NULL
|| (m
= atoi(arg
)) <= 0)
494 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
496 dtp
->dt_treedump
= m
;
502 dt_opt_tregs(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
506 if (arg
== NULL
|| (n
= atoi(arg
)) <= 0)
507 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
509 dtp
->dt_conf
.dtc_diftupregs
= n
;
515 dt_opt_xlate(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
518 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
520 if (strcmp(arg
, "dynamic") == 0)
521 dtp
->dt_xlatemode
= DT_XL_DYNAMIC
;
522 else if (strcmp(arg
, "static") == 0)
523 dtp
->dt_xlatemode
= DT_XL_STATIC
;
525 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
532 dt_opt_cflags(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
535 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
537 if (dtp
->dt_pcb
!= NULL
)
538 dtp
->dt_pcb
->pcb_cflags
|= option
;
540 dtp
->dt_cflags
|= option
;
546 dt_opt_dflags(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
549 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
551 dtp
->dt_dflags
|= option
;
556 dt_opt_invcflags(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
559 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
561 if (dtp
->dt_pcb
!= NULL
)
562 dtp
->dt_pcb
->pcb_cflags
&= ~option
;
564 dtp
->dt_cflags
&= ~option
;
571 dt_opt_version(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
576 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
578 if (dt_version_str2num(arg
, &v
) == -1)
579 return (dt_set_errno(dtp
, EDT_VERSINVAL
));
581 if (!dt_version_defined(v
))
582 return (dt_set_errno(dtp
, EDT_VERSUNDEF
));
584 return (dt_reduce(dtp
, v
));
588 dt_opt_runtime(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
591 dtrace_optval_t val
= 0;
599 { "enable", "disable" },
600 { "enabled", "disabled" },
608 if (arg
[0] == '\0') {
609 val
= DTRACEOPT_UNSET
;
613 for (i
= 0; couples
[i
].positive
!= NULL
; i
++) {
614 if (strcasecmp(couples
[i
].positive
, arg
) == 0) {
619 if (strcasecmp(couples
[i
].negative
, arg
) == 0) {
620 val
= DTRACEOPT_UNSET
;
626 val
= strtoull(arg
, &end
, 0);
628 if (*end
!= '\0' || errno
!= 0 || val
< 0)
629 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
633 dtp
->dt_options
[option
] = val
;
638 dt_optval_parse(const char *arg
, dtrace_optval_t
*rval
)
640 dtrace_optval_t mul
= 1;
647 switch (arg
[len
- 1]) {
669 *rval
= strtoull(arg
, &end
, 0) * mul
;
671 if ((mul
> 1 && end
!= &arg
[len
- 1]) || (mul
== 1 && *end
!= '\0') ||
672 *rval
< 0 || errno
!= 0)
679 dt_opt_size(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
681 dtrace_optval_t val
= 0;
683 if (arg
!= NULL
&& dt_optval_parse(arg
, &val
) != 0)
684 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
686 dtp
->dt_options
[option
] = val
;
691 dt_opt_rate(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
695 dtrace_optval_t mul
= 1, val
= 0;
701 { "ns", NANOSEC
/ NANOSEC
},
702 { "nsec", NANOSEC
/ NANOSEC
},
703 { "us", NANOSEC
/ MICROSEC
},
704 { "usec", NANOSEC
/ MICROSEC
},
705 { "ms", NANOSEC
/ MILLISEC
},
706 { "msec", NANOSEC
/ MILLISEC
},
707 { "s", NANOSEC
/ SEC
},
708 { "sec", NANOSEC
/ SEC
},
709 { "m", NANOSEC
* (hrtime_t
)60 },
710 { "min", NANOSEC
* (hrtime_t
)60 },
711 { "h", NANOSEC
* (hrtime_t
)60 * (hrtime_t
)60 },
712 { "hour", NANOSEC
* (hrtime_t
)60 * (hrtime_t
)60 },
713 { "d", NANOSEC
* (hrtime_t
)(24 * 60 * 60) },
714 { "day", NANOSEC
* (hrtime_t
)(24 * 60 * 60) },
721 val
= strtoull(arg
, &end
, 0);
723 for (i
= 0; suffix
[i
].name
!= NULL
; i
++) {
724 if (strcasecmp(suffix
[i
].name
, end
) == 0) {
730 if (suffix
[i
].name
== NULL
&& *end
!= '\0' || val
< 0)
731 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
735 * The rate has been specified in frequency-per-second.
744 dtp
->dt_options
[option
] = val
;
749 * When setting the strsize option, set the option in the dt_options array
750 * using dt_opt_size() as usual, and then update the definition of the CTF
751 * type for the D intrinsic "string" to be an array of the corresponding size.
752 * If any errors occur, reset dt_options[option] to its previous value.
755 dt_opt_strsize(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
757 dtrace_optval_t val
= dtp
->dt_options
[option
];
758 ctf_file_t
*fp
= DT_STR_CTFP(dtp
);
759 ctf_id_t type
= ctf_type_resolve(fp
, DT_STR_TYPE(dtp
));
762 if (dt_opt_size(dtp
, arg
, option
) != 0)
763 return (-1); /* dt_errno is set for us */
765 if (dtp
->dt_options
[option
] > UINT_MAX
) {
766 dtp
->dt_options
[option
] = val
;
767 return (dt_set_errno(dtp
, EOVERFLOW
));
770 if (ctf_array_info(fp
, type
, &r
) == CTF_ERR
) {
771 dtp
->dt_options
[option
] = val
;
772 dtp
->dt_ctferr
= ctf_errno(fp
);
773 return (dt_set_errno(dtp
, EDT_CTF
));
776 r
.ctr_nelems
= (uint_t
)dtp
->dt_options
[option
];
778 if (ctf_set_array(fp
, type
, &r
) == CTF_ERR
||
779 ctf_update(fp
) == CTF_ERR
) {
780 dtp
->dt_options
[option
] = val
;
781 dtp
->dt_ctferr
= ctf_errno(fp
);
782 return (dt_set_errno(dtp
, EDT_CTF
));
788 static const struct {
789 const char *dtbp_name
;
791 } _dtrace_bufpolicies
[] = {
792 { "ring", DTRACEOPT_BUFPOLICY_RING
},
793 { "fill", DTRACEOPT_BUFPOLICY_FILL
},
794 { "switch", DTRACEOPT_BUFPOLICY_SWITCH
},
800 dt_opt_bufpolicy(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
802 dtrace_optval_t policy
= DTRACEOPT_UNSET
;
806 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
808 for (i
= 0; _dtrace_bufpolicies
[i
].dtbp_name
!= NULL
; i
++) {
809 if (strcmp(_dtrace_bufpolicies
[i
].dtbp_name
, arg
) == 0) {
810 policy
= _dtrace_bufpolicies
[i
].dtbp_policy
;
815 if (policy
== DTRACEOPT_UNSET
)
816 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
818 dtp
->dt_options
[DTRACEOPT_BUFPOLICY
] = policy
;
823 static const struct {
824 const char *dtbr_name
;
826 } _dtrace_bufresize
[] = {
827 { "auto", DTRACEOPT_BUFRESIZE_AUTO
},
828 { "manual", DTRACEOPT_BUFRESIZE_MANUAL
},
834 dt_opt_bufresize(dtrace_hdl_t
*dtp
, const char *arg
, uintptr_t option
)
836 dtrace_optval_t policy
= DTRACEOPT_UNSET
;
840 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
842 for (i
= 0; _dtrace_bufresize
[i
].dtbr_name
!= NULL
; i
++) {
843 if (strcmp(_dtrace_bufresize
[i
].dtbr_name
, arg
) == 0) {
844 policy
= _dtrace_bufresize
[i
].dtbr_policy
;
849 if (policy
== DTRACEOPT_UNSET
)
850 return (dt_set_errno(dtp
, EDT_BADOPTVAL
));
852 dtp
->dt_options
[DTRACEOPT_BUFRESIZE
] = policy
;
858 dt_options_load(dtrace_hdl_t
*dtp
)
866 * To load the option values, we need to ask the kernel to provide its
867 * DOF, which we'll sift through to look for OPTDESC sections.
869 bzero(&hdr
, sizeof (dof_hdr_t
));
870 hdr
.dofh_loadsz
= sizeof (dof_hdr_t
);
872 if (dt_ioctl(dtp
, DTRACEIOC_DOFGET
, &hdr
) == -1)
873 return (dt_set_errno(dtp
, errno
));
875 if (hdr
.dofh_loadsz
< sizeof (dof_hdr_t
))
876 return (dt_set_errno(dtp
, EINVAL
));
878 dof
= alloca(hdr
.dofh_loadsz
);
879 bzero(dof
, sizeof (dof_hdr_t
));
880 dof
->dofh_loadsz
= hdr
.dofh_loadsz
;
882 for (i
= 0; i
< DTRACEOPT_MAX
; i
++)
883 dtp
->dt_options
[i
] = DTRACEOPT_UNSET
;
885 if (dt_ioctl(dtp
, DTRACEIOC_DOFGET
, dof
) == -1)
886 return (dt_set_errno(dtp
, errno
));
888 for (i
= 0; i
< dof
->dofh_secnum
; i
++) {
889 sec
= (dof_sec_t
*)(uintptr_t)((uintptr_t)dof
+
890 dof
->dofh_secoff
+ i
* dof
->dofh_secsize
);
892 if (sec
->dofs_type
!= DOF_SECT_OPTDESC
)
898 for (offs
= 0; offs
< sec
->dofs_size
; offs
+= sec
->dofs_entsize
) {
899 dof_optdesc_t
*opt
= (dof_optdesc_t
*)(uintptr_t)
900 ((uintptr_t)dof
+ sec
->dofs_offset
+ offs
);
902 if (opt
->dofo_strtab
!= DOF_SECIDX_NONE
)
905 if (opt
->dofo_option
>= DTRACEOPT_MAX
)
908 dtp
->dt_options
[opt
->dofo_option
] = opt
->dofo_value
;
914 typedef struct dt_option
{
916 int (*o_func
)(dtrace_hdl_t
*, const char *, uintptr_t);
921 * Compile-time options.
923 static const dt_option_t _dtrace_ctoptions
[] = {
924 { "aggpercpu", dt_opt_agg
, DTRACE_A_PERCPU
},
925 { "amin", dt_opt_amin
},
926 { "argref", dt_opt_cflags
, DTRACE_C_ARGREF
},
927 { "core", dt_opt_core
},
928 { "cpp", dt_opt_cflags
, DTRACE_C_CPP
},
929 { "cpphdrs", dt_opt_cpp_hdrs
},
930 { "cpppath", dt_opt_cpp_path
},
931 { "ctypes", dt_opt_ctypes
},
932 { "defaultargs", dt_opt_cflags
, DTRACE_C_DEFARG
},
933 { "dtypes", dt_opt_dtypes
},
934 { "debug", dt_opt_debug
},
935 { "define", dt_opt_cpp_opts
, (uintptr_t)"-D" },
936 { "droptags", dt_opt_droptags
},
937 { "empty", dt_opt_cflags
, DTRACE_C_EMPTY
},
938 { "encoding", dt_opt_encoding
},
939 { "errtags", dt_opt_cflags
, DTRACE_C_ETAGS
},
940 { "evaltime", dt_opt_evaltime
},
941 { "incdir", dt_opt_cpp_opts
, (uintptr_t)"-I" },
942 { "iregs", dt_opt_iregs
},
943 { "kdefs", dt_opt_invcflags
, DTRACE_C_KNODEF
},
944 { "knodefs", dt_opt_cflags
, DTRACE_C_KNODEF
},
945 { "late", dt_opt_xlate
},
946 { "lazyload", dt_opt_lazyload
},
947 { "ldpath", dt_opt_ld_path
},
948 { "libdir", dt_opt_libdir
},
949 { "linkmode", dt_opt_linkmode
},
950 { "linktype", dt_opt_linktype
},
951 { "nolibs", dt_opt_cflags
, DTRACE_C_NOLIBS
},
952 { "pgmax", dt_opt_pgmax
},
953 { "pspec", dt_opt_cflags
, DTRACE_C_PSPEC
},
954 { "setenv", dt_opt_setenv
, 1 },
955 { "stdc", dt_opt_stdc
},
956 { "strip", dt_opt_dflags
, DTRACE_D_STRIP
},
957 { "syslibdir", dt_opt_syslibdir
},
958 { "tree", dt_opt_tree
},
959 { "tregs", dt_opt_tregs
},
960 { "udefs", dt_opt_invcflags
, DTRACE_C_UNODEF
},
961 { "undef", dt_opt_cpp_opts
, (uintptr_t)"-U" },
962 { "unodefs", dt_opt_cflags
, DTRACE_C_UNODEF
},
963 { "unsetenv", dt_opt_setenv
, 0 },
964 { "verbose", dt_opt_cflags
, DTRACE_C_DIFV
},
965 { "version", dt_opt_version
},
966 { "zdefs", dt_opt_cflags
, DTRACE_C_ZDEFS
},
973 static const dt_option_t _dtrace_rtoptions
[] = {
974 { "aggsize", dt_opt_size
, DTRACEOPT_AGGSIZE
},
975 { "bufsize", dt_opt_size
, DTRACEOPT_BUFSIZE
},
976 { "bufpolicy", dt_opt_bufpolicy
, DTRACEOPT_BUFPOLICY
},
977 { "bufresize", dt_opt_bufresize
, DTRACEOPT_BUFRESIZE
},
978 { "cleanrate", dt_opt_rate
, DTRACEOPT_CLEANRATE
},
979 { "cpu", dt_opt_runtime
, DTRACEOPT_CPU
},
980 { "destructive", dt_opt_runtime
, DTRACEOPT_DESTRUCTIVE
},
981 { "dynvarsize", dt_opt_size
, DTRACEOPT_DYNVARSIZE
},
982 { "grabanon", dt_opt_runtime
, DTRACEOPT_GRABANON
},
983 { "jstackframes", dt_opt_runtime
, DTRACEOPT_JSTACKFRAMES
},
984 { "jstackstrsize", dt_opt_size
, DTRACEOPT_JSTACKSTRSIZE
},
985 { "nspec", dt_opt_runtime
, DTRACEOPT_NSPEC
},
986 { "specsize", dt_opt_size
, DTRACEOPT_SPECSIZE
},
987 { "stackframes", dt_opt_runtime
, DTRACEOPT_STACKFRAMES
},
988 { "statusrate", dt_opt_rate
, DTRACEOPT_STATUSRATE
},
989 { "strsize", dt_opt_strsize
, DTRACEOPT_STRSIZE
},
990 { "ustackframes", dt_opt_runtime
, DTRACEOPT_USTACKFRAMES
},
991 { "temporal", dt_opt_runtime
, DTRACEOPT_TEMPORAL
},
996 * Dynamic run-time options.
998 static const dt_option_t _dtrace_drtoptions
[] = {
999 { "agghist", dt_opt_runtime
, DTRACEOPT_AGGHIST
},
1000 { "aggpack", dt_opt_runtime
, DTRACEOPT_AGGPACK
},
1001 { "aggrate", dt_opt_rate
, DTRACEOPT_AGGRATE
},
1002 { "aggsortkey", dt_opt_runtime
, DTRACEOPT_AGGSORTKEY
},
1003 { "aggsortkeypos", dt_opt_runtime
, DTRACEOPT_AGGSORTKEYPOS
},
1004 { "aggsortpos", dt_opt_runtime
, DTRACEOPT_AGGSORTPOS
},
1005 { "aggsortrev", dt_opt_runtime
, DTRACEOPT_AGGSORTREV
},
1006 { "aggzoom", dt_opt_runtime
, DTRACEOPT_AGGZOOM
},
1007 { "flowindent", dt_opt_runtime
, DTRACEOPT_FLOWINDENT
},
1008 { "quiet", dt_opt_runtime
, DTRACEOPT_QUIET
},
1009 { "rawbytes", dt_opt_runtime
, DTRACEOPT_RAWBYTES
},
1010 { "stackindent", dt_opt_runtime
, DTRACEOPT_STACKINDENT
},
1011 { "switchrate", dt_opt_rate
, DTRACEOPT_SWITCHRATE
},
1016 dtrace_getopt(dtrace_hdl_t
*dtp
, const char *opt
, dtrace_optval_t
*val
)
1018 const dt_option_t
*op
;
1021 return (dt_set_errno(dtp
, EINVAL
));
1024 * We only need to search the run-time options -- it's not legal
1025 * to get the values of compile-time options.
1027 for (op
= _dtrace_rtoptions
; op
->o_name
!= NULL
; op
++) {
1028 if (strcmp(op
->o_name
, opt
) == 0) {
1029 *val
= dtp
->dt_options
[op
->o_option
];
1034 for (op
= _dtrace_drtoptions
; op
->o_name
!= NULL
; op
++) {
1035 if (strcmp(op
->o_name
, opt
) == 0) {
1036 *val
= dtp
->dt_options
[op
->o_option
];
1041 return (dt_set_errno(dtp
, EDT_BADOPTNAME
));
1045 dtrace_setopt(dtrace_hdl_t
*dtp
, const char *opt
, const char *val
)
1047 const dt_option_t
*op
;
1050 return (dt_set_errno(dtp
, EINVAL
));
1052 for (op
= _dtrace_ctoptions
; op
->o_name
!= NULL
; op
++) {
1053 if (strcmp(op
->o_name
, opt
) == 0)
1054 return (op
->o_func(dtp
, val
, op
->o_option
));
1057 for (op
= _dtrace_drtoptions
; op
->o_name
!= NULL
; op
++) {
1058 if (strcmp(op
->o_name
, opt
) == 0)
1059 return (op
->o_func(dtp
, val
, op
->o_option
));
1062 for (op
= _dtrace_rtoptions
; op
->o_name
!= NULL
; op
++) {
1063 if (strcmp(op
->o_name
, opt
) == 0) {
1065 * Only dynamic run-time options may be set while
1066 * tracing is active.
1069 return (dt_set_errno(dtp
, EDT_ACTIVE
));
1071 return (op
->o_func(dtp
, val
, op
->o_option
));
1075 return (dt_set_errno(dtp
, EDT_BADOPTNAME
));