1178479Sjb/* 2178479Sjb * CDDL HEADER START 3178479Sjb * 4178479Sjb * The contents of this file are subject to the terms of the 5178479Sjb * Common Development and Distribution License (the "License"). 6178479Sjb * You may not use this file except in compliance with the License. 7178479Sjb * 8178479Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9178479Sjb * or http://www.opensolaris.org/os/licensing. 10178479Sjb * See the License for the specific language governing permissions 11178479Sjb * and limitations under the License. 12178479Sjb * 13178479Sjb * When distributing Covered Code, include this CDDL HEADER in each 14178479Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15178479Sjb * If applicable, add the following below this CDDL HEADER, with the 16178479Sjb * fields enclosed by brackets "[]" replaced with your own identifying 17178479Sjb * information: Portions Copyright [yyyy] [name of copyright owner] 18178479Sjb * 19178479Sjb * CDDL HEADER END 20178479Sjb */ 21178479Sjb 22178479Sjb/* 23178479Sjb * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24178479Sjb * Use is subject to license terms. 25178479Sjb */ 26178479Sjb 27250574Smarkj/* 28267942Srpaulo * Copyright (c) 2013, Joyent, Inc. All rights reserved. 29250574Smarkj * Copyright (c) 2012 by Delphix. All rights reserved. 30250574Smarkj */ 31250574Smarkj 32178479Sjb#include <sys/resource.h> 33178479Sjb#include <sys/mman.h> 34178479Sjb#include <sys/types.h> 35178479Sjb 36178479Sjb#include <strings.h> 37178479Sjb#include <signal.h> 38178479Sjb#include <stdlib.h> 39178479Sjb#include <unistd.h> 40178479Sjb#include <limits.h> 41277300Ssmh#ifdef illumos 42178479Sjb#include <alloca.h> 43178569Sjb#endif 44178479Sjb#include <errno.h> 45178479Sjb#include <fcntl.h> 46178479Sjb 47178479Sjb#include <dt_impl.h> 48178479Sjb#include <dt_string.h> 49178479Sjb 50178479Sjbstatic int 51178479Sjbdt_opt_agg(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 52178479Sjb{ 53178479Sjb dt_aggregate_t *agp = &dtp->dt_aggregate; 54178479Sjb 55178479Sjb if (arg != NULL) 56178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 57178479Sjb 58178479Sjb agp->dtat_flags |= option; 59178479Sjb return (0); 60178479Sjb} 61178479Sjb 62178479Sjb/*ARGSUSED*/ 63178479Sjbstatic int 64178479Sjbdt_opt_amin(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 65178479Sjb{ 66178479Sjb char str[DTRACE_ATTR2STR_MAX]; 67178479Sjb dtrace_attribute_t attr; 68178479Sjb 69178479Sjb if (arg == NULL || dtrace_str2attr(arg, &attr) == -1) 70178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 71178479Sjb 72178479Sjb dt_dprintf("set compiler attribute minimum to %s\n", 73178479Sjb dtrace_attr2str(attr, str, sizeof (str))); 74178479Sjb 75178479Sjb if (dtp->dt_pcb != NULL) { 76178479Sjb dtp->dt_pcb->pcb_cflags |= DTRACE_C_EATTR; 77178479Sjb dtp->dt_pcb->pcb_amin = attr; 78178479Sjb } else { 79178479Sjb dtp->dt_cflags |= DTRACE_C_EATTR; 80178479Sjb dtp->dt_amin = attr; 81178479Sjb } 82178479Sjb 83178479Sjb return (0); 84178479Sjb} 85178479Sjb 86178479Sjbstatic void 87178479Sjbdt_coredump(void) 88178479Sjb{ 89178479Sjb const char msg[] = "libdtrace DEBUG: [ forcing coredump ]\n"; 90178479Sjb 91178479Sjb struct sigaction act; 92178479Sjb struct rlimit lim; 93178479Sjb 94178479Sjb (void) write(STDERR_FILENO, msg, sizeof (msg) - 1); 95178479Sjb 96178479Sjb act.sa_handler = SIG_DFL; 97178479Sjb act.sa_flags = 0; 98178479Sjb 99178479Sjb (void) sigemptyset(&act.sa_mask); 100178479Sjb (void) sigaction(SIGABRT, &act, NULL); 101178479Sjb 102178479Sjb lim.rlim_cur = RLIM_INFINITY; 103178479Sjb lim.rlim_max = RLIM_INFINITY; 104178479Sjb 105178479Sjb (void) setrlimit(RLIMIT_CORE, &lim); 106178479Sjb abort(); 107178479Sjb} 108178479Sjb 109178479Sjb/*ARGSUSED*/ 110178479Sjbstatic int 111178479Sjbdt_opt_core(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 112178479Sjb{ 113178479Sjb static int enabled = 0; 114178479Sjb 115178479Sjb if (arg != NULL) 116178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 117178479Sjb 118178479Sjb if (enabled++ || atexit(dt_coredump) == 0) 119178479Sjb return (0); 120178479Sjb 121178479Sjb return (dt_set_errno(dtp, errno)); 122178479Sjb} 123178479Sjb 124178479Sjb/*ARGSUSED*/ 125178479Sjbstatic int 126178479Sjbdt_opt_cpp_hdrs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 127178479Sjb{ 128178479Sjb if (arg != NULL) 129178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 130178479Sjb 131178479Sjb if (dtp->dt_pcb != NULL) 132178479Sjb return (dt_set_errno(dtp, EDT_BADOPTCTX)); 133178479Sjb 134178479Sjb if (dt_cpp_add_arg(dtp, "-H") == NULL) 135178479Sjb return (dt_set_errno(dtp, EDT_NOMEM)); 136178479Sjb 137178479Sjb return (0); 138178479Sjb} 139178479Sjb 140178479Sjb/*ARGSUSED*/ 141178479Sjbstatic int 142178479Sjbdt_opt_cpp_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 143178479Sjb{ 144178479Sjb char *cpp; 145178479Sjb 146178479Sjb if (arg == NULL) 147178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 148178479Sjb 149178479Sjb if (dtp->dt_pcb != NULL) 150178479Sjb return (dt_set_errno(dtp, EDT_BADOPTCTX)); 151178479Sjb 152178479Sjb if ((cpp = strdup(arg)) == NULL) 153178479Sjb return (dt_set_errno(dtp, EDT_NOMEM)); 154178479Sjb 155178479Sjb dtp->dt_cpp_argv[0] = (char *)strbasename(cpp); 156178479Sjb free(dtp->dt_cpp_path); 157178479Sjb dtp->dt_cpp_path = cpp; 158178479Sjb 159178479Sjb return (0); 160178479Sjb} 161178479Sjb 162178479Sjbstatic int 163178479Sjbdt_opt_cpp_opts(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 164178479Sjb{ 165178479Sjb char *buf; 166178479Sjb size_t len; 167178479Sjb const char *opt = (const char *)option; 168178479Sjb 169178479Sjb if (opt == NULL || arg == NULL) 170178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 171178479Sjb 172178479Sjb if (dtp->dt_pcb != NULL) 173178479Sjb return (dt_set_errno(dtp, EDT_BADOPTCTX)); 174178479Sjb 175178479Sjb len = strlen(opt) + strlen(arg) + 1; 176178479Sjb buf = alloca(len); 177178479Sjb 178178479Sjb (void) strcpy(buf, opt); 179178479Sjb (void) strcat(buf, arg); 180178479Sjb 181178479Sjb if (dt_cpp_add_arg(dtp, buf) == NULL) 182178479Sjb return (dt_set_errno(dtp, EDT_NOMEM)); 183178479Sjb 184178479Sjb return (0); 185178479Sjb} 186178479Sjb 187178479Sjb/*ARGSUSED*/ 188178479Sjbstatic int 189178479Sjbdt_opt_ctypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 190178479Sjb{ 191178479Sjb int fd; 192178479Sjb 193178479Sjb if (arg == NULL) 194178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 195178479Sjb 196178479Sjb if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1) 197178479Sjb return (dt_set_errno(dtp, errno)); 198178479Sjb 199178479Sjb (void) close(dtp->dt_cdefs_fd); 200178479Sjb dtp->dt_cdefs_fd = fd; 201178479Sjb return (0); 202178479Sjb} 203178479Sjb 204178479Sjb/*ARGSUSED*/ 205178479Sjbstatic int 206178479Sjbdt_opt_droptags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 207178479Sjb{ 208178479Sjb dtp->dt_droptags = 1; 209178479Sjb return (0); 210178479Sjb} 211178479Sjb 212178479Sjb/*ARGSUSED*/ 213178479Sjbstatic int 214178479Sjbdt_opt_dtypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 215178479Sjb{ 216178479Sjb int fd; 217178479Sjb 218178479Sjb if (arg == NULL) 219178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 220178479Sjb 221178479Sjb if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1) 222178479Sjb return (dt_set_errno(dtp, errno)); 223178479Sjb 224178479Sjb (void) close(dtp->dt_ddefs_fd); 225178479Sjb dtp->dt_ddefs_fd = fd; 226178479Sjb return (0); 227178479Sjb} 228178479Sjb 229178479Sjb/*ARGSUSED*/ 230178479Sjbstatic int 231178479Sjbdt_opt_debug(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 232178479Sjb{ 233178479Sjb if (arg != NULL) 234178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 235178479Sjb 236178479Sjb _dtrace_debug = 1; 237178479Sjb return (0); 238178479Sjb} 239178479Sjb 240178479Sjb/*ARGSUSED*/ 241178479Sjbstatic int 242178479Sjbdt_opt_iregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 243178479Sjb{ 244178479Sjb int n; 245178479Sjb 246178479Sjb if (arg == NULL || (n = atoi(arg)) <= 0) 247178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 248178479Sjb 249178479Sjb dtp->dt_conf.dtc_difintregs = n; 250178479Sjb return (0); 251178479Sjb} 252178479Sjb 253178479Sjb/*ARGSUSED*/ 254178479Sjbstatic int 255178479Sjbdt_opt_lazyload(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 256178479Sjb{ 257178479Sjb dtp->dt_lazyload = 1; 258178479Sjb 259178479Sjb return (0); 260178479Sjb} 261178479Sjb 262178479Sjb/*ARGSUSED*/ 263178479Sjbstatic int 264178479Sjbdt_opt_ld_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 265178479Sjb{ 266178479Sjb char *ld; 267178479Sjb 268178479Sjb if (arg == NULL) 269178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 270178479Sjb 271178479Sjb if (dtp->dt_pcb != NULL) 272178479Sjb return (dt_set_errno(dtp, EDT_BADOPTCTX)); 273178479Sjb 274178479Sjb if ((ld = strdup(arg)) == NULL) 275178479Sjb return (dt_set_errno(dtp, EDT_NOMEM)); 276178479Sjb 277178479Sjb free(dtp->dt_ld_path); 278178479Sjb dtp->dt_ld_path = ld; 279178479Sjb 280178479Sjb return (0); 281178479Sjb} 282178479Sjb 283278934Smarkj#ifdef __FreeBSD__ 284278934Smarkjstatic int 285278934Smarkjdt_opt_objcopy_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 286278934Smarkj{ 287278934Smarkj char *objcopy; 288278934Smarkj 289278934Smarkj if (arg == NULL) 290278934Smarkj return (dt_set_errno(dtp, EDT_BADOPTVAL)); 291278934Smarkj 292278934Smarkj if (dtp->dt_pcb != NULL) 293278934Smarkj return (dt_set_errno(dtp, EDT_BADOPTCTX)); 294278934Smarkj 295278934Smarkj if ((objcopy = strdup(arg)) == NULL) 296278934Smarkj return (dt_set_errno(dtp, EDT_NOMEM)); 297278934Smarkj 298278934Smarkj free(dtp->dt_objcopy_path); 299278934Smarkj dtp->dt_objcopy_path = objcopy; 300278934Smarkj 301278934Smarkj return (0); 302278934Smarkj} 303278934Smarkj#endif 304278934Smarkj 305178479Sjb/*ARGSUSED*/ 306178479Sjbstatic int 307178479Sjbdt_opt_libdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 308178479Sjb{ 309178479Sjb dt_dirpath_t *dp; 310178479Sjb 311178479Sjb if (arg == NULL) 312178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 313178479Sjb 314178479Sjb if ((dp = malloc(sizeof (dt_dirpath_t))) == NULL || 315178479Sjb (dp->dir_path = strdup(arg)) == NULL) { 316178479Sjb free(dp); 317178479Sjb return (dt_set_errno(dtp, EDT_NOMEM)); 318178479Sjb } 319178479Sjb 320178479Sjb dt_list_append(&dtp->dt_lib_path, dp); 321178479Sjb return (0); 322178479Sjb} 323178479Sjb 324178479Sjb/*ARGSUSED*/ 325178479Sjbstatic int 326178479Sjbdt_opt_linkmode(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 327178479Sjb{ 328178479Sjb if (arg == NULL) 329178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 330178479Sjb 331178479Sjb if (strcmp(arg, "kernel") == 0) 332178479Sjb dtp->dt_linkmode = DT_LINK_KERNEL; 333178479Sjb else if (strcmp(arg, "primary") == 0) 334178479Sjb dtp->dt_linkmode = DT_LINK_PRIMARY; 335178479Sjb else if (strcmp(arg, "dynamic") == 0) 336178479Sjb dtp->dt_linkmode = DT_LINK_DYNAMIC; 337178479Sjb else if (strcmp(arg, "static") == 0) 338178479Sjb dtp->dt_linkmode = DT_LINK_STATIC; 339178479Sjb else 340178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 341178479Sjb 342178479Sjb return (0); 343178479Sjb} 344178479Sjb 345178479Sjb/*ARGSUSED*/ 346178479Sjbstatic int 347178479Sjbdt_opt_linktype(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 348178479Sjb{ 349178479Sjb if (arg == NULL) 350178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 351178479Sjb 352178479Sjb if (strcasecmp(arg, "elf") == 0) 353178479Sjb dtp->dt_linktype = DT_LTYP_ELF; 354178479Sjb else if (strcasecmp(arg, "dof") == 0) 355178479Sjb dtp->dt_linktype = DT_LTYP_DOF; 356178479Sjb else 357178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 358178479Sjb 359178479Sjb return (0); 360178479Sjb} 361178479Sjb 362178479Sjb/*ARGSUSED*/ 363178479Sjbstatic int 364267942Srpaulodt_opt_encoding(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 365267942Srpaulo{ 366267942Srpaulo if (arg == NULL) 367267942Srpaulo return (dt_set_errno(dtp, EDT_BADOPTVAL)); 368267942Srpaulo 369267942Srpaulo if (strcmp(arg, "ascii") == 0) 370267942Srpaulo dtp->dt_encoding = DT_ENCODING_ASCII; 371267942Srpaulo else if (strcmp(arg, "utf8") == 0) 372267942Srpaulo dtp->dt_encoding = DT_ENCODING_UTF8; 373267942Srpaulo else 374267942Srpaulo return (dt_set_errno(dtp, EDT_BADOPTVAL)); 375267942Srpaulo 376267942Srpaulo return (0); 377267942Srpaulo} 378267942Srpaulo 379267942Srpaulo/*ARGSUSED*/ 380267942Srpaulostatic int 381178479Sjbdt_opt_evaltime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 382178479Sjb{ 383178479Sjb if (arg == NULL) 384178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 385178479Sjb 386178479Sjb if (strcmp(arg, "exec") == 0) 387178479Sjb dtp->dt_prcmode = DT_PROC_STOP_CREATE; 388178479Sjb else if (strcmp(arg, "preinit") == 0) 389178479Sjb dtp->dt_prcmode = DT_PROC_STOP_PREINIT; 390178479Sjb else if (strcmp(arg, "postinit") == 0) 391178479Sjb dtp->dt_prcmode = DT_PROC_STOP_POSTINIT; 392178479Sjb else if (strcmp(arg, "main") == 0) 393178479Sjb dtp->dt_prcmode = DT_PROC_STOP_MAIN; 394178479Sjb else 395178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 396178479Sjb 397178479Sjb return (0); 398178479Sjb} 399178479Sjb 400178479Sjb/*ARGSUSED*/ 401178479Sjbstatic int 402178479Sjbdt_opt_pgmax(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 403178479Sjb{ 404178479Sjb int n; 405178479Sjb 406178479Sjb if (arg == NULL || (n = atoi(arg)) < 0) 407178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 408178479Sjb 409178479Sjb dtp->dt_procs->dph_lrulim = n; 410178479Sjb return (0); 411178479Sjb} 412178479Sjb 413250574Smarkjstatic int 414250574Smarkjdt_opt_setenv(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 415250574Smarkj{ 416250574Smarkj char **p; 417250574Smarkj char *var; 418250574Smarkj int i; 419250574Smarkj 420250574Smarkj /* 421250574Smarkj * We can't effectively set environment variables from #pragma lines 422250574Smarkj * since the processes have already been spawned. 423250574Smarkj */ 424250574Smarkj if (dtp->dt_pcb != NULL) 425250574Smarkj return (dt_set_errno(dtp, EDT_BADOPTCTX)); 426250574Smarkj 427250574Smarkj if (arg == NULL) 428250574Smarkj return (dt_set_errno(dtp, EDT_BADOPTVAL)); 429250574Smarkj 430250574Smarkj if (!option && strchr(arg, '=') != NULL) 431250574Smarkj return (dt_set_errno(dtp, EDT_BADOPTVAL)); 432250574Smarkj 433250574Smarkj for (i = 1, p = dtp->dt_proc_env; *p != NULL; i++, p++) 434250574Smarkj continue; 435250574Smarkj 436250574Smarkj for (p = dtp->dt_proc_env; *p != NULL; p++) { 437250574Smarkj var = strchr(*p, '='); 438250574Smarkj if (var == NULL) 439250574Smarkj var = *p + strlen(*p); 440250574Smarkj if (strncmp(*p, arg, var - *p) == 0) { 441250574Smarkj dt_free(dtp, *p); 442250574Smarkj *p = dtp->dt_proc_env[i - 1]; 443250574Smarkj dtp->dt_proc_env[i - 1] = NULL; 444250574Smarkj i--; 445250574Smarkj } 446250574Smarkj } 447250574Smarkj 448250574Smarkj if (option) { 449250574Smarkj if ((var = strdup(arg)) == NULL) 450250574Smarkj return (dt_set_errno(dtp, EDT_NOMEM)); 451250574Smarkj 452250574Smarkj if ((p = dt_alloc(dtp, sizeof (char *) * (i + 1))) == NULL) { 453250574Smarkj dt_free(dtp, var); 454250574Smarkj return (dt_set_errno(dtp, EDT_NOMEM)); 455250574Smarkj } 456250574Smarkj 457250574Smarkj bcopy(dtp->dt_proc_env, p, sizeof (char *) * i); 458250574Smarkj dt_free(dtp, dtp->dt_proc_env); 459250574Smarkj dtp->dt_proc_env = p; 460250574Smarkj 461250574Smarkj dtp->dt_proc_env[i - 1] = var; 462250574Smarkj dtp->dt_proc_env[i] = NULL; 463250574Smarkj } 464250574Smarkj 465250574Smarkj return (0); 466250574Smarkj} 467250574Smarkj 468178479Sjb/*ARGSUSED*/ 469178479Sjbstatic int 470178479Sjbdt_opt_stdc(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 471178479Sjb{ 472178479Sjb if (arg == NULL) 473178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 474178479Sjb 475178479Sjb if (dtp->dt_pcb != NULL) 476178479Sjb return (dt_set_errno(dtp, EDT_BADOPTCTX)); 477178479Sjb 478178479Sjb if (strcmp(arg, "a") == 0) 479178479Sjb dtp->dt_stdcmode = DT_STDC_XA; 480178479Sjb else if (strcmp(arg, "c") == 0) 481178479Sjb dtp->dt_stdcmode = DT_STDC_XC; 482178479Sjb else if (strcmp(arg, "s") == 0) 483178479Sjb dtp->dt_stdcmode = DT_STDC_XS; 484178479Sjb else if (strcmp(arg, "t") == 0) 485178479Sjb dtp->dt_stdcmode = DT_STDC_XT; 486178479Sjb else 487178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 488178479Sjb 489178479Sjb return (0); 490178479Sjb} 491178479Sjb 492178479Sjb/*ARGSUSED*/ 493178479Sjbstatic int 494178479Sjbdt_opt_syslibdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 495178479Sjb{ 496178479Sjb dt_dirpath_t *dp = dt_list_next(&dtp->dt_lib_path); 497178479Sjb char *path; 498178479Sjb 499178479Sjb if (arg == NULL) 500178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 501178479Sjb 502178479Sjb if ((path = strdup(arg)) == NULL) 503178479Sjb return (dt_set_errno(dtp, EDT_NOMEM)); 504178479Sjb 505178479Sjb free(dp->dir_path); 506178479Sjb dp->dir_path = path; 507178479Sjb 508178479Sjb return (0); 509178479Sjb} 510178479Sjb 511178479Sjb/*ARGSUSED*/ 512178479Sjbstatic int 513178479Sjbdt_opt_tree(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 514178479Sjb{ 515178479Sjb int m; 516178479Sjb 517178479Sjb if (arg == NULL || (m = atoi(arg)) <= 0) 518178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 519178479Sjb 520178479Sjb dtp->dt_treedump = m; 521178479Sjb return (0); 522178479Sjb} 523178479Sjb 524178479Sjb/*ARGSUSED*/ 525178479Sjbstatic int 526178479Sjbdt_opt_tregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 527178479Sjb{ 528178479Sjb int n; 529178479Sjb 530178479Sjb if (arg == NULL || (n = atoi(arg)) <= 0) 531178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 532178479Sjb 533178479Sjb dtp->dt_conf.dtc_diftupregs = n; 534178479Sjb return (0); 535178479Sjb} 536178479Sjb 537178479Sjb/*ARGSUSED*/ 538178479Sjbstatic int 539178479Sjbdt_opt_xlate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 540178479Sjb{ 541178479Sjb if (arg == NULL) 542178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 543178479Sjb 544178479Sjb if (strcmp(arg, "dynamic") == 0) 545178479Sjb dtp->dt_xlatemode = DT_XL_DYNAMIC; 546178479Sjb else if (strcmp(arg, "static") == 0) 547178479Sjb dtp->dt_xlatemode = DT_XL_STATIC; 548178479Sjb else 549178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 550178479Sjb 551178479Sjb return (0); 552178479Sjb} 553178479Sjb 554178479Sjb/*ARGSUSED*/ 555178479Sjbstatic int 556178479Sjbdt_opt_cflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 557178479Sjb{ 558178479Sjb if (arg != NULL) 559178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 560178479Sjb 561178479Sjb if (dtp->dt_pcb != NULL) 562178479Sjb dtp->dt_pcb->pcb_cflags |= option; 563178479Sjb else 564178479Sjb dtp->dt_cflags |= option; 565178479Sjb 566178479Sjb return (0); 567178479Sjb} 568178479Sjb 569178479Sjbstatic int 570178479Sjbdt_opt_dflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 571178479Sjb{ 572178479Sjb if (arg != NULL) 573178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 574178479Sjb 575178479Sjb dtp->dt_dflags |= option; 576178479Sjb return (0); 577178479Sjb} 578178479Sjb 579178479Sjbstatic int 580178479Sjbdt_opt_invcflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 581178479Sjb{ 582178479Sjb if (arg != NULL) 583178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 584178479Sjb 585178479Sjb if (dtp->dt_pcb != NULL) 586178479Sjb dtp->dt_pcb->pcb_cflags &= ~option; 587178479Sjb else 588178479Sjb dtp->dt_cflags &= ~option; 589178479Sjb 590178479Sjb return (0); 591178479Sjb} 592178479Sjb 593178479Sjb/*ARGSUSED*/ 594178479Sjbstatic int 595178479Sjbdt_opt_version(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 596178479Sjb{ 597178479Sjb dt_version_t v; 598178479Sjb 599178479Sjb if (arg == NULL) 600178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 601178479Sjb 602178479Sjb if (dt_version_str2num(arg, &v) == -1) 603178479Sjb return (dt_set_errno(dtp, EDT_VERSINVAL)); 604178479Sjb 605178479Sjb if (!dt_version_defined(v)) 606178479Sjb return (dt_set_errno(dtp, EDT_VERSUNDEF)); 607178479Sjb 608178479Sjb return (dt_reduce(dtp, v)); 609178479Sjb} 610178479Sjb 611178479Sjbstatic int 612178479Sjbdt_opt_runtime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 613178479Sjb{ 614178479Sjb char *end; 615178479Sjb dtrace_optval_t val = 0; 616178479Sjb int i; 617178479Sjb 618178479Sjb const struct { 619178479Sjb char *positive; 620178479Sjb char *negative; 621178479Sjb } couples[] = { 622178479Sjb { "yes", "no" }, 623178479Sjb { "enable", "disable" }, 624178479Sjb { "enabled", "disabled" }, 625178479Sjb { "true", "false" }, 626178479Sjb { "on", "off" }, 627178479Sjb { "set", "unset" }, 628178479Sjb { NULL } 629178479Sjb }; 630178479Sjb 631178479Sjb if (arg != NULL) { 632178479Sjb if (arg[0] == '\0') { 633178479Sjb val = DTRACEOPT_UNSET; 634178479Sjb goto out; 635178479Sjb } 636178479Sjb 637178479Sjb for (i = 0; couples[i].positive != NULL; i++) { 638178479Sjb if (strcasecmp(couples[i].positive, arg) == 0) { 639178479Sjb val = 1; 640178479Sjb goto out; 641178479Sjb } 642178479Sjb 643178479Sjb if (strcasecmp(couples[i].negative, arg) == 0) { 644178479Sjb val = DTRACEOPT_UNSET; 645178479Sjb goto out; 646178479Sjb } 647178479Sjb } 648178479Sjb 649178479Sjb errno = 0; 650178479Sjb val = strtoull(arg, &end, 0); 651178479Sjb 652178479Sjb if (*end != '\0' || errno != 0 || val < 0) 653178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 654178479Sjb } 655178479Sjb 656178479Sjbout: 657178479Sjb dtp->dt_options[option] = val; 658178479Sjb return (0); 659178479Sjb} 660178479Sjb 661178479Sjbstatic int 662178479Sjbdt_optval_parse(const char *arg, dtrace_optval_t *rval) 663178479Sjb{ 664178479Sjb dtrace_optval_t mul = 1; 665178479Sjb size_t len; 666178479Sjb char *end; 667178479Sjb 668178479Sjb len = strlen(arg); 669178479Sjb errno = 0; 670178479Sjb 671178479Sjb switch (arg[len - 1]) { 672178479Sjb case 't': 673178479Sjb case 'T': 674178479Sjb mul *= 1024; 675178479Sjb /*FALLTHRU*/ 676178479Sjb case 'g': 677178479Sjb case 'G': 678178479Sjb mul *= 1024; 679178479Sjb /*FALLTHRU*/ 680178479Sjb case 'm': 681178479Sjb case 'M': 682178479Sjb mul *= 1024; 683178479Sjb /*FALLTHRU*/ 684178479Sjb case 'k': 685178479Sjb case 'K': 686178479Sjb mul *= 1024; 687178479Sjb /*FALLTHRU*/ 688178479Sjb default: 689178479Sjb break; 690178479Sjb } 691178479Sjb 692178479Sjb errno = 0; 693178479Sjb *rval = strtoull(arg, &end, 0) * mul; 694178479Sjb 695178479Sjb if ((mul > 1 && end != &arg[len - 1]) || (mul == 1 && *end != '\0') || 696178479Sjb *rval < 0 || errno != 0) 697178479Sjb return (-1); 698178479Sjb 699178479Sjb return (0); 700178479Sjb} 701178479Sjb 702178479Sjbstatic int 703178479Sjbdt_opt_size(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 704178479Sjb{ 705178479Sjb dtrace_optval_t val = 0; 706178479Sjb 707178479Sjb if (arg != NULL && dt_optval_parse(arg, &val) != 0) 708178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 709178479Sjb 710178479Sjb dtp->dt_options[option] = val; 711178479Sjb return (0); 712178479Sjb} 713178479Sjb 714178479Sjbstatic int 715178479Sjbdt_opt_rate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 716178479Sjb{ 717178479Sjb char *end; 718178479Sjb int i; 719178479Sjb dtrace_optval_t mul = 1, val = 0; 720178479Sjb 721178479Sjb const struct { 722178479Sjb char *name; 723178479Sjb hrtime_t mul; 724178479Sjb } suffix[] = { 725178479Sjb { "ns", NANOSEC / NANOSEC }, 726178479Sjb { "nsec", NANOSEC / NANOSEC }, 727178479Sjb { "us", NANOSEC / MICROSEC }, 728178479Sjb { "usec", NANOSEC / MICROSEC }, 729178479Sjb { "ms", NANOSEC / MILLISEC }, 730178479Sjb { "msec", NANOSEC / MILLISEC }, 731178479Sjb { "s", NANOSEC / SEC }, 732178479Sjb { "sec", NANOSEC / SEC }, 733178479Sjb { "m", NANOSEC * (hrtime_t)60 }, 734178479Sjb { "min", NANOSEC * (hrtime_t)60 }, 735178479Sjb { "h", NANOSEC * (hrtime_t)60 * (hrtime_t)60 }, 736178479Sjb { "hour", NANOSEC * (hrtime_t)60 * (hrtime_t)60 }, 737178479Sjb { "d", NANOSEC * (hrtime_t)(24 * 60 * 60) }, 738178479Sjb { "day", NANOSEC * (hrtime_t)(24 * 60 * 60) }, 739178479Sjb { "hz", 0 }, 740178479Sjb { NULL } 741178479Sjb }; 742178479Sjb 743178479Sjb if (arg != NULL) { 744178479Sjb errno = 0; 745178479Sjb val = strtoull(arg, &end, 0); 746178479Sjb 747178479Sjb for (i = 0; suffix[i].name != NULL; i++) { 748178479Sjb if (strcasecmp(suffix[i].name, end) == 0) { 749178479Sjb mul = suffix[i].mul; 750178479Sjb break; 751178479Sjb } 752178479Sjb } 753178479Sjb 754178479Sjb if (suffix[i].name == NULL && *end != '\0' || val < 0) 755178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 756178479Sjb 757178479Sjb if (mul == 0) { 758178479Sjb /* 759178479Sjb * The rate has been specified in frequency-per-second. 760178479Sjb */ 761178479Sjb if (val != 0) 762178479Sjb val = NANOSEC / val; 763178479Sjb } else { 764178479Sjb val *= mul; 765178479Sjb } 766178479Sjb } 767178479Sjb 768178479Sjb dtp->dt_options[option] = val; 769178479Sjb return (0); 770178479Sjb} 771178479Sjb 772178479Sjb/* 773178479Sjb * When setting the strsize option, set the option in the dt_options array 774178479Sjb * using dt_opt_size() as usual, and then update the definition of the CTF 775178479Sjb * type for the D intrinsic "string" to be an array of the corresponding size. 776178479Sjb * If any errors occur, reset dt_options[option] to its previous value. 777178479Sjb */ 778178479Sjbstatic int 779178479Sjbdt_opt_strsize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 780178479Sjb{ 781178479Sjb dtrace_optval_t val = dtp->dt_options[option]; 782178479Sjb ctf_file_t *fp = DT_STR_CTFP(dtp); 783178479Sjb ctf_id_t type = ctf_type_resolve(fp, DT_STR_TYPE(dtp)); 784178479Sjb ctf_arinfo_t r; 785178479Sjb 786178479Sjb if (dt_opt_size(dtp, arg, option) != 0) 787178479Sjb return (-1); /* dt_errno is set for us */ 788178479Sjb 789178479Sjb if (dtp->dt_options[option] > UINT_MAX) { 790178479Sjb dtp->dt_options[option] = val; 791178479Sjb return (dt_set_errno(dtp, EOVERFLOW)); 792178479Sjb } 793178479Sjb 794178479Sjb if (ctf_array_info(fp, type, &r) == CTF_ERR) { 795178479Sjb dtp->dt_options[option] = val; 796178479Sjb dtp->dt_ctferr = ctf_errno(fp); 797178479Sjb return (dt_set_errno(dtp, EDT_CTF)); 798178479Sjb } 799178479Sjb 800178479Sjb r.ctr_nelems = (uint_t)dtp->dt_options[option]; 801178479Sjb 802178479Sjb if (ctf_set_array(fp, type, &r) == CTF_ERR || 803178479Sjb ctf_update(fp) == CTF_ERR) { 804178479Sjb dtp->dt_options[option] = val; 805178479Sjb dtp->dt_ctferr = ctf_errno(fp); 806178479Sjb return (dt_set_errno(dtp, EDT_CTF)); 807178479Sjb } 808178479Sjb 809178479Sjb return (0); 810178479Sjb} 811178479Sjb 812178479Sjbstatic const struct { 813178479Sjb const char *dtbp_name; 814178479Sjb int dtbp_policy; 815178479Sjb} _dtrace_bufpolicies[] = { 816178479Sjb { "ring", DTRACEOPT_BUFPOLICY_RING }, 817178479Sjb { "fill", DTRACEOPT_BUFPOLICY_FILL }, 818178479Sjb { "switch", DTRACEOPT_BUFPOLICY_SWITCH }, 819178479Sjb { NULL, 0 } 820178479Sjb}; 821178479Sjb 822178479Sjb/*ARGSUSED*/ 823178479Sjbstatic int 824178479Sjbdt_opt_bufpolicy(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 825178479Sjb{ 826178479Sjb dtrace_optval_t policy = DTRACEOPT_UNSET; 827178479Sjb int i; 828178479Sjb 829178479Sjb if (arg == NULL) 830178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 831178479Sjb 832178479Sjb for (i = 0; _dtrace_bufpolicies[i].dtbp_name != NULL; i++) { 833178479Sjb if (strcmp(_dtrace_bufpolicies[i].dtbp_name, arg) == 0) { 834178479Sjb policy = _dtrace_bufpolicies[i].dtbp_policy; 835178479Sjb break; 836178479Sjb } 837178479Sjb } 838178479Sjb 839178479Sjb if (policy == DTRACEOPT_UNSET) 840178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 841178479Sjb 842178479Sjb dtp->dt_options[DTRACEOPT_BUFPOLICY] = policy; 843178479Sjb 844178479Sjb return (0); 845178479Sjb} 846178479Sjb 847178479Sjbstatic const struct { 848178479Sjb const char *dtbr_name; 849178479Sjb int dtbr_policy; 850178479Sjb} _dtrace_bufresize[] = { 851178479Sjb { "auto", DTRACEOPT_BUFRESIZE_AUTO }, 852178479Sjb { "manual", DTRACEOPT_BUFRESIZE_MANUAL }, 853178479Sjb { NULL, 0 } 854178479Sjb}; 855178479Sjb 856178479Sjb/*ARGSUSED*/ 857178479Sjbstatic int 858178479Sjbdt_opt_bufresize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 859178479Sjb{ 860178479Sjb dtrace_optval_t policy = DTRACEOPT_UNSET; 861178479Sjb int i; 862178479Sjb 863178479Sjb if (arg == NULL) 864178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 865178479Sjb 866178479Sjb for (i = 0; _dtrace_bufresize[i].dtbr_name != NULL; i++) { 867178479Sjb if (strcmp(_dtrace_bufresize[i].dtbr_name, arg) == 0) { 868178479Sjb policy = _dtrace_bufresize[i].dtbr_policy; 869178479Sjb break; 870178479Sjb } 871178479Sjb } 872178479Sjb 873178479Sjb if (policy == DTRACEOPT_UNSET) 874178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 875178479Sjb 876178479Sjb dtp->dt_options[DTRACEOPT_BUFRESIZE] = policy; 877178479Sjb 878178479Sjb return (0); 879178479Sjb} 880178479Sjb 881178479Sjbint 882178479Sjbdt_options_load(dtrace_hdl_t *dtp) 883178479Sjb{ 884178479Sjb dof_hdr_t hdr, *dof; 885178479Sjb dof_sec_t *sec; 886178479Sjb size_t offs; 887178479Sjb int i; 888178479Sjb 889178479Sjb /* 890178479Sjb * To load the option values, we need to ask the kernel to provide its 891178479Sjb * DOF, which we'll sift through to look for OPTDESC sections. 892178479Sjb */ 893178479Sjb bzero(&hdr, sizeof (dof_hdr_t)); 894178479Sjb hdr.dofh_loadsz = sizeof (dof_hdr_t); 895178479Sjb 896277300Ssmh#ifdef illumos 897178479Sjb if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &hdr) == -1) 898178569Sjb#else 899178569Sjb dof = &hdr; 900178569Sjb if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &dof) == -1) 901178569Sjb#endif 902178479Sjb return (dt_set_errno(dtp, errno)); 903178479Sjb 904178479Sjb if (hdr.dofh_loadsz < sizeof (dof_hdr_t)) 905178479Sjb return (dt_set_errno(dtp, EINVAL)); 906178479Sjb 907178479Sjb dof = alloca(hdr.dofh_loadsz); 908178479Sjb bzero(dof, sizeof (dof_hdr_t)); 909178479Sjb dof->dofh_loadsz = hdr.dofh_loadsz; 910178479Sjb 911178479Sjb for (i = 0; i < DTRACEOPT_MAX; i++) 912178479Sjb dtp->dt_options[i] = DTRACEOPT_UNSET; 913178479Sjb 914277300Ssmh#ifdef illumos 915178479Sjb if (dt_ioctl(dtp, DTRACEIOC_DOFGET, dof) == -1) 916178569Sjb#else 917178569Sjb if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &dof) == -1) 918178569Sjb#endif 919178479Sjb return (dt_set_errno(dtp, errno)); 920178479Sjb 921178479Sjb for (i = 0; i < dof->dofh_secnum; i++) { 922178479Sjb sec = (dof_sec_t *)(uintptr_t)((uintptr_t)dof + 923178479Sjb dof->dofh_secoff + i * dof->dofh_secsize); 924178479Sjb 925178479Sjb if (sec->dofs_type != DOF_SECT_OPTDESC) 926178479Sjb continue; 927178479Sjb 928178479Sjb break; 929178479Sjb } 930178479Sjb 931178479Sjb for (offs = 0; offs < sec->dofs_size; offs += sec->dofs_entsize) { 932178479Sjb dof_optdesc_t *opt = (dof_optdesc_t *)(uintptr_t) 933178479Sjb ((uintptr_t)dof + sec->dofs_offset + offs); 934178479Sjb 935178479Sjb if (opt->dofo_strtab != DOF_SECIDX_NONE) 936178479Sjb continue; 937178479Sjb 938178479Sjb if (opt->dofo_option >= DTRACEOPT_MAX) 939178479Sjb continue; 940178479Sjb 941178479Sjb dtp->dt_options[opt->dofo_option] = opt->dofo_value; 942178479Sjb } 943178479Sjb 944178479Sjb return (0); 945178479Sjb} 946178479Sjb 947178479Sjbtypedef struct dt_option { 948178479Sjb const char *o_name; 949178479Sjb int (*o_func)(dtrace_hdl_t *, const char *, uintptr_t); 950178479Sjb uintptr_t o_option; 951178479Sjb} dt_option_t; 952178479Sjb 953178479Sjb/* 954178479Sjb * Compile-time options. 955178479Sjb */ 956178479Sjbstatic const dt_option_t _dtrace_ctoptions[] = { 957178479Sjb { "aggpercpu", dt_opt_agg, DTRACE_A_PERCPU }, 958178479Sjb { "amin", dt_opt_amin }, 959178479Sjb { "argref", dt_opt_cflags, DTRACE_C_ARGREF }, 960178479Sjb { "core", dt_opt_core }, 961178479Sjb { "cpp", dt_opt_cflags, DTRACE_C_CPP }, 962178479Sjb { "cpphdrs", dt_opt_cpp_hdrs }, 963178479Sjb { "cpppath", dt_opt_cpp_path }, 964178479Sjb { "ctypes", dt_opt_ctypes }, 965178479Sjb { "defaultargs", dt_opt_cflags, DTRACE_C_DEFARG }, 966178479Sjb { "dtypes", dt_opt_dtypes }, 967178479Sjb { "debug", dt_opt_debug }, 968178479Sjb { "define", dt_opt_cpp_opts, (uintptr_t)"-D" }, 969178479Sjb { "droptags", dt_opt_droptags }, 970178479Sjb { "empty", dt_opt_cflags, DTRACE_C_EMPTY }, 971267942Srpaulo { "encoding", dt_opt_encoding }, 972178479Sjb { "errtags", dt_opt_cflags, DTRACE_C_ETAGS }, 973178479Sjb { "evaltime", dt_opt_evaltime }, 974178479Sjb { "incdir", dt_opt_cpp_opts, (uintptr_t)"-I" }, 975178479Sjb { "iregs", dt_opt_iregs }, 976178479Sjb { "kdefs", dt_opt_invcflags, DTRACE_C_KNODEF }, 977178479Sjb { "knodefs", dt_opt_cflags, DTRACE_C_KNODEF }, 978178479Sjb { "late", dt_opt_xlate }, 979178479Sjb { "lazyload", dt_opt_lazyload }, 980178479Sjb { "ldpath", dt_opt_ld_path }, 981178479Sjb { "libdir", dt_opt_libdir }, 982178479Sjb { "linkmode", dt_opt_linkmode }, 983178479Sjb { "linktype", dt_opt_linktype }, 984178479Sjb { "nolibs", dt_opt_cflags, DTRACE_C_NOLIBS }, 985278934Smarkj#ifdef __FreeBSD__ 986278934Smarkj { "objcopypath", dt_opt_objcopy_path }, 987278934Smarkj#endif 988178479Sjb { "pgmax", dt_opt_pgmax }, 989178479Sjb { "pspec", dt_opt_cflags, DTRACE_C_PSPEC }, 990250574Smarkj { "setenv", dt_opt_setenv, 1 }, 991178479Sjb { "stdc", dt_opt_stdc }, 992178479Sjb { "strip", dt_opt_dflags, DTRACE_D_STRIP }, 993178479Sjb { "syslibdir", dt_opt_syslibdir }, 994178479Sjb { "tree", dt_opt_tree }, 995178479Sjb { "tregs", dt_opt_tregs }, 996178479Sjb { "udefs", dt_opt_invcflags, DTRACE_C_UNODEF }, 997178479Sjb { "undef", dt_opt_cpp_opts, (uintptr_t)"-U" }, 998178479Sjb { "unodefs", dt_opt_cflags, DTRACE_C_UNODEF }, 999250574Smarkj { "unsetenv", dt_opt_setenv, 0 }, 1000178479Sjb { "verbose", dt_opt_cflags, DTRACE_C_DIFV }, 1001178479Sjb { "version", dt_opt_version }, 1002178479Sjb { "zdefs", dt_opt_cflags, DTRACE_C_ZDEFS }, 1003178569Sjb { NULL, NULL, 0 } 1004178479Sjb}; 1005178479Sjb 1006178479Sjb/* 1007178479Sjb * Run-time options. 1008178479Sjb */ 1009178479Sjbstatic const dt_option_t _dtrace_rtoptions[] = { 1010178479Sjb { "aggsize", dt_opt_size, DTRACEOPT_AGGSIZE }, 1011178479Sjb { "bufsize", dt_opt_size, DTRACEOPT_BUFSIZE }, 1012178479Sjb { "bufpolicy", dt_opt_bufpolicy, DTRACEOPT_BUFPOLICY }, 1013178479Sjb { "bufresize", dt_opt_bufresize, DTRACEOPT_BUFRESIZE }, 1014178479Sjb { "cleanrate", dt_opt_rate, DTRACEOPT_CLEANRATE }, 1015178479Sjb { "cpu", dt_opt_runtime, DTRACEOPT_CPU }, 1016178479Sjb { "destructive", dt_opt_runtime, DTRACEOPT_DESTRUCTIVE }, 1017178479Sjb { "dynvarsize", dt_opt_size, DTRACEOPT_DYNVARSIZE }, 1018178479Sjb { "grabanon", dt_opt_runtime, DTRACEOPT_GRABANON }, 1019178479Sjb { "jstackframes", dt_opt_runtime, DTRACEOPT_JSTACKFRAMES }, 1020178479Sjb { "jstackstrsize", dt_opt_size, DTRACEOPT_JSTACKSTRSIZE }, 1021178479Sjb { "nspec", dt_opt_runtime, DTRACEOPT_NSPEC }, 1022178479Sjb { "specsize", dt_opt_size, DTRACEOPT_SPECSIZE }, 1023178479Sjb { "stackframes", dt_opt_runtime, DTRACEOPT_STACKFRAMES }, 1024178479Sjb { "statusrate", dt_opt_rate, DTRACEOPT_STATUSRATE }, 1025178479Sjb { "strsize", dt_opt_strsize, DTRACEOPT_STRSIZE }, 1026178479Sjb { "ustackframes", dt_opt_runtime, DTRACEOPT_USTACKFRAMES }, 1027250574Smarkj { "temporal", dt_opt_runtime, DTRACEOPT_TEMPORAL }, 1028178569Sjb { NULL, NULL, 0 } 1029178479Sjb}; 1030178479Sjb 1031178479Sjb/* 1032178479Sjb * Dynamic run-time options. 1033178479Sjb */ 1034178479Sjbstatic const dt_option_t _dtrace_drtoptions[] = { 1035267942Srpaulo { "agghist", dt_opt_runtime, DTRACEOPT_AGGHIST }, 1036267942Srpaulo { "aggpack", dt_opt_runtime, DTRACEOPT_AGGPACK }, 1037178479Sjb { "aggrate", dt_opt_rate, DTRACEOPT_AGGRATE }, 1038178479Sjb { "aggsortkey", dt_opt_runtime, DTRACEOPT_AGGSORTKEY }, 1039178479Sjb { "aggsortkeypos", dt_opt_runtime, DTRACEOPT_AGGSORTKEYPOS }, 1040178479Sjb { "aggsortpos", dt_opt_runtime, DTRACEOPT_AGGSORTPOS }, 1041178479Sjb { "aggsortrev", dt_opt_runtime, DTRACEOPT_AGGSORTREV }, 1042267942Srpaulo { "aggzoom", dt_opt_runtime, DTRACEOPT_AGGZOOM }, 1043178479Sjb { "flowindent", dt_opt_runtime, DTRACEOPT_FLOWINDENT }, 1044178479Sjb { "quiet", dt_opt_runtime, DTRACEOPT_QUIET }, 1045178479Sjb { "rawbytes", dt_opt_runtime, DTRACEOPT_RAWBYTES }, 1046178479Sjb { "stackindent", dt_opt_runtime, DTRACEOPT_STACKINDENT }, 1047178479Sjb { "switchrate", dt_opt_rate, DTRACEOPT_SWITCHRATE }, 1048178569Sjb { NULL, NULL, 0 } 1049178479Sjb}; 1050178479Sjb 1051178479Sjbint 1052178479Sjbdtrace_getopt(dtrace_hdl_t *dtp, const char *opt, dtrace_optval_t *val) 1053178479Sjb{ 1054178479Sjb const dt_option_t *op; 1055178479Sjb 1056178479Sjb if (opt == NULL) 1057178479Sjb return (dt_set_errno(dtp, EINVAL)); 1058178479Sjb 1059178479Sjb /* 1060178479Sjb * We only need to search the run-time options -- it's not legal 1061178479Sjb * to get the values of compile-time options. 1062178479Sjb */ 1063178479Sjb for (op = _dtrace_rtoptions; op->o_name != NULL; op++) { 1064178479Sjb if (strcmp(op->o_name, opt) == 0) { 1065178479Sjb *val = dtp->dt_options[op->o_option]; 1066178479Sjb return (0); 1067178479Sjb } 1068178479Sjb } 1069178479Sjb 1070178479Sjb for (op = _dtrace_drtoptions; op->o_name != NULL; op++) { 1071178479Sjb if (strcmp(op->o_name, opt) == 0) { 1072178479Sjb *val = dtp->dt_options[op->o_option]; 1073178479Sjb return (0); 1074178479Sjb } 1075178479Sjb } 1076178479Sjb 1077178479Sjb return (dt_set_errno(dtp, EDT_BADOPTNAME)); 1078178479Sjb} 1079178479Sjb 1080178479Sjbint 1081178479Sjbdtrace_setopt(dtrace_hdl_t *dtp, const char *opt, const char *val) 1082178479Sjb{ 1083178479Sjb const dt_option_t *op; 1084178479Sjb 1085178479Sjb if (opt == NULL) 1086178479Sjb return (dt_set_errno(dtp, EINVAL)); 1087178479Sjb 1088178479Sjb for (op = _dtrace_ctoptions; op->o_name != NULL; op++) { 1089178479Sjb if (strcmp(op->o_name, opt) == 0) 1090178479Sjb return (op->o_func(dtp, val, op->o_option)); 1091178479Sjb } 1092178479Sjb 1093178479Sjb for (op = _dtrace_drtoptions; op->o_name != NULL; op++) { 1094178479Sjb if (strcmp(op->o_name, opt) == 0) 1095178479Sjb return (op->o_func(dtp, val, op->o_option)); 1096178479Sjb } 1097178479Sjb 1098178479Sjb for (op = _dtrace_rtoptions; op->o_name != NULL; op++) { 1099178479Sjb if (strcmp(op->o_name, opt) == 0) { 1100178479Sjb /* 1101178479Sjb * Only dynamic run-time options may be set while 1102178479Sjb * tracing is active. 1103178479Sjb */ 1104178479Sjb if (dtp->dt_active) 1105178479Sjb return (dt_set_errno(dtp, EDT_ACTIVE)); 1106178479Sjb 1107178479Sjb return (op->o_func(dtp, val, op->o_option)); 1108178479Sjb } 1109178479Sjb } 1110178479Sjb 1111178479Sjb return (dt_set_errno(dtp, EDT_BADOPTNAME)); 1112178479Sjb} 1113