dt_options.c revision 250574
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 27178479Sjb#pragma ident "%Z%%M% %I% %E% SMI" 28178479Sjb 29250574Smarkj/* 30250574Smarkj * Copyright (c) 2012 by Delphix. All rights reserved. 31250574Smarkj */ 32250574Smarkj 33178479Sjb#include <sys/resource.h> 34178479Sjb#include <sys/mman.h> 35178479Sjb#include <sys/types.h> 36178479Sjb 37178479Sjb#include <strings.h> 38178479Sjb#include <signal.h> 39178479Sjb#include <stdlib.h> 40178479Sjb#include <unistd.h> 41178479Sjb#include <limits.h> 42178569Sjb#if defined(sun) 43178479Sjb#include <alloca.h> 44178569Sjb#endif 45178479Sjb#include <errno.h> 46178479Sjb#include <fcntl.h> 47178479Sjb 48178479Sjb#include <dt_impl.h> 49178479Sjb#include <dt_string.h> 50178479Sjb 51178479Sjbstatic int 52178479Sjbdt_opt_agg(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 53178479Sjb{ 54178479Sjb dt_aggregate_t *agp = &dtp->dt_aggregate; 55178479Sjb 56178479Sjb if (arg != NULL) 57178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 58178479Sjb 59178479Sjb agp->dtat_flags |= option; 60178479Sjb return (0); 61178479Sjb} 62178479Sjb 63178479Sjb/*ARGSUSED*/ 64178479Sjbstatic int 65178479Sjbdt_opt_amin(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 66178479Sjb{ 67178479Sjb char str[DTRACE_ATTR2STR_MAX]; 68178479Sjb dtrace_attribute_t attr; 69178479Sjb 70178479Sjb if (arg == NULL || dtrace_str2attr(arg, &attr) == -1) 71178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 72178479Sjb 73178479Sjb dt_dprintf("set compiler attribute minimum to %s\n", 74178479Sjb dtrace_attr2str(attr, str, sizeof (str))); 75178479Sjb 76178479Sjb if (dtp->dt_pcb != NULL) { 77178479Sjb dtp->dt_pcb->pcb_cflags |= DTRACE_C_EATTR; 78178479Sjb dtp->dt_pcb->pcb_amin = attr; 79178479Sjb } else { 80178479Sjb dtp->dt_cflags |= DTRACE_C_EATTR; 81178479Sjb dtp->dt_amin = attr; 82178479Sjb } 83178479Sjb 84178479Sjb return (0); 85178479Sjb} 86178479Sjb 87178479Sjbstatic void 88178479Sjbdt_coredump(void) 89178479Sjb{ 90178479Sjb const char msg[] = "libdtrace DEBUG: [ forcing coredump ]\n"; 91178479Sjb 92178479Sjb struct sigaction act; 93178479Sjb struct rlimit lim; 94178479Sjb 95178479Sjb (void) write(STDERR_FILENO, msg, sizeof (msg) - 1); 96178479Sjb 97178479Sjb act.sa_handler = SIG_DFL; 98178479Sjb act.sa_flags = 0; 99178479Sjb 100178479Sjb (void) sigemptyset(&act.sa_mask); 101178479Sjb (void) sigaction(SIGABRT, &act, NULL); 102178479Sjb 103178479Sjb lim.rlim_cur = RLIM_INFINITY; 104178479Sjb lim.rlim_max = RLIM_INFINITY; 105178479Sjb 106178479Sjb (void) setrlimit(RLIMIT_CORE, &lim); 107178479Sjb abort(); 108178479Sjb} 109178479Sjb 110178479Sjb/*ARGSUSED*/ 111178479Sjbstatic int 112178479Sjbdt_opt_core(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 113178479Sjb{ 114178479Sjb static int enabled = 0; 115178479Sjb 116178479Sjb if (arg != NULL) 117178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 118178479Sjb 119178479Sjb if (enabled++ || atexit(dt_coredump) == 0) 120178479Sjb return (0); 121178479Sjb 122178479Sjb return (dt_set_errno(dtp, errno)); 123178479Sjb} 124178479Sjb 125178479Sjb/*ARGSUSED*/ 126178479Sjbstatic int 127178479Sjbdt_opt_cpp_hdrs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 128178479Sjb{ 129178479Sjb if (arg != NULL) 130178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 131178479Sjb 132178479Sjb if (dtp->dt_pcb != NULL) 133178479Sjb return (dt_set_errno(dtp, EDT_BADOPTCTX)); 134178479Sjb 135178479Sjb if (dt_cpp_add_arg(dtp, "-H") == NULL) 136178479Sjb return (dt_set_errno(dtp, EDT_NOMEM)); 137178479Sjb 138178479Sjb return (0); 139178479Sjb} 140178479Sjb 141178479Sjb/*ARGSUSED*/ 142178479Sjbstatic int 143178479Sjbdt_opt_cpp_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 144178479Sjb{ 145178479Sjb char *cpp; 146178479Sjb 147178479Sjb if (arg == NULL) 148178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 149178479Sjb 150178479Sjb if (dtp->dt_pcb != NULL) 151178479Sjb return (dt_set_errno(dtp, EDT_BADOPTCTX)); 152178479Sjb 153178479Sjb if ((cpp = strdup(arg)) == NULL) 154178479Sjb return (dt_set_errno(dtp, EDT_NOMEM)); 155178479Sjb 156178479Sjb dtp->dt_cpp_argv[0] = (char *)strbasename(cpp); 157178479Sjb free(dtp->dt_cpp_path); 158178479Sjb dtp->dt_cpp_path = cpp; 159178479Sjb 160178479Sjb return (0); 161178479Sjb} 162178479Sjb 163178479Sjbstatic int 164178479Sjbdt_opt_cpp_opts(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 165178479Sjb{ 166178479Sjb char *buf; 167178479Sjb size_t len; 168178479Sjb const char *opt = (const char *)option; 169178479Sjb 170178479Sjb if (opt == NULL || arg == NULL) 171178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 172178479Sjb 173178479Sjb if (dtp->dt_pcb != NULL) 174178479Sjb return (dt_set_errno(dtp, EDT_BADOPTCTX)); 175178479Sjb 176178479Sjb len = strlen(opt) + strlen(arg) + 1; 177178479Sjb buf = alloca(len); 178178479Sjb 179178479Sjb (void) strcpy(buf, opt); 180178479Sjb (void) strcat(buf, arg); 181178479Sjb 182178479Sjb if (dt_cpp_add_arg(dtp, buf) == NULL) 183178479Sjb return (dt_set_errno(dtp, EDT_NOMEM)); 184178479Sjb 185178479Sjb return (0); 186178479Sjb} 187178479Sjb 188178479Sjb/*ARGSUSED*/ 189178479Sjbstatic int 190178479Sjbdt_opt_ctypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 191178479Sjb{ 192178479Sjb int fd; 193178479Sjb 194178479Sjb if (arg == NULL) 195178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 196178479Sjb 197178479Sjb if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1) 198178479Sjb return (dt_set_errno(dtp, errno)); 199178479Sjb 200178479Sjb (void) close(dtp->dt_cdefs_fd); 201178479Sjb dtp->dt_cdefs_fd = fd; 202178479Sjb return (0); 203178479Sjb} 204178479Sjb 205178479Sjb/*ARGSUSED*/ 206178479Sjbstatic int 207178479Sjbdt_opt_droptags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 208178479Sjb{ 209178479Sjb dtp->dt_droptags = 1; 210178479Sjb return (0); 211178479Sjb} 212178479Sjb 213178479Sjb/*ARGSUSED*/ 214178479Sjbstatic int 215178479Sjbdt_opt_dtypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 216178479Sjb{ 217178479Sjb int fd; 218178479Sjb 219178479Sjb if (arg == NULL) 220178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 221178479Sjb 222178479Sjb if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1) 223178479Sjb return (dt_set_errno(dtp, errno)); 224178479Sjb 225178479Sjb (void) close(dtp->dt_ddefs_fd); 226178479Sjb dtp->dt_ddefs_fd = fd; 227178479Sjb return (0); 228178479Sjb} 229178479Sjb 230178479Sjb/*ARGSUSED*/ 231178479Sjbstatic int 232178479Sjbdt_opt_debug(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 233178479Sjb{ 234178479Sjb if (arg != NULL) 235178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 236178479Sjb 237178479Sjb _dtrace_debug = 1; 238178479Sjb return (0); 239178479Sjb} 240178479Sjb 241178479Sjb/*ARGSUSED*/ 242178479Sjbstatic int 243178479Sjbdt_opt_iregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 244178479Sjb{ 245178479Sjb int n; 246178479Sjb 247178479Sjb if (arg == NULL || (n = atoi(arg)) <= 0) 248178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 249178479Sjb 250178479Sjb dtp->dt_conf.dtc_difintregs = n; 251178479Sjb return (0); 252178479Sjb} 253178479Sjb 254178479Sjb/*ARGSUSED*/ 255178479Sjbstatic int 256178479Sjbdt_opt_lazyload(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 257178479Sjb{ 258178479Sjb dtp->dt_lazyload = 1; 259178479Sjb 260178479Sjb return (0); 261178479Sjb} 262178479Sjb 263178479Sjb/*ARGSUSED*/ 264178479Sjbstatic int 265178479Sjbdt_opt_ld_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 266178479Sjb{ 267178479Sjb char *ld; 268178479Sjb 269178479Sjb if (arg == NULL) 270178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 271178479Sjb 272178479Sjb if (dtp->dt_pcb != NULL) 273178479Sjb return (dt_set_errno(dtp, EDT_BADOPTCTX)); 274178479Sjb 275178479Sjb if ((ld = strdup(arg)) == NULL) 276178479Sjb return (dt_set_errno(dtp, EDT_NOMEM)); 277178479Sjb 278178479Sjb free(dtp->dt_ld_path); 279178479Sjb dtp->dt_ld_path = ld; 280178479Sjb 281178479Sjb return (0); 282178479Sjb} 283178479Sjb 284178479Sjb/*ARGSUSED*/ 285178479Sjbstatic int 286178479Sjbdt_opt_libdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 287178479Sjb{ 288178479Sjb dt_dirpath_t *dp; 289178479Sjb 290178479Sjb if (arg == NULL) 291178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 292178479Sjb 293178479Sjb if ((dp = malloc(sizeof (dt_dirpath_t))) == NULL || 294178479Sjb (dp->dir_path = strdup(arg)) == NULL) { 295178479Sjb free(dp); 296178479Sjb return (dt_set_errno(dtp, EDT_NOMEM)); 297178479Sjb } 298178479Sjb 299178479Sjb dt_list_append(&dtp->dt_lib_path, dp); 300178479Sjb return (0); 301178479Sjb} 302178479Sjb 303178479Sjb/*ARGSUSED*/ 304178479Sjbstatic int 305178479Sjbdt_opt_linkmode(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 306178479Sjb{ 307178479Sjb if (arg == NULL) 308178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 309178479Sjb 310178479Sjb if (strcmp(arg, "kernel") == 0) 311178479Sjb dtp->dt_linkmode = DT_LINK_KERNEL; 312178479Sjb else if (strcmp(arg, "primary") == 0) 313178479Sjb dtp->dt_linkmode = DT_LINK_PRIMARY; 314178479Sjb else if (strcmp(arg, "dynamic") == 0) 315178479Sjb dtp->dt_linkmode = DT_LINK_DYNAMIC; 316178479Sjb else if (strcmp(arg, "static") == 0) 317178479Sjb dtp->dt_linkmode = DT_LINK_STATIC; 318178479Sjb else 319178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 320178479Sjb 321178479Sjb return (0); 322178479Sjb} 323178479Sjb 324178479Sjb/*ARGSUSED*/ 325178479Sjbstatic int 326178479Sjbdt_opt_linktype(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 (strcasecmp(arg, "elf") == 0) 332178479Sjb dtp->dt_linktype = DT_LTYP_ELF; 333178479Sjb else if (strcasecmp(arg, "dof") == 0) 334178479Sjb dtp->dt_linktype = DT_LTYP_DOF; 335178479Sjb else 336178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 337178479Sjb 338178479Sjb return (0); 339178479Sjb} 340178479Sjb 341178479Sjb/*ARGSUSED*/ 342178479Sjbstatic int 343178479Sjbdt_opt_evaltime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 344178479Sjb{ 345178479Sjb if (arg == NULL) 346178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 347178479Sjb 348178479Sjb if (strcmp(arg, "exec") == 0) 349178479Sjb dtp->dt_prcmode = DT_PROC_STOP_CREATE; 350178479Sjb else if (strcmp(arg, "preinit") == 0) 351178479Sjb dtp->dt_prcmode = DT_PROC_STOP_PREINIT; 352178479Sjb else if (strcmp(arg, "postinit") == 0) 353178479Sjb dtp->dt_prcmode = DT_PROC_STOP_POSTINIT; 354178479Sjb else if (strcmp(arg, "main") == 0) 355178479Sjb dtp->dt_prcmode = DT_PROC_STOP_MAIN; 356178479Sjb else 357178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 358178479Sjb 359178479Sjb return (0); 360178479Sjb} 361178479Sjb 362178479Sjb/*ARGSUSED*/ 363178479Sjbstatic int 364178479Sjbdt_opt_pgmax(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 365178479Sjb{ 366178479Sjb int n; 367178479Sjb 368178479Sjb if (arg == NULL || (n = atoi(arg)) < 0) 369178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 370178479Sjb 371178479Sjb dtp->dt_procs->dph_lrulim = n; 372178479Sjb return (0); 373178479Sjb} 374178479Sjb 375250574Smarkjstatic int 376250574Smarkjdt_opt_setenv(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 377250574Smarkj{ 378250574Smarkj char **p; 379250574Smarkj char *var; 380250574Smarkj int i; 381250574Smarkj 382250574Smarkj /* 383250574Smarkj * We can't effectively set environment variables from #pragma lines 384250574Smarkj * since the processes have already been spawned. 385250574Smarkj */ 386250574Smarkj if (dtp->dt_pcb != NULL) 387250574Smarkj return (dt_set_errno(dtp, EDT_BADOPTCTX)); 388250574Smarkj 389250574Smarkj if (arg == NULL) 390250574Smarkj return (dt_set_errno(dtp, EDT_BADOPTVAL)); 391250574Smarkj 392250574Smarkj if (!option && strchr(arg, '=') != NULL) 393250574Smarkj return (dt_set_errno(dtp, EDT_BADOPTVAL)); 394250574Smarkj 395250574Smarkj for (i = 1, p = dtp->dt_proc_env; *p != NULL; i++, p++) 396250574Smarkj continue; 397250574Smarkj 398250574Smarkj for (p = dtp->dt_proc_env; *p != NULL; p++) { 399250574Smarkj var = strchr(*p, '='); 400250574Smarkj if (var == NULL) 401250574Smarkj var = *p + strlen(*p); 402250574Smarkj if (strncmp(*p, arg, var - *p) == 0) { 403250574Smarkj dt_free(dtp, *p); 404250574Smarkj *p = dtp->dt_proc_env[i - 1]; 405250574Smarkj dtp->dt_proc_env[i - 1] = NULL; 406250574Smarkj i--; 407250574Smarkj } 408250574Smarkj } 409250574Smarkj 410250574Smarkj if (option) { 411250574Smarkj if ((var = strdup(arg)) == NULL) 412250574Smarkj return (dt_set_errno(dtp, EDT_NOMEM)); 413250574Smarkj 414250574Smarkj if ((p = dt_alloc(dtp, sizeof (char *) * (i + 1))) == NULL) { 415250574Smarkj dt_free(dtp, var); 416250574Smarkj return (dt_set_errno(dtp, EDT_NOMEM)); 417250574Smarkj } 418250574Smarkj 419250574Smarkj bcopy(dtp->dt_proc_env, p, sizeof (char *) * i); 420250574Smarkj dt_free(dtp, dtp->dt_proc_env); 421250574Smarkj dtp->dt_proc_env = p; 422250574Smarkj 423250574Smarkj dtp->dt_proc_env[i - 1] = var; 424250574Smarkj dtp->dt_proc_env[i] = NULL; 425250574Smarkj } 426250574Smarkj 427250574Smarkj return (0); 428250574Smarkj} 429250574Smarkj 430178479Sjb/*ARGSUSED*/ 431178479Sjbstatic int 432178479Sjbdt_opt_stdc(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 433178479Sjb{ 434178479Sjb if (arg == NULL) 435178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 436178479Sjb 437178479Sjb if (dtp->dt_pcb != NULL) 438178479Sjb return (dt_set_errno(dtp, EDT_BADOPTCTX)); 439178479Sjb 440178479Sjb if (strcmp(arg, "a") == 0) 441178479Sjb dtp->dt_stdcmode = DT_STDC_XA; 442178479Sjb else if (strcmp(arg, "c") == 0) 443178479Sjb dtp->dt_stdcmode = DT_STDC_XC; 444178479Sjb else if (strcmp(arg, "s") == 0) 445178479Sjb dtp->dt_stdcmode = DT_STDC_XS; 446178479Sjb else if (strcmp(arg, "t") == 0) 447178479Sjb dtp->dt_stdcmode = DT_STDC_XT; 448178479Sjb else 449178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 450178479Sjb 451178479Sjb return (0); 452178479Sjb} 453178479Sjb 454178479Sjb/*ARGSUSED*/ 455178479Sjbstatic int 456178479Sjbdt_opt_syslibdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 457178479Sjb{ 458178479Sjb dt_dirpath_t *dp = dt_list_next(&dtp->dt_lib_path); 459178479Sjb char *path; 460178479Sjb 461178479Sjb if (arg == NULL) 462178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 463178479Sjb 464178479Sjb if ((path = strdup(arg)) == NULL) 465178479Sjb return (dt_set_errno(dtp, EDT_NOMEM)); 466178479Sjb 467178479Sjb free(dp->dir_path); 468178479Sjb dp->dir_path = path; 469178479Sjb 470178479Sjb return (0); 471178479Sjb} 472178479Sjb 473178479Sjb/*ARGSUSED*/ 474178479Sjbstatic int 475178479Sjbdt_opt_tree(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 476178479Sjb{ 477178479Sjb int m; 478178479Sjb 479178479Sjb if (arg == NULL || (m = atoi(arg)) <= 0) 480178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 481178479Sjb 482178479Sjb dtp->dt_treedump = m; 483178479Sjb return (0); 484178479Sjb} 485178479Sjb 486178479Sjb/*ARGSUSED*/ 487178479Sjbstatic int 488178479Sjbdt_opt_tregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 489178479Sjb{ 490178479Sjb int n; 491178479Sjb 492178479Sjb if (arg == NULL || (n = atoi(arg)) <= 0) 493178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 494178479Sjb 495178479Sjb dtp->dt_conf.dtc_diftupregs = n; 496178479Sjb return (0); 497178479Sjb} 498178479Sjb 499178479Sjb/*ARGSUSED*/ 500178479Sjbstatic int 501178479Sjbdt_opt_xlate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 502178479Sjb{ 503178479Sjb if (arg == NULL) 504178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 505178479Sjb 506178479Sjb if (strcmp(arg, "dynamic") == 0) 507178479Sjb dtp->dt_xlatemode = DT_XL_DYNAMIC; 508178479Sjb else if (strcmp(arg, "static") == 0) 509178479Sjb dtp->dt_xlatemode = DT_XL_STATIC; 510178479Sjb else 511178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 512178479Sjb 513178479Sjb return (0); 514178479Sjb} 515178479Sjb 516178479Sjb/*ARGSUSED*/ 517178479Sjbstatic int 518178479Sjbdt_opt_cflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 519178479Sjb{ 520178479Sjb if (arg != NULL) 521178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 522178479Sjb 523178479Sjb if (dtp->dt_pcb != NULL) 524178479Sjb dtp->dt_pcb->pcb_cflags |= option; 525178479Sjb else 526178479Sjb dtp->dt_cflags |= option; 527178479Sjb 528178479Sjb return (0); 529178479Sjb} 530178479Sjb 531178479Sjbstatic int 532178479Sjbdt_opt_dflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 533178479Sjb{ 534178479Sjb if (arg != NULL) 535178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 536178479Sjb 537178479Sjb dtp->dt_dflags |= option; 538178479Sjb return (0); 539178479Sjb} 540178479Sjb 541178479Sjbstatic int 542178479Sjbdt_opt_invcflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 543178479Sjb{ 544178479Sjb if (arg != NULL) 545178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 546178479Sjb 547178479Sjb if (dtp->dt_pcb != NULL) 548178479Sjb dtp->dt_pcb->pcb_cflags &= ~option; 549178479Sjb else 550178479Sjb dtp->dt_cflags &= ~option; 551178479Sjb 552178479Sjb return (0); 553178479Sjb} 554178479Sjb 555178479Sjb/*ARGSUSED*/ 556178479Sjbstatic int 557178479Sjbdt_opt_version(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 558178479Sjb{ 559178479Sjb dt_version_t v; 560178479Sjb 561178479Sjb if (arg == NULL) 562178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 563178479Sjb 564178479Sjb if (dt_version_str2num(arg, &v) == -1) 565178479Sjb return (dt_set_errno(dtp, EDT_VERSINVAL)); 566178479Sjb 567178479Sjb if (!dt_version_defined(v)) 568178479Sjb return (dt_set_errno(dtp, EDT_VERSUNDEF)); 569178479Sjb 570178479Sjb return (dt_reduce(dtp, v)); 571178479Sjb} 572178479Sjb 573178479Sjbstatic int 574178479Sjbdt_opt_runtime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 575178479Sjb{ 576178479Sjb char *end; 577178479Sjb dtrace_optval_t val = 0; 578178479Sjb int i; 579178479Sjb 580178479Sjb const struct { 581178479Sjb char *positive; 582178479Sjb char *negative; 583178479Sjb } couples[] = { 584178479Sjb { "yes", "no" }, 585178479Sjb { "enable", "disable" }, 586178479Sjb { "enabled", "disabled" }, 587178479Sjb { "true", "false" }, 588178479Sjb { "on", "off" }, 589178479Sjb { "set", "unset" }, 590178479Sjb { NULL } 591178479Sjb }; 592178479Sjb 593178479Sjb if (arg != NULL) { 594178479Sjb if (arg[0] == '\0') { 595178479Sjb val = DTRACEOPT_UNSET; 596178479Sjb goto out; 597178479Sjb } 598178479Sjb 599178479Sjb for (i = 0; couples[i].positive != NULL; i++) { 600178479Sjb if (strcasecmp(couples[i].positive, arg) == 0) { 601178479Sjb val = 1; 602178479Sjb goto out; 603178479Sjb } 604178479Sjb 605178479Sjb if (strcasecmp(couples[i].negative, arg) == 0) { 606178479Sjb val = DTRACEOPT_UNSET; 607178479Sjb goto out; 608178479Sjb } 609178479Sjb } 610178479Sjb 611178479Sjb errno = 0; 612178479Sjb val = strtoull(arg, &end, 0); 613178479Sjb 614178479Sjb if (*end != '\0' || errno != 0 || val < 0) 615178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 616178479Sjb } 617178479Sjb 618178479Sjbout: 619178479Sjb dtp->dt_options[option] = val; 620178479Sjb return (0); 621178479Sjb} 622178479Sjb 623178479Sjbstatic int 624178479Sjbdt_optval_parse(const char *arg, dtrace_optval_t *rval) 625178479Sjb{ 626178479Sjb dtrace_optval_t mul = 1; 627178479Sjb size_t len; 628178479Sjb char *end; 629178479Sjb 630178479Sjb len = strlen(arg); 631178479Sjb errno = 0; 632178479Sjb 633178479Sjb switch (arg[len - 1]) { 634178479Sjb case 't': 635178479Sjb case 'T': 636178479Sjb mul *= 1024; 637178479Sjb /*FALLTHRU*/ 638178479Sjb case 'g': 639178479Sjb case 'G': 640178479Sjb mul *= 1024; 641178479Sjb /*FALLTHRU*/ 642178479Sjb case 'm': 643178479Sjb case 'M': 644178479Sjb mul *= 1024; 645178479Sjb /*FALLTHRU*/ 646178479Sjb case 'k': 647178479Sjb case 'K': 648178479Sjb mul *= 1024; 649178479Sjb /*FALLTHRU*/ 650178479Sjb default: 651178479Sjb break; 652178479Sjb } 653178479Sjb 654178479Sjb errno = 0; 655178479Sjb *rval = strtoull(arg, &end, 0) * mul; 656178479Sjb 657178479Sjb if ((mul > 1 && end != &arg[len - 1]) || (mul == 1 && *end != '\0') || 658178479Sjb *rval < 0 || errno != 0) 659178479Sjb return (-1); 660178479Sjb 661178479Sjb return (0); 662178479Sjb} 663178479Sjb 664178479Sjbstatic int 665178479Sjbdt_opt_size(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 666178479Sjb{ 667178479Sjb dtrace_optval_t val = 0; 668178479Sjb 669178479Sjb if (arg != NULL && dt_optval_parse(arg, &val) != 0) 670178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 671178479Sjb 672178479Sjb dtp->dt_options[option] = val; 673178479Sjb return (0); 674178479Sjb} 675178479Sjb 676178479Sjbstatic int 677178479Sjbdt_opt_rate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 678178479Sjb{ 679178479Sjb char *end; 680178479Sjb int i; 681178479Sjb dtrace_optval_t mul = 1, val = 0; 682178479Sjb 683178479Sjb const struct { 684178479Sjb char *name; 685178479Sjb hrtime_t mul; 686178479Sjb } suffix[] = { 687178479Sjb { "ns", NANOSEC / NANOSEC }, 688178479Sjb { "nsec", NANOSEC / NANOSEC }, 689178479Sjb { "us", NANOSEC / MICROSEC }, 690178479Sjb { "usec", NANOSEC / MICROSEC }, 691178479Sjb { "ms", NANOSEC / MILLISEC }, 692178479Sjb { "msec", NANOSEC / MILLISEC }, 693178479Sjb { "s", NANOSEC / SEC }, 694178479Sjb { "sec", NANOSEC / SEC }, 695178479Sjb { "m", NANOSEC * (hrtime_t)60 }, 696178479Sjb { "min", NANOSEC * (hrtime_t)60 }, 697178479Sjb { "h", NANOSEC * (hrtime_t)60 * (hrtime_t)60 }, 698178479Sjb { "hour", NANOSEC * (hrtime_t)60 * (hrtime_t)60 }, 699178479Sjb { "d", NANOSEC * (hrtime_t)(24 * 60 * 60) }, 700178479Sjb { "day", NANOSEC * (hrtime_t)(24 * 60 * 60) }, 701178479Sjb { "hz", 0 }, 702178479Sjb { NULL } 703178479Sjb }; 704178479Sjb 705178479Sjb if (arg != NULL) { 706178479Sjb errno = 0; 707178479Sjb val = strtoull(arg, &end, 0); 708178479Sjb 709178479Sjb for (i = 0; suffix[i].name != NULL; i++) { 710178479Sjb if (strcasecmp(suffix[i].name, end) == 0) { 711178479Sjb mul = suffix[i].mul; 712178479Sjb break; 713178479Sjb } 714178479Sjb } 715178479Sjb 716178479Sjb if (suffix[i].name == NULL && *end != '\0' || val < 0) 717178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 718178479Sjb 719178479Sjb if (mul == 0) { 720178479Sjb /* 721178479Sjb * The rate has been specified in frequency-per-second. 722178479Sjb */ 723178479Sjb if (val != 0) 724178479Sjb val = NANOSEC / val; 725178479Sjb } else { 726178479Sjb val *= mul; 727178479Sjb } 728178479Sjb } 729178479Sjb 730178479Sjb dtp->dt_options[option] = val; 731178479Sjb return (0); 732178479Sjb} 733178479Sjb 734178479Sjb/* 735178479Sjb * When setting the strsize option, set the option in the dt_options array 736178479Sjb * using dt_opt_size() as usual, and then update the definition of the CTF 737178479Sjb * type for the D intrinsic "string" to be an array of the corresponding size. 738178479Sjb * If any errors occur, reset dt_options[option] to its previous value. 739178479Sjb */ 740178479Sjbstatic int 741178479Sjbdt_opt_strsize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 742178479Sjb{ 743178479Sjb dtrace_optval_t val = dtp->dt_options[option]; 744178479Sjb ctf_file_t *fp = DT_STR_CTFP(dtp); 745178479Sjb ctf_id_t type = ctf_type_resolve(fp, DT_STR_TYPE(dtp)); 746178479Sjb ctf_arinfo_t r; 747178479Sjb 748178479Sjb if (dt_opt_size(dtp, arg, option) != 0) 749178479Sjb return (-1); /* dt_errno is set for us */ 750178479Sjb 751178479Sjb if (dtp->dt_options[option] > UINT_MAX) { 752178479Sjb dtp->dt_options[option] = val; 753178479Sjb return (dt_set_errno(dtp, EOVERFLOW)); 754178479Sjb } 755178479Sjb 756178479Sjb if (ctf_array_info(fp, type, &r) == CTF_ERR) { 757178479Sjb dtp->dt_options[option] = val; 758178479Sjb dtp->dt_ctferr = ctf_errno(fp); 759178479Sjb return (dt_set_errno(dtp, EDT_CTF)); 760178479Sjb } 761178479Sjb 762178479Sjb r.ctr_nelems = (uint_t)dtp->dt_options[option]; 763178479Sjb 764178479Sjb if (ctf_set_array(fp, type, &r) == CTF_ERR || 765178479Sjb ctf_update(fp) == CTF_ERR) { 766178479Sjb dtp->dt_options[option] = val; 767178479Sjb dtp->dt_ctferr = ctf_errno(fp); 768178479Sjb return (dt_set_errno(dtp, EDT_CTF)); 769178479Sjb } 770178479Sjb 771178479Sjb return (0); 772178479Sjb} 773178479Sjb 774178479Sjbstatic const struct { 775178479Sjb const char *dtbp_name; 776178479Sjb int dtbp_policy; 777178479Sjb} _dtrace_bufpolicies[] = { 778178479Sjb { "ring", DTRACEOPT_BUFPOLICY_RING }, 779178479Sjb { "fill", DTRACEOPT_BUFPOLICY_FILL }, 780178479Sjb { "switch", DTRACEOPT_BUFPOLICY_SWITCH }, 781178479Sjb { NULL, 0 } 782178479Sjb}; 783178479Sjb 784178479Sjb/*ARGSUSED*/ 785178479Sjbstatic int 786178479Sjbdt_opt_bufpolicy(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 787178479Sjb{ 788178479Sjb dtrace_optval_t policy = DTRACEOPT_UNSET; 789178479Sjb int i; 790178479Sjb 791178479Sjb if (arg == NULL) 792178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 793178479Sjb 794178479Sjb for (i = 0; _dtrace_bufpolicies[i].dtbp_name != NULL; i++) { 795178479Sjb if (strcmp(_dtrace_bufpolicies[i].dtbp_name, arg) == 0) { 796178479Sjb policy = _dtrace_bufpolicies[i].dtbp_policy; 797178479Sjb break; 798178479Sjb } 799178479Sjb } 800178479Sjb 801178479Sjb if (policy == DTRACEOPT_UNSET) 802178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 803178479Sjb 804178479Sjb dtp->dt_options[DTRACEOPT_BUFPOLICY] = policy; 805178479Sjb 806178479Sjb return (0); 807178479Sjb} 808178479Sjb 809178479Sjbstatic const struct { 810178479Sjb const char *dtbr_name; 811178479Sjb int dtbr_policy; 812178479Sjb} _dtrace_bufresize[] = { 813178479Sjb { "auto", DTRACEOPT_BUFRESIZE_AUTO }, 814178479Sjb { "manual", DTRACEOPT_BUFRESIZE_MANUAL }, 815178479Sjb { NULL, 0 } 816178479Sjb}; 817178479Sjb 818178479Sjb/*ARGSUSED*/ 819178479Sjbstatic int 820178479Sjbdt_opt_bufresize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 821178479Sjb{ 822178479Sjb dtrace_optval_t policy = DTRACEOPT_UNSET; 823178479Sjb int i; 824178479Sjb 825178479Sjb if (arg == NULL) 826178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 827178479Sjb 828178479Sjb for (i = 0; _dtrace_bufresize[i].dtbr_name != NULL; i++) { 829178479Sjb if (strcmp(_dtrace_bufresize[i].dtbr_name, arg) == 0) { 830178479Sjb policy = _dtrace_bufresize[i].dtbr_policy; 831178479Sjb break; 832178479Sjb } 833178479Sjb } 834178479Sjb 835178479Sjb if (policy == DTRACEOPT_UNSET) 836178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 837178479Sjb 838178479Sjb dtp->dt_options[DTRACEOPT_BUFRESIZE] = policy; 839178479Sjb 840178479Sjb return (0); 841178479Sjb} 842178479Sjb 843178479Sjbint 844178479Sjbdt_options_load(dtrace_hdl_t *dtp) 845178479Sjb{ 846178479Sjb dof_hdr_t hdr, *dof; 847178479Sjb dof_sec_t *sec; 848178479Sjb size_t offs; 849178479Sjb int i; 850178479Sjb 851178479Sjb /* 852178479Sjb * To load the option values, we need to ask the kernel to provide its 853178479Sjb * DOF, which we'll sift through to look for OPTDESC sections. 854178479Sjb */ 855178479Sjb bzero(&hdr, sizeof (dof_hdr_t)); 856178479Sjb hdr.dofh_loadsz = sizeof (dof_hdr_t); 857178479Sjb 858178569Sjb#if defined(sun) 859178479Sjb if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &hdr) == -1) 860178569Sjb#else 861178569Sjb dof = &hdr; 862178569Sjb if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &dof) == -1) 863178569Sjb#endif 864178479Sjb return (dt_set_errno(dtp, errno)); 865178479Sjb 866178479Sjb if (hdr.dofh_loadsz < sizeof (dof_hdr_t)) 867178479Sjb return (dt_set_errno(dtp, EINVAL)); 868178479Sjb 869178479Sjb dof = alloca(hdr.dofh_loadsz); 870178479Sjb bzero(dof, sizeof (dof_hdr_t)); 871178479Sjb dof->dofh_loadsz = hdr.dofh_loadsz; 872178479Sjb 873178479Sjb for (i = 0; i < DTRACEOPT_MAX; i++) 874178479Sjb dtp->dt_options[i] = DTRACEOPT_UNSET; 875178479Sjb 876178569Sjb#if defined(sun) 877178479Sjb if (dt_ioctl(dtp, DTRACEIOC_DOFGET, dof) == -1) 878178569Sjb#else 879178569Sjb if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &dof) == -1) 880178569Sjb#endif 881178479Sjb return (dt_set_errno(dtp, errno)); 882178479Sjb 883178479Sjb for (i = 0; i < dof->dofh_secnum; i++) { 884178479Sjb sec = (dof_sec_t *)(uintptr_t)((uintptr_t)dof + 885178479Sjb dof->dofh_secoff + i * dof->dofh_secsize); 886178479Sjb 887178479Sjb if (sec->dofs_type != DOF_SECT_OPTDESC) 888178479Sjb continue; 889178479Sjb 890178479Sjb break; 891178479Sjb } 892178479Sjb 893178479Sjb for (offs = 0; offs < sec->dofs_size; offs += sec->dofs_entsize) { 894178479Sjb dof_optdesc_t *opt = (dof_optdesc_t *)(uintptr_t) 895178479Sjb ((uintptr_t)dof + sec->dofs_offset + offs); 896178479Sjb 897178479Sjb if (opt->dofo_strtab != DOF_SECIDX_NONE) 898178479Sjb continue; 899178479Sjb 900178479Sjb if (opt->dofo_option >= DTRACEOPT_MAX) 901178479Sjb continue; 902178479Sjb 903178479Sjb dtp->dt_options[opt->dofo_option] = opt->dofo_value; 904178479Sjb } 905178479Sjb 906178479Sjb return (0); 907178479Sjb} 908178479Sjb 909178479Sjb/*ARGSUSED*/ 910178479Sjbstatic int 911178479Sjbdt_opt_preallocate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 912178479Sjb{ 913178479Sjb dtrace_optval_t size; 914178479Sjb void *p; 915178479Sjb 916178479Sjb if (arg == NULL || dt_optval_parse(arg, &size) != 0) 917178479Sjb return (dt_set_errno(dtp, EDT_BADOPTVAL)); 918178479Sjb 919178479Sjb if (size > SIZE_MAX) 920178479Sjb size = SIZE_MAX; 921178479Sjb 922178479Sjb if ((p = dt_zalloc(dtp, size)) == NULL) { 923178479Sjb do { 924178479Sjb size /= 2; 925178479Sjb } while ((p = dt_zalloc(dtp, size)) == NULL); 926178479Sjb } 927178479Sjb 928178479Sjb dt_free(dtp, p); 929178479Sjb 930178479Sjb return (0); 931178479Sjb} 932178479Sjb 933178479Sjbtypedef struct dt_option { 934178479Sjb const char *o_name; 935178479Sjb int (*o_func)(dtrace_hdl_t *, const char *, uintptr_t); 936178479Sjb uintptr_t o_option; 937178479Sjb} dt_option_t; 938178479Sjb 939178479Sjb/* 940178479Sjb * Compile-time options. 941178479Sjb */ 942178479Sjbstatic const dt_option_t _dtrace_ctoptions[] = { 943178479Sjb { "aggpercpu", dt_opt_agg, DTRACE_A_PERCPU }, 944178479Sjb { "amin", dt_opt_amin }, 945178479Sjb { "argref", dt_opt_cflags, DTRACE_C_ARGREF }, 946178479Sjb { "core", dt_opt_core }, 947178479Sjb { "cpp", dt_opt_cflags, DTRACE_C_CPP }, 948178479Sjb { "cpphdrs", dt_opt_cpp_hdrs }, 949178479Sjb { "cpppath", dt_opt_cpp_path }, 950178479Sjb { "ctypes", dt_opt_ctypes }, 951178479Sjb { "defaultargs", dt_opt_cflags, DTRACE_C_DEFARG }, 952178479Sjb { "dtypes", dt_opt_dtypes }, 953178479Sjb { "debug", dt_opt_debug }, 954178479Sjb { "define", dt_opt_cpp_opts, (uintptr_t)"-D" }, 955178479Sjb { "droptags", dt_opt_droptags }, 956178479Sjb { "empty", dt_opt_cflags, DTRACE_C_EMPTY }, 957178479Sjb { "errtags", dt_opt_cflags, DTRACE_C_ETAGS }, 958178479Sjb { "evaltime", dt_opt_evaltime }, 959178479Sjb { "incdir", dt_opt_cpp_opts, (uintptr_t)"-I" }, 960178479Sjb { "iregs", dt_opt_iregs }, 961178479Sjb { "kdefs", dt_opt_invcflags, DTRACE_C_KNODEF }, 962178479Sjb { "knodefs", dt_opt_cflags, DTRACE_C_KNODEF }, 963178479Sjb { "late", dt_opt_xlate }, 964178479Sjb { "lazyload", dt_opt_lazyload }, 965178479Sjb { "ldpath", dt_opt_ld_path }, 966178479Sjb { "libdir", dt_opt_libdir }, 967178479Sjb { "linkmode", dt_opt_linkmode }, 968178479Sjb { "linktype", dt_opt_linktype }, 969178479Sjb { "nolibs", dt_opt_cflags, DTRACE_C_NOLIBS }, 970178479Sjb { "pgmax", dt_opt_pgmax }, 971178479Sjb { "preallocate", dt_opt_preallocate }, 972178479Sjb { "pspec", dt_opt_cflags, DTRACE_C_PSPEC }, 973250574Smarkj { "setenv", dt_opt_setenv, 1 }, 974178479Sjb { "stdc", dt_opt_stdc }, 975178479Sjb { "strip", dt_opt_dflags, DTRACE_D_STRIP }, 976178479Sjb { "syslibdir", dt_opt_syslibdir }, 977178479Sjb { "tree", dt_opt_tree }, 978178479Sjb { "tregs", dt_opt_tregs }, 979178479Sjb { "udefs", dt_opt_invcflags, DTRACE_C_UNODEF }, 980178479Sjb { "undef", dt_opt_cpp_opts, (uintptr_t)"-U" }, 981178479Sjb { "unodefs", dt_opt_cflags, DTRACE_C_UNODEF }, 982250574Smarkj { "unsetenv", dt_opt_setenv, 0 }, 983178479Sjb { "verbose", dt_opt_cflags, DTRACE_C_DIFV }, 984178479Sjb { "version", dt_opt_version }, 985178479Sjb { "zdefs", dt_opt_cflags, DTRACE_C_ZDEFS }, 986178569Sjb { NULL, NULL, 0 } 987178479Sjb}; 988178479Sjb 989178479Sjb/* 990178479Sjb * Run-time options. 991178479Sjb */ 992178479Sjbstatic const dt_option_t _dtrace_rtoptions[] = { 993178479Sjb { "aggsize", dt_opt_size, DTRACEOPT_AGGSIZE }, 994178479Sjb { "bufsize", dt_opt_size, DTRACEOPT_BUFSIZE }, 995178479Sjb { "bufpolicy", dt_opt_bufpolicy, DTRACEOPT_BUFPOLICY }, 996178479Sjb { "bufresize", dt_opt_bufresize, DTRACEOPT_BUFRESIZE }, 997178479Sjb { "cleanrate", dt_opt_rate, DTRACEOPT_CLEANRATE }, 998178479Sjb { "cpu", dt_opt_runtime, DTRACEOPT_CPU }, 999178479Sjb { "destructive", dt_opt_runtime, DTRACEOPT_DESTRUCTIVE }, 1000178479Sjb { "dynvarsize", dt_opt_size, DTRACEOPT_DYNVARSIZE }, 1001178479Sjb { "grabanon", dt_opt_runtime, DTRACEOPT_GRABANON }, 1002178479Sjb { "jstackframes", dt_opt_runtime, DTRACEOPT_JSTACKFRAMES }, 1003178479Sjb { "jstackstrsize", dt_opt_size, DTRACEOPT_JSTACKSTRSIZE }, 1004178479Sjb { "nspec", dt_opt_runtime, DTRACEOPT_NSPEC }, 1005178479Sjb { "specsize", dt_opt_size, DTRACEOPT_SPECSIZE }, 1006178479Sjb { "stackframes", dt_opt_runtime, DTRACEOPT_STACKFRAMES }, 1007178479Sjb { "statusrate", dt_opt_rate, DTRACEOPT_STATUSRATE }, 1008178479Sjb { "strsize", dt_opt_strsize, DTRACEOPT_STRSIZE }, 1009178479Sjb { "ustackframes", dt_opt_runtime, DTRACEOPT_USTACKFRAMES }, 1010250574Smarkj { "temporal", dt_opt_runtime, DTRACEOPT_TEMPORAL }, 1011178569Sjb { NULL, NULL, 0 } 1012178479Sjb}; 1013178479Sjb 1014178479Sjb/* 1015178479Sjb * Dynamic run-time options. 1016178479Sjb */ 1017178479Sjbstatic const dt_option_t _dtrace_drtoptions[] = { 1018178479Sjb { "aggrate", dt_opt_rate, DTRACEOPT_AGGRATE }, 1019178479Sjb { "aggsortkey", dt_opt_runtime, DTRACEOPT_AGGSORTKEY }, 1020178479Sjb { "aggsortkeypos", dt_opt_runtime, DTRACEOPT_AGGSORTKEYPOS }, 1021178479Sjb { "aggsortpos", dt_opt_runtime, DTRACEOPT_AGGSORTPOS }, 1022178479Sjb { "aggsortrev", dt_opt_runtime, DTRACEOPT_AGGSORTREV }, 1023178479Sjb { "flowindent", dt_opt_runtime, DTRACEOPT_FLOWINDENT }, 1024178479Sjb { "quiet", dt_opt_runtime, DTRACEOPT_QUIET }, 1025178479Sjb { "rawbytes", dt_opt_runtime, DTRACEOPT_RAWBYTES }, 1026178479Sjb { "stackindent", dt_opt_runtime, DTRACEOPT_STACKINDENT }, 1027178479Sjb { "switchrate", dt_opt_rate, DTRACEOPT_SWITCHRATE }, 1028178569Sjb { NULL, NULL, 0 } 1029178479Sjb}; 1030178479Sjb 1031178479Sjbint 1032178479Sjbdtrace_getopt(dtrace_hdl_t *dtp, const char *opt, dtrace_optval_t *val) 1033178479Sjb{ 1034178479Sjb const dt_option_t *op; 1035178479Sjb 1036178479Sjb if (opt == NULL) 1037178479Sjb return (dt_set_errno(dtp, EINVAL)); 1038178479Sjb 1039178479Sjb /* 1040178479Sjb * We only need to search the run-time options -- it's not legal 1041178479Sjb * to get the values of compile-time options. 1042178479Sjb */ 1043178479Sjb for (op = _dtrace_rtoptions; op->o_name != NULL; op++) { 1044178479Sjb if (strcmp(op->o_name, opt) == 0) { 1045178479Sjb *val = dtp->dt_options[op->o_option]; 1046178479Sjb return (0); 1047178479Sjb } 1048178479Sjb } 1049178479Sjb 1050178479Sjb for (op = _dtrace_drtoptions; op->o_name != NULL; op++) { 1051178479Sjb if (strcmp(op->o_name, opt) == 0) { 1052178479Sjb *val = dtp->dt_options[op->o_option]; 1053178479Sjb return (0); 1054178479Sjb } 1055178479Sjb } 1056178479Sjb 1057178479Sjb return (dt_set_errno(dtp, EDT_BADOPTNAME)); 1058178479Sjb} 1059178479Sjb 1060178479Sjbint 1061178479Sjbdtrace_setopt(dtrace_hdl_t *dtp, const char *opt, const char *val) 1062178479Sjb{ 1063178479Sjb const dt_option_t *op; 1064178479Sjb 1065178479Sjb if (opt == NULL) 1066178479Sjb return (dt_set_errno(dtp, EINVAL)); 1067178479Sjb 1068178479Sjb for (op = _dtrace_ctoptions; op->o_name != NULL; op++) { 1069178479Sjb if (strcmp(op->o_name, opt) == 0) 1070178479Sjb return (op->o_func(dtp, val, op->o_option)); 1071178479Sjb } 1072178479Sjb 1073178479Sjb for (op = _dtrace_drtoptions; op->o_name != NULL; op++) { 1074178479Sjb if (strcmp(op->o_name, opt) == 0) 1075178479Sjb return (op->o_func(dtp, val, op->o_option)); 1076178479Sjb } 1077178479Sjb 1078178479Sjb for (op = _dtrace_rtoptions; op->o_name != NULL; op++) { 1079178479Sjb if (strcmp(op->o_name, opt) == 0) { 1080178479Sjb /* 1081178479Sjb * Only dynamic run-time options may be set while 1082178479Sjb * tracing is active. 1083178479Sjb */ 1084178479Sjb if (dtp->dt_active) 1085178479Sjb return (dt_set_errno(dtp, EDT_ACTIVE)); 1086178479Sjb 1087178479Sjb return (op->o_func(dtp, val, op->o_option)); 1088178479Sjb } 1089178479Sjb } 1090178479Sjb 1091178479Sjb return (dt_set_errno(dtp, EDT_BADOPTNAME)); 1092178479Sjb} 1093