1 1.1 darran /* 2 1.1 darran * CDDL HEADER START 3 1.1 darran * 4 1.1 darran * The contents of this file are subject to the terms of the 5 1.1 darran * Common Development and Distribution License (the "License"). 6 1.1 darran * You may not use this file except in compliance with the License. 7 1.1 darran * 8 1.1 darran * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 1.1 darran * or http://www.opensolaris.org/os/licensing. 10 1.1 darran * See the License for the specific language governing permissions 11 1.1 darran * and limitations under the License. 12 1.1 darran * 13 1.1 darran * When distributing Covered Code, include this CDDL HEADER in each 14 1.1 darran * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 1.1 darran * If applicable, add the following below this CDDL HEADER, with the 16 1.1 darran * fields enclosed by brackets "[]" replaced with your own identifying 17 1.1 darran * information: Portions Copyright [yyyy] [name of copyright owner] 18 1.1 darran * 19 1.1 darran * CDDL HEADER END 20 1.1 darran */ 21 1.1 darran 22 1.1 darran /* 23 1.1 darran * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 1.1 darran * Use is subject to license terms. 25 1.1 darran */ 26 1.1 darran 27 1.7 christos /* 28 1.7 christos * Copyright (c) 2013, Joyent, Inc. All rights reserved. 29 1.7 christos * Copyright (c) 2012 by Delphix. All rights reserved. 30 1.7 christos */ 31 1.1 darran 32 1.1 darran #include <sys/resource.h> 33 1.1 darran #include <sys/mman.h> 34 1.1 darran #include <sys/types.h> 35 1.1 darran 36 1.1 darran #include <strings.h> 37 1.1 darran #include <signal.h> 38 1.1 darran #include <stdlib.h> 39 1.1 darran #include <unistd.h> 40 1.1 darran #include <limits.h> 41 1.7 christos #ifdef illumos 42 1.1 darran #include <alloca.h> 43 1.2 darran #endif 44 1.1 darran #include <errno.h> 45 1.1 darran #include <fcntl.h> 46 1.1 darran 47 1.1 darran #include <dt_impl.h> 48 1.1 darran #include <dt_string.h> 49 1.1 darran 50 1.1 darran static int 51 1.1 darran dt_opt_agg(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 52 1.1 darran { 53 1.1 darran dt_aggregate_t *agp = &dtp->dt_aggregate; 54 1.1 darran 55 1.1 darran if (arg != NULL) 56 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 57 1.1 darran 58 1.1 darran agp->dtat_flags |= option; 59 1.1 darran return (0); 60 1.1 darran } 61 1.1 darran 62 1.1 darran /*ARGSUSED*/ 63 1.1 darran static int 64 1.1 darran dt_opt_amin(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 65 1.1 darran { 66 1.1 darran char str[DTRACE_ATTR2STR_MAX]; 67 1.1 darran dtrace_attribute_t attr; 68 1.1 darran 69 1.1 darran if (arg == NULL || dtrace_str2attr(arg, &attr) == -1) 70 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 71 1.1 darran 72 1.1 darran dt_dprintf("set compiler attribute minimum to %s\n", 73 1.1 darran dtrace_attr2str(attr, str, sizeof (str))); 74 1.1 darran 75 1.1 darran if (dtp->dt_pcb != NULL) { 76 1.1 darran dtp->dt_pcb->pcb_cflags |= DTRACE_C_EATTR; 77 1.1 darran dtp->dt_pcb->pcb_amin = attr; 78 1.1 darran } else { 79 1.1 darran dtp->dt_cflags |= DTRACE_C_EATTR; 80 1.1 darran dtp->dt_amin = attr; 81 1.1 darran } 82 1.1 darran 83 1.1 darran return (0); 84 1.1 darran } 85 1.1 darran 86 1.1 darran static void 87 1.1 darran dt_coredump(void) 88 1.1 darran { 89 1.1 darran const char msg[] = "libdtrace DEBUG: [ forcing coredump ]\n"; 90 1.1 darran 91 1.1 darran struct sigaction act; 92 1.1 darran struct rlimit lim; 93 1.1 darran 94 1.1 darran (void) write(STDERR_FILENO, msg, sizeof (msg) - 1); 95 1.1 darran 96 1.1 darran act.sa_handler = SIG_DFL; 97 1.1 darran act.sa_flags = 0; 98 1.1 darran 99 1.1 darran (void) sigemptyset(&act.sa_mask); 100 1.1 darran (void) sigaction(SIGABRT, &act, NULL); 101 1.1 darran 102 1.1 darran lim.rlim_cur = RLIM_INFINITY; 103 1.1 darran lim.rlim_max = RLIM_INFINITY; 104 1.1 darran 105 1.1 darran (void) setrlimit(RLIMIT_CORE, &lim); 106 1.1 darran abort(); 107 1.1 darran } 108 1.1 darran 109 1.1 darran /*ARGSUSED*/ 110 1.1 darran static int 111 1.1 darran dt_opt_core(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 112 1.1 darran { 113 1.1 darran static int enabled = 0; 114 1.1 darran 115 1.1 darran if (arg != NULL) 116 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 117 1.1 darran 118 1.1 darran if (enabled++ || atexit(dt_coredump) == 0) 119 1.1 darran return (0); 120 1.1 darran 121 1.1 darran return (dt_set_errno(dtp, errno)); 122 1.1 darran } 123 1.1 darran 124 1.1 darran /*ARGSUSED*/ 125 1.1 darran static int 126 1.1 darran dt_opt_cpp_hdrs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 127 1.1 darran { 128 1.1 darran if (arg != NULL) 129 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 130 1.1 darran 131 1.1 darran if (dtp->dt_pcb != NULL) 132 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTCTX)); 133 1.1 darran 134 1.1 darran if (dt_cpp_add_arg(dtp, "-H") == NULL) 135 1.1 darran return (dt_set_errno(dtp, EDT_NOMEM)); 136 1.1 darran 137 1.1 darran return (0); 138 1.1 darran } 139 1.1 darran 140 1.1 darran /*ARGSUSED*/ 141 1.1 darran static int 142 1.1 darran dt_opt_cpp_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 143 1.1 darran { 144 1.1 darran char *cpp; 145 1.1 darran 146 1.1 darran if (arg == NULL) 147 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 148 1.1 darran 149 1.1 darran if (dtp->dt_pcb != NULL) 150 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTCTX)); 151 1.1 darran 152 1.1 darran if ((cpp = strdup(arg)) == NULL) 153 1.1 darran return (dt_set_errno(dtp, EDT_NOMEM)); 154 1.1 darran 155 1.1 darran dtp->dt_cpp_argv[0] = (char *)strbasename(cpp); 156 1.1 darran free(dtp->dt_cpp_path); 157 1.1 darran dtp->dt_cpp_path = cpp; 158 1.1 darran 159 1.1 darran return (0); 160 1.1 darran } 161 1.1 darran 162 1.1 darran static int 163 1.1 darran dt_opt_cpp_opts(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 164 1.1 darran { 165 1.1 darran char *buf; 166 1.1 darran size_t len; 167 1.1 darran const char *opt = (const char *)option; 168 1.1 darran 169 1.1 darran if (opt == NULL || arg == NULL) 170 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 171 1.1 darran 172 1.1 darran if (dtp->dt_pcb != NULL) 173 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTCTX)); 174 1.1 darran 175 1.1 darran len = strlen(opt) + strlen(arg) + 1; 176 1.1 darran buf = alloca(len); 177 1.1 darran 178 1.1 darran (void) strcpy(buf, opt); 179 1.1 darran (void) strcat(buf, arg); 180 1.1 darran 181 1.1 darran if (dt_cpp_add_arg(dtp, buf) == NULL) 182 1.1 darran return (dt_set_errno(dtp, EDT_NOMEM)); 183 1.1 darran 184 1.1 darran return (0); 185 1.1 darran } 186 1.1 darran 187 1.1 darran /*ARGSUSED*/ 188 1.1 darran static int 189 1.1 darran dt_opt_ctypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 190 1.1 darran { 191 1.1 darran int fd; 192 1.1 darran 193 1.1 darran if (arg == NULL) 194 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 195 1.1 darran 196 1.1 darran if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1) 197 1.1 darran return (dt_set_errno(dtp, errno)); 198 1.1 darran 199 1.1 darran (void) close(dtp->dt_cdefs_fd); 200 1.1 darran dtp->dt_cdefs_fd = fd; 201 1.1 darran return (0); 202 1.1 darran } 203 1.1 darran 204 1.1 darran /*ARGSUSED*/ 205 1.1 darran static int 206 1.1 darran dt_opt_droptags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 207 1.1 darran { 208 1.1 darran dtp->dt_droptags = 1; 209 1.1 darran return (0); 210 1.1 darran } 211 1.1 darran 212 1.1 darran /*ARGSUSED*/ 213 1.1 darran static int 214 1.1 darran dt_opt_dtypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 215 1.1 darran { 216 1.1 darran int fd; 217 1.1 darran 218 1.1 darran if (arg == NULL) 219 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 220 1.1 darran 221 1.1 darran if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1) 222 1.1 darran return (dt_set_errno(dtp, errno)); 223 1.1 darran 224 1.1 darran (void) close(dtp->dt_ddefs_fd); 225 1.1 darran dtp->dt_ddefs_fd = fd; 226 1.1 darran return (0); 227 1.1 darran } 228 1.1 darran 229 1.1 darran /*ARGSUSED*/ 230 1.1 darran static int 231 1.1 darran dt_opt_debug(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 232 1.1 darran { 233 1.1 darran if (arg != NULL) 234 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 235 1.1 darran 236 1.1 darran _dtrace_debug = 1; 237 1.1 darran return (0); 238 1.1 darran } 239 1.1 darran 240 1.1 darran /*ARGSUSED*/ 241 1.1 darran static int 242 1.1 darran dt_opt_iregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 243 1.1 darran { 244 1.1 darran int n; 245 1.1 darran 246 1.1 darran if (arg == NULL || (n = atoi(arg)) <= 0) 247 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 248 1.1 darran 249 1.1 darran dtp->dt_conf.dtc_difintregs = n; 250 1.1 darran return (0); 251 1.1 darran } 252 1.1 darran 253 1.1 darran /*ARGSUSED*/ 254 1.1 darran static int 255 1.1 darran dt_opt_lazyload(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 256 1.1 darran { 257 1.1 darran dtp->dt_lazyload = 1; 258 1.1 darran 259 1.1 darran return (0); 260 1.1 darran } 261 1.1 darran 262 1.1 darran /*ARGSUSED*/ 263 1.1 darran static int 264 1.1 darran dt_opt_ld_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 265 1.1 darran { 266 1.1 darran char *ld; 267 1.1 darran 268 1.1 darran if (arg == NULL) 269 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 270 1.1 darran 271 1.1 darran if (dtp->dt_pcb != NULL) 272 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTCTX)); 273 1.1 darran 274 1.1 darran if ((ld = strdup(arg)) == NULL) 275 1.1 darran return (dt_set_errno(dtp, EDT_NOMEM)); 276 1.1 darran 277 1.1 darran free(dtp->dt_ld_path); 278 1.1 darran dtp->dt_ld_path = ld; 279 1.1 darran 280 1.1 darran return (0); 281 1.1 darran } 282 1.1 darran 283 1.7 christos #if defined(__FreeBSD__) || defined(__NetBSD__) 284 1.7 christos static int 285 1.7 christos dt_opt_objcopy_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 286 1.7 christos { 287 1.7 christos char *objcopy; 288 1.7 christos 289 1.7 christos if (arg == NULL) 290 1.7 christos return (dt_set_errno(dtp, EDT_BADOPTVAL)); 291 1.7 christos 292 1.7 christos if (dtp->dt_pcb != NULL) 293 1.7 christos return (dt_set_errno(dtp, EDT_BADOPTCTX)); 294 1.7 christos 295 1.7 christos if ((objcopy = strdup(arg)) == NULL) 296 1.7 christos return (dt_set_errno(dtp, EDT_NOMEM)); 297 1.7 christos 298 1.7 christos free(dtp->dt_objcopy_path); 299 1.7 christos dtp->dt_objcopy_path = objcopy; 300 1.7 christos 301 1.7 christos return (0); 302 1.7 christos } 303 1.7 christos #endif 304 1.7 christos 305 1.1 darran /*ARGSUSED*/ 306 1.1 darran static int 307 1.1 darran dt_opt_libdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 308 1.1 darran { 309 1.1 darran dt_dirpath_t *dp; 310 1.1 darran 311 1.1 darran if (arg == NULL) 312 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 313 1.1 darran 314 1.1 darran if ((dp = malloc(sizeof (dt_dirpath_t))) == NULL || 315 1.1 darran (dp->dir_path = strdup(arg)) == NULL) { 316 1.1 darran free(dp); 317 1.1 darran return (dt_set_errno(dtp, EDT_NOMEM)); 318 1.1 darran } 319 1.1 darran 320 1.1 darran dt_list_append(&dtp->dt_lib_path, dp); 321 1.1 darran return (0); 322 1.1 darran } 323 1.1 darran 324 1.1 darran /*ARGSUSED*/ 325 1.1 darran static int 326 1.1 darran dt_opt_linkmode(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 327 1.1 darran { 328 1.1 darran if (arg == NULL) 329 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 330 1.1 darran 331 1.1 darran if (strcmp(arg, "kernel") == 0) 332 1.1 darran dtp->dt_linkmode = DT_LINK_KERNEL; 333 1.1 darran else if (strcmp(arg, "primary") == 0) 334 1.1 darran dtp->dt_linkmode = DT_LINK_PRIMARY; 335 1.1 darran else if (strcmp(arg, "dynamic") == 0) 336 1.1 darran dtp->dt_linkmode = DT_LINK_DYNAMIC; 337 1.1 darran else if (strcmp(arg, "static") == 0) 338 1.1 darran dtp->dt_linkmode = DT_LINK_STATIC; 339 1.1 darran else 340 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 341 1.1 darran 342 1.1 darran return (0); 343 1.1 darran } 344 1.1 darran 345 1.1 darran /*ARGSUSED*/ 346 1.1 darran static int 347 1.1 darran dt_opt_linktype(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 348 1.1 darran { 349 1.1 darran if (arg == NULL) 350 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 351 1.1 darran 352 1.1 darran if (strcasecmp(arg, "elf") == 0) 353 1.1 darran dtp->dt_linktype = DT_LTYP_ELF; 354 1.1 darran else if (strcasecmp(arg, "dof") == 0) 355 1.1 darran dtp->dt_linktype = DT_LTYP_DOF; 356 1.1 darran else 357 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 358 1.1 darran 359 1.1 darran return (0); 360 1.1 darran } 361 1.1 darran 362 1.1 darran /*ARGSUSED*/ 363 1.1 darran static int 364 1.7 christos dt_opt_encoding(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 365 1.7 christos { 366 1.7 christos if (arg == NULL) 367 1.7 christos return (dt_set_errno(dtp, EDT_BADOPTVAL)); 368 1.7 christos 369 1.7 christos if (strcmp(arg, "ascii") == 0) 370 1.7 christos dtp->dt_encoding = DT_ENCODING_ASCII; 371 1.7 christos else if (strcmp(arg, "utf8") == 0) 372 1.7 christos dtp->dt_encoding = DT_ENCODING_UTF8; 373 1.7 christos else 374 1.7 christos return (dt_set_errno(dtp, EDT_BADOPTVAL)); 375 1.7 christos 376 1.7 christos return (0); 377 1.7 christos } 378 1.7 christos 379 1.7 christos /*ARGSUSED*/ 380 1.7 christos static int 381 1.1 darran dt_opt_evaltime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 382 1.1 darran { 383 1.1 darran if (arg == NULL) 384 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 385 1.1 darran 386 1.1 darran if (strcmp(arg, "exec") == 0) 387 1.1 darran dtp->dt_prcmode = DT_PROC_STOP_CREATE; 388 1.1 darran else if (strcmp(arg, "preinit") == 0) 389 1.1 darran dtp->dt_prcmode = DT_PROC_STOP_PREINIT; 390 1.1 darran else if (strcmp(arg, "postinit") == 0) 391 1.1 darran dtp->dt_prcmode = DT_PROC_STOP_POSTINIT; 392 1.1 darran else if (strcmp(arg, "main") == 0) 393 1.1 darran dtp->dt_prcmode = DT_PROC_STOP_MAIN; 394 1.1 darran else 395 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 396 1.1 darran 397 1.1 darran return (0); 398 1.1 darran } 399 1.1 darran 400 1.1 darran /*ARGSUSED*/ 401 1.1 darran static int 402 1.1 darran dt_opt_pgmax(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 403 1.1 darran { 404 1.1 darran int n; 405 1.1 darran 406 1.1 darran if (arg == NULL || (n = atoi(arg)) < 0) 407 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 408 1.1 darran 409 1.1 darran dtp->dt_procs->dph_lrulim = n; 410 1.1 darran return (0); 411 1.1 darran } 412 1.1 darran 413 1.7 christos static int 414 1.7 christos dt_opt_setenv(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 415 1.7 christos { 416 1.7 christos char **p; 417 1.7 christos char *var; 418 1.7 christos int i; 419 1.7 christos 420 1.7 christos /* 421 1.7 christos * We can't effectively set environment variables from #pragma lines 422 1.7 christos * since the processes have already been spawned. 423 1.7 christos */ 424 1.7 christos if (dtp->dt_pcb != NULL) 425 1.7 christos return (dt_set_errno(dtp, EDT_BADOPTCTX)); 426 1.7 christos 427 1.7 christos if (arg == NULL) 428 1.7 christos return (dt_set_errno(dtp, EDT_BADOPTVAL)); 429 1.7 christos 430 1.7 christos if (!option && strchr(arg, '=') != NULL) 431 1.7 christos return (dt_set_errno(dtp, EDT_BADOPTVAL)); 432 1.7 christos 433 1.7 christos for (i = 1, p = dtp->dt_proc_env; *p != NULL; i++, p++) 434 1.7 christos continue; 435 1.7 christos 436 1.7 christos for (p = dtp->dt_proc_env; *p != NULL; p++) { 437 1.7 christos var = strchr(*p, '='); 438 1.7 christos if (var == NULL) 439 1.7 christos var = *p + strlen(*p); 440 1.7 christos if (strncmp(*p, arg, var - *p) == 0) { 441 1.7 christos dt_free(dtp, *p); 442 1.7 christos *p = dtp->dt_proc_env[i - 1]; 443 1.7 christos dtp->dt_proc_env[i - 1] = NULL; 444 1.7 christos i--; 445 1.7 christos } 446 1.7 christos } 447 1.7 christos 448 1.7 christos if (option) { 449 1.7 christos if ((var = strdup(arg)) == NULL) 450 1.7 christos return (dt_set_errno(dtp, EDT_NOMEM)); 451 1.7 christos 452 1.7 christos if ((p = dt_alloc(dtp, sizeof (char *) * (i + 1))) == NULL) { 453 1.7 christos dt_free(dtp, var); 454 1.7 christos return (dt_set_errno(dtp, EDT_NOMEM)); 455 1.7 christos } 456 1.7 christos 457 1.7 christos bcopy(dtp->dt_proc_env, p, sizeof (char *) * i); 458 1.7 christos dt_free(dtp, dtp->dt_proc_env); 459 1.7 christos dtp->dt_proc_env = p; 460 1.7 christos 461 1.7 christos dtp->dt_proc_env[i - 1] = var; 462 1.7 christos dtp->dt_proc_env[i] = NULL; 463 1.7 christos } 464 1.7 christos 465 1.7 christos return (0); 466 1.7 christos } 467 1.7 christos 468 1.1 darran /*ARGSUSED*/ 469 1.1 darran static int 470 1.1 darran dt_opt_stdc(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 471 1.1 darran { 472 1.1 darran if (arg == NULL) 473 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 474 1.1 darran 475 1.1 darran if (dtp->dt_pcb != NULL) 476 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTCTX)); 477 1.1 darran 478 1.1 darran if (strcmp(arg, "a") == 0) 479 1.1 darran dtp->dt_stdcmode = DT_STDC_XA; 480 1.1 darran else if (strcmp(arg, "c") == 0) 481 1.1 darran dtp->dt_stdcmode = DT_STDC_XC; 482 1.1 darran else if (strcmp(arg, "s") == 0) 483 1.1 darran dtp->dt_stdcmode = DT_STDC_XS; 484 1.1 darran else if (strcmp(arg, "t") == 0) 485 1.1 darran dtp->dt_stdcmode = DT_STDC_XT; 486 1.1 darran else 487 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 488 1.1 darran 489 1.1 darran return (0); 490 1.1 darran } 491 1.1 darran 492 1.1 darran /*ARGSUSED*/ 493 1.1 darran static int 494 1.1 darran dt_opt_syslibdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 495 1.1 darran { 496 1.1 darran dt_dirpath_t *dp = dt_list_next(&dtp->dt_lib_path); 497 1.1 darran char *path; 498 1.1 darran 499 1.1 darran if (arg == NULL) 500 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 501 1.1 darran 502 1.1 darran if ((path = strdup(arg)) == NULL) 503 1.1 darran return (dt_set_errno(dtp, EDT_NOMEM)); 504 1.1 darran 505 1.1 darran free(dp->dir_path); 506 1.1 darran dp->dir_path = path; 507 1.1 darran 508 1.1 darran return (0); 509 1.1 darran } 510 1.1 darran 511 1.1 darran /*ARGSUSED*/ 512 1.1 darran static int 513 1.1 darran dt_opt_tree(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 514 1.1 darran { 515 1.1 darran int m; 516 1.1 darran 517 1.1 darran if (arg == NULL || (m = atoi(arg)) <= 0) 518 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 519 1.1 darran 520 1.1 darran dtp->dt_treedump = m; 521 1.1 darran return (0); 522 1.1 darran } 523 1.1 darran 524 1.1 darran /*ARGSUSED*/ 525 1.1 darran static int 526 1.1 darran dt_opt_tregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 527 1.1 darran { 528 1.1 darran int n; 529 1.1 darran 530 1.1 darran if (arg == NULL || (n = atoi(arg)) <= 0) 531 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 532 1.1 darran 533 1.1 darran dtp->dt_conf.dtc_diftupregs = n; 534 1.1 darran return (0); 535 1.1 darran } 536 1.1 darran 537 1.1 darran /*ARGSUSED*/ 538 1.1 darran static int 539 1.1 darran dt_opt_xlate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 540 1.1 darran { 541 1.1 darran if (arg == NULL) 542 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 543 1.1 darran 544 1.1 darran if (strcmp(arg, "dynamic") == 0) 545 1.1 darran dtp->dt_xlatemode = DT_XL_DYNAMIC; 546 1.1 darran else if (strcmp(arg, "static") == 0) 547 1.1 darran dtp->dt_xlatemode = DT_XL_STATIC; 548 1.1 darran else 549 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 550 1.1 darran 551 1.1 darran return (0); 552 1.1 darran } 553 1.1 darran 554 1.1 darran /*ARGSUSED*/ 555 1.1 darran static int 556 1.1 darran dt_opt_cflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 557 1.1 darran { 558 1.1 darran if (arg != NULL) 559 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 560 1.1 darran 561 1.1 darran if (dtp->dt_pcb != NULL) 562 1.1 darran dtp->dt_pcb->pcb_cflags |= option; 563 1.1 darran else 564 1.1 darran dtp->dt_cflags |= option; 565 1.1 darran 566 1.1 darran return (0); 567 1.1 darran } 568 1.1 darran 569 1.1 darran static int 570 1.1 darran dt_opt_dflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 571 1.1 darran { 572 1.1 darran if (arg != NULL) 573 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 574 1.1 darran 575 1.1 darran dtp->dt_dflags |= option; 576 1.1 darran return (0); 577 1.1 darran } 578 1.1 darran 579 1.1 darran static int 580 1.1 darran dt_opt_invcflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 581 1.1 darran { 582 1.1 darran if (arg != NULL) 583 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 584 1.1 darran 585 1.1 darran if (dtp->dt_pcb != NULL) 586 1.1 darran dtp->dt_pcb->pcb_cflags &= ~option; 587 1.1 darran else 588 1.1 darran dtp->dt_cflags &= ~option; 589 1.1 darran 590 1.1 darran return (0); 591 1.1 darran } 592 1.1 darran 593 1.1 darran /*ARGSUSED*/ 594 1.1 darran static int 595 1.1 darran dt_opt_version(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 596 1.1 darran { 597 1.1 darran dt_version_t v; 598 1.1 darran 599 1.1 darran if (arg == NULL) 600 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 601 1.1 darran 602 1.1 darran if (dt_version_str2num(arg, &v) == -1) 603 1.1 darran return (dt_set_errno(dtp, EDT_VERSINVAL)); 604 1.1 darran 605 1.1 darran if (!dt_version_defined(v)) 606 1.1 darran return (dt_set_errno(dtp, EDT_VERSUNDEF)); 607 1.1 darran 608 1.1 darran return (dt_reduce(dtp, v)); 609 1.1 darran } 610 1.1 darran 611 1.1 darran static int 612 1.1 darran dt_opt_runtime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 613 1.1 darran { 614 1.1 darran char *end; 615 1.1 darran dtrace_optval_t val = 0; 616 1.1 darran int i; 617 1.1 darran 618 1.1 darran const struct { 619 1.1 darran char *positive; 620 1.1 darran char *negative; 621 1.1 darran } couples[] = { 622 1.1 darran { "yes", "no" }, 623 1.1 darran { "enable", "disable" }, 624 1.1 darran { "enabled", "disabled" }, 625 1.1 darran { "true", "false" }, 626 1.1 darran { "on", "off" }, 627 1.1 darran { "set", "unset" }, 628 1.1 darran { NULL } 629 1.1 darran }; 630 1.1 darran 631 1.1 darran if (arg != NULL) { 632 1.1 darran if (arg[0] == '\0') { 633 1.1 darran val = DTRACEOPT_UNSET; 634 1.1 darran goto out; 635 1.1 darran } 636 1.1 darran 637 1.1 darran for (i = 0; couples[i].positive != NULL; i++) { 638 1.1 darran if (strcasecmp(couples[i].positive, arg) == 0) { 639 1.1 darran val = 1; 640 1.1 darran goto out; 641 1.1 darran } 642 1.1 darran 643 1.1 darran if (strcasecmp(couples[i].negative, arg) == 0) { 644 1.1 darran val = DTRACEOPT_UNSET; 645 1.1 darran goto out; 646 1.1 darran } 647 1.1 darran } 648 1.1 darran 649 1.1 darran errno = 0; 650 1.1 darran val = strtoull(arg, &end, 0); 651 1.1 darran 652 1.1 darran if (*end != '\0' || errno != 0 || val < 0) 653 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 654 1.1 darran } 655 1.1 darran 656 1.1 darran out: 657 1.1 darran dtp->dt_options[option] = val; 658 1.1 darran return (0); 659 1.1 darran } 660 1.1 darran 661 1.1 darran static int 662 1.1 darran dt_optval_parse(const char *arg, dtrace_optval_t *rval) 663 1.1 darran { 664 1.1 darran dtrace_optval_t mul = 1; 665 1.1 darran size_t len; 666 1.1 darran char *end; 667 1.1 darran 668 1.1 darran len = strlen(arg); 669 1.1 darran errno = 0; 670 1.1 darran 671 1.1 darran switch (arg[len - 1]) { 672 1.1 darran case 't': 673 1.1 darran case 'T': 674 1.1 darran mul *= 1024; 675 1.1 darran /*FALLTHRU*/ 676 1.1 darran case 'g': 677 1.1 darran case 'G': 678 1.1 darran mul *= 1024; 679 1.1 darran /*FALLTHRU*/ 680 1.1 darran case 'm': 681 1.1 darran case 'M': 682 1.1 darran mul *= 1024; 683 1.1 darran /*FALLTHRU*/ 684 1.1 darran case 'k': 685 1.1 darran case 'K': 686 1.1 darran mul *= 1024; 687 1.1 darran /*FALLTHRU*/ 688 1.1 darran default: 689 1.1 darran break; 690 1.1 darran } 691 1.1 darran 692 1.1 darran errno = 0; 693 1.1 darran *rval = strtoull(arg, &end, 0) * mul; 694 1.1 darran 695 1.1 darran if ((mul > 1 && end != &arg[len - 1]) || (mul == 1 && *end != '\0') || 696 1.1 darran *rval < 0 || errno != 0) 697 1.1 darran return (-1); 698 1.1 darran 699 1.1 darran return (0); 700 1.1 darran } 701 1.1 darran 702 1.1 darran static int 703 1.1 darran dt_opt_size(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 704 1.1 darran { 705 1.1 darran dtrace_optval_t val = 0; 706 1.1 darran 707 1.1 darran if (arg != NULL && dt_optval_parse(arg, &val) != 0) 708 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 709 1.1 darran 710 1.1 darran dtp->dt_options[option] = val; 711 1.1 darran return (0); 712 1.1 darran } 713 1.1 darran 714 1.1 darran static int 715 1.1 darran dt_opt_rate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 716 1.1 darran { 717 1.1 darran char *end; 718 1.1 darran int i; 719 1.1 darran dtrace_optval_t mul = 1, val = 0; 720 1.1 darran 721 1.1 darran const struct { 722 1.1 darran char *name; 723 1.1 darran hrtime_t mul; 724 1.1 darran } suffix[] = { 725 1.1 darran { "ns", NANOSEC / NANOSEC }, 726 1.1 darran { "nsec", NANOSEC / NANOSEC }, 727 1.1 darran { "us", NANOSEC / MICROSEC }, 728 1.1 darran { "usec", NANOSEC / MICROSEC }, 729 1.1 darran { "ms", NANOSEC / MILLISEC }, 730 1.1 darran { "msec", NANOSEC / MILLISEC }, 731 1.1 darran { "s", NANOSEC / SEC }, 732 1.1 darran { "sec", NANOSEC / SEC }, 733 1.1 darran { "m", NANOSEC * (hrtime_t)60 }, 734 1.1 darran { "min", NANOSEC * (hrtime_t)60 }, 735 1.1 darran { "h", NANOSEC * (hrtime_t)60 * (hrtime_t)60 }, 736 1.1 darran { "hour", NANOSEC * (hrtime_t)60 * (hrtime_t)60 }, 737 1.1 darran { "d", NANOSEC * (hrtime_t)(24 * 60 * 60) }, 738 1.1 darran { "day", NANOSEC * (hrtime_t)(24 * 60 * 60) }, 739 1.1 darran { "hz", 0 }, 740 1.1 darran { NULL } 741 1.1 darran }; 742 1.1 darran 743 1.1 darran if (arg != NULL) { 744 1.1 darran errno = 0; 745 1.1 darran val = strtoull(arg, &end, 0); 746 1.1 darran 747 1.1 darran for (i = 0; suffix[i].name != NULL; i++) { 748 1.1 darran if (strcasecmp(suffix[i].name, end) == 0) { 749 1.1 darran mul = suffix[i].mul; 750 1.1 darran break; 751 1.1 darran } 752 1.1 darran } 753 1.1 darran 754 1.8 chs if (suffix[i].name == NULL && *end != '\0' || val < 0) 755 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 756 1.1 darran 757 1.1 darran if (mul == 0) { 758 1.1 darran /* 759 1.1 darran * The rate has been specified in frequency-per-second. 760 1.1 darran */ 761 1.1 darran if (val != 0) 762 1.1 darran val = NANOSEC / val; 763 1.1 darran } else { 764 1.1 darran val *= mul; 765 1.1 darran } 766 1.1 darran } 767 1.1 darran 768 1.1 darran dtp->dt_options[option] = val; 769 1.1 darran return (0); 770 1.1 darran } 771 1.1 darran 772 1.1 darran /* 773 1.1 darran * When setting the strsize option, set the option in the dt_options array 774 1.1 darran * using dt_opt_size() as usual, and then update the definition of the CTF 775 1.1 darran * type for the D intrinsic "string" to be an array of the corresponding size. 776 1.1 darran * If any errors occur, reset dt_options[option] to its previous value. 777 1.1 darran */ 778 1.1 darran static int 779 1.1 darran dt_opt_strsize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 780 1.1 darran { 781 1.1 darran dtrace_optval_t val = dtp->dt_options[option]; 782 1.1 darran ctf_file_t *fp = DT_STR_CTFP(dtp); 783 1.1 darran ctf_id_t type = ctf_type_resolve(fp, DT_STR_TYPE(dtp)); 784 1.1 darran ctf_arinfo_t r; 785 1.1 darran 786 1.1 darran if (dt_opt_size(dtp, arg, option) != 0) 787 1.1 darran return (-1); /* dt_errno is set for us */ 788 1.1 darran 789 1.1 darran if (dtp->dt_options[option] > UINT_MAX) { 790 1.1 darran dtp->dt_options[option] = val; 791 1.1 darran return (dt_set_errno(dtp, EOVERFLOW)); 792 1.1 darran } 793 1.1 darran 794 1.1 darran if (ctf_array_info(fp, type, &r) == CTF_ERR) { 795 1.1 darran dtp->dt_options[option] = val; 796 1.1 darran dtp->dt_ctferr = ctf_errno(fp); 797 1.1 darran return (dt_set_errno(dtp, EDT_CTF)); 798 1.1 darran } 799 1.1 darran 800 1.1 darran r.ctr_nelems = (uint_t)dtp->dt_options[option]; 801 1.1 darran 802 1.1 darran if (ctf_set_array(fp, type, &r) == CTF_ERR || 803 1.1 darran ctf_update(fp) == CTF_ERR) { 804 1.1 darran dtp->dt_options[option] = val; 805 1.1 darran dtp->dt_ctferr = ctf_errno(fp); 806 1.1 darran return (dt_set_errno(dtp, EDT_CTF)); 807 1.1 darran } 808 1.1 darran 809 1.1 darran return (0); 810 1.1 darran } 811 1.1 darran 812 1.1 darran static const struct { 813 1.1 darran const char *dtbp_name; 814 1.1 darran int dtbp_policy; 815 1.1 darran } _dtrace_bufpolicies[] = { 816 1.1 darran { "ring", DTRACEOPT_BUFPOLICY_RING }, 817 1.1 darran { "fill", DTRACEOPT_BUFPOLICY_FILL }, 818 1.1 darran { "switch", DTRACEOPT_BUFPOLICY_SWITCH }, 819 1.1 darran { NULL, 0 } 820 1.1 darran }; 821 1.1 darran 822 1.1 darran /*ARGSUSED*/ 823 1.1 darran static int 824 1.1 darran dt_opt_bufpolicy(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 825 1.1 darran { 826 1.1 darran dtrace_optval_t policy = DTRACEOPT_UNSET; 827 1.1 darran int i; 828 1.1 darran 829 1.1 darran if (arg == NULL) 830 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 831 1.1 darran 832 1.1 darran for (i = 0; _dtrace_bufpolicies[i].dtbp_name != NULL; i++) { 833 1.1 darran if (strcmp(_dtrace_bufpolicies[i].dtbp_name, arg) == 0) { 834 1.1 darran policy = _dtrace_bufpolicies[i].dtbp_policy; 835 1.1 darran break; 836 1.1 darran } 837 1.1 darran } 838 1.1 darran 839 1.1 darran if (policy == DTRACEOPT_UNSET) 840 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 841 1.1 darran 842 1.1 darran dtp->dt_options[DTRACEOPT_BUFPOLICY] = policy; 843 1.1 darran 844 1.1 darran return (0); 845 1.1 darran } 846 1.1 darran 847 1.1 darran static const struct { 848 1.1 darran const char *dtbr_name; 849 1.1 darran int dtbr_policy; 850 1.1 darran } _dtrace_bufresize[] = { 851 1.1 darran { "auto", DTRACEOPT_BUFRESIZE_AUTO }, 852 1.1 darran { "manual", DTRACEOPT_BUFRESIZE_MANUAL }, 853 1.1 darran { NULL, 0 } 854 1.1 darran }; 855 1.1 darran 856 1.1 darran /*ARGSUSED*/ 857 1.1 darran static int 858 1.1 darran dt_opt_bufresize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) 859 1.1 darran { 860 1.1 darran dtrace_optval_t policy = DTRACEOPT_UNSET; 861 1.1 darran int i; 862 1.1 darran 863 1.1 darran if (arg == NULL) 864 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 865 1.1 darran 866 1.1 darran for (i = 0; _dtrace_bufresize[i].dtbr_name != NULL; i++) { 867 1.1 darran if (strcmp(_dtrace_bufresize[i].dtbr_name, arg) == 0) { 868 1.1 darran policy = _dtrace_bufresize[i].dtbr_policy; 869 1.1 darran break; 870 1.1 darran } 871 1.1 darran } 872 1.1 darran 873 1.1 darran if (policy == DTRACEOPT_UNSET) 874 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTVAL)); 875 1.1 darran 876 1.1 darran dtp->dt_options[DTRACEOPT_BUFRESIZE] = policy; 877 1.1 darran 878 1.1 darran return (0); 879 1.1 darran } 880 1.1 darran 881 1.1 darran int 882 1.1 darran dt_options_load(dtrace_hdl_t *dtp) 883 1.1 darran { 884 1.1 darran dof_hdr_t hdr, *dof; 885 1.7 christos dof_sec_t *sec = NULL; // XXX: gcc 886 1.1 darran size_t offs; 887 1.1 darran int i; 888 1.1 darran 889 1.1 darran /* 890 1.1 darran * To load the option values, we need to ask the kernel to provide its 891 1.1 darran * DOF, which we'll sift through to look for OPTDESC sections. 892 1.1 darran */ 893 1.1 darran bzero(&hdr, sizeof (dof_hdr_t)); 894 1.1 darran hdr.dofh_loadsz = sizeof (dof_hdr_t); 895 1.1 darran 896 1.7 christos #ifdef illumos 897 1.1 darran if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &hdr) == -1) 898 1.2 darran #else 899 1.2 darran dof = &hdr; 900 1.2 darran if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &dof) == -1) 901 1.2 darran #endif 902 1.1 darran return (dt_set_errno(dtp, errno)); 903 1.1 darran 904 1.1 darran if (hdr.dofh_loadsz < sizeof (dof_hdr_t)) 905 1.1 darran return (dt_set_errno(dtp, EINVAL)); 906 1.1 darran 907 1.9 christos dof = calloc(hdr.dofh_loadsz, 1); 908 1.9 christos if (dof == NULL) 909 1.9 christos return (dt_set_errno(dtp, errno)); 910 1.1 darran dof->dofh_loadsz = hdr.dofh_loadsz; 911 1.1 darran 912 1.1 darran for (i = 0; i < DTRACEOPT_MAX; i++) 913 1.1 darran dtp->dt_options[i] = DTRACEOPT_UNSET; 914 1.1 darran 915 1.7 christos #ifdef illumos 916 1.1 darran if (dt_ioctl(dtp, DTRACEIOC_DOFGET, dof) == -1) 917 1.2 darran #else 918 1.2 darran if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &dof) == -1) 919 1.2 darran #endif 920 1.9 christos { 921 1.9 christos free(dof); 922 1.1 darran return (dt_set_errno(dtp, errno)); 923 1.9 christos } 924 1.1 darran 925 1.1 darran for (i = 0; i < dof->dofh_secnum; i++) { 926 1.1 darran sec = (dof_sec_t *)(uintptr_t)((uintptr_t)dof + 927 1.1 darran dof->dofh_secoff + i * dof->dofh_secsize); 928 1.1 darran 929 1.1 darran if (sec->dofs_type != DOF_SECT_OPTDESC) 930 1.1 darran continue; 931 1.1 darran 932 1.1 darran break; 933 1.1 darran } 934 1.1 darran 935 1.1 darran for (offs = 0; offs < sec->dofs_size; offs += sec->dofs_entsize) { 936 1.1 darran dof_optdesc_t *opt = (dof_optdesc_t *)(uintptr_t) 937 1.1 darran ((uintptr_t)dof + sec->dofs_offset + offs); 938 1.1 darran 939 1.1 darran if (opt->dofo_strtab != DOF_SECIDX_NONE) 940 1.1 darran continue; 941 1.1 darran 942 1.1 darran if (opt->dofo_option >= DTRACEOPT_MAX) 943 1.1 darran continue; 944 1.1 darran 945 1.1 darran dtp->dt_options[opt->dofo_option] = opt->dofo_value; 946 1.1 darran } 947 1.9 christos free(dof); 948 1.1 darran return (0); 949 1.1 darran } 950 1.1 darran 951 1.1 darran typedef struct dt_option { 952 1.1 darran const char *o_name; 953 1.1 darran int (*o_func)(dtrace_hdl_t *, const char *, uintptr_t); 954 1.1 darran uintptr_t o_option; 955 1.1 darran } dt_option_t; 956 1.1 darran 957 1.1 darran /* 958 1.1 darran * Compile-time options. 959 1.1 darran */ 960 1.1 darran static const dt_option_t _dtrace_ctoptions[] = { 961 1.1 darran { "aggpercpu", dt_opt_agg, DTRACE_A_PERCPU }, 962 1.1 darran { "amin", dt_opt_amin }, 963 1.1 darran { "argref", dt_opt_cflags, DTRACE_C_ARGREF }, 964 1.1 darran { "core", dt_opt_core }, 965 1.1 darran { "cpp", dt_opt_cflags, DTRACE_C_CPP }, 966 1.1 darran { "cpphdrs", dt_opt_cpp_hdrs }, 967 1.1 darran { "cpppath", dt_opt_cpp_path }, 968 1.1 darran { "ctypes", dt_opt_ctypes }, 969 1.1 darran { "defaultargs", dt_opt_cflags, DTRACE_C_DEFARG }, 970 1.1 darran { "dtypes", dt_opt_dtypes }, 971 1.1 darran { "debug", dt_opt_debug }, 972 1.1 darran { "define", dt_opt_cpp_opts, (uintptr_t)"-D" }, 973 1.1 darran { "droptags", dt_opt_droptags }, 974 1.1 darran { "empty", dt_opt_cflags, DTRACE_C_EMPTY }, 975 1.7 christos { "encoding", dt_opt_encoding }, 976 1.1 darran { "errtags", dt_opt_cflags, DTRACE_C_ETAGS }, 977 1.1 darran { "evaltime", dt_opt_evaltime }, 978 1.1 darran { "incdir", dt_opt_cpp_opts, (uintptr_t)"-I" }, 979 1.1 darran { "iregs", dt_opt_iregs }, 980 1.1 darran { "kdefs", dt_opt_invcflags, DTRACE_C_KNODEF }, 981 1.1 darran { "knodefs", dt_opt_cflags, DTRACE_C_KNODEF }, 982 1.1 darran { "late", dt_opt_xlate }, 983 1.1 darran { "lazyload", dt_opt_lazyload }, 984 1.1 darran { "ldpath", dt_opt_ld_path }, 985 1.1 darran { "libdir", dt_opt_libdir }, 986 1.1 darran { "linkmode", dt_opt_linkmode }, 987 1.1 darran { "linktype", dt_opt_linktype }, 988 1.1 darran { "nolibs", dt_opt_cflags, DTRACE_C_NOLIBS }, 989 1.7 christos #if defined(__FreeBSD__) || defined(__NetBSD__) 990 1.7 christos { "objcopypath", dt_opt_objcopy_path }, 991 1.7 christos #endif 992 1.1 darran { "pgmax", dt_opt_pgmax }, 993 1.1 darran { "pspec", dt_opt_cflags, DTRACE_C_PSPEC }, 994 1.7 christos { "setenv", dt_opt_setenv, 1 }, 995 1.1 darran { "stdc", dt_opt_stdc }, 996 1.1 darran { "strip", dt_opt_dflags, DTRACE_D_STRIP }, 997 1.1 darran { "syslibdir", dt_opt_syslibdir }, 998 1.1 darran { "tree", dt_opt_tree }, 999 1.1 darran { "tregs", dt_opt_tregs }, 1000 1.1 darran { "udefs", dt_opt_invcflags, DTRACE_C_UNODEF }, 1001 1.1 darran { "undef", dt_opt_cpp_opts, (uintptr_t)"-U" }, 1002 1.1 darran { "unodefs", dt_opt_cflags, DTRACE_C_UNODEF }, 1003 1.7 christos { "unsetenv", dt_opt_setenv, 0 }, 1004 1.1 darran { "verbose", dt_opt_cflags, DTRACE_C_DIFV }, 1005 1.1 darran { "version", dt_opt_version }, 1006 1.1 darran { "zdefs", dt_opt_cflags, DTRACE_C_ZDEFS }, 1007 1.2 darran { NULL, NULL, 0 } 1008 1.1 darran }; 1009 1.1 darran 1010 1.1 darran /* 1011 1.1 darran * Run-time options. 1012 1.1 darran */ 1013 1.1 darran static const dt_option_t _dtrace_rtoptions[] = { 1014 1.1 darran { "aggsize", dt_opt_size, DTRACEOPT_AGGSIZE }, 1015 1.1 darran { "bufsize", dt_opt_size, DTRACEOPT_BUFSIZE }, 1016 1.1 darran { "bufpolicy", dt_opt_bufpolicy, DTRACEOPT_BUFPOLICY }, 1017 1.1 darran { "bufresize", dt_opt_bufresize, DTRACEOPT_BUFRESIZE }, 1018 1.1 darran { "cleanrate", dt_opt_rate, DTRACEOPT_CLEANRATE }, 1019 1.1 darran { "cpu", dt_opt_runtime, DTRACEOPT_CPU }, 1020 1.1 darran { "destructive", dt_opt_runtime, DTRACEOPT_DESTRUCTIVE }, 1021 1.1 darran { "dynvarsize", dt_opt_size, DTRACEOPT_DYNVARSIZE }, 1022 1.1 darran { "grabanon", dt_opt_runtime, DTRACEOPT_GRABANON }, 1023 1.1 darran { "jstackframes", dt_opt_runtime, DTRACEOPT_JSTACKFRAMES }, 1024 1.1 darran { "jstackstrsize", dt_opt_size, DTRACEOPT_JSTACKSTRSIZE }, 1025 1.1 darran { "nspec", dt_opt_runtime, DTRACEOPT_NSPEC }, 1026 1.1 darran { "specsize", dt_opt_size, DTRACEOPT_SPECSIZE }, 1027 1.1 darran { "stackframes", dt_opt_runtime, DTRACEOPT_STACKFRAMES }, 1028 1.1 darran { "statusrate", dt_opt_rate, DTRACEOPT_STATUSRATE }, 1029 1.1 darran { "strsize", dt_opt_strsize, DTRACEOPT_STRSIZE }, 1030 1.1 darran { "ustackframes", dt_opt_runtime, DTRACEOPT_USTACKFRAMES }, 1031 1.7 christos { "temporal", dt_opt_runtime, DTRACEOPT_TEMPORAL }, 1032 1.2 darran { NULL, NULL, 0 } 1033 1.1 darran }; 1034 1.1 darran 1035 1.1 darran /* 1036 1.1 darran * Dynamic run-time options. 1037 1.1 darran */ 1038 1.1 darran static const dt_option_t _dtrace_drtoptions[] = { 1039 1.7 christos { "agghist", dt_opt_runtime, DTRACEOPT_AGGHIST }, 1040 1.7 christos { "aggpack", dt_opt_runtime, DTRACEOPT_AGGPACK }, 1041 1.1 darran { "aggrate", dt_opt_rate, DTRACEOPT_AGGRATE }, 1042 1.1 darran { "aggsortkey", dt_opt_runtime, DTRACEOPT_AGGSORTKEY }, 1043 1.1 darran { "aggsortkeypos", dt_opt_runtime, DTRACEOPT_AGGSORTKEYPOS }, 1044 1.1 darran { "aggsortpos", dt_opt_runtime, DTRACEOPT_AGGSORTPOS }, 1045 1.1 darran { "aggsortrev", dt_opt_runtime, DTRACEOPT_AGGSORTREV }, 1046 1.7 christos { "aggzoom", dt_opt_runtime, DTRACEOPT_AGGZOOM }, 1047 1.1 darran { "flowindent", dt_opt_runtime, DTRACEOPT_FLOWINDENT }, 1048 1.1 darran { "quiet", dt_opt_runtime, DTRACEOPT_QUIET }, 1049 1.1 darran { "rawbytes", dt_opt_runtime, DTRACEOPT_RAWBYTES }, 1050 1.1 darran { "stackindent", dt_opt_runtime, DTRACEOPT_STACKINDENT }, 1051 1.1 darran { "switchrate", dt_opt_rate, DTRACEOPT_SWITCHRATE }, 1052 1.2 darran { NULL, NULL, 0 } 1053 1.1 darran }; 1054 1.1 darran 1055 1.1 darran int 1056 1.1 darran dtrace_getopt(dtrace_hdl_t *dtp, const char *opt, dtrace_optval_t *val) 1057 1.1 darran { 1058 1.1 darran const dt_option_t *op; 1059 1.1 darran 1060 1.1 darran if (opt == NULL) 1061 1.1 darran return (dt_set_errno(dtp, EINVAL)); 1062 1.1 darran 1063 1.1 darran /* 1064 1.1 darran * We only need to search the run-time options -- it's not legal 1065 1.1 darran * to get the values of compile-time options. 1066 1.1 darran */ 1067 1.1 darran for (op = _dtrace_rtoptions; op->o_name != NULL; op++) { 1068 1.1 darran if (strcmp(op->o_name, opt) == 0) { 1069 1.1 darran *val = dtp->dt_options[op->o_option]; 1070 1.1 darran return (0); 1071 1.1 darran } 1072 1.1 darran } 1073 1.1 darran 1074 1.1 darran for (op = _dtrace_drtoptions; op->o_name != NULL; op++) { 1075 1.1 darran if (strcmp(op->o_name, opt) == 0) { 1076 1.1 darran *val = dtp->dt_options[op->o_option]; 1077 1.1 darran return (0); 1078 1.1 darran } 1079 1.1 darran } 1080 1.1 darran 1081 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTNAME)); 1082 1.1 darran } 1083 1.1 darran 1084 1.1 darran int 1085 1.1 darran dtrace_setopt(dtrace_hdl_t *dtp, const char *opt, const char *val) 1086 1.1 darran { 1087 1.1 darran const dt_option_t *op; 1088 1.1 darran 1089 1.1 darran if (opt == NULL) 1090 1.1 darran return (dt_set_errno(dtp, EINVAL)); 1091 1.1 darran 1092 1.1 darran for (op = _dtrace_ctoptions; op->o_name != NULL; op++) { 1093 1.1 darran if (strcmp(op->o_name, opt) == 0) 1094 1.1 darran return (op->o_func(dtp, val, op->o_option)); 1095 1.1 darran } 1096 1.1 darran 1097 1.1 darran for (op = _dtrace_drtoptions; op->o_name != NULL; op++) { 1098 1.1 darran if (strcmp(op->o_name, opt) == 0) 1099 1.1 darran return (op->o_func(dtp, val, op->o_option)); 1100 1.1 darran } 1101 1.1 darran 1102 1.1 darran for (op = _dtrace_rtoptions; op->o_name != NULL; op++) { 1103 1.1 darran if (strcmp(op->o_name, opt) == 0) { 1104 1.1 darran /* 1105 1.1 darran * Only dynamic run-time options may be set while 1106 1.1 darran * tracing is active. 1107 1.1 darran */ 1108 1.1 darran if (dtp->dt_active) 1109 1.1 darran return (dt_set_errno(dtp, EDT_ACTIVE)); 1110 1.1 darran 1111 1.1 darran return (op->o_func(dtp, val, op->o_option)); 1112 1.1 darran } 1113 1.1 darran } 1114 1.1 darran 1115 1.1 darran return (dt_set_errno(dtp, EDT_BADOPTNAME)); 1116 1.1 darran } 1117